Skip to content

Commit

Permalink
Merge pull request #310 from zksecurity/feature/secp256r1
Browse files Browse the repository at this point in the history
Support Secp256r1
  • Loading branch information
Trivo25 authored Oct 30, 2024
2 parents f811fc2 + e4cbf60 commit acc5a7c
Show file tree
Hide file tree
Showing 5 changed files with 221 additions and 70 deletions.
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 = {
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

0 comments on commit acc5a7c

Please sign in to comment.