Skip to content

Add secp384r1 (NIST P-384) curve support#59

Merged
maurges merged 5 commits intoLFDT-Lockness:mfrom
sridhar-panigrahi:feat/add-secp384r1-support
Mar 20, 2026
Merged

Add secp384r1 (NIST P-384) curve support#59
maurges merged 5 commits intoLFDT-Lockness:mfrom
sridhar-panigrahi:feat/add-secp384r1-support

Conversation

@sridhar-panigrahi
Copy link
Copy Markdown
Contributor

Summary

Hey! Following up on the discussion in #lockness-contribute and the plan laid out in #58 — this PR adds secp384r1 (NIST P-384) as the first curve with a larger scalar size (48 bytes / 384 bits) to the library.

The goal here was to actually plug in a bigger curve, run the full test suite against it, and see what breaks. The good news is: nothing broke. The existing scalar pipeline and the Straus NAF fix from #57 handle the 48-byte scalars cleanly.

What's in here

  • p384 crate wired in — new secp384r1 feature flag through both generic-ec-curves and generic-ec, following the same RustCrypto pattern as the existing curves
  • Scalar traits implementedCurveName, FromUniformBytes (L=64 bytes per RFC 9380), BytesModOrder, Reduce<48> via U384, and NoInvalidPoints
  • New reduction utilitiesscalar_from_{be,le}_bytes_mod_order_reducing_48 for Horner-method mod-order reduction using 48-byte chunks (same pattern as the _reducing_32 variants)
  • Every test instantiated for secp384r1 — scalar ops, point ops, serde round-trips, Straus multiscalar multiplication, affine coordinates, dlog_eq ZK proofs, Reduce<48>, and from_bytes_mod_order with various input sizes
  • Benchmarks added for the new curve

Test results

All 180 tests pass, including all the new secp384r1 ones. Clippy is clean too. No hardcoded scalar-size assumptions surfaced beyond the one already fixed in #57.

What's next (per the plan in #58)

  • Look at adding more curves with different scalar sizes (curve448, P-521) to stress-test further
  • Update cggmp24 and givre to use these curves and make sure their tests pass
  • Do a careful review for any remaining scalar-size assumptions that the test suite might not cover

Happy to adjust anything based on your feedback!

Relates to #58
Depends on #57

Test plan

  • cargo test --all-features — 180/180 tests pass
  • cargo clippy --all-features — no warnings
  • Scalar byte round-trips (BE/LE) work for 48-byte scalars
  • from_bytes_mod_order works with various input lengths (8, 16, 32, 48, 64, 80, 96, 128, 256, 512 bytes and random lengths)
  • Straus multiscalar multiplication works with 384-bit NAFs
  • Serde serialization/deserialization round-trips
  • Affine coordinate access (x, y, parity) works
  • dlog_eq zero-knowledge proofs pass (both interactive and non-interactive)

@socket-security
Copy link
Copy Markdown

socket-security bot commented Mar 12, 2026

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedp384@​0.13.110010093100100

View full report

@sridhar-panigrahi
Copy link
Copy Markdown
Contributor Author

@survived , let me know your thoughts on this !

Copy link
Copy Markdown
Contributor

@survived survived left a comment

Choose a reason for hiding this comment

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

Hi @sridhar-panigrahi, the PR looks good on my end. There's one unnecessary change I found, but rather than that it's good!

Could you do GPG-signing on your commits? We can't merge unsigned commits unfortunately (it's mentioned in CONTRIBUTING.md).

In meantime, I'll update cggmp to use this curve and see if all works and it's able to generate valid P-384 ECDSA signatures.

@sridhar-panigrahi sridhar-panigrahi force-pushed the feat/add-secp384r1-support branch from d257a78 to bcc44ee Compare March 16, 2026 18:51
The `add_scalar` method in `NafMatrix` hardcodes `x_u64[0..4]` when
reading scalar bytes, which only works for 32-byte scalars. This panics
for curves with different scalar sizes like P-384 or P-521.

Use the actual scalar byte length instead.

Signed-off-by: Shridhar Panigrahi <sridharpanigrahi2006@gmail.com>
The `doc_auto_cfg` feature was merged into `doc_cfg` in Rust 1.92.0
(see rust-lang/rust#138907), causing nightly rustdoc builds to fail
with E0557. Remove it from the feature list.

Signed-off-by: Shridhar Panigrahi <sridharpanigrahi2006@gmail.com>
This is the first curve with a larger scalar size (48 bytes instead of
32) to be added to the library. It exercises the full scalar pipeline
with a non-256-bit field and validates that no hardcoded scalar-size
assumptions remain.

What's included:
- p384 crate dependency and `secp384r1` feature flag wired through
  generic-ec-curves and generic-ec
- CurveName, FromUniformBytes (L=64 per RFC 9380), BytesModOrder,
  Reduce<48>, and NoInvalidPoints implementations
- New scalar_from_{be,le}_bytes_mod_order_reducing_48 utility functions
  for Horner-method reduction using 48-byte chunks
- All existing tests instantiated for Secp384r1: scalar ops, point ops,
  serde, multiscalar (Straus), coordinates, dlog_eq ZKPs, Reduce<48>
- Benchmarks updated for the new curve

All 180 tests pass. Zero breakage — the dynamic scalar-size handling
(including the Straus NAF fix from LFDT-Lockness#57) generalizes cleanly to 384-bit
scalars.

Relates to LFDT-Lockness#58

Signed-off-by: Shridhar Panigrahi <sridharpanigrahi2006@gmail.com>
@sridhar-panigrahi sridhar-panigrahi force-pushed the feat/add-secp384r1-support branch from bcc44ee to c0011e2 Compare March 16, 2026 18:53
@sridhar-panigrahi
Copy link
Copy Markdown
Contributor Author

Hi @survived and @maurges, thanks for the feedback! I've gone ahead and addressed both of the review comments:

  • Removed secp384r1 from the Sha256 cfg import guard since P-384 uses sha2::Sha384 instead (thanks for catching that @survived!)
  • Unified the duplicated _32 and _48 helpers into a single generic scalar_from_{le,be}_bytes_mod_order_reducing<S, const N: usize> to avoid the code duplication (great suggestion @maurges!)

All commits are GPG-signed as well. Let me know if there's anything else you'd like me to change!

@maurges
Copy link
Copy Markdown
Contributor

maurges commented Mar 17, 2026

Thanks for the change. It seems you haven't signed off on the latest commit, that's why the CI is failing now

- Remove `secp384r1` from the `Sha256` cfg import guard; P-384 uses
  `sha2::Sha384`, not `Sha256` (reported by survived)
- Replace the duplicated `scalar_from_{le,be}_bytes_mod_order_reducing_32`
  and `_48` helpers with a single pair generic over `const N: usize`,
  reducing code duplication (suggested by maurges)

Signed-off-by: Shridhar Panigrahi <sridharpanigrahi2006@gmail.com>
@sridhar-panigrahi sridhar-panigrahi force-pushed the feat/add-secp384r1-support branch from c0011e2 to 28fa09a Compare March 17, 2026 19:03
@sridhar-panigrahi
Copy link
Copy Markdown
Contributor Author

@maurges Added the DCO sign-off to the latest commit. CI checks are passing now.

@sridhar-panigrahi
Copy link
Copy Markdown
Contributor Author

@survived @maurges , please do let me know if you think there could be any changes
.

@maurges
Copy link
Copy Markdown
Contributor

maurges commented Mar 20, 2026

The code looks good, I resolved the remaining comments. The CI is still failing - it seems you updated the docs in lib.rs without updating the readme accordingly. Currently they need to manually be kept in sync, and you can test that on your machine by running cd generic-ec; cargo rdme -r ../README.md --check (the same command as in CI)

@survived
Copy link
Copy Markdown
Contributor

by running cd generic-ec; cargo rdme -r ../README.md --check (the same command as in CI)

We have make readme for that!

Signed-off-by: Shridhar Panigrahi <sridharpanigrahi2006@gmail.com>
@sridhar-panigrahi
Copy link
Copy Markdown
Contributor Author

@maurges @survived Thanks for the heads up! I've synced the README with
cargo rdme and pushed the fix. Good to know about make readme — I'll use
that going forward. CI is green now.

Copy link
Copy Markdown
Contributor

@survived survived left a comment

Choose a reason for hiding this comment

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

All looks good! I tested that cggmp can successfully yield a valid signature on secp384r1 curve in LFDT-Lockness/cggmp21#173

@sridhar-panigrahi
Copy link
Copy Markdown
Contributor Author

@survived Awesome, thanks for testing and approving! Great to hear the
P-384 ECDSA signatures work end-to-end with cggmp.

@maurges maurges merged commit b51cb69 into LFDT-Lockness:m Mar 20, 2026
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.

3 participants