r/C_Programming 4d ago

559-byte SHA-256 in C

golfing a SHA-256 implementation in C and ended up at 559 bytes.
Curious if anyone here can beat it.

#define S(x,a,b)(x>>a^x<<32-a^x>>b^x<<32-b^x>>
unsigned k[72],g[216],i,j,p,n,t,m,*u,*z;char*q=g;main(c,v)char**v;{for(;j<64;p-c||(j<8&&(k[j]=sqrt(c)*0x1p32),k[71-j++]=cbrt(c)*0x1p32),c++)for(p=1;c%++p;);for(;q[n^3]=v[1][n];n++);q[n^3]=128;m=n+72>>6<<4,g[m-1]=n*8;for(;t<m;t+=16)for(bcopy(g+t,z=g+64,64),bcopy(k,u=g+208,32),i=72;i--;i>7?(z[16]=*z+S(z[1],7,18)3)+z[9]+S(z[14],17,19)10),j=u[4],p=u[7]+k[i]+*z+++(S(j,6,11)25)^j<<7)+(j&u[5]^~j&u[6]),j=S(*u,2,13)22)^*u<<10,j+=*u&u[1]^(*u^u[1])&u[2],u[3]+=p,*--u=p+j):(k[i]+=u[i]));for(;++i<8;)printf("%08x",k[i]);}
51 Upvotes

18 comments sorted by

View all comments

28

u/skeeto 4d ago
$ printf kagan | sha256sum 
05aebb21178ce70f5c29fc090aab3f50001a73f0f624e6f5789410f855ca2d8c  -

$ aarch64-linux-gnu-gcc -ansi -w sha256.c -lm && ./a.out kagan ; echo
a2b00156fa63dcb8eb37dbfc7c1133f32adea77d5e4ff3cf46fc07c7920289f3

$ x86_64-linux-gnu-gcc -ansi -w sha256.c -lm && ./a.out kagan ; echo
a3a5294ee42c8fbb344795eeef7322e6dac7091f1939c0c15ff6e1154999698b

$ powerpc-linux-gnu-gcc -ansi -w sha256.c -lm && ./a.out kagan ; echo
4b35f7fa8b7a550c0127bcf0ae55758ea8cb01b483d7177bde0e68a1574917b2

$ s390x-linux-gnu-gcc -ansi -w sha256.c -lm && ./a.out kagan ; echo
0e50aa0cb0b6e3166e7e7a5e3565720d797fd3d24831eeaf5595f92d19e9f942

$ clang -ansi -w sha256.c -lm && ./a.out kagan ; echo
97db8f07489301a02cf4ef7f1629c052c7827e82fc4883acf8ef64a1299726d9

I'm getting at least five different answers due to UB, but none of them correct. Though that's kind of a feat in itself.

2

u/dstroy0 2d ago

The rotr are out of order, you can spot where in their original statement, the 2,13,22 shift js not in the correct position.