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 #1885

Merged
merged 9 commits into from
Oct 30, 2024
Merged

Support Secp256r1 #1885

merged 9 commits into from
Oct 30, 2024

Conversation

mitschabaude
Copy link
Contributor

@mitschabaude mitschabaude commented Oct 24, 2024

closes #1724

this adds ECDSA (and general) support for the curve secp256r1, also known as P-256, which is the standard curve used in ECDSA outside the crypto world, due to its recommendation by NIST; see P-256 in this document

Most changes are in o1-labs/o1js-bindings#310

changes here:

  • properly treat and pass on curve parameter a in EC addition and doubling methods
    • no circuit changes! the parameter was just missing in witness generation
  • add secp256r1 to the curve and ECDSA unit tests

Efficiency

Sadly, secp256r1 doesn't support the endomorphism we have implemented, because that endomorphism crucially relies on the a = 0 property. Therefore, in our ECDSA circuit the GLV method is not used, which means significant constraint savings get lost:

  • ECDSA on secp256k1: 32k constraints
  • ECDSA on secp256r1: 40k constraints

@mitschabaude
Copy link
Contributor Author

@Trivo25 can you get me the necessary reviewers for this?

Copy link
Member

@Geometer1729 Geometer1729 left a comment

Choose a reason for hiding this comment

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

LGTM

@mitschabaude
Copy link
Contributor Author

Thanks for the review @Geometer1729! I also need one here and then I need you to merge both PRs since I don't have permission to

@mitschabaude
Copy link
Contributor Author

Oh and @Trivo25 I also need admin review for changing the bindings commit

@Geometer1729
Copy link
Member

@mitschabaude Can you run npm run build:update-bindings and push the changes that creates in o1js-bindings? I think the bindings not having been recompiled may be why CI is failing.

@mitschabaude
Copy link
Contributor Author

@mitschabaude Can you run npm run build:update-bindings and push the changes that creates in o1js-bindings? I think the bindings not having been recompiled may be why CI is failing.

no @Geometer1729, I didn't change anything that needs compiling. also, CI isn't failing, just the benchmark job is, and that one always fails on forks

@mitschabaude
Copy link
Contributor Author

updating the bindings is just needed when you need to recompile ocaml or rust sources

@Geometer1729
Copy link
Member

Oh, I thought it was also affected by some of the content of o1js-bindings. Fair enough sorry about that.

});

console.time('ecdsa verify, no endomorphism (build constraint system)');
let csNoEndo = (await programNoEndo.analyzeMethods()).ecdsa;
Copy link
Contributor

Choose a reason for hiding this comment

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

Could we add some test vectors to verify this implementation?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes! I'll do that

@45930
Copy link
Contributor

45930 commented Oct 24, 2024

Amazing work! Florian has final approval, but it LGTM

@mitschabaude
Copy link
Contributor Author

the test is failing because we're still running node 18 in CI, where the web crypto API is missing 😬

do you mind if I change it to node 20?

@mitschabaude
Copy link
Contributor Author

need workflow approval again 😢 @Trivo25

@mitschabaude
Copy link
Contributor Author

and again @Trivo25!

@mitschabaude
Copy link
Contributor Author

mitschabaude commented Oct 25, 2024

@nicc @mrmr1993 that's why I need write access to the repo ^^ #1885 (comment) #1885 (comment)

@mitschabaude
Copy link
Contributor Author

mitschabaude commented Oct 25, 2024

CI is green, ready to approve & merge 🚀

EDIT: and the bindings PR!

@Trivo25
Copy link
Member

Trivo25 commented Oct 28, 2024

@hattyhattington17 can we get your eyes on this too?

@Trivo25
Copy link
Member

Trivo25 commented Oct 28, 2024

@mitschabaude fyi I will get this merged before the next release

@@ -129,7 +128,7 @@ function double(p1: Point, Curve: { modulus: bigint; a: bigint }) {
let [x1_, y1_] = Field3.toBigints(x1, y1);
let denom = inverse(mod(2n * y1_, f), f) ?? 0n;

let m = mod(3n * mod(x1_ ** 2n, f) * denom, f);
let m = mod((3n * mod(x1_ ** 2n, f) + Curve.a) * denom, f);
Copy link
Member

Choose a reason for hiding this comment

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

In PR310 this m is computed with a single modular operation, meaning: let m = mod((3n * x * x + a) * d, p);. Cannot we remove one mod from this line?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

good question! I think using mod() twice is better actually, because both x and d are large field elements. so x^2 is already a bigint of 2x the length, and it's more efficient to first reduce it (with mod()) back to 1x the length before doing another bigint multiplication with d. In the code you mention, we get an intermediate result of 2x * 1x = 3x the length

@Trivo25 Trivo25 merged commit e1bac02 into o1-labs:main Oct 30, 2024
24 of 26 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Any easy way to verify secp256r1 (NIST P256) ECDSA signature?
6 participants