commit
5ef0b8e5ee
12 changed files with 329 additions and 355 deletions
13
Cargo.lock
generated
13
Cargo.lock
generated
|
@ -67,6 +67,17 @@ dependencies = [
|
||||||
"ark-std",
|
"ark-std",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ark-bls12-381"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "70e1c2ad76c4f725520440b981df3ce2d635f2baa1122750c757c0cf0f3d4b74"
|
||||||
|
dependencies = [
|
||||||
|
"ark-ec",
|
||||||
|
"ark-ff",
|
||||||
|
"ark-std",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ark-bn254"
|
name = "ark-bn254"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
|
@ -2501,10 +2512,12 @@ name = "zokrates_field"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ark-bls12-377",
|
"ark-bls12-377",
|
||||||
|
"ark-bls12-381",
|
||||||
"ark-bn254",
|
"ark-bn254",
|
||||||
"ark-bw6-761",
|
"ark-bw6-761",
|
||||||
"ark-ec",
|
"ark-ec",
|
||||||
"ark-ff",
|
"ark-ff",
|
||||||
|
"ark-serialize",
|
||||||
"bellman_ce",
|
"bellman_ce",
|
||||||
"bincode",
|
"bincode",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
|
|
1
changelogs/unreleased/1061-schaeff
Normal file
1
changelogs/unreleased/1061-schaeff
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Use ark-ff under the hood for optimized field operations
|
|
@ -13,7 +13,7 @@ libsnark = ["cc", "cmake", "git2"]
|
||||||
bellman = ["bellman_ce", "pairing_ce", "ff_ce", "zokrates_field/bellman"]
|
bellman = ["bellman_ce", "pairing_ce", "ff_ce", "zokrates_field/bellman"]
|
||||||
wasm = ["bellman_ce/nolog", "bellman_ce/wasm"]
|
wasm = ["bellman_ce/nolog", "bellman_ce/wasm"]
|
||||||
multicore = ["bellman_ce/multicore"]
|
multicore = ["bellman_ce/multicore"]
|
||||||
ark = ["ark-ff", "ark-ec", "ark-bn254", "ark-bls12-377", "ark-bw6-761", "ark-gm17", "ark-serialize", "ark-relations", "ark-marlin", "ark-poly", "ark-poly-commit", "zokrates_field/ark", "sha2"]
|
ark = ["ark-ff", "ark-ec", "ark-bn254", "ark-bls12-377", "ark-bw6-761", "ark-gm17", "ark-serialize", "ark-relations", "ark-marlin", "ark-poly", "ark-poly-commit", "sha2"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
|
|
|
@ -5,8 +5,7 @@ authors = ["Thibaut Schaeffer <thibaut@schaeff.fr>", "Guillaume Ballet <gballet@
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["ark", "bellman"]
|
default = ["bellman"]
|
||||||
ark = ["ark-ff", "ark-ec", "ark-bn254", "ark-bls12-377", "ark-bw6-761"]
|
|
||||||
bellman = ["bellman_ce"]
|
bellman = ["bellman_ce"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
@ -23,11 +22,13 @@ num-integer = { version = "0.1", default-features = false }
|
||||||
bellman_ce = { version = "^0.3", default-features = false, optional = true }
|
bellman_ce = { version = "^0.3", default-features = false, optional = true }
|
||||||
|
|
||||||
# ark
|
# ark
|
||||||
ark-ff = { version = "^0.2.0", default-features = false, optional = true }
|
ark-ec = { version = "^0.2.0", default-features = false }
|
||||||
ark-ec = { version = "^0.2.0", default-features = false, optional = true }
|
ark-ff = { version = "^0.2.0", default-features = false }
|
||||||
ark-bn254 = { version = "^0.2.0", features = ["curve"], default-features = false, optional = true }
|
ark-bn254 = { version = "^0.2.0", features = ["curve"], default-features = false }
|
||||||
ark-bls12-377 = { version = "^0.2.0", features = ["curve"], default-features = false, optional = true }
|
ark-bls12-377 = { version = "^0.2.0", features = ["curve"], default-features = false }
|
||||||
ark-bw6-761 = { version = "^0.2.0", default-features = false, optional = true }
|
ark-bls12-381 = { version = "^0.2.0", features = ["curve"], default-features = false }
|
||||||
|
ark-bw6-761 = { version = "^0.2.0", default-features = false }
|
||||||
|
ark-serialize = { version = "^0.2.0", default-features = false }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
rand = "0.4"
|
rand = "0.4"
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
prime_field!(
|
use ark_bls12_377::Bls12_377;
|
||||||
b"8444461749428370424248824938781546531375899335154063827935233455917409239041",
|
|
||||||
"bls12_377"
|
|
||||||
);
|
|
||||||
|
|
||||||
#[cfg(feature = "ark")]
|
prime_field!("bls12_377", Bls12_377);
|
||||||
ark_extensions!(ark_bls12_377::Bls12_377);
|
|
||||||
|
ark_extensions!(Bls12_377);
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
prime_field!(
|
use ark_bls12_381::Bls12_381;
|
||||||
b"52435875175126190479447740508185965837690552500527637822603658699938581184513",
|
|
||||||
"bls12_381"
|
prime_field!("bls12_381", Bls12_381);
|
||||||
);
|
|
||||||
|
ark_extensions!(Bls12_381);
|
||||||
|
|
||||||
#[cfg(feature = "bellman")]
|
#[cfg(feature = "bellman")]
|
||||||
use bellman_ce::pairing::bls12_381::{Bls12, Fq2};
|
use bellman_ce::pairing::bls12_381::{Bls12, Fq2};
|
||||||
|
|
|
@ -1,18 +1,14 @@
|
||||||
prime_field!(
|
use ark_bn254::Bn254;
|
||||||
b"21888242871839275222246405745257275088548364400416034343698204186575808495617",
|
|
||||||
"bn128"
|
prime_field!("bn128", Bn254);
|
||||||
);
|
|
||||||
|
ark_extensions!(Bn254);
|
||||||
|
|
||||||
#[cfg(feature = "bellman")]
|
#[cfg(feature = "bellman")]
|
||||||
use bellman_ce::pairing::bn256::{Bn256, Fq2};
|
use bellman_ce::pairing::bn256::{Bn256, Fq2};
|
||||||
#[cfg(feature = "bellman")]
|
#[cfg(feature = "bellman")]
|
||||||
bellman_extensions!(Bn256, Fq2);
|
bellman_extensions!(Bn256, Fq2);
|
||||||
|
|
||||||
#[cfg(feature = "ark")]
|
|
||||||
use ark_bn254::Bn254;
|
|
||||||
#[cfg(feature = "ark")]
|
|
||||||
ark_extensions!(Bn254);
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -37,157 +33,139 @@ mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn positive_number() {
|
|
||||||
assert_eq!(
|
|
||||||
"1234245612".parse::<BigInt>().unwrap(),
|
|
||||||
FieldPrime::from("1234245612").value
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn negative_number() {
|
|
||||||
assert_eq!(
|
|
||||||
P.checked_sub(&"12".parse::<BigInt>().unwrap()).unwrap(),
|
|
||||||
FieldPrime::from("-12").value
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn addition() {
|
fn addition() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
"65484493".parse::<BigInt>().unwrap(),
|
FieldPrime::from("65484493"),
|
||||||
(FieldPrime::from("65416358") + FieldPrime::from("68135")).value
|
FieldPrime::from("65416358") + FieldPrime::from("68135")
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
"65484493".parse::<BigInt>().unwrap(),
|
FieldPrime::from("65484493"),
|
||||||
(FieldPrime::from("65416358") + &FieldPrime::from("68135")).value
|
FieldPrime::from("65416358") + &FieldPrime::from("68135")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn addition_negative_small() {
|
fn addition_negative_small() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
"3".parse::<BigInt>().unwrap(),
|
FieldPrime::from("3"),
|
||||||
(FieldPrime::from("5") + FieldPrime::from("-2")).value
|
FieldPrime::from("5") + FieldPrime::from(-2)
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
"3".parse::<BigInt>().unwrap(),
|
FieldPrime::from("3"),
|
||||||
(FieldPrime::from("5") + &FieldPrime::from("-2")).value
|
FieldPrime::from("5") + &FieldPrime::from(-2)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn addition_negative() {
|
fn addition_negative() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
"65348223".parse::<BigInt>().unwrap(),
|
FieldPrime::from("65348223"),
|
||||||
(FieldPrime::from("65416358") + FieldPrime::from("-68135")).value
|
FieldPrime::from("65416358") + FieldPrime::from(-68135)
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
"65348223".parse::<BigInt>().unwrap(),
|
FieldPrime::from("65348223"),
|
||||||
(FieldPrime::from("65416358") + &FieldPrime::from("-68135")).value
|
FieldPrime::from("65416358") + &FieldPrime::from(-68135)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn subtraction() {
|
fn subtraction() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
"65348223".parse::<BigInt>().unwrap(),
|
FieldPrime::from("65348223"),
|
||||||
(FieldPrime::from("65416358") - FieldPrime::from("68135")).value
|
FieldPrime::from("65416358") - FieldPrime::from("68135")
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
"65348223".parse::<BigInt>().unwrap(),
|
FieldPrime::from("65348223"),
|
||||||
(FieldPrime::from("65416358") - &FieldPrime::from("68135")).value
|
FieldPrime::from("65416358") - &FieldPrime::from("68135")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn subtraction_negative() {
|
fn subtraction_negative() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
"65484493".parse::<BigInt>().unwrap(),
|
FieldPrime::from("65484493"),
|
||||||
(FieldPrime::from("65416358") - FieldPrime::from("-68135")).value
|
FieldPrime::from("65416358") - FieldPrime::from(-68135)
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
"65484493".parse::<BigInt>().unwrap(),
|
FieldPrime::from("65484493"),
|
||||||
(FieldPrime::from("65416358") - &FieldPrime::from("-68135")).value
|
FieldPrime::from("65416358") - &FieldPrime::from(-68135)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn subtraction_overflow() {
|
fn subtraction_overflow() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
"21888242871839275222246405745257275088548364400416034343698204186575743147394"
|
FieldPrime::from(
|
||||||
.parse::<BigInt>()
|
"21888242871839275222246405745257275088548364400416034343698204186575743147394"
|
||||||
.unwrap(),
|
),
|
||||||
(FieldPrime::from("68135") - FieldPrime::from("65416358")).value
|
FieldPrime::from("68135") - FieldPrime::from("65416358")
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
"21888242871839275222246405745257275088548364400416034343698204186575743147394"
|
FieldPrime::from(
|
||||||
.parse::<BigInt>()
|
"21888242871839275222246405745257275088548364400416034343698204186575743147394"
|
||||||
.unwrap(),
|
),
|
||||||
(FieldPrime::from("68135") - &FieldPrime::from("65416358")).value
|
FieldPrime::from("68135") - &FieldPrime::from("65416358")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn multiplication() {
|
fn multiplication() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
"13472".parse::<BigInt>().unwrap(),
|
FieldPrime::from("13472"),
|
||||||
(FieldPrime::from("32") * FieldPrime::from("421")).value
|
FieldPrime::from("32") * FieldPrime::from("421")
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
"13472".parse::<BigInt>().unwrap(),
|
FieldPrime::from("13472"),
|
||||||
(FieldPrime::from("32") * &FieldPrime::from("421")).value
|
FieldPrime::from("32") * &FieldPrime::from("421")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn multiplication_negative() {
|
fn multiplication_negative() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
"21888242871839275222246405745257275088548364400416034343698204186575808014369"
|
FieldPrime::from(
|
||||||
.parse::<BigInt>()
|
"21888242871839275222246405745257275088548364400416034343698204186575808014369"
|
||||||
.unwrap(),
|
),
|
||||||
(FieldPrime::from("54") * FieldPrime::from("-8912")).value
|
FieldPrime::from("54") * FieldPrime::from(-8912)
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
"21888242871839275222246405745257275088548364400416034343698204186575808014369"
|
FieldPrime::from(
|
||||||
.parse::<BigInt>()
|
"21888242871839275222246405745257275088548364400416034343698204186575808014369"
|
||||||
.unwrap(),
|
),
|
||||||
(FieldPrime::from("54") * &FieldPrime::from("-8912")).value
|
FieldPrime::from("54") * &FieldPrime::from(-8912)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn multiplication_two_negative() {
|
fn multiplication_two_negative() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
"648".parse::<BigInt>().unwrap(),
|
FieldPrime::from("648"),
|
||||||
(FieldPrime::from("-54") * FieldPrime::from("-12")).value
|
FieldPrime::from(-54) * FieldPrime::from(-12)
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
"648".parse::<BigInt>().unwrap(),
|
FieldPrime::from("648"),
|
||||||
(FieldPrime::from("-54") * &FieldPrime::from("-12")).value
|
FieldPrime::from(-54) * &FieldPrime::from(-12)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn multiplication_overflow() {
|
fn multiplication_overflow() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
"6042471409729479866150380306128222617399890671095126975526159292198160466142"
|
FieldPrime::from(
|
||||||
.parse::<BigInt>()
|
"6042471409729479866150380306128222617399890671095126975526159292198160466142"
|
||||||
.unwrap(),
|
),
|
||||||
(FieldPrime::from(
|
FieldPrime::from(
|
||||||
"21888242871839225222246405785257275088694311157297823662689037894645225727"
|
"21888242871839225222246405785257275088694311157297823662689037894645225727"
|
||||||
) * FieldPrime::from("218882428715392752222464057432572755886923"))
|
) * FieldPrime::from("218882428715392752222464057432572755886923")
|
||||||
.value
|
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
"6042471409729479866150380306128222617399890671095126975526159292198160466142"
|
FieldPrime::from(
|
||||||
.parse::<BigInt>()
|
"6042471409729479866150380306128222617399890671095126975526159292198160466142"
|
||||||
.unwrap(),
|
),
|
||||||
(FieldPrime::from(
|
FieldPrime::from(
|
||||||
"21888242871839225222246405785257275088694311157297823662689037894645225727"
|
"21888242871839225222246405785257275088694311157297823662689037894645225727"
|
||||||
) * &FieldPrime::from("218882428715392752222464057432572755886923"))
|
) * &FieldPrime::from("218882428715392752222464057432572755886923")
|
||||||
.value
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,6 +181,36 @@ mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn required_bits() {
|
||||||
|
assert_eq!(FieldPrime::get_required_bits(), 254);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn bits() {
|
||||||
|
assert_eq!(FieldPrime::from(0).bits(), 1);
|
||||||
|
assert_eq!(FieldPrime::from(1).bits(), 1);
|
||||||
|
assert_eq!(FieldPrime::from(2).bits(), 2);
|
||||||
|
assert_eq!(FieldPrime::from(3).bits(), 2);
|
||||||
|
assert_eq!(FieldPrime::from(4).bits(), 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn to_biguint() {
|
||||||
|
assert_eq!(
|
||||||
|
FieldPrime::try_from(FieldPrime::from(2).to_biguint()),
|
||||||
|
Ok(FieldPrime::from(2))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
FieldPrime::try_from(FieldPrime::from(0).to_biguint()),
|
||||||
|
Ok(FieldPrime::from(0))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
FieldPrime::try_from(FieldPrime::max_value().to_biguint()),
|
||||||
|
Ok(FieldPrime::max_value())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn division_negative() {
|
fn division_negative() {
|
||||||
let res = FieldPrime::from(-54) / FieldPrime::from(12);
|
let res = FieldPrime::from(-54) / FieldPrime::from(12);
|
||||||
|
@ -218,8 +226,8 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn pow_usize() {
|
fn pow_usize() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
"614787626176508399616".parse::<BigInt>().unwrap(),
|
FieldPrime::from("614787626176508399616"),
|
||||||
(FieldPrime::from("54").pow(12)).value
|
FieldPrime::from("54").pow(12)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,72 +283,6 @@ mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn bigint_assertions() {
|
|
||||||
let x = BigInt::parse_bytes(b"65", 10).unwrap();
|
|
||||||
assert_eq!(&x + &x, BigInt::parse_bytes(b"130", 10).unwrap());
|
|
||||||
assert_eq!(
|
|
||||||
"1".parse::<BigInt>().unwrap(),
|
|
||||||
"3".parse::<BigInt>()
|
|
||||||
.unwrap()
|
|
||||||
.div_floor(&"2".parse::<BigInt>().unwrap())
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
"-2".parse::<BigInt>().unwrap(),
|
|
||||||
"-3".parse::<BigInt>()
|
|
||||||
.unwrap()
|
|
||||||
.div_floor(&"2".parse::<BigInt>().unwrap())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_extended_euclid() {
|
|
||||||
assert_eq!(
|
|
||||||
(
|
|
||||||
ToBigInt::to_bigint(&1).unwrap(),
|
|
||||||
ToBigInt::to_bigint(&-9).unwrap(),
|
|
||||||
ToBigInt::to_bigint(&47).unwrap()
|
|
||||||
),
|
|
||||||
extended_euclid(
|
|
||||||
&ToBigInt::to_bigint(&120).unwrap(),
|
|
||||||
&ToBigInt::to_bigint(&23).unwrap()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
(
|
|
||||||
ToBigInt::to_bigint(&2).unwrap(),
|
|
||||||
ToBigInt::to_bigint(&2).unwrap(),
|
|
||||||
ToBigInt::to_bigint(&-11).unwrap()
|
|
||||||
),
|
|
||||||
extended_euclid(
|
|
||||||
&ToBigInt::to_bigint(&122).unwrap(),
|
|
||||||
&ToBigInt::to_bigint(&22).unwrap()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
(
|
|
||||||
ToBigInt::to_bigint(&2).unwrap(),
|
|
||||||
ToBigInt::to_bigint(&-9).unwrap(),
|
|
||||||
ToBigInt::to_bigint(&47).unwrap()
|
|
||||||
),
|
|
||||||
extended_euclid(
|
|
||||||
&ToBigInt::to_bigint(&240).unwrap(),
|
|
||||||
&ToBigInt::to_bigint(&46).unwrap()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
let (b, s, _) = extended_euclid(&ToBigInt::to_bigint(&253).unwrap(), &*P);
|
|
||||||
assert_eq!(b, BigInt::one());
|
|
||||||
let s_field = FieldPrime {
|
|
||||||
value: &s - s.div_floor(&*P) * &*P,
|
|
||||||
};
|
|
||||||
assert_eq!(
|
|
||||||
FieldPrime::from(
|
|
||||||
"12717674712096337777352654721552646000065650461901806515903699665717959876900"
|
|
||||||
),
|
|
||||||
s_field
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "bellman")]
|
#[cfg(feature = "bellman")]
|
||||||
mod bellman {
|
mod bellman {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
prime_field!(
|
|
||||||
b"258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458177",
|
|
||||||
"bw6_761"
|
|
||||||
);
|
|
||||||
|
|
||||||
#[cfg(feature = "ark")]
|
|
||||||
use ark_bw6_761::BW6_761;
|
use ark_bw6_761::BW6_761;
|
||||||
#[cfg(feature = "ark")]
|
|
||||||
|
prime_field!("bw6_761", BW6_761);
|
||||||
|
|
||||||
ark_extensions!(BW6_761);
|
ark_extensions!(BW6_761);
|
||||||
|
|
|
@ -6,9 +6,6 @@
|
||||||
|
|
||||||
extern crate num_bigint;
|
extern crate num_bigint;
|
||||||
|
|
||||||
#[cfg(feature = "ark")]
|
|
||||||
use ark_ec::PairingEngine;
|
|
||||||
|
|
||||||
#[cfg(feature = "bellman")]
|
#[cfg(feature = "bellman")]
|
||||||
use bellman_ce::pairing::{ff::ScalarEngine, Engine};
|
use bellman_ce::pairing::{ff::ScalarEngine, Engine};
|
||||||
|
|
||||||
|
@ -36,10 +33,9 @@ pub trait BellmanFieldExtensions {
|
||||||
fn new_fq2(c0: &str, c1: &str) -> <Self::BellmanEngine as Engine>::Fqe;
|
fn new_fq2(c0: &str, c1: &str) -> <Self::BellmanEngine as Engine>::Fqe;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "ark")]
|
|
||||||
pub trait ArkFieldExtensions {
|
pub trait ArkFieldExtensions {
|
||||||
/// An associated type to be able to operate with ark ff traits
|
/// An associated type to be able to operate with ark ff traits
|
||||||
type ArkEngine: PairingEngine;
|
type ArkEngine: ark_ec::PairingEngine;
|
||||||
|
|
||||||
fn from_ark(e: <Self::ArkEngine as ark_ec::PairingEngine>::Fr) -> Self;
|
fn from_ark(e: <Self::ArkEngine as ark_ec::PairingEngine>::Fr) -> Self;
|
||||||
fn into_ark(self) -> <Self::ArkEngine as ark_ec::PairingEngine>::Fr;
|
fn into_ark(self) -> <Self::ArkEngine as ark_ec::PairingEngine>::Fr;
|
||||||
|
@ -159,35 +155,44 @@ pub trait Field:
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod prime_field {
|
mod prime_field {
|
||||||
macro_rules! prime_field {
|
macro_rules! prime_field {
|
||||||
($modulus:expr, $name:expr) => {
|
($name:expr, $v:ty) => {
|
||||||
use crate::{Field, FieldParseError, Pow};
|
use crate::{Field, FieldParseError, Pow};
|
||||||
use lazy_static::lazy_static;
|
use ark_ff::{Field as ArkField, PrimeField};
|
||||||
use num_bigint::{BigInt, BigUint, Sign, ToBigInt};
|
use num_bigint::BigUint;
|
||||||
use num_integer::Integer;
|
|
||||||
use num_traits::{CheckedDiv, One, Zero};
|
use num_traits::{CheckedDiv, One, Zero};
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde::de::{self, Visitor};
|
||||||
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
use std::convert::From;
|
use std::convert::From;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::fmt::{Debug, Display};
|
use std::fmt::{Debug, Display};
|
||||||
use std::ops::{Add, Div, Mul, Sub};
|
use std::ops::{Add, Div, Mul, Sub};
|
||||||
|
|
||||||
lazy_static! {
|
type Fr = <$v as ark_ec::PairingEngine>::Fr;
|
||||||
static ref P: BigInt = BigInt::parse_bytes($modulus, 10).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq, PartialOrd, Clone, Eq, Ord, Hash, Serialize, Deserialize)]
|
#[derive(PartialEq, PartialOrd, Clone, Eq, Ord, Hash)]
|
||||||
pub struct FieldPrime {
|
pub struct FieldPrime {
|
||||||
value: BigInt,
|
v: Fr,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Field for FieldPrime {
|
impl Field for FieldPrime {
|
||||||
fn bits(&self) -> u32 {
|
fn bits(&self) -> u32 {
|
||||||
self.value.bits() as 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 {
|
fn to_biguint(&self) -> BigUint {
|
||||||
self.value.to_biguint().unwrap()
|
use ark_ff::BigInteger;
|
||||||
|
BigUint::from_bytes_le(&self.v.into_repr().to_bytes_le())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_bits_be(&self) -> Vec<u8> {
|
fn to_bits_be(&self) -> Vec<u8> {
|
||||||
|
@ -195,78 +200,72 @@ mod prime_field {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_byte_vector(&self) -> Vec<u8> {
|
fn to_byte_vector(&self) -> Vec<u8> {
|
||||||
match self.value.to_biguint() {
|
use ark_ff::BigInteger;
|
||||||
Option::Some(val) => val.to_bytes_le(),
|
self.v.into_repr().to_bytes_le()
|
||||||
Option::None => panic!("Should never happen."),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_byte_vector(bytes: Vec<u8>) -> Self {
|
fn from_byte_vector(bytes: Vec<u8>) -> Self {
|
||||||
let uval = BigUint::from_bytes_le(bytes.as_slice());
|
use ark_ff::FromBytes;
|
||||||
|
|
||||||
FieldPrime {
|
FieldPrime {
|
||||||
value: BigInt::from_biguint(Sign::Plus, uval),
|
v: Fr::from(<Fr as PrimeField>::BigInt::read(&bytes[..]).unwrap()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_dec_string(&self) -> String {
|
fn to_dec_string(&self) -> String {
|
||||||
self.value.to_str_radix(10)
|
self.to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inverse_mul(&self) -> Option<FieldPrime> {
|
fn inverse_mul(&self) -> Option<Self> {
|
||||||
let (b, s, _) = extended_euclid(&self.value, &*P);
|
use ark_ff::Field;
|
||||||
if b == BigInt::one() {
|
Some(FieldPrime {
|
||||||
Some(FieldPrime {
|
v: self.v.inverse()?,
|
||||||
value: &s - s.div_floor(&*P) * &*P,
|
})
|
||||||
})
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn min_value() -> FieldPrime {
|
fn min_value() -> FieldPrime {
|
||||||
FieldPrime {
|
FieldPrime { v: Fr::zero() }
|
||||||
value: ToBigInt::to_bigint(&0).unwrap(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
fn max_value() -> FieldPrime {
|
fn max_value() -> FieldPrime {
|
||||||
FieldPrime {
|
FieldPrime { v: -Fr::one() }
|
||||||
value: &*P - ToBigInt::to_bigint(&1).unwrap(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
fn max_unique_value() -> FieldPrime {
|
fn max_unique_value() -> FieldPrime {
|
||||||
use num_traits::Pow;
|
|
||||||
|
|
||||||
FieldPrime {
|
FieldPrime {
|
||||||
value: BigInt::from(2u32).pow(Self::get_required_bits() - 1) - 1,
|
v: Fr::from(2u32).pow([Self::get_required_bits() as u64 - 1]) - Fr::one(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn get_required_bits() -> usize {
|
fn get_required_bits() -> usize {
|
||||||
(*P).bits()
|
use ark_ff::FpParameters;
|
||||||
|
<Fr as PrimeField>::Params::MODULUS_BITS as usize
|
||||||
}
|
}
|
||||||
fn try_from_dec_str(s: &str) -> Result<Self, FieldParseError> {
|
fn try_from_dec_str(s: &str) -> Result<Self, FieldParseError> {
|
||||||
Self::try_from_str(s, 10)
|
use std::str::FromStr;
|
||||||
}
|
|
||||||
fn try_from_str(s: &str, radix: u32) -> Result<Self, FieldParseError> {
|
|
||||||
let x = BigInt::parse_bytes(s.as_bytes(), radix).ok_or(FieldParseError)?;
|
|
||||||
Ok(FieldPrime {
|
Ok(FieldPrime {
|
||||||
value: &x - x.div_floor(&*P) * &*P,
|
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 {
|
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
|
//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.value <= FieldPrime::max_value().value / 2 {
|
if self.v.into_repr() <= Fr::modulus_minus_one_div_two() {
|
||||||
format!("{}", self.value.to_str_radix(10))
|
format!("{}", self.to_string())
|
||||||
} else {
|
} else {
|
||||||
format!(
|
format!(
|
||||||
"({})",
|
"(-{})",
|
||||||
(&self.value - (FieldPrime::max_value().value + BigInt::one()))
|
(FieldPrime::max_value() - self + FieldPrime::one()).to_string()
|
||||||
.to_str_radix(10)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn id() -> [u8; 4] {
|
fn id() -> [u8; 4] {
|
||||||
let mut res = [0u8; 4];
|
let mut res = [0u8; 4];
|
||||||
|
use ark_ff::BigInteger;
|
||||||
|
use ark_ff::FpParameters;
|
||||||
use sha2::{Digest, Sha256};
|
use sha2::{Digest, Sha256};
|
||||||
let hash = Sha256::digest(&P.to_bytes_le().1);
|
let hash = Sha256::digest(&<Fr as PrimeField>::Params::MODULUS.to_bytes_le());
|
||||||
for i in 0..4 {
|
for i in 0..4 {
|
||||||
res[i] = hash[i];
|
res[i] = hash[i];
|
||||||
}
|
}
|
||||||
|
@ -280,29 +279,32 @@ mod prime_field {
|
||||||
|
|
||||||
impl Default for FieldPrime {
|
impl Default for FieldPrime {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
FieldPrime {
|
FieldPrime { v: Fr::zero() }
|
||||||
value: BigInt::default(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for FieldPrime {
|
impl Display for FieldPrime {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "{}", self.value.to_str_radix(10))
|
write!(f, "{}", self.to_biguint())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for FieldPrime {
|
impl Debug for FieldPrime {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "{}", self.value.to_str_radix(10))
|
write!(f, "{}", self.to_biguint())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<i32> for FieldPrime {
|
impl From<i32> for FieldPrime {
|
||||||
fn from(num: i32) -> Self {
|
fn from(num: i32) -> Self {
|
||||||
let x = ToBigInt::to_bigint(&num).unwrap();
|
if num < 0 {
|
||||||
FieldPrime {
|
FieldPrime {
|
||||||
value: &x - x.div_floor(&*P) * &*P,
|
v: -Fr::from((-num) as u32),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
FieldPrime {
|
||||||
|
v: Fr::from(num as u32),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -318,28 +320,21 @@ mod prime_field {
|
||||||
|
|
||||||
impl From<u32> for FieldPrime {
|
impl From<u32> for FieldPrime {
|
||||||
fn from(num: u32) -> Self {
|
fn from(num: u32) -> Self {
|
||||||
let x = ToBigInt::to_bigint(&num).unwrap();
|
FieldPrime { v: Fr::from(num) }
|
||||||
FieldPrime {
|
|
||||||
value: &x - x.div_floor(&*P) * &*P,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<usize> for FieldPrime {
|
impl From<usize> for FieldPrime {
|
||||||
fn from(num: usize) -> Self {
|
fn from(num: usize) -> Self {
|
||||||
let x = ToBigInt::to_bigint(&num).unwrap();
|
|
||||||
FieldPrime {
|
FieldPrime {
|
||||||
value: &x - x.div_floor(&*P) * &*P,
|
v: Fr::from(num as u128),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<u128> for FieldPrime {
|
impl From<u128> for FieldPrime {
|
||||||
fn from(num: u128) -> Self {
|
fn from(num: u128) -> Self {
|
||||||
let x = ToBigInt::to_bigint(&num).unwrap();
|
FieldPrime { v: Fr::from(num) }
|
||||||
FieldPrime {
|
|
||||||
value: &x - x.div_floor(&*P) * &*P,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -349,8 +344,10 @@ mod prime_field {
|
||||||
fn try_from(value: BigUint) -> Result<Self, ()> {
|
fn try_from(value: BigUint) -> Result<Self, ()> {
|
||||||
match value <= Self::max_value().to_biguint() {
|
match value <= Self::max_value().to_biguint() {
|
||||||
true => {
|
true => {
|
||||||
let x = ToBigInt::to_bigint(&value).unwrap();
|
use std::str::FromStr;
|
||||||
Ok(FieldPrime { value: x })
|
Ok(FieldPrime {
|
||||||
|
v: Fr::from_str(&value.to_string()).unwrap(),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
false => Err(()),
|
false => Err(()),
|
||||||
}
|
}
|
||||||
|
@ -359,20 +356,16 @@ mod prime_field {
|
||||||
|
|
||||||
impl Zero for FieldPrime {
|
impl Zero for FieldPrime {
|
||||||
fn zero() -> FieldPrime {
|
fn zero() -> FieldPrime {
|
||||||
FieldPrime {
|
FieldPrime { v: Fr::zero() }
|
||||||
value: ToBigInt::to_bigint(&0).unwrap(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
fn is_zero(&self) -> bool {
|
fn is_zero(&self) -> bool {
|
||||||
self.value == ToBigInt::to_bigint(&0).unwrap()
|
self.v.is_zero()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl One for FieldPrime {
|
impl One for FieldPrime {
|
||||||
fn one() -> FieldPrime {
|
fn one() -> FieldPrime {
|
||||||
FieldPrime {
|
FieldPrime { v: Fr::one() }
|
||||||
value: ToBigInt::to_bigint(&1).unwrap(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -380,16 +373,8 @@ mod prime_field {
|
||||||
type Output = FieldPrime;
|
type Output = FieldPrime;
|
||||||
|
|
||||||
fn add(self, other: FieldPrime) -> FieldPrime {
|
fn add(self, other: FieldPrime) -> FieldPrime {
|
||||||
if self.value == BigInt::zero() {
|
|
||||||
return other;
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.value == BigInt::zero() {
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
FieldPrime {
|
FieldPrime {
|
||||||
value: (self.value + other.value) % &*P,
|
v: self.v + other.v,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -398,16 +383,8 @@ mod prime_field {
|
||||||
type Output = FieldPrime;
|
type Output = FieldPrime;
|
||||||
|
|
||||||
fn add(self, other: &FieldPrime) -> FieldPrime {
|
fn add(self, other: &FieldPrime) -> FieldPrime {
|
||||||
if self.value == BigInt::zero() {
|
|
||||||
return other.clone();
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.value == BigInt::zero() {
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
FieldPrime {
|
FieldPrime {
|
||||||
value: (self.value + &other.value) % &*P,
|
v: self.v + other.v,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -416,9 +393,8 @@ mod prime_field {
|
||||||
type Output = FieldPrime;
|
type Output = FieldPrime;
|
||||||
|
|
||||||
fn sub(self, other: FieldPrime) -> FieldPrime {
|
fn sub(self, other: FieldPrime) -> FieldPrime {
|
||||||
let x = self.value - other.value;
|
|
||||||
FieldPrime {
|
FieldPrime {
|
||||||
value: &x - x.div_floor(&*P) * &*P,
|
v: self.v - other.v,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -427,9 +403,8 @@ mod prime_field {
|
||||||
type Output = FieldPrime;
|
type Output = FieldPrime;
|
||||||
|
|
||||||
fn sub(self, other: &FieldPrime) -> FieldPrime {
|
fn sub(self, other: &FieldPrime) -> FieldPrime {
|
||||||
let x = self.value - &other.value;
|
|
||||||
FieldPrime {
|
FieldPrime {
|
||||||
value: &x - x.div_floor(&*P) * &*P,
|
v: self.v - other.v,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -438,16 +413,8 @@ mod prime_field {
|
||||||
type Output = FieldPrime;
|
type Output = FieldPrime;
|
||||||
|
|
||||||
fn mul(self, other: FieldPrime) -> FieldPrime {
|
fn mul(self, other: FieldPrime) -> FieldPrime {
|
||||||
if self.value == BigInt::one() {
|
|
||||||
return other;
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.value == BigInt::one() {
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
FieldPrime {
|
FieldPrime {
|
||||||
value: (self.value * other.value) % &*P,
|
v: self.v * other.v,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -456,23 +423,21 @@ mod prime_field {
|
||||||
type Output = FieldPrime;
|
type Output = FieldPrime;
|
||||||
|
|
||||||
fn mul(self, other: &FieldPrime) -> FieldPrime {
|
fn mul(self, other: &FieldPrime) -> FieldPrime {
|
||||||
if self.value == BigInt::one() {
|
|
||||||
return other.clone();
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.value == BigInt::one() {
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
FieldPrime {
|
FieldPrime {
|
||||||
value: (self.value * &other.value) % &*P,
|
v: self.v * other.v,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CheckedDiv for FieldPrime {
|
impl CheckedDiv for FieldPrime {
|
||||||
fn checked_div(&self, other: &FieldPrime) -> Option<FieldPrime> {
|
fn checked_div(&self, other: &FieldPrime) -> Option<FieldPrime> {
|
||||||
other.inverse_mul().map(|inv| inv * self)
|
if other.v == Fr::zero() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(FieldPrime {
|
||||||
|
v: self.v / other.v,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -496,11 +461,9 @@ mod prime_field {
|
||||||
type Output = FieldPrime;
|
type Output = FieldPrime;
|
||||||
|
|
||||||
fn pow(self, exp: usize) -> FieldPrime {
|
fn pow(self, exp: usize) -> FieldPrime {
|
||||||
let mut res = FieldPrime::from(1);
|
FieldPrime {
|
||||||
for _ in 0..exp {
|
v: self.v.pow(&[exp as u64]),
|
||||||
res = res * &self;
|
|
||||||
}
|
}
|
||||||
res
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -511,12 +474,16 @@ mod prime_field {
|
||||||
assert!(self <= &bound);
|
assert!(self <= &bound);
|
||||||
assert!(other <= &bound);
|
assert!(other <= &bound);
|
||||||
|
|
||||||
let big_res = &self.value + &other.value;
|
let left = self.to_biguint();
|
||||||
|
let right = other.to_biguint();
|
||||||
|
|
||||||
if big_res > bound.value {
|
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
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(FieldPrime { value: big_res })
|
Some(self.clone() + other)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -528,40 +495,84 @@ mod prime_field {
|
||||||
assert!(self <= &bound);
|
assert!(self <= &bound);
|
||||||
assert!(other <= &bound);
|
assert!(other <= &bound);
|
||||||
|
|
||||||
let big_res = &self.value * &other.value;
|
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
|
// we only go up to 2**(bitwidth - 1) because after that we lose uniqueness of bit decomposition
|
||||||
if big_res > bound.value {
|
if big_res > bound.to_biguint() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(FieldPrime { value: big_res })
|
Some(self.clone() * other)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calculates the gcd using an iterative implementation of the extended euclidian algorithm.
|
impl Serialize for FieldPrime {
|
||||||
/// Returning `(d, s, t)` so that `d = s * a + t * b`
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
///
|
where
|
||||||
/// # Arguments
|
S: Serializer,
|
||||||
/// * `a` - First number as `BigInt`
|
{
|
||||||
/// * `b` - Second number as `BigInt`
|
use ark_serialize::CanonicalSerialize;
|
||||||
fn extended_euclid(a: &BigInt, b: &BigInt) -> (BigInt, BigInt, BigInt) {
|
use serde::ser::Error;
|
||||||
let (mut s, mut old_s) = (BigInt::zero(), BigInt::one());
|
let mut data: Vec<u8> = vec![];
|
||||||
let (mut t, mut old_t) = (BigInt::one(), BigInt::zero());
|
self.v
|
||||||
let (mut r, mut old_r) = (b.clone(), a.clone());
|
.serialize(&mut data)
|
||||||
while !&r.is_zero() {
|
.map_err(|e| S::Error::custom(e.to_string()))?;
|
||||||
let quotient = &old_r / &r;
|
serializer.serialize_bytes(&data)
|
||||||
let tmp_r = old_r.clone();
|
}
|
||||||
old_r = r.clone();
|
}
|
||||||
r = &tmp_r - "ient * &r;
|
|
||||||
let tmp_s = old_s.clone();
|
struct FieldVisitor;
|
||||||
old_s = s.clone();
|
|
||||||
s = &tmp_s - "ient * &s;
|
use serde::de::SeqAccess;
|
||||||
let tmp_t = old_t.clone();
|
|
||||||
old_t = t.clone();
|
impl<'de> Visitor<'de> for FieldVisitor {
|
||||||
t = &tmp_t - "ient * &t;
|
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)
|
||||||
}
|
}
|
||||||
return (old_r, old_s, old_t);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -601,7 +612,6 @@ mod prime_field {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "ark")]
|
|
||||||
macro_rules! ark_extensions {
|
macro_rules! ark_extensions {
|
||||||
($ark_type:ty) => {
|
($ark_type:ty) => {
|
||||||
use crate::ArkFieldExtensions;
|
use crate::ArkFieldExtensions;
|
||||||
|
@ -610,16 +620,11 @@ mod prime_field {
|
||||||
type ArkEngine = $ark_type;
|
type ArkEngine = $ark_type;
|
||||||
|
|
||||||
fn from_ark(e: <Self::ArkEngine as ark_ec::PairingEngine>::Fr) -> Self {
|
fn from_ark(e: <Self::ArkEngine as ark_ec::PairingEngine>::Fr) -> Self {
|
||||||
use ark_ff::{BigInteger, PrimeField};
|
Self { v: e }
|
||||||
let mut res: Vec<u8> = vec![];
|
|
||||||
e.into_repr().write_le(&mut res).unwrap();
|
|
||||||
Self::from_byte_vector(res)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn into_ark(self) -> <Self::ArkEngine as ark_ec::PairingEngine>::Fr {
|
fn into_ark(self) -> <Self::ArkEngine as ark_ec::PairingEngine>::Fr {
|
||||||
use core::str::FromStr;
|
self.v
|
||||||
let s = self.to_dec_string();
|
|
||||||
<Self::ArkEngine as ark_ec::PairingEngine>::Fr::from_str(&s).unwrap()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
39
zokrates_js/Cargo.lock
generated
39
zokrates_js/Cargo.lock
generated
|
@ -49,6 +49,28 @@ dependencies = [
|
||||||
"ark-std",
|
"ark-std",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ark-bls12-381"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "70e1c2ad76c4f725520440b981df3ce2d635f2baa1122750c757c0cf0f3d4b74"
|
||||||
|
dependencies = [
|
||||||
|
"ark-ec",
|
||||||
|
"ark-ff",
|
||||||
|
"ark-std",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ark-bn254"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3ead066869de5e8cb2938123204d1572f09496b629e146a6f80fa8ec508446ba"
|
||||||
|
dependencies = [
|
||||||
|
"ark-ec",
|
||||||
|
"ark-ff",
|
||||||
|
"ark-std",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ark-bw6-761"
|
name = "ark-bw6-761"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
|
@ -1571,7 +1593,7 @@ version = "0.1.0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zokrates_core"
|
name = "zokrates_core"
|
||||||
version = "0.6.7"
|
version = "0.6.8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bellman_ce",
|
"bellman_ce",
|
||||||
"cfg-if 0.1.10",
|
"cfg-if 0.1.10",
|
||||||
|
@ -1600,7 +1622,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zokrates_embed"
|
name = "zokrates_embed"
|
||||||
version = "0.1.4"
|
version = "0.1.5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ark-bls12-377",
|
"ark-bls12-377",
|
||||||
"ark-bw6-761",
|
"ark-bw6-761",
|
||||||
|
@ -1620,6 +1642,13 @@ dependencies = [
|
||||||
name = "zokrates_field"
|
name = "zokrates_field"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"ark-bls12-377",
|
||||||
|
"ark-bls12-381",
|
||||||
|
"ark-bn254",
|
||||||
|
"ark-bw6-761",
|
||||||
|
"ark-ec",
|
||||||
|
"ark-ff",
|
||||||
|
"ark-serialize",
|
||||||
"bellman_ce",
|
"bellman_ce",
|
||||||
"bincode",
|
"bincode",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
|
@ -1634,7 +1663,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zokrates_js"
|
name = "zokrates_js"
|
||||||
version = "1.0.36"
|
version = "1.0.37"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"console_error_panic_hook",
|
"console_error_panic_hook",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
|
@ -1650,7 +1679,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zokrates_parser"
|
name = "zokrates_parser"
|
||||||
version = "0.2.4"
|
version = "0.2.5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"pest",
|
"pest",
|
||||||
"pest_derive",
|
"pest_derive",
|
||||||
|
@ -1658,7 +1687,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zokrates_pest_ast"
|
name = "zokrates_pest_ast"
|
||||||
version = "0.2.3"
|
version = "0.2.4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"from-pest",
|
"from-pest",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
|
|
|
@ -15,6 +15,6 @@ wasm-bindgen = { version = "0.2.46", features = ["serde-serialize"] }
|
||||||
typed-arena = "1.4.1"
|
typed-arena = "1.4.1"
|
||||||
zokrates_core = { path = "../zokrates_core", features = ["wasm", "bellman"], default-features = false }
|
zokrates_core = { path = "../zokrates_core", features = ["wasm", "bellman"], default-features = false }
|
||||||
zokrates_common = { path = "../zokrates_common" }
|
zokrates_common = { path = "../zokrates_common" }
|
||||||
zokrates_field = { path = "../zokrates_field", default-features = false, features = ["bellman"] }
|
zokrates_field = { path = "../zokrates_field", features = ["bellman"] }
|
||||||
zokrates_abi = { path = "../zokrates_abi" }
|
zokrates_abi = { path = "../zokrates_abi" }
|
||||||
console_error_panic_hook = "0.1.6"
|
console_error_panic_hook = "0.1.6"
|
|
@ -24,18 +24,6 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"input": {
|
|
||||||
"values": ["21888242871839275222246405745257275088548364400416034343698204186575808495617", "0", "0"]
|
|
||||||
},
|
|
||||||
"output": {
|
|
||||||
"Ok": {
|
|
||||||
"values": [
|
|
||||||
"14543742788565021628577424853847564376151732847602780516906950225481254681152", "21165881269406212375659499083070944693027168220143204011932538650149052385959"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue