I am looking for javascript code for generating a SHA256 with 32 bytes for a given string
this code is suppose to work inside a browser so it should work without any dependencies
so far I found the following function that gives 64 bytes SHA256:
/**
* Secure Hash Algorithm (SHA256)
* http://www.webtoolkit.info/
* Original code by Angel Marin, Paul Johnston
**/
function SHA256(s){
var chrsz = 8;
var hexcase = 0;
function safe_add (x, y) {
var lsw = (x & 0xFFFF) + (y & 0xFFFF);
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 0xFFFF);
}
function S (X, n) { return ( X >>> n ) | (X << (32 - n)); }
function R (X, n) { return ( X >>> n ); }
function Ch(x, y, z) { return ((x & y) ^ ((~x) & z)); }
function Maj(x, y, z) { return ((x & y) ^ (x & z) ^ (y & z)); }
function Sigma0256(x) { return (S(x, 2) ^ S(x, 13) ^ S(x, 22)); }
function Sigma1256(x) { return (S(x, 6) ^ S(x, 11) ^ S(x, 25)); }
function Gamma0256(x) { return (S(x, 7) ^ S(x, 18) ^ R(x, 3)); }
function Gamma1256(x) { return (S(x, 17) ^ S(x, 19) ^ R(x, 10)); }
function core_sha256 (m, l) {
var K = new Array(0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, 0xE49B69C1, 0xEFBE4786, 0xFC19DC6, 0x240CA1CC, 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, 0xC6E00BF3, 0xD5A79147, 0x6CA6351, 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);
var HASH = new Array(0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19);
var W = new Array(64);
var a, b, c, d, e, f, g, h, i, j;
var T1, T2;
m[l >> 5] |= 0x80 << (24 - l % 32);
m[((l + 64 >> 9) << 4) + 15] = l;
for ( var i = 0; i<m.length; i+=16 ) {
a = HASH[0];
b = HASH[1];
c = HASH[2];
d = HASH[3];
e = HASH[4];
f = HASH[5];
g = HASH[6];
h = HASH[7];
for ( var j = 0; j<64; j++) {
if (j < 16) W[j] = m[j + i];
else W[j] = safe_add(safe_add(safe_add(Gamma1256(W[j - 2]), W[j - 7]), Gamma0256(W[j - 15])), W[j - 16]);
T1 = safe_add(safe_add(safe_add(safe_add(h, Sigma1256(e)), Ch(e, f, g)), K[j]), W[j]);
T2 = safe_add(Sigma0256(a), Maj(a, b, c));
h = g;
g = f;
f = e;
e = safe_add(d, T1);
d = c;
c = b;
b = a;
a = safe_add(T1, T2);
}
HASH[0] = safe_add(a, HASH[0]);
HASH[1] = safe_add(b, HASH[1]);
HASH[2] = safe_add(c, HASH[2]);
HASH[3] = safe_add(d, HASH[3]);
HASH[4] = safe_add(e, HASH[4]);
HASH[5] = safe_add(f, HASH[5]);
HASH[6] = safe_add(g, HASH[6]);
HASH[7] = safe_add(h, HASH[7]);
}
return HASH;
}
function str2binb (str) {
var bin = Array();
var mask = (1 << chrsz) - 1;
for(var i = 0; i < str.length * chrsz; i += chrsz) {
bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (24 - i % 32);
}
return bin;
}
function Utf8Encode(string) {
string = string.replace(/\r\n/g,'\n');
var utftext = '';
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
}
else if((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
}
else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
}
function binb2hex (binarray) {
var hex_tab = hexcase ? '0123456789ABCDEF' : '0123456789abcdef';
var str = '';
for(var i = 0; i < binarray.length * 4; i++) {
str += hex_tab.charAt((binarray[i>>2] >> ((3 - i % 4)*8+4)) & 0xF) +
hex_tab.charAt((binarray[i>>2] >> ((3 - i % 4)*8 )) & 0xF);
}
return str;
}
s = Utf8Encode(s);
return binb2hex(core_sha256(str2binb(s), s.length * chrsz));
}
The result you're receiving actually are 32 bytes.
Let's have a look at an example:
console.log(SHA256("test"));
returns:
9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
What we see is a string representation of 32 bytes which results in 64 bytes of individual chars. However a group of two chars is actually one byte, ranging from 0 up to 255 in decimal.
9f (hex) -> 10011111 (binary) -> 159 (decimal)
86 (hex) -> 10000110 (binary) -> 134 (decimal)
and so on.
If you want to store the 64 character sequence as 'real' 32 bytes, you need to convert pairs of two characters to an 8-bit unsigned integer value (0-255) and put those in a JavaScript typed array.
For example ...
let hexString = "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08";
let unsignedIntegers = hexString.match(/[\dA-F]{2}/gi).map(function(s) {
return parseInt(s, 16);
});
let typedArray = new Uint8Array(unsignedIntegers);
console.log(typedArray);
... gives a 32 bytes Uint8Array.
I have what I thought was a pretty simply question. I'm using this code to generate a SHA1 uuid in Golang:
namespace := uuid.Parse("b9cfdb9d-f741-4e1f-89ae-fac6b2a5d740")
sha := uuid.NewSHA1(namespace, []byte("something"))
fmt.Println(sha.String())
Now I want to generate the same UUID in javascript, and I thought it would be as easy as something like this:
var hash = CryptoJS.SHA1("b9cfdb9d-f741-4e1f-89ae-fac6b2a5d740" + "something")
// chomp the hash into a UUID string
However, I'm running into serious issues. It seems that the uuid.Parse function in Golang is running this parsing function that converts the namespace to a 16-byte array, so even though I use the same SHA1 algorithm in Javascript, I'm not getting the same output.
I'v been messing around with doing the same in JS, but I'm stumped.
Any smart crypto people in here that can help me?
Well, that only took me a month.
var SHA1Generator = {
hex_chr: "0123456789abcdef",
hex: function (num) {
var str = "";
for (var j = 7; j >= 0; j--)
str += this.hex_chr.charAt((num >> (j * 4)) & 0x0F);
return str;
},
str2blks_SHA1: function (str) {
var nblk = ((str.length + 8) >> 6) + 1;
var blks = new Array(nblk * 16);
for (var i = 0; i < nblk * 16; i++) blks[i] = 0;
for (i = 0; i < str.length; i++)
blks[i >> 2] |= str.charCodeAt(i) << (24 - (i % 4) * 8);
blks[i >> 2] |= 0x80 << (24 - (i % 4) * 8);
blks[nblk * 16 - 1] = str.length * 8;
return blks;
},
add: function (x, y) {
var lsw = (x & 0xFFFF) + (y & 0xFFFF);
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 0xFFFF);
},
rol: function (num, cnt) {
return (num << cnt) | (num >>> (32 - cnt));
},
ft: function (t, b, c, d) {
if (t < 20) return (b & c) | ((~b) & d);
if (t < 40) return b ^ c ^ d;
if (t < 60) return (b & c) | (b & d) | (c & d);
return b ^ c ^ d;
},
kt: function (t) {
return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 :
(t < 60) ? -1894007588 : -899497514;
},
calcSHA1FromByte: function(byteArr) {
var str = '';
for(var i=0; i<byteArr.length; i++)
str += String.fromCharCode(byteArr[i]);
return this.calcSHA1(str);
},
calcSHA1: function (str) {
if (str != '') {
var x = this.str2blks_SHA1(str);
var w = new Array(80);
var a = 1732584193;
var b = -271733879;
var c = -1732584194;
var d = 271733878;
var e = -1009589776;
for (var i = 0; i < x.length; i += 16) {
var olda = a;
var oldb = b;
var oldc = c;
var oldd = d;
var olde = e;
for (var j = 0; j < 80; j++) {
if (j < 16) w[j] = x[i + j];
else w[j] = this.rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1);
t = this.add(this.add(this.rol(a, 5), this.ft(j, b, c, d)), this.add(this.add(e, w[j]), this.kt(j)));
e = d;
d = c;
c = this.rol(b, 30);
b = a;
a = t;
}
a = this.add(a, olda);
b = this.add(b, oldb);
c = this.add(c, oldc);
d = this.add(d, oldd);
e = this.add(e, olde);
}
return this.hex(a) + this.hex(b) + this.hex(c) + this.hex(d) + this.hex(e);
}
else {
return '';
}
}
};
function stringToByteArray(str) {
var bytes = [];
for (var i = 0; i < str.length; ++i) {
bytes.push(str.charCodeAt(i));
}
return bytes;
}
function uuidToByteArray(hex) {
// If this is a uuid, remove the dashes
hex = hex.replace(/-/g, "");
// convert each hex number into a string representation
// of the byte integer.
var bytes = [];
for(var i = 0; i < hex.length; i += 2) {
bytes.push(parseInt(hex.substring(i, i+2),16));
}
return bytes;
}
function sha1ToUUID5(hash) {
var uuid = hash.substring(0, 8) +
'-' + hash.substring(8, 12) +
// four most significant bits holds version number 5
'-' + ((parseInt(hash.substring(12, 16), 16) & 0x0fff) | 0x5000).toString(16) +
// two most significant bits holds zero and one for variant DCE1.1
'-' + ((parseInt(hash.substring(16, 20), 16) & 0x3fff) | 0x8000).toString(16) +
'-' + hash.substring(20, 32); //12 digits
return uuid;
}
var namespace = "e75a36a9-3323-40dd-a7d1-1c57ad2aa3cd"
var id = "event154"
var namespaceBytes = uuidToByteArray(namespace);
var idBytes = stringToByteArray(id);
var allBytes = namespaceBytes.concat(idBytes);
console.log("ORG 4505612c-c323-5d6f-b5cc-b7f362b9ba55")
console.log("NEW " + sha1ToUUID5(SHA1Generator.calcSHA1FromByte(allBytes)))
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
How to convert the following js to python?
function sha1(str1,raw)
{
var hexcase = 0;
var chrsz = 8;
str1 = utf16to8(str1);
function utf16to8(str)
{
var out, i, len, c;
out = "";
len = str.length;
for(i = 0; i < len; i++)
{
c = str.charCodeAt(i);
if ((c >= 0x0001) && (c <= 0x007F))
{
out += str.charAt(i);
}
else if (c > 0x07FF)
{
out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F));
out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F));
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
}
else
{
out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F));
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
}
}
return out;
}
function hex_sha1(s)
{
return binb2hex(core_sha1(str2binb(s),s.length * chrsz));
}
function str_sha1(s)
{
return binb2str(core_sha1(str2binb(s),s.length * chrsz));
}
function binb2hex(binarray)
{
var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
var str = "";
for(var i = 0; i < binarray.length * 4; i++)
{
str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) +
hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8 )) & 0xF);
}
return str;
}
function binb2str(bin)
{
var str = "";
var mask = (1 << chrsz) - 1;
for(var i = 0; i < bin.length * 32; i += chrsz)
str += String.fromCharCode((bin[i>>5] >>> (32 - chrsz - i%32)) & mask);
return str;
}
function str2binb(str2)
{
var bin = Array();
var mask = (1 << chrsz) - 1;
for(var i = 0; i < str2.length * chrsz; i += chrsz)
bin[i>>5] |= (str2.charCodeAt(i / chrsz) & mask) << (32 - chrsz - i%32);
return bin;
}
function safe_add(x, y)
{
var lsw = (x & 0xFFFF) + (y & 0xFFFF);
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 0xFFFF);
}
function rol(num, cnt)
{
return (num << cnt) | (num >>> (32 - cnt));
}
function sha1_ft(t, b, c, d)
{
if(t < 20)
return (b & c) | ((~b) & d);
if(t < 40)
return b ^ c ^ d;
if(t < 60)
return (b & c) | (b & d) | (c & d);
return b ^ c ^ d;
}
function sha1_kt(t)
{
return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 : (t < 60) ? -1894007588 : -899497514;
}
function core_sha1(x, len)
{
x[len >> 5] |= 0x80 << (24 - len % 32);
x[((len + 64 >> 9) << 4) + 15] = len;
var w = Array(80);
var a = 1732584193;
var b = -271733879;
var c = -1732584194;
var d = 271733878;
var e = -1009589776;
for(var i = 0; i < x.length; i += 16)
{
var olda = a;
var oldb = b;
var oldc = c;
var oldd = d;
var olde = e;
for(var j = 0; j < 80; j++)
{
if(j < 16)
w[j] = x[i + j];
else
w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)), safe_add(safe_add(e, w[j]), sha1_kt(j)));
e = d;
d = c;
c = rol(b, 30);
b = a;
a = t;
}
a = safe_add(a, olda);
b = safe_add(b, oldb);
c = safe_add(c, oldc);
d = safe_add(d, oldd);
e = safe_add(e, olde);
}
return Array(a, b, c, d, e);
}
if (raw == true)
{
return str_sha1(str1);
}
else
{
return hex_sha1(str1);
}
}
The standard library hashlib module includes sha1:
>>> import hashlib
>>> h = hashlib.sha1("lkjlkjlkj")
>>> h.digest()
"N]\x96\xb3:a^6\xa9A}.\x92\xea\xf6\xaa\x19'b{"
>>> h.hexdigest()
'4e5d96b33a615e36a9417d2e92eaf6aa1927627b'
So I need to get a SHA1 hash of a byte array in javascript (Will be array of integer values 0-255), I can't seem to figure out how to achive this.
I need to be able to get the same result as the C# SHA1.ComputeHash function, meaning I input a byte array and get a 20 byte array back representing the resulting checksum.
Does anyone have a way to achieve this?
Thanks!
Use the calcSHA1FromByte function to get the sha1 of a byte array
var SHA1Generator = {
hex_chr: "0123456789abcdef",
hex: function (num) {
var str = "";
for (var j = 7; j >= 0; j--)
str += this.hex_chr.charAt((num >> (j * 4)) & 0x0F);
return str;
},
str2blks_SHA1: function (str) {
var nblk = ((str.length + 8) >> 6) + 1;
var blks = new Array(nblk * 16);
for (var i = 0; i < nblk * 16; i++) blks[i] = 0;
for (i = 0; i < str.length; i++)
blks[i >> 2] |= str.charCodeAt(i) << (24 - (i % 4) * 8);
blks[i >> 2] |= 0x80 << (24 - (i % 4) * 8);
blks[nblk * 16 - 1] = str.length * 8;
return blks;
},
add: function (x, y) {
var lsw = (x & 0xFFFF) + (y & 0xFFFF);
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 0xFFFF);
},
rol: function (num, cnt) {
return (num << cnt) | (num >>> (32 - cnt));
},
ft: function (t, b, c, d) {
if (t < 20) return (b & c) | ((~b) & d);
if (t < 40) return b ^ c ^ d;
if (t < 60) return (b & c) | (b & d) | (c & d);
return b ^ c ^ d;
},
kt: function (t) {
return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 :
(t < 60) ? -1894007588 : -899497514;
},
calcSHA1FromByte: function(byteArr) {
var str = '';
for(var i=0; i<byteArr.length; i++)
str += String.fromCharCode(byteArr[i]);
return this.calcSHA1(str);
},
calcSHA1: function (str) {
if (str != '') {
var x = this.str2blks_SHA1(str);
var w = new Array(80);
var a = 1732584193;
var b = -271733879;
var c = -1732584194;
var d = 271733878;
var e = -1009589776;
for (var i = 0; i < x.length; i += 16) {
var olda = a;
var oldb = b;
var oldc = c;
var oldd = d;
var olde = e;
for (var j = 0; j < 80; j++) {
if (j < 16) w[j] = x[i + j];
else w[j] = this.rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1);
t = this.add(this.add(this.rol(a, 5), this.ft(j, b, c, d)), this.add(this.add(e, w[j]), this.kt(j)));
e = d;
d = c;
c = this.rol(b, 30);
b = a;
a = t;
}
a = this.add(a, olda);
b = this.add(b, oldb);
c = this.add(c, oldc);
d = this.add(d, oldd);
e = this.add(e, olde);
}
return this.hex(a) + this.hex(b) + this.hex(c) + this.hex(d) + this.hex(e);
}
else {
return '';
}
}
};
// your byte array
var byteArr = ['100','101','114'];
var sha1 = SHA1Generator.calcSHA1FromByte(byteArr);
I am wondering if anyone can help me in porting a SHA-512 implemention in Javascript to Actionscript. Since both Javascript and Actionscript share the same origin, I think porting it will be easy for people who are used to Actionscript.
The code for sha512 in javascript can be found here:
http://pajhome.org.uk/crypt/md5/sha512.html
Thank you.
Here is the code ported by me. The code is separated between two files Int64.as and Sha512.as, both of them belong to the com.crypto package.
com/crypto/Int64.as
/*
* Int64 for ActionScript
* Ported by: AAA
* Ported from: See below
*/
/*
* A JavaScript implementation of the Secure Hash Algorithm, SHA-512, as defined
* in FIPS 180-2
* Version 2.2 Copyright Anonymous Contributor, Paul Johnston 2000 - 2009.
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
* Distributed under the BSD License
* See http://pajhome.org.uk/crypt/md5 for details.
*/
package com.crypto {
public class Int64 {
public var h;
public var l;
public function Int64(h, l) {
this.h = h;
this.l = l;
}
public function copy(src) {
this.h = src.h;
this.l = src.l;
}
public function rrot(x, shift) {
this.l = (x.l >>> shift) | (x.h << (32-shift));
this.h = (x.h >>> shift) | (x.l << (32-shift));
}
public function revrrot(x, shift) {
this.l = (x.h >>> shift) | (x.l << (32-shift));
this.h = (x.l >>> shift) | (x.h << (32-shift));
}
public function shr(x, shift) {
this.l = (x.l >>> shift) | (x.h << (32-shift));
this.h = (x.h >>> shift);
}
public function add(x, y) {
var w0 = (x.l & 0xffff) + (y.l & 0xffff);
var w1 = (x.l >>> 16) + (y.l >>> 16) + (w0 >>> 16);
var w2 = (x.h & 0xffff) + (y.h & 0xffff) + (w1 >>> 16);
var w3 = (x.h >>> 16) + (y.h >>> 16) + (w2 >>> 16);
this.l = (w0 & 0xffff) | (w1 << 16);
this.h = (w2 & 0xffff) | (w3 << 16);
}
public function add4(a, b, c, d) {
var w0 = (a.l & 0xffff) + (b.l & 0xffff) + (c.l & 0xffff) + (d.l & 0xffff);
var w1 = (a.l >>> 16) + (b.l >>> 16) + (c.l >>> 16) + (d.l >>> 16) + (w0 >>> 16);
var w2 = (a.h & 0xffff) + (b.h & 0xffff) + (c.h & 0xffff) + (d.h & 0xffff) + (w1 >>> 16);
var w3 = (a.h >>> 16) + (b.h >>> 16) + (c.h >>> 16) + (d.h >>> 16) + (w2 >>> 16);
this.l = (w0 & 0xffff) | (w1 << 16);
this.h = (w2 & 0xffff) | (w3 << 16);
}
public function add5(a, b, c, d, e) {
var w0 = (a.l & 0xffff) + (b.l & 0xffff) + (c.l & 0xffff) + (d.l & 0xffff) + (e.l & 0xffff);
var w1 = (a.l >>> 16) + (b.l >>> 16) + (c.l >>> 16) + (d.l >>> 16) + (e.l >>> 16) + (w0 >>> 16);
var w2 = (a.h & 0xffff) + (b.h & 0xffff) + (c.h & 0xffff) + (d.h & 0xffff) + (e.h & 0xffff) + (w1 >>> 16);
var w3 = (a.h >>> 16) + (b.h >>> 16) + (c.h >>> 16) + (d.h >>> 16) + (e.h >>> 16) + (w2 >>> 16);
this.l = (w0 & 0xffff) | (w1 << 16);
this.h = (w2 & 0xffff) | (w3 << 16);
}
}
}
com/crypto/Sha512.as
/*
* SHA-512 for ActionScript
* Ported by: AAA
* Ported from: See below
*/
/*
* A JavaScript implementation of the Secure Hash Algorithm, SHA-512, as defined
* in FIPS 180-2
* Version 2.2 Copyright Anonymous Contributor, Paul Johnston 2000 - 2009.
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
* Distributed under the BSD License
* See http://pajhome.org.uk/crypt/md5 for details.
*/
package com.crypto {
public class Sha512 {
public var hexcase = 0;
public var b64pad = "";
public function Sha512() {
}
public function hex_sha512(s) { return rstr2hex(rstr_sha512(str2rstr_utf8(s))); }
public function b64_sha512(s) { return rstr2b64(rstr_sha512(str2rstr_utf8(s))); }
public function any_sha512(s, e) { return rstr2any(rstr_sha512(str2rstr_utf8(s)), e);}
public function hex_hmac_sha512(k, d) { return rstr2hex(rstr_hmac_sha512(str2rstr_utf8(k), str2rstr_utf8(d))); }
public function b64_hmac_sha512(k, d) { return rstr2b64(rstr_hmac_sha512(str2rstr_utf8(k), str2rstr_utf8(d))); }
public function any_hmac_sha512(k, d, e) { return rstr2any(rstr_hmac_sha512(str2rstr_utf8(k), str2rstr_utf8(d)), e);}
public function sha512_vm_test() {
return hex_sha512("abc").toLowerCase() == "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a"
+ "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f";
}
private function rstr_sha512(s) {
return binb2rstr(binb_sha512(rstr2binb(s), s.length * 8));
}
private function rstr_hmac_sha512(key, data) {
var bkey = rstr2binb(key);
if(bkey.length > 32) bkey = binb_sha512(bkey, key.length * 8);
var ipad = new Array(32)
var opad = new Array(32);
for(var i = 0; i < 32; i++) {
ipad[i] = bkey[i] ^ 0x36363636;
opad[i] = bkey[i] ^ 0x5C5C5C5C;
}
var hash = binb_sha512(ipad.concat(rstr2binb(data)), 1024 + data.length * 8);
return binb2rstr(binb_sha512(opad.concat(hash), 1024 + 512));
}
private function rstr2hex(input) {
try { hexcase } catch(e) { hexcase=0; }
var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
var output = "";
var x;
for(var i = 0; i < input.length; i++) {
x = input.charCodeAt(i);
output += hex_tab.charAt((x >>> 4) & 0x0F) + hex_tab.charAt(x & 0x0F);
}
return output;
}
private function rstr2b64(input)
{
try { b64pad } catch(e) { b64pad=''; }
var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var output = "";
var len = input.length;
for(var i = 0; i < len; i += 3) {
var triplet = (input.charCodeAt(i) << 16)
| (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0)
| (i + 2 < len ? input.charCodeAt(i+2) : 0);
for(var j = 0; j < 4; j++) {
if(i * 8 + j * 6 > input.length * 8) output += b64pad;
else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F);
}
}
return output;
}
private function rstr2any(input, encoding) {
var divisor = encoding.length;
var i, j, q, x, quotient;
var dividend = new Array(Math.ceil(input.length / 2));
for(i = 0; i < dividend.length; i++) {
dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
}
var full_length = Math.ceil(input.length * 8 / (Math.log(encoding.length) / Math.log(2)));
var remainders = new Array(full_length);
for(j = 0; j < full_length; j++) {
quotient = new Array();
x = 0;
for(i = 0; i < dividend.length; i++) {
x = (x << 16) + dividend[i];
q = Math.floor(x / divisor);
x -= q * divisor;
if(quotient.length > 0 || q > 0)
quotient[quotient.length] = q;
}
remainders[j] = x;
dividend = quotient;
}
var output = "";
for(i = remainders.length - 1; i >= 0; i--)
output += encoding.charAt(remainders[i]);
return output;
}
private function str2rstr_utf8(input) {
var output = "";
var i = -1;
var x, y;
while(++i < input.length) {
x = input.charCodeAt(i);
y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF) {
x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
i++;
}
if(x <= 0x7F)
output += String.fromCharCode(x);
else if(x <= 0x7FF)
output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F), 0x80 | ( x & 0x3F));
else if(x <= 0xFFFF)
output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
0x80 | ((x >>> 6 ) & 0x3F),
0x80 | ( x & 0x3F));
else if(x <= 0x1FFFFF)
output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
0x80 | ((x >>> 12) & 0x3F),
0x80 | ((x >>> 6 ) & 0x3F),
0x80 | ( x & 0x3F));
}
return output;
}
private function str2rstr_utf16le(input) {
var output = "";
for(var i = 0; i < input.length; i++)
output += String.fromCharCode( input.charCodeAt(i) & 0xFF,
(input.charCodeAt(i) >>> 8) & 0xFF);
return output;
}
private function str2rstr_utf16be(input) {
var output = "";
for(var i = 0; i < input.length; i++)
output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF,
input.charCodeAt(i) & 0xFF);
return output;
}
private function rstr2binb(input) {
var output = new Array(input.length >> 2);
for(var i = 0; i < output.length; i++)
output[i] = 0;
for(var i = 0; i < input.length * 8; i += 8)
output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32);
return output;
}
private function binb2rstr(input) {
var output = "";
for(var i = 0; i < input.length * 32; i += 8)
output += String.fromCharCode((input[i>>5] >>> (24 - i % 32)) & 0xFF);
return output;
}
var sha512_k;
private function binb_sha512(x, len) {
if(sha512_k == undefined) {
sha512_k = new Array(
new Int64(0x428a2f98, -685199838), new Int64(0x71374491, 0x23ef65cd),
new Int64(-1245643825, -330482897), new Int64(-373957723, -2121671748),
new Int64(0x3956c25b, -213338824), new Int64(0x59f111f1, -1241133031),
new Int64(-1841331548, -1357295717), new Int64(-1424204075, -630357736),
new Int64(-670586216, -1560083902), new Int64(0x12835b01, 0x45706fbe),
new Int64(0x243185be, 0x4ee4b28c), new Int64(0x550c7dc3, -704662302),
new Int64(0x72be5d74, -226784913), new Int64(-2132889090, 0x3b1696b1),
new Int64(-1680079193, 0x25c71235), new Int64(-1046744716, -815192428),
new Int64(-459576895, -1628353838), new Int64(-272742522, 0x384f25e3),
new Int64(0xfc19dc6, -1953704523), new Int64(0x240ca1cc, 0x77ac9c65),
new Int64(0x2de92c6f, 0x592b0275), new Int64(0x4a7484aa, 0x6ea6e483),
new Int64(0x5cb0a9dc, -1119749164), new Int64(0x76f988da, -2096016459),
new Int64(-1740746414, -295247957), new Int64(-1473132947, 0x2db43210),
new Int64(-1341970488, -1728372417), new Int64(-1084653625, -1091629340),
new Int64(-958395405, 0x3da88fc2), new Int64(-710438585, -1828018395),
new Int64(0x6ca6351, -536640913), new Int64(0x14292967, 0xa0e6e70),
new Int64(0x27b70a85, 0x46d22ffc), new Int64(0x2e1b2138, 0x5c26c926),
new Int64(0x4d2c6dfc, 0x5ac42aed), new Int64(0x53380d13, -1651133473),
new Int64(0x650a7354, -1951439906), new Int64(0x766a0abb, 0x3c77b2a8),
new Int64(-2117940946, 0x47edaee6), new Int64(-1838011259, 0x1482353b),
new Int64(-1564481375, 0x4cf10364), new Int64(-1474664885, -1136513023),
new Int64(-1035236496, -789014639), new Int64(-949202525, 0x654be30),
new Int64(-778901479, -688958952), new Int64(-694614492, 0x5565a910),
new Int64(-200395387, 0x5771202a), new Int64(0x106aa070, 0x32bbd1b8),
new Int64(0x19a4c116, -1194143544), new Int64(0x1e376c08, 0x5141ab53),
new Int64(0x2748774c, -544281703), new Int64(0x34b0bcb5, -509917016),
new Int64(0x391c0cb3, -976659869), new Int64(0x4ed8aa4a, -482243893),
new Int64(0x5b9cca4f, 0x7763e373), new Int64(0x682e6ff3, -692930397),
new Int64(0x748f82ee, 0x5defb2fc), new Int64(0x78a5636f, 0x43172f60),
new Int64(-2067236844, -1578062990), new Int64(-1933114872, 0x1a6439ec),
new Int64(-1866530822, 0x23631e28), new Int64(-1538233109, -561857047),
new Int64(-1090935817, -1295615723), new Int64(-965641998, -479046869),
new Int64(-903397682, -366583396), new Int64(-779700025, 0x21c0c207),
new Int64(-354779690, -840897762), new Int64(-176337025, -294727304),
new Int64(0x6f067aa, 0x72176fba), new Int64(0xa637dc5, -1563912026),
new Int64(0x113f9804, -1090974290), new Int64(0x1b710b35, 0x131c471b),
new Int64(0x28db77f5, 0x23047d84), new Int64(0x32caab7b, 0x40c72493),
new Int64(0x3c9ebe0a, 0x15c9bebc), new Int64(0x431d67c4, -1676669620),
new Int64(0x4cc5d4be, -885112138), new Int64(0x597f299c, -60457430),
new Int64(0x5fcb6fab, 0x3ad6faec), new Int64(0x6c44198c, 0x4a475817));
}
var H = new Array(
new Int64(0x6a09e667, -205731576),
new Int64(-1150833019, -2067093701),
new Int64(0x3c6ef372, -23791573),
new Int64(-1521486534, 0x5f1d36f1),
new Int64(0x510e527f, -1377402159),
new Int64(-1694144372, 0x2b3e6c1f),
new Int64(0x1f83d9ab, -79577749),
new Int64(0x5be0cd19, 0x137e2179));
var T1 = new Int64(0, 0),
T2 = new Int64(0, 0),
a = new Int64(0,0),
b = new Int64(0,0),
c = new Int64(0,0),
d = new Int64(0,0),
e = new Int64(0,0),
f = new Int64(0,0),
g = new Int64(0,0),
h = new Int64(0,0),
s0 = new Int64(0, 0),
s1 = new Int64(0, 0),
Ch = new Int64(0, 0),
Maj = new Int64(0, 0),
r1 = new Int64(0, 0),
r2 = new Int64(0, 0),
r3 = new Int64(0, 0);
var j, i;
var W = new Array(80);
for(i=0; i<80; i++)
W[i] = new Int64(0, 0);
x[len >> 5] |= 0x80 << (24 - (len & 0x1f));
x[((len + 128 >> 10)<< 5) + 31] = len;
for(i = 0; i<x.length; i+=32) {
a.copy(H[0]);
b.copy(H[1]);
c.copy(H[2]);
d.copy(H[3]);
e.copy(H[4]);
f.copy(H[5]);
g.copy(H[6]);
h.copy(H[7]);
for(j=0; j<16; j++) {
W[j].h = x[i + 2*j];
W[j].l = x[i + 2*j + 1];
}
for(j=16; j<80; j++) {
r1.rrot(W[j-2], 19);
r2.revrrot(W[j-2], 29);
r3.shr(W[j-2], 6);
s1.l = r1.l ^ r2.l ^ r3.l;
s1.h = r1.h ^ r2.h ^ r3.h;
r1.rrot(W[j-15], 1);
r2.rrot(W[j-15], 8);
r3.shr(W[j-15], 7);
s0.l = r1.l ^ r2.l ^ r3.l;
s0.h = r1.h ^ r2.h ^ r3.h;
W[j].add4(s1, W[j-7], s0, W[j-16]);
}
for(j = 0; j < 80; j++) {
Ch.l = (e.l & f.l) ^ (~e.l & g.l);
Ch.h = (e.h & f.h) ^ (~e.h & g.h);
r1.rrot(e, 14);
r2.rrot(e, 18);
r3.revrrot(e, 9);
s1.l = r1.l ^ r2.l ^ r3.l;
s1.h = r1.h ^ r2.h ^ r3.h;
r1.rrot(a, 28);
r2.revrrot(a, 2);
r3.revrrot(a, 7);
s0.l = r1.l ^ r2.l ^ r3.l;
s0.h = r1.h ^ r2.h ^ r3.h;
Maj.l = (a.l & b.l) ^ (a.l & c.l) ^ (b.l & c.l);
Maj.h = (a.h & b.h) ^ (a.h & c.h) ^ (b.h & c.h);
T1.add5(h, s1, Ch, sha512_k[j], W[j]);
T2.add(s0, Maj);
h.copy(g);
g.copy(f);
f.copy(e);
e.add(d, T1);
d.copy(c);
c.copy(b);
b.copy(a);
a.add(T1, T2);
}
H[0].add(H[0], a);
H[1].add(H[1], b);
H[2].add(H[2], c);
H[3].add(H[3], d);
H[4].add(H[4], e);
H[5].add(H[5], f);
H[6].add(H[6], g);
H[7].add(H[7], h);
}
var hash = new Array(16);
for(i=0; i<8; i++) {
hash[2*i] = H[i].h;
hash[2*i + 1] = H[i].l;
}
return hash;
}
}
}
Sorry, I could not find a proper place to upload them.
I am not able to post a comment on the above (where this should be), but there is an error with some signatures using this code due to Actionscript's imaginative behaviour when appending the null character to a string (it doesn't).
For a quick and dirty fix to the hex encoded hmac which is what I am using, I changed the hex_hmac_sha512 function (just for the encoding it calls) and added a binb2hex function as follows:
private function hex_hmac_sha512(key, data) {
key = str2rstr_utf8(key);
data = str2rstr_utf8(data);
var bkey = rstr2binb(key);
if(bkey.length > 32) bkey = binb_sha512(bkey, key.length * 8);
var ipad = new Array(32)
var opad = new Array(32);
for(var i = 0; i < 32; i++) {
ipad[i] = bkey[i] ^ 0x36363636;
opad[i] = bkey[i] ^ 0x5C5C5C5C;
}
var hash = binb_sha512(ipad.concat(rstr2binb(data)), 1024 + data.length * 8);
return binb2hex(binb_sha512(opad.concat(hash), 1024 + 512));
}
private function binb2hex(input) {
var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
var output = "";
for(var i = 0; i < input.length * 32; i += 8){
var schar = (input[i>>5] >>> (24 - i % 32)) & 0xFF;
output += hex_tab.charAt((schar >>> 4) & 0x0F) + hex_tab.charAt(schar & 0x0F);
}
return output;
}