commit
661558e0c8
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "ff"
|
name = "ff"
|
||||||
version = "0.3.0"
|
version = "0.4.0"
|
||||||
authors = ["Sean Bowe <ewillbefull@gmail.com>"]
|
authors = ["Sean Bowe <ewillbefull@gmail.com>"]
|
||||||
description = "Library for building and interfacing with finite fields"
|
description = "Library for building and interfacing with finite fields"
|
||||||
documentation = "https://docs.rs/ff/"
|
documentation = "https://docs.rs/ff/"
|
||||||
|
@ -14,6 +14,5 @@ rand = "0.4"
|
||||||
ff_derive = { version = "0.3.0", path = "ff_derive", optional = true }
|
ff_derive = { version = "0.3.0", path = "ff_derive", optional = true }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["derive"]
|
default = []
|
||||||
u128-support = []
|
|
||||||
derive = ["ff_derive"]
|
derive = ["ff_derive"]
|
||||||
|
|
14
README.md
14
README.md
|
@ -5,7 +5,6 @@
|
||||||
## Disclaimers
|
## Disclaimers
|
||||||
|
|
||||||
* This library does not provide constant-time guarantees.
|
* 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
|
## Usage
|
||||||
|
|
||||||
|
@ -13,15 +12,24 @@ Add the `ff` crate to your `Cargo.toml`:
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
[dependencies]
|
[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)]
|
### #![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.
|
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
|
```rust
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
|
90
src/lib.rs
90
src/lib.rs
|
@ -3,9 +3,11 @@
|
||||||
extern crate byteorder;
|
extern crate byteorder;
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
|
|
||||||
|
#[cfg(feature = "derive")]
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate ff_derive;
|
extern crate ff_derive;
|
||||||
|
|
||||||
|
#[cfg(feature = "derive")]
|
||||||
pub use ff_derive::*;
|
pub use ff_derive::*;
|
||||||
|
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
@ -288,6 +290,14 @@ pub trait PrimeField: Field {
|
||||||
fn root_of_unity() -> Self;
|
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)]
|
#[derive(Debug)]
|
||||||
pub struct BitIterator<E> {
|
pub struct BitIterator<E> {
|
||||||
t: E,
|
t: E,
|
||||||
|
@ -347,7 +357,6 @@ fn test_bit_iterator() {
|
||||||
|
|
||||||
pub use self::arith_impl::*;
|
pub use self::arith_impl::*;
|
||||||
|
|
||||||
#[cfg(feature = "u128-support")]
|
|
||||||
mod arith_impl {
|
mod arith_impl {
|
||||||
/// Calculate a - b - borrow, returning the result and modifying
|
/// Calculate a - b - borrow, returning the result and modifying
|
||||||
/// the borrow value.
|
/// the borrow value.
|
||||||
|
@ -382,82 +391,3 @@ mod arith_impl {
|
||||||
tmp as u64
|
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue