Last active
July 8, 2025 21:35
-
-
Save odzhan/8e97006807192c35ad9b138777f537f1 to your computer and use it in GitHub Desktop.
sha256
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef SHA256_H | |
#define SHA256_H | |
#define R(v,n)(((v)>>(n))|((v)<<(32-(n)))) | |
#define F(n)for(i=0;i<n;i++) | |
#ifdef _MSC_VER | |
#include <intrin.h> | |
#define rev32(x) _byteswap_ulong(x) | |
#define rev64(x) _byteswap_uint64(x) | |
#else // GCC/Clang | |
#define rev32(x) __builtin_bswap32(x) | |
#define rev64(x) __builtin_bswap64(x) | |
#endif | |
typedef struct _sha256_ctx { | |
union { | |
uint32_t b[32]; | |
uint32_t w[8]; | |
} s; | |
union { | |
uint8_t b[64]; | |
uint32_t w[16]; | |
uint64_t q[8]; | |
}x; | |
uint32_t len; | |
} sha256_ctx; | |
#ifdef __cplusplus | |
extern "C" { | |
#endif | |
void sha256_init(sha256_ctx *c); | |
void sha256_update(sha256_ctx *c, const void *in, uint32_t len); | |
void sha256_final(void *out, sha256_ctx *c); | |
#ifdef __cplusplus | |
} | |
#endif | |
#endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "sha256.h" | |
#define CH(x,y,z)(((x)&(y))^(~(x)&(z))) | |
#define MAJ(x,y,z)(((x)&(y))^((x)&(z))^((y)&(z))) | |
#define EP0(x)(R(x,2)^R(x,13)^R(x,22)) | |
#define EP1(x)(R(x,6)^R(x,11)^R(x,25)) | |
#define SIG0(x)(R(x,7)^R(x,18)^((x)>>3)) | |
#define SIG1(x)(R(x,17)^R(x,19)^((x)>>10)) | |
void sha256_compress(sha256_ctx *c) { | |
uint32_t t1,t2,i,w[64],x[8]; | |
uint32_t k[64]= | |
{ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, | |
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, | |
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, | |
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, | |
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, | |
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, | |
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, | |
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, | |
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, | |
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, | |
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, | |
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, | |
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, | |
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, | |
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, | |
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 }; | |
// load input in big endian byte order | |
F(16)w[i] = rev32(c->x.w[i]); | |
// expand input | |
for(i=16;i<64;i++) | |
w[i] = SIG1(w[i-2])+w[i-7]+SIG0(w[i-15])+w[i-16]; | |
// load state | |
F(8)x[i] = c->s.w[i]; | |
// permute | |
F(64) { | |
t1 = x[7] + EP1(x[4]) + CH(x[4],x[5],x[6]) + w[i] + k[i]; | |
t2 = EP0(x[0]) + MAJ(x[0],x[1],x[2]); | |
x[7] = x[6],x[6] = x[5],x[5] = x[4],x[4] = x[3] + t1; | |
x[3] = x[2],x[2] = x[1],x[1] = x[0], x[0] = t1 + t2; | |
} | |
// update state | |
F(8)c->s.w[i] += x[i]; | |
} | |
void sha256_init(sha256_ctx *c) { | |
c->s.w[0]=0x6a09e667; | |
c->s.w[1]=0xbb67ae85; | |
c->s.w[2]=0x3c6ef372; | |
c->s.w[3]=0xa54ff53a; | |
c->s.w[4]=0x510e527f; | |
c->s.w[5]=0x9b05688c; | |
c->s.w[6]=0x1f83d9ab; | |
c->s.w[7]=0x5be0cd19; | |
c->len =0; | |
} | |
void sha256_update(sha256_ctx *c,const void *in,uint32_t len) { | |
uint8_t *p=(uint8_t*)in; | |
uint32_t i, idx; | |
// index = len % 64 | |
idx = c->len & 63; | |
// update total length | |
c->len += len; | |
for (i=0;i<len;i++) { | |
// add byte to buffer | |
c->x.b[idx]=p[i]; idx++; | |
// buffer filled? | |
if(idx==64) { | |
// compress it | |
sha256_compress(c); | |
idx=0; | |
} | |
} | |
} | |
void sha256_final(void *out,sha256_ctx *c) { | |
uint32_t i,len,*p=(uint32_t*)out; | |
// get index | |
i = len = c->len & 63; | |
// zero remainder of buffer | |
while(i < 64) c->x.b[i++]=0; | |
// add 1 bit | |
c->x.b[len]=0x80; | |
// exceeds or equals area for total bits? | |
if(len >= 56) { | |
// compress it | |
sha256_compress(c); | |
// zero buffer | |
F(16)c->x.w[i]=0; | |
} | |
// add total length in bits | |
c->x.q[7]=rev64(c->len*8); | |
// compress it | |
sha256_compress(c); | |
// return hash | |
F(8)p[i] = rev32(c->s.w[i]); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment