webmcp
diff libraries/moonhash/moonhash_sha3.c @ 499:b36e366bba2b
Added SHA-3 hashing functions (using compact Keccak code)
author | jbe |
---|---|
date | Sun Aug 13 03:22:48 2017 +0200 (2017-08-13) |
parents | |
children | 5e6dbaa3e219 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/libraries/moonhash/moonhash_sha3.c Sun Aug 13 03:22:48 2017 +0200 1.3 @@ -0,0 +1,47 @@ 1.4 +/* This file is derived from "Keccak-more-compact.c", which has been downloaded from <https://github.com/gvanas/KeccakCodePackage/blob/10856bc1922a1ee2c4d2822a88b9ef8fb5059932/Standalone/CompactFIPS202/Keccak-more-compact.c>. The original file "Keccak-more-compact.c" has, according to <https://github.com/gvanas/KeccakCodePackage/blob/10856bc1922a1ee2c4d2822a88b9ef8fb5059932/README.markdown>, been put into the public domain. */ 1.5 + 1.6 +#include <stdint.h> 1.7 +#include <sys/endian.h> 1.8 + 1.9 +#define FOR(i,n) for(i=0; i<n; ++i) 1.10 +typedef uint8_t u8; 1.11 +typedef uint64_t u64; 1.12 +typedef unsigned int ui; 1.13 + 1.14 +static void Keccak(ui r, ui c, const u8 *in, u64 inLen, u8 sfx, u8 *out, u64 outLen); 1.15 +void FIPS202_SHAKE128(const u8 *in, u64 inLen, u8 *out, u64 outLen) { Keccak(1344, 256, in, inLen, 0x1F, out, outLen); } 1.16 +void FIPS202_SHAKE256(const u8 *in, u64 inLen, u8 *out, u64 outLen) { Keccak(1088, 512, in, inLen, 0x1F, out, outLen); } 1.17 +void FIPS202_SHA3_224(const u8 *in, u64 inLen, u8 *out) { Keccak(1152, 448, in, inLen, 0x06, out, 28); } 1.18 +void FIPS202_SHA3_256(const u8 *in, u64 inLen, u8 *out) { Keccak(1088, 512, in, inLen, 0x06, out, 32); } 1.19 +void FIPS202_SHA3_384(const u8 *in, u64 inLen, u8 *out) { Keccak(832, 768, in, inLen, 0x06, out, 48); } 1.20 +void FIPS202_SHA3_512(const u8 *in, u64 inLen, u8 *out) { Keccak(576, 1024, in, inLen, 0x06, out, 64); } 1.21 + 1.22 +static int LFSR86540(u8 *R) { (*R)=((*R)<<1)^(((*R)&0x80)?0x71:0); return ((*R)&2)>>1; } 1.23 +#define ROL(a,o) ((((u64)a)<<o)^(((u64)a)>>(64-o))) 1.24 +#define load64 le64dec 1.25 +#define store64 le64enc 1.26 +#if _BYTE_ORDER == _LITTLE_ENDIAN 1.27 +static void xor64(u8 *x, u64 u) { *(u64 *)x ^= u; } 1.28 +#else 1.29 +static void xor64(u8 *x, u64 u) { ui i; FOR(i,8) { x[i]^=u; u>>=8; } } 1.30 +#endif 1.31 +#define rL(x,y) load64((u8*)s+8*(x+5*y)) 1.32 +#define wL(x,y,l) store64((u8*)s+8*(x+5*y),l) 1.33 +#define XL(x,y,l) xor64((u8*)s+8*(x+5*y),l) 1.34 +static void KeccakF1600(void *s) 1.35 +{ 1.36 + ui r,x,y,i,j,Y; u8 R=0x01; u64 C[5],D; 1.37 + for(i=0; i<24; i++) { 1.38 + /*θ*/ 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); } 1.39 + /*ρπ*/ 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]; } 1.40 + /*χ*/ 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])); } 1.41 + /*ι*/ FOR(j,7) if (LFSR86540(&R)) XL(0,0,(u64)1<<((1<<j)-1)); 1.42 + } 1.43 +} 1.44 +static void Keccak(ui r, ui c, const u8 *in, u64 inLen, u8 sfx, u8 *out, u64 outLen) 1.45 +{ 1.46 + /*initialize*/ u8 s[200]; ui R=r/8; ui i,b=0; FOR(i,200) s[i]=0; 1.47 + /*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; } } 1.48 + /*pad*/ s[b]^=sfx; if((sfx&0x80)&&(b==(R-1))) KeccakF1600(s); s[R-1]^=0x80; KeccakF1600(s); 1.49 + /*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); } 1.50 +}