forked from tornado-packages/noble-curves
Rename field methods: multiply to mul
This commit is contained in:
parent
6ffe656871
commit
0277c01efd
@ -42,25 +42,25 @@ const Fp2Add = ({ c0, c1 }: Fp2, { c0: r0, c1: r1 }: Fp2) => ({
|
||||
c1: Fp.add(c1, r1),
|
||||
});
|
||||
const Fp2Subtract = ({ c0, c1 }: Fp2, { c0: r0, c1: r1 }: Fp2) => ({
|
||||
c0: Fp.subtract(c0, r0),
|
||||
c1: Fp.subtract(c1, r1),
|
||||
c0: Fp.sub(c0, r0),
|
||||
c1: Fp.sub(c1, r1),
|
||||
});
|
||||
const Fp2Multiply = ({ c0, c1 }: Fp2, rhs: Fp2) => {
|
||||
if (typeof rhs === 'bigint') return { c0: Fp.multiply(c0, rhs), c1: Fp.multiply(c1, rhs) };
|
||||
if (typeof rhs === 'bigint') return { c0: Fp.mul(c0, rhs), c1: Fp.mul(c1, rhs) };
|
||||
// (a+bi)(c+di) = (ac−bd) + (ad+bc)i
|
||||
const { c0: r0, c1: r1 } = rhs;
|
||||
let t1 = Fp.multiply(c0, r0); // c0 * o0
|
||||
let t2 = Fp.multiply(c1, r1); // c1 * o1
|
||||
let t1 = Fp.mul(c0, r0); // c0 * o0
|
||||
let t2 = Fp.mul(c1, r1); // c1 * o1
|
||||
// (T1 - T2) + ((c0 + c1) * (r0 + r1) - (T1 + T2))*i
|
||||
const o0 = Fp.subtract(t1, t2);
|
||||
const o1 = Fp.subtract(Fp.multiply(Fp.add(c0, c1), Fp.add(r0, r1)), Fp.add(t1, t2));
|
||||
const o0 = Fp.sub(t1, t2);
|
||||
const o1 = Fp.sub(Fp.mul(Fp.add(c0, c1), Fp.add(r0, r1)), Fp.add(t1, t2));
|
||||
return { c0: o0, c1: o1 };
|
||||
};
|
||||
const Fp2Square = ({ c0, c1 }: Fp2) => {
|
||||
const a = Fp.add(c0, c1);
|
||||
const b = Fp.subtract(c0, c1);
|
||||
const b = Fp.sub(c0, c1);
|
||||
const c = Fp.add(c0, c0);
|
||||
return { c0: Fp.multiply(a, b), c1: Fp.multiply(c, c1) };
|
||||
return { c0: Fp.mul(a, b), c1: Fp.mul(c, c1) };
|
||||
};
|
||||
type Fp2Utils = {
|
||||
fromBigTuple: (tuple: BigintTuple | bigint[]) => Fp2;
|
||||
@ -94,17 +94,17 @@ const Fp2: mod.Field<Fp2> & Fp2Utils = {
|
||||
invertBatch: (nums) => mod.FpInvertBatch(Fp2, nums),
|
||||
// Normalized
|
||||
add: Fp2Add,
|
||||
subtract: Fp2Subtract,
|
||||
multiply: Fp2Multiply,
|
||||
sub: Fp2Subtract,
|
||||
mul: Fp2Multiply,
|
||||
square: Fp2Square,
|
||||
// NonNormalized stuff
|
||||
addN: Fp2Add,
|
||||
subtractN: Fp2Subtract,
|
||||
multiplyN: Fp2Multiply,
|
||||
subN: Fp2Subtract,
|
||||
mulN: Fp2Multiply,
|
||||
squareN: Fp2Square,
|
||||
// Why inversion for bigint inside Fp instead of Fp2? it is even used in that context?
|
||||
div: (lhs, rhs) =>
|
||||
Fp2.multiply(lhs, typeof rhs === 'bigint' ? Fp.invert(Fp.create(rhs)) : Fp2.invert(rhs)),
|
||||
Fp2.mul(lhs, typeof rhs === 'bigint' ? Fp.invert(Fp.create(rhs)) : Fp2.invert(rhs)),
|
||||
invert: ({ c0: a, c1: b }) => {
|
||||
// We wish to find the multiplicative inverse of a nonzero
|
||||
// element a + bu in Fp2. We leverage an identity
|
||||
@ -120,7 +120,7 @@ const Fp2: mod.Field<Fp2> & Fp2Utils = {
|
||||
// of (a + bu). Importantly, this can be computing using
|
||||
// only a single inversion in Fp.
|
||||
const factor = Fp.invert(Fp.create(a * a + b * b));
|
||||
return { c0: Fp.multiply(factor, Fp.create(a)), c1: Fp.multiply(factor, Fp.create(-b)) };
|
||||
return { c0: Fp.mul(factor, Fp.create(a)), c1: Fp.mul(factor, Fp.create(-b)) };
|
||||
},
|
||||
sqrt: (num) => {
|
||||
// TODO: Optimize this line. It's extremely slow.
|
||||
@ -156,12 +156,12 @@ const Fp2: mod.Field<Fp2> & Fp2Utils = {
|
||||
// }
|
||||
reim: ({ c0, c1 }) => ({ re: c0, im: c1 }),
|
||||
// multiply by u + 1
|
||||
mulByNonresidue: ({ c0, c1 }) => ({ c0: Fp.subtract(c0, c1), c1: Fp.add(c0, c1) }),
|
||||
mulByNonresidue: ({ c0, c1 }) => ({ c0: Fp.sub(c0, c1), c1: Fp.add(c0, c1) }),
|
||||
multiplyByB: ({ c0, c1 }) => {
|
||||
let t0 = Fp.multiply(c0, 4n); // 4 * c0
|
||||
let t1 = Fp.multiply(c1, 4n); // 4 * c1
|
||||
let t0 = Fp.mul(c0, 4n); // 4 * c0
|
||||
let t1 = Fp.mul(c1, 4n); // 4 * c1
|
||||
// (T0-T1) + (T0+T1)*i
|
||||
return { c0: Fp.subtract(t0, t1), c1: Fp.add(t0, t1) };
|
||||
return { c0: Fp.sub(t0, t1), c1: Fp.add(t0, t1) };
|
||||
},
|
||||
fromBigTuple: (tuple: BigintTuple | bigint[]) => {
|
||||
if (tuple.length !== 2) throw new Error('Invalid tuple');
|
||||
@ -170,7 +170,7 @@ const Fp2: mod.Field<Fp2> & Fp2Utils = {
|
||||
},
|
||||
frobeniusMap: ({ c0, c1 }, power: number): Fp2 => ({
|
||||
c0,
|
||||
c1: Fp.multiply(c1, FP2_FROBENIUS_COEFFICIENTS[power % 2]),
|
||||
c1: Fp.mul(c1, FP2_FROBENIUS_COEFFICIENTS[power % 2]),
|
||||
}),
|
||||
};
|
||||
// Finite extension field over irreducible polynominal.
|
||||
@ -223,50 +223,50 @@ const Fp6Add = ({ c0, c1, c2 }: Fp6, { c0: r0, c1: r1, c2: r2 }: Fp6) => ({
|
||||
c2: Fp2.add(c2, r2),
|
||||
});
|
||||
const Fp6Subtract = ({ c0, c1, c2 }: Fp6, { c0: r0, c1: r1, c2: r2 }: Fp6) => ({
|
||||
c0: Fp2.subtract(c0, r0),
|
||||
c1: Fp2.subtract(c1, r1),
|
||||
c2: Fp2.subtract(c2, r2),
|
||||
c0: Fp2.sub(c0, r0),
|
||||
c1: Fp2.sub(c1, r1),
|
||||
c2: Fp2.sub(c2, r2),
|
||||
});
|
||||
const Fp6Multiply = ({ c0, c1, c2 }: Fp6, rhs: Fp6 | bigint) => {
|
||||
if (typeof rhs === 'bigint') {
|
||||
return {
|
||||
c0: Fp2.multiply(c0, rhs),
|
||||
c1: Fp2.multiply(c1, rhs),
|
||||
c2: Fp2.multiply(c2, rhs),
|
||||
c0: Fp2.mul(c0, rhs),
|
||||
c1: Fp2.mul(c1, rhs),
|
||||
c2: Fp2.mul(c2, rhs),
|
||||
};
|
||||
}
|
||||
const { c0: r0, c1: r1, c2: r2 } = rhs;
|
||||
const t0 = Fp2.multiply(c0, r0); // c0 * o0
|
||||
const t1 = Fp2.multiply(c1, r1); // c1 * o1
|
||||
const t2 = Fp2.multiply(c2, r2); // c2 * o2
|
||||
const t0 = Fp2.mul(c0, r0); // c0 * o0
|
||||
const t1 = Fp2.mul(c1, r1); // c1 * o1
|
||||
const t2 = Fp2.mul(c2, r2); // c2 * o2
|
||||
return {
|
||||
// t0 + (c1 + c2) * (r1 * r2) - (T1 + T2) * (u + 1)
|
||||
c0: Fp2.add(
|
||||
t0,
|
||||
Fp2.mulByNonresidue(
|
||||
Fp2.subtract(Fp2.multiply(Fp2.add(c1, c2), Fp2.add(r1, r2)), Fp2.add(t1, t2))
|
||||
Fp2.sub(Fp2.mul(Fp2.add(c1, c2), Fp2.add(r1, r2)), Fp2.add(t1, t2))
|
||||
)
|
||||
),
|
||||
// (c0 + c1) * (r0 + r1) - (T0 + T1) + T2 * (u + 1)
|
||||
c1: Fp2.add(
|
||||
Fp2.subtract(Fp2.multiply(Fp2.add(c0, c1), Fp2.add(r0, r1)), Fp2.add(t0, t1)),
|
||||
Fp2.sub(Fp2.mul(Fp2.add(c0, c1), Fp2.add(r0, r1)), Fp2.add(t0, t1)),
|
||||
Fp2.mulByNonresidue(t2)
|
||||
),
|
||||
// T1 + (c0 + c2) * (r0 + r2) - T0 + T2
|
||||
c2: Fp2.subtract(Fp2.add(t1, Fp2.multiply(Fp2.add(c0, c2), Fp2.add(r0, r2))), Fp2.add(t0, t2)),
|
||||
c2: Fp2.sub(Fp2.add(t1, Fp2.mul(Fp2.add(c0, c2), Fp2.add(r0, r2))), Fp2.add(t0, t2)),
|
||||
};
|
||||
};
|
||||
const Fp6Square = ({ c0, c1, c2 }: Fp6) => {
|
||||
let t0 = Fp2.square(c0); // c0²
|
||||
let t1 = Fp2.multiply(Fp2.multiply(c0, c1), 2n); // 2 * c0 * c1
|
||||
let t3 = Fp2.multiply(Fp2.multiply(c1, c2), 2n); // 2 * c1 * c2
|
||||
let t1 = Fp2.mul(Fp2.mul(c0, c1), 2n); // 2 * c0 * c1
|
||||
let t3 = Fp2.mul(Fp2.mul(c1, c2), 2n); // 2 * c1 * c2
|
||||
let t4 = Fp2.square(c2); // c2²
|
||||
return {
|
||||
c0: Fp2.add(Fp2.mulByNonresidue(t3), t0), // T3 * (u + 1) + T0
|
||||
c1: Fp2.add(Fp2.mulByNonresidue(t4), t1), // T4 * (u + 1) + T1
|
||||
// T1 + (c0 - c1 + c2)² + T3 - T0 - T4
|
||||
c2: Fp2.subtract(
|
||||
Fp2.subtract(Fp2.add(Fp2.add(t1, Fp2.square(Fp2.add(Fp2.subtract(c0, c1), c2))), t3), t0),
|
||||
c2: Fp2.sub(
|
||||
Fp2.sub(Fp2.add(Fp2.add(t1, Fp2.square(Fp2.add(Fp2.sub(c0, c1), c2))), t3), t0),
|
||||
t4
|
||||
),
|
||||
};
|
||||
@ -298,32 +298,32 @@ const Fp6: mod.Field<Fp6> & Fp6Utils = {
|
||||
},
|
||||
// Do we need division by bigint at all? Should be done via order:
|
||||
div: (lhs, rhs) =>
|
||||
Fp6.multiply(lhs, typeof rhs === 'bigint' ? Fp.invert(Fp.create(rhs)) : Fp6.invert(rhs)),
|
||||
Fp6.mul(lhs, typeof rhs === 'bigint' ? Fp.invert(Fp.create(rhs)) : Fp6.invert(rhs)),
|
||||
pow: (num, power) => mod.FpPow(Fp6, num, power),
|
||||
invertBatch: (nums) => mod.FpInvertBatch(Fp6, nums),
|
||||
// Normalized
|
||||
add: Fp6Add,
|
||||
subtract: Fp6Subtract,
|
||||
multiply: Fp6Multiply,
|
||||
sub: Fp6Subtract,
|
||||
mul: Fp6Multiply,
|
||||
square: Fp6Square,
|
||||
// NonNormalized stuff
|
||||
addN: Fp6Add,
|
||||
subtractN: Fp6Subtract,
|
||||
multiplyN: Fp6Multiply,
|
||||
subN: Fp6Subtract,
|
||||
mulN: Fp6Multiply,
|
||||
squareN: Fp6Square,
|
||||
|
||||
invert: ({ c0, c1, c2 }) => {
|
||||
let t0 = Fp2.subtract(Fp2.square(c0), Fp2.mulByNonresidue(Fp2.multiply(c2, c1))); // c0² - c2 * c1 * (u + 1)
|
||||
let t1 = Fp2.subtract(Fp2.mulByNonresidue(Fp2.square(c2)), Fp2.multiply(c0, c1)); // c2² * (u + 1) - c0 * c1
|
||||
let t2 = Fp2.subtract(Fp2.square(c1), Fp2.multiply(c0, c2)); // c1² - c0 * c2
|
||||
let t0 = Fp2.sub(Fp2.square(c0), Fp2.mulByNonresidue(Fp2.mul(c2, c1))); // c0² - c2 * c1 * (u + 1)
|
||||
let t1 = Fp2.sub(Fp2.mulByNonresidue(Fp2.square(c2)), Fp2.mul(c0, c1)); // c2² * (u + 1) - c0 * c1
|
||||
let t2 = Fp2.sub(Fp2.square(c1), Fp2.mul(c0, c2)); // c1² - c0 * c2
|
||||
// 1/(((c2 * T1 + c1 * T2) * v) + c0 * T0)
|
||||
let t4 = Fp2.invert(
|
||||
Fp2.add(
|
||||
Fp2.mulByNonresidue(Fp2.add(Fp2.multiply(c2, t1), Fp2.multiply(c1, t2))),
|
||||
Fp2.multiply(c0, t0)
|
||||
Fp2.mulByNonresidue(Fp2.add(Fp2.mul(c2, t1), Fp2.mul(c1, t2))),
|
||||
Fp2.mul(c0, t0)
|
||||
)
|
||||
);
|
||||
return { c0: Fp2.multiply(t4, t0), c1: Fp2.multiply(t4, t1), c2: Fp2.multiply(t4, t2) };
|
||||
return { c0: Fp2.mul(t4, t0), c1: Fp2.mul(t4, t1), c2: Fp2.mul(t4, t2) };
|
||||
},
|
||||
// Bytes utils
|
||||
fromBytes: (b: Uint8Array): Fp6 => {
|
||||
@ -354,35 +354,35 @@ const Fp6: mod.Field<Fp6> & Fp6Utils = {
|
||||
},
|
||||
frobeniusMap: ({ c0, c1, c2 }, power: number) => ({
|
||||
c0: Fp2.frobeniusMap(c0, power),
|
||||
c1: Fp2.multiply(Fp2.frobeniusMap(c1, power), FP6_FROBENIUS_COEFFICIENTS_1[power % 6]),
|
||||
c2: Fp2.multiply(Fp2.frobeniusMap(c2, power), FP6_FROBENIUS_COEFFICIENTS_2[power % 6]),
|
||||
c1: Fp2.mul(Fp2.frobeniusMap(c1, power), FP6_FROBENIUS_COEFFICIENTS_1[power % 6]),
|
||||
c2: Fp2.mul(Fp2.frobeniusMap(c2, power), FP6_FROBENIUS_COEFFICIENTS_2[power % 6]),
|
||||
}),
|
||||
mulByNonresidue: ({ c0, c1, c2 }) => ({ c0: Fp2.mulByNonresidue(c2), c1: c0, c2: c1 }),
|
||||
|
||||
// Sparse multiplication
|
||||
multiplyBy1: ({ c0, c1, c2 }, b1: Fp2): Fp6 => ({
|
||||
c0: Fp2.mulByNonresidue(Fp2.multiply(c2, b1)),
|
||||
c1: Fp2.multiply(c0, b1),
|
||||
c2: Fp2.multiply(c1, b1),
|
||||
c0: Fp2.mulByNonresidue(Fp2.mul(c2, b1)),
|
||||
c1: Fp2.mul(c0, b1),
|
||||
c2: Fp2.mul(c1, b1),
|
||||
}),
|
||||
// Sparse multiplication
|
||||
multiplyBy01({ c0, c1, c2 }, b0: Fp2, b1: Fp2): Fp6 {
|
||||
let t0 = Fp2.multiply(c0, b0); // c0 * b0
|
||||
let t1 = Fp2.multiply(c1, b1); // c1 * b1
|
||||
let t0 = Fp2.mul(c0, b0); // c0 * b0
|
||||
let t1 = Fp2.mul(c1, b1); // c1 * b1
|
||||
return {
|
||||
// ((c1 + c2) * b1 - T1) * (u + 1) + T0
|
||||
c0: Fp2.add(Fp2.mulByNonresidue(Fp2.subtract(Fp2.multiply(Fp2.add(c1, c2), b1), t1)), t0),
|
||||
c0: Fp2.add(Fp2.mulByNonresidue(Fp2.sub(Fp2.mul(Fp2.add(c1, c2), b1), t1)), t0),
|
||||
// (b0 + b1) * (c0 + c1) - T0 - T1
|
||||
c1: Fp2.subtract(Fp2.subtract(Fp2.multiply(Fp2.add(b0, b1), Fp2.add(c0, c1)), t0), t1),
|
||||
c1: Fp2.sub(Fp2.sub(Fp2.mul(Fp2.add(b0, b1), Fp2.add(c0, c1)), t0), t1),
|
||||
// (c0 + c2) * b0 - T0 + T1
|
||||
c2: Fp2.add(Fp2.subtract(Fp2.multiply(Fp2.add(c0, c2), b0), t0), t1),
|
||||
c2: Fp2.add(Fp2.sub(Fp2.mul(Fp2.add(c0, c2), b0), t0), t1),
|
||||
};
|
||||
},
|
||||
|
||||
multiplyByFp2: ({ c0, c1, c2 }, rhs: Fp2): Fp6 => ({
|
||||
c0: Fp2.multiply(c0, rhs),
|
||||
c1: Fp2.multiply(c1, rhs),
|
||||
c2: Fp2.multiply(c2, rhs),
|
||||
c0: Fp2.mul(c0, rhs),
|
||||
c1: Fp2.mul(c1, rhs),
|
||||
c2: Fp2.mul(c2, rhs),
|
||||
}),
|
||||
};
|
||||
|
||||
@ -448,26 +448,26 @@ const Fp12Add = ({ c0, c1 }: Fp12, { c0: r0, c1: r1 }: Fp12) => ({
|
||||
c1: Fp6.add(c1, r1),
|
||||
});
|
||||
const Fp12Subtract = ({ c0, c1 }: Fp12, { c0: r0, c1: r1 }: Fp12) => ({
|
||||
c0: Fp6.subtract(c0, r0),
|
||||
c1: Fp6.subtract(c1, r1),
|
||||
c0: Fp6.sub(c0, r0),
|
||||
c1: Fp6.sub(c1, r1),
|
||||
});
|
||||
const Fp12Multiply = ({ c0, c1 }: Fp12, rhs: Fp12 | bigint) => {
|
||||
if (typeof rhs === 'bigint') return { c0: Fp6.multiply(c0, rhs), c1: Fp6.multiply(c1, rhs) };
|
||||
if (typeof rhs === 'bigint') return { c0: Fp6.mul(c0, rhs), c1: Fp6.mul(c1, rhs) };
|
||||
let { c0: r0, c1: r1 } = rhs;
|
||||
let t1 = Fp6.multiply(c0, r0); // c0 * r0
|
||||
let t2 = Fp6.multiply(c1, r1); // c1 * r1
|
||||
let t1 = Fp6.mul(c0, r0); // c0 * r0
|
||||
let t2 = Fp6.mul(c1, r1); // c1 * r1
|
||||
return {
|
||||
c0: Fp6.add(t1, Fp6.mulByNonresidue(t2)), // T1 + T2 * v
|
||||
// (c0 + c1) * (r0 + r1) - (T1 + T2)
|
||||
c1: Fp6.subtract(Fp6.multiply(Fp6.add(c0, c1), Fp6.add(r0, r1)), Fp6.add(t1, t2)),
|
||||
c1: Fp6.sub(Fp6.mul(Fp6.add(c0, c1), Fp6.add(r0, r1)), Fp6.add(t1, t2)),
|
||||
};
|
||||
};
|
||||
const Fp12Square = ({ c0, c1 }: Fp12) => {
|
||||
let ab = Fp6.multiply(c0, c1); // c0 * c1
|
||||
let ab = Fp6.mul(c0, c1); // c0 * c1
|
||||
return {
|
||||
// (c1 * v + c0) * (c0 + c1) - AB - AB * v
|
||||
c0: Fp6.subtract(
|
||||
Fp6.subtract(Fp6.multiply(Fp6.add(Fp6.mulByNonresidue(c1), c0), Fp6.add(c0, c1)), ab),
|
||||
c0: Fp6.sub(
|
||||
Fp6.sub(Fp6.mul(Fp6.add(Fp6.mulByNonresidue(c1), c0), Fp6.add(c0, c1)), ab),
|
||||
Fp6.mulByNonresidue(ab)
|
||||
),
|
||||
c1: Fp6.add(ab, ab),
|
||||
@ -478,7 +478,7 @@ function Fp4Square(a: Fp2, b: Fp2): { first: Fp2; second: Fp2 } {
|
||||
const b2 = Fp2.square(b);
|
||||
return {
|
||||
first: Fp2.add(Fp2.mulByNonresidue(b2), a2), // b² * Nonresidue + a²
|
||||
second: Fp2.subtract(Fp2.subtract(Fp2.square(Fp2.add(a, b)), a2), b2), // (a + b)² - a² - b²
|
||||
second: Fp2.sub(Fp2.sub(Fp2.square(Fp2.add(a, b)), a2), b2), // (a + b)² - a² - b²
|
||||
};
|
||||
}
|
||||
type Fp12Utils = {
|
||||
@ -508,22 +508,22 @@ const Fp12: mod.Field<Fp12> & Fp12Utils = {
|
||||
throw new Error('Not implemented');
|
||||
},
|
||||
invert: ({ c0, c1 }) => {
|
||||
let t = Fp6.invert(Fp6.subtract(Fp6.square(c0), Fp6.mulByNonresidue(Fp6.square(c1)))); // 1 / (c0² - c1² * v)
|
||||
return { c0: Fp6.multiply(c0, t), c1: Fp6.negate(Fp6.multiply(c1, t)) }; // ((C0 * T) * T) + (-C1 * T) * w
|
||||
let t = Fp6.invert(Fp6.sub(Fp6.square(c0), Fp6.mulByNonresidue(Fp6.square(c1)))); // 1 / (c0² - c1² * v)
|
||||
return { c0: Fp6.mul(c0, t), c1: Fp6.negate(Fp6.mul(c1, t)) }; // ((C0 * T) * T) + (-C1 * T) * w
|
||||
},
|
||||
div: (lhs, rhs) =>
|
||||
Fp12.multiply(lhs, typeof rhs === 'bigint' ? Fp.invert(Fp.create(rhs)) : Fp12.invert(rhs)),
|
||||
Fp12.mul(lhs, typeof rhs === 'bigint' ? Fp.invert(Fp.create(rhs)) : Fp12.invert(rhs)),
|
||||
pow: (num, power) => mod.FpPow(Fp12, num, power),
|
||||
invertBatch: (nums) => mod.FpInvertBatch(Fp12, nums),
|
||||
// Normalized
|
||||
add: Fp12Add,
|
||||
subtract: Fp12Subtract,
|
||||
multiply: Fp12Multiply,
|
||||
sub: Fp12Subtract,
|
||||
mul: Fp12Multiply,
|
||||
square: Fp12Square,
|
||||
// NonNormalized stuff
|
||||
addN: Fp12Add,
|
||||
subtractN: Fp12Subtract,
|
||||
multiplyN: Fp12Multiply,
|
||||
subN: Fp12Subtract,
|
||||
mulN: Fp12Multiply,
|
||||
squareN: Fp12Square,
|
||||
|
||||
// Bytes utils
|
||||
@ -555,9 +555,9 @@ const Fp12: mod.Field<Fp12> & Fp12Utils = {
|
||||
return {
|
||||
c0: r0,
|
||||
c1: Fp6.create({
|
||||
c0: Fp2.multiply(c0, coeff),
|
||||
c1: Fp2.multiply(c1, coeff),
|
||||
c2: Fp2.multiply(c2, coeff),
|
||||
c0: Fp2.mul(c0, coeff),
|
||||
c1: Fp2.mul(c1, coeff),
|
||||
c2: Fp2.mul(c2, coeff),
|
||||
}),
|
||||
};
|
||||
},
|
||||
@ -568,8 +568,8 @@ const Fp12: mod.Field<Fp12> & Fp12Utils = {
|
||||
return {
|
||||
c0: Fp6.add(Fp6.mulByNonresidue(t1), t0), // T1 * v + T0
|
||||
// (c1 + c0) * [o0, o1+o4] - T0 - T1
|
||||
c1: Fp6.subtract(
|
||||
Fp6.subtract(Fp6.multiplyBy01(Fp6.add(c1, c0), o0, Fp2.add(o1, o4)), t0),
|
||||
c1: Fp6.sub(
|
||||
Fp6.sub(Fp6.multiplyBy01(Fp6.add(c1, c0), o0, Fp2.add(o1, o4)), t0),
|
||||
t1
|
||||
),
|
||||
};
|
||||
@ -593,14 +593,14 @@ const Fp12: mod.Field<Fp12> & Fp12Utils = {
|
||||
let t9 = Fp2.mulByNonresidue(t8); // T8 * (u + 1)
|
||||
return {
|
||||
c0: Fp6.create({
|
||||
c0: Fp2.add(Fp2.multiply(Fp2.subtract(t3, c0c0), 2n), t3), // 2 * (T3 - c0c0) + T3
|
||||
c1: Fp2.add(Fp2.multiply(Fp2.subtract(t5, c0c1), 2n), t5), // 2 * (T5 - c0c1) + T5
|
||||
c2: Fp2.add(Fp2.multiply(Fp2.subtract(t7, c0c2), 2n), t7),
|
||||
c0: Fp2.add(Fp2.mul(Fp2.sub(t3, c0c0), 2n), t3), // 2 * (T3 - c0c0) + T3
|
||||
c1: Fp2.add(Fp2.mul(Fp2.sub(t5, c0c1), 2n), t5), // 2 * (T5 - c0c1) + T5
|
||||
c2: Fp2.add(Fp2.mul(Fp2.sub(t7, c0c2), 2n), t7),
|
||||
}), // 2 * (T7 - c0c2) + T7
|
||||
c1: Fp6.create({
|
||||
c0: Fp2.add(Fp2.multiply(Fp2.add(t9, c1c0), 2n), t9), // 2 * (T9 + c1c0) + T9
|
||||
c1: Fp2.add(Fp2.multiply(Fp2.add(t4, c1c1), 2n), t4), // 2 * (T4 + c1c1) + T4
|
||||
c2: Fp2.add(Fp2.multiply(Fp2.add(t6, c1c2), 2n), t6),
|
||||
c0: Fp2.add(Fp2.mul(Fp2.add(t9, c1c0), 2n), t9), // 2 * (T9 + c1c0) + T9
|
||||
c1: Fp2.add(Fp2.mul(Fp2.add(t4, c1c1), 2n), t4), // 2 * (T4 + c1c1) + T4
|
||||
c2: Fp2.add(Fp2.mul(Fp2.add(t6, c1c2), 2n), t6),
|
||||
}),
|
||||
}; // 2 * (T6 + c1c2) + T6
|
||||
},
|
||||
@ -608,7 +608,7 @@ const Fp12: mod.Field<Fp12> & Fp12Utils = {
|
||||
let z = Fp12.ONE;
|
||||
for (let i = BLS_X_LEN - 1; i >= 0; i--) {
|
||||
z = Fp12._cyclotomicSquare(z);
|
||||
if (bitGet(n, i)) z = Fp12.multiply(z, num);
|
||||
if (bitGet(n, i)) z = Fp12.mul(z, num);
|
||||
}
|
||||
return z;
|
||||
},
|
||||
@ -619,23 +619,23 @@ const Fp12: mod.Field<Fp12> & Fp12Utils = {
|
||||
// this^(q⁶) / this
|
||||
const t0 = Fp12.div(Fp12.frobeniusMap(num, 6), num);
|
||||
// t0^(q²) * t0
|
||||
const t1 = Fp12.multiply(Fp12.frobeniusMap(t0, 2), t0);
|
||||
const t1 = Fp12.mul(Fp12.frobeniusMap(t0, 2), t0);
|
||||
const t2 = Fp12.conjugate(Fp12._cyclotomicExp(t1, x));
|
||||
const t3 = Fp12.multiply(Fp12.conjugate(Fp12._cyclotomicSquare(t1)), t2);
|
||||
const t3 = Fp12.mul(Fp12.conjugate(Fp12._cyclotomicSquare(t1)), t2);
|
||||
const t4 = Fp12.conjugate(Fp12._cyclotomicExp(t3, x));
|
||||
const t5 = Fp12.conjugate(Fp12._cyclotomicExp(t4, x));
|
||||
const t6 = Fp12.multiply(
|
||||
const t6 = Fp12.mul(
|
||||
Fp12.conjugate(Fp12._cyclotomicExp(t5, x)),
|
||||
Fp12._cyclotomicSquare(t2)
|
||||
);
|
||||
const t7 = Fp12.conjugate(Fp12._cyclotomicExp(t6, x));
|
||||
const t2_t5_pow_q2 = Fp12.frobeniusMap(Fp12.multiply(t2, t5), 2);
|
||||
const t4_t1_pow_q3 = Fp12.frobeniusMap(Fp12.multiply(t4, t1), 3);
|
||||
const t6_t1c_pow_q1 = Fp12.frobeniusMap(Fp12.multiply(t6, Fp12.conjugate(t1)), 1);
|
||||
const t7_t3c_t1 = Fp12.multiply(Fp12.multiply(t7, Fp12.conjugate(t3)), t1);
|
||||
const t2_t5_pow_q2 = Fp12.frobeniusMap(Fp12.mul(t2, t5), 2);
|
||||
const t4_t1_pow_q3 = Fp12.frobeniusMap(Fp12.mul(t4, t1), 3);
|
||||
const t6_t1c_pow_q1 = Fp12.frobeniusMap(Fp12.mul(t6, Fp12.conjugate(t1)), 1);
|
||||
const t7_t3c_t1 = Fp12.mul(Fp12.mul(t7, Fp12.conjugate(t3)), t1);
|
||||
// (t2 * t5)^(q²) * (t4 * t1)^(q³) * (t6 * t1.conj)^(q^1) * t7 * t3.conj * t1
|
||||
return Fp12.multiply(
|
||||
Fp12.multiply(Fp12.multiply(t2_t5_pow_q2, t4_t1_pow_q3), t6_t1c_pow_q1),
|
||||
return Fp12.mul(
|
||||
Fp12.mul(Fp12.mul(t2_t5_pow_q2, t4_t1_pow_q3), t6_t1c_pow_q1),
|
||||
t7_t3c_t1
|
||||
);
|
||||
},
|
||||
@ -855,18 +855,18 @@ const P_MINUS_9_DIV_16 = (Fp.ORDER ** 2n - 9n) / 16n;
|
||||
// if valid square root is found
|
||||
function sqrt_div_fp2(u: Fp2, v: Fp2) {
|
||||
const v7 = Fp2.pow(v, 7n);
|
||||
const uv7 = Fp2.multiply(u, v7);
|
||||
const uv15 = Fp2.multiply(uv7, Fp2.multiply(v7, v));
|
||||
const uv7 = Fp2.mul(u, v7);
|
||||
const uv15 = Fp2.mul(uv7, Fp2.mul(v7, v));
|
||||
// gamma = uv⁷ * (uv¹⁵)^((p² - 9) / 16)
|
||||
const gamma = Fp2.multiply(Fp2.pow(uv15, P_MINUS_9_DIV_16), uv7);
|
||||
const gamma = Fp2.mul(Fp2.pow(uv15, P_MINUS_9_DIV_16), uv7);
|
||||
let success = false;
|
||||
let result = gamma;
|
||||
// Constant-time routine, so we do not early-return.
|
||||
const positiveRootsOfUnity = FP2_ROOTS_OF_UNITY.slice(0, 4);
|
||||
positiveRootsOfUnity.forEach((root) => {
|
||||
// Valid if (root * gamma)² * v - u == 0
|
||||
const candidate = Fp2.multiply(root, gamma);
|
||||
if (Fp2.isZero(Fp2.subtract(Fp2.multiply(Fp2.pow(candidate, 2n), v), u)) && !success) {
|
||||
const candidate = Fp2.mul(root, gamma);
|
||||
if (Fp2.isZero(Fp2.sub(Fp2.mul(Fp2.pow(candidate, 2n), v), u)) && !success) {
|
||||
success = true;
|
||||
result = candidate;
|
||||
}
|
||||
@ -885,13 +885,13 @@ function map_to_curve_simple_swu_9mod16(t: bigint[] | Fp2): [Fp2, Fp2] {
|
||||
if (Array.isArray(t)) t = Fp2.fromBigTuple(t);
|
||||
|
||||
const t2 = Fp2.pow(t, 2n);
|
||||
const iso_3_z_t2 = Fp2.multiply(iso_3_z, t2);
|
||||
const iso_3_z_t2 = Fp2.mul(iso_3_z, t2);
|
||||
const ztzt = Fp2.add(iso_3_z_t2, Fp2.pow(iso_3_z_t2, 2n)); // (Z * t² + Z² * t⁴)
|
||||
let denominator = Fp2.negate(Fp2.multiply(iso_3_a, ztzt)); // -a(Z * t² + Z² * t⁴)
|
||||
let numerator = Fp2.multiply(iso_3_b, Fp2.add(ztzt, Fp2.ONE)); // b(Z * t² + Z² * t⁴ + 1)
|
||||
let denominator = Fp2.negate(Fp2.mul(iso_3_a, ztzt)); // -a(Z * t² + Z² * t⁴)
|
||||
let numerator = Fp2.mul(iso_3_b, Fp2.add(ztzt, Fp2.ONE)); // b(Z * t² + Z² * t⁴ + 1)
|
||||
|
||||
// Exceptional case
|
||||
if (Fp2.isZero(denominator)) denominator = Fp2.multiply(iso_3_z, iso_3_a);
|
||||
if (Fp2.isZero(denominator)) denominator = Fp2.mul(iso_3_z, iso_3_a);
|
||||
|
||||
// v = D³
|
||||
let v = Fp2.pow(denominator, 3n);
|
||||
@ -899,9 +899,9 @@ function map_to_curve_simple_swu_9mod16(t: bigint[] | Fp2): [Fp2, Fp2] {
|
||||
let u = Fp2.add(
|
||||
Fp2.add(
|
||||
Fp2.pow(numerator, 3n),
|
||||
Fp2.multiply(Fp2.multiply(iso_3_a, numerator), Fp2.pow(denominator, 2n))
|
||||
Fp2.mul(Fp2.mul(iso_3_a, numerator), Fp2.pow(denominator, 2n))
|
||||
),
|
||||
Fp2.multiply(iso_3_b, v)
|
||||
Fp2.mul(iso_3_b, v)
|
||||
);
|
||||
// Attempt y = sqrt(u / v)
|
||||
const { success, sqrtCandidateOrGamma } = sqrt_div_fp2(u, v);
|
||||
@ -909,22 +909,22 @@ function map_to_curve_simple_swu_9mod16(t: bigint[] | Fp2): [Fp2, Fp2] {
|
||||
if (success) y = sqrtCandidateOrGamma;
|
||||
// Handle case where (u / v) is not square
|
||||
// sqrt_candidate(x1) = sqrt_candidate(x0) * t³
|
||||
const sqrtCandidateX1 = Fp2.multiply(sqrtCandidateOrGamma, Fp2.pow(t, 3n));
|
||||
const sqrtCandidateX1 = Fp2.mul(sqrtCandidateOrGamma, Fp2.pow(t, 3n));
|
||||
|
||||
// u(x1) = Z³ * t⁶ * u(x0)
|
||||
u = Fp2.multiply(Fp2.pow(iso_3_z_t2, 3n), u);
|
||||
u = Fp2.mul(Fp2.pow(iso_3_z_t2, 3n), u);
|
||||
let success2 = false;
|
||||
FP2_ETAs.forEach((eta) => {
|
||||
// Valid solution if (eta * sqrt_candidate(x1))² * v - u == 0
|
||||
const etaSqrtCandidate = Fp2.multiply(eta, sqrtCandidateX1);
|
||||
const temp = Fp2.subtract(Fp2.multiply(Fp2.pow(etaSqrtCandidate, 2n), v), u);
|
||||
const etaSqrtCandidate = Fp2.mul(eta, sqrtCandidateX1);
|
||||
const temp = Fp2.sub(Fp2.mul(Fp2.pow(etaSqrtCandidate, 2n), v), u);
|
||||
if (Fp2.isZero(temp) && !success && !success2) {
|
||||
y = etaSqrtCandidate;
|
||||
success2 = true;
|
||||
}
|
||||
});
|
||||
if (!success && !success2) throw new Error('Hash to Curve - Optimized SWU failure');
|
||||
if (success2) numerator = Fp2.multiply(numerator, iso_3_z_t2);
|
||||
if (success2) numerator = Fp2.mul(numerator, iso_3_z_t2);
|
||||
y = y as Fp2;
|
||||
if (sgn0_fp2(t) !== sgn0_fp2(y)) y = Fp2.negate(y);
|
||||
return [Fp2.div(numerator, denominator), y];
|
||||
@ -945,27 +945,27 @@ function map_to_curve_simple_swu_3mod4(u: Fp): [Fp, Fp] {
|
||||
// Static value so we can know that is there always root
|
||||
const c2 = Fp.sqrt(Fp.pow(Fp.negate(Z), 3n)); // sqrt((-Z) ^ 3)
|
||||
const tv1 = Fp.square(u); // u ** 2n;
|
||||
const tv3 = Fp.multiply(Z, tv1); //
|
||||
const tv3 = Fp.mul(Z, tv1); //
|
||||
let xDen = Fp.add(Fp.square(tv3), tv3);
|
||||
// X
|
||||
const xNum1 = Fp.multiply(Fp.add(xDen, Fp.ONE), B); // (xd + 1) * B
|
||||
const xNum2 = Fp.multiply(tv3, xNum1); // x2 = x2n / xd = Z * u^2 * x1n / xd
|
||||
xDen = Fp.multiply(Fp.negate(A), xDen); // -A * xDen
|
||||
if (Fp.isZero(xDen)) xDen = Fp.multiply(A, Z);
|
||||
const xNum1 = Fp.mul(Fp.add(xDen, Fp.ONE), B); // (xd + 1) * B
|
||||
const xNum2 = Fp.mul(tv3, xNum1); // x2 = x2n / xd = Z * u^2 * x1n / xd
|
||||
xDen = Fp.mul(Fp.negate(A), xDen); // -A * xDen
|
||||
if (Fp.isZero(xDen)) xDen = Fp.mul(A, Z);
|
||||
let tv2 = Fp.square(xDen); // xDen ^ 2
|
||||
const gxd = Fp.multiply(tv2, xDen); // xDen ^ 3
|
||||
tv2 = Fp.multiply(A, tv2); // A * tv2
|
||||
let gx1 = Fp.multiply(Fp.add(Fp.square(xNum1), tv2), xNum1); // x1n^3 + A * x1n * xd^2
|
||||
tv2 = Fp.multiply(B, gxd); // B * gxd
|
||||
const gxd = Fp.mul(tv2, xDen); // xDen ^ 3
|
||||
tv2 = Fp.mul(A, tv2); // A * tv2
|
||||
let gx1 = Fp.mul(Fp.add(Fp.square(xNum1), tv2), xNum1); // x1n^3 + A * x1n * xd^2
|
||||
tv2 = Fp.mul(B, gxd); // B * gxd
|
||||
gx1 = Fp.add(gx1, tv2); // x1n^3 + A * x1n * xd^2 + B * xd^3
|
||||
tv2 = Fp.multiply(gx1, gxd); // gx1 * gxd
|
||||
const tv4 = Fp.multiply(Fp.square(gxd), tv2); // gx1 * gxd^3
|
||||
tv2 = Fp.mul(gx1, gxd); // gx1 * gxd
|
||||
const tv4 = Fp.mul(Fp.square(gxd), tv2); // gx1 * gxd^3
|
||||
// Y
|
||||
const y1 = Fp.multiply(Fp.pow(tv4, c1), tv2); // gx1 * gxd * (gx1 * gxd^3)^((q - 3) / 4)
|
||||
const y2 = Fp.multiply(Fp.multiply(Fp.multiply(y1, c2), tv1), u); // y1 * c2 * tv1 * u
|
||||
const y1 = Fp.mul(Fp.pow(tv4, c1), tv2); // gx1 * gxd * (gx1 * gxd^3)^((q - 3) / 4)
|
||||
const y2 = Fp.mul(Fp.mul(Fp.mul(y1, c2), tv1), u); // y1 * c2 * tv1 * u
|
||||
let xNum, yPos;
|
||||
// y1^2 * gxd == gx1
|
||||
if (Fp.equals(Fp.multiply(Fp.square(y1), gxd), gx1)) {
|
||||
if (Fp.equals(Fp.mul(Fp.square(y1), gxd), gx1)) {
|
||||
xNum = xNum1;
|
||||
yPos = y1;
|
||||
} else {
|
||||
@ -985,10 +985,10 @@ function isogenyMap<T, F extends mod.Field<T>>(
|
||||
y: T
|
||||
): [T, T] {
|
||||
const [xNum, xDen, yNum, yDen] = COEFF.map((val) =>
|
||||
val.reduce((acc, i) => field.add(field.multiply(acc, x), i))
|
||||
val.reduce((acc, i) => field.add(field.mul(acc, x), i))
|
||||
);
|
||||
x = field.div(xNum, xDen); // xNum / xDen
|
||||
y = field.multiply(y, field.div(yNum, yDen)); // y * (yNum / yDev)
|
||||
y = field.mul(y, field.div(yNum, yDen)); // y * (yNum / yDev)
|
||||
return [x, y];
|
||||
}
|
||||
// 3-isogeny map from E' to E
|
||||
@ -1005,8 +1005,8 @@ const wcu = Fp12.create({ c0: Fp6.ZERO, c1: ut_root });
|
||||
const [wsq_inv, wcu_inv] = Fp12.invertBatch([wsq, wcu]);
|
||||
function psi(x: Fp2, y: Fp2): [Fp2, Fp2] {
|
||||
// Untwist Fp2->Fp12 && frobenius(1) && twist back
|
||||
const x2 = Fp12.multiply(Fp12.frobeniusMap(Fp12.multiplyByFp2(wsq_inv, x), 1), wsq).c0.c0;
|
||||
const y2 = Fp12.multiply(Fp12.frobeniusMap(Fp12.multiplyByFp2(wcu_inv, y), 1), wcu).c0.c0;
|
||||
const x2 = Fp12.mul(Fp12.frobeniusMap(Fp12.multiplyByFp2(wsq_inv, x), 1), wsq).c0.c0;
|
||||
const y2 = Fp12.mul(Fp12.frobeniusMap(Fp12.multiplyByFp2(wcu_inv, y), 1), wcu).c0.c0;
|
||||
return [x2, y2];
|
||||
}
|
||||
// Ψ endomorphism
|
||||
@ -1021,7 +1021,7 @@ const PSI2_C1 =
|
||||
0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaacn;
|
||||
|
||||
function psi2(x: Fp2, y: Fp2): [Fp2, Fp2] {
|
||||
return [Fp2.multiply(x, PSI2_C1), Fp2.negate(y)];
|
||||
return [Fp2.mul(x, PSI2_C1), Fp2.negate(y)];
|
||||
}
|
||||
function G2psi2(c: ProjectiveConstructor<Fp2>, P: ProjectivePointType<Fp2>) {
|
||||
const affine = P.toAffine();
|
||||
@ -1113,7 +1113,7 @@ export const bls12_381: CurveFn<Fp, Fp2, Fp6, Fp12> = bls({
|
||||
// φ endomorphism
|
||||
const cubicRootOfUnityModP =
|
||||
0x5f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffen;
|
||||
const phi = new c(Fp.multiply(point.x, cubicRootOfUnityModP), point.y, point.z);
|
||||
const phi = new c(Fp.mul(point.x, cubicRootOfUnityModP), point.y, point.z);
|
||||
|
||||
// todo: unroll
|
||||
const xP = point.multiplyUnsafe(bls12_381.CURVE.x).negate(); // [x]P
|
||||
|
@ -92,8 +92,8 @@ const getPubKey = (priv) => bls.getPublicKey(priv);
|
||||
fc.assert(
|
||||
fc.property(FC_BIGINT, (num) => {
|
||||
const a = Fp.create(num);
|
||||
deepStrictEqual(Fp.subtract(a, Fp.ZERO), a);
|
||||
deepStrictEqual(Fp.subtract(a, a), Fp.ZERO);
|
||||
deepStrictEqual(Fp.sub(a, Fp.ZERO), a);
|
||||
deepStrictEqual(Fp.sub(a, a), Fp.ZERO);
|
||||
})
|
||||
);
|
||||
});
|
||||
@ -102,9 +102,9 @@ const getPubKey = (priv) => bls.getPublicKey(priv);
|
||||
fc.property(FC_BIGINT, (num1) => {
|
||||
const a = Fp.create(num1);
|
||||
const b = Fp.create(num1);
|
||||
deepStrictEqual(Fp.subtract(Fp.ZERO, a), Fp.negate(a));
|
||||
deepStrictEqual(Fp.subtract(a, b), Fp.add(a, Fp.negate(b)));
|
||||
deepStrictEqual(Fp.subtract(a, b), Fp.add(a, Fp.multiply(b, Fp.create(-1n))));
|
||||
deepStrictEqual(Fp.sub(Fp.ZERO, a), Fp.negate(a));
|
||||
deepStrictEqual(Fp.sub(a, b), Fp.add(a, Fp.negate(b)));
|
||||
deepStrictEqual(Fp.sub(a, b), Fp.add(a, Fp.mul(b, Fp.create(-1n))));
|
||||
})
|
||||
);
|
||||
});
|
||||
@ -112,8 +112,8 @@ const getPubKey = (priv) => bls.getPublicKey(priv);
|
||||
fc.assert(
|
||||
fc.property(FC_BIGINT, (num) => {
|
||||
const a = Fp.create(num);
|
||||
deepStrictEqual(Fp.negate(a), Fp.subtract(Fp.ZERO, a));
|
||||
deepStrictEqual(Fp.negate(a), Fp.multiply(a, Fp.create(-1n)));
|
||||
deepStrictEqual(Fp.negate(a), Fp.sub(Fp.ZERO, a));
|
||||
deepStrictEqual(Fp.negate(a), Fp.mul(a, Fp.create(-1n)));
|
||||
})
|
||||
);
|
||||
});
|
||||
@ -123,7 +123,7 @@ const getPubKey = (priv) => bls.getPublicKey(priv);
|
||||
fc.property(FC_BIGINT, FC_BIGINT, (num1, num2) => {
|
||||
const a = Fp.create(num1);
|
||||
const b = Fp.create(num2);
|
||||
deepStrictEqual(Fp.multiply(a, b), Fp.multiply(b, a));
|
||||
deepStrictEqual(Fp.mul(a, b), Fp.mul(b, a));
|
||||
})
|
||||
);
|
||||
});
|
||||
@ -133,7 +133,7 @@ const getPubKey = (priv) => bls.getPublicKey(priv);
|
||||
const a = Fp.create(num1);
|
||||
const b = Fp.create(num2);
|
||||
const c = Fp.create(num3);
|
||||
deepStrictEqual(Fp.multiply(a, Fp.multiply(b, c)), Fp.multiply(Fp.multiply(a, b), c));
|
||||
deepStrictEqual(Fp.mul(a, Fp.mul(b, c)), Fp.mul(Fp.mul(a, b), c));
|
||||
})
|
||||
);
|
||||
});
|
||||
@ -143,7 +143,7 @@ const getPubKey = (priv) => bls.getPublicKey(priv);
|
||||
const a = Fp.create(num1);
|
||||
const b = Fp.create(num2);
|
||||
const c = Fp.create(num3);
|
||||
deepStrictEqual(Fp.multiply(a, Fp.add(b, c)), Fp.add(Fp.multiply(b, a), Fp.multiply(c, a)));
|
||||
deepStrictEqual(Fp.mul(a, Fp.add(b, c)), Fp.add(Fp.mul(b, a), Fp.mul(c, a)));
|
||||
})
|
||||
);
|
||||
});
|
||||
@ -151,13 +151,13 @@ const getPubKey = (priv) => bls.getPublicKey(priv);
|
||||
fc.assert(
|
||||
fc.property(FC_BIGINT, (num) => {
|
||||
const a = Fp.create(num);
|
||||
deepStrictEqual(Fp.multiply(a, Fp.create(0n)), Fp.ZERO);
|
||||
deepStrictEqual(Fp.multiply(a, Fp.ZERO), Fp.ZERO);
|
||||
deepStrictEqual(Fp.multiply(a, Fp.create(1n)), a);
|
||||
deepStrictEqual(Fp.multiply(a, Fp.ONE), a);
|
||||
deepStrictEqual(Fp.multiply(a, Fp.create(2n)), Fp.add(a, a));
|
||||
deepStrictEqual(Fp.multiply(a, Fp.create(3n)), Fp.add(Fp.add(a, a), a));
|
||||
deepStrictEqual(Fp.multiply(a, Fp.create(4n)), Fp.add(Fp.add(Fp.add(a, a), a), a));
|
||||
deepStrictEqual(Fp.mul(a, Fp.create(0n)), Fp.ZERO);
|
||||
deepStrictEqual(Fp.mul(a, Fp.ZERO), Fp.ZERO);
|
||||
deepStrictEqual(Fp.mul(a, Fp.create(1n)), a);
|
||||
deepStrictEqual(Fp.mul(a, Fp.ONE), a);
|
||||
deepStrictEqual(Fp.mul(a, Fp.create(2n)), Fp.add(a, a));
|
||||
deepStrictEqual(Fp.mul(a, Fp.create(3n)), Fp.add(Fp.add(a, a), a));
|
||||
deepStrictEqual(Fp.mul(a, Fp.create(4n)), Fp.add(Fp.add(Fp.add(a, a), a), a));
|
||||
})
|
||||
);
|
||||
});
|
||||
@ -165,7 +165,7 @@ const getPubKey = (priv) => bls.getPublicKey(priv);
|
||||
fc.assert(
|
||||
fc.property(FC_BIGINT, (num) => {
|
||||
const a = Fp.create(num);
|
||||
deepStrictEqual(Fp.square(a), Fp.multiply(a, a));
|
||||
deepStrictEqual(Fp.square(a), Fp.mul(a, a));
|
||||
})
|
||||
);
|
||||
});
|
||||
@ -175,8 +175,8 @@ const getPubKey = (priv) => bls.getPublicKey(priv);
|
||||
const a = Fp.create(num);
|
||||
deepStrictEqual(Fp.pow(a, 0n), Fp.ONE);
|
||||
deepStrictEqual(Fp.pow(a, 1n), a);
|
||||
deepStrictEqual(Fp.pow(a, 2n), Fp.multiply(a, a));
|
||||
deepStrictEqual(Fp.pow(a, 3n), Fp.multiply(Fp.multiply(a, a), a));
|
||||
deepStrictEqual(Fp.pow(a, 2n), Fp.mul(a, a));
|
||||
deepStrictEqual(Fp.pow(a, 3n), Fp.mul(Fp.mul(a, a), a));
|
||||
})
|
||||
);
|
||||
});
|
||||
@ -221,7 +221,7 @@ const getPubKey = (priv) => bls.getPublicKey(priv);
|
||||
fc.property(FC_BIGINT, FC_BIGINT, (num1, num2) => {
|
||||
const a = Fp.create(num1);
|
||||
const b = Fp.create(num2);
|
||||
deepStrictEqual(Fp.div(a, b), Fp.multiply(a, Fp.invert(b)));
|
||||
deepStrictEqual(Fp.div(a, b), Fp.mul(a, Fp.invert(b)));
|
||||
})
|
||||
);
|
||||
});
|
||||
@ -285,8 +285,8 @@ const getPubKey = (priv) => bls.getPublicKey(priv);
|
||||
fc.assert(
|
||||
fc.property(FC_BIGINT_2, (num) => {
|
||||
const a = Fp2.fromBigTuple([num[0], num[1]]);
|
||||
deepStrictEqual(Fp2.subtract(a, Fp2.ZERO), a);
|
||||
deepStrictEqual(Fp2.subtract(a, a), Fp2.ZERO);
|
||||
deepStrictEqual(Fp2.sub(a, Fp2.ZERO), a);
|
||||
deepStrictEqual(Fp2.sub(a, a), Fp2.ZERO);
|
||||
})
|
||||
);
|
||||
});
|
||||
@ -295,9 +295,9 @@ const getPubKey = (priv) => bls.getPublicKey(priv);
|
||||
fc.property(FC_BIGINT_2, (num1) => {
|
||||
const a = Fp2.fromBigTuple([num1[0], num1[1]]);
|
||||
const b = Fp2.fromBigTuple([num1[0], num1[1]]);
|
||||
deepStrictEqual(Fp2.subtract(Fp2.ZERO, a), Fp2.negate(a));
|
||||
deepStrictEqual(Fp2.subtract(a, b), Fp2.add(a, Fp2.negate(b)));
|
||||
deepStrictEqual(Fp2.subtract(a, b), Fp2.add(a, Fp2.multiply(b, -1n)));
|
||||
deepStrictEqual(Fp2.sub(Fp2.ZERO, a), Fp2.negate(a));
|
||||
deepStrictEqual(Fp2.sub(a, b), Fp2.add(a, Fp2.negate(b)));
|
||||
deepStrictEqual(Fp2.sub(a, b), Fp2.add(a, Fp2.mul(b, -1n)));
|
||||
})
|
||||
);
|
||||
});
|
||||
@ -305,8 +305,8 @@ const getPubKey = (priv) => bls.getPublicKey(priv);
|
||||
fc.assert(
|
||||
fc.property(FC_BIGINT_2, (num) => {
|
||||
const a = Fp2.fromBigTuple([num[0], num[1]]);
|
||||
deepStrictEqual(Fp2.negate(a), Fp2.subtract(Fp2.ZERO, a));
|
||||
deepStrictEqual(Fp2.negate(a), Fp2.multiply(a, -1n));
|
||||
deepStrictEqual(Fp2.negate(a), Fp2.sub(Fp2.ZERO, a));
|
||||
deepStrictEqual(Fp2.negate(a), Fp2.mul(a, -1n));
|
||||
})
|
||||
);
|
||||
});
|
||||
@ -316,7 +316,7 @@ const getPubKey = (priv) => bls.getPublicKey(priv);
|
||||
fc.property(FC_BIGINT_2, FC_BIGINT_2, (num1, num2) => {
|
||||
const a = Fp2.fromBigTuple([num1[0], num1[1]]);
|
||||
const b = Fp2.fromBigTuple([num2[0], num2[1]]);
|
||||
deepStrictEqual(Fp2.multiply(a, b), Fp2.multiply(b, a));
|
||||
deepStrictEqual(Fp2.mul(a, b), Fp2.mul(b, a));
|
||||
})
|
||||
);
|
||||
});
|
||||
@ -326,7 +326,7 @@ const getPubKey = (priv) => bls.getPublicKey(priv);
|
||||
const a = Fp2.fromBigTuple([num1[0], num1[1]]);
|
||||
const b = Fp2.fromBigTuple([num2[0], num2[1]]);
|
||||
const c = Fp2.fromBigTuple([num3[0], num3[1]]);
|
||||
deepStrictEqual(Fp2.multiply(a, Fp2.multiply(b, c)), Fp2.multiply(Fp2.multiply(a, b), c));
|
||||
deepStrictEqual(Fp2.mul(a, Fp2.mul(b, c)), Fp2.mul(Fp2.mul(a, b), c));
|
||||
})
|
||||
);
|
||||
});
|
||||
@ -337,8 +337,8 @@ const getPubKey = (priv) => bls.getPublicKey(priv);
|
||||
const b = Fp2.fromBigTuple([num2[0], num2[1]]);
|
||||
const c = Fp2.fromBigTuple([num3[0], num3[1]]);
|
||||
deepStrictEqual(
|
||||
Fp2.multiply(a, Fp2.add(b, c)),
|
||||
Fp2.add(Fp2.multiply(b, a), Fp2.multiply(c, a))
|
||||
Fp2.mul(a, Fp2.add(b, c)),
|
||||
Fp2.add(Fp2.mul(b, a), Fp2.mul(c, a))
|
||||
);
|
||||
})
|
||||
);
|
||||
@ -347,13 +347,13 @@ const getPubKey = (priv) => bls.getPublicKey(priv);
|
||||
fc.assert(
|
||||
fc.property(FC_BIGINT_2, (num) => {
|
||||
const a = Fp2.fromBigTuple([num[0], num[1]]);
|
||||
deepStrictEqual(Fp2.multiply(a, 0n), Fp2.ZERO);
|
||||
deepStrictEqual(Fp2.multiply(a, Fp2.ZERO), Fp2.ZERO);
|
||||
deepStrictEqual(Fp2.multiply(a, 1n), a);
|
||||
deepStrictEqual(Fp2.multiply(a, Fp2.ONE), a);
|
||||
deepStrictEqual(Fp2.multiply(a, 2n), Fp2.add(a, a));
|
||||
deepStrictEqual(Fp2.multiply(a, 3n), Fp2.add(Fp2.add(a, a), a));
|
||||
deepStrictEqual(Fp2.multiply(a, 4n), Fp2.add(Fp2.add(Fp2.add(a, a), a), a));
|
||||
deepStrictEqual(Fp2.mul(a, 0n), Fp2.ZERO);
|
||||
deepStrictEqual(Fp2.mul(a, Fp2.ZERO), Fp2.ZERO);
|
||||
deepStrictEqual(Fp2.mul(a, 1n), a);
|
||||
deepStrictEqual(Fp2.mul(a, Fp2.ONE), a);
|
||||
deepStrictEqual(Fp2.mul(a, 2n), Fp2.add(a, a));
|
||||
deepStrictEqual(Fp2.mul(a, 3n), Fp2.add(Fp2.add(a, a), a));
|
||||
deepStrictEqual(Fp2.mul(a, 4n), Fp2.add(Fp2.add(Fp2.add(a, a), a), a));
|
||||
})
|
||||
);
|
||||
});
|
||||
@ -361,7 +361,7 @@ const getPubKey = (priv) => bls.getPublicKey(priv);
|
||||
fc.assert(
|
||||
fc.property(FC_BIGINT_2, (num) => {
|
||||
const a = Fp2.fromBigTuple([num[0], num[1]]);
|
||||
deepStrictEqual(Fp2.square(a), Fp2.multiply(a, a));
|
||||
deepStrictEqual(Fp2.square(a), Fp2.mul(a, a));
|
||||
})
|
||||
);
|
||||
});
|
||||
@ -371,8 +371,8 @@ const getPubKey = (priv) => bls.getPublicKey(priv);
|
||||
const a = Fp2.fromBigTuple([num[0], num[1]]);
|
||||
deepStrictEqual(Fp2.pow(a, 0n), Fp2.ONE);
|
||||
deepStrictEqual(Fp2.pow(a, 1n), a);
|
||||
deepStrictEqual(Fp2.pow(a, 2n), Fp2.multiply(a, a));
|
||||
deepStrictEqual(Fp2.pow(a, 3n), Fp2.multiply(Fp2.multiply(a, a), a));
|
||||
deepStrictEqual(Fp2.pow(a, 2n), Fp2.mul(a, a));
|
||||
deepStrictEqual(Fp2.pow(a, 3n), Fp2.mul(Fp2.mul(a, a), a));
|
||||
})
|
||||
);
|
||||
});
|
||||
@ -410,7 +410,7 @@ const getPubKey = (priv) => bls.getPublicKey(priv);
|
||||
fc.property(FC_BIGINT_2, FC_BIGINT_2, (num1, num2) => {
|
||||
const a = Fp2.fromBigTuple([num1[0], num1[1]]);
|
||||
const b = Fp2.fromBigTuple([num2[0], num2[1]]);
|
||||
deepStrictEqual(Fp2.div(a, b), Fp2.multiply(a, Fp2.invert(b)));
|
||||
deepStrictEqual(Fp2.div(a, b), Fp2.mul(a, Fp2.invert(b)));
|
||||
})
|
||||
);
|
||||
});
|
||||
@ -536,8 +536,8 @@ const getPubKey = (priv) => bls.getPublicKey(priv);
|
||||
fc.assert(
|
||||
fc.property(FC_BIGINT_12, (num) => {
|
||||
const a = Fp12.fromBigTwelve(num);
|
||||
deepStrictEqual(Fp12.subtract(a, Fp12.ZERO), a);
|
||||
deepStrictEqual(Fp12.subtract(a, a), Fp12.ZERO);
|
||||
deepStrictEqual(Fp12.sub(a, Fp12.ZERO), a);
|
||||
deepStrictEqual(Fp12.sub(a, a), Fp12.ZERO);
|
||||
})
|
||||
);
|
||||
});
|
||||
@ -546,9 +546,9 @@ const getPubKey = (priv) => bls.getPublicKey(priv);
|
||||
fc.property(FC_BIGINT_12, (num1) => {
|
||||
const a = Fp12.fromBigTwelve(num1);
|
||||
const b = Fp12.fromBigTwelve(num1);
|
||||
deepStrictEqual(Fp12.subtract(Fp12.ZERO, a), Fp12.negate(a));
|
||||
deepStrictEqual(Fp12.subtract(a, b), Fp12.add(a, Fp12.negate(b)));
|
||||
deepStrictEqual(Fp12.subtract(a, b), Fp12.add(a, Fp12.multiply(b, -1n)));
|
||||
deepStrictEqual(Fp12.sub(Fp12.ZERO, a), Fp12.negate(a));
|
||||
deepStrictEqual(Fp12.sub(a, b), Fp12.add(a, Fp12.negate(b)));
|
||||
deepStrictEqual(Fp12.sub(a, b), Fp12.add(a, Fp12.mul(b, -1n)));
|
||||
})
|
||||
);
|
||||
});
|
||||
@ -556,8 +556,8 @@ const getPubKey = (priv) => bls.getPublicKey(priv);
|
||||
fc.assert(
|
||||
fc.property(FC_BIGINT_12, (num) => {
|
||||
const a = Fp12.fromBigTwelve(num);
|
||||
deepStrictEqual(Fp12.negate(a), Fp12.subtract(Fp12.ZERO, a));
|
||||
deepStrictEqual(Fp12.negate(a), Fp12.multiply(a, -1n));
|
||||
deepStrictEqual(Fp12.negate(a), Fp12.sub(Fp12.ZERO, a));
|
||||
deepStrictEqual(Fp12.negate(a), Fp12.mul(a, -1n));
|
||||
})
|
||||
);
|
||||
});
|
||||
@ -567,7 +567,7 @@ const getPubKey = (priv) => bls.getPublicKey(priv);
|
||||
fc.property(FC_BIGINT_12, FC_BIGINT_12, (num1, num2) => {
|
||||
const a = Fp12.fromBigTwelve(num1);
|
||||
const b = Fp12.fromBigTwelve(num2);
|
||||
deepStrictEqual(Fp12.multiply(a, b), Fp12.multiply(b, a));
|
||||
deepStrictEqual(Fp12.mul(a, b), Fp12.mul(b, a));
|
||||
})
|
||||
);
|
||||
});
|
||||
@ -578,8 +578,8 @@ const getPubKey = (priv) => bls.getPublicKey(priv);
|
||||
const b = Fp12.fromBigTwelve(num2);
|
||||
const c = Fp12.fromBigTwelve(num3);
|
||||
deepStrictEqual(
|
||||
Fp12.multiply(a, Fp12.multiply(b, c)),
|
||||
Fp12.multiply(Fp12.multiply(a, b), c)
|
||||
Fp12.mul(a, Fp12.mul(b, c)),
|
||||
Fp12.mul(Fp12.mul(a, b), c)
|
||||
);
|
||||
})
|
||||
);
|
||||
@ -591,8 +591,8 @@ const getPubKey = (priv) => bls.getPublicKey(priv);
|
||||
const b = Fp12.fromBigTwelve(num2);
|
||||
const c = Fp12.fromBigTwelve(num3);
|
||||
deepStrictEqual(
|
||||
Fp12.multiply(a, Fp12.add(b, c)),
|
||||
Fp12.add(Fp12.multiply(b, a), Fp12.multiply(c, a))
|
||||
Fp12.mul(a, Fp12.add(b, c)),
|
||||
Fp12.add(Fp12.mul(b, a), Fp12.mul(c, a))
|
||||
);
|
||||
})
|
||||
);
|
||||
@ -601,13 +601,13 @@ const getPubKey = (priv) => bls.getPublicKey(priv);
|
||||
fc.assert(
|
||||
fc.property(FC_BIGINT_12, (num) => {
|
||||
const a = Fp12.fromBigTwelve(num);
|
||||
deepStrictEqual(Fp12.multiply(a, 0n), Fp12.ZERO);
|
||||
deepStrictEqual(Fp12.multiply(a, Fp12.ZERO), Fp12.ZERO);
|
||||
deepStrictEqual(Fp12.multiply(a, 1n), a);
|
||||
deepStrictEqual(Fp12.multiply(a, Fp12.ONE), a);
|
||||
deepStrictEqual(Fp12.multiply(a, 2n), Fp12.add(a, a));
|
||||
deepStrictEqual(Fp12.multiply(a, 3n), Fp12.add(Fp12.add(a, a), a));
|
||||
deepStrictEqual(Fp12.multiply(a, 4n), Fp12.add(Fp12.add(Fp12.add(a, a), a), a));
|
||||
deepStrictEqual(Fp12.mul(a, 0n), Fp12.ZERO);
|
||||
deepStrictEqual(Fp12.mul(a, Fp12.ZERO), Fp12.ZERO);
|
||||
deepStrictEqual(Fp12.mul(a, 1n), a);
|
||||
deepStrictEqual(Fp12.mul(a, Fp12.ONE), a);
|
||||
deepStrictEqual(Fp12.mul(a, 2n), Fp12.add(a, a));
|
||||
deepStrictEqual(Fp12.mul(a, 3n), Fp12.add(Fp12.add(a, a), a));
|
||||
deepStrictEqual(Fp12.mul(a, 4n), Fp12.add(Fp12.add(Fp12.add(a, a), a), a));
|
||||
})
|
||||
);
|
||||
});
|
||||
@ -615,7 +615,7 @@ const getPubKey = (priv) => bls.getPublicKey(priv);
|
||||
fc.assert(
|
||||
fc.property(FC_BIGINT_12, (num) => {
|
||||
const a = Fp12.fromBigTwelve(num);
|
||||
deepStrictEqual(Fp12.square(a), Fp12.multiply(a, a));
|
||||
deepStrictEqual(Fp12.square(a), Fp12.mul(a, a));
|
||||
})
|
||||
);
|
||||
});
|
||||
@ -625,8 +625,8 @@ const getPubKey = (priv) => bls.getPublicKey(priv);
|
||||
const a = Fp12.fromBigTwelve(num);
|
||||
deepStrictEqual(Fp12.pow(a, 0n), Fp12.ONE);
|
||||
deepStrictEqual(Fp12.pow(a, 1n), a);
|
||||
deepStrictEqual(Fp12.pow(a, 2n), Fp12.multiply(a, a));
|
||||
deepStrictEqual(Fp12.pow(a, 3n), Fp12.multiply(Fp12.multiply(a, a), a));
|
||||
deepStrictEqual(Fp12.pow(a, 2n), Fp12.mul(a, a));
|
||||
deepStrictEqual(Fp12.pow(a, 3n), Fp12.mul(Fp12.mul(a, a), a));
|
||||
})
|
||||
);
|
||||
});
|
||||
@ -664,7 +664,7 @@ const getPubKey = (priv) => bls.getPublicKey(priv);
|
||||
fc.property(FC_BIGINT_12, FC_BIGINT_12, (num1, num2) => {
|
||||
const a = Fp12.fromBigTwelve(num1);
|
||||
const b = Fp12.fromBigTwelve(num2);
|
||||
deepStrictEqual(Fp12.div(a, b), Fp12.multiply(a, Fp12.invert(b)));
|
||||
deepStrictEqual(Fp12.div(a, b), Fp12.mul(a, Fp12.invert(b)));
|
||||
})
|
||||
);
|
||||
});
|
||||
@ -1519,7 +1519,7 @@ should('bls12-381/basic/should not verify wrong multi-signature as simple signat
|
||||
should('pairing/creates negative G1 pairing', () => {
|
||||
const p1 = pairing(G1, G2);
|
||||
const p2 = pairing(G1.negate(), G2);
|
||||
deepStrictEqual(Fp12.multiply(p1, p2), Fp12.ONE);
|
||||
deepStrictEqual(Fp12.mul(p1, p2), Fp12.ONE);
|
||||
});
|
||||
should('pairing/creates negative G2 pairing', () => {
|
||||
const p2 = pairing(G1.negate(), G2);
|
||||
@ -1534,7 +1534,7 @@ should('bls12-381/basic/should not verify wrong multi-signature as simple signat
|
||||
should('pairing/G1 billinearity', () => {
|
||||
const p1 = pairing(G1, G2);
|
||||
const p2 = pairing(G1.multiply(2n), G2);
|
||||
deepStrictEqual(Fp12.multiply(p1, p1), p2);
|
||||
deepStrictEqual(Fp12.mul(p1, p1), p2);
|
||||
});
|
||||
should('pairing/should not degenerate', () => {
|
||||
const p1 = pairing(G1, G2);
|
||||
@ -1547,7 +1547,7 @@ should('bls12-381/basic/should not verify wrong multi-signature as simple signat
|
||||
should('pairing/G2 billinearity', () => {
|
||||
const p1 = pairing(G1, G2);
|
||||
const p2 = pairing(G1, G2.multiply(2n));
|
||||
deepStrictEqual(Fp12.multiply(p1, p1), p2);
|
||||
deepStrictEqual(Fp12.mul(p1, p1), p2);
|
||||
});
|
||||
should('pairing/proper pairing composite check', () => {
|
||||
const p1 = pairing(G1.multiply(37n), G2.multiply(27n));
|
||||
|
42
src/bls.ts
42
src/bls.ts
@ -114,33 +114,33 @@ export function bls<Fp2, Fp6, Fp12>(
|
||||
// Double
|
||||
let t0 = Fp2.square(Ry); // Ry²
|
||||
let t1 = Fp2.square(Rz); // Rz²
|
||||
let t2 = Fp2.multiplyByB(Fp2.multiply(t1, 3n)); // 3 * T1 * B
|
||||
let t3 = Fp2.multiply(t2, 3n); // 3 * T2
|
||||
let t4 = Fp2.subtract(Fp2.subtract(Fp2.square(Fp2.add(Ry, Rz)), t1), t0); // (Ry + Rz)² - T1 - T0
|
||||
let t2 = Fp2.multiplyByB(Fp2.mul(t1, 3n)); // 3 * T1 * B
|
||||
let t3 = Fp2.mul(t2, 3n); // 3 * T2
|
||||
let t4 = Fp2.sub(Fp2.sub(Fp2.square(Fp2.add(Ry, Rz)), t1), t0); // (Ry + Rz)² - T1 - T0
|
||||
ell_coeff.push([
|
||||
Fp2.subtract(t2, t0), // T2 - T0
|
||||
Fp2.multiply(Fp2.square(Rx), 3n), // 3 * Rx²
|
||||
Fp2.sub(t2, t0), // T2 - T0
|
||||
Fp2.mul(Fp2.square(Rx), 3n), // 3 * Rx²
|
||||
Fp2.negate(t4), // -T4
|
||||
]);
|
||||
Rx = Fp2.div(Fp2.multiply(Fp2.multiply(Fp2.subtract(t0, t3), Rx), Ry), 2n); // ((T0 - T3) * Rx * Ry) / 2
|
||||
Ry = Fp2.subtract(Fp2.square(Fp2.div(Fp2.add(t0, t3), 2n)), Fp2.multiply(Fp2.square(t2), 3n)); // ((T0 + T3) / 2)² - 3 * T2²
|
||||
Rz = Fp2.multiply(t0, t4); // T0 * T4
|
||||
Rx = Fp2.div(Fp2.mul(Fp2.mul(Fp2.sub(t0, t3), Rx), Ry), 2n); // ((T0 - T3) * Rx * Ry) / 2
|
||||
Ry = Fp2.sub(Fp2.square(Fp2.div(Fp2.add(t0, t3), 2n)), Fp2.mul(Fp2.square(t2), 3n)); // ((T0 + T3) / 2)² - 3 * T2²
|
||||
Rz = Fp2.mul(t0, t4); // T0 * T4
|
||||
if (bitGet(CURVE.x, i)) {
|
||||
// Addition
|
||||
let t0 = Fp2.subtract(Ry, Fp2.multiply(Qy, Rz)); // Ry - Qy * Rz
|
||||
let t1 = Fp2.subtract(Rx, Fp2.multiply(Qx, Rz)); // Rx - Qx * Rz
|
||||
let t0 = Fp2.sub(Ry, Fp2.mul(Qy, Rz)); // Ry - Qy * Rz
|
||||
let t1 = Fp2.sub(Rx, Fp2.mul(Qx, Rz)); // Rx - Qx * Rz
|
||||
ell_coeff.push([
|
||||
Fp2.subtract(Fp2.multiply(t0, Qx), Fp2.multiply(t1, Qy)), // T0 * Qx - T1 * Qy
|
||||
Fp2.sub(Fp2.mul(t0, Qx), Fp2.mul(t1, Qy)), // T0 * Qx - T1 * Qy
|
||||
Fp2.negate(t0), // -T0
|
||||
t1, // T1
|
||||
]);
|
||||
let t2 = Fp2.square(t1); // T1²
|
||||
let t3 = Fp2.multiply(t2, t1); // T2 * T1
|
||||
let t4 = Fp2.multiply(t2, Rx); // T2 * Rx
|
||||
let t5 = Fp2.add(Fp2.subtract(t3, Fp2.multiply(t4, 2n)), Fp2.multiply(Fp2.square(t0), Rz)); // T3 - 2 * T4 + T0² * Rz
|
||||
Rx = Fp2.multiply(t1, t5); // T1 * T5
|
||||
Ry = Fp2.subtract(Fp2.multiply(Fp2.subtract(t4, t5), t0), Fp2.multiply(t3, Ry)); // (T4 - T5) * T0 - T3 * Ry
|
||||
Rz = Fp2.multiply(Rz, t3); // Rz * T3
|
||||
let t3 = Fp2.mul(t2, t1); // T2 * T1
|
||||
let t4 = Fp2.mul(t2, Rx); // T2 * Rx
|
||||
let t5 = Fp2.add(Fp2.sub(t3, Fp2.mul(t4, 2n)), Fp2.mul(Fp2.square(t0), Rz)); // T3 - 2 * T4 + T0² * Rz
|
||||
Rx = Fp2.mul(t1, t5); // T1 * T5
|
||||
Ry = Fp2.sub(Fp2.mul(Fp2.sub(t4, t5), t0), Fp2.mul(t3, Ry)); // (T4 - T5) * T0 - T3 * Ry
|
||||
Rz = Fp2.mul(Rz, t3); // Rz * T3
|
||||
}
|
||||
}
|
||||
return ell_coeff;
|
||||
@ -152,11 +152,11 @@ export function bls<Fp2, Fp6, Fp12>(
|
||||
let f12 = Fp12.ONE;
|
||||
for (let j = 0, i = BLS_X_LEN - 2; i >= 0; i--, j++) {
|
||||
const E = ell[j];
|
||||
f12 = Fp12.multiplyBy014(f12, E[0], Fp2.multiply(E[1], Px), Fp2.multiply(E[2], Py));
|
||||
f12 = Fp12.multiplyBy014(f12, E[0], Fp2.mul(E[1], Px), Fp2.mul(E[2], Py));
|
||||
if (bitGet(CURVE.x, i)) {
|
||||
j += 1;
|
||||
const F = ell[j];
|
||||
f12 = Fp12.multiplyBy014(f12, F[0], Fp2.multiply(F[1], Px), Fp2.multiply(F[2], Py));
|
||||
f12 = Fp12.multiplyBy014(f12, F[0], Fp2.mul(F[1], Px), Fp2.mul(F[2], Py));
|
||||
}
|
||||
if (i !== 0) f12 = Fp12.square(f12);
|
||||
}
|
||||
@ -325,7 +325,7 @@ export function bls<Fp2, Fp6, Fp12>(
|
||||
// and do one exp after multiplying 2 points.
|
||||
const ePHm = pairing(P.negate(), Hm, false);
|
||||
const eGS = pairing(G, S, false);
|
||||
const exp = Fp12.finalExponentiate(Fp12.multiply(eGS, ePHm));
|
||||
const exp = Fp12.finalExponentiate(Fp12.mul(eGS, ePHm));
|
||||
return Fp12.equals(exp, Fp12.ONE);
|
||||
}
|
||||
|
||||
@ -385,7 +385,7 @@ export function bls<Fp2, Fp6, Fp12>(
|
||||
paired.push(pairing(groupPublicKey, message, false));
|
||||
}
|
||||
paired.push(pairing(G1.Point.BASE.negate(), sig, false));
|
||||
const product = paired.reduce((a, b) => Fp12.multiply(a, b), Fp12.ONE);
|
||||
const product = paired.reduce((a, b) => Fp12.mul(a, b), Fp12.ONE);
|
||||
const exp = Fp12.finalExponentiate(product);
|
||||
return Fp12.equals(exp, Fp12.ONE);
|
||||
} catch {
|
||||
|
@ -280,7 +280,6 @@ export function twistedEdwards(curveDef: CurveType): CurveFn {
|
||||
const C = modP(T1 * d * T2); // C = T1*d*T2
|
||||
const D = modP(Z1 * Z2); // D = Z1*Z2
|
||||
const E = modP((X1 + Y1) * (X2 + Y2) - A - B); // E = (X1+Y1)*(X2+Y2)-A-B
|
||||
// TODO: do we need to check for same point here? Looks like working without it
|
||||
const F = D - C; // F = D-C
|
||||
const G = D + C; // G = D+C
|
||||
const H = modP(B - a * A); // H = B-a*A
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
// Default group related functions
|
||||
// Abelian group utilities
|
||||
const _0n = BigInt(0);
|
||||
const _1n = BigInt(1);
|
||||
|
||||
@ -67,8 +67,9 @@ export function wNAF<T extends Group<T>>(c: GroupConstructor<T>, bits: number) {
|
||||
|
||||
/**
|
||||
* Implements w-ary non-adjacent form for calculating ec multiplication.
|
||||
* @param n
|
||||
* @param W window size
|
||||
* @param affinePoint optional 2d point to save cached precompute windows on it.
|
||||
* @param n bits
|
||||
* @returns real and fake (for const-time) points
|
||||
*/
|
||||
wNAF(W: number, precomputes: T[], n: bigint): { p: T; f: T } {
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
import * as utils from './utils.js';
|
||||
// Utilities for modular arithmetics
|
||||
// Utilities for modular arithmetics and finite fields
|
||||
const _0n = BigInt(0);
|
||||
const _1n = BigInt(1);
|
||||
const _2n = BigInt(2);
|
||||
@ -161,14 +161,14 @@ export interface Field<T> {
|
||||
// 2-args
|
||||
equals(lhs: T, rhs: T): boolean;
|
||||
add(lhs: T, rhs: T): T;
|
||||
subtract(lhs: T, rhs: T): T;
|
||||
multiply(lhs: T, rhs: T | bigint): T;
|
||||
sub(lhs: T, rhs: T): T;
|
||||
mul(lhs: T, rhs: T | bigint): T;
|
||||
pow(lhs: T, power: bigint): T;
|
||||
div(lhs: T, rhs: T | bigint): T;
|
||||
// N for NonNormalized (for now)
|
||||
addN(lhs: T, rhs: T): T;
|
||||
subtractN(lhs: T, rhs: T): T;
|
||||
multiplyN(lhs: T, rhs: T | bigint): T;
|
||||
subN(lhs: T, rhs: T): T;
|
||||
mulN(lhs: T, rhs: T | bigint): T;
|
||||
squareN(num: T): T;
|
||||
|
||||
// Optional
|
||||
@ -182,8 +182,8 @@ export interface Field<T> {
|
||||
// prettier-ignore
|
||||
const FIELD_FIELDS = [
|
||||
'create', 'isValid', 'isZero', 'negate', 'invert', 'sqrt', 'square',
|
||||
'equals', 'add', 'subtract', 'multiply', 'pow', 'div',
|
||||
'addN', 'subtractN', 'multiplyN', 'squareN'
|
||||
'equals', 'add', 'sub', 'mul', 'pow', 'div',
|
||||
'addN', 'subN', 'mulN', 'squareN'
|
||||
] as const;
|
||||
export function validateField<T>(field: Field<T>) {
|
||||
for (const i of ['ORDER', 'MASK'] as const) {
|
||||
@ -210,7 +210,7 @@ export function FpPow<T>(f: Field<T>, num: T, power: bigint): T {
|
||||
let p = f.ONE;
|
||||
let d = num;
|
||||
while (power > _0n) {
|
||||
if (power & _1n) p = f.multiply(p, d);
|
||||
if (power & _1n) p = f.mul(p, d);
|
||||
d = f.square(d);
|
||||
power >>= 1n;
|
||||
}
|
||||
@ -223,21 +223,21 @@ export function FpInvertBatch<T>(f: Field<T>, nums: T[]): T[] {
|
||||
const lastMultiplied = nums.reduce((acc, num, i) => {
|
||||
if (f.isZero(num)) return acc;
|
||||
tmp[i] = acc;
|
||||
return f.multiply(acc, num);
|
||||
return f.mul(acc, num);
|
||||
}, f.ONE);
|
||||
// Invert last element
|
||||
const inverted = f.invert(lastMultiplied);
|
||||
// Walk from last to first, multiply them by inverted each other MOD p
|
||||
nums.reduceRight((acc, num, i) => {
|
||||
if (f.isZero(num)) return acc;
|
||||
tmp[i] = f.multiply(acc, tmp[i]);
|
||||
return f.multiply(acc, num);
|
||||
tmp[i] = f.mul(acc, tmp[i]);
|
||||
return f.mul(acc, num);
|
||||
}, inverted);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
export function FpDiv<T>(f: Field<T>, lhs: T, rhs: T | bigint): T {
|
||||
return f.multiply(lhs, typeof rhs === 'bigint' ? invert(rhs, f.ORDER) : f.invert(rhs));
|
||||
return f.mul(lhs, typeof rhs === 'bigint' ? invert(rhs, f.ORDER) : f.invert(rhs));
|
||||
}
|
||||
|
||||
// NOTE: very fragile, always bench. Major performance points:
|
||||
@ -274,16 +274,16 @@ export function Fp(
|
||||
|
||||
square: (num) => mod(num * num, ORDER),
|
||||
add: (lhs, rhs) => mod(lhs + rhs, ORDER),
|
||||
subtract: (lhs, rhs) => mod(lhs - rhs, ORDER),
|
||||
multiply: (lhs, rhs) => mod(lhs * rhs, ORDER),
|
||||
sub: (lhs, rhs) => mod(lhs - rhs, ORDER),
|
||||
mul: (lhs, rhs) => mod(lhs * rhs, ORDER),
|
||||
pow: (num, power) => FpPow(f, num, power),
|
||||
div: (lhs, rhs) => mod(lhs * invert(rhs, ORDER), ORDER),
|
||||
|
||||
// Same as above, but doesn't normalize
|
||||
squareN: (num) => num * num,
|
||||
addN: (lhs, rhs) => lhs + rhs,
|
||||
subtractN: (lhs, rhs) => lhs - rhs,
|
||||
multiplyN: (lhs, rhs) => lhs * rhs,
|
||||
subN: (lhs, rhs) => lhs - rhs,
|
||||
mulN: (lhs, rhs) => lhs * rhs,
|
||||
|
||||
invert: (num) => invert(num, ORDER),
|
||||
sqrt: redef.sqrt || sqrtP,
|
||||
|
@ -230,8 +230,8 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>) {
|
||||
function weierstrassEquation(x: T): T {
|
||||
const { a, b } = CURVE;
|
||||
const x2 = Fp.square(x); // x * x
|
||||
const x3 = Fp.multiply(x2, x); // x2 * x
|
||||
return Fp.add(Fp.add(x3, Fp.multiply(x, a)), b); // x3 + a * x + b
|
||||
const x3 = Fp.mul(x2, x); // x2 * x
|
||||
return Fp.add(Fp.add(x3, Fp.mul(x, a)), b); // x3 + a * x + b
|
||||
}
|
||||
|
||||
function isWithinCurveOrder(num: bigint): boolean {
|
||||
@ -305,11 +305,11 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>) {
|
||||
* Compare one point to another.
|
||||
*/
|
||||
equals(other: ProjectivePoint): boolean {
|
||||
if (!(other instanceof ProjectivePoint)) throw new TypeError('ProjectivePoint expected');
|
||||
assertPrjPoint(other);
|
||||
const { x: X1, y: Y1, z: Z1 } = this;
|
||||
const { x: X2, y: Y2, z: Z2 } = other;
|
||||
const U1 = Fp.equals(Fp.multiply(X1, Z2), Fp.multiply(X2, Z1));
|
||||
const U2 = Fp.equals(Fp.multiply(Y1, Z2), Fp.multiply(Y2, Z1));
|
||||
const U1 = Fp.equals(Fp.mul(X1, Z2), Fp.mul(X2, Z1));
|
||||
const U2 = Fp.equals(Fp.mul(Y1, Z2), Fp.mul(Y2, Z1));
|
||||
return U1 && U2;
|
||||
}
|
||||
|
||||
@ -330,38 +330,38 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>) {
|
||||
// Cost: 8M + 3S + 3*a + 2*b3 + 15add.
|
||||
double() {
|
||||
const { a, b } = CURVE;
|
||||
const b3 = Fp.multiply(b, 3n);
|
||||
const b3 = Fp.mul(b, 3n);
|
||||
const { x: X1, y: Y1, z: Z1 } = this;
|
||||
let X3 = Fp.ZERO, Y3 = Fp.ZERO, Z3 = Fp.ZERO; // prettier-ignore
|
||||
let t0 = Fp.multiply(X1, X1); // step 1
|
||||
let t1 = Fp.multiply(Y1, Y1);
|
||||
let t2 = Fp.multiply(Z1, Z1);
|
||||
let t3 = Fp.multiply(X1, Y1);
|
||||
let t0 = Fp.mul(X1, X1); // step 1
|
||||
let t1 = Fp.mul(Y1, Y1);
|
||||
let t2 = Fp.mul(Z1, Z1);
|
||||
let t3 = Fp.mul(X1, Y1);
|
||||
t3 = Fp.add(t3, t3); // step 5
|
||||
Z3 = Fp.multiply(X1, Z1);
|
||||
Z3 = Fp.mul(X1, Z1);
|
||||
Z3 = Fp.add(Z3, Z3);
|
||||
X3 = Fp.multiply(a, Z3);
|
||||
Y3 = Fp.multiply(b3, t2);
|
||||
X3 = Fp.mul(a, Z3);
|
||||
Y3 = Fp.mul(b3, t2);
|
||||
Y3 = Fp.add(X3, Y3); // step 10
|
||||
X3 = Fp.subtract(t1, Y3);
|
||||
X3 = Fp.sub(t1, Y3);
|
||||
Y3 = Fp.add(t1, Y3);
|
||||
Y3 = Fp.multiply(X3, Y3);
|
||||
X3 = Fp.multiply(t3, X3);
|
||||
Z3 = Fp.multiply(b3, Z3); // step 15
|
||||
t2 = Fp.multiply(a, t2);
|
||||
t3 = Fp.subtract(t0, t2);
|
||||
t3 = Fp.multiply(a, t3);
|
||||
Y3 = Fp.mul(X3, Y3);
|
||||
X3 = Fp.mul(t3, X3);
|
||||
Z3 = Fp.mul(b3, Z3); // step 15
|
||||
t2 = Fp.mul(a, t2);
|
||||
t3 = Fp.sub(t0, t2);
|
||||
t3 = Fp.mul(a, t3);
|
||||
t3 = Fp.add(t3, Z3);
|
||||
Z3 = Fp.add(t0, t0); // step 20
|
||||
t0 = Fp.add(Z3, t0);
|
||||
t0 = Fp.add(t0, t2);
|
||||
t0 = Fp.multiply(t0, t3);
|
||||
t0 = Fp.mul(t0, t3);
|
||||
Y3 = Fp.add(Y3, t0);
|
||||
t2 = Fp.multiply(Y1, Z1); // step 25
|
||||
t2 = Fp.mul(Y1, Z1); // step 25
|
||||
t2 = Fp.add(t2, t2);
|
||||
t0 = Fp.multiply(t2, t3);
|
||||
X3 = Fp.subtract(X3, t0);
|
||||
Z3 = Fp.multiply(t2, t1);
|
||||
t0 = Fp.mul(t2, t3);
|
||||
X3 = Fp.sub(X3, t0);
|
||||
Z3 = Fp.mul(t2, t1);
|
||||
Z3 = Fp.add(Z3, Z3); // step 30
|
||||
Z3 = Fp.add(Z3, Z3);
|
||||
return new ProjectivePoint(X3, Y3, Z3);
|
||||
@ -372,51 +372,51 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>) {
|
||||
// https://eprint.iacr.org/2015/1060, algorithm 1
|
||||
// Cost: 12M + 0S + 3*a + 3*b3 + 23add.
|
||||
add(other: ProjectivePoint): ProjectivePoint {
|
||||
if (!(other instanceof ProjectivePoint)) throw new TypeError('ProjectivePoint expected');
|
||||
assertPrjPoint(other);
|
||||
const { x: X1, y: Y1, z: Z1 } = this;
|
||||
const { x: X2, y: Y2, z: Z2 } = other;
|
||||
let X3 = Fp.ZERO, Y3 = Fp.ZERO, Z3 = Fp.ZERO; // prettier-ignore
|
||||
const a = CURVE.a;
|
||||
const b3 = Fp.multiply(CURVE.b, 3n);
|
||||
let t0 = Fp.multiply(X1, X2); // step 1
|
||||
let t1 = Fp.multiply(Y1, Y2);
|
||||
let t2 = Fp.multiply(Z1, Z2);
|
||||
const b3 = Fp.mul(CURVE.b, 3n);
|
||||
let t0 = Fp.mul(X1, X2); // step 1
|
||||
let t1 = Fp.mul(Y1, Y2);
|
||||
let t2 = Fp.mul(Z1, Z2);
|
||||
let t3 = Fp.add(X1, Y1);
|
||||
let t4 = Fp.add(X2, Y2); // step 5
|
||||
t3 = Fp.multiply(t3, t4);
|
||||
t3 = Fp.mul(t3, t4);
|
||||
t4 = Fp.add(t0, t1);
|
||||
t3 = Fp.subtract(t3, t4);
|
||||
t3 = Fp.sub(t3, t4);
|
||||
t4 = Fp.add(X1, Z1);
|
||||
let t5 = Fp.add(X2, Z2); // step 10
|
||||
t4 = Fp.multiply(t4, t5);
|
||||
t4 = Fp.mul(t4, t5);
|
||||
t5 = Fp.add(t0, t2);
|
||||
t4 = Fp.subtract(t4, t5);
|
||||
t4 = Fp.sub(t4, t5);
|
||||
t5 = Fp.add(Y1, Z1);
|
||||
X3 = Fp.add(Y2, Z2); // step 15
|
||||
t5 = Fp.multiply(t5, X3);
|
||||
t5 = Fp.mul(t5, X3);
|
||||
X3 = Fp.add(t1, t2);
|
||||
t5 = Fp.subtract(t5, X3);
|
||||
Z3 = Fp.multiply(a, t4);
|
||||
X3 = Fp.multiply(b3, t2); // step 20
|
||||
t5 = Fp.sub(t5, X3);
|
||||
Z3 = Fp.mul(a, t4);
|
||||
X3 = Fp.mul(b3, t2); // step 20
|
||||
Z3 = Fp.add(X3, Z3);
|
||||
X3 = Fp.subtract(t1, Z3);
|
||||
X3 = Fp.sub(t1, Z3);
|
||||
Z3 = Fp.add(t1, Z3);
|
||||
Y3 = Fp.multiply(X3, Z3);
|
||||
Y3 = Fp.mul(X3, Z3);
|
||||
t1 = Fp.add(t0, t0); // step 25
|
||||
t1 = Fp.add(t1, t0);
|
||||
t2 = Fp.multiply(a, t2);
|
||||
t4 = Fp.multiply(b3, t4);
|
||||
t2 = Fp.mul(a, t2);
|
||||
t4 = Fp.mul(b3, t4);
|
||||
t1 = Fp.add(t1, t2);
|
||||
t2 = Fp.subtract(t0, t2); // step 30
|
||||
t2 = Fp.multiply(a, t2);
|
||||
t2 = Fp.sub(t0, t2); // step 30
|
||||
t2 = Fp.mul(a, t2);
|
||||
t4 = Fp.add(t4, t2);
|
||||
t0 = Fp.multiply(t1, t4);
|
||||
t0 = Fp.mul(t1, t4);
|
||||
Y3 = Fp.add(Y3, t0);
|
||||
t0 = Fp.multiply(t5, t4); // step 35
|
||||
X3 = Fp.multiply(t3, X3);
|
||||
X3 = Fp.subtract(X3, t0);
|
||||
t0 = Fp.multiply(t3, t1);
|
||||
Z3 = Fp.multiply(t5, Z3);
|
||||
t0 = Fp.mul(t5, t4); // step 35
|
||||
X3 = Fp.mul(t3, X3);
|
||||
X3 = Fp.sub(X3, t0);
|
||||
t0 = Fp.mul(t3, t1);
|
||||
Z3 = Fp.mul(t5, Z3);
|
||||
Z3 = Fp.add(Z3, t0); // step 40
|
||||
return new ProjectivePoint(X3, Y3, Z3);
|
||||
}
|
||||
@ -453,7 +453,7 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>) {
|
||||
}
|
||||
if (k1neg) k1p = k1p.negate();
|
||||
if (k2neg) k2p = k2p.negate();
|
||||
k2p = new ProjectivePoint(Fp.multiply(k2p.x, CURVE.endo.beta), k2p.y, k2p.z);
|
||||
k2p = new ProjectivePoint(Fp.mul(k2p.x, CURVE.endo.beta), k2p.y, k2p.z);
|
||||
return k1p.add(k2p);
|
||||
}
|
||||
|
||||
@ -496,7 +496,7 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>) {
|
||||
let { p: k2p, f: f2p } = this.wNAF(k2, affinePoint);
|
||||
k1p = wnaf.constTimeNegate(k1neg, k1p);
|
||||
k2p = wnaf.constTimeNegate(k2neg, k2p);
|
||||
k2p = new ProjectivePoint(Fp.multiply(k2p.x, CURVE.endo.beta), k2p.y, k2p.z);
|
||||
k2p = new ProjectivePoint(Fp.mul(k2p.x, CURVE.endo.beta), k2p.y, k2p.z);
|
||||
point = k1p.add(k2p);
|
||||
fake = f1p.add(f2p);
|
||||
} else {
|
||||
@ -517,9 +517,9 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>) {
|
||||
// If invZ was 0, we return zero point. However we still want to execute
|
||||
// all operations, so we replace invZ with a random number, 1.
|
||||
if (invZ == null) invZ = is0 ? Fp.ONE : Fp.invert(z);
|
||||
const ax = Fp.multiply(x, invZ);
|
||||
const ay = Fp.multiply(y, invZ);
|
||||
const zz = Fp.multiply(z, invZ);
|
||||
const ax = Fp.mul(x, invZ);
|
||||
const ay = Fp.mul(y, invZ);
|
||||
const zz = Fp.mul(z, invZ);
|
||||
if (is0) return Point.ZERO;
|
||||
if (!Fp.equals(zz, Fp.ONE)) throw new Error('invZ was invalid');
|
||||
return new Point(ax, ay);
|
||||
@ -539,6 +539,10 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>) {
|
||||
}
|
||||
}
|
||||
const wnaf = wNAF(ProjectivePoint, CURVE.endo ? nBitLength / 2 : nBitLength);
|
||||
|
||||
function assertPrjPoint(other: unknown) {
|
||||
if (!(other instanceof ProjectivePoint)) throw new TypeError('ProjectivePoint expected');
|
||||
}
|
||||
// Stores precomputed values for points.
|
||||
const pointPrecomputes = new WeakMap<Point, ProjectivePoint[]>();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user