From 17e5be5f1bf6f9ce7e2b5f9921f560004bed09d9 Mon Sep 17 00:00:00 2001 From: Paul Miller Date: Tue, 24 Jan 2023 04:37:53 +0000 Subject: [PATCH] edwards: affine Point removal tests --- benchmark/index.js | 16 ++++----- src/abstract/edwards.ts | 7 ++-- src/abstract/hash-to-curve.ts | 18 +++++----- src/abstract/weierstrass.ts | 17 +++++++--- src/ed25519.ts | 2 +- src/ed448.ts | 2 +- src/jubjub.ts | 2 +- test/basic.test.js | 40 +++++++++++----------- test/ed25519.test.js | 64 +++++++++++++++-------------------- test/ed448.test.js | 23 +++++++------ test/hash-to-curve.test.js | 16 +++++---- test/jubjub.test.js | 28 +++++++-------- 12 files changed, 123 insertions(+), 112 deletions(-) diff --git a/benchmark/index.js b/benchmark/index.js index e1f4756..14e492a 100644 --- a/benchmark/index.js +++ b/benchmark/index.js @@ -96,10 +96,10 @@ export const CURVES = { old_secp.recoverPublicKey(msg, new old_secp.Signature(sig.r, sig.s), sig.recovery), secp256k1: ({ sig, msg }) => sig.recoverPublicKey(msg), }, - hashToCurve: { - samples: 500, - noble: () => secp256k1.Point.hashToCurve('abcd'), - }, + // hashToCurve: { + // samples: 500, + // noble: () => secp256k1.Point.hashToCurve('abcd'), + // }, }, ed25519: { data: () => { @@ -128,10 +128,10 @@ export const CURVES = { old: ({ sig, msg, pub }) => noble_ed25519.sync.verify(sig, msg, pub), noble: ({ sig, msg, pub }) => ed25519.verify(sig, msg, pub), }, - hashToCurve: { - samples: 500, - noble: () => ed25519.Point.hashToCurve('abcd'), - }, + // hashToCurve: { + // samples: 500, + // noble: () => ed25519.Point.hashToCurve('abcd'), + // }, }, ed448: { data: () => { diff --git a/src/abstract/edwards.ts b/src/abstract/edwards.ts index 6fe7cff..a6aa279 100644 --- a/src/abstract/edwards.ts +++ b/src/abstract/edwards.ts @@ -61,7 +61,10 @@ function validateOpts(curve: CurveType) { } // 2d point in XY coords -export interface AffinePoint { x: bigint; y: bigint }; +export interface AffinePoint { + x: bigint; + y: bigint; +} // Instance of Extended Point with coordinates in X, Y, Z, T export interface ExtendedPointType extends Group { @@ -384,7 +387,7 @@ export function twistedEdwards(curveDef: CurveType): CurveFn { } } const { BASE: G, ZERO: I } = ExtendedPoint; - let Gpows: ExtendedPoint[] | undefined = undefined; // precomputes for base point G + let Gpows: ExtendedPoint[] | undefined = undefined; // precomputes for base point G const wnaf = wNAF(ExtendedPoint, CURVE.nByteLength * 8); function wNAF_TMP_FN(P: ExtendedPoint, n: bigint): ExtendedPoint { if (P.equals(G)) { diff --git a/src/abstract/hash-to-curve.ts b/src/abstract/hash-to-curve.ts index c454f0f..888f6b9 100644 --- a/src/abstract/hash-to-curve.ts +++ b/src/abstract/hash-to-curve.ts @@ -179,13 +179,16 @@ export function isogenyMap>(field: F, map: [T[], T[], } export interface Point extends Group> { - readonly x: T; - readonly y: T; + // readonly x: T; + // readonly y: T; + add(rhs: Point): Point; + toAffine(iz?: bigint): { x: T; y: T }; clearCofactor(): Point; } export interface PointConstructor extends GroupConstructor> { - new (x: T, y: T): Point; + // new (x: T, y: T): Point; + fromAffine(ap: { x: T; y: T }): Point; } export type MapToCurve = (scalar: bigint[]) => { x: T; y: T }; @@ -207,9 +210,9 @@ export function hashToCurve(Point: PointConstructor, mapToCurve: MapToCurv if (!mapToCurve) throw new Error('CURVE.mapToCurve() has not been defined'); msg = ut.ensureBytes(msg); const u = hash_to_field(msg, 2, { ...def, DST: def.DST, ...options } as Opts); - const { x: x0, y: y0 } = mapToCurve(u[0]); - const { x: x1, y: y1 } = mapToCurve(u[1]); - return new Point(x0, y0).add(new Point(x1, y1)).clearCofactor(); + return Point.fromAffine(mapToCurve(u[0])) + .add(Point.fromAffine(mapToCurve(u[1]))) + .clearCofactor(); }, // https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-16#section-3 @@ -217,8 +220,7 @@ export function hashToCurve(Point: PointConstructor, mapToCurve: MapToCurv if (!mapToCurve) throw new Error('CURVE.mapToCurve() has not been defined'); msg = ut.ensureBytes(msg); const u = hash_to_field(msg, 1, { ...def, DST: def.encodeDST, ...options } as Opts); - const { x, y } = mapToCurve(u[0]); - return new Point(x, y).clearCofactor(); + return Point.fromAffine(mapToCurve(u[0])).clearCofactor(); }, }; } diff --git a/src/abstract/weierstrass.ts b/src/abstract/weierstrass.ts index d6492a7..dc9b3ca 100644 --- a/src/abstract/weierstrass.ts +++ b/src/abstract/weierstrass.ts @@ -137,10 +137,12 @@ export interface PointType extends Group> { assertValidity(): void; multiplyAndAddUnsafe(Q: PointType, a: bigint, b: bigint): PointType | undefined; clearCofactor(): PointType; + toAffine(iz?: bigint): { x: T; y: T }; } // Static methods for 2d XY points export interface PointConstructor extends GroupConstructor> { new (x: T, y: T): PointType; + fromAffine(ap: { x: T; y: T }): PointType; fromHex(hex: Hex): PointType; fromPrivateKey(privateKey: PrivKey): PointType; } @@ -546,6 +548,12 @@ export function weierstrassPoints(opts: CurvePointsType) { * Identity point aka point at infinity. p - p = zero_p; p + zero_p = p */ static ZERO: Point = new Point(Fp.ZERO, Fp.ZERO); + static fromAffine(ap: { x: T; y: T }) { + return new Point(ap.x, ap.y); + } + toAffine(iz?: bigint) { + return { x: this.x, y: this.y }; + } // We calculate precomputes for elliptic curve point multiplication // using windowed method. This specifies window size and @@ -1124,10 +1132,11 @@ export function weierstrass(curveDef: CurveType): CurveFn { // Also it can be bigger for P224 + SHA256 function prepSig(msgHash: Hex, privateKey: PrivKey, opts = defaultSigOpts) { if (msgHash == null) throw new Error(`sign: expected valid message hash, not "${msgHash}"`); - if (['recovered', 'canonical'].some(k => k in opts)) // Ban legacy options + if (['recovered', 'canonical'].some((k) => k in opts)) + // Ban legacy options throw new Error('sign() legacy options not supported'); - let { lowS } = opts; // generates low-s sigs by default - if (lowS == null) lowS = true; // RFC6979 3.2: we skip step A, because + let { lowS } = opts; // generates low-s sigs by default + if (lowS == null) lowS = true; // RFC6979 3.2: we skip step A, because // Step A is ignored, since we already provide hash instead of msg // NOTE: instead of bits2int, we calling here truncateHash, since we need @@ -1141,7 +1150,7 @@ export function weierstrass(curveDef: CurveType): CurveFn { const d = normalizePrivateKey(privateKey); // K = HMAC_K(V || 0x00 || int2octets(x) || bits2octets(h1) || k') const seedArgs = [int2octets(d), h1octets]; - let ent = opts.extraEntropy; // RFC6979 3.6: additional k' (optional) + let ent = opts.extraEntropy; // RFC6979 3.6: additional k' (optional) if (ent != null) { if (ent === true) ent = CURVE.randomBytes(Fp.BYTES); const e = ut.ensureBytes(ent); diff --git a/src/ed25519.ts b/src/ed25519.ts index a5f873c..eef3edb 100644 --- a/src/ed25519.ts +++ b/src/ed25519.ts @@ -210,7 +210,7 @@ export const ed25519ph = twistedEdwards({ }); const { hashToCurve, encodeToCurve } = htf.hashToCurve( - ed25519.Point, + ed25519.ExtendedPoint, (scalars: bigint[]) => map_to_curve_elligator2_edwards25519(scalars[0]), { DST: 'edwards25519_XMD:SHA-512_ELL2_RO_', diff --git a/src/ed448.ts b/src/ed448.ts index 20e8ad2..630f227 100644 --- a/src/ed448.ts +++ b/src/ed448.ts @@ -197,7 +197,7 @@ export const ed448 = twistedEdwards(ED448_DEF); export const ed448ph = twistedEdwards({ ...ED448_DEF, preHash: shake256_64 }); const { hashToCurve, encodeToCurve } = htf.hashToCurve( - ed448.Point, + ed448.ExtendedPoint, (scalars: bigint[]) => map_to_curve_elligator2_edwards448(scalars[0]), { DST: 'edwards448_XOF:SHAKE256_ELL2_RO_', diff --git a/src/jubjub.ts b/src/jubjub.ts index 8fb66f8..e7a6cc0 100644 --- a/src/jubjub.ts +++ b/src/jubjub.ts @@ -39,7 +39,7 @@ export function groupHash(tag: Uint8Array, personalization: Uint8Array) { h.update(GH_FIRST_BLOCK); h.update(tag); // NOTE: returns ExtendedPoint, in case it will be multiplied later - let p = jubjub.ExtendedPoint.fromAffine(jubjub.Point.fromHex(h.digest())); + let p = jubjub.ExtendedPoint.fromAffine(jubjub.ExtendedPoint.fromHex(h.digest())); // NOTE: cannot replace with isSmallOrder, returns Point*8 p = p.multiply(jubjub.CURVE.h); if (p.equals(jubjub.ExtendedPoint.ZERO)) throw new Error('Point has small order'); diff --git a/test/basic.test.js b/test/basic.test.js index e37cc36..b908719 100644 --- a/test/basic.test.js +++ b/test/basic.test.js @@ -313,12 +313,12 @@ const NUM_RUNS = 5; const getXY = (p) => ({ x: p.x, y: p.y }); function equal(a, b, comment) { - deepStrictEqual(a.equals(b), true, 'eq(${comment})'); + deepStrictEqual(a.equals(b), true, `eq(${comment})`); if (a.toAffine && b.toAffine) { - deepStrictEqual(getXY(a.toAffine()), getXY(b.toAffine()), 'eqToAffine(${comment})'); + deepStrictEqual(getXY(a.toAffine()), getXY(b.toAffine()), `eqToAffine(${comment})`); } else if (!a.toAffine && !b.toAffine) { // Already affine - deepStrictEqual(getXY(a), getXY(b), 'eqAffine(${comment})'); + deepStrictEqual(getXY(a), getXY(b), `eqAffine(${comment})`); } else throw new Error('Different point types'); } @@ -354,8 +354,8 @@ for (const name in CURVES) { equal(G[0].negate(), G[0], '-0 = 0'); for (let i = 0; i < G.length; i++) { const p = G[i]; - equal(p, p.add(G[0]), '${i}*G + 0 = ${i}*G'); - equal(G[0].multiply(BigInt(i + 1)), G[0], '${i + 1}*0 = 0'); + equal(p, p.add(G[0]), `${i}*G + 0 = ${i}*G`); + equal(G[0].multiply(BigInt(i + 1)), G[0], `${i + 1}*0 = 0`); } }); should('(one)', () => { @@ -447,8 +447,8 @@ for (const name in CURVES) { throws(() => G[1][op](new Uint8Array([0])), 'ui8a([0])'); throws(() => G[1][op](new Uint8Array([1])), 'ui8a([1])'); throws(() => G[1][op](new Uint8Array(4096).fill(1)), 'ui8a(4096*[1])'); - if (G[1].toAffine) throws(() => G[1][op](C.Point.BASE), 'Point ${op} ${pointName}'); - throws(() => G[1][op](o.BASE), '${op}/other curve point'); + // if (G[1].toAffine) throws(() => G[1][op](C.Point.BASE), `Point ${op} ${pointName}`); + throws(() => G[1][op](o.BASE), `${op}/other curve point`); }); }); } @@ -468,7 +468,7 @@ for (const name in CURVES) { throws(() => G[1].equals(new Uint8Array([0])), 'ui8a([0])'); throws(() => G[1].equals(new Uint8Array([1])), 'ui8a([1])'); throws(() => G[1].equals(new Uint8Array(4096).fill(1)), 'ui8a(4096*[1])'); - if (G[1].toAffine) throws(() => G[1].equals(C.Point.BASE), 'Point.equals(${pointName})'); + // if (G[1].toAffine) throws(() => G[1].equals(C.Point.BASE), 'Point.equals(${pointName})'); throws(() => G[1].equals(o.BASE), 'other curve point'); }); @@ -497,18 +497,18 @@ for (const name in CURVES) { }); } // Complex point (Extended/Jacobian/Projective?) - if (p.BASE.toAffine) { - should('toAffine()', () => { - equal(p.ZERO.toAffine(), C.Point.ZERO, '0 = 0'); - equal(p.BASE.toAffine(), C.Point.BASE, '1 = 1'); - }); - } - if (p.fromAffine) { - should('fromAffine()', () => { - equal(p.ZERO, p.fromAffine(C.Point.ZERO), '0 = 0'); - equal(p.BASE, p.fromAffine(C.Point.BASE), '1 = 1'); - }); - } + // if (p.BASE.toAffine && C.Point) { + // should('toAffine()', () => { + // equal(p.ZERO.toAffine(), C.Point.ZERO, '0 = 0'); + // equal(p.BASE.toAffine(), C.Point.BASE, '1 = 1'); + // }); + // } + // if (p.fromAffine && C.Point) { + // should('fromAffine()', () => { + // equal(p.ZERO, p.fromAffine(C.Point.ZERO), '0 = 0'); + // equal(p.BASE, p.fromAffine(C.Point.BASE), '1 = 1'); + // }); + // } // toHex/fromHex (if available) if (p.fromHex && p.BASE.toHex) { should('fromHex(toHex()) roundtrip', () => { diff --git a/test/ed25519.test.js b/test/ed25519.test.js index 86a9580..2f78e79 100644 --- a/test/ed25519.test.js +++ b/test/ed25519.test.js @@ -20,6 +20,7 @@ import { default as x25519vectors } from './wycheproof/x25519_test.json' assert describe('ed25519', () => { const ed = ed25519; const hex = bytesToHex; + const Point = ed.ExtendedPoint; function to32Bytes(numOrStr) { let hex = typeof numOrStr === 'string' ? numOrStr : numOrStr.toString(16); @@ -114,55 +115,45 @@ describe('ed25519', () => { deepStrictEqual(ed.verify(signature, wrongMsg, publicKey), false); }); }); - // https://xmr.llcoins.net/addresstests.html - should( - 'ed25519/BASE_POINT.multiply()/should create right publicKey without SHA-512 hashing TEST 1', - () => { + describe('BASE_POINT.multiply()', () => { + // https://xmr.llcoins.net/addresstests.html + should('create right publicKey without SHA-512 hashing TEST 1', () => { const publicKey = - ed.Point.BASE.multiply(0x90af56259a4b6bfbc4337980d5d75fbe3c074630368ff3804d33028e5dbfa77n); + Point.BASE.multiply(0x90af56259a4b6bfbc4337980d5d75fbe3c074630368ff3804d33028e5dbfa77n); deepStrictEqual( publicKey.toHex(), '0f3b913371411b27e646b537e888f685bf929ea7aab93c950ed84433f064480d' ); - } - ); - should( - 'ed25519/BASE_POINT.multiply()/should create right publicKey without SHA-512 hashing TEST 2', - () => { + }); + should('create right publicKey without SHA-512 hashing TEST 2', () => { const publicKey = - ed.Point.BASE.multiply(0x364e8711a60780382a5d57b061c126f039940f28a9e91fe039d4d3094d8b88n); + Point.BASE.multiply(0x364e8711a60780382a5d57b061c126f039940f28a9e91fe039d4d3094d8b88n); deepStrictEqual( publicKey.toHex(), 'ad545340b58610f0cd62f17d55af1ab11ecde9c084d5476865ddb4dbda015349' ); - } - ); - should( - 'ed25519/BASE_POINT.multiply()/should create right publicKey without SHA-512 hashing TEST 3', - () => { + }); + should('create right publicKey without SHA-512 hashing TEST 3', () => { const publicKey = - ed.Point.BASE.multiply(0xb9bf90ff3abec042752cac3a07a62f0c16cfb9d32a3fc2305d676ec2d86e941n); + Point.BASE.multiply(0xb9bf90ff3abec042752cac3a07a62f0c16cfb9d32a3fc2305d676ec2d86e941n); deepStrictEqual( publicKey.toHex(), 'e097c4415fe85724d522b2e449e8fd78dd40d20097bdc9ae36fe8ec6fe12cb8c' ); - } - ); - should( - 'ed25519/BASE_POINT.multiply()/should create right publicKey without SHA-512 hashing TEST 4', - () => { + }); + should('create right publicKey without SHA-512 hashing TEST 4', () => { const publicKey = - ed.Point.BASE.multiply(0x69d896f02d79524c9878e080308180e2859d07f9f54454e0800e8db0847a46en); + Point.BASE.multiply(0x69d896f02d79524c9878e080308180e2859d07f9f54454e0800e8db0847a46en); deepStrictEqual( publicKey.toHex(), 'f12cb7c43b59971395926f278ce7c2eaded9444fbce62ca717564cb508a0db1d' ); - } - ); - should('ed25519/BASE_POINT.multiply()/should throw Point#multiply on TEST 5', () => { - for (const num of [0n, 0, -1n, -1, 1.1]) { - throws(() => ed.Point.BASE.multiply(num)); - } + }); + should('throw Point#multiply on TEST 5', () => { + for (const num of [0n, 0, -1n, -1, 1.1]) { + throws(() => Point.BASE.multiply(num)); + } + }); }); // https://ed25519.cr.yp.to/python/sign.py @@ -184,7 +175,7 @@ describe('ed25519', () => { // Calculate const pub = ed.getPublicKey(to32Bytes(priv)); deepStrictEqual(hex(pub), expectedPub); - deepStrictEqual(pub, ed.Point.fromHex(pub).toRawBytes()); + deepStrictEqual(pub, Point.fromHex(pub).toRawBytes()); const signature = hex(ed.sign(msg, priv)); // console.log('vector', i); @@ -444,9 +435,10 @@ describe('ed25519', () => { } }); should('ZIP-215 compliance tests/disallows sig.s >= CURVE.n', () => { - const sig = new ed.Signature(ed.Point.BASE, 1n); - sig.s = ed.CURVE.n + 1n; - throws(() => ed.verify(sig, 'deadbeef', ed.Point.BASE)); + // sig.R = BASE, sig.s = N+1 + const sig = + '5866666666666666666666666666666666666666666666666666666666666666eed3f55c1a631258d69cf7a2def9de1400000000000000000000000000000010'; + throws(() => ed.verify(sig, 'deadbeef', Point.BASE)); }); const rfc7748Mul = [ @@ -511,7 +503,7 @@ describe('ed25519', () => { // should('X25519: should convert base point to montgomery using fromPoint', () => { // deepStrictEqual( - // hex(ed.montgomeryCurve.UfromPoint(ed.Point.BASE)), + // hex(ed.montgomeryCurve.UfromPoint(Point.BASE)), // ed.montgomeryCurve.BASE_POINT_U // ); // }); @@ -655,7 +647,7 @@ describe('ed25519', () => { } should('X25519 base point', () => { - const { y } = ed25519.Point.BASE; + const { y } = ed25519.ExtendedPoint.BASE; const { Fp } = ed25519.CURVE; const u = Fp.create((y + 1n) * Fp.invert(1n - y)); deepStrictEqual(hex(numberToBytesLE(u, 32)), x25519.Gu); @@ -664,7 +656,7 @@ describe('ed25519', () => { should('isTorsionFree()', () => { const orig = ed.utils.getExtendedPublicKey(ed.utils.randomPrivateKey()).point; for (const hex of ED25519_TORSION_SUBGROUP.slice(1)) { - const dirty = orig.add(ed.Point.fromHex(hex)); + const dirty = orig.add(Point.fromHex(hex)); const cleared = dirty.clearCofactor(); strictEqual(orig.isTorsionFree(), true, `orig must be torsionFree: ${hex}`); strictEqual(dirty.isTorsionFree(), false, `dirty must not be torsionFree: ${hex}`); diff --git a/test/ed448.test.js b/test/ed448.test.js index c3fa31a..0b2b0a0 100644 --- a/test/ed448.test.js +++ b/test/ed448.test.js @@ -11,9 +11,10 @@ describe('ed448', () => { const ed = ed448; const hex = bytesToHex; ed.utils.precompute(4); + const Point = ed.ExtendedPoint; should(`Basic`, () => { - const G1 = ed.Point.BASE; + const G1 = Point.BASE.toAffine(); deepStrictEqual( G1.x, 224580040295924300187604334099896036246789641632564134246125461686950415467406032909029192869357953282578032075146446173674602635247710n @@ -22,7 +23,7 @@ describe('ed448', () => { G1.y, 298819210078481492676017930443930673437544040154080242095928241372331506189835876003536878655418784733982303233503462500531545062832660n ); - const G2 = ed.Point.BASE.multiply(2n); + const G2 = Point.BASE.multiply(2n).toAffine(); deepStrictEqual( G2.x, 484559149530404593699549205258669689569094240458212040187660132787056912146709081364401144455726350866276831544947397859048262938744149n @@ -31,7 +32,7 @@ describe('ed448', () => { G2.y, 494088759867433727674302672526735089350544552303727723746126484473087719117037293890093462157703888342865036477787453078312060500281069n ); - const G3 = ed.Point.BASE.multiply(3n); + const G3 = Point.BASE.multiply(3n).toAffine(); deepStrictEqual( G3.x, 23839778817283171003887799738662344287085130522697782688245073320169861206004018274567429238677677920280078599146891901463786155880335n @@ -43,12 +44,12 @@ describe('ed448', () => { }); should('Basic/decompress', () => { - const G1 = ed.Point.BASE; - const G2 = ed.Point.BASE.multiply(2n); - const G3 = ed.Point.BASE.multiply(3n); + const G1 = Point.BASE; + const G2 = Point.BASE.multiply(2n); + const G3 = Point.BASE.multiply(3n); const points = [G1, G2, G3]; - const getXY = (p) => ({ x: p.x, y: p.y }); - for (const p of points) deepStrictEqual(getXY(ed.Point.fromHex(p.toHex())), getXY(p)); + const getXY = (p) => p.toAffine(); + for (const p of points) deepStrictEqual(getXY(Point.fromHex(p.toHex())), getXY(p)); }); const VECTORS_RFC8032 = [ @@ -412,7 +413,7 @@ describe('ed448', () => { should('BASE_POINT.multiply() throws in Point#multiply on TEST 5', () => { for (const num of [0n, 0, -1n, -1, 1.1]) { - throws(() => ed.Point.BASE.multiply(num)); + throws(() => ed.ExtendedPoint.BASE.multiply(num)); } }); @@ -559,7 +560,7 @@ describe('ed448', () => { // should('X448: should convert base point to montgomery using fromPoint', () => { // deepStrictEqual( - // hex(ed.montgomeryCurve.UfromPoint(ed.Point.BASE)), + // hex(ed.montgomeryCurve.UfromPoint(Point.BASE)), // ed.montgomeryCurve.BASE_POINT_U // ); // }); @@ -654,7 +655,7 @@ describe('ed448', () => { } should('X448 base point', () => { - const { x, y } = ed448.Point.BASE; + const { x, y } = Point.BASE; const { Fp } = ed448.CURVE; // const invX = Fp.invert(x * x); // x² const u = Fp.div(Fp.create(y * y), Fp.create(x * x)); // (y²/x²) diff --git a/test/hash-to-curve.test.js b/test/hash-to-curve.test.js index ed11794..d7771b6 100644 --- a/test/hash-to-curve.test.js +++ b/test/hash-to-curve.test.js @@ -111,9 +111,11 @@ function testCurve(curve, ro, nu) { for (let i = 0; i < ro.vectors.length; i++) { const t = ro.vectors[i]; should(`(${i})`, () => { - const p = curve.hashToCurve(stringToBytes(t.msg), { - DST: ro.dst, - }); + const p = curve + .hashToCurve(stringToBytes(t.msg), { + DST: ro.dst, + }) + .toAffine(); deepStrictEqual(p.x, stringToFp(t.P.x), 'Px'); deepStrictEqual(p.y, stringToFp(t.P.y), 'Py'); }); @@ -123,9 +125,11 @@ function testCurve(curve, ro, nu) { for (let i = 0; i < nu.vectors.length; i++) { const t = nu.vectors[i]; should(`(${i})`, () => { - const p = curve.encodeToCurve(stringToBytes(t.msg), { - DST: nu.dst, - }); + const p = curve + .encodeToCurve(stringToBytes(t.msg), { + DST: nu.dst, + }) + .toAffine(); deepStrictEqual(p.x, stringToFp(t.P.x), 'Px'); deepStrictEqual(p.y, stringToFp(t.P.y), 'Py'); }); diff --git a/test/jubjub.test.js b/test/jubjub.test.js index d5a88a2..0ce59f9 100644 --- a/test/jubjub.test.js +++ b/test/jubjub.test.js @@ -1,15 +1,15 @@ import { jubjub, findGroupHash } from '../lib/esm/jubjub.js'; import { describe, should } from 'micro-should'; import { deepStrictEqual, throws } from 'assert'; -import { hexToBytes, bytesToHex } from '@noble/hashes/utils'; +const Point = jubjub.ExtendedPoint; -const G_SPEND = new jubjub.ExtendedPoint( +const G_SPEND = new Point( 0x055f1f24f0f0512287e51c3c5a0a6903fc0baf8711de9eafd7c0e66f69d8d2dbn, 0x566178b2505fdd52132a5007d80a04652842e78ffb376897588f406278214ed7n, 0x0141fafa1f11088a3b2007c14d652375888f3b37838ba6bdffae096741ceddfen, 0x12eada93c0b7d595f5f04f5ebfb4b7d033ef2884136475cab5e41ce17db5be9cn ); -const G_PROOF = new jubjub.ExtendedPoint( +const G_PROOF = new Point( 0x0174d54ce9fad258a2f8a86a1deabf15c7a2b51106b0fbcd9d29020f78936f71n, 0x16871d6d877dcd222e4ec3bccb3f37cb1865a2d37dd3a5dcbc032a69b62b4445n, 0x57a3cd31e496d82bd4aa78bd5ecd751cfb76d54a5d3f4560866379f9fc11c9b3n, @@ -22,7 +22,7 @@ describe('jubjub', () => { should('toHex/fromHex', () => { // More than field throws(() => - jubjub.Point.fromHex( + Point.fromHex( new Uint8Array([ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -31,14 +31,14 @@ describe('jubjub', () => { ); // Multiplicative generator (sqrt == null), not on curve. throws(() => - jubjub.Point.fromHex( + Point.fromHex( new Uint8Array([ 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]) ) ); - const tmp = jubjub.Point.fromHex( + const tmp = Point.fromHex( new Uint8Array([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -47,14 +47,14 @@ describe('jubjub', () => { deepStrictEqual(tmp.x, 0x8d51ccce760304d0ec030002760300000001000000000000n); deepStrictEqual(tmp.y, 0n); - const S = G_SPEND.toAffine().toRawBytes(); - const S2 = G_SPEND.double().toAffine().toRawBytes(); - const P = G_PROOF.toAffine().toRawBytes(); - const P2 = G_PROOF.double().toAffine().toRawBytes(); - const S_exp = jubjub.Point.fromHex(S); - const S2_exp = jubjub.Point.fromHex(S2); - const P_exp = jubjub.Point.fromHex(P); - const P2_exp = jubjub.Point.fromHex(P2); + const S = G_SPEND.toRawBytes(); + const S2 = G_SPEND.double().toRawBytes(); + const P = G_PROOF.toRawBytes(); + const P2 = G_PROOF.double().toRawBytes(); + const S_exp = Point.fromHex(S); + const S2_exp = Point.fromHex(S2); + const P_exp = Point.fromHex(P); + const P2_exp = Point.fromHex(P2); deepStrictEqual(getXY(G_SPEND.toAffine()), getXY(S_exp)); deepStrictEqual(getXY(G_SPEND.double().toAffine()), getXY(S2_exp)); deepStrictEqual(getXY(G_PROOF.toAffine()), getXY(P_exp));