cargo fmt

This commit is contained in:
Jack Grigg
2018-06-26 10:48:27 -04:00
committed by str4d
parent c7252a43bf
commit 755fc7aba8
2 changed files with 164 additions and 193 deletions

View File

@@ -1,4 +1,4 @@
#![recursion_limit="1024"] #![recursion_limit = "1024"]
extern crate proc_macro; extern crate proc_macro;
extern crate syn; extern crate syn;
@@ -6,19 +6,16 @@ extern crate syn;
extern crate quote; extern crate quote;
extern crate num_bigint; extern crate num_bigint;
extern crate num_traits;
extern crate num_integer; extern crate num_integer;
extern crate num_traits;
use num_integer::Integer;
use num_traits::{Zero, One, ToPrimitive};
use num_bigint::BigUint; use num_bigint::BigUint;
use num_integer::Integer;
use num_traits::{One, ToPrimitive, Zero};
use std::str::FromStr; use std::str::FromStr;
#[proc_macro_derive(PrimeField, attributes(PrimeFieldModulus, PrimeFieldGenerator))] #[proc_macro_derive(PrimeField, attributes(PrimeFieldModulus, PrimeFieldGenerator))]
pub fn prime_field( pub fn prime_field(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
input: proc_macro::TokenStream
) -> proc_macro::TokenStream
{
// Construct a string representation of the type definition // Construct a string representation of the type definition
let s = input.to_string(); let s = input.to_string();
@@ -32,13 +29,15 @@ pub fn prime_field(
// We're given the modulus p of the prime field // We're given the modulus p of the prime field
let modulus: BigUint = fetch_attr("PrimeFieldModulus", &ast.attrs) let modulus: BigUint = fetch_attr("PrimeFieldModulus", &ast.attrs)
.expect("Please supply a PrimeFieldModulus attribute") .expect("Please supply a PrimeFieldModulus attribute")
.parse().expect("PrimeFieldModulus should be a number"); .parse()
.expect("PrimeFieldModulus should be a number");
// We may be provided with a generator of p - 1 order. It is required that this generator be quadratic // We may be provided with a generator of p - 1 order. It is required that this generator be quadratic
// nonresidue. // nonresidue.
let generator: BigUint = fetch_attr("PrimeFieldGenerator", &ast.attrs) let generator: BigUint = fetch_attr("PrimeFieldGenerator", &ast.attrs)
.expect("Please supply a PrimeFieldGenerator attribute") .expect("Please supply a PrimeFieldGenerator attribute")
.parse().expect("PrimeFieldGenerator should be a number"); .parse()
.expect("PrimeFieldGenerator should be a number");
// The arithmetic in this library only works if the modulus*2 is smaller than the backing // The arithmetic in this library only works if the modulus*2 is smaller than the backing
// representation. Compute the number of limbs we need. // representation. Compute the number of limbs we need.
@@ -55,7 +54,13 @@ pub fn prime_field(
let mut gen = quote::Tokens::new(); let mut gen = quote::Tokens::new();
gen.append(prime_field_repr_impl(&repr_ident, limbs)); gen.append(prime_field_repr_impl(&repr_ident, limbs));
gen.append(prime_field_constants_and_sqrt(&ast.ident, &repr_ident, modulus, limbs, generator)); gen.append(prime_field_constants_and_sqrt(
&ast.ident,
&repr_ident,
modulus,
limbs,
generator,
));
gen.append(prime_field_impl(&ast.ident, &repr_ident, limbs)); gen.append(prime_field_impl(&ast.ident, &repr_ident, limbs));
// Return the generated impl // Return the generated impl
@@ -63,10 +68,7 @@ pub fn prime_field(
} }
/// Fetches the ident being wrapped by the type we're deriving. /// Fetches the ident being wrapped by the type we're deriving.
fn fetch_wrapped_ident( fn fetch_wrapped_ident(body: &syn::Body) -> Option<syn::Ident> {
body: &syn::Body
) -> Option<syn::Ident>
{
match body { match body {
&syn::Body::Struct(ref variant_data) => { &syn::Body::Struct(ref variant_data) => {
let fields = variant_data.fields(); let fields = variant_data.fields();
@@ -76,11 +78,11 @@ fn fetch_wrapped_ident(
if path.segments.len() == 1 { if path.segments.len() == 1 {
return Some(path.segments[0].ident.clone()); return Some(path.segments[0].ident.clone());
} }
}, }
_ => {} _ => {}
} }
} }
}, }
_ => {} _ => {}
}; };
@@ -88,23 +90,15 @@ fn fetch_wrapped_ident(
} }
/// Fetch an attribute string from the derived struct. /// Fetch an attribute string from the derived struct.
fn fetch_attr( fn fetch_attr(name: &str, attrs: &[syn::Attribute]) -> Option<String> {
name: &str,
attrs: &[syn::Attribute]
) -> Option<String>
{
for attr in attrs { for attr in attrs {
if attr.name() == name { if attr.name() == name {
match attr.value { match attr.value {
syn::MetaItem::NameValue(_, ref val) => { syn::MetaItem::NameValue(_, ref val) => match val {
match val { &syn::Lit::Str(ref s, _) => return Some(s.clone()),
&syn::Lit::Str(ref s, _) => {
return Some(s.clone())
},
_ => { _ => {
panic!("attribute {} should be a string", name); panic!("attribute {} should be a string", name);
} }
}
}, },
_ => { _ => {
panic!("attribute {} should be a string", name); panic!("attribute {} should be a string", name);
@@ -117,11 +111,7 @@ fn fetch_attr(
} }
// Implement PrimeFieldRepr for the wrapped ident `repr` with `limbs` limbs. // Implement PrimeFieldRepr for the wrapped ident `repr` with `limbs` limbs.
fn prime_field_repr_impl( fn prime_field_repr_impl(repr: &syn::Ident, limbs: usize) -> quote::Tokens {
repr: &syn::Ident,
limbs: usize
) -> quote::Tokens
{
quote! { quote! {
#[derive(Copy, Clone, PartialEq, Eq, Default)] #[derive(Copy, Clone, PartialEq, Eq, Default)]
pub struct #repr(pub [u64; #limbs]); pub struct #repr(pub [u64; #limbs]);
@@ -263,11 +253,7 @@ fn prime_field_repr_impl(
} }
/// Convert BigUint into a vector of 64-bit limbs. /// Convert BigUint into a vector of 64-bit limbs.
fn biguint_to_u64_vec( fn biguint_to_u64_vec(mut v: BigUint, limbs: usize) -> Vec<u64> {
mut v: BigUint,
limbs: usize
) -> Vec<u64>
{
let m = BigUint::one() << 64; let m = BigUint::one() << 64;
let mut ret = vec![]; let mut ret = vec![];
@@ -285,10 +271,7 @@ fn biguint_to_u64_vec(
ret ret
} }
fn biguint_num_bits( fn biguint_num_bits(mut v: BigUint) -> u32 {
mut v: BigUint
) -> u32
{
let mut bits = 0; let mut bits = 0;
while v != BigUint::zero() { while v != BigUint::zero() {
@@ -300,12 +283,7 @@ fn biguint_num_bits(
} }
/// BigUint modular exponentiation by square-and-multiply. /// BigUint modular exponentiation by square-and-multiply.
fn exp( fn exp(base: BigUint, exp: &BigUint, modulus: &BigUint) -> BigUint {
base: BigUint,
exp: &BigUint,
modulus: &BigUint
) -> BigUint
{
let mut ret = BigUint::one(); let mut ret = BigUint::one();
for i in exp.to_bytes_be() for i in exp.to_bytes_be()
@@ -327,9 +305,13 @@ fn test_exp() {
exp( exp(
BigUint::from_str("4398572349857239485729348572983472345").unwrap(), BigUint::from_str("4398572349857239485729348572983472345").unwrap(),
&BigUint::from_str("5489673498567349856734895").unwrap(), &BigUint::from_str("5489673498567349856734895").unwrap(),
&BigUint::from_str("52435875175126190479447740508185965837690552500527637822603658699938581184513").unwrap() &BigUint::from_str(
"52435875175126190479447740508185965837690552500527637822603658699938581184513"
).unwrap()
), ),
BigUint::from_str("4371221214068404307866768905142520595925044802278091865033317963560480051536").unwrap() BigUint::from_str(
"4371221214068404307866768905142520595925044802278091865033317963560480051536"
).unwrap()
); );
} }
@@ -338,9 +320,8 @@ fn prime_field_constants_and_sqrt(
repr: &syn::Ident, repr: &syn::Ident,
modulus: BigUint, modulus: BigUint,
limbs: usize, limbs: usize,
generator: BigUint generator: BigUint,
) -> quote::Tokens ) -> quote::Tokens {
{
let modulus_num_bits = biguint_num_bits(modulus.clone()); let modulus_num_bits = biguint_num_bits(modulus.clone());
// The number of bits we should "shave" from a randomly sampled reputation, i.e., // The number of bits we should "shave" from a randomly sampled reputation, i.e.,
@@ -361,12 +342,16 @@ fn prime_field_constants_and_sqrt(
} }
// Compute 2^s root of unity given the generator // Compute 2^s root of unity given the generator
let root_of_unity = biguint_to_u64_vec((exp(generator.clone(), &t, &modulus) * &r) % &modulus, limbs); let root_of_unity = biguint_to_u64_vec(
(exp(generator.clone(), &t, &modulus) * &r) % &modulus,
limbs,
);
let generator = biguint_to_u64_vec((generator.clone() * &r) % &modulus, limbs); let generator = biguint_to_u64_vec((generator.clone() * &r) % &modulus, limbs);
let sqrt_impl = let sqrt_impl =
if (&modulus % BigUint::from_str("4").unwrap()) == BigUint::from_str("3").unwrap() { if (&modulus % BigUint::from_str("4").unwrap()) == BigUint::from_str("3").unwrap() {
let mod_minus_3_over_4 = biguint_to_u64_vec((&modulus - BigUint::from_str("3").unwrap()) >> 2, limbs); let mod_minus_3_over_4 =
biguint_to_u64_vec((&modulus - BigUint::from_str("3").unwrap()) >> 2, limbs);
// Compute -R as (m - r) // Compute -R as (m - r)
let rneg = biguint_to_u64_vec(&modulus - &r, limbs); let rneg = biguint_to_u64_vec(&modulus - &r, limbs);
@@ -393,7 +378,8 @@ fn prime_field_constants_and_sqrt(
} }
} }
} else if (&modulus % BigUint::from_str("16").unwrap()) == BigUint::from_str("1").unwrap() { } else if (&modulus % BigUint::from_str("16").unwrap()) == BigUint::from_str("1").unwrap() {
let mod_minus_1_over_2 = biguint_to_u64_vec((&modulus - BigUint::from_str("1").unwrap()) >> 1, limbs); let mod_minus_1_over_2 =
biguint_to_u64_vec((&modulus - BigUint::from_str("1").unwrap()) >> 1, limbs);
let t_plus_1_over_2 = biguint_to_u64_vec((&t + BigUint::one()) >> 1, limbs); let t_plus_1_over_2 = biguint_to_u64_vec((&t + BigUint::one()) >> 1, limbs);
let t = biguint_to_u64_vec(t.clone(), limbs); let t = biguint_to_u64_vec(t.clone(), limbs);
@@ -496,12 +482,7 @@ fn prime_field_constants_and_sqrt(
} }
/// Implement PrimeField for the derived type. /// Implement PrimeField for the derived type.
fn prime_field_impl( fn prime_field_impl(name: &syn::Ident, repr: &syn::Ident, limbs: usize) -> quote::Tokens {
name: &syn::Ident,
repr: &syn::Ident,
limbs: usize
) -> quote::Tokens
{
// Returns r{n} as an ident. // Returns r{n} as an ident.
fn get_temp(n: usize) -> syn::Ident { fn get_temp(n: usize) -> syn::Ident {
syn::Ident::from(format!("r{}", n)) syn::Ident::from(format!("r{}", n))
@@ -511,20 +492,18 @@ fn prime_field_impl(
// r0: u64, mut r1: u64, mut r2: u64, ... // r0: u64, mut r1: u64, mut r2: u64, ...
let mut mont_paramlist = quote::Tokens::new(); let mut mont_paramlist = quote::Tokens::new();
mont_paramlist.append_separated( mont_paramlist.append_separated(
(0..(limbs*2)).map(|i| (i, get_temp(i))) (0..(limbs * 2)).map(|i| (i, get_temp(i))).map(|(i, x)| {
.map(|(i, x)| {
if i != 0 { if i != 0 {
quote!{mut #x: u64} quote!{mut #x: u64}
} else { } else {
quote!{#x: u64} quote!{#x: u64}
} }
}), }),
"," ",",
); );
// Implement montgomery reduction for some number of limbs // Implement montgomery reduction for some number of limbs
fn mont_impl(limbs: usize) -> quote::Tokens fn mont_impl(limbs: usize) -> quote::Tokens {
{
let mut gen = quote::Tokens::new(); let mut gen = quote::Tokens::new();
for i in 0..limbs { for i in 0..limbs {
@@ -574,16 +553,15 @@ fn prime_field_impl(
gen gen
} }
fn sqr_impl(a: quote::Tokens, limbs: usize) -> quote::Tokens fn sqr_impl(a: quote::Tokens, limbs: usize) -> quote::Tokens {
{
let mut gen = quote::Tokens::new(); let mut gen = quote::Tokens::new();
for i in 0..(limbs-1) { for i in 0..(limbs - 1) {
gen.append(quote!{ gen.append(quote!{
let mut carry = 0; let mut carry = 0;
}); });
for j in (i+1)..limbs { for j in (i + 1)..limbs {
let temp = get_temp(i + j); let temp = get_temp(i + j);
if i == 0 { if i == 0 {
gen.append(quote!{ gen.append(quote!{
@@ -603,7 +581,7 @@ fn prime_field_impl(
}); });
} }
for i in 1..(limbs*2) { for i in 1..(limbs * 2) {
let k = get_temp(i); let k = get_temp(i);
if i == 1 { if i == 1 {
@@ -611,7 +589,7 @@ fn prime_field_impl(
let tmp0 = #k >> 63; let tmp0 = #k >> 63;
let #k = #k << 1; let #k = #k << 1;
}); });
} else if i == (limbs*2 - 1) { } else if i == (limbs * 2 - 1) {
gen.append(quote!{ gen.append(quote!{
let #k = tmp0; let #k = tmp0;
}); });
@@ -648,7 +626,7 @@ fn prime_field_impl(
} }
let mut mont_calling = quote::Tokens::new(); let mut mont_calling = quote::Tokens::new();
mont_calling.append_separated((0..(limbs*2)).map(|i| get_temp(i)), ","); mont_calling.append_separated((0..(limbs * 2)).map(|i| get_temp(i)), ",");
gen.append(quote!{ gen.append(quote!{
self.mont_reduce(#mont_calling); self.mont_reduce(#mont_calling);
@@ -657,8 +635,7 @@ fn prime_field_impl(
gen gen
} }
fn mul_impl(a: quote::Tokens, b: quote::Tokens, limbs: usize) -> quote::Tokens fn mul_impl(a: quote::Tokens, b: quote::Tokens, limbs: usize) -> quote::Tokens {
{
let mut gen = quote::Tokens::new(); let mut gen = quote::Tokens::new();
for i in 0..limbs { for i in 0..limbs {
@@ -688,7 +665,7 @@ fn prime_field_impl(
} }
let mut mont_calling = quote::Tokens::new(); let mut mont_calling = quote::Tokens::new();
mont_calling.append_separated((0..(limbs*2)).map(|i| get_temp(i)), ","); mont_calling.append_separated((0..(limbs * 2)).map(|i| get_temp(i)), ",");
gen.append(quote!{ gen.append(quote!{
self.mont_reduce(#mont_calling); self.mont_reduce(#mont_calling);
@@ -704,9 +681,10 @@ fn prime_field_impl(
// (self.0).0[0], (self.0).0[1], ..., 0, 0, 0, 0, ... // (self.0).0[0], (self.0).0[1], ..., 0, 0, 0, 0, ...
let mut into_repr_params = quote::Tokens::new(); let mut into_repr_params = quote::Tokens::new();
into_repr_params.append_separated( into_repr_params.append_separated(
(0..limbs).map(|i| quote!{ (self.0).0[#i] }) (0..limbs)
.map(|i| quote!{ (self.0).0[#i] })
.chain((0..limbs).map(|_| quote!{0})), .chain((0..limbs).map(|_| quote!{0})),
"," ",",
); );
quote!{ quote!{

View File

@@ -11,15 +11,8 @@ pub use ff_derive::*;
use std::fmt; use std::fmt;
/// This trait represents an element of a field. /// This trait represents an element of a field.
pub trait Field: Sized + pub trait Field:
Eq + Sized + Eq + Copy + Clone + Send + Sync + fmt::Debug + 'static + rand::Rand
Copy +
Clone +
Send +
Sync +
fmt::Debug +
'static +
rand::Rand
{ {
/// Returns the zero element of the field, the additive identity. /// Returns the zero element of the field, the additive identity.
fn zero() -> Self; fn zero() -> Self;
@@ -57,8 +50,7 @@ pub trait Field: Sized +
/// Exponentiates this element by a number represented with `u64` limbs, /// Exponentiates this element by a number represented with `u64` limbs,
/// least significant digit first. /// least significant digit first.
fn pow<S: AsRef<[u64]>>(&self, exp: S) -> Self fn pow<S: AsRef<[u64]>>(&self, exp: S) -> Self {
{
let mut res = Self::one(); let mut res = Self::one();
for i in BitIterator::new(exp) { for i in BitIterator::new(exp) {
@@ -73,8 +65,7 @@ pub trait Field: Sized +
} }
/// This trait represents an element of a field that has a square root operation described for it. /// This trait represents an element of a field that has a square root operation described for it.
pub trait SqrtField: Field pub trait SqrtField: Field {
{
/// Returns the square root of the field element, if it is /// Returns the square root of the field element, if it is
/// quadratic residue. /// quadratic residue.
fn sqrt(&self) -> Option<Self>; fn sqrt(&self) -> Option<Self>;
@@ -83,18 +74,19 @@ pub trait SqrtField: Field
/// This trait represents a wrapper around a biginteger which can encode any element of a particular /// This trait represents a wrapper around a biginteger which can encode any element of a particular
/// prime field. It is a smart wrapper around a sequence of `u64` limbs, least-significant digit /// prime field. It is a smart wrapper around a sequence of `u64` limbs, least-significant digit
/// first. /// first.
pub trait PrimeFieldRepr: Sized + pub trait PrimeFieldRepr:
Copy + Sized
Clone + + Copy
Eq + + Clone
Ord + + Eq
Send + + Ord
Sync + + Send
fmt::Debug + + Sync
'static + + fmt::Debug
rand::Rand + + 'static
AsRef<[u64]> + + rand::Rand
From<u64> + AsRef<[u64]>
+ From<u64>
{ {
/// Subtract another reprensetation from this one, returning the borrow bit. /// Subtract another reprensetation from this one, returning the borrow bit.
fn sub_noborrow(&mut self, other: &Self) -> bool; fn sub_noborrow(&mut self, other: &Self) -> bool;
@@ -124,8 +116,7 @@ pub trait PrimeFieldRepr: Sized +
} }
/// This represents an element of a prime field. /// This represents an element of a prime field.
pub trait PrimeField: Field pub trait PrimeField: Field {
{
/// The prime field can be converted back and forth into this biginteger /// The prime field can be converted back and forth into this biginteger
/// representation. /// representation.
type Repr: PrimeFieldRepr; type Repr: PrimeFieldRepr;
@@ -162,17 +153,14 @@ pub trait PrimeField: Field
pub struct BitIterator<E> { pub struct BitIterator<E> {
t: E, t: E,
n: usize n: usize,
} }
impl<E: AsRef<[u64]>> BitIterator<E> { impl<E: AsRef<[u64]>> BitIterator<E> {
fn new(t: E) -> Self { fn new(t: E) -> Self {
let n = t.as_ref().len() * 64; let n = t.as_ref().len() * 64;
BitIterator { BitIterator { t: t, n: n }
t: t,
n: n
}
} }
} }
@@ -205,7 +193,12 @@ fn test_bit_iterator() {
let expected = "1010010101111110101010000101101011101000011101110101001000011001100100100011011010001011011011010001011011101100110100111011010010110001000011110100110001100110011101101000101100011100100100100100001010011101010111110011101011000011101000111011011101011001"; let expected = "1010010101111110101010000101101011101000011101110101001000011001100100100011011010001011011011010001011011101100110100111011010010110001000011110100110001100110011101101000101100011100100100100100001010011101010111110011101011000011101000111011011101011001";
let mut a = BitIterator::new([0x429d5f3ac3a3b759, 0xb10f4c66768b1c92, 0x92368b6d16ecd3b4, 0xa57ea85ae8775219]); let mut a = BitIterator::new([
0x429d5f3ac3a3b759,
0xb10f4c66768b1c92,
0x92368b6d16ecd3b4,
0xa57ea85ae8775219,
]);
for e in expected.chars() { for e in expected.chars() {
assert!(a.next().unwrap() == (e == '1')); assert!(a.next().unwrap() == (e == '1'));