secp256k1 & other implementations: reduce bundle size by 20% by using PURE.

PURE annotation helps bundlers during tree-shaking and eliminates dead code.

* secp256k1: 75.4kb => 62.3kb

* ed25519: 67.5kb => 51.1kb

* ed448: 55.1kb => 44.0kb

* p256: 67.8kb => 59.8kb

* p384: 75.4kb => 67.4kb

* p521: 75.8kb => 67.8kb
This commit is contained in:
Paul Miller 2023-05-20 10:47:42 +02:00
parent 648fd2cc07
commit ff5b231e31
No known key found for this signature in database
GPG Key ID: 697079DA6878B89B
6 changed files with 190 additions and 180 deletions

@ -12,7 +12,7 @@ import {
Hex, Hex,
numberToBytesLE, numberToBytesLE,
} from './abstract/utils.js'; } from './abstract/utils.js';
import * as htf from './abstract/hash-to-curve.js'; import { createHasher, htfBasicOpts, expand_message_xmd } from './abstract/hash-to-curve.js';
import { AffinePoint } from './abstract/curve.js'; import { AffinePoint } from './abstract/curve.js';
/** /**
@ -142,21 +142,22 @@ export const ed25519ph = twistedEdwards({
prehash: sha512, prehash: sha512,
}); });
export const x25519 = montgomery({ export const x25519 = /* @__PURE__ */ (() =>
P: ED25519_P, montgomery({
a: BigInt(486662), P: ED25519_P,
montgomeryBits: 255, // n is 253 bits a: BigInt(486662),
nByteLength: 32, montgomeryBits: 255, // n is 253 bits
Gu: BigInt(9), nByteLength: 32,
powPminus2: (x: bigint): bigint => { Gu: BigInt(9),
const P = ED25519_P; powPminus2: (x: bigint): bigint => {
// x^(p-2) aka x^(2^255-21) const P = ED25519_P;
const { pow_p_5_8, b2 } = ed25519_pow_2_252_3(x); // x^(p-2) aka x^(2^255-21)
return mod(pow2(pow_p_5_8, BigInt(3), P) * b2, P); const { pow_p_5_8, b2 } = ed25519_pow_2_252_3(x);
}, return mod(pow2(pow_p_5_8, BigInt(3), P) * b2, P);
adjustScalarBytes, },
randomBytes, adjustScalarBytes,
}); randomBytes,
}))();
/** /**
* Converts ed25519 public key to x25519 public key. Uses formula: * Converts ed25519 public key to x25519 public key. Uses formula:
@ -260,29 +261,29 @@ function map_to_curve_elligator2_edwards25519(u: bigint) {
return { x: Fp.mul(xn, inv[0]), y: Fp.mul(yn, inv[1]) }; // 13. return (xn, xd, yn, yd) return { x: Fp.mul(xn, inv[0]), y: Fp.mul(yn, inv[1]) }; // 13. return (xn, xd, yn, yd)
} }
const { hashToCurve, encodeToCurve } = htf.createHasher( const htf = /* @__PURE__ */ (() =>
ed25519.ExtendedPoint, createHasher(
(scalars: bigint[]) => map_to_curve_elligator2_edwards25519(scalars[0]), ed25519.ExtendedPoint,
{ (scalars: bigint[]) => map_to_curve_elligator2_edwards25519(scalars[0]),
DST: 'edwards25519_XMD:SHA-512_ELL2_RO_', {
encodeDST: 'edwards25519_XMD:SHA-512_ELL2_NU_', DST: 'edwards25519_XMD:SHA-512_ELL2_RO_',
p: Fp.ORDER, encodeDST: 'edwards25519_XMD:SHA-512_ELL2_NU_',
m: 1, p: Fp.ORDER,
k: 128, m: 1,
expand: 'xmd', k: 128,
hash: sha512, expand: 'xmd',
} hash: sha512,
); }
export { hashToCurve, encodeToCurve }; ))();
export const hashToCurve = /* @__PURE__ */ (() => htf.hashToCurve)();
export const encodeToCurve = /* @__PURE__ */ (() => htf.encodeToCurve)();
function assertRstPoint(other: unknown) { function assertRstPoint(other: unknown) {
if (!(other instanceof RistrettoPoint)) throw new Error('RistrettoPoint expected'); if (!(other instanceof RistPoint)) throw new Error('RistrettoPoint expected');
} }
// √(-1) aka √(a) aka 2^((p-1)/4) // √(-1) aka √(a) aka 2^((p-1)/4)
const SQRT_M1 = BigInt( const SQRT_M1 = ED25519_SQRT_M1;
'19681161376707505956807079304988542015446066515923890162744021073123829784752'
);
// √(ad - 1) // √(ad - 1)
const SQRT_AD_MINUS_ONE = BigInt( const SQRT_AD_MINUS_ONE = BigInt(
'25063068953384623474111414158702152701244531502492656460079210482610430750235' '25063068953384623474111414158702152701244531502492656460079210482610430750235'
@ -339,16 +340,15 @@ function calcElligatorRistrettoMap(r0: bigint): ExtendedPoint {
* but it should work in its own namespace: do not combine those two. * but it should work in its own namespace: do not combine those two.
* https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-ristretto255-decaf448 * https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-ristretto255-decaf448
*/ */
export class RistrettoPoint { class RistPoint {
static BASE = new RistrettoPoint(ed25519.ExtendedPoint.BASE); static BASE: RistPoint;
static ZERO = new RistrettoPoint(ed25519.ExtendedPoint.ZERO); static ZERO: RistPoint;
// Private property to discourage combining ExtendedPoint + RistrettoPoint // Private property to discourage combining ExtendedPoint + RistrettoPoint
// Always use Ristretto encoding/decoding instead. // Always use Ristretto encoding/decoding instead.
constructor(private readonly ep: ExtendedPoint) {} constructor(private readonly ep: ExtendedPoint) {}
static fromAffine(ap: AffinePoint<bigint>) { static fromAffine(ap: AffinePoint<bigint>) {
return new RistrettoPoint(ed25519.ExtendedPoint.fromAffine(ap)); return new RistPoint(ed25519.ExtendedPoint.fromAffine(ap));
} }
/** /**
@ -358,13 +358,13 @@ export class RistrettoPoint {
* https://ristretto.group/formulas/elligator.html * https://ristretto.group/formulas/elligator.html
* @param hex 64-byte output of a hash function * @param hex 64-byte output of a hash function
*/ */
static hashToCurve(hex: Hex): RistrettoPoint { static hashToCurve(hex: Hex): RistPoint {
hex = ensureBytes('ristrettoHash', hex, 64); hex = ensureBytes('ristrettoHash', hex, 64);
const r1 = bytes255ToNumberLE(hex.slice(0, 32)); const r1 = bytes255ToNumberLE(hex.slice(0, 32));
const R1 = calcElligatorRistrettoMap(r1); const R1 = calcElligatorRistrettoMap(r1);
const r2 = bytes255ToNumberLE(hex.slice(32, 64)); const r2 = bytes255ToNumberLE(hex.slice(32, 64));
const R2 = calcElligatorRistrettoMap(r2); const R2 = calcElligatorRistrettoMap(r2);
return new RistrettoPoint(R1.add(R2)); return new RistPoint(R1.add(R2));
} }
/** /**
@ -372,7 +372,7 @@ export class RistrettoPoint {
* https://ristretto.group/formulas/decoding.html * https://ristretto.group/formulas/decoding.html
* @param hex Ristretto-encoded 32 bytes. Not every 32-byte string is valid ristretto encoding * @param hex Ristretto-encoded 32 bytes. Not every 32-byte string is valid ristretto encoding
*/ */
static fromHex(hex: Hex): RistrettoPoint { static fromHex(hex: Hex): RistPoint {
hex = ensureBytes('ristrettoHex', hex, 32); hex = ensureBytes('ristrettoHex', hex, 32);
const { a, d } = ed25519.CURVE; const { a, d } = ed25519.CURVE;
const P = ed25519.CURVE.Fp.ORDER; const P = ed25519.CURVE.Fp.ORDER;
@ -396,7 +396,7 @@ export class RistrettoPoint {
const y = mod(u1 * Dy); // 11 const y = mod(u1 * Dy); // 11
const t = mod(x * y); // 12 const t = mod(x * y); // 12
if (!isValid || isNegativeLE(t, P) || y === _0n) throw new Error(emsg); if (!isValid || isNegativeLE(t, P) || y === _0n) throw new Error(emsg);
return new RistrettoPoint(new ed25519.ExtendedPoint(x, y, _1n, t)); return new RistPoint(new ed25519.ExtendedPoint(x, y, _1n, t));
} }
/** /**
@ -440,7 +440,7 @@ export class RistrettoPoint {
} }
// Compare one point to another. // Compare one point to another.
equals(other: RistrettoPoint): boolean { equals(other: RistPoint): boolean {
assertRstPoint(other); assertRstPoint(other);
const { ex: X1, ey: Y1 } = this.ep; const { ex: X1, ey: Y1 } = this.ep;
const { ex: X2, ey: Y2 } = other.ep; const { ex: X2, ey: Y2 } = other.ep;
@ -451,31 +451,36 @@ export class RistrettoPoint {
return one || two; return one || two;
} }
add(other: RistrettoPoint): RistrettoPoint { add(other: RistPoint): RistPoint {
assertRstPoint(other); assertRstPoint(other);
return new RistrettoPoint(this.ep.add(other.ep)); return new RistPoint(this.ep.add(other.ep));
} }
subtract(other: RistrettoPoint): RistrettoPoint { subtract(other: RistPoint): RistPoint {
assertRstPoint(other); assertRstPoint(other);
return new RistrettoPoint(this.ep.subtract(other.ep)); return new RistPoint(this.ep.subtract(other.ep));
} }
multiply(scalar: bigint): RistrettoPoint { multiply(scalar: bigint): RistPoint {
return new RistrettoPoint(this.ep.multiply(scalar)); return new RistPoint(this.ep.multiply(scalar));
} }
multiplyUnsafe(scalar: bigint): RistrettoPoint { multiplyUnsafe(scalar: bigint): RistPoint {
return new RistrettoPoint(this.ep.multiplyUnsafe(scalar)); return new RistPoint(this.ep.multiplyUnsafe(scalar));
} }
} }
export const RistrettoPoint = /* @__PURE__ */ (() => {
if (!RistPoint.BASE) RistPoint.BASE = new RistPoint(ed25519.ExtendedPoint.BASE);
if (!RistPoint.ZERO) RistPoint.ZERO = new RistPoint(ed25519.ExtendedPoint.ZERO);
return RistPoint;
})();
// https://datatracker.ietf.org/doc/draft-irtf-cfrg-hash-to-curve/14/ // https://datatracker.ietf.org/doc/draft-irtf-cfrg-hash-to-curve/14/
// Appendix B. Hashing to ristretto255 // Appendix B. Hashing to ristretto255
export const hash_to_ristretto255 = (msg: Uint8Array, options: htf.htfBasicOpts) => { export const hash_to_ristretto255 = (msg: Uint8Array, options: htfBasicOpts) => {
const d = options.DST; const d = options.DST;
const DST = typeof d === 'string' ? utf8ToBytes(d) : d; const DST = typeof d === 'string' ? utf8ToBytes(d) : d;
const uniform_bytes = htf.expand_message_xmd(msg, DST, 64, sha512); const uniform_bytes = expand_message_xmd(msg, DST, 64, sha512);
const P = RistrettoPoint.hashToCurve(uniform_bytes); const P = RistPoint.hashToCurve(uniform_bytes);
return P; return P;
}; };

@ -4,7 +4,7 @@ import { concatBytes, randomBytes, utf8ToBytes, wrapConstructor } from '@noble/h
import { twistedEdwards } from './abstract/edwards.js'; import { twistedEdwards } from './abstract/edwards.js';
import { mod, pow2, Field } from './abstract/modular.js'; import { mod, pow2, Field } from './abstract/modular.js';
import { montgomery } from './abstract/montgomery.js'; import { montgomery } from './abstract/montgomery.js';
import * as htf from './abstract/hash-to-curve.js'; import { createHasher } from './abstract/hash-to-curve.js';
/** /**
* Edwards448 (not Ed448-Goldilocks) curve with following addons: * Edwards448 (not Ed448-Goldilocks) curve with following addons:
@ -122,21 +122,22 @@ export const ed448 = twistedEdwards(ED448_DEF);
// NOTE: there is no ed448ctx, since ed448 supports ctx by default // NOTE: there is no ed448ctx, since ed448 supports ctx by default
export const ed448ph = twistedEdwards({ ...ED448_DEF, prehash: shake256_64 }); export const ed448ph = twistedEdwards({ ...ED448_DEF, prehash: shake256_64 });
export const x448 = montgomery({ export const x448 = /* @__PURE__ */ (() =>
a: BigInt(156326), montgomery({
montgomeryBits: 448, a: BigInt(156326),
nByteLength: 57, montgomeryBits: 448,
P: ed448P, nByteLength: 57,
Gu: BigInt(5), P: ed448P,
powPminus2: (x: bigint): bigint => { Gu: BigInt(5),
const P = ed448P; powPminus2: (x: bigint): bigint => {
const Pminus3div4 = ed448_pow_Pminus3div4(x); const P = ed448P;
const Pminus3 = pow2(Pminus3div4, BigInt(2), P); const Pminus3div4 = ed448_pow_Pminus3div4(x);
return mod(Pminus3 * x, P); // Pminus3 * x = Pminus2 const Pminus3 = pow2(Pminus3div4, BigInt(2), P);
}, return mod(Pminus3 * x, P); // Pminus3 * x = Pminus2
adjustScalarBytes, },
randomBytes, adjustScalarBytes,
}); randomBytes,
}))();
/** /**
* Converts edwards448 public key to x448 public key. Uses formula: * Converts edwards448 public key to x448 public key. Uses formula:
@ -228,17 +229,19 @@ function map_to_curve_elligator2_edwards448(u: bigint) {
return { x: Fp.mul(xEn, inv[0]), y: Fp.mul(yEn, inv[1]) }; // 38. return (xEn, xEd, yEn, yEd) return { x: Fp.mul(xEn, inv[0]), y: Fp.mul(yEn, inv[1]) }; // 38. return (xEn, xEd, yEn, yEd)
} }
const { hashToCurve, encodeToCurve } = htf.createHasher( const htf = /* @__PURE__ */ (() =>
ed448.ExtendedPoint, createHasher(
(scalars: bigint[]) => map_to_curve_elligator2_edwards448(scalars[0]), ed448.ExtendedPoint,
{ (scalars: bigint[]) => map_to_curve_elligator2_edwards448(scalars[0]),
DST: 'edwards448_XOF:SHAKE256_ELL2_RO_', {
encodeDST: 'edwards448_XOF:SHAKE256_ELL2_NU_', DST: 'edwards448_XOF:SHAKE256_ELL2_RO_',
p: Fp.ORDER, encodeDST: 'edwards448_XOF:SHAKE256_ELL2_NU_',
m: 1, p: Fp.ORDER,
k: 224, m: 1,
expand: 'xof', k: 224,
hash: shake256, expand: 'xof',
} hash: shake256,
); }
export { hashToCurve, encodeToCurve }; ))();
export const hashToCurve = /* @__PURE__ */ (() => htf.hashToCurve)();
export const encodeToCurve = /* @__PURE__ */ (() => htf.encodeToCurve)();

@ -3,7 +3,7 @@ import { createCurve } from './_shortw_utils.js';
import { sha256 } from '@noble/hashes/sha256'; import { sha256 } from '@noble/hashes/sha256';
import { Field } from './abstract/modular.js'; import { Field } from './abstract/modular.js';
import { mapToCurveSimpleSWU } from './abstract/weierstrass.js'; import { mapToCurveSimpleSWU } from './abstract/weierstrass.js';
import * as htf from './abstract/hash-to-curve.js'; import { createHasher } from './abstract/hash-to-curve.js';
// NIST secp256r1 aka p256 // NIST secp256r1 aka p256
// https://www.secg.org/sec2-v2.pdf, https://neuromancer.sk/std/nist/P-256 // https://www.secg.org/sec2-v2.pdf, https://neuromancer.sk/std/nist/P-256
@ -12,12 +12,6 @@ const Fp = Field(BigInt('0xffffffff00000001000000000000000000000000fffffffffffff
const CURVE_A = Fp.create(BigInt('-3')); const CURVE_A = Fp.create(BigInt('-3'));
const CURVE_B = BigInt('0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b'); const CURVE_B = BigInt('0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b');
const mapSWU = mapToCurveSimpleSWU(Fp, {
A: CURVE_A,
B: CURVE_B,
Z: Fp.create(BigInt('-10')),
});
// prettier-ignore // prettier-ignore
export const p256 = createCurve({ export const p256 = createCurve({
a: CURVE_A, // Equation params: a, b a: CURVE_A, // Equation params: a, b
@ -33,10 +27,15 @@ export const p256 = createCurve({
} as const, sha256); } as const, sha256);
export const secp256r1 = p256; export const secp256r1 = p256;
const { hashToCurve, encodeToCurve } = htf.createHasher( const mapSWU = /* @__PURE__ */ (() =>
secp256r1.ProjectivePoint, mapToCurveSimpleSWU(Fp, {
(scalars: bigint[]) => mapSWU(scalars[0]), A: CURVE_A,
{ B: CURVE_B,
Z: Fp.create(BigInt('-10')),
}))();
const htf = /* @__PURE__ */ (() =>
createHasher(secp256r1.ProjectivePoint, (scalars: bigint[]) => mapSWU(scalars[0]), {
DST: 'P256_XMD:SHA-256_SSWU_RO_', DST: 'P256_XMD:SHA-256_SSWU_RO_',
encodeDST: 'P256_XMD:SHA-256_SSWU_NU_', encodeDST: 'P256_XMD:SHA-256_SSWU_NU_',
p: Fp.ORDER, p: Fp.ORDER,
@ -44,6 +43,6 @@ const { hashToCurve, encodeToCurve } = htf.createHasher(
k: 128, k: 128,
expand: 'xmd', expand: 'xmd',
hash: sha256, hash: sha256,
} }))();
); export const hashToCurve = /* @__PURE__ */ (() => htf.hashToCurve)();
export { hashToCurve, encodeToCurve }; export const encodeToCurve = /* @__PURE__ */ (() => htf.encodeToCurve)();

@ -3,7 +3,7 @@ import { createCurve } from './_shortw_utils.js';
import { sha384 } from '@noble/hashes/sha512'; import { sha384 } from '@noble/hashes/sha512';
import { Field } from './abstract/modular.js'; import { Field } from './abstract/modular.js';
import { mapToCurveSimpleSWU } from './abstract/weierstrass.js'; import { mapToCurveSimpleSWU } from './abstract/weierstrass.js';
import * as htf from './abstract/hash-to-curve.js'; import { createHasher } from './abstract/hash-to-curve.js';
// NIST secp384r1 aka p384 // NIST secp384r1 aka p384
// https://www.secg.org/sec2-v2.pdf, https://neuromancer.sk/std/nist/P-384 // https://www.secg.org/sec2-v2.pdf, https://neuromancer.sk/std/nist/P-384
@ -31,16 +31,15 @@ export const p384 = createCurve({
} as const, sha384); } as const, sha384);
export const secp384r1 = p384; export const secp384r1 = p384;
const mapSWU = mapToCurveSimpleSWU(Fp, { const mapSWU = /* @__PURE__ */ (() =>
A: CURVE_A, mapToCurveSimpleSWU(Fp, {
B: CURVE_B, A: CURVE_A,
Z: Fp.create(BigInt('-12')), B: CURVE_B,
}); Z: Fp.create(BigInt('-12')),
}))();
const { hashToCurve, encodeToCurve } = htf.createHasher( const htf = /* @__PURE__ */ (() =>
secp384r1.ProjectivePoint, createHasher(secp384r1.ProjectivePoint, (scalars: bigint[]) => mapSWU(scalars[0]), {
(scalars: bigint[]) => mapSWU(scalars[0]),
{
DST: 'P384_XMD:SHA-384_SSWU_RO_', DST: 'P384_XMD:SHA-384_SSWU_RO_',
encodeDST: 'P384_XMD:SHA-384_SSWU_NU_', encodeDST: 'P384_XMD:SHA-384_SSWU_NU_',
p: Fp.ORDER, p: Fp.ORDER,
@ -48,6 +47,6 @@ const { hashToCurve, encodeToCurve } = htf.createHasher(
k: 192, k: 192,
expand: 'xmd', expand: 'xmd',
hash: sha384, hash: sha384,
} }))();
); export const hashToCurve = /* @__PURE__ */ (() => htf.hashToCurve)();
export { hashToCurve, encodeToCurve }; export const encodeToCurve = /* @__PURE__ */ (() => htf.encodeToCurve)();

@ -3,7 +3,7 @@ import { createCurve } from './_shortw_utils.js';
import { sha512 } from '@noble/hashes/sha512'; import { sha512 } from '@noble/hashes/sha512';
import { Field } from './abstract/modular.js'; import { Field } from './abstract/modular.js';
import { mapToCurveSimpleSWU } from './abstract/weierstrass.js'; import { mapToCurveSimpleSWU } from './abstract/weierstrass.js';
import * as htf from './abstract/hash-to-curve.js'; import { createHasher } from './abstract/hash-to-curve.js';
// NIST secp521r1 aka p521 // NIST secp521r1 aka p521
// Note that it's 521, which differs from 512 of its hash function. // Note that it's 521, which differs from 512 of its hash function.
@ -47,16 +47,15 @@ export const p521 = createCurve({
} as const, sha512); } as const, sha512);
export const secp521r1 = p521; export const secp521r1 = p521;
const mapSWU = mapToCurveSimpleSWU(Fp, { const mapSWU = /* @__PURE__ */ (() =>
A: CURVE.a, mapToCurveSimpleSWU(Fp, {
B: CURVE.b, A: CURVE.a,
Z: Fp.create(BigInt('-4')), B: CURVE.b,
}); Z: Fp.create(BigInt('-4')),
}))();
const { hashToCurve, encodeToCurve } = htf.createHasher( const htf = /* @__PURE__ */ (() =>
secp521r1.ProjectivePoint, createHasher(secp521r1.ProjectivePoint, (scalars: bigint[]) => mapSWU(scalars[0]), {
(scalars: bigint[]) => mapSWU(scalars[0]),
{
DST: 'P521_XMD:SHA-512_SSWU_RO_', DST: 'P521_XMD:SHA-512_SSWU_RO_',
encodeDST: 'P521_XMD:SHA-512_SSWU_NU_', encodeDST: 'P521_XMD:SHA-512_SSWU_NU_',
p: Fp.ORDER, p: Fp.ORDER,
@ -64,6 +63,6 @@ const { hashToCurve, encodeToCurve } = htf.createHasher(
k: 256, k: 256,
expand: 'xmd', expand: 'xmd',
hash: sha512, hash: sha512,
} }))();
); export const hashToCurve = /* @__PURE__ */ (() => htf.hashToCurve)();
export { hashToCurve, encodeToCurve }; export const encodeToCurve = /* @__PURE__ */ (() => htf.encodeToCurve)();

@ -5,7 +5,7 @@ import { Field, mod, pow2 } from './abstract/modular.js';
import { ProjPointType as PointType, mapToCurveSimpleSWU } from './abstract/weierstrass.js'; import { ProjPointType as PointType, mapToCurveSimpleSWU } from './abstract/weierstrass.js';
import type { Hex, PrivKey } from './abstract/utils.js'; import type { Hex, PrivKey } from './abstract/utils.js';
import { bytesToNumberBE, concatBytes, ensureBytes, numberToBytesBE } from './abstract/utils.js'; import { bytesToNumberBE, concatBytes, ensureBytes, numberToBytesBE } from './abstract/utils.js';
import * as htf from './abstract/hash-to-curve.js'; import { createHasher, isogenyMap } from './abstract/hash-to-curve.js';
import { createCurve } from './_shortw_utils.js'; import { createCurve } from './_shortw_utils.js';
const secp256k1P = BigInt('0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f'); const secp256k1P = BigInt('0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f');
@ -199,7 +199,7 @@ function schnorrVerify(signature: Hex, message: Hex, publicKey: Hex): boolean {
} }
} }
export const schnorr = { export const schnorr = /* @__PURE__ */ (() => ({
getPublicKey: schnorrGetPublicKey, getPublicKey: schnorrGetPublicKey,
sign: schnorrSign, sign: schnorrSign,
verify: schnorrVerify, verify: schnorrVerify,
@ -212,58 +212,63 @@ export const schnorr = {
taggedHash, taggedHash,
mod, mod,
}, },
}; }))();
const isoMap = htf.isogenyMap( const isoMap = /* @__PURE__ */ (() =>
Fp, isogenyMap(
[ Fp,
// xNum
[ [
'0x8e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38daaaaa8c7', // xNum
'0x7d3d4c80bc321d5b9f315cea7fd44c5d595d2fc0bf63b92dfff1044f17c6581', [
'0x534c328d23f234e6e2a413deca25caece4506144037c40314ecbd0b53d9dd262', '0x8e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38daaaaa8c7',
'0x8e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38daaaaa88c', '0x7d3d4c80bc321d5b9f315cea7fd44c5d595d2fc0bf63b92dfff1044f17c6581',
], '0x534c328d23f234e6e2a413deca25caece4506144037c40314ecbd0b53d9dd262',
// xDen '0x8e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38daaaaa88c',
[ ],
'0xd35771193d94918a9ca34ccbb7b640dd86cd409542f8487d9fe6b745781eb49b', // xDen
'0xedadc6f64383dc1df7c4b2d51b54225406d36b641f5e41bbc52a56612a8c6d14', [
'0x0000000000000000000000000000000000000000000000000000000000000001', // LAST 1 '0xd35771193d94918a9ca34ccbb7b640dd86cd409542f8487d9fe6b745781eb49b',
], '0xedadc6f64383dc1df7c4b2d51b54225406d36b641f5e41bbc52a56612a8c6d14',
// yNum '0x0000000000000000000000000000000000000000000000000000000000000001', // LAST 1
[ ],
'0x4bda12f684bda12f684bda12f684bda12f684bda12f684bda12f684b8e38e23c', // yNum
'0xc75e0c32d5cb7c0fa9d0a54b12a0a6d5647ab046d686da6fdffc90fc201d71a3', [
'0x29a6194691f91a73715209ef6512e576722830a201be2018a765e85a9ecee931', '0x4bda12f684bda12f684bda12f684bda12f684bda12f684bda12f684b8e38e23c',
'0x2f684bda12f684bda12f684bda12f684bda12f684bda12f684bda12f38e38d84', '0xc75e0c32d5cb7c0fa9d0a54b12a0a6d5647ab046d686da6fdffc90fc201d71a3',
], '0x29a6194691f91a73715209ef6512e576722830a201be2018a765e85a9ecee931',
// yDen '0x2f684bda12f684bda12f684bda12f684bda12f684bda12f684bda12f38e38d84',
[ ],
'0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffff93b', // yDen
'0x7a06534bb8bdb49fd5e9e6632722c2989467c1bfc8e8d978dfb425d2685c2573', [
'0x6484aa716545ca2cf3a70c3fa8fe337e0a3d21162f0d6299a7bf8192bfd2a76f', '0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffff93b',
'0x0000000000000000000000000000000000000000000000000000000000000001', // LAST 1 '0x7a06534bb8bdb49fd5e9e6632722c2989467c1bfc8e8d978dfb425d2685c2573',
], '0x6484aa716545ca2cf3a70c3fa8fe337e0a3d21162f0d6299a7bf8192bfd2a76f',
].map((i) => i.map((j) => BigInt(j))) as [bigint[], bigint[], bigint[], bigint[]] '0x0000000000000000000000000000000000000000000000000000000000000001', // LAST 1
); ],
const mapSWU = mapToCurveSimpleSWU(Fp, { ].map((i) => i.map((j) => BigInt(j))) as [bigint[], bigint[], bigint[], bigint[]]
A: BigInt('0x3f8731abdd661adca08a5558f0f5d272e953d363cb6f0e5d405447c01a444533'), ))();
B: BigInt('1771'), const mapSWU = /* @__PURE__ */ (() =>
Z: Fp.create(BigInt('-11')), mapToCurveSimpleSWU(Fp, {
}); A: BigInt('0x3f8731abdd661adca08a5558f0f5d272e953d363cb6f0e5d405447c01a444533'),
export const { hashToCurve, encodeToCurve } = htf.createHasher( B: BigInt('1771'),
secp256k1.ProjectivePoint, Z: Fp.create(BigInt('-11')),
(scalars: bigint[]) => { }))();
const { x, y } = mapSWU(Fp.create(scalars[0])); const htf = /* @__PURE__ */ (() =>
return isoMap(x, y); createHasher(
}, secp256k1.ProjectivePoint,
{ (scalars: bigint[]) => {
DST: 'secp256k1_XMD:SHA-256_SSWU_RO_', const { x, y } = mapSWU(Fp.create(scalars[0]));
encodeDST: 'secp256k1_XMD:SHA-256_SSWU_NU_', return isoMap(x, y);
p: Fp.ORDER, },
m: 1, {
k: 128, DST: 'secp256k1_XMD:SHA-256_SSWU_RO_',
expand: 'xmd', encodeDST: 'secp256k1_XMD:SHA-256_SSWU_NU_',
hash: sha256, p: Fp.ORDER,
} m: 1,
); k: 128,
expand: 'xmd',
hash: sha256,
}
))();
export const hashToCurve = /* @__PURE__ */ (() => htf.hashToCurve)();
export const encodeToCurve = /* @__PURE__ */ (() => htf.encodeToCurve)();