Skip to content

Instantly share code, notes, and snippets.

@dchest
Last active August 29, 2015 14:02
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 dchest/c4c35be6e75ae87f635a to your computer and use it in GitHub Desktop.
Save dchest/c4c35be6e75ae87f635a to your computer and use it in GitHub Desktop.
<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