diff --git a/Cargo.toml b/Cargo.toml index d2af3de..22db67a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ff" -version = "0.3.0" +version = "0.4.0" authors = ["Sean Bowe "] description = "Library for building and interfacing with finite fields" documentation = "https://docs.rs/ff/" @@ -14,6 +14,5 @@ rand = "0.4" ff_derive = { version = "0.3.0", path = "ff_derive", optional = true } [features] -default = ["derive"] -u128-support = [] +default = [] derive = ["ff_derive"] diff --git a/README.md b/README.md index 4bd82ad..3efef94 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,6 @@ ## Disclaimers * This library does not provide constant-time guarantees. -* This library relies on Rust's `i128_type` feature, which is currently only available in the nightly compiler. ## Usage @@ -13,15 +12,24 @@ Add the `ff` crate to your `Cargo.toml`: ```toml [dependencies] -ff = "0.2" +ff = "0.4" ``` -The `ff` crate contains `Field`, `PrimeField`, `PrimeFieldRepr` and `SqrtField` traits. See the **[documentation](https://docs.rs/ff/0.2.0/ff/)** for more. +The `ff` crate contains `Field`, `PrimeField`, `PrimeFieldRepr` and `SqrtField` traits. See the **[documentation](https://docs.rs/ff/0.4.0/ff/)** for more. ### #![derive(PrimeField)] If you need an implementation of a prime field, this library also provides a procedural macro that will expand into an efficient implementation of a prime field when supplied with the modulus. `PrimeFieldGenerator` must be an element of Fp of p-1 order, that is also quadratic nonresidue. +First, enable the `derive` crate feature: + +```toml +[dependencies] +ff = { version = "0.4", features = ["derive"] } +``` + +And then use the macro like so: + ```rust extern crate rand; #[macro_use] diff --git a/src/lib.rs b/src/lib.rs index 541fe76..a9d117f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,9 +3,11 @@ extern crate byteorder; extern crate rand; +#[cfg(feature = "derive")] #[macro_use] extern crate ff_derive; +#[cfg(feature = "derive")] pub use ff_derive::*; use std::error::Error; @@ -288,6 +290,14 @@ pub trait PrimeField: Field { fn root_of_unity() -> Self; } +/// An "engine" is a collection of types (fields, elliptic curve groups, etc.) +/// with well-defined relationships. Specific relationships (for example, a +/// pairing-friendly curve) can be defined in a subtrait. +pub trait ScalarEngine: Sized + 'static + Clone { + /// This is the scalar field of the engine's groups. + type Fr: PrimeField + SqrtField; +} + #[derive(Debug)] pub struct BitIterator { t: E, @@ -347,7 +357,6 @@ fn test_bit_iterator() { pub use self::arith_impl::*; -#[cfg(feature = "u128-support")] mod arith_impl { /// Calculate a - b - borrow, returning the result and modifying /// the borrow value. @@ -382,82 +391,3 @@ mod arith_impl { tmp as u64 } } - -#[cfg(not(feature = "u128-support"))] -mod arith_impl { - #[inline(always)] - fn split_u64(i: u64) -> (u64, u64) { - (i >> 32, i & 0xFFFFFFFF) - } - - #[inline(always)] - fn combine_u64(hi: u64, lo: u64) -> u64 { - (hi << 32) | lo - } - - /// Calculate a - b - borrow, returning the result and modifying - /// the borrow value. - #[inline(always)] - pub fn sbb(a: u64, b: u64, borrow: &mut u64) -> u64 { - let (a_hi, a_lo) = split_u64(a); - let (b_hi, b_lo) = split_u64(b); - let (b, r0) = split_u64((1 << 32) + a_lo - b_lo - *borrow); - let (b, r1) = split_u64((1 << 32) + a_hi - b_hi - ((b == 0) as u64)); - - *borrow = (b == 0) as u64; - - combine_u64(r1, r0) - } - - /// Calculate a + b + carry, returning the sum and modifying the - /// carry value. - #[inline(always)] - pub fn adc(a: u64, b: u64, carry: &mut u64) -> u64 { - let (a_hi, a_lo) = split_u64(a); - let (b_hi, b_lo) = split_u64(b); - let (carry_hi, carry_lo) = split_u64(*carry); - - let (t, r0) = split_u64(a_lo + b_lo + carry_lo); - let (t, r1) = split_u64(t + a_hi + b_hi + carry_hi); - - *carry = t; - - combine_u64(r1, r0) - } - - /// Calculate a + (b * c) + carry, returning the least significant digit - /// and setting carry to the most significant digit. - #[inline(always)] - pub fn mac_with_carry(a: u64, b: u64, c: u64, carry: &mut u64) -> u64 { - /* - [ b_hi | b_lo ] - [ c_hi | c_lo ] * - ------------------------------------------- - [ b_lo * c_lo ] <-- w - [ b_hi * c_lo ] <-- x - [ b_lo * c_hi ] <-- y - [ b_hi * c_lo ] <-- z - [ a_hi | a_lo ] - [ C_hi | C_lo ] - */ - - let (a_hi, a_lo) = split_u64(a); - let (b_hi, b_lo) = split_u64(b); - let (c_hi, c_lo) = split_u64(c); - let (carry_hi, carry_lo) = split_u64(*carry); - - let (w_hi, w_lo) = split_u64(b_lo * c_lo); - let (x_hi, x_lo) = split_u64(b_hi * c_lo); - let (y_hi, y_lo) = split_u64(b_lo * c_hi); - let (z_hi, z_lo) = split_u64(b_hi * c_hi); - - let (t, r0) = split_u64(w_lo + a_lo + carry_lo); - let (t, r1) = split_u64(t + w_hi + x_lo + y_lo + a_hi + carry_hi); - let (t, r2) = split_u64(t + x_hi + y_hi + z_lo); - let (_, r3) = split_u64(t + z_hi); - - *carry = combine_u64(r3, r2); - - combine_u64(r1, r0) - } -}