This commit is contained in:
DR497 2021-10-15 11:29:21 +08:00
parent 291c8ac874
commit f4bcc857ea
1 changed files with 124 additions and 124 deletions

View File

@ -5,23 +5,22 @@
* Written by Dmitry Chestnykh in 2014. Public domain. * Written by Dmitry Chestnykh in 2014. Public domain.
*/ */
/* jshint newcap: false */ /* jshint newcap: false */
;(function (root, f) { (function (root, f) {
'use strict'
// eslint-disable-next-line @typescript-eslint/no-var-requires // eslint-disable-next-line @typescript-eslint/no-var-requires
if (typeof module !== 'undefined' && module.exports) module.exports = f(require('tweetnacl')) if (typeof module !== 'undefined' && module.exports)
else root.ed2curve = f(root.nacl) module.exports = f(require('tweetnacl'));
else root.ed2curve = f(root.nacl);
})(this, function (nacl) { })(this, function (nacl) {
'use strict' if (!nacl) throw new Error('tweetnacl not loaded');
if (!nacl) throw new Error('tweetnacl not loaded')
// -- Operations copied from TweetNaCl.js. -- // -- Operations copied from TweetNaCl.js. --
var gf = function (init) { var gf = function (init) {
var i, var i,
r = new Float64Array(16) r = new Float64Array(16);
if (init) for (i = 0; i < init.length; i++) r[i] = init[i] if (init) for (i = 0; i < init.length; i++) r[i] = init[i];
return r return r;
} };
var gf0 = gf(), var gf0 = gf(),
gf1 = gf([1]), gf1 = gf([1]),
@ -60,147 +59,148 @@
0x4fc1, 0x4fc1,
0x2480, 0x2480,
0x2b83, 0x2b83,
]) ]);
function car25519(o) { function car25519(o) {
var c var c;
var i var i;
for (i = 0; i < 16; i++) { for (i = 0; i < 16; i++) {
o[i] += 65536 o[i] += 65536;
c = Math.floor(o[i] / 65536) c = Math.floor(o[i] / 65536);
o[(i + 1) * (i < 15 ? 1 : 0)] += c - 1 + 37 * (c - 1) * (i === 15 ? 1 : 0) o[(i + 1) * (i < 15 ? 1 : 0)] +=
o[i] -= c * 65536 c - 1 + 37 * (c - 1) * (i === 15 ? 1 : 0);
o[i] -= c * 65536;
} }
} }
function sel25519(p, q, b) { function sel25519(p, q, b) {
var t, var t,
c = ~(b - 1) c = ~(b - 1);
for (var i = 0; i < 16; i++) { for (var i = 0; i < 16; i++) {
t = c & (p[i] ^ q[i]) t = c & (p[i] ^ q[i]);
p[i] ^= t p[i] ^= t;
q[i] ^= t q[i] ^= t;
} }
} }
function unpack25519(o, n) { function unpack25519(o, n) {
var i var i;
for (i = 0; i < 16; i++) o[i] = n[2 * i] + (n[2 * i + 1] << 8) for (i = 0; i < 16; i++) o[i] = n[2 * i] + (n[2 * i + 1] << 8);
o[15] &= 0x7fff o[15] &= 0x7fff;
} }
// addition // addition
function A(o, a, b) { function A(o, a, b) {
var i var i;
for (i = 0; i < 16; i++) o[i] = (a[i] + b[i]) | 0 for (i = 0; i < 16; i++) o[i] = (a[i] + b[i]) | 0;
} }
// subtraction // subtraction
function Z(o, a, b) { function Z(o, a, b) {
var i var i;
for (i = 0; i < 16; i++) o[i] = (a[i] - b[i]) | 0 for (i = 0; i < 16; i++) o[i] = (a[i] - b[i]) | 0;
} }
// multiplication // multiplication
function M(o, a, b) { function M(o, a, b) {
var i, var i,
j, j,
t = new Float64Array(31) t = new Float64Array(31);
for (i = 0; i < 31; i++) t[i] = 0 for (i = 0; i < 31; i++) t[i] = 0;
for (i = 0; i < 16; i++) { for (i = 0; i < 16; i++) {
for (j = 0; j < 16; j++) { for (j = 0; j < 16; j++) {
t[i + j] += a[i] * b[j] t[i + j] += a[i] * b[j];
} }
} }
for (i = 0; i < 15; i++) { for (i = 0; i < 15; i++) {
t[i] += 38 * t[i + 16] t[i] += 38 * t[i + 16];
} }
for (i = 0; i < 16; i++) o[i] = t[i] for (i = 0; i < 16; i++) o[i] = t[i];
car25519(o) car25519(o);
car25519(o) car25519(o);
} }
// squaring // squaring
function S(o, a) { function S(o, a) {
M(o, a, a) M(o, a, a);
} }
// inversion // inversion
function inv25519(o, i) { function inv25519(o, i) {
var c = gf() var c = gf();
var a var a;
for (a = 0; a < 16; a++) c[a] = i[a] for (a = 0; a < 16; a++) c[a] = i[a];
for (a = 253; a >= 0; a--) { for (a = 253; a >= 0; a--) {
S(c, c) S(c, c);
if (a !== 2 && a !== 4) M(c, c, i) if (a !== 2 && a !== 4) M(c, c, i);
} }
for (a = 0; a < 16; a++) o[a] = c[a] for (a = 0; a < 16; a++) o[a] = c[a];
} }
function pack25519(o, n) { function pack25519(o, n) {
var i, j, b var i, j, b;
var m = gf(), var m = gf(),
t = gf() t = gf();
for (i = 0; i < 16; i++) t[i] = n[i] for (i = 0; i < 16; i++) t[i] = n[i];
car25519(t) car25519(t);
car25519(t) car25519(t);
car25519(t) car25519(t);
for (j = 0; j < 2; j++) { for (j = 0; j < 2; j++) {
m[0] = t[0] - 0xffed m[0] = t[0] - 0xffed;
for (i = 1; i < 15; i++) { for (i = 1; i < 15; i++) {
m[i] = t[i] - 0xffff - ((m[i - 1] >> 16) & 1) m[i] = t[i] - 0xffff - ((m[i - 1] >> 16) & 1);
m[i - 1] &= 0xffff m[i - 1] &= 0xffff;
} }
m[15] = t[15] - 0x7fff - ((m[14] >> 16) & 1) m[15] = t[15] - 0x7fff - ((m[14] >> 16) & 1);
b = (m[15] >> 16) & 1 b = (m[15] >> 16) & 1;
m[14] &= 0xffff m[14] &= 0xffff;
sel25519(t, m, 1 - b) sel25519(t, m, 1 - b);
} }
for (i = 0; i < 16; i++) { for (i = 0; i < 16; i++) {
o[2 * i] = t[i] & 0xff o[2 * i] = t[i] & 0xff;
o[2 * i + 1] = t[i] >> 8 o[2 * i + 1] = t[i] >> 8;
} }
} }
function par25519(a) { function par25519(a) {
var d = new Uint8Array(32) var d = new Uint8Array(32);
pack25519(d, a) pack25519(d, a);
return d[0] & 1 return d[0] & 1;
} }
function vn(x, xi, y, yi, n) { function vn(x, xi, y, yi, n) {
var i, var i,
d = 0 d = 0;
for (i = 0; i < n; i++) d |= x[xi + i] ^ y[yi + i] for (i = 0; i < n; i++) d |= x[xi + i] ^ y[yi + i];
return (1 & ((d - 1) >>> 8)) - 1 return (1 & ((d - 1) >>> 8)) - 1;
} }
function crypto_verify_32(x, xi, y, yi) { function crypto_verify_32(x, xi, y, yi) {
return vn(x, xi, y, yi, 32) return vn(x, xi, y, yi, 32);
} }
function neq25519(a, b) { function neq25519(a, b) {
var c = new Uint8Array(32), var c = new Uint8Array(32),
d = new Uint8Array(32) d = new Uint8Array(32);
pack25519(c, a) pack25519(c, a);
pack25519(d, b) pack25519(d, b);
return crypto_verify_32(c, 0, d, 0) return crypto_verify_32(c, 0, d, 0);
} }
function pow2523(o, i) { function pow2523(o, i) {
var c = gf() var c = gf();
var a var a;
for (a = 0; a < 16; a++) c[a] = i[a] for (a = 0; a < 16; a++) c[a] = i[a];
for (a = 250; a >= 0; a--) { for (a = 250; a >= 0; a--) {
S(c, c) S(c, c);
if (a !== 1) M(c, c, i) if (a !== 1) M(c, c, i);
} }
for (a = 0; a < 16; a++) o[a] = c[a] for (a = 0; a < 16; a++) o[a] = c[a];
} }
function set25519(r, a) { function set25519(r, a) {
var i var i;
for (i = 0; i < 16; i++) r[i] = a[i] | 0 for (i = 0; i < 16; i++) r[i] = a[i] | 0;
} }
function unpackneg(r, p) { function unpackneg(r, p) {
@ -210,39 +210,39 @@
den = gf(), den = gf(),
den2 = gf(), den2 = gf(),
den4 = gf(), den4 = gf(),
den6 = gf() den6 = gf();
set25519(r[2], gf1) set25519(r[2], gf1);
unpack25519(r[1], p) unpack25519(r[1], p);
S(num, r[1]) S(num, r[1]);
M(den, num, D) M(den, num, D);
Z(num, num, r[2]) Z(num, num, r[2]);
A(den, r[2], den) A(den, r[2], den);
S(den2, den) S(den2, den);
S(den4, den2) S(den4, den2);
M(den6, den4, den2) M(den6, den4, den2);
M(t, den6, num) M(t, den6, num);
M(t, t, den) M(t, t, den);
pow2523(t, t) pow2523(t, t);
M(t, t, num) M(t, t, num);
M(t, t, den) M(t, t, den);
M(t, t, den) M(t, t, den);
M(r[0], t, den) M(r[0], t, den);
S(chk, r[0]) S(chk, r[0]);
M(chk, chk, den) M(chk, chk, den);
if (neq25519(chk, num)) M(r[0], r[0], I) if (neq25519(chk, num)) M(r[0], r[0], I);
S(chk, r[0]) S(chk, r[0]);
M(chk, chk, den) M(chk, chk, den);
if (neq25519(chk, num)) return -1 if (neq25519(chk, num)) return -1;
if (par25519(r[0]) === p[31] >> 7) Z(r[0], gf0, r[0]) if (par25519(r[0]) === p[31] >> 7) Z(r[0], gf0, r[0]);
M(r[3], r[0], r[1]) M(r[3], r[0], r[1]);
return 0 return 0;
} }
// ---- // ----
@ -253,47 +253,47 @@
var z = new Uint8Array(32), var z = new Uint8Array(32),
q = [gf(), gf(), gf(), gf()], q = [gf(), gf(), gf(), gf()],
a = gf(), a = gf(),
b = gf() b = gf();
if (unpackneg(q, pk)) return null // reject invalid key if (unpackneg(q, pk)) return null; // reject invalid key
var y = q[1] var y = q[1];
A(a, gf1, y) A(a, gf1, y);
Z(b, gf1, y) Z(b, gf1, y);
inv25519(b, b) inv25519(b, b);
M(a, a, b) M(a, a, b);
pack25519(z, a) pack25519(z, a);
return z return z;
} }
// Converts Ed25519 secret key to Curve25519 secret key. // Converts Ed25519 secret key to Curve25519 secret key.
function convertSecretKey(sk) { function convertSecretKey(sk) {
var d = new Uint8Array(64), var d = new Uint8Array(64),
o = new Uint8Array(32), o = new Uint8Array(32),
i i;
nacl.lowlevel.crypto_hash(d, sk, 32) nacl.lowlevel.crypto_hash(d, sk, 32);
d[0] &= 248 d[0] &= 248;
d[31] &= 127 d[31] &= 127;
d[31] |= 64 d[31] |= 64;
for (i = 0; i < 32; i++) o[i] = d[i] for (i = 0; i < 32; i++) o[i] = d[i];
for (i = 0; i < 64; i++) d[i] = 0 for (i = 0; i < 64; i++) d[i] = 0;
return o return o;
} }
function convertKeyPair(edKeyPair) { function convertKeyPair(edKeyPair) {
var publicKey = convertPublicKey(edKeyPair.publicKey) var publicKey = convertPublicKey(edKeyPair.publicKey);
if (!publicKey) return null if (!publicKey) return null;
return { return {
publicKey: publicKey, publicKey: publicKey,
secretKey: convertSecretKey(edKeyPair.secretKey), secretKey: convertSecretKey(edKeyPair.secretKey),
} };
} }
return { return {
convertPublicKey: convertPublicKey, convertPublicKey: convertPublicKey,
convertSecretKey: convertSecretKey, convertSecretKey: convertSecretKey,
convertKeyPair: convertKeyPair, convertKeyPair: convertKeyPair,
} };
}) });