noble-curves-extended
Version:
This project extends @noble/curves to allow randomBytes to be specified externally
325 lines (324 loc) • 10.8 kB
JavaScript
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
};