From 6dd00e11439ff129826f413dcb6818e4b1301be7 Mon Sep 17 00:00:00 2001
From: Benjamin Auder <benjamin.auder@somewhere>
Date: Tue, 23 Jan 2018 01:15:25 +0100
Subject: [PATCH] First commit

---
 README.md |   7 +++
 sha1.js   | 126 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 133 insertions(+)
 create mode 100644 README.md
 create mode 100644 sha1.js

diff --git a/README.md b/README.md
new file mode 100644
index 0000000..97d6a30
--- /dev/null
+++ b/README.md
@@ -0,0 +1,7 @@
+# sha1.js
+
+Just a few lines of javascript code to compute the Sha-1 sum, which
+I often use to validate some secret string on a website.
+
+It's actually limited to "not-too-long" messages: as far as you don't
+hash a big file everything should be fine.
diff --git a/sha1.js b/sha1.js
new file mode 100644
index 0000000..cc352d0
--- /dev/null
+++ b/sha1.js
@@ -0,0 +1,126 @@
+var Sha1 = {};  // SHA-1 namespace
+
+// SHA-1 algorithm as described at http://en.wikipedia.org/wiki/SHA-1
+// The implementation follows http://fr.wikipedia.org/wiki/Sp%C3%A9cifications_SHA-1 (in french).
+// SHA-1 implementation of Chris Veness 2002-2010 [www.movable-type.co.uk] helped a lot for debugging,
+// and for hacks like toHexStr(). See his script at http://www.movable-type.co.uk/scripts/sha1.html
+Sha1.Compute = function(subject)
+{
+	var i, j, tmp, redIndex, a, b, c, d, e;
+
+	// 1) pretreatment
+
+	// note: no check on message length, since the 2^64 boundary is 
+	// a lot longer than what would be allowed by HTML/PHP
+
+	// add trailing '1' bit (+ 0's padding) to string
+	subject += String.fromCharCode(0x80);
+
+	// add 8 for two last reserved words to store message length
+	// 8 = 2 x 4, one 32-bits word is 4 characters (bytes) length.
+	var L = subject.length + 8;
+
+	// initialize 512-bits blocks representing the message, each containing 16 32-bits words.
+	// NOTE: one char is 8 bits, so one block in the initial string is 64 chars.
+	var countBlocks = Math.ceil(L / 64);
+	var blocks = new Array(countBlocks);
+	for (i=0; i<countBlocks; i++)
+	{
+		var words = new Array(16);
+		for (j=0; j<16; j++)
+		{
+			tmp = subject.substr(64 * i + 4 * j, 4);
+			// note: running off the end of msg is ok because bitwise ops on NaN return 0
+			words[j] = (1 << 24) * tmp.charCodeAt(0) | (1 << 16) * tmp.charCodeAt(1) | (1 << 8) * tmp.charCodeAt(2) | tmp.charCodeAt(3);
+		}
+		blocks[i] = words;
+	}
+
+	// note: 'subject' in our context will never be of length >= 2^32.
+	// therefore we don't need to fill before-last block.
+	blocks[countBlocks-1][15] = (subject.length-1) * 8;
+
+	// initialize parts of the final hash
+	var h0 = 0x67452301;
+	var h1 = 0xefcdab89;
+	var h2 = 0x98badcfe;
+	var h3 = 0x10325476;
+	var h4 = 0xc3d2e1f0;
+
+	// initialize constants array
+	var k = [0x5a827999,0x6ed9eba1,0x8f1bbcdc,0xca62c1d6];
+
+	// 2) computations
+
+	for (i=0; i<blocks.length; i++)
+	{
+		// initialize w array
+		var w = new Array(80);
+		for (j=0; j<16; j++) w[j] = blocks[i][j];
+		for (j=16; j<80; j++)
+		{
+			w[j] = Sha1.LeftRotate(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
+		}
+
+		// initialize a,b,c,d,e variables
+		a = h0;
+		b = h1;
+		c = h2;
+		d = h3;
+		e = h4;
+
+		// iterations over a,b,c,d,e
+		for (j=0; j<80; j++)
+		{
+			// note: '& 0xffffffff' == 'modulo 2^32'.
+			redIndex = Math.floor(j/20);
+			tmp = (Sha1.LeftRotate(a, 5) + Sha1.BitOp(b, c, d, redIndex) + e + k[redIndex] + w[j]) & 0xffffffff;
+			e = d;
+			d = c;
+			c = Sha1.LeftRotate(b, 30);
+			b = a;
+			a = tmp;
+		}
+
+		// update intermediate hash values
+		h0 = (h0+a) & 0xffffffff;
+		h1 = (h1+b) & 0xffffffff;
+		h2 = (h2+c) & 0xffffffff;
+		h3 = (h3+d) & 0xffffffff;
+		h4 = (h4+e) & 0xffffffff;
+	}
+
+	return Sha1.ToHexStr(h0)+Sha1.ToHexStr(h1)+Sha1.ToHexStr(h2)+Sha1.ToHexStr(h3)+Sha1.ToHexStr(h4);
+}
+
+// auxiliary functions.
+Sha1.BitOp = function(x, y, z, t)
+{
+	if (t == 0) return (x & y) ^ (~x & z);
+	if (t == 1) return x ^ y ^ z;
+	if (t == 2) return (x & y) ^ (x & z) ^ (y & z);
+	if (t == 3) return x ^ y ^ z;
+}
+
+// left rotation (within 32 bits).
+Sha1.LeftRotate = function(x, n)
+{
+	return (x << n) | (x >>> (32 - n));
+}
+
+// [copy-pasted from Chris Veness implementation]
+// Hexadecimal representation of a number 
+// (note toString(16) is implementation-dependant, and  
+// in IE returns signed numbers when used on full words)
+Sha1.ToHexStr = function(x)
+{
+	var s="";
+	for (var i=7; i>=0; i--)
+	{
+		var v = (x >>> (i*4)) & 0xf;
+		s += v.toString(16);
+	}
+	return s;
+}
+
+try { module.exports = Sha1; } catch (err) { }
-- 
2.44.0