Skip to content

Instantly share code, notes, and snippets.

@ysc3839
Last active March 9, 2019 13:11
Show Gist options
  • Save ysc3839/fae61e880be9368b5154b42ce4d2d879 to your computer and use it in GitHub Desktop.
Save ysc3839/fae61e880be9368b5154b42ce4d2d879 to your computer and use it in GitHub Desktop.
// 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();
}
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