Skip to content

Instantly share code, notes, and snippets.

@atsjj
Last active December 15, 2015 23:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save atsjj/5341658 to your computer and use it in GitHub Desktop.
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...
# 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
@atsjj
Copy link
Author

atsjj commented Apr 9, 2013

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment