-rw-r--r-- 1733 libmceliece-20240513/crypto_xof/shake256/tweet/shake256.c raw
#include "crypto_xof.h" #include "crypto_uint64.h" #define ratebytes 136 #define squeezebytes 136 #define padding 31 // the following is mostly copied from https://twitter.com/tweetfips202 // (by Daniel J. Bernstein, Peter Schwabe, Gilles Van Assche) // except for the following changes in Keccak() function: // * r arg replaced with ratebytes // * d arg replaced with squeezebytes // * p arg replaced with padding // * u64 n arg replaced with long long mlen // * new arg: long long hlen // * final squeeze changed to hlen loop // * arg order: h,hlen,m,mlen // * function name crypto_xof instead of Keccak // and the following change: // * u64 is defined as crypto_uint64 instead of unsigned long long #define FOR(i,n) for (i = 0;i < n;++i) typedef unsigned char u8; typedef crypto_uint64 u64; static u64 ROL(u64 a,u8 n){return(a<<n)|(a>>(64-n));} static u64 L64(const u8*x){u64 r=0,i;FOR(i,8)r|=(u64)x[i]<<8*i;return r;} static void F(u64*s){u8 x,y,j,R=1,r,n;u64 t,B[5],Y;FOR(n,24){FOR(x,5){B[x]=0;FOR(y,5)B[x]^=s[x+5*y];}FOR(x,5){t=B[(x+4)%5]^ROL(B[(x+1)%5],1);FOR(y,5)s[x+5*y]^=t;}t=s[1];y=r=0;x=1;FOR(j,24){r+=j+1;Y=2*x+3*y;x=y;y=Y%5;Y=s[x+5*y];s[x+5*y]=ROL(t,r%64);t=Y;}FOR(y,5){FOR(x,5)B[x]=s[x+5*y];FOR(x,5)s[x+5*y]=B[x]^(~B[(x+1)%5]&B[(x+2)%5]);}FOR(y,7)if((R=(R<<1)^(113*(R>>7)))&2)*s^=1ULL<<((1<<y)-1);}} void crypto_xof(u8 *h,long long hlen,const u8*m,long long mlen){u64 s[25],i;u8 t[200];FOR(i,25)s[i]=0;while(mlen>=ratebytes){FOR(i,ratebytes/8)s[i]^=L64(m+8*i);F(s);mlen-=ratebytes;m+=ratebytes;}FOR(i,ratebytes)t[i]=0;FOR(i,mlen)t[i]=m[i];t[i]=padding;t[ratebytes-1]|=128;FOR(i,ratebytes/8)s[i]^=L64(t+8*i); while(hlen>0){F(s);FOR(i,squeezebytes)if(i<hlen)h[i]=s[i/8]>>8*(i%8);h+=squeezebytes;hlen-=squeezebytes;}}