Path: blob/master/sha3/sph_radiogatun.c
1306 views
/* $Id: radiogatun.c 226 2010-06-16 17:28:08Z tp $ */1/*2* RadioGatun implementation.3*4* ==========================(LICENSE BEGIN)============================5*6* Copyright (c) 2007-2010 Projet RNRT SAPHIR7*8* Permission is hereby granted, free of charge, to any person obtaining9* a copy of this software and associated documentation files (the10* "Software"), to deal in the Software without restriction, including11* without limitation the rights to use, copy, modify, merge, publish,12* distribute, sublicense, and/or sell copies of the Software, and to13* permit persons to whom the Software is furnished to do so, subject to14* the following conditions:15*16* The above copyright notice and this permission notice shall be17* included in all copies or substantial portions of the Software.18*19* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,20* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF21* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.22* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY23* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,24* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE25* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.26*27* ===========================(LICENSE END)=============================28*29* @author Thomas Pornin <[email protected]>30*/3132#include <stddef.h>33#include <string.h>3435#include "sph_radiogatun.h"3637#if SPH_SMALL_FOOTPRINT && !defined SPH_SMALL_FOOTPRINT_RADIOGATUN38#define SPH_SMALL_FOOTPRINT_RADIOGATUN 139#endif4041/* ======================================================================= */42/*43* The core macros. We want to unroll 13 successive rounds so that the44* belt rotation becomes pure routing, solved at compilation time, with45* no unnecessary copying. We also wish all state variables to be46* independant local variables, so that the C compiler becomes free to47* map these on registers at it sees fit. This requires some heavy48* preprocessor trickeries, including a full addition macro modulo 13.49*50* These macros are size-independent. Some macros must be defined before51* use:52* WT evaluates to the type for a word (32-bit or 64-bit)53* T truncates a value to the proper word size54* ROR(x, n) right rotation of a word x, with explicit modular55* reduction of the rotation count n by the word size56* INW(i, j) input word j (0, 1, or 2) of block i (0 to 12)57*58* For INW, the input buffer is pointed to by "buf" which has type59* "const unsigned char *".60*/6162#define MUL19(action) do { \63action(0); \64action(1); \65action(2); \66action(3); \67action(4); \68action(5); \69action(6); \70action(7); \71action(8); \72action(9); \73action(10); \74action(11); \75action(12); \76action(13); \77action(14); \78action(15); \79action(16); \80action(17); \81action(18); \82} while (0)8384#define DECL19(b) b ## 0, b ## 1, b ## 2, b ## 3, b ## 4, b ## 5, \85b ## 6, b ## 7, b ## 8, b ## 9, b ## 10, b ## 11, \86b ## 12, b ## 13, b ## 14, b ## 15, b ## 16, \87b ## 17, b ## 188889#define M19_T7(i) M19_T7_(i)90#define M19_T7_(i) M19_T7_ ## i91#define M19_T7_0 092#define M19_T7_1 793#define M19_T7_2 1494#define M19_T7_3 295#define M19_T7_4 996#define M19_T7_5 1697#define M19_T7_6 498#define M19_T7_7 1199#define M19_T7_8 18100#define M19_T7_9 6101#define M19_T7_10 13102#define M19_T7_11 1103#define M19_T7_12 8104#define M19_T7_13 15105#define M19_T7_14 3106#define M19_T7_15 10107#define M19_T7_16 17108#define M19_T7_17 5109#define M19_T7_18 12110111#define M19_A1(i) M19_A1_(i)112#define M19_A1_(i) M19_A1_ ## i113#define M19_A1_0 1114#define M19_A1_1 2115#define M19_A1_2 3116#define M19_A1_3 4117#define M19_A1_4 5118#define M19_A1_5 6119#define M19_A1_6 7120#define M19_A1_7 8121#define M19_A1_8 9122#define M19_A1_9 10123#define M19_A1_10 11124#define M19_A1_11 12125#define M19_A1_12 13126#define M19_A1_13 14127#define M19_A1_14 15128#define M19_A1_15 16129#define M19_A1_16 17130#define M19_A1_17 18131#define M19_A1_18 0132133#define M19_A2(i) M19_A2_(i)134#define M19_A2_(i) M19_A2_ ## i135#define M19_A2_0 2136#define M19_A2_1 3137#define M19_A2_2 4138#define M19_A2_3 5139#define M19_A2_4 6140#define M19_A2_5 7141#define M19_A2_6 8142#define M19_A2_7 9143#define M19_A2_8 10144#define M19_A2_9 11145#define M19_A2_10 12146#define M19_A2_11 13147#define M19_A2_12 14148#define M19_A2_13 15149#define M19_A2_14 16150#define M19_A2_15 17151#define M19_A2_16 18152#define M19_A2_17 0153#define M19_A2_18 1154155#define M19_A4(i) M19_A4_(i)156#define M19_A4_(i) M19_A4_ ## i157#define M19_A4_0 4158#define M19_A4_1 5159#define M19_A4_2 6160#define M19_A4_3 7161#define M19_A4_4 8162#define M19_A4_5 9163#define M19_A4_6 10164#define M19_A4_7 11165#define M19_A4_8 12166#define M19_A4_9 13167#define M19_A4_10 14168#define M19_A4_11 15169#define M19_A4_12 16170#define M19_A4_13 17171#define M19_A4_14 18172#define M19_A4_15 0173#define M19_A4_16 1174#define M19_A4_17 2175#define M19_A4_18 3176177#define ACC_a(i) ACC_a_(i)178#define ACC_a_(i) a ## i179#define ACC_atmp(i) ACC_atmp_(i)180#define ACC_atmp_(i) atmp ## i181182#define MILL1(i) (atmp ## i = a ## i ^ T(ACC_a(M19_A1(i)) \183| ~ACC_a(M19_A2(i))))184#define MILL2(i) (a ## i = ROR(ACC_atmp(M19_T7(i)), ((i * (i + 1)) >> 1)))185#define MILL3(i) (atmp ## i = a ## i ^ ACC_a(M19_A1(i)) ^ ACC_a(M19_A4(i)))186#define MILL4(i) (a ## i = atmp ## i ^ (i == 0))187188#define MILL do { \189WT DECL19(atmp); \190MUL19(MILL1); \191MUL19(MILL2); \192MUL19(MILL3); \193MUL19(MILL4); \194} while (0)195196#define DECL13(b) b ## 0 ## _0, b ## 0 ## _1, b ## 0 ## _2, \197b ## 1 ## _0, b ## 1 ## _1, b ## 1 ## _2, \198b ## 2 ## _0, b ## 2 ## _1, b ## 2 ## _2, \199b ## 3 ## _0, b ## 3 ## _1, b ## 3 ## _2, \200b ## 4 ## _0, b ## 4 ## _1, b ## 4 ## _2, \201b ## 5 ## _0, b ## 5 ## _1, b ## 5 ## _2, \202b ## 6 ## _0, b ## 6 ## _1, b ## 6 ## _2, \203b ## 7 ## _0, b ## 7 ## _1, b ## 7 ## _2, \204b ## 8 ## _0, b ## 8 ## _1, b ## 8 ## _2, \205b ## 9 ## _0, b ## 9 ## _1, b ## 9 ## _2, \206b ## 10 ## _0, b ## 10 ## _1, b ## 10 ## _2, \207b ## 11 ## _0, b ## 11 ## _1, b ## 11 ## _2, \208b ## 12 ## _0, b ## 12 ## _1, b ## 12 ## _2209210#define M13_A(i, j) M13_A_(i, j)211#define M13_A_(i, j) M13_A_ ## i ## _ ## j212#define M13_A_0_0 0213#define M13_A_0_1 1214#define M13_A_0_2 2215#define M13_A_0_3 3216#define M13_A_0_4 4217#define M13_A_0_5 5218#define M13_A_0_6 6219#define M13_A_0_7 7220#define M13_A_0_8 8221#define M13_A_0_9 9222#define M13_A_0_10 10223#define M13_A_0_11 11224#define M13_A_0_12 12225#define M13_A_1_0 1226#define M13_A_1_1 2227#define M13_A_1_2 3228#define M13_A_1_3 4229#define M13_A_1_4 5230#define M13_A_1_5 6231#define M13_A_1_6 7232#define M13_A_1_7 8233#define M13_A_1_8 9234#define M13_A_1_9 10235#define M13_A_1_10 11236#define M13_A_1_11 12237#define M13_A_1_12 0238#define M13_A_2_0 2239#define M13_A_2_1 3240#define M13_A_2_2 4241#define M13_A_2_3 5242#define M13_A_2_4 6243#define M13_A_2_5 7244#define M13_A_2_6 8245#define M13_A_2_7 9246#define M13_A_2_8 10247#define M13_A_2_9 11248#define M13_A_2_10 12249#define M13_A_2_11 0250#define M13_A_2_12 1251#define M13_A_3_0 3252#define M13_A_3_1 4253#define M13_A_3_2 5254#define M13_A_3_3 6255#define M13_A_3_4 7256#define M13_A_3_5 8257#define M13_A_3_6 9258#define M13_A_3_7 10259#define M13_A_3_8 11260#define M13_A_3_9 12261#define M13_A_3_10 0262#define M13_A_3_11 1263#define M13_A_3_12 2264#define M13_A_4_0 4265#define M13_A_4_1 5266#define M13_A_4_2 6267#define M13_A_4_3 7268#define M13_A_4_4 8269#define M13_A_4_5 9270#define M13_A_4_6 10271#define M13_A_4_7 11272#define M13_A_4_8 12273#define M13_A_4_9 0274#define M13_A_4_10 1275#define M13_A_4_11 2276#define M13_A_4_12 3277#define M13_A_5_0 5278#define M13_A_5_1 6279#define M13_A_5_2 7280#define M13_A_5_3 8281#define M13_A_5_4 9282#define M13_A_5_5 10283#define M13_A_5_6 11284#define M13_A_5_7 12285#define M13_A_5_8 0286#define M13_A_5_9 1287#define M13_A_5_10 2288#define M13_A_5_11 3289#define M13_A_5_12 4290#define M13_A_6_0 6291#define M13_A_6_1 7292#define M13_A_6_2 8293#define M13_A_6_3 9294#define M13_A_6_4 10295#define M13_A_6_5 11296#define M13_A_6_6 12297#define M13_A_6_7 0298#define M13_A_6_8 1299#define M13_A_6_9 2300#define M13_A_6_10 3301#define M13_A_6_11 4302#define M13_A_6_12 5303#define M13_A_7_0 7304#define M13_A_7_1 8305#define M13_A_7_2 9306#define M13_A_7_3 10307#define M13_A_7_4 11308#define M13_A_7_5 12309#define M13_A_7_6 0310#define M13_A_7_7 1311#define M13_A_7_8 2312#define M13_A_7_9 3313#define M13_A_7_10 4314#define M13_A_7_11 5315#define M13_A_7_12 6316#define M13_A_8_0 8317#define M13_A_8_1 9318#define M13_A_8_2 10319#define M13_A_8_3 11320#define M13_A_8_4 12321#define M13_A_8_5 0322#define M13_A_8_6 1323#define M13_A_8_7 2324#define M13_A_8_8 3325#define M13_A_8_9 4326#define M13_A_8_10 5327#define M13_A_8_11 6328#define M13_A_8_12 7329#define M13_A_9_0 9330#define M13_A_9_1 10331#define M13_A_9_2 11332#define M13_A_9_3 12333#define M13_A_9_4 0334#define M13_A_9_5 1335#define M13_A_9_6 2336#define M13_A_9_7 3337#define M13_A_9_8 4338#define M13_A_9_9 5339#define M13_A_9_10 6340#define M13_A_9_11 7341#define M13_A_9_12 8342#define M13_A_10_0 10343#define M13_A_10_1 11344#define M13_A_10_2 12345#define M13_A_10_3 0346#define M13_A_10_4 1347#define M13_A_10_5 2348#define M13_A_10_6 3349#define M13_A_10_7 4350#define M13_A_10_8 5351#define M13_A_10_9 6352#define M13_A_10_10 7353#define M13_A_10_11 8354#define M13_A_10_12 9355#define M13_A_11_0 11356#define M13_A_11_1 12357#define M13_A_11_2 0358#define M13_A_11_3 1359#define M13_A_11_4 2360#define M13_A_11_5 3361#define M13_A_11_6 4362#define M13_A_11_7 5363#define M13_A_11_8 6364#define M13_A_11_9 7365#define M13_A_11_10 8366#define M13_A_11_11 9367#define M13_A_11_12 10368#define M13_A_12_0 12369#define M13_A_12_1 0370#define M13_A_12_2 1371#define M13_A_12_3 2372#define M13_A_12_4 3373#define M13_A_12_5 4374#define M13_A_12_6 5375#define M13_A_12_7 6376#define M13_A_12_8 7377#define M13_A_12_9 8378#define M13_A_12_10 9379#define M13_A_12_11 10380#define M13_A_12_12 11381382#define M13_N(i) M13_N_(i)383#define M13_N_(i) M13_N_ ## i384#define M13_N_0 12385#define M13_N_1 11386#define M13_N_2 10387#define M13_N_3 9388#define M13_N_4 8389#define M13_N_5 7390#define M13_N_6 6391#define M13_N_7 5392#define M13_N_8 4393#define M13_N_9 3394#define M13_N_10 2395#define M13_N_11 1396#define M13_N_12 0397398#define ACC_b(i, k) ACC_b_(i, k)399#define ACC_b_(i, k) b ## i ## _ ## k400401#define ROUND_ELT(k, s) do { \402if ((bj += 3) == 39) \403bj = 0; \404sc->b[bj + s] ^= a ## k; \405} while (0)406407#define ROUND_SF(j) do { \408size_t bj = (j) * 3; \409ROUND_ELT(1, 0); \410ROUND_ELT(2, 1); \411ROUND_ELT(3, 2); \412ROUND_ELT(4, 0); \413ROUND_ELT(5, 1); \414ROUND_ELT(6, 2); \415ROUND_ELT(7, 0); \416ROUND_ELT(8, 1); \417ROUND_ELT(9, 2); \418ROUND_ELT(10, 0); \419ROUND_ELT(11, 1); \420ROUND_ELT(12, 2); \421MILL; \422bj = (j) * 3; \423a ## 13 ^= sc->b[bj + 0]; \424a ## 14 ^= sc->b[bj + 1]; \425a ## 15 ^= sc->b[bj + 2]; \426} while (0)427428#define INPUT_SF(j, p0, p1, p2) do { \429size_t bj = ((j) + 1) * 3; \430if (bj == 39) \431bj = 0; \432sc->b[bj + 0] ^= (p0); \433sc->b[bj + 1] ^= (p1); \434sc->b[bj + 2] ^= (p2); \435a16 ^= (p0); \436a17 ^= (p1); \437a18 ^= (p2); \438} while (0)439440441#if SPH_SMALL_FOOTPRINT_RADIOGATUN442443#define ROUND ROUND_SF444#define INPUT INPUT_SF445446#else447448/*449* Round function R, on base j. The value j is such that B[0] is actually450* b[j] after the initial rotation. On the 13-round macro, j has the451* successive values 12, 11, 10... 1, 0.452*/453#define ROUND(j) do { \454ACC_b(M13_A(1, j), 0) ^= a ## 1; \455ACC_b(M13_A(2, j), 1) ^= a ## 2; \456ACC_b(M13_A(3, j), 2) ^= a ## 3; \457ACC_b(M13_A(4, j), 0) ^= a ## 4; \458ACC_b(M13_A(5, j), 1) ^= a ## 5; \459ACC_b(M13_A(6, j), 2) ^= a ## 6; \460ACC_b(M13_A(7, j), 0) ^= a ## 7; \461ACC_b(M13_A(8, j), 1) ^= a ## 8; \462ACC_b(M13_A(9, j), 2) ^= a ## 9; \463ACC_b(M13_A(10, j), 0) ^= a ## 10; \464ACC_b(M13_A(11, j), 1) ^= a ## 11; \465ACC_b(M13_A(12, j), 2) ^= a ## 12; \466MILL; \467a ## 13 ^= ACC_b(j, 0); \468a ## 14 ^= ACC_b(j, 1); \469a ## 15 ^= ACC_b(j, 2); \470} while (0)471472#define INPUT(j, p0, p1, p2) do { \473ACC_b(M13_A(1, j), 0) ^= (p0); \474ACC_b(M13_A(1, j), 1) ^= (p1); \475ACC_b(M13_A(1, j), 2) ^= (p2); \476a16 ^= (p0); \477a17 ^= (p1); \478a18 ^= (p2); \479} while (0)480481#endif482483#define MUL13(action) do { \484action(0); \485action(1); \486action(2); \487action(3); \488action(4); \489action(5); \490action(6); \491action(7); \492action(8); \493action(9); \494action(10); \495action(11); \496action(12); \497} while (0)498499#define MILL_READ_ELT(i) do { \500a ## i = sc->a[i]; \501} while (0)502503#define MILL_WRITE_ELT(i) do { \504sc->a[i] = a ## i; \505} while (0)506507#define STATE_READ_SF do { \508MUL19(MILL_READ_ELT); \509} while (0)510511#define STATE_WRITE_SF do { \512MUL19(MILL_WRITE_ELT); \513} while (0)514515#define PUSH13_SF do { \516WT DECL19(a); \517const unsigned char *buf; \518\519buf = data; \520STATE_READ_SF; \521while (len >= sizeof sc->data) { \522size_t mk; \523for (mk = 13; mk > 0; mk --) { \524WT p0 = INW(0, 0); \525WT p1 = INW(0, 1); \526WT p2 = INW(0, 2); \527INPUT_SF(mk - 1, p0, p1, p2); \528ROUND_SF(mk - 1); \529buf += (sizeof sc->data) / 13; \530len -= (sizeof sc->data) / 13; \531} \532} \533STATE_WRITE_SF; \534return len; \535} while (0)536537#if SPH_SMALL_FOOTPRINT_RADIOGATUN538539#define STATE_READ STATE_READ_SF540#define STATE_WRITE STATE_WRITE_SF541#define PUSH13 PUSH13_SF542543#else544545#define BELT_READ_ELT(i) do { \546b ## i ## _0 = sc->b[3 * i + 0]; \547b ## i ## _1 = sc->b[3 * i + 1]; \548b ## i ## _2 = sc->b[3 * i + 2]; \549} while (0)550551#define BELT_WRITE_ELT(i) do { \552sc->b[3 * i + 0] = b ## i ## _0; \553sc->b[3 * i + 1] = b ## i ## _1; \554sc->b[3 * i + 2] = b ## i ## _2; \555} while (0)556557#define STATE_READ do { \558MUL13(BELT_READ_ELT); \559MUL19(MILL_READ_ELT); \560} while (0)561562#define STATE_WRITE do { \563MUL13(BELT_WRITE_ELT); \564MUL19(MILL_WRITE_ELT); \565} while (0)566567/*568* Input data by chunks of 13*3 blocks. This is the body of the569* radiogatun32_push13() and radiogatun64_push13() functions.570*/571#define PUSH13 do { \572WT DECL19(a), DECL13(b); \573const unsigned char *buf; \574\575buf = data; \576STATE_READ; \577while (len >= sizeof sc->data) { \578WT p0, p1, p2; \579MUL13(PUSH13_ELT); \580buf += sizeof sc->data; \581len -= sizeof sc->data; \582} \583STATE_WRITE; \584return len; \585} while (0)586587#define PUSH13_ELT(k) do { \588p0 = INW(k, 0); \589p1 = INW(k, 1); \590p2 = INW(k, 2); \591INPUT(M13_N(k), p0, p1, p2); \592ROUND(M13_N(k)); \593} while (0)594595#endif596597#define BLANK13_SF do { \598size_t mk = 13; \599while (mk -- > 0) \600ROUND_SF(mk); \601} while (0)602603#define BLANK1_SF do { \604WT tmp0, tmp1, tmp2; \605ROUND_SF(12); \606tmp0 = sc->b[36]; \607tmp1 = sc->b[37]; \608tmp2 = sc->b[38]; \609memmove(sc->b + 3, sc->b, 36 * sizeof sc->b[0]); \610sc->b[0] = tmp0; \611sc->b[1] = tmp1; \612sc->b[2] = tmp2; \613} while (0)614615#if SPH_SMALL_FOOTPRINT_RADIOGATUN616617#define BLANK13 BLANK13_SF618#define BLANK1 BLANK1_SF619620#else621622/*623* Run 13 blank rounds. This macro expects the "a" and "b" state variables624* to be alread declared.625*/626#define BLANK13 MUL13(BLANK13_ELT)627628#define BLANK13_ELT(k) ROUND(M13_N(k))629630#define MUL12(action) do { \631action(0); \632action(1); \633action(2); \634action(3); \635action(4); \636action(5); \637action(6); \638action(7); \639action(8); \640action(9); \641action(10); \642action(11); \643} while (0)644645/*646* Run a single blank round, and physically rotate the belt. This is used647* for the last blank rounds, and the output rounds. This macro expects the648* "a" abd "b" state variables to be already declared.649*/650#define BLANK1 do { \651WT tmp0, tmp1, tmp2; \652ROUND(12); \653tmp0 = b0_0; \654tmp1 = b0_1; \655tmp2 = b0_2; \656MUL12(BLANK1_ELT); \657b1_0 = tmp0; \658b1_1 = tmp1; \659b1_2 = tmp2; \660} while (0)661662#define BLANK1_ELT(i) do { \663ACC_b(M13_A(M13_N(i), 1), 0) = ACC_b(M13_N(i), 0); \664ACC_b(M13_A(M13_N(i), 1), 1) = ACC_b(M13_N(i), 1); \665ACC_b(M13_A(M13_N(i), 1), 2) = ACC_b(M13_N(i), 2); \666} while (0)667668#endif669670#define NO_TOKEN671672/*673* Perform padding, then blank rounds, then output some words. This is674* the body of sph_radiogatun32_close() and sph_radiogatun64_close().675*/676#define CLOSE_SF(width) CLOSE_GEN(width, \677NO_TOKEN, STATE_READ_SF, BLANK1_SF, BLANK13_SF)678679#if SPH_SMALL_FOOTPRINT_RADIOGATUN680#define CLOSE CLOSE_SF681#else682#define CLOSE(width) CLOSE_GEN(width, \683WT DECL13(b);, STATE_READ, BLANK1, BLANK13)684#endif685686#define CLOSE_GEN(width, WTb13, state_read, blank1, blank13) do { \687unsigned ptr, num; \688unsigned char *out; \689WT DECL19(a); \690WTb13 \691\692ptr = sc->data_ptr; \693sc->data[ptr ++] = 0x01; \694memset(sc->data + ptr, 0, (sizeof sc->data) - ptr); \695radiogatun ## width ## _push13(sc, sc->data, sizeof sc->data); \696\697num = 17; \698for (;;) { \699ptr += 3 * (width >> 3); \700if (ptr > sizeof sc->data) \701break; \702num --; \703} \704\705state_read; \706if (num >= 13) { \707blank13; \708num -= 13; \709} \710while (num -- > 0) \711blank1; \712\713num = 0; \714out = dst; \715for (;;) { \716OUTW(out, a1); \717out += width >> 3; \718OUTW(out, a2); \719out += width >> 3; \720num += 2 * (width >> 3); \721if (num >= 32) \722break; \723blank1; \724} \725INIT; \726} while (0)727728/*729* Initialize context structure.730*/731#if SPH_LITTLE_ENDIAN || SPH_BIG_ENDIAN732733#define INIT do { \734memset(sc->a, 0, sizeof sc->a); \735memset(sc->b, 0, sizeof sc->b); \736sc->data_ptr = 0; \737} while (0)738739#else740741#define INIT do { \742size_t u; \743for (u = 0; u < 19; u ++) \744sc->a[u] = 0; \745for (u = 0; u < 39; u ++) \746sc->b[u] = 0; \747sc->data_ptr = 0; \748} while (0)749750#endif751752/* ======================================================================= */753/*754* RadioGatun[32].755*/756757#if !SPH_NO_RG32758759#undef WT760#define WT sph_u32761#undef T762#define T SPH_T32763#undef ROR764#define ROR(x, n) SPH_T32(((x) << ((32 - (n)) & 31)) | ((x) >> ((n) & 31)))765#undef INW766#define INW(i, j) sph_dec32le_aligned(buf + (4 * (3 * (i) + (j))))767#undef OUTW768#define OUTW(b, v) sph_enc32le(b, v)769770/*771* Insert data by big chunks of 13*12 = 156 bytes. Returned value is the772* number of remaining bytes (between 0 and 155). This method assumes that773* the input data is suitably aligned.774*/775static size_t776radiogatun32_push13(sph_radiogatun32_context *sc, const void *data, size_t len)777{778PUSH13;779}780781/* see sph_radiogatun.h */782void783sph_radiogatun32_init(void *cc)784{785sph_radiogatun32_context *sc;786787sc = cc;788INIT;789}790791#ifdef SPH_UPTR792static void793radiogatun32_short(void *cc, const void *data, size_t len)794#else795/* see sph_radiogatun.h */796void797sph_radiogatun32(void *cc, const void *data, size_t len)798#endif799{800sph_radiogatun32_context *sc;801unsigned ptr;802803sc = cc;804ptr = sc->data_ptr;805while (len > 0) {806size_t clen;807808clen = (sizeof sc->data) - ptr;809if (clen > len)810clen = len;811memcpy(sc->data + ptr, data, clen);812data = (const unsigned char *)data + clen;813len -= clen;814ptr += clen;815if (ptr == sizeof sc->data) {816radiogatun32_push13(sc, sc->data, sizeof sc->data);817ptr = 0;818}819}820sc->data_ptr = ptr;821}822823#ifdef SPH_UPTR824/* see sph_radiogatun.h */825void826sph_radiogatun32(void *cc, const void *data, size_t len)827{828sph_radiogatun32_context *sc;829unsigned ptr;830size_t rlen;831832if (len < (2 * sizeof sc->data)) {833radiogatun32_short(cc, data, len);834return;835}836sc = cc;837ptr = sc->data_ptr;838if (ptr > 0) {839unsigned t;840841t = (sizeof sc->data) - ptr;842radiogatun32_short(sc, data, t);843data = (const unsigned char *)data + t;844len -= t;845}846#if !SPH_UNALIGNED847if (((SPH_UPTR)data & 3) != 0) {848radiogatun32_short(sc, data, len);849return;850}851#endif852rlen = radiogatun32_push13(sc, data, len);853memcpy(sc->data, (const unsigned char *)data + len - rlen, rlen);854sc->data_ptr = rlen;855}856#endif857858/* see sph_radiogatun.h */859void860sph_radiogatun32_close(void *cc, void *dst)861{862sph_radiogatun32_context *sc;863864sc = cc;865CLOSE(32);866}867868#endif869870/* ======================================================================= */871/*872* RadioGatun[64]. Compiled only if a 64-bit or more type is available.873*/874875#if SPH_64876877#if !SPH_NO_RG64878879#undef WT880#define WT sph_u64881#undef T882#define T SPH_T64883#undef ROR884#define ROR(x, n) SPH_T64(((x) << ((64 - (n)) & 63)) | ((x) >> ((n) & 63)))885#undef INW886#define INW(i, j) sph_dec64le_aligned(buf + (8 * (3 * (i) + (j))))887#undef OUTW888#define OUTW(b, v) sph_enc64le(b, v)889890/*891* On 32-bit x86, register pressure is such that using the small892* footprint version is a net gain (x2 speed), because that variant893* uses fewer local variables.894*/895#if SPH_I386_MSVC || SPH_I386_GCC || defined __i386__896#undef PUSH13897#define PUSH13 PUSH13_SF898#undef CLOSE899#define CLOSE CLOSE_SF900#endif901902/*903* Insert data by big chunks of 13*24 = 312 bytes. Returned value is the904* number of remaining bytes (between 0 and 311). This method assumes that905* the input data is suitably aligned.906*/907static size_t908radiogatun64_push13(sph_radiogatun64_context *sc, const void *data, size_t len)909{910PUSH13;911}912913/* see sph_radiogatun.h */914void915sph_radiogatun64_init(void *cc)916{917sph_radiogatun64_context *sc;918919sc = cc;920INIT;921}922923#ifdef SPH_UPTR924static void925radiogatun64_short(void *cc, const void *data, size_t len)926#else927/* see sph_radiogatun.h */928void929sph_radiogatun64(void *cc, const void *data, size_t len)930#endif931{932sph_radiogatun64_context *sc;933unsigned ptr;934935sc = cc;936ptr = sc->data_ptr;937while (len > 0) {938size_t clen;939940clen = (sizeof sc->data) - ptr;941if (clen > len)942clen = len;943memcpy(sc->data + ptr, data, clen);944data = (const unsigned char *)data + clen;945len -= clen;946ptr += clen;947if (ptr == sizeof sc->data) {948radiogatun64_push13(sc, sc->data, sizeof sc->data);949ptr = 0;950}951}952sc->data_ptr = ptr;953}954955#ifdef SPH_UPTR956/* see sph_radiogatun.h */957void958sph_radiogatun64(void *cc, const void *data, size_t len)959{960sph_radiogatun64_context *sc;961unsigned ptr;962size_t rlen;963964if (len < (2 * sizeof sc->data)) {965radiogatun64_short(cc, data, len);966return;967}968sc = cc;969ptr = sc->data_ptr;970if (ptr > 0) {971unsigned t;972973t = (sizeof sc->data) - ptr;974radiogatun64_short(sc, data, t);975data = (const unsigned char *)data + t;976len -= t;977}978#if !SPH_UNALIGNED979if (((SPH_UPTR)data & 7) != 0) {980radiogatun64_short(sc, data, len);981return;982}983#endif984rlen = radiogatun64_push13(sc, data, len);985memcpy(sc->data, (const unsigned char *)data + len - rlen, rlen);986sc->data_ptr = rlen;987}988#endif989990/* see sph_radiogatun.h */991void992sph_radiogatun64_close(void *cc, void *dst)993{994sph_radiogatun64_context *sc;995996sc = cc;997CLOSE(64);998}9991000#endif10011002#endif100310041005