Squashed 'ff/' changes from 661558e..ddff465

ddff465 Bump version and dependency on ff_derive
25d11d6 Bump version
95e2723 Bump version to 0.5.1
f76872a Add ?Sized to RngCore trait bounds (#14)
09a32b1 ff 0.5.0
32543ab Crate docs
22031dc Update READMEs
658fe6d CI: Check intra-doc links
35f5026 Add READMEs to Cargo.toml files
6804225 Migrate ff_derive to proc-macro2 1.0
b9a79ce cargo fmt
82574c2 cargo fix --edition-idioms for ff
3b0cf72 Add edition = 2018
8a2b51b Replace try! macro
40fc9ba cargo fix --edition for ff
22c67f3 cargo fmt
312141c Clarify masking of bits in Field::random impls
89a68e1 Migrate to rand 0.7
58415fb Migrate ff, group, pairing, and bellman to rand 0.6
8b6e6b1 Migrate ff to rand_core 0.3 (used by rand 0.5)

git-subtree-dir: ff
git-subtree-split: ddff4658ddd7496bb29cc636c391b7aaaca24673
This commit is contained in:
Sean Bowe
2020-03-03 17:43:16 -07:00
parent 661558e0c8
commit d7f78db121
5 changed files with 129 additions and 111 deletions

View File

@@ -1,18 +1,23 @@
[package]
name = "ff"
version = "0.4.0"
version = "0.5.2"
authors = ["Sean Bowe <ewillbefull@gmail.com>"]
description = "Library for building and interfacing with finite fields"
readme = "README.md"
documentation = "https://docs.rs/ff/"
homepage = "https://github.com/ebfull/ff"
license = "MIT/Apache-2.0"
repository = "https://github.com/ebfull/ff"
edition = "2018"
[dependencies]
byteorder = "1"
rand = "0.4"
ff_derive = { version = "0.3.0", path = "ff_derive", optional = true }
ff_derive = { version = "^0.4.1", path = "ff_derive", optional = true }
rand_core = "0.5"
[features]
default = []
derive = ["ff_derive"]
[badges]
maintenance = { status = "actively-developed" }

View File

@@ -12,14 +12,18 @@ Add the `ff` crate to your `Cargo.toml`:
```toml
[dependencies]
ff = "0.4"
ff = "0.5"
```
The `ff` crate contains `Field`, `PrimeField`, `PrimeFieldRepr` and `SqrtField` traits. See the **[documentation](https://docs.rs/ff/0.4.0/ff/)** for more.
The `ff` crate contains `Field`, `PrimeField`, `PrimeFieldRepr` and `SqrtField` traits.
See the **[documentation](https://docs.rs/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.
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:
@@ -41,13 +45,16 @@ extern crate ff;
struct Fp(FpRepr);
```
And that's it! `Fp` now implements `Field` and `PrimeField`. `Fp` will also implement `SqrtField` if supported. The library implements `FpRepr` itself and derives `PrimeFieldRepr` for it.
And that's it! `Fp` now implements `Field` and `PrimeField`. `Fp` will also implement
`SqrtField` if supported. The library implements `FpRepr` itself and derives
`PrimeFieldRepr` for it.
## License
Licensed under either of
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
http://www.apache.org/licenses/LICENSE-2.0)
* MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
at your option.

View File

@@ -1,12 +1,13 @@
[package]
name = "ff_derive"
version = "0.3.0"
version = "0.4.1"
authors = ["Sean Bowe <ewillbefull@gmail.com>"]
description = "Procedural macro library used to build custom prime field implementations"
documentation = "https://docs.rs/ff/"
homepage = "https://github.com/ebfull/ff"
license = "MIT/Apache-2.0"
repository = "https://github.com/ebfull/ff"
edition = "2018"
[lib]
proc-macro = true
@@ -15,6 +16,9 @@ proc-macro = true
num-bigint = "0.2"
num-traits = "0.2"
num-integer = "0.1"
proc-macro2 = "0.4"
quote = "0.6"
syn = "0.14"
proc-macro2 = "1"
quote = "1"
syn = "1"
[badges]
maintenance = { status = "passively-maintained" }

View File

@@ -52,13 +52,8 @@ pub fn prime_field(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let mut gen = proc_macro2::TokenStream::new();
let (constants_impl, sqrt_impl) = prime_field_constants_and_sqrt(
&ast.ident,
&repr_ident,
modulus,
limbs,
generator,
);
let (constants_impl, sqrt_impl) =
prime_field_constants_and_sqrt(&ast.ident, &repr_ident, modulus, limbs, generator);
gen.extend(constants_impl);
gen.extend(prime_field_repr_impl(&repr_ident, limbs));
@@ -96,10 +91,10 @@ fn fetch_wrapped_ident(body: &syn::Data) -> Option<syn::Ident> {
/// Fetch an attribute string from the derived struct.
fn fetch_attr(name: &str, attrs: &[syn::Attribute]) -> Option<String> {
for attr in attrs {
if let Some(meta) = attr.interpret_meta() {
if let Ok(meta) = attr.parse_meta() {
match meta {
syn::Meta::NameValue(nv) => {
if nv.ident.to_string() == name {
if nv.path.get_ident().map(|i| i.to_string()) == Some(name.to_string()) {
match nv.lit {
syn::Lit::Str(ref s) => return Some(s.value()),
_ => {
@@ -127,27 +122,20 @@ fn prime_field_repr_impl(repr: &syn::Ident, limbs: usize) -> proc_macro2::TokenS
impl ::std::fmt::Debug for #repr
{
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
try!(write!(f, "0x"));
write!(f, "0x")?;
for i in self.0.iter().rev() {
try!(write!(f, "{:016x}", *i));
write!(f, "{:016x}", *i)?;
}
Ok(())
}
}
impl ::rand::Rand for #repr {
#[inline(always)]
fn rand<R: ::rand::Rng>(rng: &mut R) -> Self {
#repr(rng.gen())
}
}
impl ::std::fmt::Display for #repr {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
try!(write!(f, "0x"));
write!(f, "0x")?;
for i in self.0.iter().rev() {
try!(write!(f, "{:016x}", *i));
write!(f, "{:016x}", *i)?;
}
Ok(())
@@ -366,7 +354,8 @@ fn biguint_num_bits(mut v: BigUint) -> u32 {
fn exp(base: BigUint, exp: &BigUint, modulus: &BigUint) -> BigUint {
let mut ret = BigUint::one();
for i in exp.to_bytes_be()
for i in exp
.to_bytes_be()
.into_iter()
.flat_map(|x| (0..8).rev().map(move |i| (x >> i).is_odd()))
{
@@ -387,11 +376,13 @@ fn test_exp() {
&BigUint::from_str("5489673498567349856734895").unwrap(),
&BigUint::from_str(
"52435875175126190479447740508185965837690552500527637822603658699938581184513"
).unwrap()
)
.unwrap()
),
BigUint::from_str(
"4371221214068404307866768905142520595925044802278091865033317963560480051536"
).unwrap()
)
.unwrap()
);
}
@@ -543,7 +534,8 @@ fn prime_field_constants_and_sqrt(
}
inv = inv.wrapping_neg();
(quote! {
(
quote! {
/// This is the modulus m of the prime field
const MODULUS: #repr = #repr([#(#modulus,)*]);
@@ -572,7 +564,9 @@ fn prime_field_constants_and_sqrt(
/// 2^s root of unity computed by GENERATOR^t
const ROOT_OF_UNITY: #repr = #repr(#root_of_unity);
}, sqrt_impl)
},
sqrt_impl,
)
}
/// Implement PrimeField for the derived type.
@@ -839,22 +833,6 @@ fn prime_field_impl(
}
}
impl ::rand::Rand for #name {
/// Computes a uniformly random element using rejection sampling.
fn rand<R: ::rand::Rng>(rng: &mut R) -> Self {
loop {
let mut tmp = #name(#repr::rand(rng));
// Mask away the unused bits at the beginning.
tmp.0.as_mut()[#top_limb_index] &= 0xffffffffffffffff >> REPR_SHAVE_BITS;
if tmp.is_valid() {
return tmp
}
}
}
}
impl From<#name> for #repr {
fn from(e: #name) -> #repr {
e.into_repr()
@@ -904,6 +882,26 @@ fn prime_field_impl(
}
impl ::ff::Field for #name {
/// Computes a uniformly random element using rejection sampling.
fn random<R: ::rand_core::RngCore + ?std::marker::Sized>(rng: &mut R) -> Self {
loop {
let mut tmp = {
let mut repr = [0u64; #limbs];
for i in 0..#limbs {
repr[i] = rng.next_u64();
}
#name(#repr(repr))
};
// Mask away the unused most-significant bits.
tmp.0.as_mut()[#top_limb_index] &= 0xffffffffffffffff >> REPR_SHAVE_BITS;
if tmp.is_valid() {
return tmp
}
}
}
#[inline]
fn zero() -> Self {
#name(#repr::from(0))

View File

@@ -1,7 +1,8 @@
#![allow(unused_imports)]
//! This crate provides traits for working with finite fields.
extern crate byteorder;
extern crate rand;
// Catch documentation errors caused by code changes.
#![deny(intra_doc_link_resolution_failure)]
#![allow(unused_imports)]
#[cfg(feature = "derive")]
#[macro_use]
@@ -10,14 +11,18 @@ extern crate ff_derive;
#[cfg(feature = "derive")]
pub use ff_derive::*;
use rand_core::RngCore;
use std::error::Error;
use std::fmt;
use std::io::{self, Read, Write};
/// This trait represents an element of a field.
pub trait Field:
Sized + Eq + Copy + Clone + Send + Sync + fmt::Debug + fmt::Display + 'static + rand::Rand
Sized + Eq + Copy + Clone + Send + Sync + fmt::Debug + fmt::Display + 'static
{
/// Returns an element chosen uniformly at random using a user-provided RNG.
fn random<R: RngCore + ?std::marker::Sized>(rng: &mut R) -> Self;
/// Returns the zero element of the field, the additive identity.
fn zero() -> Self;
@@ -100,7 +105,6 @@ pub trait PrimeFieldRepr:
+ fmt::Debug
+ fmt::Display
+ 'static
+ rand::Rand
+ AsRef<[u64]>
+ AsMut<[u64]>
+ From<u64>
@@ -207,7 +211,7 @@ impl Error for PrimeFieldDecodingError {
}
impl fmt::Display for PrimeFieldDecodingError {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
match *self {
PrimeFieldDecodingError::NotInField(ref repr) => {
write!(f, "{} is not an element of the field", repr)
@@ -263,7 +267,7 @@ pub trait PrimeField: Field {
}
/// Convert this prime field element into a biginteger representation.
fn from_repr(Self::Repr) -> Result<Self, PrimeFieldDecodingError>;
fn from_repr(_: Self::Repr) -> Result<Self, PrimeFieldDecodingError>;
/// Convert a biginteger representation into a prime field element, if
/// the number is an element of the field.