1
0
Fork 0
mirror of synced 2025-09-24 04:40:05 +00:00
ZoKrates/zokrates_field/src/lib.rs

626 lines
21 KiB
Rust

//
// @file field.rs
// @author Dennis Kuhnert <dennis.kuhnert@campus.tu-berlin.de>
// @author Jacob Eberhardt <jacob.eberhardt@tu-berlin.de>
// @date 2017
extern crate num_bigint;
#[cfg(feature = "bellman")]
use bellman_ce::pairing::{ff::ScalarEngine, Engine};
use num_bigint::BigUint;
use num_traits::{CheckedDiv, One, Zero};
use serde::{Deserialize, Serialize};
use std::convert::{From, TryFrom};
use std::fmt;
use std::fmt::{Debug, Display};
use std::hash::Hash;
use std::ops::{Add, Div, Mul, Sub};
pub trait Pow<RHS> {
type Output;
fn pow(self, _: RHS) -> Self::Output;
}
#[cfg(feature = "bellman")]
pub trait BellmanFieldExtensions {
/// An associated type to be able to operate with Bellman ff traits
type BellmanEngine: Engine;
fn from_bellman(e: <Self::BellmanEngine as ScalarEngine>::Fr) -> Self;
fn into_bellman(self) -> <Self::BellmanEngine as ScalarEngine>::Fr;
fn new_fq2(c0: &str, c1: &str) -> <Self::BellmanEngine as Engine>::Fqe;
}
pub trait ArkFieldExtensions {
/// An associated type to be able to operate with ark ff traits
type ArkEngine: ark_ec::PairingEngine;
fn from_ark(e: <Self::ArkEngine as ark_ec::PairingEngine>::Fr) -> Self;
fn into_ark(self) -> <Self::ArkEngine as ark_ec::PairingEngine>::Fr;
}
pub struct FieldParseError;
impl fmt::Debug for FieldParseError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Failed to parse to field element")
}
}
pub trait Field:
From<i32>
+ From<u32>
+ From<usize>
+ From<u128>
+ TryFrom<BigUint, Error = ()>
+ Zero
+ One
+ Clone
+ PartialEq
+ Eq
+ Hash
+ PartialOrd
+ Ord
+ Display
+ Debug
+ Default
+ Hash
+ Add<Self, Output = Self>
+ for<'a> Add<&'a Self, Output = Self>
+ Sub<Self, Output = Self>
+ for<'a> Sub<&'a Self, Output = Self>
+ Mul<Self, Output = Self>
+ for<'a> Mul<&'a Self, Output = Self>
+ CheckedDiv
+ Div<Self, Output = Self>
+ for<'a> Div<&'a Self, Output = Self>
+ Pow<usize, Output = Self>
+ for<'a> Deserialize<'a>
+ Serialize
+ num_traits::CheckedAdd
+ num_traits::CheckedMul
{
/// Returns this `Field`'s contents as little-endian byte vector
fn to_byte_vector(&self) -> Vec<u8>;
/// Returns an element of this `Field` from a little-endian byte vector
fn from_byte_vector(_: Vec<u8>) -> Self;
/// Returns this `Field`'s contents as decimal string
fn to_dec_string(&self) -> String;
/// Returns the multiplicative inverse, i.e.: self * self.inverse_mul() = Self::one()
fn inverse_mul(&self) -> Option<Self>;
/// Returns the smallest value that can be represented by this field type.
fn min_value() -> Self;
/// Returns the largest value that can be represented by this field type.
fn max_value() -> Self;
/// Returns the largest value `m` such that there exist a number of bits `n` so that any value smaller or equal to
/// m` has a single `n`-bit decomposition
fn max_unique_value() -> Self;
/// Returns the number of bits required to represent any element of this field type.
fn get_required_bits() -> usize;
/// Tries to parse a string into this representation
fn try_from_dec_str(s: &str) -> Result<Self, FieldParseError>;
fn try_from_str(s: &str, radix: u32) -> Result<Self, FieldParseError>;
/// Returns a decimal string representing a the member of the equivalence class of this `Field` in Z/pZ
/// which lies in [-(p-1)/2, (p-1)/2]
fn to_compact_dec_string(&self) -> String;
/// Returns the size of the field as a decimal string
fn id() -> [u8; 4];
/// the name of the curve associated with this field
fn name() -> &'static str;
/// Gets the number of bits
fn bits(&self) -> u32;
/// Returns this `Field`'s largest value as a big-endian bit vector
/// Always returns `Self::get_required_bits()` elements
fn bit_vector_be(&self) -> Vec<bool> {
fn bytes_to_bits(bytes: &[u8]) -> Vec<bool> {
bytes
.iter()
.flat_map(|&v| (0..8).rev().map(move |i| (v >> i) & 1 == 1))
.collect()
}
let field_bytes_le = self.to_byte_vector();
// reverse for big-endianess
let field_bytes_be = field_bytes_le.into_iter().rev().collect::<Vec<u8>>();
let field_bits_be = bytes_to_bits(&field_bytes_be);
let field_bits_be: Vec<_> = (0..Self::get_required_bits()
.saturating_sub(field_bits_be.len()))
.map(|_| &false)
.chain(
&field_bits_be[field_bits_be
.len()
.saturating_sub(Self::get_required_bits())..],
)
.cloned()
.collect();
assert_eq!(field_bits_be.len(), Self::get_required_bits());
field_bits_be
}
/// Returns the value as a BigUint
fn to_biguint(&self) -> BigUint;
}
#[macro_use]
mod prime_field {
macro_rules! prime_field {
($name:expr, $v:ty) => {
use crate::{Field, FieldParseError, Pow};
use ark_ff::{Field as ArkField, PrimeField};
use num_bigint::BigUint;
use num_traits::{CheckedDiv, One, Zero};
use serde::de::{self, Visitor};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::convert::From;
use std::convert::TryFrom;
use std::fmt;
use std::fmt::{Debug, Display};
use std::ops::{Add, Div, Mul, Sub};
type Fr = <$v as ark_ec::PairingEngine>::Fr;
#[derive(PartialEq, PartialOrd, Clone, Eq, Ord, Hash)]
pub struct FieldPrime {
v: Fr,
}
impl Field for FieldPrime {
fn bits(&self) -> u32 {
use ark_ff::BigInteger;
let bits = self.v.into_repr().to_bits_be();
let mut size = bits.len();
for bit in bits {
if !bit {
size -= 1;
} else {
break;
}
}
std::cmp::max(size as u32, 1)
}
fn to_biguint(&self) -> BigUint {
use ark_ff::BigInteger;
BigUint::from_bytes_le(&self.v.into_repr().to_bytes_le())
}
fn to_byte_vector(&self) -> Vec<u8> {
use ark_ff::BigInteger;
self.v.into_repr().to_bytes_le()
}
fn from_byte_vector(bytes: Vec<u8>) -> Self {
use ark_ff::FromBytes;
FieldPrime {
v: Fr::from(<Fr as PrimeField>::BigInt::read(&bytes[..]).unwrap()),
}
}
fn to_dec_string(&self) -> String {
self.to_string()
}
fn inverse_mul(&self) -> Option<Self> {
use ark_ff::Field;
Some(FieldPrime {
v: self.v.inverse()?,
})
}
fn min_value() -> FieldPrime {
FieldPrime { v: Fr::from(0u32) }
}
fn max_value() -> FieldPrime {
FieldPrime {
v: Fr::from(0u32) - Fr::from(1u32),
}
}
fn max_unique_value() -> FieldPrime {
FieldPrime {
v: Fr::from(2u32).pow([Self::get_required_bits() as u64 - 1])
- Fr::from(1u32),
}
}
fn get_required_bits() -> usize {
use ark_ff::FpParameters;
<Fr as PrimeField>::Params::MODULUS_BITS as usize
}
fn try_from_dec_str(s: &str) -> Result<Self, FieldParseError> {
use std::str::FromStr;
Ok(FieldPrime {
v: Fr::from_str(s).map_err(|_| FieldParseError)?,
})
}
fn try_from_str(s: &str, radix: u32) -> Result<Self, FieldParseError> {
let x = BigUint::parse_bytes(s.as_bytes(), radix).ok_or(FieldParseError)?;
FieldPrime::try_from(x).map_err(|_| FieldParseError)
}
fn to_compact_dec_string(&self) -> String {
//values up to (p-1)/2 included are represented as positive, values between (p+1)/2 and p-1 as represented as negative by subtracting p
if self.v.into_repr() <= Fr::modulus_minus_one_div_two() {
format!("{}", self.to_string())
} else {
format!(
"(-{})",
(FieldPrime::max_value() - self + FieldPrime::one()).to_string()
)
}
}
fn id() -> [u8; 4] {
let mut res = [0u8; 4];
use ark_ff::BigInteger;
use ark_ff::FpParameters;
use sha2::{Digest, Sha256};
let hash = Sha256::digest(&<Fr as PrimeField>::Params::MODULUS.to_bytes_le());
for i in 0..4 {
res[i] = hash[i];
}
res
}
fn name() -> &'static str {
$name
}
}
impl Default for FieldPrime {
fn default() -> Self {
FieldPrime { v: Fr::from(0u32) }
}
}
impl Display for FieldPrime {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.to_biguint())
}
}
impl Debug for FieldPrime {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.to_biguint())
}
}
impl From<i32> for FieldPrime {
fn from(num: i32) -> Self {
if num < 0 {
FieldPrime {
v: Fr::zero() - Fr::from((-num) as u32),
}
} else {
FieldPrime {
v: Fr::from(num as u32),
}
}
}
}
impl From<u32> for FieldPrime {
fn from(num: u32) -> Self {
FieldPrime { v: Fr::from(num) }
}
}
impl From<usize> for FieldPrime {
fn from(num: usize) -> Self {
FieldPrime {
v: Fr::from(num as u128),
}
}
}
impl From<u128> for FieldPrime {
fn from(num: u128) -> Self {
FieldPrime { v: Fr::from(num) }
}
}
impl TryFrom<BigUint> for FieldPrime {
type Error = ();
fn try_from(value: BigUint) -> Result<Self, ()> {
match value <= Self::max_value().to_biguint() {
true => {
use std::str::FromStr;
Ok(FieldPrime {
v: Fr::from_str(&value.to_string()).unwrap(),
})
}
false => Err(()),
}
}
}
impl Zero for FieldPrime {
fn zero() -> FieldPrime {
FieldPrime { v: Fr::zero() }
}
fn is_zero(&self) -> bool {
self.v.is_zero()
}
}
impl One for FieldPrime {
fn one() -> FieldPrime {
FieldPrime { v: Fr::one() }
}
}
impl Add<FieldPrime> for FieldPrime {
type Output = FieldPrime;
fn add(self, other: FieldPrime) -> FieldPrime {
FieldPrime {
v: self.v + other.v,
}
}
}
impl<'a> Add<&'a FieldPrime> for FieldPrime {
type Output = FieldPrime;
fn add(self, other: &FieldPrime) -> FieldPrime {
FieldPrime {
v: self.v + other.v,
}
}
}
impl Sub<FieldPrime> for FieldPrime {
type Output = FieldPrime;
fn sub(self, other: FieldPrime) -> FieldPrime {
FieldPrime {
v: self.v - other.v,
}
}
}
impl<'a> Sub<&'a FieldPrime> for FieldPrime {
type Output = FieldPrime;
fn sub(self, other: &FieldPrime) -> FieldPrime {
FieldPrime {
v: self.v - other.v,
}
}
}
impl Mul<FieldPrime> for FieldPrime {
type Output = FieldPrime;
fn mul(self, other: FieldPrime) -> FieldPrime {
FieldPrime {
v: self.v * other.v,
}
}
}
impl<'a> Mul<&'a FieldPrime> for FieldPrime {
type Output = FieldPrime;
fn mul(self, other: &FieldPrime) -> FieldPrime {
FieldPrime {
v: self.v * other.v,
}
}
}
impl CheckedDiv for FieldPrime {
fn checked_div(&self, other: &FieldPrime) -> Option<FieldPrime> {
if other.v == Fr::zero() {
None
} else {
Some(FieldPrime {
v: self.v / other.v,
})
}
}
}
impl Div<FieldPrime> for FieldPrime {
type Output = FieldPrime;
fn div(self, other: FieldPrime) -> FieldPrime {
self.checked_div(&other).unwrap()
}
}
impl<'a> Div<&'a FieldPrime> for FieldPrime {
type Output = FieldPrime;
fn div(self, other: &FieldPrime) -> FieldPrime {
self.checked_div(&other).unwrap()
}
}
impl Pow<usize> for FieldPrime {
type Output = FieldPrime;
fn pow(self, exp: usize) -> FieldPrime {
FieldPrime {
v: self.v.pow(&[exp as u64]),
}
}
}
impl num_traits::CheckedAdd for FieldPrime {
fn checked_add(&self, other: &Self) -> Option<Self> {
let bound = Self::max_unique_value();
assert!(self <= &bound);
assert!(other <= &bound);
let left = self.to_biguint();
let right = other.to_biguint();
let big_res = left + right;
// we only go up to 2**(bitwidth - 1) because after that we lose uniqueness of bit decomposition
if big_res > bound.to_biguint() {
None
} else {
Some(self.clone() + other)
}
}
}
impl num_traits::CheckedMul for FieldPrime {
fn checked_mul(&self, other: &Self) -> Option<Self> {
let bound = Self::max_unique_value();
assert!(self <= &bound);
assert!(other <= &bound);
let left = self.to_biguint();
let right = other.to_biguint();
let big_res = left * right;
// we only go up to 2**(bitwidth - 1) because after that we lose uniqueness of bit decomposition
if big_res > bound.to_biguint() {
None
} else {
Some(self.clone() * other)
}
}
}
impl Serialize for FieldPrime {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
use ark_serialize::CanonicalSerialize;
use serde::ser::Error;
let mut data: Vec<u8> = vec![];
self.v
.serialize(&mut data)
.map_err(|e| S::Error::custom(e.to_string()))?;
serializer.serialize_bytes(&data)
}
}
struct FieldVisitor;
use serde::de::SeqAccess;
impl<'de> Visitor<'de> for FieldVisitor {
type Value = FieldPrime;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("an ark field element")
}
fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
where
E: de::Error,
{
use ark_serialize::CanonicalDeserialize;
let value: Fr = Fr::deserialize(value).map_err(|e| E::custom(e.to_string()))?;
Ok(FieldPrime { v: value })
}
fn visit_byte_buf<E>(self, value: Vec<u8>) -> Result<Self::Value, E>
where
E: de::Error,
{
self.visit_bytes(&value[..])
}
fn visit_seq<A>(self, value: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let mut value = value;
let mut elements = vec![];
while let Some(v) = value.next_element()? {
elements.push(v);
}
self.visit_bytes(&elements[..])
}
}
impl<'de> Deserialize<'de> for FieldPrime {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_bytes(FieldVisitor)
}
}
};
}
#[cfg(feature = "bellman")]
macro_rules! bellman_extensions {
($bellman_type:ty, $fq2_type:ident) => {
use crate::BellmanFieldExtensions;
use bellman_ce::pairing::ff::ScalarEngine;
impl BellmanFieldExtensions for FieldPrime {
type BellmanEngine = $bellman_type;
fn from_bellman(e: <Self::BellmanEngine as ScalarEngine>::Fr) -> Self {
use bellman_ce::pairing::ff::{PrimeField, PrimeFieldRepr};
let mut res: Vec<u8> = vec![];
e.into_repr().write_le(&mut res).unwrap();
Self::from_byte_vector(res)
}
fn into_bellman(self) -> <Self::BellmanEngine as ScalarEngine>::Fr {
use bellman_ce::pairing::ff::PrimeField;
let s = self.to_dec_string();
<Self::BellmanEngine as ScalarEngine>::Fr::from_str(&s).unwrap()
}
fn new_fq2(
c0: &str,
c1: &str,
) -> <Self::BellmanEngine as bellman_ce::pairing::Engine>::Fqe {
$fq2_type {
c0: bellman_ce::pairing::from_hex(c0).unwrap(),
c1: bellman_ce::pairing::from_hex(c1).unwrap(),
}
}
}
};
}
macro_rules! ark_extensions {
($ark_type:ty) => {
use crate::ArkFieldExtensions;
impl ArkFieldExtensions for FieldPrime {
type ArkEngine = $ark_type;
fn from_ark(e: <Self::ArkEngine as ark_ec::PairingEngine>::Fr) -> Self {
Self { v: e }
}
fn into_ark(self) -> <Self::ArkEngine as ark_ec::PairingEngine>::Fr {
self.v
}
}
};
}
}
pub mod bls12_377;
pub mod bls12_381;
pub mod bn128;
pub mod bw6_761;
pub use bls12_377::FieldPrime as Bls12_377Field;
pub use bls12_381::FieldPrime as Bls12_381Field;
pub use bn128::FieldPrime as Bn128Field;
pub use bw6_761::FieldPrime as Bw6_761Field;