Skip to content

Commit 4544805

Browse files
committed
p384: add cfg(p384_backend = "bignum")
Adds support for an experimental backend which uses `crypto-bigint` as the field element representation, as an off-by-default alternative to `fiat-crypto`. This uses the `monty_field_arithmetic!` macro introduced in #1547 which in turn builds on the `MontyFieldElement` type introduced in #1311, which builds on `crypto-bigint`'s `ConstMontyForm` type, which implements Montgomery form modular arithmetic.
1 parent e398536 commit 4544805

File tree

6 files changed

+61
-7
lines changed

6 files changed

+61
-7
lines changed

.github/workflows/p384.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@ jobs:
100100
- run: cargo test --release --target ${{ matrix.target }} --no-default-features
101101
- run: cargo test --release --target ${{ matrix.target }}
102102
- run: cargo test --release --target ${{ matrix.target }} --all-features
103+
- env:
104+
RUSTFLAGS: '--cfg p384_backend="bignum"'
105+
RUSTDOCFLAGS: '--cfg p384_backend="bignum"'
106+
run: cargo test --release --target ${{ matrix.target }} --all-features
103107

104108
cross:
105109
strategy:

p384/Cargo.toml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ rust-version = "1.85"
1919

2020
[dependencies]
2121
elliptic-curve = { version = "0.14.0-rc.17", default-features = false, features = ["sec1"] }
22-
fiat-crypto = { version = "0.3", default-features = false }
2322

2423
# optional dependencies
2524
ecdsa-core = { version = "0.17.0-rc.9", package = "ecdsa", optional = true, default-features = false, features = ["der"] }
@@ -30,6 +29,9 @@ primeorder = { version = "0.14.0-rc.1", optional = true }
3029
serdect = { version = "0.4", optional = true, default-features = false }
3130
sha2 = { version = "0.11.0-rc.3", optional = true, default-features = false }
3231

32+
[target.'cfg(not(p384_backend = "bignum"))'.dependencies]
33+
fiat-crypto = { version = "0.3", default-features = false }
34+
3335
[dev-dependencies]
3436
criterion = "0.7"
3537
ecdsa-core = { version = "0.17.0-rc.9", package = "ecdsa", default-features = false, features = ["dev"] }
@@ -75,3 +77,7 @@ required-features = ["expose-field"]
7577
[[bench]]
7678
name = "scalar"
7779
harness = false
80+
81+
[lints.rust.unexpected_cfgs]
82+
level = "warn"
83+
check-cfg = ['cfg(p384_backend, values("bignum", "fiat"))'] # default: "fiat"

p384/benches/field.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
//! secp384r1 field element benchmarks
22
3+
use core::hint::black_box;
34
use criterion::{
45
BenchmarkGroup, Criterion, criterion_group, criterion_main, measurement::Measurement,
56
};
67
use hex_literal::hex;
78
use p384::{FieldElement, elliptic_curve::ff::Field};
89

910
fn test_field_element_x() -> FieldElement {
10-
FieldElement::from_bytes(
11+
black_box(FieldElement::from_bytes(
1112
&hex!("c2b47944fb5de342d03285880177ca5f7d0f2fcad7678cce4229d6e1932fcac11bfc3c3e97d942a3c56bf34123013dbf").into()
1213
)
13-
.unwrap()
14+
.unwrap())
1415
}
1516

1617
fn test_field_element_y() -> FieldElement {

p384/src/arithmetic/field.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@
1010
//! Apache License (Version 2.0), and the BSD 1-Clause License;
1111
//! users may pick which license to apply.
1212
13-
#[cfg(target_pointer_width = "32")]
13+
// Default backend: fiat-crypto
14+
#[cfg(all(not(p384_backend = "bignum"), target_pointer_width = "32"))]
1415
use fiat_crypto::p384_32::*;
15-
#[cfg(target_pointer_width = "64")]
16+
#[cfg(all(not(p384_backend = "bignum"), target_pointer_width = "64"))]
1617
use fiat_crypto::p384_64::*;
1718

1819
use elliptic_curve::{
@@ -41,6 +42,14 @@ primefield::monty_field_element! {
4142
doc: "Element in the finite field modulo `p = 2^{384} − 2^{128} − 2^{96} + 2^{32} − 1`."
4243
}
4344

45+
#[cfg(p384_backend = "bignum")]
46+
primefield::monty_field_arithmetic! {
47+
name: FieldElement,
48+
params: FieldParams,
49+
uint: U384
50+
}
51+
52+
#[cfg(not(p384_backend = "bignum"))]
4453
primefield::monty_field_fiat_arithmetic! {
4554
name: FieldElement,
4655
params: FieldParams,

p384/src/arithmetic/scalar.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010
//! Apache License (Version 2.0), and the BSD 1-Clause License;
1111
//! users may pick which license to apply.
1212
13-
#[cfg(target_pointer_width = "32")]
13+
#[cfg(all(not(p384_backend = "bignum"), target_pointer_width = "32"))]
1414
use fiat_crypto::p384_scalar_32::*;
15-
#[cfg(target_pointer_width = "64")]
15+
#[cfg(all(not(p384_backend = "bignum"), target_pointer_width = "64"))]
1616
use fiat_crypto::p384_scalar_64::*;
1717

1818
use crate::{FieldBytes, NistP384, ORDER_HEX, U384};
@@ -50,6 +50,14 @@ primefield::monty_field_element! {
5050
doc: "Element in the NIST P-384 scalar field modulo `n`."
5151
}
5252

53+
#[cfg(p384_backend = "bignum")]
54+
primefield::monty_field_arithmetic! {
55+
name: Scalar,
56+
params: ScalarParams,
57+
uint: U384
58+
}
59+
60+
#[cfg(not(p384_backend = "bignum"))]
5361
primefield::monty_field_fiat_arithmetic! {
5462
name: Scalar,
5563
params: ScalarParams,

p384/src/lib.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,32 @@
88
#![warn(missing_docs, rust_2018_idioms, unused_qualifications)]
99
#![doc = include_str!("../README.md")]
1010

11+
//! ## Backends
12+
//!
13+
//! This crate has support for two different field arithmetic backends which can be selected using
14+
//! `cfg(p384_backend)`, e.g. to select the `bignum` backend:
15+
//!
16+
//! ```console
17+
//! $ RUSTFLAGS='--cfg p384_backend="bignum"' cargo test
18+
//! ```
19+
//!
20+
//! Or it can be set through [`.cargo/config`][buildrustflags]:
21+
//!
22+
//! ```toml
23+
//! [build]
24+
//! rustflags = ['--cfg', 'p384_backend="bignum"']
25+
//! ```
26+
//!
27+
//! The available backends are:
28+
//! - `bignum`: experimental backend provided by [crypto-bigint]. May offer better performance in
29+
//! some cases along with smaller code size, but might also have bugs.
30+
//! - `fiat` (default): formally verified implementation synthesized by [fiat-crypto] which should
31+
//! be correct for all inputs (though there's a possibility of bugs in the code which glues to it)
32+
//!
33+
//! [buildrustflags]: https://doc.rust-lang.org/cargo/reference/config.html#buildrustflags
34+
//! [crypto-bigint]: https://github.com/RustCrypto/crypto-bigint
35+
//! [fiat-crypto]: https://github.com/mit-plv/fiat-crypto
36+
//!
1137
//! ## `serde` support
1238
//!
1339
//! When the `serde` feature of this crate is enabled, `Serialize` and

0 commit comments

Comments
 (0)