1671 lines
54 KiB
Diff
1671 lines
54 KiB
Diff
diff --git a/node_modules/@noble/ed25519/lib/esm/index.js b/node_modules/@noble/ed25519/lib/esm/index.js
|
|
index e617211..c3a04be 100644
|
|
--- a/node_modules/@noble/ed25519/lib/esm/index.js
|
|
+++ b/node_modules/@noble/ed25519/lib/esm/index.js
|
|
@@ -1,10 +1,21 @@
|
|
/*! noble-ed25519 - MIT License (c) 2019 Paul Miller (paulmillr.com) */
|
|
-import * as nodeCrypto from 'crypto';
|
|
-const _0n = BigInt(0);
|
|
-const _1n = BigInt(1);
|
|
-const _2n = BigInt(2);
|
|
-const _8n = BigInt(8);
|
|
-const CU_O = BigInt('7237005577332262213973186563042994240857116359379907606001950938285454250989');
|
|
+import * as nodeCrypto from 'crypto'
|
|
+import { Crypto } from "@peculiar/webcrypto";
|
|
+let globalCrypto = self.crypto;
|
|
+if (!globalCrypto.subtle) {
|
|
+ let subtleCrypto = new Crypto().subtle;
|
|
+ Object.defineProperty(globalCrypto, "subtle", {
|
|
+ get() {
|
|
+ return subtleCrypto;
|
|
+ },
|
|
+ });
|
|
+}
|
|
+
|
|
+const _0n = BigInt(0)
|
|
+const _1n = BigInt(1)
|
|
+const _2n = BigInt(2)
|
|
+const _8n = BigInt(8)
|
|
+const CU_O = BigInt('7237005577332262213973186563042994240857116359379907606001950938285454250989')
|
|
const CURVE = Object.freeze({
|
|
a: BigInt(-1),
|
|
d: BigInt('37095705934669439343138083508754565189542113879843219016388785533085940283555'),
|
|
@@ -14,808 +25,907 @@ const CURVE = Object.freeze({
|
|
h: BigInt(8),
|
|
Gx: BigInt('15112221349535400772501151409588531511454012693041857206046113283949847762202'),
|
|
Gy: BigInt('46316835694926478169428394003475163141307993866256225615783033603165251855960'),
|
|
-});
|
|
-export { CURVE };
|
|
-const POW_2_256 = BigInt('0x10000000000000000000000000000000000000000000000000000000000000000');
|
|
-const SQRT_M1 = BigInt('19681161376707505956807079304988542015446066515923890162744021073123829784752');
|
|
-const SQRT_D = BigInt('6853475219497561581579357271197624642482790079785650197046958215289687604742');
|
|
-const SQRT_AD_MINUS_ONE = BigInt('25063068953384623474111414158702152701244531502492656460079210482610430750235');
|
|
-const INVSQRT_A_MINUS_D = BigInt('54469307008909316920995813868745141605393597292927456921205312896311721017578');
|
|
-const ONE_MINUS_D_SQ = BigInt('1159843021668779879193775521855586647937357759715417654439879720876111806838');
|
|
-const D_MINUS_ONE_SQ = BigInt('40440834346308536858101042469323190826248399146238708352240133220865137265952');
|
|
+})
|
|
+export { CURVE }
|
|
+const POW_2_256 = BigInt('0x10000000000000000000000000000000000000000000000000000000000000000')
|
|
+const SQRT_M1 = BigInt('19681161376707505956807079304988542015446066515923890162744021073123829784752')
|
|
+const SQRT_D = BigInt('6853475219497561581579357271197624642482790079785650197046958215289687604742')
|
|
+const SQRT_AD_MINUS_ONE = BigInt('25063068953384623474111414158702152701244531502492656460079210482610430750235')
|
|
+const INVSQRT_A_MINUS_D = BigInt('54469307008909316920995813868745141605393597292927456921205312896311721017578')
|
|
+const ONE_MINUS_D_SQ = BigInt('1159843021668779879193775521855586647937357759715417654439879720876111806838')
|
|
+const D_MINUS_ONE_SQ = BigInt('40440834346308536858101042469323190826248399146238708352240133220865137265952')
|
|
+
|
|
class ExtendedPoint {
|
|
- constructor(x, y, z, t) {
|
|
- this.x = x;
|
|
- this.y = y;
|
|
- this.z = z;
|
|
- this.t = t;
|
|
- }
|
|
- static fromAffine(p) {
|
|
+ constructor (x, y, z, t) {
|
|
+ this.x = x
|
|
+ this.y = y
|
|
+ this.z = z
|
|
+ this.t = t
|
|
+ }
|
|
+
|
|
+ static fromAffine (p) {
|
|
if (!(p instanceof Point)) {
|
|
- throw new TypeError('ExtendedPoint#fromAffine: expected Point');
|
|
+ throw new TypeError('ExtendedPoint#fromAffine: expected Point')
|
|
}
|
|
if (p.equals(Point.ZERO))
|
|
- return ExtendedPoint.ZERO;
|
|
- return new ExtendedPoint(p.x, p.y, _1n, mod(p.x * p.y));
|
|
- }
|
|
- static toAffineBatch(points) {
|
|
- const toInv = invertBatch(points.map((p) => p.z));
|
|
- return points.map((p, i) => p.toAffine(toInv[i]));
|
|
- }
|
|
- static normalizeZ(points) {
|
|
- return this.toAffineBatch(points).map(this.fromAffine);
|
|
- }
|
|
- equals(other) {
|
|
- assertExtPoint(other);
|
|
- const { x: X1, y: Y1, z: Z1 } = this;
|
|
- const { x: X2, y: Y2, z: Z2 } = other;
|
|
- const X1Z2 = mod(X1 * Z2);
|
|
- const X2Z1 = mod(X2 * Z1);
|
|
- const Y1Z2 = mod(Y1 * Z2);
|
|
- const Y2Z1 = mod(Y2 * Z1);
|
|
- return X1Z2 === X2Z1 && Y1Z2 === Y2Z1;
|
|
- }
|
|
- negate() {
|
|
- return new ExtendedPoint(mod(-this.x), this.y, this.z, mod(-this.t));
|
|
- }
|
|
- double() {
|
|
- const { x: X1, y: Y1, z: Z1 } = this;
|
|
- const { a } = CURVE;
|
|
- const A = mod(X1 * X1);
|
|
- const B = mod(Y1 * Y1);
|
|
- const C = mod(_2n * mod(Z1 * Z1));
|
|
- const D = mod(a * A);
|
|
- const x1y1 = X1 + Y1;
|
|
- const E = mod(mod(x1y1 * x1y1) - A - B);
|
|
- const G = D + B;
|
|
- const F = G - C;
|
|
- const H = D - B;
|
|
- const X3 = mod(E * F);
|
|
- const Y3 = mod(G * H);
|
|
- const T3 = mod(E * H);
|
|
- const Z3 = mod(F * G);
|
|
- return new ExtendedPoint(X3, Y3, Z3, T3);
|
|
- }
|
|
- add(other) {
|
|
- assertExtPoint(other);
|
|
- const { x: X1, y: Y1, z: Z1, t: T1 } = this;
|
|
- const { x: X2, y: Y2, z: Z2, t: T2 } = other;
|
|
- const A = mod((Y1 - X1) * (Y2 + X2));
|
|
- const B = mod((Y1 + X1) * (Y2 - X2));
|
|
- const F = mod(B - A);
|
|
+ return ExtendedPoint.ZERO
|
|
+ return new ExtendedPoint(p.x, p.y, _1n, mod(p.x * p.y))
|
|
+ }
|
|
+
|
|
+ static toAffineBatch (points) {
|
|
+ const toInv = invertBatch(points.map((p) => p.z))
|
|
+ return points.map((p, i) => p.toAffine(toInv[i]))
|
|
+ }
|
|
+
|
|
+ static normalizeZ (points) {
|
|
+ return this.toAffineBatch(points).map(this.fromAffine)
|
|
+ }
|
|
+
|
|
+ equals (other) {
|
|
+ assertExtPoint(other)
|
|
+ const { x: X1, y: Y1, z: Z1 } = this
|
|
+ const { x: X2, y: Y2, z: Z2 } = other
|
|
+ const X1Z2 = mod(X1 * Z2)
|
|
+ const X2Z1 = mod(X2 * Z1)
|
|
+ const Y1Z2 = mod(Y1 * Z2)
|
|
+ const Y2Z1 = mod(Y2 * Z1)
|
|
+ return X1Z2 === X2Z1 && Y1Z2 === Y2Z1
|
|
+ }
|
|
+
|
|
+ negate () {
|
|
+ return new ExtendedPoint(mod(-this.x), this.y, this.z, mod(-this.t))
|
|
+ }
|
|
+
|
|
+ double () {
|
|
+ const { x: X1, y: Y1, z: Z1 } = this
|
|
+ const { a } = CURVE
|
|
+ const A = mod(X1 * X1)
|
|
+ const B = mod(Y1 * Y1)
|
|
+ const C = mod(_2n * mod(Z1 * Z1))
|
|
+ const D = mod(a * A)
|
|
+ const x1y1 = X1 + Y1
|
|
+ const E = mod(mod(x1y1 * x1y1) - A - B)
|
|
+ const G = D + B
|
|
+ const F = G - C
|
|
+ const H = D - B
|
|
+ const X3 = mod(E * F)
|
|
+ const Y3 = mod(G * H)
|
|
+ const T3 = mod(E * H)
|
|
+ const Z3 = mod(F * G)
|
|
+ return new ExtendedPoint(X3, Y3, Z3, T3)
|
|
+ }
|
|
+
|
|
+ add (other) {
|
|
+ assertExtPoint(other)
|
|
+ const { x: X1, y: Y1, z: Z1, t: T1 } = this
|
|
+ const { x: X2, y: Y2, z: Z2, t: T2 } = other
|
|
+ const A = mod((Y1 - X1) * (Y2 + X2))
|
|
+ const B = mod((Y1 + X1) * (Y2 - X2))
|
|
+ const F = mod(B - A)
|
|
if (F === _0n)
|
|
- return this.double();
|
|
- const C = mod(Z1 * _2n * T2);
|
|
- const D = mod(T1 * _2n * Z2);
|
|
- const E = D + C;
|
|
- const G = B + A;
|
|
- const H = D - C;
|
|
- const X3 = mod(E * F);
|
|
- const Y3 = mod(G * H);
|
|
- const T3 = mod(E * H);
|
|
- const Z3 = mod(F * G);
|
|
- return new ExtendedPoint(X3, Y3, Z3, T3);
|
|
- }
|
|
- subtract(other) {
|
|
- return this.add(other.negate());
|
|
- }
|
|
- precomputeWindow(W) {
|
|
- const windows = 1 + 256 / W;
|
|
- const points = [];
|
|
- let p = this;
|
|
- let base = p;
|
|
+ return this.double()
|
|
+ const C = mod(Z1 * _2n * T2)
|
|
+ const D = mod(T1 * _2n * Z2)
|
|
+ const E = D + C
|
|
+ const G = B + A
|
|
+ const H = D - C
|
|
+ const X3 = mod(E * F)
|
|
+ const Y3 = mod(G * H)
|
|
+ const T3 = mod(E * H)
|
|
+ const Z3 = mod(F * G)
|
|
+ return new ExtendedPoint(X3, Y3, Z3, T3)
|
|
+ }
|
|
+
|
|
+ subtract (other) {
|
|
+ return this.add(other.negate())
|
|
+ }
|
|
+
|
|
+ precomputeWindow (W) {
|
|
+ const windows = 1 + 256 / W
|
|
+ const points = []
|
|
+ let p = this
|
|
+ let base = p
|
|
for (let window = 0; window < windows; window++) {
|
|
- base = p;
|
|
- points.push(base);
|
|
+ base = p
|
|
+ points.push(base)
|
|
for (let i = 1; i < 2 ** (W - 1); i++) {
|
|
- base = base.add(p);
|
|
- points.push(base);
|
|
+ base = base.add(p)
|
|
+ points.push(base)
|
|
}
|
|
- p = base.double();
|
|
+ p = base.double()
|
|
}
|
|
- return points;
|
|
+ return points
|
|
}
|
|
- wNAF(n, affinePoint) {
|
|
+
|
|
+ wNAF (n, affinePoint) {
|
|
if (!affinePoint && this.equals(ExtendedPoint.BASE))
|
|
- affinePoint = Point.BASE;
|
|
- const W = (affinePoint && affinePoint._WINDOW_SIZE) || 1;
|
|
+ affinePoint = Point.BASE
|
|
+ const W = (affinePoint && affinePoint._WINDOW_SIZE) || 1
|
|
if (256 % W) {
|
|
- throw new Error('Point#wNAF: Invalid precomputation window, must be power of 2');
|
|
+ throw new Error('Point#wNAF: Invalid precomputation window, must be power of 2')
|
|
}
|
|
- let precomputes = affinePoint && pointPrecomputes.get(affinePoint);
|
|
+ let precomputes = affinePoint && pointPrecomputes.get(affinePoint)
|
|
if (!precomputes) {
|
|
- precomputes = this.precomputeWindow(W);
|
|
+ precomputes = this.precomputeWindow(W)
|
|
if (affinePoint && W !== 1) {
|
|
- precomputes = ExtendedPoint.normalizeZ(precomputes);
|
|
- pointPrecomputes.set(affinePoint, precomputes);
|
|
+ precomputes = ExtendedPoint.normalizeZ(precomputes)
|
|
+ pointPrecomputes.set(affinePoint, precomputes)
|
|
}
|
|
}
|
|
- let p = ExtendedPoint.ZERO;
|
|
- let f = ExtendedPoint.BASE;
|
|
- const windows = 1 + 256 / W;
|
|
- const windowSize = 2 ** (W - 1);
|
|
- const mask = BigInt(2 ** W - 1);
|
|
- const maxNumber = 2 ** W;
|
|
- const shiftBy = BigInt(W);
|
|
+ let p = ExtendedPoint.ZERO
|
|
+ let f = ExtendedPoint.BASE
|
|
+ const windows = 1 + 256 / W
|
|
+ const windowSize = 2 ** (W - 1)
|
|
+ const mask = BigInt(2 ** W - 1)
|
|
+ const maxNumber = 2 ** W
|
|
+ const shiftBy = BigInt(W)
|
|
for (let window = 0; window < windows; window++) {
|
|
- const offset = window * windowSize;
|
|
- let wbits = Number(n & mask);
|
|
- n >>= shiftBy;
|
|
+ const offset = window * windowSize
|
|
+ let wbits = Number(n & mask)
|
|
+ n >>= shiftBy
|
|
if (wbits > windowSize) {
|
|
- wbits -= maxNumber;
|
|
- n += _1n;
|
|
+ wbits -= maxNumber
|
|
+ n += _1n
|
|
}
|
|
- const offset1 = offset;
|
|
- const offset2 = offset + Math.abs(wbits) - 1;
|
|
- const cond1 = window % 2 !== 0;
|
|
- const cond2 = wbits < 0;
|
|
+ const offset1 = offset
|
|
+ const offset2 = offset + Math.abs(wbits) - 1
|
|
+ const cond1 = window % 2 !== 0
|
|
+ const cond2 = wbits < 0
|
|
if (wbits === 0) {
|
|
- f = f.add(constTimeNegate(cond1, precomputes[offset1]));
|
|
- }
|
|
- else {
|
|
- p = p.add(constTimeNegate(cond2, precomputes[offset2]));
|
|
+ f = f.add(constTimeNegate(cond1, precomputes[offset1]))
|
|
+ } else {
|
|
+ p = p.add(constTimeNegate(cond2, precomputes[offset2]))
|
|
}
|
|
}
|
|
- return ExtendedPoint.normalizeZ([p, f])[0];
|
|
+ return ExtendedPoint.normalizeZ([p, f])[0]
|
|
}
|
|
- multiply(scalar, affinePoint) {
|
|
- return this.wNAF(normalizeScalar(scalar, CURVE.l), affinePoint);
|
|
+
|
|
+ multiply (scalar, affinePoint) {
|
|
+ return this.wNAF(normalizeScalar(scalar, CURVE.l), affinePoint)
|
|
}
|
|
- multiplyUnsafe(scalar) {
|
|
- let n = normalizeScalar(scalar, CURVE.l, false);
|
|
- const G = ExtendedPoint.BASE;
|
|
- const P0 = ExtendedPoint.ZERO;
|
|
+
|
|
+ multiplyUnsafe (scalar) {
|
|
+ let n = normalizeScalar(scalar, CURVE.l, false)
|
|
+ const G = ExtendedPoint.BASE
|
|
+ const P0 = ExtendedPoint.ZERO
|
|
if (n === _0n)
|
|
- return P0;
|
|
+ return P0
|
|
if (this.equals(P0) || n === _1n)
|
|
- return this;
|
|
+ return this
|
|
if (this.equals(G))
|
|
- return this.wNAF(n);
|
|
- let p = P0;
|
|
- let d = this;
|
|
+ return this.wNAF(n)
|
|
+ let p = P0
|
|
+ let d = this
|
|
while (n > _0n) {
|
|
if (n & _1n)
|
|
- p = p.add(d);
|
|
- d = d.double();
|
|
- n >>= _1n;
|
|
+ p = p.add(d)
|
|
+ d = d.double()
|
|
+ n >>= _1n
|
|
}
|
|
- return p;
|
|
+ return p
|
|
}
|
|
- isSmallOrder() {
|
|
- return this.multiplyUnsafe(CURVE.h).equals(ExtendedPoint.ZERO);
|
|
+
|
|
+ isSmallOrder () {
|
|
+ return this.multiplyUnsafe(CURVE.h).equals(ExtendedPoint.ZERO)
|
|
}
|
|
- isTorsionFree() {
|
|
- let p = this.multiplyUnsafe(CURVE.l / _2n).double();
|
|
+
|
|
+ isTorsionFree () {
|
|
+ let p = this.multiplyUnsafe(CURVE.l / _2n).double()
|
|
if (CURVE.l % _2n)
|
|
- p = p.add(this);
|
|
- return p.equals(ExtendedPoint.ZERO);
|
|
+ p = p.add(this)
|
|
+ return p.equals(ExtendedPoint.ZERO)
|
|
}
|
|
- toAffine(invZ) {
|
|
- const { x, y, z } = this;
|
|
- const is0 = this.equals(ExtendedPoint.ZERO);
|
|
+
|
|
+ toAffine (invZ) {
|
|
+ const { x, y, z } = this
|
|
+ const is0 = this.equals(ExtendedPoint.ZERO)
|
|
if (invZ == null)
|
|
- invZ = is0 ? _8n : invert(z);
|
|
- const ax = mod(x * invZ);
|
|
- const ay = mod(y * invZ);
|
|
- const zz = mod(z * invZ);
|
|
+ invZ = is0 ? _8n : invert(z)
|
|
+ const ax = mod(x * invZ)
|
|
+ const ay = mod(y * invZ)
|
|
+ const zz = mod(z * invZ)
|
|
if (is0)
|
|
- return Point.ZERO;
|
|
+ return Point.ZERO
|
|
if (zz !== _1n)
|
|
- throw new Error('invZ was invalid');
|
|
- return new Point(ax, ay);
|
|
+ throw new Error('invZ was invalid')
|
|
+ return new Point(ax, ay)
|
|
}
|
|
- fromRistrettoBytes() {
|
|
- legacyRist();
|
|
+
|
|
+ fromRistrettoBytes () {
|
|
+ legacyRist()
|
|
}
|
|
- toRistrettoBytes() {
|
|
- legacyRist();
|
|
+
|
|
+ toRistrettoBytes () {
|
|
+ legacyRist()
|
|
}
|
|
- fromRistrettoHash() {
|
|
- legacyRist();
|
|
+
|
|
+ fromRistrettoHash () {
|
|
+ legacyRist()
|
|
}
|
|
}
|
|
-ExtendedPoint.BASE = new ExtendedPoint(CURVE.Gx, CURVE.Gy, _1n, mod(CURVE.Gx * CURVE.Gy));
|
|
-ExtendedPoint.ZERO = new ExtendedPoint(_0n, _1n, _1n, _0n);
|
|
-function constTimeNegate(condition, item) {
|
|
- const neg = item.negate();
|
|
- return condition ? neg : item;
|
|
+
|
|
+ExtendedPoint.BASE = new ExtendedPoint(CURVE.Gx, CURVE.Gy, _1n, mod(CURVE.Gx * CURVE.Gy))
|
|
+ExtendedPoint.ZERO = new ExtendedPoint(_0n, _1n, _1n, _0n)
|
|
+
|
|
+function constTimeNegate (condition, item) {
|
|
+ const neg = item.negate()
|
|
+ return condition ? neg : item
|
|
}
|
|
-function assertExtPoint(other) {
|
|
+
|
|
+function assertExtPoint (other) {
|
|
if (!(other instanceof ExtendedPoint))
|
|
- throw new TypeError('ExtendedPoint expected');
|
|
+ throw new TypeError('ExtendedPoint expected')
|
|
}
|
|
-function assertRstPoint(other) {
|
|
+
|
|
+function assertRstPoint (other) {
|
|
if (!(other instanceof RistrettoPoint))
|
|
- throw new TypeError('RistrettoPoint expected');
|
|
+ throw new TypeError('RistrettoPoint expected')
|
|
}
|
|
-function legacyRist() {
|
|
- throw new Error('Legacy method: switch to RistrettoPoint');
|
|
+
|
|
+function legacyRist () {
|
|
+ throw new Error('Legacy method: switch to RistrettoPoint')
|
|
}
|
|
+
|
|
class RistrettoPoint {
|
|
- constructor(ep) {
|
|
- this.ep = ep;
|
|
- }
|
|
- static calcElligatorRistrettoMap(r0) {
|
|
- const { d } = CURVE;
|
|
- const r = mod(SQRT_M1 * r0 * r0);
|
|
- const Ns = mod((r + _1n) * ONE_MINUS_D_SQ);
|
|
- let c = BigInt(-1);
|
|
- const D = mod((c - d * r) * mod(r + d));
|
|
- let { isValid: Ns_D_is_sq, value: s } = uvRatio(Ns, D);
|
|
- let s_ = mod(s * r0);
|
|
+ constructor (ep) {
|
|
+ this.ep = ep
|
|
+ }
|
|
+
|
|
+ static calcElligatorRistrettoMap (r0) {
|
|
+ const { d } = CURVE
|
|
+ const r = mod(SQRT_M1 * r0 * r0)
|
|
+ const Ns = mod((r + _1n) * ONE_MINUS_D_SQ)
|
|
+ let c = BigInt(-1)
|
|
+ const D = mod((c - d * r) * mod(r + d))
|
|
+ let { isValid: Ns_D_is_sq, value: s } = uvRatio(Ns, D)
|
|
+ let s_ = mod(s * r0)
|
|
if (!edIsNegative(s_))
|
|
- s_ = mod(-s_);
|
|
+ s_ = mod(-s_)
|
|
if (!Ns_D_is_sq)
|
|
- s = s_;
|
|
+ s = s_
|
|
if (!Ns_D_is_sq)
|
|
- c = r;
|
|
- const Nt = mod(c * (r - _1n) * D_MINUS_ONE_SQ - D);
|
|
- const s2 = s * s;
|
|
- const W0 = mod((s + s) * D);
|
|
- const W1 = mod(Nt * SQRT_AD_MINUS_ONE);
|
|
- const W2 = mod(_1n - s2);
|
|
- const W3 = mod(_1n + s2);
|
|
- return new ExtendedPoint(mod(W0 * W3), mod(W2 * W1), mod(W1 * W3), mod(W0 * W2));
|
|
- }
|
|
- static hashToCurve(hex) {
|
|
- hex = ensureBytes(hex, 64);
|
|
- const r1 = bytes255ToNumberLE(hex.slice(0, 32));
|
|
- const R1 = this.calcElligatorRistrettoMap(r1);
|
|
- const r2 = bytes255ToNumberLE(hex.slice(32, 64));
|
|
- const R2 = this.calcElligatorRistrettoMap(r2);
|
|
- return new RistrettoPoint(R1.add(R2));
|
|
- }
|
|
- static fromHex(hex) {
|
|
- hex = ensureBytes(hex, 32);
|
|
- const { a, d } = CURVE;
|
|
- const emsg = 'RistrettoPoint.fromHex: the hex is not valid encoding of RistrettoPoint';
|
|
- const s = bytes255ToNumberLE(hex);
|
|
+ c = r
|
|
+ const Nt = mod(c * (r - _1n) * D_MINUS_ONE_SQ - D)
|
|
+ const s2 = s * s
|
|
+ const W0 = mod((s + s) * D)
|
|
+ const W1 = mod(Nt * SQRT_AD_MINUS_ONE)
|
|
+ const W2 = mod(_1n - s2)
|
|
+ const W3 = mod(_1n + s2)
|
|
+ return new ExtendedPoint(mod(W0 * W3), mod(W2 * W1), mod(W1 * W3), mod(W0 * W2))
|
|
+ }
|
|
+
|
|
+ static hashToCurve (hex) {
|
|
+ hex = ensureBytes(hex, 64)
|
|
+ const r1 = bytes255ToNumberLE(hex.slice(0, 32))
|
|
+ const R1 = this.calcElligatorRistrettoMap(r1)
|
|
+ const r2 = bytes255ToNumberLE(hex.slice(32, 64))
|
|
+ const R2 = this.calcElligatorRistrettoMap(r2)
|
|
+ return new RistrettoPoint(R1.add(R2))
|
|
+ }
|
|
+
|
|
+ static fromHex (hex) {
|
|
+ hex = ensureBytes(hex, 32)
|
|
+ const { a, d } = CURVE
|
|
+ const emsg = 'RistrettoPoint.fromHex: the hex is not valid encoding of RistrettoPoint'
|
|
+ const s = bytes255ToNumberLE(hex)
|
|
if (!equalBytes(numberTo32BytesLE(s), hex) || edIsNegative(s))
|
|
- throw new Error(emsg);
|
|
- const s2 = mod(s * s);
|
|
- const u1 = mod(_1n + a * s2);
|
|
- const u2 = mod(_1n - a * s2);
|
|
- const u1_2 = mod(u1 * u1);
|
|
- const u2_2 = mod(u2 * u2);
|
|
- const v = mod(a * d * u1_2 - u2_2);
|
|
- const { isValid, value: I } = invertSqrt(mod(v * u2_2));
|
|
- const Dx = mod(I * u2);
|
|
- const Dy = mod(I * Dx * v);
|
|
- let x = mod((s + s) * Dx);
|
|
+ throw new Error(emsg)
|
|
+ const s2 = mod(s * s)
|
|
+ const u1 = mod(_1n + a * s2)
|
|
+ const u2 = mod(_1n - a * s2)
|
|
+ const u1_2 = mod(u1 * u1)
|
|
+ const u2_2 = mod(u2 * u2)
|
|
+ const v = mod(a * d * u1_2 - u2_2)
|
|
+ const { isValid, value: I } = invertSqrt(mod(v * u2_2))
|
|
+ const Dx = mod(I * u2)
|
|
+ const Dy = mod(I * Dx * v)
|
|
+ let x = mod((s + s) * Dx)
|
|
if (edIsNegative(x))
|
|
- x = mod(-x);
|
|
- const y = mod(u1 * Dy);
|
|
- const t = mod(x * y);
|
|
+ x = mod(-x)
|
|
+ const y = mod(u1 * Dy)
|
|
+ const t = mod(x * y)
|
|
if (!isValid || edIsNegative(t) || y === _0n)
|
|
- throw new Error(emsg);
|
|
- return new RistrettoPoint(new ExtendedPoint(x, y, _1n, t));
|
|
- }
|
|
- toRawBytes() {
|
|
- let { x, y, z, t } = this.ep;
|
|
- const u1 = mod(mod(z + y) * mod(z - y));
|
|
- const u2 = mod(x * y);
|
|
- const u2sq = mod(u2 * u2);
|
|
- const { value: invsqrt } = invertSqrt(mod(u1 * u2sq));
|
|
- const D1 = mod(invsqrt * u1);
|
|
- const D2 = mod(invsqrt * u2);
|
|
- const zInv = mod(D1 * D2 * t);
|
|
- let D;
|
|
+ throw new Error(emsg)
|
|
+ return new RistrettoPoint(new ExtendedPoint(x, y, _1n, t))
|
|
+ }
|
|
+
|
|
+ toRawBytes () {
|
|
+ let { x, y, z, t } = this.ep
|
|
+ const u1 = mod(mod(z + y) * mod(z - y))
|
|
+ const u2 = mod(x * y)
|
|
+ const u2sq = mod(u2 * u2)
|
|
+ const { value: invsqrt } = invertSqrt(mod(u1 * u2sq))
|
|
+ const D1 = mod(invsqrt * u1)
|
|
+ const D2 = mod(invsqrt * u2)
|
|
+ const zInv = mod(D1 * D2 * t)
|
|
+ let D
|
|
if (edIsNegative(t * zInv)) {
|
|
- let _x = mod(y * SQRT_M1);
|
|
- let _y = mod(x * SQRT_M1);
|
|
- x = _x;
|
|
- y = _y;
|
|
- D = mod(D1 * INVSQRT_A_MINUS_D);
|
|
- }
|
|
- else {
|
|
- D = D2;
|
|
+ let _x = mod(y * SQRT_M1)
|
|
+ let _y = mod(x * SQRT_M1)
|
|
+ x = _x
|
|
+ y = _y
|
|
+ D = mod(D1 * INVSQRT_A_MINUS_D)
|
|
+ } else {
|
|
+ D = D2
|
|
}
|
|
if (edIsNegative(x * zInv))
|
|
- y = mod(-y);
|
|
- let s = mod((z - y) * D);
|
|
+ y = mod(-y)
|
|
+ let s = mod((z - y) * D)
|
|
if (edIsNegative(s))
|
|
- s = mod(-s);
|
|
- return numberTo32BytesLE(s);
|
|
- }
|
|
- toHex() {
|
|
- return bytesToHex(this.toRawBytes());
|
|
- }
|
|
- toString() {
|
|
- return this.toHex();
|
|
- }
|
|
- equals(other) {
|
|
- assertRstPoint(other);
|
|
- const a = this.ep;
|
|
- const b = other.ep;
|
|
- const one = mod(a.x * b.y) === mod(a.y * b.x);
|
|
- const two = mod(a.y * b.y) === mod(a.x * b.x);
|
|
- return one || two;
|
|
- }
|
|
- add(other) {
|
|
- assertRstPoint(other);
|
|
- return new RistrettoPoint(this.ep.add(other.ep));
|
|
- }
|
|
- subtract(other) {
|
|
- assertRstPoint(other);
|
|
- return new RistrettoPoint(this.ep.subtract(other.ep));
|
|
- }
|
|
- multiply(scalar) {
|
|
- return new RistrettoPoint(this.ep.multiply(scalar));
|
|
- }
|
|
- multiplyUnsafe(scalar) {
|
|
- return new RistrettoPoint(this.ep.multiplyUnsafe(scalar));
|
|
- }
|
|
-}
|
|
-RistrettoPoint.BASE = new RistrettoPoint(ExtendedPoint.BASE);
|
|
-RistrettoPoint.ZERO = new RistrettoPoint(ExtendedPoint.ZERO);
|
|
-const pointPrecomputes = new WeakMap();
|
|
+ s = mod(-s)
|
|
+ return numberTo32BytesLE(s)
|
|
+ }
|
|
+
|
|
+ toHex () {
|
|
+ return bytesToHex(this.toRawBytes())
|
|
+ }
|
|
+
|
|
+ toString () {
|
|
+ return this.toHex()
|
|
+ }
|
|
+
|
|
+ equals (other) {
|
|
+ assertRstPoint(other)
|
|
+ const a = this.ep
|
|
+ const b = other.ep
|
|
+ const one = mod(a.x * b.y) === mod(a.y * b.x)
|
|
+ const two = mod(a.y * b.y) === mod(a.x * b.x)
|
|
+ return one || two
|
|
+ }
|
|
+
|
|
+ add (other) {
|
|
+ assertRstPoint(other)
|
|
+ return new RistrettoPoint(this.ep.add(other.ep))
|
|
+ }
|
|
+
|
|
+ subtract (other) {
|
|
+ assertRstPoint(other)
|
|
+ return new RistrettoPoint(this.ep.subtract(other.ep))
|
|
+ }
|
|
+
|
|
+ multiply (scalar) {
|
|
+ return new RistrettoPoint(this.ep.multiply(scalar))
|
|
+ }
|
|
+
|
|
+ multiplyUnsafe (scalar) {
|
|
+ return new RistrettoPoint(this.ep.multiplyUnsafe(scalar))
|
|
+ }
|
|
+}
|
|
+
|
|
+RistrettoPoint.BASE = new RistrettoPoint(ExtendedPoint.BASE)
|
|
+RistrettoPoint.ZERO = new RistrettoPoint(ExtendedPoint.ZERO)
|
|
+const pointPrecomputes = new WeakMap()
|
|
+
|
|
class Point {
|
|
- constructor(x, y) {
|
|
- this.x = x;
|
|
- this.y = y;
|
|
- }
|
|
- _setWindowSize(windowSize) {
|
|
- this._WINDOW_SIZE = windowSize;
|
|
- pointPrecomputes.delete(this);
|
|
- }
|
|
- static fromHex(hex, strict = true) {
|
|
- const { d, P } = CURVE;
|
|
- hex = ensureBytes(hex, 32);
|
|
- const normed = hex.slice();
|
|
- normed[31] = hex[31] & ~0x80;
|
|
- const y = bytesToNumberLE(normed);
|
|
+ constructor (x, y) {
|
|
+ this.x = x
|
|
+ this.y = y
|
|
+ }
|
|
+
|
|
+ _setWindowSize (windowSize) {
|
|
+ this._WINDOW_SIZE = windowSize
|
|
+ pointPrecomputes.delete(this)
|
|
+ }
|
|
+
|
|
+ static fromHex (hex, strict = true) {
|
|
+ const { d, P } = CURVE
|
|
+ hex = ensureBytes(hex, 32)
|
|
+ const normed = hex.slice()
|
|
+ normed[31] = hex[31] & ~0x80
|
|
+ const y = bytesToNumberLE(normed)
|
|
if (strict && y >= P)
|
|
- throw new Error('Expected 0 < hex < P');
|
|
+ throw new Error('Expected 0 < hex < P')
|
|
if (!strict && y >= POW_2_256)
|
|
- throw new Error('Expected 0 < hex < 2**256');
|
|
- const y2 = mod(y * y);
|
|
- const u = mod(y2 - _1n);
|
|
- const v = mod(d * y2 + _1n);
|
|
- let { isValid, value: x } = uvRatio(u, v);
|
|
+ throw new Error('Expected 0 < hex < 2**256')
|
|
+ const y2 = mod(y * y)
|
|
+ const u = mod(y2 - _1n)
|
|
+ const v = mod(d * y2 + _1n)
|
|
+ let { isValid, value: x } = uvRatio(u, v)
|
|
if (!isValid)
|
|
- throw new Error('Point.fromHex: invalid y coordinate');
|
|
- const isXOdd = (x & _1n) === _1n;
|
|
- const isLastByteOdd = (hex[31] & 0x80) !== 0;
|
|
+ throw new Error('Point.fromHex: invalid y coordinate')
|
|
+ const isXOdd = (x & _1n) === _1n
|
|
+ const isLastByteOdd = (hex[31] & 0x80) !== 0
|
|
if (isLastByteOdd !== isXOdd) {
|
|
- x = mod(-x);
|
|
+ x = mod(-x)
|
|
}
|
|
- return new Point(x, y);
|
|
+ return new Point(x, y)
|
|
}
|
|
- static async fromPrivateKey(privateKey) {
|
|
- return (await getExtendedPublicKey(privateKey)).point;
|
|
+
|
|
+ static async fromPrivateKey (privateKey) {
|
|
+ return (await getExtendedPublicKey(privateKey)).point
|
|
}
|
|
- toRawBytes() {
|
|
- const bytes = numberTo32BytesLE(this.y);
|
|
- bytes[31] |= this.x & _1n ? 0x80 : 0;
|
|
- return bytes;
|
|
+
|
|
+ toRawBytes () {
|
|
+ const bytes = numberTo32BytesLE(this.y)
|
|
+ bytes[31] |= this.x & _1n ? 0x80 : 0
|
|
+ return bytes
|
|
}
|
|
- toHex() {
|
|
- return bytesToHex(this.toRawBytes());
|
|
+
|
|
+ toHex () {
|
|
+ return bytesToHex(this.toRawBytes())
|
|
}
|
|
- toX25519() {
|
|
- const { y } = this;
|
|
- const u = mod((_1n + y) * invert(_1n - y));
|
|
- return numberTo32BytesLE(u);
|
|
+
|
|
+ toX25519 () {
|
|
+ const { y } = this
|
|
+ const u = mod((_1n + y) * invert(_1n - y))
|
|
+ return numberTo32BytesLE(u)
|
|
}
|
|
- isTorsionFree() {
|
|
- return ExtendedPoint.fromAffine(this).isTorsionFree();
|
|
+
|
|
+ isTorsionFree () {
|
|
+ return ExtendedPoint.fromAffine(this).isTorsionFree()
|
|
}
|
|
- equals(other) {
|
|
- return this.x === other.x && this.y === other.y;
|
|
+
|
|
+ equals (other) {
|
|
+ return this.x === other.x && this.y === other.y
|
|
}
|
|
- negate() {
|
|
- return new Point(mod(-this.x), this.y);
|
|
+
|
|
+ negate () {
|
|
+ return new Point(mod(-this.x), this.y)
|
|
}
|
|
- add(other) {
|
|
- return ExtendedPoint.fromAffine(this).add(ExtendedPoint.fromAffine(other)).toAffine();
|
|
+
|
|
+ add (other) {
|
|
+ return ExtendedPoint.fromAffine(this).add(ExtendedPoint.fromAffine(other)).toAffine()
|
|
}
|
|
- subtract(other) {
|
|
- return this.add(other.negate());
|
|
+
|
|
+ subtract (other) {
|
|
+ return this.add(other.negate())
|
|
}
|
|
- multiply(scalar) {
|
|
- return ExtendedPoint.fromAffine(this).multiply(scalar, this).toAffine();
|
|
+
|
|
+ multiply (scalar) {
|
|
+ return ExtendedPoint.fromAffine(this).multiply(scalar, this).toAffine()
|
|
}
|
|
}
|
|
-Point.BASE = new Point(CURVE.Gx, CURVE.Gy);
|
|
-Point.ZERO = new Point(_0n, _1n);
|
|
+
|
|
+Point.BASE = new Point(CURVE.Gx, CURVE.Gy)
|
|
+Point.ZERO = new Point(_0n, _1n)
|
|
+
|
|
class Signature {
|
|
- constructor(r, s) {
|
|
- this.r = r;
|
|
- this.s = s;
|
|
- this.assertValidity();
|
|
- }
|
|
- static fromHex(hex) {
|
|
- const bytes = ensureBytes(hex, 64);
|
|
- const r = Point.fromHex(bytes.slice(0, 32), false);
|
|
- const s = bytesToNumberLE(bytes.slice(32, 64));
|
|
- return new Signature(r, s);
|
|
- }
|
|
- assertValidity() {
|
|
- const { r, s } = this;
|
|
+ constructor (r, s) {
|
|
+ this.r = r
|
|
+ this.s = s
|
|
+ this.assertValidity()
|
|
+ }
|
|
+
|
|
+ static fromHex (hex) {
|
|
+ const bytes = ensureBytes(hex, 64)
|
|
+ const r = Point.fromHex(bytes.slice(0, 32), false)
|
|
+ const s = bytesToNumberLE(bytes.slice(32, 64))
|
|
+ return new Signature(r, s)
|
|
+ }
|
|
+
|
|
+ assertValidity () {
|
|
+ const { r, s } = this
|
|
if (!(r instanceof Point))
|
|
- throw new Error('Expected Point instance');
|
|
- normalizeScalar(s, CURVE.l, false);
|
|
- return this;
|
|
- }
|
|
- toRawBytes() {
|
|
- const u8 = new Uint8Array(64);
|
|
- u8.set(this.r.toRawBytes());
|
|
- u8.set(numberTo32BytesLE(this.s), 32);
|
|
- return u8;
|
|
- }
|
|
- toHex() {
|
|
- return bytesToHex(this.toRawBytes());
|
|
- }
|
|
-}
|
|
-export { ExtendedPoint, RistrettoPoint, Point, Signature };
|
|
-function concatBytes(...arrays) {
|
|
+ throw new Error('Expected Point instance')
|
|
+ normalizeScalar(s, CURVE.l, false)
|
|
+ return this
|
|
+ }
|
|
+
|
|
+ toRawBytes () {
|
|
+ const u8 = new Uint8Array(64)
|
|
+ u8.set(this.r.toRawBytes())
|
|
+ u8.set(numberTo32BytesLE(this.s), 32)
|
|
+ return u8
|
|
+ }
|
|
+
|
|
+ toHex () {
|
|
+ return bytesToHex(this.toRawBytes())
|
|
+ }
|
|
+}
|
|
+
|
|
+export { ExtendedPoint, RistrettoPoint, Point, Signature }
|
|
+
|
|
+function concatBytes (...arrays) {
|
|
if (!arrays.every((a) => a instanceof Uint8Array))
|
|
- throw new Error('Expected Uint8Array list');
|
|
+ throw new Error('Expected Uint8Array list')
|
|
if (arrays.length === 1)
|
|
- return arrays[0];
|
|
- const length = arrays.reduce((a, arr) => a + arr.length, 0);
|
|
- const result = new Uint8Array(length);
|
|
+ return arrays[0]
|
|
+ const length = arrays.reduce((a, arr) => a + arr.length, 0)
|
|
+ const result = new Uint8Array(length)
|
|
for (let i = 0, pad = 0; i < arrays.length; i++) {
|
|
- const arr = arrays[i];
|
|
- result.set(arr, pad);
|
|
- pad += arr.length;
|
|
+ const arr = arrays[i]
|
|
+ result.set(arr, pad)
|
|
+ pad += arr.length
|
|
}
|
|
- return result;
|
|
+ return result
|
|
}
|
|
-const hexes = Array.from({ length: 256 }, (v, i) => i.toString(16).padStart(2, '0'));
|
|
-function bytesToHex(uint8a) {
|
|
+
|
|
+const hexes = Array.from({ length: 256 }, (v, i) => i.toString(16).padStart(2, '0'))
|
|
+
|
|
+function bytesToHex (uint8a) {
|
|
if (!(uint8a instanceof Uint8Array))
|
|
- throw new Error('Uint8Array expected');
|
|
- let hex = '';
|
|
+ throw new Error('Uint8Array expected')
|
|
+ let hex = ''
|
|
for (let i = 0; i < uint8a.length; i++) {
|
|
- hex += hexes[uint8a[i]];
|
|
+ hex += hexes[uint8a[i]]
|
|
}
|
|
- return hex;
|
|
+ return hex
|
|
}
|
|
-function hexToBytes(hex) {
|
|
+
|
|
+function hexToBytes (hex) {
|
|
if (typeof hex !== 'string') {
|
|
- throw new TypeError('hexToBytes: expected string, got ' + typeof hex);
|
|
+ throw new TypeError('hexToBytes: expected string, got ' + typeof hex)
|
|
}
|
|
if (hex.length % 2)
|
|
- throw new Error('hexToBytes: received invalid unpadded hex');
|
|
- const array = new Uint8Array(hex.length / 2);
|
|
+ throw new Error('hexToBytes: received invalid unpadded hex')
|
|
+ const array = new Uint8Array(hex.length / 2)
|
|
for (let i = 0; i < array.length; i++) {
|
|
- const j = i * 2;
|
|
- const hexByte = hex.slice(j, j + 2);
|
|
- const byte = Number.parseInt(hexByte, 16);
|
|
+ const j = i * 2
|
|
+ const hexByte = hex.slice(j, j + 2)
|
|
+ const byte = Number.parseInt(hexByte, 16)
|
|
if (Number.isNaN(byte) || byte < 0)
|
|
- throw new Error('Invalid byte sequence');
|
|
- array[i] = byte;
|
|
+ throw new Error('Invalid byte sequence')
|
|
+ array[i] = byte
|
|
}
|
|
- return array;
|
|
+ return array
|
|
}
|
|
-function numberTo32BytesBE(num) {
|
|
- const length = 32;
|
|
- const hex = num.toString(16).padStart(length * 2, '0');
|
|
- return hexToBytes(hex);
|
|
+
|
|
+function numberTo32BytesBE (num) {
|
|
+ const length = 32
|
|
+ const hex = num.toString(16).padStart(length * 2, '0')
|
|
+ return hexToBytes(hex)
|
|
}
|
|
-function numberTo32BytesLE(num) {
|
|
- return numberTo32BytesBE(num).reverse();
|
|
+
|
|
+function numberTo32BytesLE (num) {
|
|
+ return numberTo32BytesBE(num).reverse()
|
|
}
|
|
-function edIsNegative(num) {
|
|
- return (mod(num) & _1n) === _1n;
|
|
+
|
|
+function edIsNegative (num) {
|
|
+ return (mod(num) & _1n) === _1n
|
|
}
|
|
-function bytesToNumberLE(uint8a) {
|
|
+
|
|
+function bytesToNumberLE (uint8a) {
|
|
if (!(uint8a instanceof Uint8Array))
|
|
- throw new Error('Expected Uint8Array');
|
|
- return BigInt('0x' + bytesToHex(Uint8Array.from(uint8a).reverse()));
|
|
-}
|
|
-const MAX_255B = BigInt('0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff');
|
|
-function bytes255ToNumberLE(bytes) {
|
|
- return mod(bytesToNumberLE(bytes) & MAX_255B);
|
|
-}
|
|
-function mod(a, b = CURVE.P) {
|
|
- const res = a % b;
|
|
- return res >= _0n ? res : b + res;
|
|
-}
|
|
-function invert(number, modulo = CURVE.P) {
|
|
+ throw new Error('Expected Uint8Array')
|
|
+ return BigInt('0x' + bytesToHex(Uint8Array.from(uint8a).reverse()))
|
|
+}
|
|
+
|
|
+const MAX_255B = BigInt('0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff')
|
|
+
|
|
+function bytes255ToNumberLE (bytes) {
|
|
+ return mod(bytesToNumberLE(bytes) & MAX_255B)
|
|
+}
|
|
+
|
|
+function mod (a, b = CURVE.P) {
|
|
+ const res = a % b
|
|
+ return res >= _0n ? res : b + res
|
|
+}
|
|
+
|
|
+function invert (number, modulo = CURVE.P) {
|
|
if (number === _0n || modulo <= _0n) {
|
|
- throw new Error(`invert: expected positive integers, got n=${number} mod=${modulo}`);
|
|
+ throw new Error(`invert: expected positive integers, got n=${number} mod=${modulo}`)
|
|
}
|
|
- let a = mod(number, modulo);
|
|
- let b = modulo;
|
|
- let x = _0n, y = _1n, u = _1n, v = _0n;
|
|
+ let a = mod(number, modulo)
|
|
+ let b = modulo
|
|
+ let x = _0n, y = _1n, u = _1n, v = _0n
|
|
while (a !== _0n) {
|
|
- const q = b / a;
|
|
- const r = b % a;
|
|
- const m = x - u * q;
|
|
- const n = y - v * q;
|
|
- b = a, a = r, x = u, y = v, u = m, v = n;
|
|
+ const q = b / a
|
|
+ const r = b % a
|
|
+ const m = x - u * q
|
|
+ const n = y - v * q
|
|
+ b = a, a = r, x = u, y = v, u = m, v = n
|
|
}
|
|
- const gcd = b;
|
|
+ const gcd = b
|
|
if (gcd !== _1n)
|
|
- throw new Error('invert: does not exist');
|
|
- return mod(x, modulo);
|
|
+ throw new Error('invert: does not exist')
|
|
+ return mod(x, modulo)
|
|
}
|
|
-function invertBatch(nums, p = CURVE.P) {
|
|
- const tmp = new Array(nums.length);
|
|
+
|
|
+function invertBatch (nums, p = CURVE.P) {
|
|
+ const tmp = new Array(nums.length)
|
|
const lastMultiplied = nums.reduce((acc, num, i) => {
|
|
if (num === _0n)
|
|
- return acc;
|
|
- tmp[i] = acc;
|
|
- return mod(acc * num, p);
|
|
- }, _1n);
|
|
- const inverted = invert(lastMultiplied, p);
|
|
+ return acc
|
|
+ tmp[i] = acc
|
|
+ return mod(acc * num, p)
|
|
+ }, _1n)
|
|
+ const inverted = invert(lastMultiplied, p)
|
|
nums.reduceRight((acc, num, i) => {
|
|
if (num === _0n)
|
|
- return acc;
|
|
- tmp[i] = mod(acc * tmp[i], p);
|
|
- return mod(acc * num, p);
|
|
- }, inverted);
|
|
- return tmp;
|
|
-}
|
|
-function pow2(x, power) {
|
|
- const { P } = CURVE;
|
|
- let res = x;
|
|
+ return acc
|
|
+ tmp[i] = mod(acc * tmp[i], p)
|
|
+ return mod(acc * num, p)
|
|
+ }, inverted)
|
|
+ return tmp
|
|
+}
|
|
+
|
|
+function pow2 (x, power) {
|
|
+ const { P } = CURVE
|
|
+ let res = x
|
|
while (power-- > _0n) {
|
|
- res *= res;
|
|
- res %= P;
|
|
- }
|
|
- return res;
|
|
-}
|
|
-function pow_2_252_3(x) {
|
|
- const { P } = CURVE;
|
|
- const _5n = BigInt(5);
|
|
- const _10n = BigInt(10);
|
|
- const _20n = BigInt(20);
|
|
- const _40n = BigInt(40);
|
|
- const _80n = BigInt(80);
|
|
- const x2 = (x * x) % P;
|
|
- const b2 = (x2 * x) % P;
|
|
- const b4 = (pow2(b2, _2n) * b2) % P;
|
|
- const b5 = (pow2(b4, _1n) * x) % P;
|
|
- const b10 = (pow2(b5, _5n) * b5) % P;
|
|
- const b20 = (pow2(b10, _10n) * b10) % P;
|
|
- const b40 = (pow2(b20, _20n) * b20) % P;
|
|
- const b80 = (pow2(b40, _40n) * b40) % P;
|
|
- const b160 = (pow2(b80, _80n) * b80) % P;
|
|
- const b240 = (pow2(b160, _80n) * b80) % P;
|
|
- const b250 = (pow2(b240, _10n) * b10) % P;
|
|
- const pow_p_5_8 = (pow2(b250, _2n) * x) % P;
|
|
- return { pow_p_5_8, b2 };
|
|
-}
|
|
-function uvRatio(u, v) {
|
|
- const v3 = mod(v * v * v);
|
|
- const v7 = mod(v3 * v3 * v);
|
|
- const pow = pow_2_252_3(u * v7).pow_p_5_8;
|
|
- let x = mod(u * v3 * pow);
|
|
- const vx2 = mod(v * x * x);
|
|
- const root1 = x;
|
|
- const root2 = mod(x * SQRT_M1);
|
|
- const useRoot1 = vx2 === u;
|
|
- const useRoot2 = vx2 === mod(-u);
|
|
- const noRoot = vx2 === mod(-u * SQRT_M1);
|
|
+ res *= res
|
|
+ res %= P
|
|
+ }
|
|
+ return res
|
|
+}
|
|
+
|
|
+function pow_2_252_3 (x) {
|
|
+ const { P } = CURVE
|
|
+ const _5n = BigInt(5)
|
|
+ const _10n = BigInt(10)
|
|
+ const _20n = BigInt(20)
|
|
+ const _40n = BigInt(40)
|
|
+ const _80n = BigInt(80)
|
|
+ const x2 = (x * x) % P
|
|
+ const b2 = (x2 * x) % P
|
|
+ const b4 = (pow2(b2, _2n) * b2) % P
|
|
+ const b5 = (pow2(b4, _1n) * x) % P
|
|
+ const b10 = (pow2(b5, _5n) * b5) % P
|
|
+ const b20 = (pow2(b10, _10n) * b10) % P
|
|
+ const b40 = (pow2(b20, _20n) * b20) % P
|
|
+ const b80 = (pow2(b40, _40n) * b40) % P
|
|
+ const b160 = (pow2(b80, _80n) * b80) % P
|
|
+ const b240 = (pow2(b160, _80n) * b80) % P
|
|
+ const b250 = (pow2(b240, _10n) * b10) % P
|
|
+ const pow_p_5_8 = (pow2(b250, _2n) * x) % P
|
|
+ return { pow_p_5_8, b2 }
|
|
+}
|
|
+
|
|
+function uvRatio (u, v) {
|
|
+ const v3 = mod(v * v * v)
|
|
+ const v7 = mod(v3 * v3 * v)
|
|
+ const pow = pow_2_252_3(u * v7).pow_p_5_8
|
|
+ let x = mod(u * v3 * pow)
|
|
+ const vx2 = mod(v * x * x)
|
|
+ const root1 = x
|
|
+ const root2 = mod(x * SQRT_M1)
|
|
+ const useRoot1 = vx2 === u
|
|
+ const useRoot2 = vx2 === mod(-u)
|
|
+ const noRoot = vx2 === mod(-u * SQRT_M1)
|
|
if (useRoot1)
|
|
- x = root1;
|
|
+ x = root1
|
|
if (useRoot2 || noRoot)
|
|
- x = root2;
|
|
+ x = root2
|
|
if (edIsNegative(x))
|
|
- x = mod(-x);
|
|
- return { isValid: useRoot1 || useRoot2, value: x };
|
|
+ x = mod(-x)
|
|
+ return { isValid: useRoot1 || useRoot2, value: x }
|
|
}
|
|
-function invertSqrt(number) {
|
|
- return uvRatio(_1n, number);
|
|
+
|
|
+function invertSqrt (number) {
|
|
+ return uvRatio(_1n, number)
|
|
}
|
|
-function modlLE(hash) {
|
|
- return mod(bytesToNumberLE(hash), CURVE.l);
|
|
+
|
|
+function modlLE (hash) {
|
|
+ return mod(bytesToNumberLE(hash), CURVE.l)
|
|
}
|
|
-function equalBytes(b1, b2) {
|
|
+
|
|
+function equalBytes (b1, b2) {
|
|
if (b1.length !== b2.length) {
|
|
- return false;
|
|
+ return false
|
|
}
|
|
for (let i = 0; i < b1.length; i++) {
|
|
if (b1[i] !== b2[i]) {
|
|
- return false;
|
|
+ return false
|
|
}
|
|
}
|
|
- return true;
|
|
+ return true
|
|
}
|
|
-function ensureBytes(hex, expectedLength) {
|
|
- const bytes = hex instanceof Uint8Array ? Uint8Array.from(hex) : hexToBytes(hex);
|
|
+
|
|
+function ensureBytes (hex, expectedLength) {
|
|
+ const bytes = hex instanceof Uint8Array ? Uint8Array.from(hex) : hexToBytes(hex)
|
|
if (typeof expectedLength === 'number' && bytes.length !== expectedLength)
|
|
- throw new Error(`Expected ${expectedLength} bytes`);
|
|
- return bytes;
|
|
+ throw new Error(`Expected ${expectedLength} bytes`)
|
|
+ return bytes
|
|
}
|
|
-function normalizeScalar(num, max, strict = true) {
|
|
+
|
|
+function normalizeScalar (num, max, strict = true) {
|
|
if (!max)
|
|
- throw new TypeError('Specify max value');
|
|
+ throw new TypeError('Specify max value')
|
|
if (typeof num === 'number' && Number.isSafeInteger(num))
|
|
- num = BigInt(num);
|
|
+ num = BigInt(num)
|
|
if (typeof num === 'bigint' && num < max) {
|
|
if (strict) {
|
|
if (_0n < num)
|
|
- return num;
|
|
- }
|
|
- else {
|
|
+ return num
|
|
+ } else {
|
|
if (_0n <= num)
|
|
- return num;
|
|
+ return num
|
|
}
|
|
}
|
|
- throw new TypeError('Expected valid scalar: 0 < scalar < max');
|
|
+ throw new TypeError('Expected valid scalar: 0 < scalar < max')
|
|
}
|
|
-function adjustBytes25519(bytes) {
|
|
- bytes[0] &= 248;
|
|
- bytes[31] &= 127;
|
|
- bytes[31] |= 64;
|
|
- return bytes;
|
|
+
|
|
+function adjustBytes25519 (bytes) {
|
|
+ bytes[0] &= 248
|
|
+ bytes[31] &= 127
|
|
+ bytes[31] |= 64
|
|
+ return bytes
|
|
}
|
|
-function decodeScalar25519(n) {
|
|
- return bytesToNumberLE(adjustBytes25519(ensureBytes(n, 32)));
|
|
+
|
|
+function decodeScalar25519 (n) {
|
|
+ return bytesToNumberLE(adjustBytes25519(ensureBytes(n, 32)))
|
|
}
|
|
-function checkPrivateKey(key) {
|
|
+
|
|
+function checkPrivateKey (key) {
|
|
key =
|
|
typeof key === 'bigint' || typeof key === 'number'
|
|
? numberTo32BytesBE(normalizeScalar(key, POW_2_256))
|
|
- : ensureBytes(key);
|
|
+ : ensureBytes(key)
|
|
if (key.length !== 32)
|
|
- throw new Error(`Expected 32 bytes`);
|
|
- return key;
|
|
-}
|
|
-function getKeyFromHash(hashed) {
|
|
- const head = adjustBytes25519(hashed.slice(0, 32));
|
|
- const prefix = hashed.slice(32, 64);
|
|
- const scalar = modlLE(head);
|
|
- const point = Point.BASE.multiply(scalar);
|
|
- const pointBytes = point.toRawBytes();
|
|
- return { head, prefix, scalar, point, pointBytes };
|
|
-}
|
|
-let _sha512Sync;
|
|
-function sha512s(...m) {
|
|
+ throw new Error(`Expected 32 bytes`)
|
|
+ return key
|
|
+}
|
|
+
|
|
+function getKeyFromHash (hashed) {
|
|
+ const head = adjustBytes25519(hashed.slice(0, 32))
|
|
+ const prefix = hashed.slice(32, 64)
|
|
+ const scalar = modlLE(head)
|
|
+ const point = Point.BASE.multiply(scalar)
|
|
+ const pointBytes = point.toRawBytes()
|
|
+ return { head, prefix, scalar, point, pointBytes }
|
|
+}
|
|
+
|
|
+let _sha512Sync
|
|
+
|
|
+function sha512s (...m) {
|
|
if (typeof _sha512Sync !== 'function')
|
|
- throw new Error('utils.sha512Sync must be set to use sync methods');
|
|
- return _sha512Sync(...m);
|
|
-}
|
|
-async function getExtendedPublicKey(key) {
|
|
- return getKeyFromHash(await utils.sha512(checkPrivateKey(key)));
|
|
-}
|
|
-function getExtendedPublicKeySync(key) {
|
|
- return getKeyFromHash(sha512s(checkPrivateKey(key)));
|
|
-}
|
|
-export async function getPublicKey(privateKey) {
|
|
- return (await getExtendedPublicKey(privateKey)).pointBytes;
|
|
-}
|
|
-function getPublicKeySync(privateKey) {
|
|
- return getExtendedPublicKeySync(privateKey).pointBytes;
|
|
-}
|
|
-export async function sign(message, privateKey) {
|
|
- message = ensureBytes(message);
|
|
- const { prefix, scalar, pointBytes } = await getExtendedPublicKey(privateKey);
|
|
- const r = modlLE(await utils.sha512(prefix, message));
|
|
- const R = Point.BASE.multiply(r);
|
|
- const k = modlLE(await utils.sha512(R.toRawBytes(), pointBytes, message));
|
|
- const s = mod(r + k * scalar, CURVE.l);
|
|
- return new Signature(R, s).toRawBytes();
|
|
-}
|
|
-function signSync(message, privateKey) {
|
|
- message = ensureBytes(message);
|
|
- const { prefix, scalar, pointBytes } = getExtendedPublicKeySync(privateKey);
|
|
- const r = modlLE(sha512s(prefix, message));
|
|
- const R = Point.BASE.multiply(r);
|
|
- const k = modlLE(sha512s(R.toRawBytes(), pointBytes, message));
|
|
- const s = mod(r + k * scalar, CURVE.l);
|
|
- return new Signature(R, s).toRawBytes();
|
|
-}
|
|
-function prepareVerification(sig, message, publicKey) {
|
|
- message = ensureBytes(message);
|
|
+ throw new Error('utils.sha512Sync must be set to use sync methods')
|
|
+ return _sha512Sync(...m)
|
|
+}
|
|
+
|
|
+async function getExtendedPublicKey (key) {
|
|
+ return getKeyFromHash(await utils.sha512(checkPrivateKey(key)))
|
|
+}
|
|
+
|
|
+function getExtendedPublicKeySync (key) {
|
|
+ return getKeyFromHash(sha512s(checkPrivateKey(key)))
|
|
+}
|
|
+
|
|
+export async function getPublicKey (privateKey) {
|
|
+ return (await getExtendedPublicKey(privateKey)).pointBytes
|
|
+}
|
|
+
|
|
+function getPublicKeySync (privateKey) {
|
|
+ return getExtendedPublicKeySync(privateKey).pointBytes
|
|
+}
|
|
+
|
|
+export async function sign (message, privateKey) {
|
|
+ message = ensureBytes(message)
|
|
+ const { prefix, scalar, pointBytes } = await getExtendedPublicKey(privateKey)
|
|
+ const r = modlLE(await utils.sha512(prefix, message))
|
|
+ const R = Point.BASE.multiply(r)
|
|
+ const k = modlLE(await utils.sha512(R.toRawBytes(), pointBytes, message))
|
|
+ const s = mod(r + k * scalar, CURVE.l)
|
|
+ return new Signature(R, s).toRawBytes()
|
|
+}
|
|
+
|
|
+function signSync (message, privateKey) {
|
|
+ message = ensureBytes(message)
|
|
+ const { prefix, scalar, pointBytes } = getExtendedPublicKeySync(privateKey)
|
|
+ const r = modlLE(sha512s(prefix, message))
|
|
+ const R = Point.BASE.multiply(r)
|
|
+ const k = modlLE(sha512s(R.toRawBytes(), pointBytes, message))
|
|
+ const s = mod(r + k * scalar, CURVE.l)
|
|
+ return new Signature(R, s).toRawBytes()
|
|
+}
|
|
+
|
|
+function prepareVerification (sig, message, publicKey) {
|
|
+ message = ensureBytes(message)
|
|
if (!(publicKey instanceof Point))
|
|
- publicKey = Point.fromHex(publicKey, false);
|
|
- const { r, s } = sig instanceof Signature ? sig.assertValidity() : Signature.fromHex(sig);
|
|
- const SB = ExtendedPoint.BASE.multiplyUnsafe(s);
|
|
- return { r, s, SB, pub: publicKey, msg: message };
|
|
-}
|
|
-function finishVerification(publicKey, r, SB, hashed) {
|
|
- const k = modlLE(hashed);
|
|
- const kA = ExtendedPoint.fromAffine(publicKey).multiplyUnsafe(k);
|
|
- const RkA = ExtendedPoint.fromAffine(r).add(kA);
|
|
- return RkA.subtract(SB).multiplyUnsafe(CURVE.h).equals(ExtendedPoint.ZERO);
|
|
-}
|
|
-export async function verify(sig, message, publicKey) {
|
|
- const { r, SB, msg, pub } = prepareVerification(sig, message, publicKey);
|
|
- const hashed = await utils.sha512(r.toRawBytes(), pub.toRawBytes(), msg);
|
|
- return finishVerification(pub, r, SB, hashed);
|
|
-}
|
|
-function verifySync(sig, message, publicKey) {
|
|
- const { r, SB, msg, pub } = prepareVerification(sig, message, publicKey);
|
|
- const hashed = sha512s(r.toRawBytes(), pub.toRawBytes(), msg);
|
|
- return finishVerification(pub, r, SB, hashed);
|
|
-}
|
|
+ publicKey = Point.fromHex(publicKey, false)
|
|
+ const { r, s } = sig instanceof Signature ? sig.assertValidity() : Signature.fromHex(sig)
|
|
+ const SB = ExtendedPoint.BASE.multiplyUnsafe(s)
|
|
+ return { r, s, SB, pub: publicKey, msg: message }
|
|
+}
|
|
+
|
|
+function finishVerification (publicKey, r, SB, hashed) {
|
|
+ const k = modlLE(hashed)
|
|
+ const kA = ExtendedPoint.fromAffine(publicKey).multiplyUnsafe(k)
|
|
+ const RkA = ExtendedPoint.fromAffine(r).add(kA)
|
|
+ return RkA.subtract(SB).multiplyUnsafe(CURVE.h).equals(ExtendedPoint.ZERO)
|
|
+}
|
|
+
|
|
+export async function verify (sig, message, publicKey) {
|
|
+ const { r, SB, msg, pub } = prepareVerification(sig, message, publicKey)
|
|
+ const hashed = await utils.sha512(r.toRawBytes(), pub.toRawBytes(), msg)
|
|
+ return finishVerification(pub, r, SB, hashed)
|
|
+}
|
|
+
|
|
+function verifySync (sig, message, publicKey) {
|
|
+ const { r, SB, msg, pub } = prepareVerification(sig, message, publicKey)
|
|
+ const hashed = sha512s(r.toRawBytes(), pub.toRawBytes(), msg)
|
|
+ return finishVerification(pub, r, SB, hashed)
|
|
+}
|
|
+
|
|
export const sync = {
|
|
getExtendedPublicKey: getExtendedPublicKeySync,
|
|
getPublicKey: getPublicKeySync,
|
|
sign: signSync,
|
|
verify: verifySync,
|
|
-};
|
|
-export async function getSharedSecret(privateKey, publicKey) {
|
|
- const { head } = await getExtendedPublicKey(privateKey);
|
|
- const u = Point.fromHex(publicKey).toX25519();
|
|
- return curve25519.scalarMult(head, u);
|
|
-}
|
|
-Point.BASE._setWindowSize(8);
|
|
-function cswap(swap, x_2, x_3) {
|
|
- const dummy = mod(swap * (x_2 - x_3));
|
|
- x_2 = mod(x_2 - dummy);
|
|
- x_3 = mod(x_3 + dummy);
|
|
- return [x_2, x_3];
|
|
-}
|
|
-function montgomeryLadder(pointU, scalar) {
|
|
- const { P } = CURVE;
|
|
- const u = normalizeScalar(pointU, P);
|
|
- const k = normalizeScalar(scalar, P);
|
|
- const a24 = BigInt(121665);
|
|
- const x_1 = u;
|
|
- let x_2 = _1n;
|
|
- let z_2 = _0n;
|
|
- let x_3 = u;
|
|
- let z_3 = _1n;
|
|
- let swap = _0n;
|
|
- let sw;
|
|
- for (let t = BigInt(255 - 1); t >= _0n; t--) {
|
|
- const k_t = (k >> t) & _1n;
|
|
- swap ^= k_t;
|
|
- sw = cswap(swap, x_2, x_3);
|
|
- x_2 = sw[0];
|
|
- x_3 = sw[1];
|
|
- sw = cswap(swap, z_2, z_3);
|
|
- z_2 = sw[0];
|
|
- z_3 = sw[1];
|
|
- swap = k_t;
|
|
- const A = x_2 + z_2;
|
|
- const AA = mod(A * A);
|
|
- const B = x_2 - z_2;
|
|
- const BB = mod(B * B);
|
|
- const E = AA - BB;
|
|
- const C = x_3 + z_3;
|
|
- const D = x_3 - z_3;
|
|
- const DA = mod(D * A);
|
|
- const CB = mod(C * B);
|
|
- const dacb = DA + CB;
|
|
- const da_cb = DA - CB;
|
|
- x_3 = mod(dacb * dacb);
|
|
- z_3 = mod(x_1 * mod(da_cb * da_cb));
|
|
- x_2 = mod(AA * BB);
|
|
- z_2 = mod(E * (AA + mod(a24 * E)));
|
|
- }
|
|
- sw = cswap(swap, x_2, x_3);
|
|
- x_2 = sw[0];
|
|
- x_3 = sw[1];
|
|
- sw = cswap(swap, z_2, z_3);
|
|
- z_2 = sw[0];
|
|
- z_3 = sw[1];
|
|
- const { pow_p_5_8, b2 } = pow_2_252_3(z_2);
|
|
- const xp2 = mod(pow2(pow_p_5_8, BigInt(3)) * b2);
|
|
- return mod(x_2 * xp2);
|
|
-}
|
|
-function encodeUCoordinate(u) {
|
|
- return numberTo32BytesLE(mod(u, CURVE.P));
|
|
-}
|
|
-function decodeUCoordinate(uEnc) {
|
|
- const u = ensureBytes(uEnc, 32);
|
|
- u[31] &= 127;
|
|
- return bytesToNumberLE(u);
|
|
}
|
|
+
|
|
+export async function getSharedSecret (privateKey, publicKey) {
|
|
+ const { head } = await getExtendedPublicKey(privateKey)
|
|
+ const u = Point.fromHex(publicKey).toX25519()
|
|
+ return curve25519.scalarMult(head, u)
|
|
+}
|
|
+
|
|
+Point.BASE._setWindowSize(8)
|
|
+
|
|
+function cswap (swap, x_2, x_3) {
|
|
+ const dummy = mod(swap * (x_2 - x_3))
|
|
+ x_2 = mod(x_2 - dummy)
|
|
+ x_3 = mod(x_3 + dummy)
|
|
+ return [x_2, x_3]
|
|
+}
|
|
+
|
|
+function montgomeryLadder (pointU, scalar) {
|
|
+ const { P } = CURVE
|
|
+ const u = normalizeScalar(pointU, P)
|
|
+ const k = normalizeScalar(scalar, P)
|
|
+ const a24 = BigInt(121665)
|
|
+ const x_1 = u
|
|
+ let x_2 = _1n
|
|
+ let z_2 = _0n
|
|
+ let x_3 = u
|
|
+ let z_3 = _1n
|
|
+ let swap = _0n
|
|
+ let sw
|
|
+ for (let t = BigInt(255 - 1); t >= _0n; t--) {
|
|
+ const k_t = (k >> t) & _1n
|
|
+ swap ^= k_t
|
|
+ sw = cswap(swap, x_2, x_3)
|
|
+ x_2 = sw[0]
|
|
+ x_3 = sw[1]
|
|
+ sw = cswap(swap, z_2, z_3)
|
|
+ z_2 = sw[0]
|
|
+ z_3 = sw[1]
|
|
+ swap = k_t
|
|
+ const A = x_2 + z_2
|
|
+ const AA = mod(A * A)
|
|
+ const B = x_2 - z_2
|
|
+ const BB = mod(B * B)
|
|
+ const E = AA - BB
|
|
+ const C = x_3 + z_3
|
|
+ const D = x_3 - z_3
|
|
+ const DA = mod(D * A)
|
|
+ const CB = mod(C * B)
|
|
+ const dacb = DA + CB
|
|
+ const da_cb = DA - CB
|
|
+ x_3 = mod(dacb * dacb)
|
|
+ z_3 = mod(x_1 * mod(da_cb * da_cb))
|
|
+ x_2 = mod(AA * BB)
|
|
+ z_2 = mod(E * (AA + mod(a24 * E)))
|
|
+ }
|
|
+ sw = cswap(swap, x_2, x_3)
|
|
+ x_2 = sw[0]
|
|
+ x_3 = sw[1]
|
|
+ sw = cswap(swap, z_2, z_3)
|
|
+ z_2 = sw[0]
|
|
+ z_3 = sw[1]
|
|
+ const { pow_p_5_8, b2 } = pow_2_252_3(z_2)
|
|
+ const xp2 = mod(pow2(pow_p_5_8, BigInt(3)) * b2)
|
|
+ return mod(x_2 * xp2)
|
|
+}
|
|
+
|
|
+function encodeUCoordinate (u) {
|
|
+ return numberTo32BytesLE(mod(u, CURVE.P))
|
|
+}
|
|
+
|
|
+function decodeUCoordinate (uEnc) {
|
|
+ const u = ensureBytes(uEnc, 32)
|
|
+ u[31] &= 127
|
|
+ return bytesToNumberLE(u)
|
|
+}
|
|
+
|
|
export const curve25519 = {
|
|
BASE_POINT_U: '0900000000000000000000000000000000000000000000000000000000000000',
|
|
- scalarMult(privateKey, publicKey) {
|
|
- const u = decodeUCoordinate(publicKey);
|
|
- const p = decodeScalar25519(privateKey);
|
|
- const pu = montgomeryLadder(u, p);
|
|
+ scalarMult (privateKey, publicKey) {
|
|
+ const u = decodeUCoordinate(publicKey)
|
|
+ const p = decodeScalar25519(privateKey)
|
|
+ const pu = montgomeryLadder(u, p)
|
|
if (pu === _0n)
|
|
- throw new Error('Invalid private or public key received');
|
|
- return encodeUCoordinate(pu);
|
|
+ throw new Error('Invalid private or public key received')
|
|
+ return encodeUCoordinate(pu)
|
|
},
|
|
- scalarMultBase(privateKey) {
|
|
- return curve25519.scalarMult(privateKey, curve25519.BASE_POINT_U);
|
|
+ scalarMultBase (privateKey) {
|
|
+ return curve25519.scalarMult(privateKey, curve25519.BASE_POINT_U)
|
|
},
|
|
-};
|
|
+}
|
|
const crypto = {
|
|
node: nodeCrypto,
|
|
web: typeof self === 'object' && 'crypto' in self ? self.crypto : undefined,
|
|
-};
|
|
+}
|
|
export const utils = {
|
|
bytesToHex,
|
|
hexToBytes,
|
|
@@ -834,56 +944,52 @@ export const utils = {
|
|
'c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa',
|
|
],
|
|
hashToPrivateScalar: (hash) => {
|
|
- hash = ensureBytes(hash);
|
|
+ hash = ensureBytes(hash)
|
|
if (hash.length < 40 || hash.length > 1024)
|
|
- throw new Error('Expected 40-1024 bytes of private key as per FIPS 186');
|
|
- return mod(bytesToNumberLE(hash), CURVE.l - _1n) + _1n;
|
|
+ throw new Error('Expected 40-1024 bytes of private key as per FIPS 186')
|
|
+ return mod(bytesToNumberLE(hash), CURVE.l - _1n) + _1n
|
|
},
|
|
randomBytes: (bytesLength = 32) => {
|
|
if (crypto.web) {
|
|
- return crypto.web.getRandomValues(new Uint8Array(bytesLength));
|
|
- }
|
|
- else if (crypto.node) {
|
|
- const { randomBytes } = crypto.node;
|
|
- return new Uint8Array(randomBytes(bytesLength).buffer);
|
|
- }
|
|
- else {
|
|
- throw new Error("The environment doesn't have randomBytes function");
|
|
+ return crypto.web.getRandomValues(new Uint8Array(bytesLength))
|
|
+ } else if (crypto.node) {
|
|
+ const { randomBytes } = crypto.node
|
|
+ return new Uint8Array(randomBytes(bytesLength).buffer)
|
|
+ } else {
|
|
+ throw new Error('The environment doesn\'t have randomBytes function')
|
|
}
|
|
},
|
|
randomPrivateKey: () => {
|
|
- return utils.randomBytes(32);
|
|
+ return utils.randomBytes(32)
|
|
},
|
|
sha512: async (...messages) => {
|
|
- const message = concatBytes(...messages);
|
|
+ const message = concatBytes(...messages)
|
|
if (crypto.web) {
|
|
- const buffer = await crypto.web.subtle.digest('SHA-512', message.buffer);
|
|
- return new Uint8Array(buffer);
|
|
- }
|
|
- else if (crypto.node) {
|
|
- return Uint8Array.from(crypto.node.createHash('sha512').update(message).digest());
|
|
- }
|
|
- else {
|
|
- throw new Error("The environment doesn't have sha512 function");
|
|
+ const buffer = await crypto.web.subtle.digest('SHA-512', message.buffer)
|
|
+ return new Uint8Array(buffer)
|
|
+ } else if (crypto.node) {
|
|
+ return Uint8Array.from(crypto.node.createHash('sha512').update(message).digest())
|
|
+ } else {
|
|
+ throw new Error('The environment doesn\'t have sha512 function')
|
|
}
|
|
},
|
|
- precompute(windowSize = 8, point = Point.BASE) {
|
|
- const cached = point.equals(Point.BASE) ? point : new Point(point.x, point.y);
|
|
- cached._setWindowSize(windowSize);
|
|
- cached.multiply(_2n);
|
|
- return cached;
|
|
+ precompute (windowSize = 8, point = Point.BASE) {
|
|
+ const cached = point.equals(Point.BASE) ? point : new Point(point.x, point.y)
|
|
+ cached._setWindowSize(windowSize)
|
|
+ cached.multiply(_2n)
|
|
+ return cached
|
|
},
|
|
sha512Sync: undefined,
|
|
-};
|
|
+}
|
|
Object.defineProperties(utils, {
|
|
sha512Sync: {
|
|
configurable: false,
|
|
- get() {
|
|
- return _sha512Sync;
|
|
+ get () {
|
|
+ return _sha512Sync
|
|
},
|
|
- set(val) {
|
|
+ set (val) {
|
|
if (!_sha512Sync)
|
|
- _sha512Sync = val;
|
|
+ _sha512Sync = val
|
|
},
|
|
},
|
|
-});
|
|
+})
|