nwcprovider/static/js/noble-secp256k1.min.js
2024-09-07 09:09:22 +00:00

520 lines
13 KiB
JavaScript

/*! noble-secp256k1 - MIT License (c) 2019 Paul Miller (paulmillr.com) */
const B256 = 2n ** 256n,
P = B256 - 0x1000003d1n,
N = B256 - 0x14551231950b75fc4402da1732fc9bebfn,
Gx = 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798n,
Gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8n,
CURVE = { p: P, n: N, a: 0n, b: 7n, Gx, Gy },
fLen = 32,
crv = (t) => mod(mod(t * t) * t + CURVE.b),
err = (t = "") => {
throw new Error(t);
},
big = (t) => "bigint" == typeof t,
str = (t) => "string" == typeof t,
fe = (t) => big(t) && 0n < t && t < P,
ge = (t) => big(t) && 0n < t && t < N,
isu8 = (t) =>
t instanceof Uint8Array ||
(null != t && "object" == typeof t && "Uint8Array" === t.constructor.name),
au8 = (t, n) =>
!isu8(t) || ("number" == typeof n && n > 0 && t.length !== n)
? err("Uint8Array expected")
: t,
u8n = (t) => new Uint8Array(t),
toU8 = (t, n) => au8(str(t) ? h2b(t) : u8n(au8(t)), n),
mod = (t, n = P) => {
let e = t % n;
return e >= 0n ? e : n + e;
},
isPoint = (t) => (t instanceof Point ? t : err("Point expected"));
class Point {
constructor(t, n, e) {
(this.px = t), (this.py = n), (this.pz = e);
}
static fromAffine(t) {
return 0n === t.x && 0n === t.y ? Point.ZERO : new Point(t.x, t.y, 1n);
}
static fromHex(t) {
let n;
const e = (t = toU8(t))[0],
r = t.subarray(1),
o = slcNum(r, 0, 32),
i = t.length;
if (33 === i && [2, 3].includes(e)) {
fe(o) || err("Point hex invalid: x not FE");
let t = sqrt(crv(o));
!(1 & ~e) !== (1n === (1n & t)) && (t = mod(-t)),
(n = new Point(o, t, 1n));
}
return (
65 === i && 4 === e && (n = new Point(o, slcNum(r, 32, 64), 1n)),
n ? n.ok() : err("Point is not on curve")
);
}
static fromPrivateKey(t) {
return G.mul(toPriv(t));
}
get x() {
return this.aff().x;
}
get y() {
return this.aff().y;
}
equals(t) {
const { px: n, py: e, pz: r } = this,
{ px: o, py: i, pz: s } = isPoint(t),
a = mod(n * s),
c = mod(o * r),
d = mod(e * s),
u = mod(i * r);
return a === c && d === u;
}
negate() {
return new Point(this.px, mod(-this.py), this.pz);
}
double() {
return this.add(this);
}
add(t) {
const { px: n, py: e, pz: r } = this,
{ px: o, py: i, pz: s } = isPoint(t),
{ a, b: c } = CURVE;
let d = 0n,
u = 0n,
m = 0n;
const h = mod(3n * c);
let l = mod(n * o),
y = mod(e * i),
f = mod(r * s),
p = mod(n + e),
b = mod(o + i);
(p = mod(p * b)), (b = mod(l + y)), (p = mod(p - b)), (b = mod(n + r));
let g = mod(o + s);
return (
(b = mod(b * g)),
(g = mod(l + f)),
(b = mod(b - g)),
(g = mod(e + r)),
(d = mod(i + s)),
(g = mod(g * d)),
(d = mod(y + f)),
(g = mod(g - d)),
(m = mod(a * b)),
(d = mod(h * f)),
(m = mod(d + m)),
(d = mod(y - m)),
(m = mod(y + m)),
(u = mod(d * m)),
(y = mod(l + l)),
(y = mod(y + l)),
(f = mod(a * f)),
(b = mod(h * b)),
(y = mod(y + f)),
(f = mod(l - f)),
(f = mod(a * f)),
(b = mod(b + f)),
(l = mod(y * b)),
(u = mod(u + l)),
(l = mod(g * b)),
(d = mod(p * d)),
(d = mod(d - l)),
(l = mod(p * y)),
(m = mod(g * m)),
(m = mod(m + l)),
new Point(d, u, m)
);
}
mul(t, n = !0) {
if (!n && 0n === t) return I;
if ((ge(t) || err("invalid scalar"), this.equals(G))) return wNAF(t).p;
let e = I,
r = G;
for (let o = this; t > 0n; o = o.double(), t >>= 1n)
1n & t ? (e = e.add(o)) : n && (r = r.add(o));
return e;
}
mulAddQUns(t, n, e) {
return this.mul(n, !1).add(t.mul(e, !1)).ok();
}
toAffine() {
const { px: t, py: n, pz: e } = this;
if (this.equals(I)) return { x: 0n, y: 0n };
if (1n === e) return { x: t, y: n };
const r = inv(e);
return (
1n !== mod(e * r) && err("invalid inverse"),
{ x: mod(t * r), y: mod(n * r) }
);
}
assertValidity() {
const { x: t, y: n } = this.aff();
return (
(fe(t) && fe(n)) || err("Point invalid: x or y"),
mod(n * n) === crv(t) ? this : err("Point invalid: not on curve")
);
}
multiply(t) {
return this.mul(t);
}
aff() {
return this.toAffine();
}
ok() {
return this.assertValidity();
}
toHex(t = !0) {
const { x: n, y: e } = this.aff();
return (
(t ? (0n === (1n & e) ? "02" : "03") : "04") + n2h(n) + (t ? "" : n2h(e))
);
}
toRawBytes(t = !0) {
return h2b(this.toHex(t));
}
}
(Point.BASE = new Point(Gx, Gy, 1n)), (Point.ZERO = new Point(0n, 1n, 0n));
const { BASE: G, ZERO: I } = Point,
padh = (t, n) => t.toString(16).padStart(n, "0"),
b2h = (t) =>
Array.from(t)
.map((t) => padh(t, 2))
.join(""),
h2b = (t) => {
const n = t.length;
(!str(t) || n % 2) && err("hex invalid 1");
const e = u8n(n / 2);
for (let n = 0; n < e.length; n++) {
const r = 2 * n,
o = t.slice(r, r + 2),
i = Number.parseInt(o, 16);
(Number.isNaN(i) || i < 0) && err("hex invalid 2"), (e[n] = i);
}
return e;
},
b2n = (t) => BigInt("0x" + (b2h(t) || "0")),
slcNum = (t, n, e) => b2n(t.slice(n, e)),
n2b = (t) =>
big(t) && t >= 0n && t < B256 ? h2b(padh(t, 64)) : err("bigint expected"),
n2h = (t) => b2h(n2b(t)),
concatB = (...t) => {
const n = u8n(t.reduce((t, n) => t + au8(n).length, 0));
let e = 0;
return (
t.forEach((t) => {
n.set(t, e), (e += t.length);
}),
n
);
},
inv = (t, n = P) => {
(0n === t || n <= 0n) && err("no inverse n=" + t + " mod=" + n);
let e = mod(t, n),
r = n,
o = 0n,
i = 1n,
s = 1n,
a = 0n;
for (; 0n !== e; ) {
const t = r / e,
n = r % e,
c = o - s * t,
d = i - a * t;
(r = e), (e = n), (o = s), (i = a), (s = c), (a = d);
}
return 1n === r ? mod(o, n) : err("no inverse");
},
sqrt = (t) => {
let n = 1n;
for (let e = t, r = (P + 1n) / 4n; r > 0n; r >>= 1n)
1n & r && (n = (n * e) % P), (e = (e * e) % P);
return mod(n * n) === t ? n : err("sqrt invalid");
},
toPriv = (t) => (
big(t) || (t = b2n(toU8(t, 32))),
ge(t) ? t : err("private key out of range")
),
moreThanHalfN = (t) => t > N >> 1n,
getPublicKey = (t, n = !0) => Point.fromPrivateKey(t).toRawBytes(n);
class Signature {
constructor(t, n, e) {
(this.r = t), (this.s = n), (this.recovery = e), this.assertValidity();
}
static fromCompact(t) {
return (
(t = toU8(t, 64)), new Signature(slcNum(t, 0, 32), slcNum(t, 32, 64))
);
}
assertValidity() {
return ge(this.r) && ge(this.s) ? this : err();
}
addRecoveryBit(t) {
return new Signature(this.r, this.s, t);
}
hasHighS() {
return moreThanHalfN(this.s);
}
normalizeS() {
return this.hasHighS()
? new Signature(this.r, mod(this.s, N), this.recovery)
: this;
}
recoverPublicKey(t) {
const { r: n, s: e, recovery: r } = this;
[0, 1, 2, 3].includes(r) || err("recovery id invalid");
const o = bits2int_modN(toU8(t, 32)),
i = 2 === r || 3 === r ? n + N : n;
i >= P && err("q.x invalid");
const s = 1 & r ? "03" : "02",
a = Point.fromHex(s + n2h(i)),
c = inv(i, N),
d = mod(-o * c, N),
u = mod(e * c, N);
return G.mulAddQUns(a, d, u);
}
toCompactRawBytes() {
return h2b(this.toCompactHex());
}
toCompactHex() {
return n2h(this.r) + n2h(this.s);
}
}
const bits2int = (t) => {
const n = 8 * t.length - 256,
e = b2n(t);
return n > 0 ? e >> BigInt(n) : e;
},
bits2int_modN = (t) => mod(bits2int(t), N),
i2o = (t) => n2b(t),
cr = () =>
"object" == typeof globalThis && "crypto" in globalThis
? globalThis.crypto
: void 0;
let _hmacSync;
const optS = { lowS: !0 },
optV = { lowS: !0 },
prepSig = (t, n, e = optS) => {
["der", "recovered", "canonical"].some((t) => t in e) &&
err("sign() legacy options not supported");
let { lowS: r } = e;
null == r && (r = !0);
const o = bits2int_modN(toU8(t)),
i = i2o(o),
s = toPriv(n),
a = [i2o(s), i];
let c = e.extraEntropy;
if (c) {
!0 === c && (c = etc.randomBytes(32));
const t = toU8(c);
32 !== t.length && err(), a.push(t);
}
const d = o;
return {
seed: concatB(...a),
k2sig: (t) => {
const n = bits2int(t);
if (!ge(n)) return;
const e = inv(n, N),
o = G.mul(n).aff(),
i = mod(o.x, N);
if (0n === i) return;
const a = mod(e * mod(d + mod(s * i, N), N), N);
if (0n === a) return;
let c = a,
u = (o.x === i ? 0 : 2) | Number(1n & o.y);
return (
r && moreThanHalfN(a) && ((c = mod(-a, N)), (u ^= 1)),
new Signature(i, c, u)
);
},
};
};
function hmacDrbg(t) {
let n = u8n(32),
e = u8n(32),
r = 0;
const o = () => {
n.fill(1), e.fill(0), (r = 0);
},
i = "drbg: tried 1000 values";
if (t) {
const t = (...t) => etc.hmacSha256Async(e, n, ...t),
s = async (r = u8n()) => {
(e = await t(u8n([0]), r)),
(n = await t()),
0 !== r.length && ((e = await t(u8n([1]), r)), (n = await t()));
},
a = async () => (r++ >= 1e3 && err(i), (n = await t()), n);
return async (t, n) => {
let e;
for (o(), await s(t); !(e = n(await a())); ) await s();
return o(), e;
};
}
{
const t = (...t) => {
const r = _hmacSync;
return r || err("etc.hmacSha256Sync not set"), r(e, n, ...t);
},
s = (r = u8n()) => {
(e = t(u8n([0]), r)),
(n = t()),
0 !== r.length && ((e = t(u8n([1]), r)), (n = t()));
},
a = () => (r++ >= 1e3 && err(i), (n = t()), n);
return (t, n) => {
let e;
for (o(), s(t); !(e = n(a())); ) s();
return o(), e;
};
}
}
const signAsync = async (t, n, e = optS) => {
const { seed: r, k2sig: o } = prepSig(t, n, e);
return hmacDrbg(!0)(r, o);
},
sign = (t, n, e = optS) => {
const { seed: r, k2sig: o } = prepSig(t, n, e);
return hmacDrbg(!1)(r, o);
},
verify = (t, n, e, r = optV) => {
let o,
i,
s,
{ lowS: a } = r;
null == a && (a = !0),
"strict" in r && err("verify() legacy options not supported");
const c = t && "object" == typeof t && "r" in t;
c || 64 === toU8(t).length || err("signature must be 64 bytes");
try {
(o = c
? new Signature(t.r, t.s).assertValidity()
: Signature.fromCompact(t)),
(i = bits2int_modN(toU8(n))),
(s = e instanceof Point ? e.ok() : Point.fromHex(e));
} catch (t) {
return !1;
}
if (!o) return !1;
const { r: d, s: u } = o;
if (a && moreThanHalfN(u)) return !1;
let m;
try {
const t = inv(u, N),
n = mod(i * t, N),
e = mod(d * t, N);
m = G.mulAddQUns(s, n, e).aff();
} catch (t) {
return !1;
}
if (!m) return !1;
return mod(m.x, N) === d;
},
getSharedSecret = (t, n, e = !0) =>
Point.fromHex(n).mul(toPriv(t)).toRawBytes(e),
hashToPrivateKey = (t) => {
((t = toU8(t)).length < 40 || t.length > 1024) &&
err("expected proper params");
const n = mod(b2n(t), N - 1n) + 1n;
return n2b(n);
},
etc = {
hexToBytes: h2b,
bytesToHex: b2h,
concatBytes: concatB,
bytesToNumberBE: b2n,
numberToBytesBE: n2b,
mod,
invert: inv,
hmacSha256Async: async (t, ...n) => {
const e = cr(),
r = e && e.subtle;
if (!r) return err("etc.hmacSha256Async not set");
const o = await r.importKey(
"raw",
t,
{ name: "HMAC", hash: { name: "SHA-256" } },
!1,
["sign"],
);
return u8n(await r.sign("HMAC", o, concatB(...n)));
},
hmacSha256Sync: _hmacSync,
hashToPrivateKey,
randomBytes: (t = 32) => {
const n = cr();
return (
(n && n.getRandomValues) ||
err("crypto.getRandomValues must be defined"),
n.getRandomValues(u8n(t))
);
},
},
utils = {
normPrivateKeyToScalar: toPriv,
isValidPrivateKey: (t) => {
try {
return !!toPriv(t);
} catch (t) {
return !1;
}
},
randomPrivateKey: () => hashToPrivateKey(etc.randomBytes(48)),
precompute: (t = 8, n = G) => (n.multiply(3n), n),
};
Object.defineProperties(etc, {
hmacSha256Sync: {
configurable: !1,
get: () => _hmacSync,
set(t) {
_hmacSync || (_hmacSync = t);
},
},
});
const W = 8,
precompute = () => {
const t = [];
let n = G,
e = n;
for (let r = 0; r < 33; r++) {
(e = n), t.push(e);
for (let r = 1; r < 128; r++) (e = e.add(n)), t.push(e);
n = e.double();
}
return t;
};
let Gpows;
const wNAF = (t) => {
const n = Gpows || (Gpows = precompute()),
e = (t, n) => {
let e = n.negate();
return t ? e : n;
};
let r = I,
o = G;
const i = BigInt(255),
s = BigInt(8);
for (let a = 0; a < 33; a++) {
const c = 128 * a;
let d = Number(t & i);
(t >>= s), d > 128 && ((d -= 256), (t += 1n));
const u = c,
m = c + Math.abs(d) - 1,
h = a % 2 != 0,
l = d < 0;
0 === d ? (o = o.add(e(h, n[u]))) : (r = r.add(e(l, n[m])));
}
return { p: r, f: o };
};
export {
getPublicKey,
sign,
signAsync,
verify,
CURVE,
getSharedSecret,
etc,
utils,
Point as ProjectivePoint,
Signature,
};