mirror of
https://github.com/Qortal/pirate-librustzcash.git
synced 2025-11-02 12:27:02 +00:00
cargo fmt
This commit is contained in:
@@ -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();
|
||||||
|
|
||||||
@@ -27,18 +24,20 @@ pub fn prime_field(
|
|||||||
|
|
||||||
// The struct we're deriving for is a wrapper around a "Repr" type we must construct.
|
// The struct we're deriving for is a wrapper around a "Repr" type we must construct.
|
||||||
let repr_ident = fetch_wrapped_ident(&ast.body)
|
let repr_ident = fetch_wrapped_ident(&ast.body)
|
||||||
.expect("PrimeField derive only operates over tuple structs of a single item");
|
.expect("PrimeField derive only operates over tuple structs of a single item");
|
||||||
|
|
||||||
// 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,22 +90,14 @@ 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
@@ -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,17 +283,12 @@ 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()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flat_map(|x| (0..8).rev().map(move |i| (x >> i).is_odd()))
|
.flat_map(|x| (0..8).rev().map(move |i| (x >> i).is_odd()))
|
||||||
{
|
{
|
||||||
ret = (&ret * &ret) % modulus;
|
ret = (&ret * &ret) % modulus;
|
||||||
if i {
|
if i {
|
||||||
@@ -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,91 +342,96 @@ 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);
|
||||||
|
|
||||||
quote!{
|
quote!{
|
||||||
impl ::ff::SqrtField for #name {
|
impl ::ff::SqrtField for #name {
|
||||||
fn sqrt(&self) -> Option<Self> {
|
fn sqrt(&self) -> Option<Self> {
|
||||||
// Shank's algorithm for q mod 4 = 3
|
// Shank's algorithm for q mod 4 = 3
|
||||||
// https://eprint.iacr.org/2012/685.pdf (page 9, algorithm 2)
|
// https://eprint.iacr.org/2012/685.pdf (page 9, algorithm 2)
|
||||||
|
|
||||||
let mut a1 = self.pow(#mod_minus_3_over_4);
|
let mut a1 = self.pow(#mod_minus_3_over_4);
|
||||||
|
|
||||||
let mut a0 = a1;
|
let mut a0 = a1;
|
||||||
a0.square();
|
a0.square();
|
||||||
a0.mul_assign(self);
|
a0.mul_assign(self);
|
||||||
|
|
||||||
if a0.0 == #repr(#rneg) {
|
if a0.0 == #repr(#rneg) {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
a1.mul_assign(self);
|
a1.mul_assign(self);
|
||||||
Some(a1)
|
Some(a1)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} 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 =
|
||||||
let mod_minus_1_over_2 = biguint_to_u64_vec((&modulus - BigUint::from_str("1").unwrap()) >> 1, limbs);
|
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);
|
||||||
|
|
||||||
quote!{
|
quote!{
|
||||||
impl ::ff::SqrtField for #name {
|
impl ::ff::SqrtField for #name {
|
||||||
fn sqrt(&self) -> Option<Self> {
|
fn sqrt(&self) -> Option<Self> {
|
||||||
// Tonelli-Shank's algorithm for q mod 16 = 1
|
// Tonelli-Shank's algorithm for q mod 16 = 1
|
||||||
// https://eprint.iacr.org/2012/685.pdf (page 12, algorithm 5)
|
// https://eprint.iacr.org/2012/685.pdf (page 12, algorithm 5)
|
||||||
|
|
||||||
if self.is_zero() {
|
if self.is_zero() {
|
||||||
return Some(*self);
|
return Some(*self);
|
||||||
}
|
|
||||||
|
|
||||||
if self.pow(#mod_minus_1_over_2) != Self::one() {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
let mut c = #name(#repr(#root_of_unity));
|
|
||||||
let mut r = self.pow(#t_plus_1_over_2);
|
|
||||||
let mut t = self.pow(#t);
|
|
||||||
let mut m = #s;
|
|
||||||
|
|
||||||
while t != Self::one() {
|
|
||||||
let mut i = 1;
|
|
||||||
{
|
|
||||||
let mut t2i = t;
|
|
||||||
t2i.square();
|
|
||||||
loop {
|
|
||||||
if t2i == Self::one() {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
t2i.square();
|
|
||||||
i += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _ in 0..(m - i - 1) {
|
|
||||||
c.square();
|
|
||||||
}
|
|
||||||
r.mul_assign(&c);
|
|
||||||
c.square();
|
|
||||||
t.mul_assign(&c);
|
|
||||||
m = i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(r)
|
if self.pow(#mod_minus_1_over_2) != Self::one() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
let mut c = #name(#repr(#root_of_unity));
|
||||||
|
let mut r = self.pow(#t_plus_1_over_2);
|
||||||
|
let mut t = self.pow(#t);
|
||||||
|
let mut m = #s;
|
||||||
|
|
||||||
|
while t != Self::one() {
|
||||||
|
let mut i = 1;
|
||||||
|
{
|
||||||
|
let mut t2i = t;
|
||||||
|
t2i.square();
|
||||||
|
loop {
|
||||||
|
if t2i == Self::one() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
t2i.square();
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _ in 0..(m - i - 1) {
|
||||||
|
c.square();
|
||||||
|
}
|
||||||
|
r.mul_assign(&c);
|
||||||
|
c.square();
|
||||||
|
t.mul_assign(&c);
|
||||||
|
m = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(r)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
} else {
|
quote!{}
|
||||||
quote!{}
|
};
|
||||||
};
|
|
||||||
|
|
||||||
// Compute R^2 mod m
|
// Compute R^2 mod m
|
||||||
let r2 = biguint_to_u64_vec((&r * &r) % &modulus, limbs);
|
let r2 = biguint_to_u64_vec((&r * &r) % &modulus, 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)
|
||||||
.chain((0..limbs).map(|_| quote!{0})),
|
.map(|i| quote!{ (self.0).0[#i] })
|
||||||
","
|
.chain((0..limbs).map(|_| quote!{0})),
|
||||||
|
",",
|
||||||
);
|
);
|
||||||
|
|
||||||
quote!{
|
quote!{
|
||||||
|
|||||||
59
src/lib.rs
59
src/lib.rs
@@ -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'));
|
||||||
|
|||||||
Reference in New Issue
Block a user