commit 008571f4bcc038b434134ae783e4059f6f0a15db Author: Chen Yi-Cyuan Date: Sun Jan 5 14:00:53 2014 +0800 create project diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..11b3c13 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,3 @@ +# v0.1.0 / 2014-01-05 + +Initial release diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..dff2ebd --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,20 @@ +Copyright 2014 emn178@gmail.com + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..aede36d --- /dev/null +++ b/README.md @@ -0,0 +1,132 @@ +# js-sha512 +This is a simple SHA-512, SHA-384, SHA-512/224, SHA-512/256 hash functions for JavaScript supports UTF-8 encoding. + +## Install +For node.js, you can use this command to install: + + npm install js-sha512 + +## Usage +If you use node.js, you should require the module first: +```JavaScript +sha512 = require('js-sha512'); +``` +or +```JavaScript +sha512 = require('js-sha512').sha512; +sha384 = require('js-sha512').sha384; +sha512_256 = require('js-sha512').sha512_256; +sha512_224 = require('js-sha512').sha512_224; +``` +And you could use like this: +```JavaScript +sha512('Message to hash'); +sha384('Message to hash'); +sha512_256('Message to hash'); +sha512_224('Message to hash'); +``` +## Example +Code +```JavaScript +sha512(''); +sha512('The quick brown fox jumps over the lazy dog'); +sha512('The quick brown fox jumps over the lazy dog.'); +sha384(''); +sha384('The quick brown fox jumps over the lazy dog'); +sha384('The quick brown fox jumps over the lazy dog.'); +sha512_256(''); +sha512_256('The quick brown fox jumps over the lazy dog'); +sha512_256('The quick brown fox jumps over the lazy dog.'); +sha512_224(''); +sha512_224('The quick brown fox jumps over the lazy dog'); +sha512_224('The quick brown fox jumps over the lazy dog.'); +``` +Output + + cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e + 07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb642e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6 + 91ea1245f20d46ae9a037a989f54f1f790f0a47607eeb8a14d12890cea77a1bbc6c7ed9cf205e67b7f2b8fd4c7dfd3a7a8617e45f3c463d481c7e586c39ac1ed + 38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b + ca737f1014a48f4c0b6dd43cb177b0afd9e5169367544c494011e3317dbf9a509cb1e5dc1e85a941bbee3d7f2afbc9b1 + ed892481d8272ca6df370bf706e4d7bc1b5739fa2177aae6c50e946678718fc67a7af2819a021c2fc34e91bdb63409d7 + c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a + dd9d67b371519c339ed8dbd25af90e976a1eeefd4ad3d889005e532fc5bef04d + 1546741840f8a492b959d9b8b2344b9b0eb51b004bba35c0aebaac86d45264c3 + 6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4 + 944cd2847fb54558d4775db0485a50003111c8e5daa63fe722c6aa37 + 6d6a9279495ec4061769752e7ff9c68b6b0b3c5a281b7917ce0572de + +It also supports UTF-8 encoding: + +Code +```JavaScript +sha512('中文'); +sha384('中文'); +sha512_256('中文'); +sha512_224('中文'); +``` +Output + + 8b88efc2ebbcbdad5ac2d65af05bec57bda25e71fd5fb25bbd892057a2755fbd05d8d8491cb2946febd5b0f124ffdfbaecf7e34946353c4f1b5ab29545895468 + 93422ceb8291a69b22f02dc1114c39a287493ad525dcebc77e4019a44eaee2633a85d0f29cd298ee6799048c33a4be0c + b6dab29c16ec35ab34a5d92ff135b58de96741dda78b1009a2181cf8b45d2f72 + 0f46a0ae7f226517dd66ece0ce1efa29ffb7ced05ac4566fdcaed188 + +## Tests +You can open `tests/index.html` in browser or use node.js to run test + + node tests/node-test.js + +or + + npm test + +## Extensions +### jQuery +If you prefer jQuery style, you can add following code to add a jQuery extension. + +Code +```JavaScript +jQuery.sha512 = sha512 +jQuery.sha384 = sha384 +jQuery.sha512_256 = sha512_256 +jQuery.sha512_224 = sha512_224 +``` +And then you could use like this: +```JavaScript +$.sha512('message'); +$.sha384('message'); +$.sha512_256('message'); +$.sha512_224('message'); +``` +### Prototype +If you prefer prototype style, you can add following code to add a prototype extension. + +Code +```JavaScript +String.prototype.sha512 = function() { + return sha512(this); +}; +String.prototype.sha384 = function() { + return sha384(this); +}; +String.prototype.sha512_256 = function() { + return sha512_256(this); +}; +String.prototype.sha512_224 = function() { + return sha512_224(this); +}; +``` +And then you could use like this: +```JavaScript +'message'.sha512(); +'message'.sha384(); +'message'.sha512_256(); +'message'.sha512_224(); +``` +## License +The project is released under the [MIT license](http://www.opensource.org/licenses/MIT). + +## Contact +The project's website is located at https://github.com/emn178/js-sha512 +Author: emn178@gmail.com diff --git a/build/sha512.min.js b/build/sha512.min.js new file mode 100644 index 0000000..faa5603 --- /dev/null +++ b/build/sha512.min.js @@ -0,0 +1,13 @@ +(function(m,K){var a=function(a,h){this.high=a|0;this.low=h|0},z="0123456789abcdef".split(""),E={0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,a:10,b:11,c:12,d:13,e:14,f:15,A:10,B:11,C:12,D:13,E:14,F:15},J=[new a(1116352408,3609767458),new a(1899447441,602891725),new a(3049323471,3964484399),new a(3921009573,2173295548),new a(961987163,4081628472),new a(1508970993,3053834265),new a(2453635748,2937671579),new a(2870763221,3664609560),new a(3624381080,2734883394),new a(310598401,1164996542),new a(607225278, +1323610764),new a(1426881987,3590304994),new a(1925078388,4068182383),new a(2162078206,991336113),new a(2614888103,633803317),new a(3248222580,3479774868),new a(3835390401,2666613458),new a(4022224774,944711139),new a(264347078,2341262773),new a(604807628,2007800933),new a(770255983,1495990901),new a(1249150122,1856431235),new a(1555081692,3175218132),new a(1996064986,2198950837),new a(2554220882,3999719339),new a(2821834349,766784016),new a(2952996808,2566594879),new a(3210313671,3203337956),new a(3336571891, +1034457026),new a(3584528711,2466948901),new a(113926993,3758326383),new a(338241895,168717936),new a(666307205,1188179964),new a(773529912,1546045734),new a(1294757372,1522805485),new a(1396182291,2643833823),new a(1695183700,2343527390),new a(1986661051,1014477480),new a(2177026350,1206759142),new a(2456956037,344077627),new a(2730485921,1290863460),new a(2820302411,3158454273),new a(3259730800,3505952657),new a(3345764771,106217008),new a(3516065817,3606008344),new a(3600352804,1432725776),new a(4094571909, +1467031594),new a(275423344,851169720),new a(430227734,3100823752),new a(506948616,1363258195),new a(659060556,3750685593),new a(883997877,3785050280),new a(958139571,3318307427),new a(1322822218,3812723403),new a(1537002063,2003034995),new a(1747873779,3602036899),new a(1955562222,1575990012),new a(2024104815,1125592928),new a(2227730452,2716904306),new a(2361852424,442776044),new a(2428436474,593698344),new a(2756734187,3733110249),new a(3204031479,2999351573),new a(3329325298,3815920427),new a(3391569614, +3928383900),new a(3515267271,566280711),new a(3940187606,3454069534),new a(4118630271,4000239992),new a(116418474,1914138554),new a(174292421,2731055270),new a(289380356,3203993006),new a(460393269,320620315),new a(685471733,587496836),new a(852142971,1086792851),new a(1017036298,365543100),new a(1126000580,2618297676),new a(1288033470,3409855158),new a(1501505948,4234509866),new a(1607167915,987167468),new a(1816402316,1246189591)],k=function(a){return q(a,512)},F=function(a){return q(a,384)},G= +function(a){return q(a,256)},H=function(a){return q(a,224)},q=function(b,h){var f;a:{for(f=b.length;f--;)if(255>2]=37==n?f[c>>2]|(E[e.charAt(++d)]<<4|E[e.charAt(++d)])<<(3-c%4<<3):f[c>>2]|n<<(3-c%4<<3);++c}e=(c+16>>7)+1<<5;d=c>>2;f[d]|=128<<(3-c%4<<3);for(d+=1;d>1]=new a(f[d],f[d+1]);f=c}else{e=b.length;f=(e+16>> +7)+1<<5;d=[];for(c=0;c>2]|=b.charCodeAt(c)<<(3-c%4<<3);d[c>>2]|=128<<(3-c%4<<3);d[f-1]=e<<3;e=[];for(c=0;c>1]=new a(d[c],d[c+1]);f=e}if(512==h)var l=new a(1779033703,4089235720),k=new a(3144134277,2227873595),s=new a(1013904242,4271175723),t=new a(2773480762,1595750129),u=new a(1359893119,2917565137),v=new a(2600822924,725511199),w=new a(528734635,4215389547),x=new a(1541459225,327033209);else 384==h?(l=new a(3418070365,3238371032),k=new a(1654270250, +914150663),s=new a(2438529370,812702999),t=new a(355462360,4144912697),u=new a(1731405415,4290775857),v=new a(2394180231,1750603025),w=new a(3675008525,1694076839),x=new a(1203062813,3204075428)):256==h?(l=new a(573645204,4230739756),k=new a(2673172387,3360449730),s=new a(596883563,1867755857),t=new a(2520282905,1497426621),u=new a(2519219938,2827943907),v=new a(3193839141,1401305490),w=new a(721525244,746961066),x=new a(246885852,2177182882)):224==h&&(l=new a(2352822216,424955298),k=new a(1944164710, +2312950998),s=new a(502970286,855612546),t=new a(1738396948,1479516111),u=new a(258812777,2077511080),v=new a(2011393907,79989058),w=new a(1067287976,1780299464),x=new a(286451373,2446758561));d=0;for(c=f.length;dg;++g)e[g]=f[d+g];for(g=16;80>g;++g)y=e[g-15].rightRotate(1).xor(e[g-15].rightRotate(8)).xor(e[g-15].shiftRightUnsigned(7)),p=e[g-2].rightRotate(19).xor(e[g-2].rightRotate(61)).xor(e[g-2].shiftRightUnsigned(6)),e[g]=e[g-16].add(y).add(e[g-7]).add(p);for(var n= +l,m=k,A=s,q=t,r=u,B=v,C=w,D=x,z,g=0;80>g;++g)y=n.rightRotate(28).xor(n.rightRotate(34)).xor(n.rightRotate(39)),p=n.and(m).xor(n.and(A)).xor(m.and(A)),y=y.add(p),p=r.rightRotate(14).xor(r.rightRotate(18)).xor(r.rightRotate(41)),z=r.and(B).xor(r.not().and(C)),p=D.add(p).add(z).add(J[g]).add(e[g]),D=C,C=B,B=r,r=q.add(p),q=A,A=m,m=n,n=p.add(y);l=l.add(n);k=k.add(m);s=s.add(A);t=t.add(q);u=u.add(r);v=v.add(B);w=w.add(C);x=x.add(D)}l=l.toHexString()+k.toHexString()+s.toHexString()+t.toHexString();if(224== +h)return l.substr(0,l.length-8);384<=h&&(l+=u.toHexString()+v.toHexString());512==h&&(l+=w.toHexString()+x.toHexString());return l},I=function(a){for(var h="",f=0;4>f;f++)var e=3-f<<3,h=h+(z[a>>e+4&15]+z[a>>e&15]);return h};a.prototype.and=function(b){return new a(this.high&b.high,this.low&b.low)};a.prototype.xor=function(b){return new a(this.high^b.high,this.low^b.low)};a.prototype.not=function(){return new a(~this.high,~this.low)};a.prototype.shiftRightUnsigned=function(b){b&=63;return 0==b?new a(this.high, +this.low):32>b?new a(this.high>>>b,this.low>>>b|this.high<<32-b):32==b?new a(0,this.high):new a(0,this.high>>>b-32)};a.prototype.rightRotate=function(b){b&=63;return 0==b?new a(this.high,this.low):32>b?new a(this.high>>>b|this.low<<32-b,this.low>>>b|this.high<<32-b):32==b?new a(this.low,this.high):new a(this.low>>>b-32|this.high<<64-b,this.high>>>b-32|this.low<<64-b)};a.prototype.add=function(b){var h=(this.low&65535)+(b.low&65535),f=(this.low>>>16)+(b.low>>>16)+(h>>>16),e=(this.high&65535)+(b.high& +65535)+(f>>>16);return new a((this.high>>>16)+(b.high>>>16)+(e>>>16)<<16|e&65535,f<<16|h&65535)};a.prototype.toHexString=function(){return I(this.high)+I(this.low)};"undefined"!=typeof module?(k.sha512=k,k.sha384=F,k.sha512_256=G,k.sha512_224=H,module.exports=k):m&&(m.sha512=k,m.sha384=F,m.sha512_256=G,m.sha512_224=H)})(this); diff --git a/package.json b/package.json new file mode 100644 index 0000000..bcc78b1 --- /dev/null +++ b/package.json @@ -0,0 +1,31 @@ +{ + "name": "js-sha512", + "version": "0.1.0", + "description": "This is a simple SHA-512, SHA-384, SHA-512/224, SHA-512/256 hash functions for JavaScript supports UTF-8 encoding.", + "main": "src/sha512.js", + "scripts": { + "test": "node tests/node-test.js" + }, + "repository": { + "type": "git", + "url": "https://github.com/emn178/js-sha512.git" + }, + "keywords": [ + "sha", + "sha2", + "sha384", + "sha512", + "sha512/224", + "sha512/256", + "hash", + "encryption", + "cryptography", + "HMAC" + ], + "license": "MIT", + "author": "emn178 ", + "homepage": "https://github.com/emn178/js-sha512", + "bugs": { + "url": "https://github.com/emn178/js-sha512/issues" + } +} diff --git a/src/sha512.js b/src/sha512.js new file mode 100644 index 0000000..b60b095 --- /dev/null +++ b/src/sha512.js @@ -0,0 +1,328 @@ +/* + * js-sha512 v0.1.0 + * https://github.com/emn178/js-sha512 + * + * Copyright 2014, emn178@gmail.com + * + * Licensed under the MIT license: + * http://www.opensource.org/licenses/MIT + */ + +(function(root, undefined){ + 'use strict'; + + // Class Long + var Long = function(high, low){ + this.high = high | 0; + this.low = low | 0; + }; + + var HEX_CHARS = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f']; + var HEX_TABLE = { + '0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9, + 'a': 10, 'b': 11, 'c': 12, 'd': 13, 'e': 14, 'f': 15, + 'A': 10, 'B': 11, 'C': 12, 'D': 13, 'E': 14, 'F': 15 + }; + + var K =[new Long(0x428A2F98, 0xD728AE22), new Long(0x71374491, 0x23EF65CD), + new Long(0xB5C0FBCF, 0xEC4D3B2F), new Long(0xE9B5DBA5, 0x8189DBBC), + new Long(0x3956C25B, 0xF348B538), new Long(0x59F111F1, 0xB605D019), + new Long(0x923F82A4, 0xAF194F9B), new Long(0xAB1C5ED5, 0xDA6D8118), + new Long(0xD807AA98, 0xA3030242), new Long(0x12835B01, 0x45706FBE), + new Long(0x243185BE, 0x4EE4B28C), new Long(0x550C7DC3, 0xD5FFB4E2), + new Long(0x72BE5D74, 0xF27B896F), new Long(0x80DEB1FE, 0x3B1696B1), + new Long(0x9BDC06A7, 0x25C71235), new Long(0xC19BF174, 0xCF692694), + new Long(0xE49B69C1, 0x9EF14AD2), new Long(0xEFBE4786, 0x384F25E3), + new Long(0x0FC19DC6, 0x8B8CD5B5), new Long(0x240CA1CC, 0x77AC9C65), + new Long(0x2DE92C6F, 0x592B0275), new Long(0x4A7484AA, 0x6EA6E483), + new Long(0x5CB0A9DC, 0xBD41FBD4), new Long(0x76F988DA, 0x831153B5), + new Long(0x983E5152, 0xEE66DFAB), new Long(0xA831C66D, 0x2DB43210), + new Long(0xB00327C8, 0x98FB213F), new Long(0xBF597FC7, 0xBEEF0EE4), + new Long(0xC6E00BF3, 0x3DA88FC2), new Long(0xD5A79147, 0x930AA725), + new Long(0x06CA6351, 0xE003826F), new Long(0x14292967, 0x0A0E6E70), + new Long(0x27B70A85, 0x46D22FFC), new Long(0x2E1B2138, 0x5C26C926), + new Long(0x4D2C6DFC, 0x5AC42AED), new Long(0x53380D13, 0x9D95B3DF), + new Long(0x650A7354, 0x8BAF63DE), new Long(0x766A0ABB, 0x3C77B2A8), + new Long(0x81C2C92E, 0x47EDAEE6), new Long(0x92722C85, 0x1482353B), + new Long(0xA2BFE8A1, 0x4CF10364), new Long(0xA81A664B, 0xBC423001), + new Long(0xC24B8B70, 0xD0F89791), new Long(0xC76C51A3, 0x0654BE30), + new Long(0xD192E819, 0xD6EF5218), new Long(0xD6990624, 0x5565A910), + new Long(0xF40E3585, 0x5771202A), new Long(0x106AA070, 0x32BBD1B8), + new Long(0x19A4C116, 0xB8D2D0C8), new Long(0x1E376C08, 0x5141AB53), + new Long(0x2748774C, 0xDF8EEB99), new Long(0x34B0BCB5, 0xE19B48A8), + new Long(0x391C0CB3, 0xC5C95A63), new Long(0x4ED8AA4A, 0xE3418ACB), + new Long(0x5B9CCA4F, 0x7763E373), new Long(0x682E6FF3, 0xD6B2B8A3), + new Long(0x748F82EE, 0x5DEFB2FC), new Long(0x78A5636F, 0x43172F60), + new Long(0x84C87814, 0xA1F0AB72), new Long(0x8CC70208, 0x1A6439EC), + new Long(0x90BEFFFA, 0x23631E28), new Long(0xA4506CEB, 0xDE82BDE9), + new Long(0xBEF9A3F7, 0xB2C67915), new Long(0xC67178F2, 0xE372532B), + new Long(0xCA273ECE, 0xEA26619C), new Long(0xD186B8C7, 0x21C0C207), + new Long(0xEADA7DD6, 0xCDE0EB1E), new Long(0xF57D4F7F, 0xEE6ED178), + new Long(0x06F067AA, 0x72176FBA), new Long(0x0A637DC5, 0xA2C898A6), + new Long(0x113F9804, 0xBEF90DAE), new Long(0x1B710B35, 0x131C471B), + new Long(0x28DB77F5, 0x23047D84), new Long(0x32CAAB7B, 0x40C72493), + new Long(0x3C9EBE0A, 0x15C9BEBC), new Long(0x431D67C4, 0x9C100D4C), + new Long(0x4CC5D4BE, 0xCB3E42B6), new Long(0x597F299C, 0xFC657E2A), + new Long(0x5FCB6FAB, 0x3AD6FAEC), new Long(0x6C44198C, 0x4A475817)]; + + var sha512 = function(message) { + return sha2(message, 512); + }; + + var sha384 = function(message) { + return sha2(message, 384); + }; + + var sha512_256 = function(message) { + return sha2(message, 256); + }; + + var sha512_224 = function(message) { + return sha2(message, 224); + }; + + var sha2 = function(message, tbit) { + var blocks = hasUTF8(message) ? UTF8toBlocks(message) : ASCIItoBlocks(message); + + if(tbit == 512) + { + var h0 = new Long(0x6A09E667, 0xF3BCC908); + var h1 = new Long(0xBB67AE85, 0x84CAA73B); + var h2 = new Long(0x3C6EF372, 0xFE94F82B); + var h3 = new Long(0xA54FF53A, 0x5F1D36F1); + var h4 = new Long(0x510E527F, 0xADE682D1); + var h5 = new Long(0x9B05688C, 0x2B3E6C1F); + var h6 = new Long(0x1F83D9AB, 0xFB41BD6B); + var h7 = new Long(0x5BE0CD19, 0x137E2179); + } + else if(tbit == 384) + { + var h0 = new Long(0xCBBB9D5D, 0xC1059ED8); + var h1 = new Long(0x629A292A, 0x367CD507); + var h2 = new Long(0x9159015A, 0x3070DD17); + var h3 = new Long(0x152FECD8, 0xF70E5939); + var h4 = new Long(0x67332667, 0xFFC00B31); + var h5 = new Long(0x8EB44A87, 0x68581511); + var h6 = new Long(0xDB0C2E0D, 0x64F98FA7); + var h7 = new Long(0x47B5481D, 0xBEFA4FA4); + } + else if(tbit == 256) + { + var h0 = new Long(0x22312194, 0xFC2BF72C); + var h1 = new Long(0x9F555FA3, 0xC84C64C2); + var h2 = new Long(0x2393B86B, 0x6F53B151); + var h3 = new Long(0x96387719, 0x5940EABD); + var h4 = new Long(0x96283EE2, 0xA88EFFE3); + var h5 = new Long(0xBE5E1E25, 0x53863992); + var h6 = new Long(0x2B0199FC, 0x2C85B8AA); + var h7 = new Long(0x0EB72DDC, 0x81C52CA2); + } + else if(tbit == 224) + { + var h0 = new Long(0x8C3D37C8, 0x19544DA2); + var h1 = new Long(0x73E19966, 0x89DCD4D6); + var h2 = new Long(0x1DFAB7AE, 0x32FF9C82); + var h3 = new Long(0x679DD514, 0x582F9FCF); + var h4 = new Long(0x0F6D2B69, 0x7BD44DA8); + var h5 = new Long(0x77E36F73, 0x04C48942); + var h6 = new Long(0x3F9D85A8, 0x6A1D36C8); + var h7 = new Long(0x1112E6AD, 0x91D692A1); + } + + for(var i = 0, length = blocks.length;i < length;i += 16) + { + var w = [], s0, s1; + for(var j = 0;j < 16;++j) + w[j] = blocks[i + j]; + for(var j = 16;j < 80;++j) + { + s0 = w[j - 15].rightRotate(1).xor(w[j - 15].rightRotate(8)).xor(w[j - 15].shiftRightUnsigned(7)); + s1 = w[j - 2].rightRotate(19).xor(w[j - 2].rightRotate(61)).xor(w[j - 2].shiftRightUnsigned(6)); + w[j] = w[j - 16].add(s0).add(w[j - 7]).add(s1); + } + + var a = h0; + var b = h1; + var c = h2; + var d = h3; + var e = h4; + var f = h5; + var g = h6; + var h = h7; + var maj, t1, t2, ch; + + for(var j = 0;j < 80;++j) + { + s0 = a.rightRotate(28).xor(a.rightRotate(34)).xor(a.rightRotate(39)); + maj = a.and(b).xor(a.and(c)).xor(b.and(c)); + t2 = s0.add(maj); + s1 = e.rightRotate(14).xor(e.rightRotate(18)).xor(e.rightRotate(41)); + ch = e.and(f).xor(e.not().and(g)); + t1 = h.add(s1).add(ch).add(K[j]).add(w[j]); + + h = g; + g = f; + f = e; + e = d.add(t1); + d = c; + c = b; + b = a; + a = t1.add(t2); + } + + h0 = h0.add(a); + h1 = h1.add(b); + h2 = h2.add(c); + h3 = h3.add(d); + h4 = h4.add(e); + h5 = h5.add(f); + h6 = h6.add(g); + h7 = h7.add(h); + } + + var hex = h0.toHexString() + h1.toHexString() + h2.toHexString() + h3.toHexString(); + if(tbit == 224) + return hex.substr(0, hex.length - 8); + if(tbit >= 384) + hex += h4.toHexString() + h5.toHexString(); + if(tbit == 512) + hex += h6.toHexString() + h7.toHexString(); + return hex; + }; + + var hasUTF8 = function(message) { + var i = message.length; + while(i--) + if(message.charCodeAt(i) > 255) + return true; + return false; + }; + + var ASCIItoBlocks = function(message) { + // a block is 32 bits(4 bytes), a chunk is 1024 bits(128 bytes) + var length = message.length; + var chunkCount = ((length + 16) >> 7) + 1; + var blockCount = chunkCount << 5; // chunkCount * 32 + var blocks = []; + var i; + for(i = 0;i < blockCount;++i) + blocks[i] = 0; + for(i = 0;i < length;++i) + blocks[i >> 2] |= message.charCodeAt(i) << (3 - (i % 4) << 3); + blocks[i >> 2] |= 0x80 << (3 - (i % 4) << 3); + blocks[blockCount - 1] = length << 3; // length * 8 + var blocks64 = []; + for(i = 0;i < blockCount;i += 2) + blocks64[i >> 1] = new Long(blocks[i], blocks[i + 1]); + return blocks64; + }; + + var UTF8toBlocks = function(message) { + var uri = encodeURIComponent(message); + var blocks = []; + for(var i = 0, bytes = 0, length = uri.length;i < length;++i) + { + var c = uri.charCodeAt(i); + if(c == 37) // % + blocks[bytes >> 2] |= ((HEX_TABLE[uri.charAt(++i)] << 4) | HEX_TABLE[uri.charAt(++i)]) << (3 - (bytes % 4) << 3); + else + blocks[bytes >> 2] |= c << (3 - (bytes % 4) << 3); + ++bytes; + } + var chunkCount = ((bytes + 16) >> 7) + 1; + var blockCount = chunkCount << 5; // chunkCount * 32 + var index = bytes >> 2; + blocks[index] |= 0x80 << (3 - (bytes % 4) << 3); + for(var i = index + 1;i < blockCount;++i) + blocks[i] = 0; + blocks[blockCount - 1] = bytes << 3; // bytes * 8 + var blocks64 = []; + for(i = 0;i < blockCount;i += 2) + blocks64[i >> 1] = new Long(blocks[i], blocks[i + 1]); + return blocks64; + }; + + var toHexString = function(num) { + var hex = ""; + for(var i = 0; i < 4; i++) + { + var offset = 3 - i << 3; + hex += HEX_CHARS[(num >> (offset + 4)) & 0x0F] + HEX_CHARS[(num >> offset) & 0x0F]; + } + return hex; + }; + + Long.prototype.and = function(other){ + return new Long(this.high & other.high, this.low & other.low); + }; + + Long.prototype.xor = function(other){ + return new Long(this.high ^ other.high, this.low ^ other.low); + }; + + Long.prototype.not = function(){ + return new Long(~this.high, ~this.low); + }; + + Long.prototype.shiftRightUnsigned = function(numBits){ + numBits &= 63; + if(numBits == 0) + return new Long(this.high, this.low); + if(numBits < 32) + return new Long(this.high >>> numBits, (this.low >>> numBits) | (this.high << (32 - numBits))); + else if(numBits == 32) + return new Long(0, this.high); + else + return new Long(0, this.high >>> (numBits - 32)); + }; + + Long.prototype.rightRotate = function(numBits){ + numBits &= 63; + if(numBits == 0) + return new Long(this.high, this.low); + if(numBits < 32) + return new Long((this.high >>> numBits) | (this.low << (32 - numBits)), (this.low >>> numBits) | (this.high << (32 - numBits))); + else if(numBits == 32) + return new Long(this.low, this.high); + else + return new Long((this.low >>> (numBits - 32)) | (this.high << (64 - numBits)), (this.high >>> (numBits - 32)) | (this.low << (64 - numBits))); + }; + + Long.prototype.add = function(other){ + var a1 = this.low & 0xFFFF; + var a2 = this.low >>> 16; + var a3 = this.high & 0xFFFF; + var a4 = this.high >>> 16; + + var b1 = other.low & 0xFFFF; + var b2 = other.low >>> 16; + var b3 = other.high & 0xFFFF; + var b4 = other.high >>> 16; + + var c1 = a1 + b1; + var c2 = a2 + b2 + (c1 >>> 16); + var c3 = a3 + b3 + (c2 >>> 16); + var c4 = a4 + b4 + (c3 >>> 16); + return new Long((c4 << 16) | (c3 & 0xFFFF), (c2 << 16) | (c1 & 0xFFFF)); + }; + + Long.prototype.toHexString = function() { + return toHexString(this.high) + toHexString(this.low); + }; + + if(typeof(module) != 'undefined') + { + sha512.sha512 = sha512; + sha512.sha384 = sha384; + sha512.sha512_256 = sha512_256; + sha512.sha512_224 = sha512_224; + module.exports = sha512; + } + else if(root) + { + root.sha512 = sha512; + root.sha384 = sha384; + root.sha512_256 = sha512_256; + root.sha512_224 = sha512_224; + } +}(this)); diff --git a/tests/debug.js b/tests/debug.js new file mode 100644 index 0000000..23900bf --- /dev/null +++ b/tests/debug.js @@ -0,0 +1,12 @@ +(function(root) { + var assert = function (title, expect, actual) { + if(expect == actual) + console.log(title + ': true'); + else + console.log(title + ': false', 'Except:' + expect, 'Actual: ' + actual); + }; + if(typeof(module) != 'undefined') + global.assert = assert; + else if(root) + root.assert = assert; +})(this); diff --git a/tests/index.html b/tests/index.html new file mode 100644 index 0000000..c56c649 --- /dev/null +++ b/tests/index.html @@ -0,0 +1,12 @@ + + + + + SHA512 + + + + + + + diff --git a/tests/node-test.js b/tests/node-test.js new file mode 100644 index 0000000..80cffbd --- /dev/null +++ b/tests/node-test.js @@ -0,0 +1,9 @@ +// this also works: +// sha512 = require('../src/sha512.js'); + +sha512 = require('../src/sha512.js').sha512; +sha384 = require('../src/sha512.js').sha384; +sha512_256 = require('../src/sha512.js').sha512_256; +sha512_224 = require('../src/sha512.js').sha512_224; +require('./debug.js'); +require('./test.js'); diff --git a/tests/test.js b/tests/test.js new file mode 100644 index 0000000..9b121d5 --- /dev/null +++ b/tests/test.js @@ -0,0 +1,12 @@ +assert('sha512 1', 'cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e', sha512('')); +assert('sha512 2', '07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb642e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6', sha512('The quick brown fox jumps over the lazy dog')); +assert('sha512 3', '91ea1245f20d46ae9a037a989f54f1f790f0a47607eeb8a14d12890cea77a1bbc6c7ed9cf205e67b7f2b8fd4c7dfd3a7a8617e45f3c463d481c7e586c39ac1ed', sha512('The quick brown fox jumps over the lazy dog.')); +assert('sha384 1', '38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b', sha384('')); +assert('sha384 2', 'ca737f1014a48f4c0b6dd43cb177b0afd9e5169367544c494011e3317dbf9a509cb1e5dc1e85a941bbee3d7f2afbc9b1', sha384('The quick brown fox jumps over the lazy dog')); +assert('sha384 3', 'ed892481d8272ca6df370bf706e4d7bc1b5739fa2177aae6c50e946678718fc67a7af2819a021c2fc34e91bdb63409d7', sha384('The quick brown fox jumps over the lazy dog.')); +assert('sha512/256 1', 'c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a', sha512_256('')); +assert('sha512/256 2', 'dd9d67b371519c339ed8dbd25af90e976a1eeefd4ad3d889005e532fc5bef04d', sha512_256('The quick brown fox jumps over the lazy dog')); +assert('sha512/256 3', '1546741840f8a492b959d9b8b2344b9b0eb51b004bba35c0aebaac86d45264c3', sha512_256('The quick brown fox jumps over the lazy dog.')); +assert('sha512/224 1', '6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4', sha512_224('')); +assert('sha512/224 2', '944cd2847fb54558d4775db0485a50003111c8e5daa63fe722c6aa37', sha512_224('The quick brown fox jumps over the lazy dog')); +assert('sha512/224 3', '6d6a9279495ec4061769752e7ff9c68b6b0b3c5a281b7917ce0572de', sha512_224('The quick brown fox jumps over the lazy dog.'));