|  | 
|  | 1 | +// Sourced from https://github.com/XKCP/XKCP/blob/e774b9606029ab79dd787252841816a3c60ef8fe/Standalone/CompactFIPS202/C/Keccak-more-compact.c | 
|  | 2 | +#define FOR(i,n) for(i=0; i<n; ++i) | 
|  | 3 | +typedef unsigned char u8; | 
|  | 4 | +typedef unsigned long long int u64; | 
|  | 5 | +typedef unsigned int ui; | 
|  | 6 | + | 
|  | 7 | +void Keccak(ui r, ui c, const u8 *in, u64 inLen, u8 sfx, u8 *out, u64 outLen); | 
|  | 8 | +void FIPS202_SHAKE128(const u8 *in, u64 inLen, u8 *out, u64 outLen) { Keccak(1344, 256, in, inLen, 0x1F, out, outLen); } | 
|  | 9 | +void FIPS202_SHAKE256(const u8 *in, u64 inLen, u8 *out, u64 outLen) { Keccak(1088, 512, in, inLen, 0x1F, out, outLen); } | 
|  | 10 | +void FIPS202_SHA3_224(const u8 *in, u64 inLen, u8 *out) { Keccak(1152, 448, in, inLen, 0x06, out, 28); } | 
|  | 11 | +void FIPS202_SHA3_256(const u8 *in, u64 inLen, u8 *out) { Keccak(1088, 512, in, inLen, 0x06, out, 32); } | 
|  | 12 | +void FIPS202_SHA3_384(const u8 *in, u64 inLen, u8 *out) { Keccak(832, 768, in, inLen, 0x06, out, 48); } | 
|  | 13 | +void FIPS202_SHA3_512(const u8 *in, u64 inLen, u8 *out) { Keccak(576, 1024, in, inLen, 0x06, out, 64); } | 
|  | 14 | + | 
|  | 15 | +int LFSR86540(u8 *R) { (*R)=((*R)<<1)^(((*R)&0x80)?0x71:0); return ((*R)&2)>>1; } | 
|  | 16 | +#define ROL(a,o) ((((u64)a)<<o)^(((u64)a)>>(64-o))) | 
|  | 17 | +static u64 load64(const u8 *x) { ui i; u64 u=0; FOR(i,8) { u<<=8; u|=x[7-i]; } return u; } | 
|  | 18 | +static void store64(u8 *x, u64 u) { ui i; FOR(i,8) { x[i]=u; u>>=8; } } | 
|  | 19 | +static void xor64(u8 *x, u64 u) { ui i; FOR(i,8) { x[i]^=u; u>>=8; } } | 
|  | 20 | +#define rL(x,y) load64((u8*)s+8*(x+5*y)) | 
|  | 21 | +#define wL(x,y,l) store64((u8*)s+8*(x+5*y),l) | 
|  | 22 | +#define XL(x,y,l) xor64((u8*)s+8*(x+5*y),l) | 
|  | 23 | +void KeccakF1600(void *s) | 
|  | 24 | +{ | 
|  | 25 | +    ui r,x,y,i,j,Y; u8 R=0x01; u64 C[5],D; | 
|  | 26 | +    for(i=0; i<24; i++) { | 
|  | 27 | +        /*θ*/ FOR(x,5) C[x]=rL(x,0)^rL(x,1)^rL(x,2)^rL(x,3)^rL(x,4); FOR(x,5) { D=C[(x+4)%5]^ROL(C[(x+1)%5],1); FOR(y,5) XL(x,y,D); } | 
|  | 28 | +        /*ρπ*/ x=1; y=r=0; D=rL(x,y); FOR(j,24) { r+=j+1; Y=(2*x+3*y)%5; x=y; y=Y; C[0]=rL(x,y); wL(x,y,ROL(D,r%64)); D=C[0]; } | 
|  | 29 | +        /*χ*/ FOR(y,5) { FOR(x,5) C[x]=rL(x,y); FOR(x,5) wL(x,y,C[x]^((~C[(x+1)%5])&C[(x+2)%5])); } | 
|  | 30 | +        /*ι*/ FOR(j,7) if (LFSR86540(&R)) XL(0,0,(u64)1<<((1<<j)-1)); | 
|  | 31 | +    } | 
|  | 32 | +} | 
|  | 33 | +void Keccak(ui r, ui c, const u8 *in, u64 inLen, u8 sfx, u8 *out, u64 outLen) | 
|  | 34 | +{ | 
|  | 35 | +    /*initialize*/ u8 s[200]; ui R=r/8; ui i,b=0; FOR(i,200) s[i]=0; | 
|  | 36 | +    /*absorb*/ while(inLen>0) { b=(inLen<R)?inLen:R; FOR(i,b) s[i]^=in[i]; in+=b; inLen-=b; if (b==R) { KeccakF1600(s); b=0; } } | 
|  | 37 | +    /*pad*/ s[b]^=sfx; if((sfx&0x80)&&(b==(R-1))) KeccakF1600(s); s[R-1]^=0x80; KeccakF1600(s); | 
|  | 38 | +    /*squeeze*/ while(outLen>0) { b=(outLen<R)?outLen:R; FOR(i,b) out[i]=s[i]; out+=b; outLen-=b; if(outLen>0) KeccakF1600(s); } | 
|  | 39 | +} | 
0 commit comments