Last active
December 15, 2015 23:39
-
-
Save atsjj/5341658 to your computer and use it in GitHub Desktop.
Wanted to try writing my own SHA256 class in CoffeeScript. Needed to warm back up after a long weekend, where I didn't touch a computer. Didn't get too far today, spent most of my time reading the spec...
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
# So far, this is being based off of http://www.movable-type.co.uk/scripts/sha256.html | |
# http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf | |
class SHA2 | |
# §5.3, *Setting the Initial Hash Value* | |
# §5.3.3, *SHA-256* | |
H = [ | |
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 | |
] | |
# §4.2.2, *SHA-224 and SHA-256 Constants* | |
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 | |
] | |
M = null | |
W = null | |
constructor: (mS = "") -> | |
# §5, *PREPROCESSING* | |
# §5.1, *Padding the Message* | |
# §5.1.1, *SHA-1, SHA-224 and SHA-256* | |
mS += String.fromCharCode 0x80 | |
parse: -> | |
# §5.2, *Parsing the Message* | |
# §5.2.1, *SHA-1, SHA-224 and SHA-256* | |
l = mS.length / 4 + 2 | |
n = Math.ceil l / 16 | |
@M = new Array n | |
for i in [0..n - 1] | |
b = new ArrayBuffer 64 | |
@M[i] = new Uint32Array b | |
for j in [0..15] | |
@M[i][j] = | |
mS.charCodeAt(i * 64 + j * 4) << 24 | | |
mS.charCodeAt(i * 64 + j * 4 + 1) << 16 | | |
mS.charCodeAt(i * 64 + j * 4 + 2) << 8 | | |
mS.charCodeAt(i * 64 + j * 4 + 3) | |
@M[n - 1][14] = ((mS.length - 1) * 8) / Math.pow 2, 32 | |
@M[n - 1][14] = Math.floor @M[n - 1][14] | |
@M[n - 1][15] = ((mS.length - 1) * 8) & 0xffffffff | |
hash: -> | |
# 6.2.2, *Hash Computation* | |
# 64, 32-bit words (4 bytes * 8 bits) = 2048 | |
b = new ArrayBuffer 256 | |
@W = new Uint32Array b | |
for n in [0..@M.length - 1] | |
@W[t] = @M[n][t] for t in [0..15] | |
for t in [16..63] | |
@W[t] = (@sigma1(@W[t-2]) + @W[t-7] + @sigma0(@W[t-15]) + @W[t-16]) & 0xffffffff | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
My next goal is to rewrite the parse method. I'd like to move it entirely to typed arrays if possible. This is becoming an exercise in learning to work with bits and bitwise operators.
I've been flipping between the spec on nist.gov and also using the impl available on http://www.movable-type.co.uk/scripts/sha256.html. I felt that I should give credit where it's due, since it's been a help to reference a finished product. A longer term goal is to document and explain what each bitwise operation is doing in the doc.