From d7f78db121ee6f720e97401ded0c9c597d1a4857 Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Tue, 3 Mar 2020 17:43:16 -0700 Subject: [PATCH] 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 --- Cargo.toml | 11 ++- README.md | 17 ++-- ff_derive/Cargo.toml | 12 ++- ff_derive/src/lib.rs | 182 +++++++++++++++++++++---------------------- src/lib.rs | 18 +++-- 5 files changed, 129 insertions(+), 111 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 22db67a..94480b0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,18 +1,23 @@ [package] name = "ff" -version = "0.4.0" +version = "0.5.2" authors = ["Sean Bowe "] 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" } diff --git a/README.md b/README.md index 3efef94..57ef693 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/ff_derive/Cargo.toml b/ff_derive/Cargo.toml index 914e392..04a9bc2 100644 --- a/ff_derive/Cargo.toml +++ b/ff_derive/Cargo.toml @@ -1,12 +1,13 @@ [package] name = "ff_derive" -version = "0.3.0" +version = "0.4.1" authors = ["Sean Bowe "] 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" } diff --git a/ff_derive/src/lib.rs b/ff_derive/src/lib.rs index 45d3445..5e56e74 100644 --- a/ff_derive/src/lib.rs +++ b/ff_derive/src/lib.rs @@ -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 { /// Fetch an attribute string from the derived struct. fn fetch_attr(name: &str, attrs: &[syn::Attribute]) -> Option { 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(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() ); } @@ -430,7 +421,7 @@ fn prime_field_constants_and_sqrt( let mod_minus_1_over_2 = biguint_to_u64_vec((&modulus - BigUint::from_str("1").unwrap()) >> 1, limbs); - let legendre_impl = quote!{ + let legendre_impl = quote! { fn legendre(&self) -> ::ff::LegendreSymbol { // s = self^((modulus - 1) // 2) let s = self.pow(#mod_minus_1_over_2); @@ -452,7 +443,7 @@ fn prime_field_constants_and_sqrt( // Compute -R as (m - r) let rneg = biguint_to_u64_vec(&modulus - &r, limbs); - quote!{ + quote! { impl ::ff::SqrtField for #name { #legendre_impl @@ -479,7 +470,7 @@ fn prime_field_constants_and_sqrt( let t_plus_1_over_2 = biguint_to_u64_vec((&t + BigUint::one()) >> 1, limbs); let t = biguint_to_u64_vec(t.clone(), limbs); - quote!{ + quote! { impl ::ff::SqrtField for #name { #legendre_impl @@ -526,7 +517,7 @@ fn prime_field_constants_and_sqrt( } } } else { - quote!{} + quote! {} }; // Compute R^2 mod m @@ -543,36 +534,39 @@ fn prime_field_constants_and_sqrt( } inv = inv.wrapping_neg(); - (quote! { - /// This is the modulus m of the prime field - const MODULUS: #repr = #repr([#(#modulus,)*]); + ( + quote! { + /// This is the modulus m of the prime field + const MODULUS: #repr = #repr([#(#modulus,)*]); - /// The number of bits needed to represent the modulus. - const MODULUS_BITS: u32 = #modulus_num_bits; + /// The number of bits needed to represent the modulus. + const MODULUS_BITS: u32 = #modulus_num_bits; - /// The number of bits that must be shaved from the beginning of - /// the representation when randomly sampling. - const REPR_SHAVE_BITS: u32 = #repr_shave_bits; + /// The number of bits that must be shaved from the beginning of + /// the representation when randomly sampling. + const REPR_SHAVE_BITS: u32 = #repr_shave_bits; - /// 2^{limbs*64} mod m - const R: #repr = #repr(#r); + /// 2^{limbs*64} mod m + const R: #repr = #repr(#r); - /// 2^{limbs*64*2} mod m - const R2: #repr = #repr(#r2); + /// 2^{limbs*64*2} mod m + const R2: #repr = #repr(#r2); - /// -(m^{-1} mod m) mod m - const INV: u64 = #inv; + /// -(m^{-1} mod m) mod m + const INV: u64 = #inv; - /// Multiplicative generator of `MODULUS` - 1 order, also quadratic - /// nonresidue. - const GENERATOR: #repr = #repr(#generator); + /// Multiplicative generator of `MODULUS` - 1 order, also quadratic + /// nonresidue. + const GENERATOR: #repr = #repr(#generator); - /// 2^s * t = MODULUS - 1 with t odd - const S: u32 = #s; + /// 2^s * t = MODULUS - 1 with t odd + const S: u32 = #s; - /// 2^s root of unity computed by GENERATOR^t - const ROOT_OF_UNITY: #repr = #repr(#root_of_unity); - }, sqrt_impl) + /// 2^s root of unity computed by GENERATOR^t + const ROOT_OF_UNITY: #repr = #repr(#root_of_unity); + }, + sqrt_impl, + ) } /// Implement PrimeField for the derived type. @@ -592,9 +586,9 @@ fn prime_field_impl( mont_paramlist.append_separated( (0..(limbs * 2)).map(|i| (i, get_temp(i))).map(|(i, x)| { if i != 0 { - quote!{mut #x: u64} + quote! {mut #x: u64} } else { - quote!{#x: u64} + quote! {#x: u64} } }), proc_macro2::Punct::new(',', proc_macro2::Spacing::Alone), @@ -607,7 +601,7 @@ fn prime_field_impl( for i in 0..limbs { { let temp = get_temp(i); - gen.extend(quote!{ + gen.extend(quote! { let k = #temp.wrapping_mul(INV); let mut carry = 0; ::ff::mac_with_carry(#temp, k, MODULUS.0[0], &mut carry); @@ -616,7 +610,7 @@ fn prime_field_impl( for j in 1..limbs { let temp = get_temp(i + j); - gen.extend(quote!{ + gen.extend(quote! { #temp = ::ff::mac_with_carry(#temp, k, MODULUS.0[#j], &mut carry); }); } @@ -624,17 +618,17 @@ fn prime_field_impl( let temp = get_temp(i + limbs); if i == 0 { - gen.extend(quote!{ + gen.extend(quote! { #temp = ::ff::adc(#temp, 0, &mut carry); }); } else { - gen.extend(quote!{ + gen.extend(quote! { #temp = ::ff::adc(#temp, carry2, &mut carry); }); } if i != (limbs - 1) { - gen.extend(quote!{ + gen.extend(quote! { let carry2 = carry; }); } @@ -643,7 +637,7 @@ fn prime_field_impl( for i in 0..limbs { let temp = get_temp(limbs + i); - gen.extend(quote!{ + gen.extend(quote! { (self.0).0[#i] = #temp; }); } @@ -655,14 +649,14 @@ fn prime_field_impl( let mut gen = proc_macro2::TokenStream::new(); for i in 0..(limbs - 1) { - gen.extend(quote!{ + gen.extend(quote! { let mut carry = 0; }); for j in (i + 1)..limbs { let temp = get_temp(i + j); if i == 0 { - gen.extend(quote!{ + gen.extend(quote! { let #temp = ::ff::mac_with_carry(0, (#a.0).0[#i], (#a.0).0[#j], &mut carry); }); } else { @@ -674,7 +668,7 @@ fn prime_field_impl( let temp = get_temp(i + limbs); - gen.extend(quote!{ + gen.extend(quote! { let #temp = carry; }); } @@ -684,21 +678,21 @@ fn prime_field_impl( let temp1 = get_temp(limbs * 2 - i - 1); if i == 1 { - gen.extend(quote!{ + gen.extend(quote! { let #temp0 = #temp1 >> 63; }); } else if i == (limbs * 2 - 1) { - gen.extend(quote!{ + gen.extend(quote! { let #temp0 = #temp0 << 1; }); } else { - gen.extend(quote!{ + gen.extend(quote! { let #temp0 = (#temp0 << 1) | (#temp1 >> 63); }); } } - gen.extend(quote!{ + gen.extend(quote! { let mut carry = 0; }); @@ -706,7 +700,7 @@ fn prime_field_impl( let temp0 = get_temp(i * 2); let temp1 = get_temp(i * 2 + 1); if i == 0 { - gen.extend(quote!{ + gen.extend(quote! { let #temp0 = ::ff::mac_with_carry(0, (#a.0).0[#i], (#a.0).0[#i], &mut carry); }); } else { @@ -715,7 +709,7 @@ fn prime_field_impl( }); } - gen.extend(quote!{ + gen.extend(quote! { let #temp1 = ::ff::adc(#temp1, 0, &mut carry); }); } @@ -726,7 +720,7 @@ fn prime_field_impl( proc_macro2::Punct::new(',', proc_macro2::Spacing::Alone), ); - gen.extend(quote!{ + gen.extend(quote! { self.mont_reduce(#mont_calling); }); @@ -741,7 +735,7 @@ fn prime_field_impl( let mut gen = proc_macro2::TokenStream::new(); for i in 0..limbs { - gen.extend(quote!{ + gen.extend(quote! { let mut carry = 0; }); @@ -749,7 +743,7 @@ fn prime_field_impl( let temp = get_temp(i + j); if i == 0 { - gen.extend(quote!{ + gen.extend(quote! { let #temp = ::ff::mac_with_carry(0, (#a.0).0[#i], (#b.0).0[#j], &mut carry); }); } else { @@ -761,7 +755,7 @@ fn prime_field_impl( let temp = get_temp(i + limbs); - gen.extend(quote!{ + gen.extend(quote! { let #temp = carry; }); } @@ -772,29 +766,29 @@ fn prime_field_impl( proc_macro2::Punct::new(',', proc_macro2::Spacing::Alone), ); - gen.extend(quote!{ + gen.extend(quote! { self.mont_reduce(#mont_calling); }); gen } - let squaring_impl = sqr_impl(quote!{self}, limbs); - let multiply_impl = mul_impl(quote!{self}, quote!{other}, limbs); + let squaring_impl = sqr_impl(quote! {self}, limbs); + let multiply_impl = mul_impl(quote! {self}, quote! {other}, limbs); let montgomery_impl = mont_impl(limbs); // (self.0).0[0], (self.0).0[1], ..., 0, 0, 0, 0, ... let mut into_repr_params = proc_macro2::TokenStream::new(); into_repr_params.append_separated( (0..limbs) - .map(|i| quote!{ (self.0).0[#i] }) - .chain((0..limbs).map(|_| quote!{0})), + .map(|i| quote! { (self.0).0[#i] }) + .chain((0..limbs).map(|_| quote! {0})), proc_macro2::Punct::new(',', proc_macro2::Spacing::Alone), ); let top_limb_index = limbs - 1; - quote!{ + quote! { impl ::std::marker::Copy for #name { } impl ::std::clone::Clone for #name { @@ -839,22 +833,6 @@ fn prime_field_impl( } } - impl ::rand::Rand for #name { - /// Computes a uniformly random element using rejection sampling. - fn rand(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(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)) diff --git a/src/lib.rs b/src/lib.rs index a9d117f..c66163d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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(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 @@ -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; + fn from_repr(_: Self::Repr) -> Result; /// Convert a biginteger representation into a prime field element, if /// the number is an element of the field.