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