Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Secp256r1 #310

Merged
merged 6 commits into from
Oct 30, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 16 additions & 12 deletions crypto/elliptic-curve-endomorphism.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
GroupProjective,
affineScale,
projectiveAdd,
projectiveDouble,
getProjectiveDouble,
projectiveFromAffine,
projectiveNeg,
projectiveToAffine,
Expand All @@ -25,10 +25,10 @@ export {
* Define methods leveraging a curve endomorphism
*/
function Endomorphism(
name: string,
Field: FiniteField,
Scalar: FiniteField,
generator: GroupAffine,
a: bigint,
endoScalar?: bigint,
endoBase?: bigint
) {
Expand All @@ -37,10 +37,10 @@ function Endomorphism(
({ endoScalar, endoBase } = computeEndoConstants(
Field,
Scalar,
generator
generator,
a
));
} catch (e: any) {
console.log(`Warning: no endomorphism for ${name}`, e?.message);
return undefined;
}
}
Expand All @@ -62,14 +62,15 @@ function Endomorphism(
},

scaleProjective(g: GroupProjective, s: bigint) {
return glvScaleProjective(g, s, Field.modulus, endoBase_, glvData);
return glvScaleProjective(g, s, Field.modulus, a, endoBase_, glvData);
},
scale(g: GroupAffine, s: bigint) {
let gProj = projectiveFromAffine(g);
let sGProj = glvScaleProjective(
gProj,
s,
Field.modulus,
a,
endoBase_,
glvData
);
Expand Down Expand Up @@ -154,10 +155,12 @@ function glvScaleProjective(
g: GroupProjective,
s: bigint,
p: bigint,
a: bigint,
endoBase: bigint,
data: GlvData
) {
let endoG = endomorphismProjective(g, endoBase, p);
let double = getProjectiveDouble(p, a);

let [s0, s1] = decompose(s, data);
let S0 = bigIntToBits(s0.abs);
Expand All @@ -168,10 +171,10 @@ function glvScaleProjective(
let h = projectiveZero;

for (let i = data.maxBits - 1; i >= 0; i--) {
if (S0[i]) h = projectiveAdd(h, g, p);
if (S1[i]) h = projectiveAdd(h, endoG, p);
if (S0[i]) h = projectiveAdd(h, g, p, a);
if (S1[i]) h = projectiveAdd(h, endoG, p, a);
if (i === 0) break;
h = projectiveDouble(h, p);
h = double(h, p);
}

return h;
Expand All @@ -185,7 +188,8 @@ function glvScaleProjective(
function computeEndoConstants(
Field: FiniteField,
Scalar: FiniteField,
G: GroupAffine
G: GroupAffine,
a: bigint
) {
let p = Field.modulus;
let q = Scalar.modulus;
Expand All @@ -207,7 +211,7 @@ function computeEndoConstants(
assert(lambda !== 1n, 'lambda is not 1');

// compute beta such that lambda * (x, y) = (beta * x, y) (endo base)
let lambdaG = affineScale(G, lambda, p);
let lambdaG = affineScale(G, lambda, p, a);
assert(lambdaG.y === G.y, 'multiplication by lambda is a cheap endomorphism');

let beta = Field.div(lambdaG.x, G.x);
Expand All @@ -217,8 +221,8 @@ function computeEndoConstants(

// confirm endomorphism at random point
// TODO would be nice to have some theory instead of this heuristic
let R = affineScale(G, Scalar.random(), p);
let lambdaR = affineScale(R, lambda, p);
let R = affineScale(G, Scalar.random(), p, a);
let lambdaR = affineScale(R, lambda, p, a);
assert(lambdaR.x === Field.mul(beta, R.x), 'confirm endomorphism');
assert(lambdaR.y === R.y, 'confirm endomorphism');

Expand Down
13 changes: 13 additions & 0 deletions crypto/elliptic-curve-examples.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,18 @@ const secp256k1Params: CurveParams = {
},
};

const secp256r1Params: CurveParams = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍🏻

name: 'secp256r1',
modulus: exampleFields.secp256r1.modulus,
order: 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551n,
a: 0xffffffff00000001000000000000000000000000fffffffffffffffffffffffcn,
b: 0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604bn,
generator: {
x: 0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296n,
y: 0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5n,
},
};

const pallasParams: CurveParams = {
name: 'Pallas',
modulus: Pallas.modulus,
Expand All @@ -39,6 +51,7 @@ const vestaParams: CurveParams = {

const CurveParams = {
Secp256k1: secp256k1Params,
Secp256r1: secp256r1Params,
Pallas: pallasParams,
Vesta: vestaParams,
};
Loading
Loading