UNPKG

noble-curves-extended

Version:

This project extends @noble/curves to allow randomBytes to be specified externally

325 lines (324 loc) 10.8 kB
import { Field as w, getMinHashLength as M, mapHashToField as O, pow2 as i, mod as B, isNegativeLE as T } from "@noble/curves/abstract/modular"; import { hmac as Q } from "@noble/hashes/hmac"; import { concatBytes as z, isBytes as g } from "@noble/hashes/utils"; import { weierstrass as N } from "@noble/curves/abstract/weierstrass"; import { sha256 as X, sha384 as Y, sha512 as G } from "@noble/hashes/sha2"; import { toB64U as m, fromB64U as k, compareUint8Arrays as Z } from "u8a-utils"; import { sha256 as ff } from "@noble/hashes/sha2.js"; import { twistedEdwards as tf } from "@noble/curves/abstract/edwards"; const K = w( BigInt("0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001") ), Kf = (t) => ({ utils: { randomPrivateKey: () => { const n = M(K.ORDER); return O(t(n), K.ORDER); } } }), nf = (t) => (f, ...n) => Q(t, f, z(...n)); function v(t, f, n) { const c = (o) => N({ ...t, hash: o, randomBytes: n, hmac: nf(o) }); return { ...c(f), create: c }; } const h = (t) => ({ ...t, sign: (n, c, o) => (g(n) && (n = Uint8Array.from(n)), g(c) && (c = Uint8Array.from(c)), t.sign(n, c, o)), verify: (n, c, o, e) => (g(n) && (n = Uint8Array.from(n)), g(c) && (c = Uint8Array.from(c)), g(o) && (o = Uint8Array.from(o)), t.verify(n, c, o, e)) }), cf = ({ curve: t, publicKey: f }) => { try { return t.ProjectivePoint.fromHex(f).assertValidity(), !0; } catch (n) { return console.log(n), !1; } }, S = { p: BigInt( "0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff" ), n: BigInt( "0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551" ), h: BigInt(1), a: BigInt( "0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc" ), b: BigInt( "0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b" ), Gx: BigInt( "0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296" ), Gy: BigInt( "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5" ) }, V = { p: BigInt( "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff" ), n: BigInt( "0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973" ), h: BigInt(1), a: BigInt( "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffc" ), b: BigInt( "0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef" ), Gx: BigInt( "0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7" ), Gy: BigInt( "0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f" ) }, W = { p: BigInt( "0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" ), n: BigInt( "0x01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409" ), h: BigInt(1), a: BigInt( "0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc" ), b: BigInt( "0x0051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00" ), Gx: BigInt( "0x00c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66" ), Gy: BigInt( "0x011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650" ) }, ef = w(S.p), of = w(V.p), rf = w(W.p), af = (t) => { const f = v( { ...S, Fp: ef, lowS: !1 }, X, t ); return h(f); }, sf = (t) => { const f = v( { ...V, Fp: of, lowS: !1 }, Y, t ); return h(f); }, df = (t) => { const f = v( { ...W, Fp: rf, lowS: !1, allowedPrivateKeyLengths: [130, 131, 132] }, G, t ); return h(f); }, H = ({ curve: t, curveName: f, publicKey: n }) => { const o = t.ProjectivePoint.fromHex(n).toRawBytes(!1), e = (o.length - 1) / 2, r = o.slice(1, 1 + e), a = o.slice(1 + e); return { kty: "EC", crv: f, x: m(r), y: m(a) }; }, bf = ({ curve: t, curveName: f, privateKey: n }) => { const c = t.getPublicKey(n); return { ...H({ curve: t, curveName: f, publicKey: c }), d: m(n) }; }, $ = ({ curve: t, jwkPublicKey: f }) => { const { x: n, y: c } = f; if (!n || !c) throw new Error("Invalid JWK public key: missing x or y coordinates"); try { const o = k(n), e = k(c), r = new Uint8Array([4, ...o, ...e]); return t.ProjectivePoint.fromHex(r), r; } catch (o) { throw new Error( `Invalid JWK public key: invalid base64url coordinates, ${o}` ); } }, lf = ({ curve: t, jwkPrivateKey: f }) => { const { d: n } = f; if (!n) throw new Error("Invalid JWK private key: missing d coordinate"); const c = k(n); if (!t.utils.isValidPrivateKey(c)) throw new Error("Invalid JWK private key: invalid private key"); let o, e; try { o = t.getPublicKey(c, !1), e = $({ curve: t, jwkPublicKey: f }); } catch (r) { throw new Error(`Invalid JWK private key: invalid private key, ${r}`); } if (!Z(o, e)) throw new Error("Invalid JWK private key: invalid private key"); return c; }, Ff = (t, f) => { const n = (() => { switch (t) { case "P-256": return af(f); case "P-384": return sf(f); case "P-521": return df(f); default: throw new Error(`Unsupported NIST curve: ${t}`); } })(); return { ...n, curveName: t, randomBytes: f, toJwkPrivateKey: (c) => bf({ curve: n, curveName: t, privateKey: c }), toJwkPublicKey: (c) => H({ curve: n, curveName: t, publicKey: c }), toRawPrivateKey: (c) => lf({ curve: n, jwkPrivateKey: c }), toRawPublicKey: (c) => $({ curve: n, jwkPublicKey: c }), isValidPublicKey: (c) => cf({ curve: n, publicKey: c }) }; }, _ = { p: BigInt( "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f" ), n: BigInt( "0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141" ), h: BigInt(1), a: BigInt(0), b: BigInt(7), Gx: BigInt( "0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798" ), Gy: BigInt( "0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8" ) }, If = BigInt(1), E = BigInt(2), F = (t, f) => (t + f / E) / f; function Bf(t) { const f = _.p, n = BigInt(3), c = BigInt(6), o = BigInt(11), e = BigInt(22), r = BigInt(23), a = BigInt(44), I = BigInt(88), b = t * t * t % f, s = b * b * t % f, d = i(s, n, f) * s % f, l = i(d, n, f) * s % f, p = i(l, E, f) * b % f, u = i(p, o, f) * p % f, x = i(u, e, f) * u % f, y = i(x, a, f) * x % f, R = i(y, I, f) * y % f, q = i(R, a, f) * x % f, j = i(q, n, f) * s % f, D = i(j, r, f) * u % f, L = i(D, c, f) * b % f, J = i(L, E, f); if (!U.eql(U.sqr(J), t)) throw new Error("Cannot find square root"); return J; } const U = w(_.p, void 0, void 0, { sqrt: Bf }), Af = (t) => { const f = v( { ..._, Fp: U, lowS: !0, // Allow only low-S signatures by default in sign() and verify() endo: { // Endomorphism, see above beta: BigInt( "0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee" ), splitScalar: (n) => { const c = _.n, o = BigInt("0x3086d221a7d46bcde86c90e49284eb15"), e = -If * BigInt("0xe4437ed6010e88286f547fa90abfe4c3"), r = BigInt("0x114ca50f7a8e2f3f657c1108d9d44cfd8"), a = o, I = BigInt("0x100000000000000000000000000000000"), b = F(a * n, c), s = F(-e * n, c); let d = B(n - b * o - s * r, c), l = B(-b * e - s * a, c); const p = d > I, u = l > I; if (p && (d = c - d), u && (l = c - l), d > I || l > I) throw new Error("splitScalar: Endomorphism failed, k=" + n); return { k1neg: p, k1: d, k2neg: u, k2: l }; } } }, ff, t ); return h(f); }, gf = BigInt(1), A = BigInt(2), pf = BigInt(5), uf = BigInt(8), P = { p: BigInt( "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed" ), n: BigInt( "0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed" ), h: uf, a: BigInt( "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec" ), d: BigInt( "0x52036cee2b6ffe738cc740797779e89800700a4d4141d8ab75eb4dca135978a3" ), Gx: BigInt( "0x216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51a" ), Gy: BigInt( "0x6666666666666666666666666666666666666666666666666666666666666658" ) }; function wf(t) { const f = BigInt(10), n = BigInt(20), c = BigInt(40), o = BigInt(80), e = P.p, a = t * t % e * t % e, I = i(a, A, e) * a % e, b = i(I, gf, e) * t % e, s = i(b, pf, e) * b % e, d = i(s, f, e) * s % e, l = i(d, n, e) * d % e, p = i(l, c, e) * l % e, u = i(p, o, e) * p % e, x = i(u, o, e) * p % e, y = i(x, f, e) * s % e; return { pow_p_5_8: i(y, A, e) * t % e, b2: a }; } function xf(t) { return t[0] &= 248, t[31] &= 127, t[31] |= 64, t; } const C = /* @__PURE__ */ BigInt( "19681161376707505956807079304988542015446066515923890162744021073123829784752" ); function yf(t, f) { const n = P.p, c = B(f * f * f, n), o = B(c * c * f, n), e = wf(t * o).pow_p_5_8; let r = B(t * c * e, n); const a = B(f * r * r, n), I = r, b = B(r * C, n), s = a === t, d = a === B(-t, n), l = a === B(-t * C, n); return s && (r = I), (d || l) && (r = b), T(r, n) && (r = B(-r, n)), { isValid: s || d, value: r }; } const _f = w(P.p, void 0, !0), vf = { ...P, Fp: _f, hash: G, adjustScalarBytes: xf, // dom2 // Ratio of u to v. Allows us to combine inversion and square root. Uses algo from RFC8032 5.1.3. // Constant-time, u/√v uvRatio: yf }, Cf = (t) => { const f = tf({ ...vf, randomBytes: t }); return { ...f, sign: (c, o, e) => (g(c) && (c = Uint8Array.from(c)), g(o) && (o = Uint8Array.from(o)), f.sign(c, o, e)), verify: (c, o, e, r) => (g(c) && (c = Uint8Array.from(c)), g(o) && (o = Uint8Array.from(o)), g(e) && (e = Uint8Array.from(e)), f.verify(c, o, e, r)) }; }; export { K as bls12381Fr, Kf as createBls12_381, v as createCurve, Cf as createEd25519, nf as createHmacFn, Ff as createNistCurve, af as createP256, sf as createP384, df as createP521, Af as createSecp256k1, h as modifyCurve, bf as toJwkPrivateKey, H as toJwkPublicKey };