Skip to content

Commit b4005bd

Browse files
committed
[WIP] primefield: generic MontyFieldElement type
The previous implementation was written entirely in terms of macros. Leveraging types from `crypto-bigint`, this provides a generic field element type with an internal Montgomery form representation.
1 parent 05a1ff0 commit b4005bd

File tree

7 files changed

+824
-5
lines changed

7 files changed

+824
-5
lines changed

Cargo.lock

Lines changed: 1 addition & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ members = [
2121
opt-level = 2
2222

2323
[patch.crates-io]
24+
crypto-bigint = { git = "https://github.com/RustCrypto/crypto-bigint" }
2425
elliptic-curve = { git = "https://github.com/RustCrypto/traits.git" }
26+
2527
hash2curve = { path = "hash2curve" }
2628
primefield = { path = "primefield" }
2729
primeorder = { path = "primeorder" }

p256/src/arithmetic/field.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use core::ops::Mul;
1111
use elliptic_curve::{
1212
FieldBytesEncoding,
1313
bigint::U256,
14+
//consts::U32,
1415
ff::PrimeField,
1516
subtle::{Choice, ConstantTimeEq, CtOption},
1617
};
@@ -26,6 +27,20 @@ const R2: FieldElement = FieldElement(U256::from_be_hex(
2627
"00000004fffffffdfffffffffffffffefffffffbffffffff0000000000000003",
2728
));
2829

30+
// primefield::monty_field_params!(
31+
// MontyFieldParams,
32+
// MODULUS_HEX,
33+
// U256,
34+
// U32,
35+
// primefield::ByteOrder::BigEndian,
36+
// "P-256 field modulus",
37+
// "FieldElement"
38+
// );
39+
//
40+
// /// An element in the finite field modulo p = 2^{224}(2^{32} − 1) + 2^{192} + 2^{96} − 1.
41+
// #[allow(dead_code)]
42+
// pub type MontyFieldElement = primefield::MontyFieldElement<MontyFieldParams, { U256::LIMBS }>;
43+
2944
/// An element in the finite field modulo p = 2^{224}(2^{32} − 1) + 2^{192} + 2^{96} − 1.
3045
///
3146
/// The internal representation is in little-endian order. Elements are always in

p256/src/arithmetic/scalar.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use core::{
1414
use elliptic_curve::{
1515
Curve,
1616
bigint::{Limb, U256, prelude::*},
17+
//consts::U32,
1718
group::ff::{self, Field, PrimeField},
1819
ops::{Invert, Reduce, ReduceNonZero},
1920
rand_core::TryRngCore,
@@ -41,6 +42,20 @@ pub(crate) const MODULUS: U256 = NistP256::ORDER;
4142
/// `MODULUS / 2`
4243
const FRAC_MODULUS_2: Scalar = Scalar(MODULUS.shr_vartime(1));
4344

45+
// primefield::monty_field_params!(
46+
// MontyScalarParams,
47+
// ORDER_HEX,
48+
// U256,
49+
// U32,
50+
// primefield::ByteOrder::BigEndian,
51+
// "P-256 scalar modulus",
52+
// "Scalar"
53+
// );
54+
//
55+
// /// Scalars are elements in the finite field modulo n.
56+
// #[allow(dead_code)]
57+
// pub type MontyScalar = primefield::MontyFieldElement<MontyScalarParams, { U256::LIMBS }>;
58+
4459
/// Scalars are elements in the finite field modulo n.
4560
///
4661
/// # Trait impls

primefield/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ edition = "2024"
1414
rust-version = "1.85"
1515

1616
[dependencies]
17-
bigint = { package = "crypto-bigint", version = "=0.7.0-pre.7", default-features = false }
17+
bigint = { package = "crypto-bigint", version = "=0.7.0-pre.7", default-features = false, features = ["hybrid-array"] }
1818
ff = { version = "=0.14.0-pre.0", default-features = false }
1919
subtle = { version = "2.6", default-features = false }
2020
rand_core = { version = "0.9", default-features = false }

primefield/src/lib.rs

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

11+
pub use array::typenum::consts;
1112
pub use bigint;
13+
pub use bigint::hybrid_array as array;
1214
pub use ff;
1315
pub use rand_core;
1416
pub use subtle;
1517
pub use zeroize;
1618

19+
pub use crate::monty::{MontyFieldElement, MontyFieldParams};
20+
1721
mod fiat;
22+
mod monty;
23+
24+
/// Byte order used when encoding/decoding field elements as bytestrings.
25+
#[derive(Debug)]
26+
pub enum ByteOrder {
27+
/// Big endian.
28+
BigEndian,
29+
30+
/// Little endian.
31+
LittleEndian,
32+
}
1833

1934
/// Implements a field element type whose internal representation is in
2035
/// Montgomery form, providing a combination of trait impls and inherent impls
@@ -220,12 +235,10 @@ macro_rules! field_element_type {
220235
Self::ZERO.ct_eq(self)
221236
}
222237

223-
#[must_use]
224238
fn square(&self) -> Self {
225239
self.square()
226240
}
227241

228-
#[must_use]
229242
fn double(&self) -> Self {
230243
self.double()
231244
}

0 commit comments

Comments
 (0)