Last active
March 9, 2019 13:11
-
-
Save ysc3839/187c3bf6f27bcfc1fccd783bc9b717fc 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/sha1.c | |
const SHA1_BLOCK_SIZE = 20 | |
class sha1_ctx | |
{ | |
constructor() | |
{ | |
data = array(64, 0); | |
datalen = 0; | |
bitlen = 0; | |
state = [ | |
0x67452301, | |
0xEFCDAB89, | |
0x98BADCFE, | |
0x10325476, | |
0xc3d2e1f0 | |
]; | |
} | |
function ROTLEFT(a, b) { return ((a << b) | (a >>> (32 - b))); } | |
function _transform() | |
{ | |
local a, b, c, d, e, i, j, t, m = array(80, 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 < 80; ++i) { | |
m[i] = (m[i - 3] ^ m[i - 8] ^ m[i - 14] ^ m[i - 16]) & 0xFFFFFFFF; | |
m[i] = ((m[i] << 1) | (m[i] >>> 31)) & 0xFFFFFFFF; | |
} | |
a = state[0]; | |
b = state[1]; | |
c = state[2]; | |
d = state[3]; | |
e = state[4]; | |
for (i = 0; i < 20; ++i) { | |
t = (ROTLEFT(a, 5) + ((b & c) ^ (~b & d)) + e + k[0] + m[i]) & 0xFFFFFFFF; | |
e = d; | |
d = c; | |
c = ROTLEFT(b, 30); | |
b = a; | |
a = t; | |
} | |
for ( ; i < 40; ++i) { | |
t = (ROTLEFT(a, 5) + (b ^ c ^ d) + e + k[1] + m[i]) & 0xFFFFFFFF; | |
e = d; | |
d = c; | |
c = ROTLEFT(b, 30); | |
b = a; | |
a = t; | |
} | |
for ( ; i < 60; ++i) { | |
t = (ROTLEFT(a, 5) + ((b & c) ^ (b & d) ^ (c & d)) + e + k[2] + m[i]) & 0xFFFFFFFF; | |
e = d; | |
d = c; | |
c = ROTLEFT(b, 30); | |
b = a; | |
a = t; | |
} | |
for ( ; i < 80; ++i) { | |
t = (ROTLEFT(a, 5) + (b ^ c ^ d) + e + k[3] + m[i]) & 0xFFFFFFFF; | |
e = d; | |
d = c; | |
c = ROTLEFT(b, 30); | |
b = a; | |
a = t; | |
} | |
state[0] += a & 0xFFFFFFFF; | |
state[1] += b & 0xFFFFFFFF; | |
state[2] += c & 0xFFFFFFFF; | |
state[3] += d & 0xFFFFFFFF; | |
state[4] += e & 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(SHA1_BLOCK_SIZE); | |
// Since this implementation uses little endian byte ordering and MD 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; | |
} | |
return hash; | |
} | |
data = null; | |
datalen = null; | |
bitlen = null; | |
state = null; | |
static k = [ | |
0x5a827999, | |
0x6ed9eba1, | |
0x8f1bbcdc, | |
0xca62c1d6, | |
]; | |
}; | |
function sha1(data) | |
{ | |
local ctx = sha1_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("sha1.nut"); | |
local data = "abc"; | |
print(format("sha1(\"%s\")=", data)); | |
local hash = sha1(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