Last active
August 29, 2015 14:02
-
-
Save dchest/c4c35be6e75ae87f635a to your computer and use it in GitHub Desktop.
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
<script> | |
// https://github.com/dchest/tweetnacl-js/issues/12 | |
var gf = function() { return [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]; }; | |
var D2 = [61785,9906,39828,60374,45398,33411,5274,224,53552,61171,33010,6542,64743,22239,55772,9222]; | |
function car25519(o) { | |
var c; | |
for (var i = 0; i < 16; i++) { | |
o[i] += 65536; | |
c = Math.floor(o[i] / 65536); | |
//o[(i+1)*(i<15)] += c - 1 + 37 * (c-1) * (i==15); | |
o[(i+1)*(i<15?1:0)] += c - 1 + 37 * (c-1) * (i==15?1:0); | |
o[i] -= (c * 65536); | |
} | |
} | |
function A(o, a, b) { | |
for (var i = 0; i < 16; i++) o[i] = (a[i]|0) + (b[i]|0); | |
} | |
function Z(o, a, b) { | |
for (var i = 0; i < 16; i++) o[i] = (a[i] - b[i])|0; | |
} | |
function M(o, a, b) { | |
var i, j, t = []; | |
for (i = 0; i < 31; i++) t[i] = 0; | |
for (i = 0; i < 16; i++) { | |
for (j = 0; j < 16; j++) { | |
t[i+j] += a[i] * b[j]; | |
} | |
} | |
for (i = 0; i < 15; i++) { | |
t[i] += 38 * t[i+16]; | |
} | |
for (i = 0; i < 16; i++) o[i] = t[i]; | |
car25519(o); | |
car25519(o); | |
} | |
function sel25519(p, q, b) { | |
var t, c = ~(b-1); | |
for (var i = 0; i < 16; i++) { | |
t = c & (p[i] ^ q[i]); | |
p[i] ^= t; | |
q[i] ^= t; | |
} | |
} | |
function cswap(p, q, b) { | |
for (var i = 0; i < 4; i++) { | |
sel25519(p[i], q[i], b); | |
} | |
} | |
function add(p, q) { | |
var a = new gf(), b = new gf(), c = new gf(), | |
d = new gf(), e = new gf(), f = new gf(), | |
g = new gf(), h = new gf(), t = new gf(); | |
Z(a, p[1], p[0]); | |
Z(t, q[1], q[0]); | |
M(a, a, t); | |
A(b, p[0], p[1]); | |
A(t, q[0], q[1]); | |
M(b, b, t); | |
M(c, p[3], q[3]); | |
M(c, c, D2); | |
M(d, p[2], q[2]); | |
A(d, d, d); | |
Z(e, b, a); | |
Z(f, d, c); | |
A(g, d, c); | |
A(h, b, a); | |
M(p[0], e, f); | |
M(p[1], h, g); | |
M(p[2], g, f); | |
M(p[3], e, h); | |
} | |
function bytesEqual(a, b) { | |
var dif = 0; | |
if (a.length !== b.length) return 0; | |
for (var i = 0; i < a.length; i++) { | |
dif |= (a[i] ^ b[i]); | |
} | |
dif = (dif - 1) >>> 31; | |
return (dif & 1); | |
} | |
var s = [198,76,249,123,70,40,177,33,142,50,56,190,85,15,4,208,188,127,58,248,200,223,134,17,90,19,111,53,239,71,221,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]; | |
var p = [ | |
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], | |
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], | |
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], | |
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] | |
]; | |
var q = [ | |
[54554,36645,11616,51542,42930,38181,51040,26924,56412,64982,57905,49316,21502,52590,14035,8553], | |
[26200,26214,26214,26214,26214,26214,26214,26214,26214,26214,26214,26214,26214,26214,26214,26214], | |
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], | |
[56720,42423,35507,28126,21237,30545,40832,8432,58237,25771,20110,26346,30309,55179,24335,59271] | |
]; | |
var expected_p = [ | |
[ | |
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], | |
[4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], | |
[4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], | |
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] | |
], | |
[ | |
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], | |
[1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], | |
[1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], | |
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] | |
], | |
[ | |
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], | |
[0, 0, 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], | |
[0, 0, 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], | |
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] | |
] | |
]; | |
var expected_q = [ | |
[ | |
[21608,15511,46466,9560,40651,21654,7554,42163,29041,63323,35015,659,20475,13753,56143,34212], | |
[39302,39321,39321,39321,39321,39321,39321,39321,39321,39321,39321,39321,39321,39321,39321,39321], | |
[4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], | |
[30386,38623,10958,46970,19413,56645,32257,33730,36340,37551,14905,39849,55701,24109,31807,40477] | |
], | |
[ | |
[31678, 38740, 33340, 22709, 52005, 38558, 33364, 45853, 29092, 23409, 51191, 37768, 64258, 47439, 20277, 42203], | |
[40118, 39321, 39321, 39321, 39321, 39321, 39321, 39321, 39321, 39321, 39321, 39321, 39321, 39321, 39321, 39321], | |
[1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], | |
[51572, 57206, 52886, 31274, 54711, 17739, 477, 49790, 62595, 44941, 14738, 43322, 38299, 11737, 16222, 7548] | |
], | |
[ | |
[49630, 30861, 31702, 38740, 33340, 22709, 52005, 38558, 33364, 45853, 29092, 23409, 51191, 37768, 64258, 47439], | |
[52406, 52428, 40140, 39321, 39321, 39321, 39321, 39321, 39321, 39321, 39321, 39321, 39321, 39321, 39321, 39321], | |
[0, 0, 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], | |
[26612, 24689, 51576, 57206, 52886, 31274, 54711, 17739, 477, 49790, 62595, 44941, 14738, 43322, 38299, 11737] | |
] | |
]; | |
var i, j, limit = 253; | |
for (i = 255; i >= limit; --i) { | |
b = (s[(i/8)|0] >> (i&7)) & 1; | |
cswap(p, q, b); | |
add(q, p); | |
add(p, p); | |
cswap(p, q, b); | |
document.write('check ', i, '<br>'); | |
for (j = 0; j < 4; j++) { | |
if (bytesEqual(expected_p[255-i][j], p[j]) !== 1) { | |
document.write('error p: ', j, '<br>'); | |
} else { | |
document.write('p ',j, ' OK<br>'); | |
} | |
} | |
for (j = 0; j < 4; j++) { | |
if (bytesEqual(expected_q[255-i][j], q[j]) !== 1) { | |
document.write('error q: ', j); | |
} else { | |
document.write('q ', j, ' OK<br>'); | |
} | |
} | |
} | |
</script> | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment