Last active
March 9, 2019 13:11
-
-
Save ysc3839/fae61e880be9368b5154b42ce4d2d879 to your computer and use it in GitHub Desktop.
This file contains 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
// https://github.com/B-Con/crypto-algorithms/blob/master/sha256.c | |
const SHA256_BLOCK_SIZE = 32 | |
class sha256_ctx | |
{ | |
constructor() | |
{ | |
data = array(64, 0); | |
datalen = 0; | |
bitlen = 0; | |
state = [ | |
0x6a09e667, | |
0xbb67ae85, | |
0x3c6ef372, | |
0xa54ff53a, | |
0x510e527f, | |
0x9b05688c, | |
0x1f83d9ab, | |
0x5be0cd19 | |
]; | |
} | |
function ROTLEFT(a,b) { return (((a) << (b)) | ((a) >>> (32-(b)))); } | |
function ROTRIGHT(a,b) { return (((a) >>> (b)) | ((a) << (32-(b)))); } | |
function CH(x,y,z) { return (((x) & (y)) ^ (~(x) & (z))); } | |
function MAJ(x,y,z) { return (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))); } | |
function EP0(x) { return (ROTRIGHT(x,2) ^ ROTRIGHT(x,13) ^ ROTRIGHT(x,22)); } | |
function EP1(x) { return (ROTRIGHT(x,6) ^ ROTRIGHT(x,11) ^ ROTRIGHT(x,25)); } | |
function SIG0(x) { return (ROTRIGHT(x,7) ^ ROTRIGHT(x,18) ^ ((x) >>> 3)); } | |
function SIG1(x) { return (ROTRIGHT(x,17) ^ ROTRIGHT(x,19) ^ ((x) >>> 10)); } | |
function _transform() | |
{ | |
local a, b, c, d, e, f, g, h, i, j, t1, t2, m = array(64, 0); | |
for (i = 0, j = 0; i < 16; ++i, j += 4) | |
m[i] = (data[j] << 24) | (data[j + 1] << 16) | (data[j + 2] << 8) | (data[j + 3]); | |
for ( ; i < 64; ++i) | |
m[i] = (SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16]) & 0xFFFFFFFF; | |
a = state[0]; | |
b = state[1]; | |
c = state[2]; | |
d = state[3]; | |
e = state[4]; | |
f = state[5]; | |
g = state[6]; | |
h = state[7]; | |
for (i = 0; i < 64; ++i) { | |
t1 = h + EP1(e) + CH(e,f,g) + k[i] + m[i]; | |
t2 = EP0(a) + MAJ(a,b,c); | |
h = g; | |
g = f; | |
f = e; | |
e = (d + t1) & 0xFFFFFFFF; | |
d = c; | |
c = b; | |
b = a; | |
a = (t1 + t2) & 0xFFFFFFFF; | |
} | |
state[0] += a & 0xFFFFFFFF; | |
state[1] += b & 0xFFFFFFFF; | |
state[2] += c & 0xFFFFFFFF; | |
state[3] += d & 0xFFFFFFFF; | |
state[4] += e & 0xFFFFFFFF; | |
state[5] += f & 0xFFFFFFFF; | |
state[6] += g & 0xFFFFFFFF; | |
state[7] += h & 0xFFFFFFFF; | |
} | |
function update(_data) | |
{ | |
for (local i = 0; i < _data.len(); ++i) { | |
data[datalen] = _data[i]; | |
datalen++; | |
if (datalen == 64) { | |
_transform(); | |
bitlen += 512; | |
datalen = 0; | |
} | |
} | |
} | |
function final() | |
{ | |
local i = datalen; | |
// Pad whatever data is left in the buffer. | |
if (datalen < 56) { | |
data[i++] = 0x80; | |
while (i < 56) | |
data[i++] = 0x00; | |
} else { | |
data[i++] = 0x80; | |
while (i < 64) | |
data[i++] = 0x00; | |
_transform(); | |
//memset(ctx->data, 0, 56); | |
for (local j = 0; j < 56; ++j) | |
data[j] = 0; | |
} | |
// Append to the padding the total message's length in bits and transform. | |
bitlen += datalen * 8; | |
data[63] = bitlen; | |
data[62] = bitlen >>> 8; | |
data[61] = bitlen >>> 16; | |
data[60] = bitlen >>> 24; | |
if (_intsize_ >= 8) { | |
data[59] = bitlen >>> 32; | |
data[58] = bitlen >>> 40; | |
data[57] = bitlen >>> 48; | |
data[56] = bitlen >>> 56; | |
} else { | |
data[59] = 0; | |
data[58] = 0; | |
data[57] = 0; | |
data[56] = 0; | |
} | |
_transform(); | |
local hash = array(SHA256_BLOCK_SIZE); | |
// Since this implementation uses little endian byte ordering and SHA uses big endian, | |
// reverse all the bytes when copying the final state to the output hash. | |
for (i = 0; i < 4; ++i) { | |
hash[i] = (state[0] >>> (24 - i * 8)) & 0x000000ff; | |
hash[i + 4] = (state[1] >>> (24 - i * 8)) & 0x000000ff; | |
hash[i + 8] = (state[2] >>> (24 - i * 8)) & 0x000000ff; | |
hash[i + 12] = (state[3] >>> (24 - i * 8)) & 0x000000ff; | |
hash[i + 16] = (state[4] >>> (24 - i * 8)) & 0x000000ff; | |
hash[i + 20] = (state[5] >>> (24 - i * 8)) & 0x000000ff; | |
hash[i + 24] = (state[6] >>> (24 - i * 8)) & 0x000000ff; | |
hash[i + 28] = (state[7] >>> (24 - i * 8)) & 0x000000ff; | |
} | |
return hash; | |
} | |
data = null; | |
datalen = null; | |
bitlen = null; | |
state = null; | |
static k = [ | |
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 | |
]; | |
}; | |
function sha256(data) | |
{ | |
local ctx = sha256_ctx(); | |
ctx.update(data); | |
return ctx.final(); | |
} |
This file contains 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
dofile("sha256.nut"); | |
local data = "a"; | |
print(format("sha256(\"%s\")=", data)); | |
local hash = sha256(data); | |
for (local i = 0; i < hash.len(); ++i) | |
print(format("%02x", hash[i])); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment