mirror of
https://github.com/Qortal/pirate-librustzcash.git
synced 2025-02-14 18:55:47 +00:00
commit
b19b40ccf0
10
Cargo.lock
generated
10
Cargo.lock
generated
@ -317,6 +317,14 @@ dependencies = [
|
|||||||
"zcash_proofs 0.0.0",
|
"zcash_proofs 0.0.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "log"
|
||||||
|
version = "0.4.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nodrop"
|
name = "nodrop"
|
||||||
version = "0.1.13"
|
version = "0.1.13"
|
||||||
@ -535,6 +543,7 @@ dependencies = [
|
|||||||
"hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"hex-literal 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"hex-literal 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pairing 0.14.2",
|
"pairing 0.14.2",
|
||||||
"rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -594,6 +603,7 @@ dependencies = [
|
|||||||
"checksum hex-literal-impl 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "520870c3213943eb8d7803e80180d12a6c7ceb4ae74602544529d1643dc4ddda"
|
"checksum hex-literal-impl 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "520870c3213943eb8d7803e80180d12a6c7ceb4ae74602544529d1643dc4ddda"
|
||||||
"checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14"
|
"checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14"
|
||||||
"checksum libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)" = "c665266eb592905e8503ba3403020f4b8794d26263f412ca33171600eca9a6fa"
|
"checksum libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)" = "c665266eb592905e8503ba3403020f4b8794d26263f412ca33171600eca9a6fa"
|
||||||
|
"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
|
||||||
"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945"
|
"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945"
|
||||||
"checksum num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "57450397855d951f1a41305e54851b1a7b8f5d2e349543a02a2effe25459f718"
|
"checksum num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "57450397855d951f1a41305e54851b1a7b8f5d2e349543a02a2effe25459f718"
|
||||||
"checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09"
|
"checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09"
|
||||||
|
@ -26,15 +26,19 @@ pub struct EvaluationDomain<E: ScalarEngine, G: Group<E>> {
|
|||||||
minv: E::Fr,
|
minv: E::Fr,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: ScalarEngine, G: Group<E>> EvaluationDomain<E, G> {
|
impl<E: ScalarEngine, G: Group<E>> AsRef<[G]> for EvaluationDomain<E, G> {
|
||||||
pub fn as_ref(&self) -> &[G] {
|
fn as_ref(&self) -> &[G] {
|
||||||
&self.coeffs
|
&self.coeffs
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn as_mut(&mut self) -> &mut [G] {
|
impl<E: ScalarEngine, G: Group<E>> AsMut<[G]> for EvaluationDomain<E, G> {
|
||||||
|
fn as_mut(&mut self) -> &mut [G] {
|
||||||
&mut self.coeffs
|
&mut self.coeffs
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E: ScalarEngine, G: Group<E>> EvaluationDomain<E, G> {
|
||||||
pub fn into_coeffs(self) -> Vec<G> {
|
pub fn into_coeffs(self) -> Vec<G> {
|
||||||
self.coeffs
|
self.coeffs
|
||||||
}
|
}
|
||||||
@ -64,9 +68,9 @@ impl<E: ScalarEngine, G: Group<E>> EvaluationDomain<E, G> {
|
|||||||
coeffs.resize(m, G::group_zero());
|
coeffs.resize(m, G::group_zero());
|
||||||
|
|
||||||
Ok(EvaluationDomain {
|
Ok(EvaluationDomain {
|
||||||
coeffs: coeffs,
|
coeffs,
|
||||||
exp: exp,
|
exp,
|
||||||
omega: omega,
|
omega,
|
||||||
omegainv: omega.inverse().unwrap(),
|
omegainv: omega.inverse().unwrap(),
|
||||||
geninv: E::Fr::multiplicative_generator().inverse().unwrap(),
|
geninv: E::Fr::multiplicative_generator().inverse().unwrap(),
|
||||||
minv: E::Fr::from_str(&format!("{}", m))
|
minv: E::Fr::from_str(&format!("{}", m))
|
||||||
@ -291,7 +295,7 @@ fn serial_fft<E: ScalarEngine, T: Group<E>>(a: &mut [T], omega: &E::Fr, log_n: u
|
|||||||
|
|
||||||
let mut m = 1;
|
let mut m = 1;
|
||||||
for _ in 0..log_n {
|
for _ in 0..log_n {
|
||||||
let w_m = omega.pow(&[(n / (2 * m)) as u64]);
|
let w_m = omega.pow(&[u64::from(n / (2 * m))]);
|
||||||
|
|
||||||
let mut k = 0;
|
let mut k = 0;
|
||||||
while k < n {
|
while k < n {
|
||||||
@ -337,12 +341,12 @@ fn parallel_fft<E: ScalarEngine, T: Group<E>>(
|
|||||||
let omega_step = omega.pow(&[(j as u64) << log_new_n]);
|
let omega_step = omega.pow(&[(j as u64) << log_new_n]);
|
||||||
|
|
||||||
let mut elt = E::Fr::one();
|
let mut elt = E::Fr::one();
|
||||||
for i in 0..(1 << log_new_n) {
|
for (i, tmp) in tmp.iter_mut().enumerate() {
|
||||||
for s in 0..num_cpus {
|
for s in 0..num_cpus {
|
||||||
let idx = (i + (s << log_new_n)) % (1 << log_n);
|
let idx = (i + (s << log_new_n)) % (1 << log_n);
|
||||||
let mut t = a[idx];
|
let mut t = a[idx];
|
||||||
t.group_mul_assign(&elt);
|
t.group_mul_assign(&elt);
|
||||||
tmp[i].group_add_assign(&t);
|
tmp.group_add_assign(&t);
|
||||||
elt.mul_assign(&omega_step);
|
elt.mul_assign(&omega_step);
|
||||||
}
|
}
|
||||||
elt.mul_assign(&omega_j);
|
elt.mul_assign(&omega_j);
|
||||||
|
@ -382,7 +382,7 @@ pub fn blake2s<E: Engine, CS: ConstraintSystem<E>>(
|
|||||||
blocks.push(this_block);
|
blocks.push(this_block);
|
||||||
}
|
}
|
||||||
|
|
||||||
if blocks.len() == 0 {
|
if blocks.is_empty() {
|
||||||
blocks.push((0..16).map(|_| UInt32::constant(0)).collect());
|
blocks.push((0..16).map(|_| UInt32::constant(0)).collect());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -404,7 +404,7 @@ pub fn blake2s<E: Engine, CS: ConstraintSystem<E>>(
|
|||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(h.iter().flat_map(|b| b.into_bits()).collect())
|
Ok(h.into_iter().flat_map(|b| b.into_bits()).collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -433,7 +433,7 @@ mod test {
|
|||||||
let expected = hex!("c59f682376d137f3f255e671e207d1f2374ebe504e9314208a52d9f88d69e8c8");
|
let expected = hex!("c59f682376d137f3f255e671e207d1f2374ebe504e9314208a52d9f88d69e8c8");
|
||||||
|
|
||||||
let mut out = out.into_iter();
|
let mut out = out.into_iter();
|
||||||
for b in expected.into_iter() {
|
for b in expected.iter() {
|
||||||
for i in 0..8 {
|
for i in 0..8 {
|
||||||
let c = out.next().unwrap().get_value().unwrap();
|
let c = out.next().unwrap().get_value().unwrap();
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ impl AllocatedBit {
|
|||||||
|
|
||||||
Ok(AllocatedBit {
|
Ok(AllocatedBit {
|
||||||
variable: var,
|
variable: var,
|
||||||
value: value,
|
value,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,7 +93,7 @@ impl AllocatedBit {
|
|||||||
|
|
||||||
Ok(AllocatedBit {
|
Ok(AllocatedBit {
|
||||||
variable: var,
|
variable: var,
|
||||||
value: value,
|
value,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,7 +302,7 @@ pub fn field_into_boolean_vec_le<E: Engine, CS: ConstraintSystem<E>, F: PrimeFie
|
|||||||
) -> Result<Vec<Boolean>, SynthesisError> {
|
) -> Result<Vec<Boolean>, SynthesisError> {
|
||||||
let v = field_into_allocated_bits_le::<E, CS, F>(cs, value)?;
|
let v = field_into_allocated_bits_le::<E, CS, F>(cs, value)?;
|
||||||
|
|
||||||
Ok(v.into_iter().map(|e| Boolean::from(e)).collect())
|
Ok(v.into_iter().map(Boolean::from).collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn field_into_allocated_bits_le<E: Engine, CS: ConstraintSystem<E>, F: PrimeField>(
|
pub fn field_into_allocated_bits_le<E: Engine, CS: ConstraintSystem<E>, F: PrimeField>(
|
||||||
@ -412,24 +412,24 @@ impl Boolean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_value(&self) -> Option<bool> {
|
pub fn get_value(&self) -> Option<bool> {
|
||||||
match self {
|
match *self {
|
||||||
&Boolean::Constant(c) => Some(c),
|
Boolean::Constant(c) => Some(c),
|
||||||
&Boolean::Is(ref v) => v.get_value(),
|
Boolean::Is(ref v) => v.get_value(),
|
||||||
&Boolean::Not(ref v) => v.get_value().map(|b| !b),
|
Boolean::Not(ref v) => v.get_value().map(|b| !b),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lc<E: Engine>(&self, one: Variable, coeff: E::Fr) -> LinearCombination<E> {
|
pub fn lc<E: Engine>(&self, one: Variable, coeff: E::Fr) -> LinearCombination<E> {
|
||||||
match self {
|
match *self {
|
||||||
&Boolean::Constant(c) => {
|
Boolean::Constant(c) => {
|
||||||
if c {
|
if c {
|
||||||
LinearCombination::<E>::zero() + (coeff, one)
|
LinearCombination::<E>::zero() + (coeff, one)
|
||||||
} else {
|
} else {
|
||||||
LinearCombination::<E>::zero()
|
LinearCombination::<E>::zero()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Boolean::Is(ref v) => LinearCombination::<E>::zero() + (coeff, v.get_variable()),
|
Boolean::Is(ref v) => LinearCombination::<E>::zero() + (coeff, v.get_variable()),
|
||||||
&Boolean::Not(ref v) => {
|
Boolean::Not(ref v) => {
|
||||||
LinearCombination::<E>::zero() + (coeff, one) - (coeff, v.get_variable())
|
LinearCombination::<E>::zero() + (coeff, one) - (coeff, v.get_variable())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -442,10 +442,10 @@ impl Boolean {
|
|||||||
|
|
||||||
/// Return a negated interpretation of this boolean.
|
/// Return a negated interpretation of this boolean.
|
||||||
pub fn not(&self) -> Self {
|
pub fn not(&self) -> Self {
|
||||||
match self {
|
match *self {
|
||||||
&Boolean::Constant(c) => Boolean::Constant(!c),
|
Boolean::Constant(c) => Boolean::Constant(!c),
|
||||||
&Boolean::Is(ref v) => Boolean::Not(v.clone()),
|
Boolean::Is(ref v) => Boolean::Not(v.clone()),
|
||||||
&Boolean::Not(ref v) => Boolean::Is(v.clone()),
|
Boolean::Not(ref v) => Boolean::Is(v.clone()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ pub struct MultiEq<E: Engine, CS: ConstraintSystem<E>> {
|
|||||||
impl<E: Engine, CS: ConstraintSystem<E>> MultiEq<E, CS> {
|
impl<E: Engine, CS: ConstraintSystem<E>> MultiEq<E, CS> {
|
||||||
pub fn new(cs: CS) -> Self {
|
pub fn new(cs: CS) -> Self {
|
||||||
MultiEq {
|
MultiEq {
|
||||||
cs: cs,
|
cs,
|
||||||
ops: 0,
|
ops: 0,
|
||||||
bits_used: 0,
|
bits_used: 0,
|
||||||
lhs: LinearCombination::zero(),
|
lhs: LinearCombination::zero(),
|
||||||
|
@ -66,7 +66,7 @@ impl<E: Engine> AllocatedNum<E> {
|
|||||||
/// order, requiring that the representation
|
/// order, requiring that the representation
|
||||||
/// strictly exists "in the field" (i.e., a
|
/// strictly exists "in the field" (i.e., a
|
||||||
/// congruency is not allowed.)
|
/// congruency is not allowed.)
|
||||||
pub fn into_bits_le_strict<CS>(&self, mut cs: CS) -> Result<Vec<Boolean>, SynthesisError>
|
pub fn to_bits_le_strict<CS>(&self, mut cs: CS) -> Result<Vec<Boolean>, SynthesisError>
|
||||||
where
|
where
|
||||||
CS: ConstraintSystem<E>,
|
CS: ConstraintSystem<E>,
|
||||||
{
|
{
|
||||||
@ -78,7 +78,7 @@ impl<E: Engine> AllocatedNum<E> {
|
|||||||
E: Engine,
|
E: Engine,
|
||||||
CS: ConstraintSystem<E>,
|
CS: ConstraintSystem<E>,
|
||||||
{
|
{
|
||||||
assert!(v.len() > 0);
|
assert!(!v.is_empty());
|
||||||
|
|
||||||
// Let's keep this simple for now and just AND them all
|
// Let's keep this simple for now and just AND them all
|
||||||
// manually
|
// manually
|
||||||
@ -132,7 +132,7 @@ impl<E: Engine> AllocatedNum<E> {
|
|||||||
current_run.push(a_bit.clone());
|
current_run.push(a_bit.clone());
|
||||||
result.push(a_bit);
|
result.push(a_bit);
|
||||||
} else {
|
} else {
|
||||||
if current_run.len() > 0 {
|
if !current_run.is_empty() {
|
||||||
// This is the start of a run of zeros, but we need
|
// This is the start of a run of zeros, but we need
|
||||||
// to k-ary AND against `last_run` first.
|
// to k-ary AND against `last_run` first.
|
||||||
|
|
||||||
@ -183,13 +183,13 @@ impl<E: Engine> AllocatedNum<E> {
|
|||||||
cs.enforce(|| "unpacking constraint", |lc| lc, |lc| lc, |_| lc);
|
cs.enforce(|| "unpacking constraint", |lc| lc, |lc| lc, |_| lc);
|
||||||
|
|
||||||
// Convert into booleans, and reverse for little-endian bit order
|
// Convert into booleans, and reverse for little-endian bit order
|
||||||
Ok(result.into_iter().map(|b| Boolean::from(b)).rev().collect())
|
Ok(result.into_iter().map(Boolean::from).rev().collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert the allocated number into its little-endian representation.
|
/// Convert the allocated number into its little-endian representation.
|
||||||
/// Note that this does not strongly enforce that the commitment is
|
/// Note that this does not strongly enforce that the commitment is
|
||||||
/// "in the field."
|
/// "in the field."
|
||||||
pub fn into_bits_le<CS>(&self, mut cs: CS) -> Result<Vec<Boolean>, SynthesisError>
|
pub fn to_bits_le<CS>(&self, mut cs: CS) -> Result<Vec<Boolean>, SynthesisError>
|
||||||
where
|
where
|
||||||
CS: ConstraintSystem<E>,
|
CS: ConstraintSystem<E>,
|
||||||
{
|
{
|
||||||
@ -208,7 +208,7 @@ impl<E: Engine> AllocatedNum<E> {
|
|||||||
|
|
||||||
cs.enforce(|| "unpacking constraint", |lc| lc, |lc| lc, |_| lc);
|
cs.enforce(|| "unpacking constraint", |lc| lc, |lc| lc, |_| lc);
|
||||||
|
|
||||||
Ok(bits.into_iter().map(|b| Boolean::from(b)).collect())
|
Ok(bits.into_iter().map(Boolean::from).collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mul<CS>(&self, mut cs: CS, other: &Self) -> Result<Self, SynthesisError>
|
pub fn mul<CS>(&self, mut cs: CS, other: &Self) -> Result<Self, SynthesisError>
|
||||||
@ -238,7 +238,7 @@ impl<E: Engine> AllocatedNum<E> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
Ok(AllocatedNum {
|
Ok(AllocatedNum {
|
||||||
value: value,
|
value,
|
||||||
variable: var,
|
variable: var,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -270,7 +270,7 @@ impl<E: Engine> AllocatedNum<E> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
Ok(AllocatedNum {
|
Ok(AllocatedNum {
|
||||||
value: value,
|
value,
|
||||||
variable: var,
|
variable: var,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -522,7 +522,7 @@ mod test {
|
|||||||
let mut cs = TestConstraintSystem::<Bls12>::new();
|
let mut cs = TestConstraintSystem::<Bls12>::new();
|
||||||
|
|
||||||
let n = AllocatedNum::alloc(&mut cs, || Ok(negone)).unwrap();
|
let n = AllocatedNum::alloc(&mut cs, || Ok(negone)).unwrap();
|
||||||
n.into_bits_le_strict(&mut cs).unwrap();
|
n.to_bits_le_strict(&mut cs).unwrap();
|
||||||
|
|
||||||
assert!(cs.is_satisfied());
|
assert!(cs.is_satisfied());
|
||||||
|
|
||||||
@ -550,9 +550,9 @@ mod test {
|
|||||||
let n = AllocatedNum::alloc(&mut cs, || Ok(r)).unwrap();
|
let n = AllocatedNum::alloc(&mut cs, || Ok(r)).unwrap();
|
||||||
|
|
||||||
let bits = if i % 2 == 0 {
|
let bits = if i % 2 == 0 {
|
||||||
n.into_bits_le(&mut cs).unwrap()
|
n.to_bits_le(&mut cs).unwrap()
|
||||||
} else {
|
} else {
|
||||||
n.into_bits_le_strict(&mut cs).unwrap()
|
n.to_bits_le_strict(&mut cs).unwrap()
|
||||||
};
|
};
|
||||||
|
|
||||||
assert!(cs.is_satisfied());
|
assert!(cs.is_satisfied());
|
||||||
|
@ -4,6 +4,7 @@ use super::uint32::UInt32;
|
|||||||
use crate::{ConstraintSystem, SynthesisError};
|
use crate::{ConstraintSystem, SynthesisError};
|
||||||
use pairing::Engine;
|
use pairing::Engine;
|
||||||
|
|
||||||
|
#[allow(clippy::unreadable_literal)]
|
||||||
const ROUND_CONSTANTS: [u32; 64] = [
|
const ROUND_CONSTANTS: [u32; 64] = [
|
||||||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
||||||
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
||||||
@ -15,6 +16,7 @@ const ROUND_CONSTANTS: [u32; 64] = [
|
|||||||
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
|
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
#[allow(clippy::unreadable_literal)]
|
||||||
const IV: [u32; 8] = [
|
const IV: [u32; 8] = [
|
||||||
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
|
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
|
||||||
];
|
];
|
||||||
@ -130,7 +132,7 @@ where
|
|||||||
Ok(match self {
|
Ok(match self {
|
||||||
Maybe::Concrete(ref v) => return Ok(v.clone()),
|
Maybe::Concrete(ref v) => return Ok(v.clone()),
|
||||||
Maybe::Deferred(mut v) => {
|
Maybe::Deferred(mut v) => {
|
||||||
v.extend(others.into_iter().cloned());
|
v.extend(others.iter().cloned());
|
||||||
UInt32::addmany(cs, &v)?
|
UInt32::addmany(cs, &v)?
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -286,7 +288,7 @@ mod test {
|
|||||||
let expected = hex!("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
|
let expected = hex!("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
|
||||||
|
|
||||||
let mut out = out_bits.into_iter();
|
let mut out = out_bits.into_iter();
|
||||||
for b in expected.into_iter() {
|
for b in expected.iter() {
|
||||||
for i in (0..8).rev() {
|
for i in (0..8).rev() {
|
||||||
let c = out.next().unwrap().get_value().unwrap();
|
let c = out.next().unwrap().get_value().unwrap();
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ fn proc_lc<E: Engine>(terms: &[(Variable, E::Fr)]) -> BTreeMap<OrderedVariable,
|
|||||||
let mut map = BTreeMap::new();
|
let mut map = BTreeMap::new();
|
||||||
for &(var, coeff) in terms {
|
for &(var, coeff) in terms {
|
||||||
map.entry(OrderedVariable(var))
|
map.entry(OrderedVariable(var))
|
||||||
.or_insert(E::Fr::zero())
|
.or_insert_with(E::Fr::zero)
|
||||||
.add_assign(&coeff);
|
.add_assign(&coeff);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,7 +157,7 @@ impl<E: Engine> TestConstraintSystem<E> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let powers_of_two = (0..E::Fr::NUM_BITS)
|
let powers_of_two = (0..E::Fr::NUM_BITS)
|
||||||
.map(|i| E::Fr::from_str("2").unwrap().pow(&[i as u64]))
|
.map(|i| E::Fr::from_str("2").unwrap().pow(&[u64::from(i)]))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let pp = |s: &mut String, lc: &LinearCombination<E>| {
|
let pp = |s: &mut String, lc: &LinearCombination<E>| {
|
||||||
@ -286,7 +286,7 @@ impl<E: Engine> TestConstraintSystem<E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn num_inputs(&self) -> usize {
|
pub fn num_inputs(&self) -> usize {
|
||||||
|
@ -33,7 +33,7 @@ impl UInt32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
UInt32 {
|
UInt32 {
|
||||||
bits: bits,
|
bits,
|
||||||
value: Some(value),
|
value: Some(value),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -69,14 +69,13 @@ impl UInt32 {
|
|||||||
})
|
})
|
||||||
.collect::<Result<Vec<_>, SynthesisError>>()?;
|
.collect::<Result<Vec<_>, SynthesisError>>()?;
|
||||||
|
|
||||||
Ok(UInt32 {
|
Ok(UInt32 { bits, value })
|
||||||
bits: bits,
|
|
||||||
value: value,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn into_bits_be(&self) -> Vec<Boolean> {
|
pub fn into_bits_be(self) -> Vec<Boolean> {
|
||||||
self.bits.iter().rev().cloned().collect()
|
let mut ret = self.bits;
|
||||||
|
ret.reverse();
|
||||||
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_bits_be(bits: &[Boolean]) -> Self {
|
pub fn from_bits_be(bits: &[Boolean]) -> Self {
|
||||||
@ -98,14 +97,14 @@ impl UInt32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
UInt32 {
|
UInt32 {
|
||||||
value: value,
|
value,
|
||||||
bits: bits.iter().rev().cloned().collect(),
|
bits: bits.iter().rev().cloned().collect(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Turns this `UInt32` into its little-endian byte order representation.
|
/// Turns this `UInt32` into its little-endian byte order representation.
|
||||||
pub fn into_bits(&self) -> Vec<Boolean> {
|
pub fn into_bits(self) -> Vec<Boolean> {
|
||||||
self.bits.clone()
|
self.bits
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a little-endian byte order representation of bits into a
|
/// Converts a little-endian byte order representation of bits into a
|
||||||
@ -119,20 +118,20 @@ impl UInt32 {
|
|||||||
for b in new_bits.iter().rev() {
|
for b in new_bits.iter().rev() {
|
||||||
value.as_mut().map(|v| *v <<= 1);
|
value.as_mut().map(|v| *v <<= 1);
|
||||||
|
|
||||||
match b {
|
match *b {
|
||||||
&Boolean::Constant(b) => {
|
Boolean::Constant(b) => {
|
||||||
if b {
|
if b {
|
||||||
value.as_mut().map(|v| *v |= 1);
|
value.as_mut().map(|v| *v |= 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Boolean::Is(ref b) => match b.get_value() {
|
Boolean::Is(ref b) => match b.get_value() {
|
||||||
Some(true) => {
|
Some(true) => {
|
||||||
value.as_mut().map(|v| *v |= 1);
|
value.as_mut().map(|v| *v |= 1);
|
||||||
}
|
}
|
||||||
Some(false) => {}
|
Some(false) => {}
|
||||||
None => value = None,
|
None => value = None,
|
||||||
},
|
},
|
||||||
&Boolean::Not(ref b) => match b.get_value() {
|
Boolean::Not(ref b) => match b.get_value() {
|
||||||
Some(false) => {
|
Some(false) => {
|
||||||
value.as_mut().map(|v| *v |= 1);
|
value.as_mut().map(|v| *v |= 1);
|
||||||
}
|
}
|
||||||
@ -143,7 +142,7 @@ impl UInt32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
UInt32 {
|
UInt32 {
|
||||||
value: value,
|
value,
|
||||||
bits: new_bits,
|
bits: new_bits,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -215,7 +214,7 @@ impl UInt32 {
|
|||||||
.collect::<Result<_, _>>()?;
|
.collect::<Result<_, _>>()?;
|
||||||
|
|
||||||
Ok(UInt32 {
|
Ok(UInt32 {
|
||||||
bits: bits,
|
bits,
|
||||||
value: new_value,
|
value: new_value,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -274,7 +273,7 @@ impl UInt32 {
|
|||||||
.collect::<Result<_, _>>()?;
|
.collect::<Result<_, _>>()?;
|
||||||
|
|
||||||
Ok(UInt32 {
|
Ok(UInt32 {
|
||||||
bits: bits,
|
bits,
|
||||||
value: new_value,
|
value: new_value,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -294,7 +293,7 @@ impl UInt32 {
|
|||||||
|
|
||||||
// Compute the maximum value of the sum so we allocate enough bits for
|
// Compute the maximum value of the sum so we allocate enough bits for
|
||||||
// the result
|
// the result
|
||||||
let mut max_value = (operands.len() as u64) * (u32::max_value() as u64);
|
let mut max_value = (operands.len() as u64) * (u64::from(u32::max_value()));
|
||||||
|
|
||||||
// Keep track of the resulting value
|
// Keep track of the resulting value
|
||||||
let mut result_value = Some(0u64);
|
let mut result_value = Some(0u64);
|
||||||
@ -310,7 +309,7 @@ impl UInt32 {
|
|||||||
// Accumulate the value
|
// Accumulate the value
|
||||||
match op.value {
|
match op.value {
|
||||||
Some(val) => {
|
Some(val) => {
|
||||||
result_value.as_mut().map(|v| *v += val as u64);
|
result_value.as_mut().map(|v| *v += u64::from(val));
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// If any of our operands have unknown value, we won't
|
// If any of our operands have unknown value, we won't
|
||||||
@ -408,8 +407,8 @@ mod test {
|
|||||||
let b = UInt32::from_bits_be(&v);
|
let b = UInt32::from_bits_be(&v);
|
||||||
|
|
||||||
for (i, bit) in b.bits.iter().enumerate() {
|
for (i, bit) in b.bits.iter().enumerate() {
|
||||||
match bit {
|
match *bit {
|
||||||
&Boolean::Constant(bit) => {
|
Boolean::Constant(bit) => {
|
||||||
assert!(bit == ((b.value.unwrap() >> i) & 1 == 1));
|
assert!(bit == ((b.value.unwrap() >> i) & 1 == 1));
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
@ -443,8 +442,8 @@ mod test {
|
|||||||
let b = UInt32::from_bits(&v);
|
let b = UInt32::from_bits(&v);
|
||||||
|
|
||||||
for (i, bit) in b.bits.iter().enumerate() {
|
for (i, bit) in b.bits.iter().enumerate() {
|
||||||
match bit {
|
match *bit {
|
||||||
&Boolean::Constant(bit) => {
|
Boolean::Constant(bit) => {
|
||||||
assert!(bit == ((b.value.unwrap() >> i) & 1 == 1));
|
assert!(bit == ((b.value.unwrap() >> i) & 1 == 1));
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
@ -491,14 +490,14 @@ mod test {
|
|||||||
assert!(r.value == Some(expected));
|
assert!(r.value == Some(expected));
|
||||||
|
|
||||||
for b in r.bits.iter() {
|
for b in r.bits.iter() {
|
||||||
match b {
|
match *b {
|
||||||
&Boolean::Is(ref b) => {
|
Boolean::Is(ref b) => {
|
||||||
assert!(b.get_value().unwrap() == (expected & 1 == 1));
|
assert!(b.get_value().unwrap() == (expected & 1 == 1));
|
||||||
}
|
}
|
||||||
&Boolean::Not(ref b) => {
|
Boolean::Not(ref b) => {
|
||||||
assert!(!b.get_value().unwrap() == (expected & 1 == 1));
|
assert!(!b.get_value().unwrap() == (expected & 1 == 1));
|
||||||
}
|
}
|
||||||
&Boolean::Constant(b) => {
|
Boolean::Constant(b) => {
|
||||||
assert!(b == (expected & 1 == 1));
|
assert!(b == (expected & 1 == 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -538,10 +537,10 @@ mod test {
|
|||||||
assert!(r.value == Some(expected));
|
assert!(r.value == Some(expected));
|
||||||
|
|
||||||
for b in r.bits.iter() {
|
for b in r.bits.iter() {
|
||||||
match b {
|
match *b {
|
||||||
&Boolean::Is(_) => panic!(),
|
Boolean::Is(_) => panic!(),
|
||||||
&Boolean::Not(_) => panic!(),
|
Boolean::Not(_) => panic!(),
|
||||||
&Boolean::Constant(b) => {
|
Boolean::Constant(b) => {
|
||||||
assert!(b == (expected & 1 == 1));
|
assert!(b == (expected & 1 == 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -576,8 +575,7 @@ mod test {
|
|||||||
let r = a_bit.xor(cs.namespace(|| "xor"), &b_bit).unwrap();
|
let r = a_bit.xor(cs.namespace(|| "xor"), &b_bit).unwrap();
|
||||||
let r = {
|
let r = {
|
||||||
let mut cs = MultiEq::new(&mut cs);
|
let mut cs = MultiEq::new(&mut cs);
|
||||||
let r = UInt32::addmany(cs.namespace(|| "addition"), &[r, c_bit, d_bit]).unwrap();
|
UInt32::addmany(cs.namespace(|| "addition"), &[r, c_bit, d_bit]).unwrap()
|
||||||
r
|
|
||||||
};
|
};
|
||||||
|
|
||||||
assert!(cs.is_satisfied());
|
assert!(cs.is_satisfied());
|
||||||
@ -585,14 +583,14 @@ mod test {
|
|||||||
assert!(r.value == Some(expected));
|
assert!(r.value == Some(expected));
|
||||||
|
|
||||||
for b in r.bits.iter() {
|
for b in r.bits.iter() {
|
||||||
match b {
|
match *b {
|
||||||
&Boolean::Is(ref b) => {
|
Boolean::Is(ref b) => {
|
||||||
assert!(b.get_value().unwrap() == (expected & 1 == 1));
|
assert!(b.get_value().unwrap() == (expected & 1 == 1));
|
||||||
}
|
}
|
||||||
&Boolean::Not(ref b) => {
|
Boolean::Not(ref b) => {
|
||||||
assert!(!b.get_value().unwrap() == (expected & 1 == 1));
|
assert!(!b.get_value().unwrap() == (expected & 1 == 1));
|
||||||
}
|
}
|
||||||
&Boolean::Constant(_) => unreachable!(),
|
Boolean::Constant(_) => unreachable!(),
|
||||||
}
|
}
|
||||||
|
|
||||||
expected >>= 1;
|
expected >>= 1;
|
||||||
@ -628,8 +626,8 @@ mod test {
|
|||||||
|
|
||||||
let mut tmp = num;
|
let mut tmp = num;
|
||||||
for b in &b.bits {
|
for b in &b.bits {
|
||||||
match b {
|
match *b {
|
||||||
&Boolean::Constant(b) => {
|
Boolean::Constant(b) => {
|
||||||
assert_eq!(b, tmp & 1 == 1);
|
assert_eq!(b, tmp & 1 == 1);
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
|
@ -451,7 +451,7 @@ where
|
|||||||
};
|
};
|
||||||
|
|
||||||
Ok(Parameters {
|
Ok(Parameters {
|
||||||
vk: vk,
|
vk,
|
||||||
h: Arc::new(h.into_iter().map(|e| e.into_affine()).collect()),
|
h: Arc::new(h.into_iter().map(|e| e.into_affine()).collect()),
|
||||||
l: Arc::new(l.into_iter().map(|e| e.into_affine()).collect()),
|
l: Arc::new(l.into_iter().map(|e| e.into_affine()).collect()),
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ impl<E: Engine> Proof<E> {
|
|||||||
}
|
}
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
Ok(Proof { a: a, b: b, c: c })
|
Ok(Proof { a, b, c })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,13 +208,13 @@ impl<E: Engine> VerifyingKey<E> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Ok(VerifyingKey {
|
Ok(VerifyingKey {
|
||||||
alpha_g1: alpha_g1,
|
alpha_g1,
|
||||||
beta_g1: beta_g1,
|
beta_g1,
|
||||||
beta_g2: beta_g2,
|
beta_g2,
|
||||||
gamma_g2: gamma_g2,
|
gamma_g2,
|
||||||
delta_g1: delta_g1,
|
delta_g1,
|
||||||
delta_g2: delta_g2,
|
delta_g2,
|
||||||
ic: ic,
|
ic,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -376,7 +376,7 @@ impl<E: Engine> Parameters<E> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Ok(Parameters {
|
Ok(Parameters {
|
||||||
vk: vk,
|
vk,
|
||||||
h: Arc::new(h),
|
h: Arc::new(h),
|
||||||
l: Arc::new(l),
|
l: Arc::new(l),
|
||||||
a: Arc::new(a),
|
a: Arc::new(a),
|
||||||
|
@ -49,7 +49,7 @@ pub fn verify_proof<'a, E: Engine>(
|
|||||||
(&acc.into_affine().prepare(), &pvk.neg_gamma_g2),
|
(&acc.into_affine().prepare(), &pvk.neg_gamma_g2),
|
||||||
(&proof.c.prepare(), &pvk.neg_delta_g2),
|
(&proof.c.prepare(), &pvk.neg_delta_g2),
|
||||||
]
|
]
|
||||||
.into_iter(),
|
.iter(),
|
||||||
))
|
))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
== pvk.alpha_g1_beta_g2)
|
== pvk.alpha_g1_beta_g2)
|
||||||
|
@ -91,6 +91,7 @@ impl<E: ScalarEngine> Add<(E::Fr, Variable)> for LinearCombination<E> {
|
|||||||
impl<E: ScalarEngine> Sub<(E::Fr, Variable)> for LinearCombination<E> {
|
impl<E: ScalarEngine> Sub<(E::Fr, Variable)> for LinearCombination<E> {
|
||||||
type Output = LinearCombination<E>;
|
type Output = LinearCombination<E>;
|
||||||
|
|
||||||
|
#[allow(clippy::suspicious_arithmetic_impl)]
|
||||||
fn sub(self, (mut coeff, var): (E::Fr, Variable)) -> LinearCombination<E> {
|
fn sub(self, (mut coeff, var): (E::Fr, Variable)) -> LinearCombination<E> {
|
||||||
coeff.negate();
|
coeff.negate();
|
||||||
|
|
||||||
@ -213,7 +214,7 @@ impl Error for SynthesisError {
|
|||||||
|
|
||||||
impl fmt::Display for SynthesisError {
|
impl fmt::Display for SynthesisError {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
||||||
if let &SynthesisError::IoError(ref e) = self {
|
if let SynthesisError::IoError(ref e) = *self {
|
||||||
write!(f, "I/O error: ")?;
|
write!(f, "I/O error: ")?;
|
||||||
e.fmt(f)
|
e.fmt(f)
|
||||||
} else {
|
} else {
|
||||||
@ -278,7 +279,7 @@ pub trait ConstraintSystem<E: ScalarEngine>: Sized {
|
|||||||
fn get_root(&mut self) -> &mut Self::Root;
|
fn get_root(&mut self) -> &mut Self::Root;
|
||||||
|
|
||||||
/// Begin a namespace for this constraint system.
|
/// Begin a namespace for this constraint system.
|
||||||
fn namespace<'a, NR, N>(&'a mut self, name_fn: N) -> Namespace<'a, E, Self::Root>
|
fn namespace<NR, N>(&mut self, name_fn: N) -> Namespace<'_, E, Self::Root>
|
||||||
where
|
where
|
||||||
NR: Into<String>,
|
NR: Into<String>,
|
||||||
N: FnOnce() -> NR,
|
N: FnOnce() -> NR,
|
||||||
|
@ -23,7 +23,7 @@ mod implementation {
|
|||||||
// CPUs configured.
|
// CPUs configured.
|
||||||
pub(crate) fn new_with_cpus(cpus: usize) -> Worker {
|
pub(crate) fn new_with_cpus(cpus: usize) -> Worker {
|
||||||
Worker {
|
Worker {
|
||||||
cpus: cpus,
|
cpus,
|
||||||
pool: CpuPool::new(cpus),
|
pool: CpuPool::new(cpus),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,7 @@ use std::ffi::OsString;
|
|||||||
use std::os::windows::ffi::OsStringExt;
|
use std::os::windows::ffi::OsStringExt;
|
||||||
|
|
||||||
use zcash_primitives::{
|
use zcash_primitives::{
|
||||||
|
block::equihash,
|
||||||
merkle_tree::CommitmentTreeWitness,
|
merkle_tree::CommitmentTreeWitness,
|
||||||
note_encryption::sapling_ka_agree,
|
note_encryption::sapling_ka_agree,
|
||||||
primitives::{Diversifier, Note, PaymentAddress, ProofGenerationKey, ViewingKey},
|
primitives::{Diversifier, Note, PaymentAddress, ProofGenerationKey, ViewingKey},
|
||||||
@ -58,8 +59,6 @@ use zcash_proofs::{
|
|||||||
sapling::{SaplingProvingContext, SaplingVerificationContext},
|
sapling::{SaplingProvingContext, SaplingVerificationContext},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub mod equihash;
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ fn test_key_agreement() {
|
|||||||
let addr = loop {
|
let addr = loop {
|
||||||
let mut d = [0; 11];
|
let mut d = [0; 11];
|
||||||
rng.fill_bytes(&mut d);
|
rng.fill_bytes(&mut d);
|
||||||
match vk.into_payment_address(Diversifier(d), ¶ms) {
|
match vk.to_payment_address(Diversifier(d), ¶ms) {
|
||||||
Some(a) => break a,
|
Some(a) => break a,
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
|
@ -678,7 +678,7 @@ fn key_components() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let pgk = ProofGenerationKey { ak, nsk };
|
let pgk = ProofGenerationKey { ak, nsk };
|
||||||
let fvk = pgk.into_viewing_key(&JUBJUB);
|
let fvk = pgk.to_viewing_key(&JUBJUB);
|
||||||
{
|
{
|
||||||
let mut vec = Vec::new();
|
let mut vec = Vec::new();
|
||||||
fvk.nk.write(&mut vec).unwrap();
|
fvk.nk.write(&mut vec).unwrap();
|
||||||
@ -704,7 +704,7 @@ fn key_components() {
|
|||||||
let diversifier = Diversifier(tv.default_d);
|
let diversifier = Diversifier(tv.default_d);
|
||||||
assert!(librustzcash_check_diversifier(&tv.default_d));
|
assert!(librustzcash_check_diversifier(&tv.default_d));
|
||||||
|
|
||||||
let addr = fvk.into_payment_address(diversifier, &JUBJUB).unwrap();
|
let addr = fvk.to_payment_address(diversifier, &JUBJUB).unwrap();
|
||||||
{
|
{
|
||||||
let mut vec = Vec::new();
|
let mut vec = Vec::new();
|
||||||
addr.pk_d.write(&mut vec).unwrap();
|
addr.pk_d.write(&mut vec).unwrap();
|
||||||
|
@ -16,6 +16,7 @@ ff = { path = "../ff" }
|
|||||||
fpe = "0.2"
|
fpe = "0.2"
|
||||||
hex = "0.3"
|
hex = "0.3"
|
||||||
lazy_static = "1"
|
lazy_static = "1"
|
||||||
|
log = "0.4"
|
||||||
pairing = { path = "../pairing" }
|
pairing = { path = "../pairing" }
|
||||||
rand = "0.7"
|
rand = "0.7"
|
||||||
rand_core = "0.5"
|
rand_core = "0.5"
|
||||||
|
@ -6,12 +6,14 @@ use std::ops::Deref;
|
|||||||
|
|
||||||
use crate::serialize::Vector;
|
use crate::serialize::Vector;
|
||||||
|
|
||||||
|
pub mod equihash;
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct BlockHash(pub [u8; 32]);
|
pub struct BlockHash(pub [u8; 32]);
|
||||||
|
|
||||||
impl fmt::Display for BlockHash {
|
impl fmt::Display for BlockHash {
|
||||||
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
let mut data = self.0.clone();
|
let mut data = self.0;
|
||||||
data.reverse();
|
data.reverse();
|
||||||
formatter.write_str(&hex::encode(data))
|
formatter.write_str(&hex::encode(data))
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use blake2b_simd::{Hash as Blake2bHash, Params as Blake2bParams, State as Blake2bState};
|
use blake2b_simd::{Hash as Blake2bHash, Params as Blake2bParams, State as Blake2bState};
|
||||||
use byteorder::{BigEndian, LittleEndian, ReadBytesExt, WriteBytesExt};
|
use byteorder::{BigEndian, LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||||
|
use log::error;
|
||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
use std::mem::size_of;
|
use std::mem::size_of;
|
||||||
|
|
||||||
@ -60,10 +61,7 @@ impl Node {
|
|||||||
indices.extend(a.indices.iter());
|
indices.extend(a.indices.iter());
|
||||||
indices
|
indices
|
||||||
};
|
};
|
||||||
Node {
|
Node { hash, indices }
|
||||||
hash: hash,
|
|
||||||
indices: indices,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_children_ref(a: &Node, b: &Node, trim: usize) -> Self {
|
fn from_children_ref(a: &Node, b: &Node, trim: usize) -> Self {
|
||||||
@ -82,10 +80,7 @@ impl Node {
|
|||||||
indices.extend(b.indices.iter());
|
indices.extend(b.indices.iter());
|
||||||
indices.extend(a.indices.iter());
|
indices.extend(a.indices.iter());
|
||||||
}
|
}
|
||||||
Node {
|
Node { hash, indices }
|
||||||
hash: hash,
|
|
||||||
indices: indices,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn indices_before(&self, other: &Node) -> bool {
|
fn indices_before(&self, other: &Node) -> bool {
|
||||||
@ -141,7 +136,7 @@ fn expand_array(vin: &[u8], bit_len: usize, byte_pad: usize) -> Vec<u8> {
|
|||||||
|
|
||||||
let mut j = 0;
|
let mut j = 0;
|
||||||
for b in vin {
|
for b in vin {
|
||||||
acc_value = (acc_value << 8) | *b as u32;
|
acc_value = (acc_value << 8) | u32::from(*b);
|
||||||
acc_bits += 8;
|
acc_bits += 8;
|
||||||
|
|
||||||
// When we have bit_len or more bits in the accumulator, write the next
|
// When we have bit_len or more bits in the accumulator, write the next
|
||||||
@ -197,18 +192,18 @@ fn distinct_indices(a: &Node, b: &Node) -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn validate_subtrees(p: &Params, a: &Node, b: &Node) -> bool {
|
fn validate_subtrees(p: &Params, a: &Node, b: &Node) -> bool {
|
||||||
if !has_collision(a, b, p.collision_byte_length()) {
|
if !has_collision(a, b, p.collision_byte_length()) {
|
||||||
// error!("Invalid solution: invalid collision length between StepRows");
|
error!("Invalid solution: invalid collision length between StepRows");
|
||||||
false
|
false
|
||||||
} else if b.indices_before(a) {
|
} else if b.indices_before(a) {
|
||||||
// error!("Invalid solution: Index tree incorrectly ordered");
|
error!("Invalid solution: Index tree incorrectly ordered");
|
||||||
false
|
false
|
||||||
} else if !distinct_indices(a, b) {
|
} else if !distinct_indices(a, b) {
|
||||||
// error!("Invalid solution: duplicate indices");
|
error!("Invalid solution: duplicate indices");
|
||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
true
|
true
|
||||||
@ -222,7 +217,7 @@ pub fn is_valid_solution_iterative(
|
|||||||
nonce: &[u8],
|
nonce: &[u8],
|
||||||
indices: &[u32],
|
indices: &[u32],
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let p = Params { n: n, k: k };
|
let p = Params { n, k };
|
||||||
|
|
||||||
let mut state = initialise_state(p.n, p.k, p.hash_output());
|
let mut state = initialise_state(p.n, p.k, p.hash_output());
|
||||||
state.update(input);
|
state.update(input);
|
||||||
@ -249,7 +244,7 @@ pub fn is_valid_solution_iterative(
|
|||||||
}
|
}
|
||||||
|
|
||||||
assert!(rows.len() == 1);
|
assert!(rows.len() == 1);
|
||||||
return rows[0].is_zero(hash_len);
|
rows[0].is_zero(hash_len)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tree_validator(p: &Params, state: &Blake2bState, indices: &[u32]) -> Option<Node> {
|
fn tree_validator(p: &Params, state: &Blake2bState, indices: &[u32]) -> Option<Node> {
|
||||||
@ -281,7 +276,7 @@ pub fn is_valid_solution_recursive(
|
|||||||
nonce: &[u8],
|
nonce: &[u8],
|
||||||
indices: &[u32],
|
indices: &[u32],
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let p = Params { n: n, k: k };
|
let p = Params { n, k };
|
||||||
|
|
||||||
let mut state = initialise_state(p.n, p.k, p.hash_output());
|
let mut state = initialise_state(p.n, p.k, p.hash_output());
|
||||||
state.update(input);
|
state.update(input);
|
||||||
@ -297,7 +292,7 @@ pub fn is_valid_solution_recursive(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_valid_solution(n: u32, k: u32, input: &[u8], nonce: &[u8], soln: &[u8]) -> bool {
|
pub fn is_valid_solution(n: u32, k: u32, input: &[u8], nonce: &[u8], soln: &[u8]) -> bool {
|
||||||
let p = Params { n: n, k: k };
|
let p = Params { n, k };
|
||||||
let indices = indices_from_minimal(soln, p.collision_bit_length());
|
let indices = indices_from_minimal(soln, p.collision_bit_length());
|
||||||
|
|
||||||
// Recursive validation is faster
|
// Recursive validation is faster
|
@ -2,31 +2,31 @@
|
|||||||
/// This is chosen to be some random string that we couldn't have anticipated when we designed
|
/// This is chosen to be some random string that we couldn't have anticipated when we designed
|
||||||
/// the algorithm, for rigidity purposes.
|
/// the algorithm, for rigidity purposes.
|
||||||
/// We deliberately use an ASCII hex string of 32 bytes here.
|
/// We deliberately use an ASCII hex string of 32 bytes here.
|
||||||
pub const GH_FIRST_BLOCK: &'static [u8; 64] =
|
pub const GH_FIRST_BLOCK: &[u8; 64] =
|
||||||
b"096b36a5804bfacef1691e173c366a47ff5ba84a44f26ddd7e8d9f79d5b42df0";
|
b"096b36a5804bfacef1691e173c366a47ff5ba84a44f26ddd7e8d9f79d5b42df0";
|
||||||
|
|
||||||
// BLAKE2s invocation personalizations
|
// BLAKE2s invocation personalizations
|
||||||
/// BLAKE2s Personalization for CRH^ivk = BLAKE2s(ak | nk)
|
/// BLAKE2s Personalization for CRH^ivk = BLAKE2s(ak | nk)
|
||||||
pub const CRH_IVK_PERSONALIZATION: &'static [u8; 8] = b"Zcashivk";
|
pub const CRH_IVK_PERSONALIZATION: &[u8; 8] = b"Zcashivk";
|
||||||
|
|
||||||
/// BLAKE2s Personalization for PRF^nf = BLAKE2s(nk | rho)
|
/// BLAKE2s Personalization for PRF^nf = BLAKE2s(nk | rho)
|
||||||
pub const PRF_NF_PERSONALIZATION: &'static [u8; 8] = b"Zcash_nf";
|
pub const PRF_NF_PERSONALIZATION: &[u8; 8] = b"Zcash_nf";
|
||||||
|
|
||||||
// Group hash personalizations
|
// Group hash personalizations
|
||||||
/// BLAKE2s Personalization for Pedersen hash generators.
|
/// BLAKE2s Personalization for Pedersen hash generators.
|
||||||
pub const PEDERSEN_HASH_GENERATORS_PERSONALIZATION: &'static [u8; 8] = b"Zcash_PH";
|
pub const PEDERSEN_HASH_GENERATORS_PERSONALIZATION: &[u8; 8] = b"Zcash_PH";
|
||||||
|
|
||||||
/// BLAKE2s Personalization for the group hash for key diversification
|
/// BLAKE2s Personalization for the group hash for key diversification
|
||||||
pub const KEY_DIVERSIFICATION_PERSONALIZATION: &'static [u8; 8] = b"Zcash_gd";
|
pub const KEY_DIVERSIFICATION_PERSONALIZATION: &[u8; 8] = b"Zcash_gd";
|
||||||
|
|
||||||
/// BLAKE2s Personalization for the spending key base point
|
/// BLAKE2s Personalization for the spending key base point
|
||||||
pub const SPENDING_KEY_GENERATOR_PERSONALIZATION: &'static [u8; 8] = b"Zcash_G_";
|
pub const SPENDING_KEY_GENERATOR_PERSONALIZATION: &[u8; 8] = b"Zcash_G_";
|
||||||
|
|
||||||
/// BLAKE2s Personalization for the proof generation key base point
|
/// BLAKE2s Personalization for the proof generation key base point
|
||||||
pub const PROOF_GENERATION_KEY_BASE_GENERATOR_PERSONALIZATION: &'static [u8; 8] = b"Zcash_H_";
|
pub const PROOF_GENERATION_KEY_BASE_GENERATOR_PERSONALIZATION: &[u8; 8] = b"Zcash_H_";
|
||||||
|
|
||||||
/// BLAKE2s Personalization for the value commitment generator for the value
|
/// BLAKE2s Personalization for the value commitment generator for the value
|
||||||
pub const VALUE_COMMITMENT_GENERATOR_PERSONALIZATION: &'static [u8; 8] = b"Zcash_cv";
|
pub const VALUE_COMMITMENT_GENERATOR_PERSONALIZATION: &[u8; 8] = b"Zcash_cv";
|
||||||
|
|
||||||
/// BLAKE2s Personalization for the nullifier position generator (for computing rho)
|
/// BLAKE2s Personalization for the nullifier position generator (for computing rho)
|
||||||
pub const NULLIFIER_POSITION_IN_TREE_GENERATOR_PERSONALIZATION: &'static [u8; 8] = b"Zcash_J_";
|
pub const NULLIFIER_POSITION_IN_TREE_GENERATOR_PERSONALIZATION: &[u8; 8] = b"Zcash_J_";
|
||||||
|
@ -132,9 +132,9 @@ impl<E: JubjubEngine> Point<E, Unknown> {
|
|||||||
t.mul_assign(&y);
|
t.mul_assign(&y);
|
||||||
|
|
||||||
Some(Point {
|
Some(Point {
|
||||||
x: x,
|
x,
|
||||||
y: y,
|
y,
|
||||||
t: t,
|
t,
|
||||||
z: E::Fr::one(),
|
z: E::Fr::one(),
|
||||||
_marker: PhantomData,
|
_marker: PhantomData,
|
||||||
})
|
})
|
||||||
@ -168,7 +168,7 @@ impl<E: JubjubEngine> Point<E, Unknown> {
|
|||||||
|
|
||||||
impl<E: JubjubEngine, Subgroup> Point<E, Subgroup> {
|
impl<E: JubjubEngine, Subgroup> Point<E, Subgroup> {
|
||||||
pub fn write<W: Write>(&self, writer: W) -> io::Result<()> {
|
pub fn write<W: Write>(&self, writer: W) -> io::Result<()> {
|
||||||
let (x, y) = self.into_xy();
|
let (x, y) = self.to_xy();
|
||||||
|
|
||||||
assert_eq!(E::Fr::NUM_BITS, 255);
|
assert_eq!(E::Fr::NUM_BITS, 255);
|
||||||
|
|
||||||
@ -183,7 +183,7 @@ impl<E: JubjubEngine, Subgroup> Point<E, Subgroup> {
|
|||||||
|
|
||||||
/// Convert from a Montgomery point
|
/// Convert from a Montgomery point
|
||||||
pub fn from_montgomery(m: &montgomery::Point<E, Subgroup>, params: &E::Params) -> Self {
|
pub fn from_montgomery(m: &montgomery::Point<E, Subgroup>, params: &E::Params) -> Self {
|
||||||
match m.into_xy() {
|
match m.to_xy() {
|
||||||
None => {
|
None => {
|
||||||
// Map the point at infinity to the neutral element.
|
// Map the point at infinity to the neutral element.
|
||||||
Point::zero()
|
Point::zero()
|
||||||
@ -277,8 +277,8 @@ impl<E: JubjubEngine, Subgroup> Point<E, Subgroup> {
|
|||||||
Point {
|
Point {
|
||||||
x: u,
|
x: u,
|
||||||
y: v,
|
y: v,
|
||||||
t: t,
|
t,
|
||||||
z: z,
|
z,
|
||||||
_marker: PhantomData,
|
_marker: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -306,7 +306,7 @@ impl<E: JubjubEngine, Subgroup> Point<E, Subgroup> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn into_xy(&self) -> (E::Fr, E::Fr) {
|
pub fn to_xy(&self) -> (E::Fr, E::Fr) {
|
||||||
let zinv = self.z.inverse().unwrap();
|
let zinv = self.z.inverse().unwrap();
|
||||||
|
|
||||||
let mut x = self.x;
|
let mut x = self.x;
|
||||||
@ -412,7 +412,7 @@ impl<E: JubjubEngine, Subgroup> Point<E, Subgroup> {
|
|||||||
b.mul_assign(&other.y);
|
b.mul_assign(&other.y);
|
||||||
|
|
||||||
// C = d * t1 * t2
|
// C = d * t1 * t2
|
||||||
let mut c = params.edwards_d().clone();
|
let mut c = *params.edwards_d();
|
||||||
c.mul_assign(&self.t);
|
c.mul_assign(&self.t);
|
||||||
c.mul_assign(&other.t);
|
c.mul_assign(&other.t);
|
||||||
|
|
||||||
|
@ -321,8 +321,8 @@ impl Field for Fs {
|
|||||||
loop {
|
loop {
|
||||||
let mut tmp = {
|
let mut tmp = {
|
||||||
let mut repr = [0u64; 4];
|
let mut repr = [0u64; 4];
|
||||||
for i in 0..4 {
|
for limb in &mut repr {
|
||||||
repr[i] = rng.next_u64();
|
*limb = rng.next_u64();
|
||||||
}
|
}
|
||||||
Fs(FsRepr(repr))
|
Fs(FsRepr(repr))
|
||||||
};
|
};
|
||||||
|
@ -199,9 +199,9 @@ impl JubjubBls12 {
|
|||||||
)
|
)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
// A = 40962
|
// A = 40962
|
||||||
montgomery_a: montgomery_a,
|
montgomery_a,
|
||||||
// 2A = 2.A
|
// 2A = 2.A
|
||||||
montgomery_2a: montgomery_2a,
|
montgomery_2a,
|
||||||
// scaling factor = sqrt(4 / (a - d))
|
// scaling factor = sqrt(4 / (a - d))
|
||||||
scale: Fr::from_str(
|
scale: Fr::from_str(
|
||||||
"17814886934372412843466061268024708274627479829237077604635722030778476050649",
|
"17814886934372412843466061268024708274627479829237077604635722030778476050649",
|
||||||
@ -384,7 +384,7 @@ impl JubjubBls12 {
|
|||||||
|
|
||||||
// coeffs = g, g*2, g*3, g*4
|
// coeffs = g, g*2, g*3, g*4
|
||||||
for _ in 0..4 {
|
for _ in 0..4 {
|
||||||
coeffs.push(g.into_xy().expect("cannot produce O"));
|
coeffs.push(g.to_xy().expect("cannot produce O"));
|
||||||
g = g.add(&gen, &tmp_params);
|
g = g.add(&gen, &tmp_params);
|
||||||
}
|
}
|
||||||
windows.push(coeffs);
|
windows.push(coeffs);
|
||||||
@ -411,7 +411,7 @@ impl JubjubBls12 {
|
|||||||
let mut coeffs = vec![(Fr::zero(), Fr::one())];
|
let mut coeffs = vec![(Fr::zero(), Fr::one())];
|
||||||
let mut g = gen.clone();
|
let mut g = gen.clone();
|
||||||
for _ in 0..7 {
|
for _ in 0..7 {
|
||||||
coeffs.push(g.into_xy());
|
coeffs.push(g.to_xy());
|
||||||
g = g.add(&gen, &tmp_params);
|
g = g.add(&gen, &tmp_params);
|
||||||
}
|
}
|
||||||
windows.push(coeffs);
|
windows.push(coeffs);
|
||||||
|
@ -64,12 +64,12 @@ impl<E: JubjubEngine> Point<E, Unknown> {
|
|||||||
y.negate();
|
y.negate();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Some(Point {
|
Some(Point {
|
||||||
x: x,
|
x,
|
||||||
y: y,
|
y,
|
||||||
infinity: false,
|
infinity: false,
|
||||||
_marker: PhantomData,
|
_marker: PhantomData,
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
None => None,
|
None => None,
|
||||||
}
|
}
|
||||||
@ -88,9 +88,8 @@ impl<E: JubjubEngine> Point<E, Unknown> {
|
|||||||
let x = E::Fr::random(rng);
|
let x = E::Fr::random(rng);
|
||||||
let sign = rng.next_u32() % 2 != 0;
|
let sign = rng.next_u32() % 2 != 0;
|
||||||
|
|
||||||
match Self::get_for_x(x, sign, params) {
|
if let Some(p) = Self::get_for_x(x, sign, params) {
|
||||||
Some(p) => return p,
|
return p;
|
||||||
None => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -99,7 +98,7 @@ impl<E: JubjubEngine> Point<E, Unknown> {
|
|||||||
impl<E: JubjubEngine, Subgroup> Point<E, Subgroup> {
|
impl<E: JubjubEngine, Subgroup> Point<E, Subgroup> {
|
||||||
/// Convert from an Edwards point
|
/// Convert from an Edwards point
|
||||||
pub fn from_edwards(e: &edwards::Point<E, Subgroup>, params: &E::Params) -> Self {
|
pub fn from_edwards(e: &edwards::Point<E, Subgroup>, params: &E::Params) -> Self {
|
||||||
let (x, y) = e.into_xy();
|
let (x, y) = e.to_xy();
|
||||||
|
|
||||||
if y == E::Fr::one() {
|
if y == E::Fr::one() {
|
||||||
// The only solution for y = 1 is x = 0. (0, 1) is
|
// The only solution for y = 1 is x = 0. (0, 1) is
|
||||||
@ -178,7 +177,7 @@ impl<E: JubjubEngine, Subgroup> Point<E, Subgroup> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn into_xy(&self) -> Option<(E::Fr, E::Fr)> {
|
pub fn to_xy(&self) -> Option<(E::Fr, E::Fr)> {
|
||||||
if self.infinity {
|
if self.infinity {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
@ -214,7 +213,7 @@ impl<E: JubjubEngine, Subgroup> Point<E, Subgroup> {
|
|||||||
|
|
||||||
let mut delta = E::Fr::one();
|
let mut delta = E::Fr::one();
|
||||||
{
|
{
|
||||||
let mut tmp = params.montgomery_a().clone();
|
let mut tmp = *params.montgomery_a();
|
||||||
tmp.mul_assign(&self.x);
|
tmp.mul_assign(&self.x);
|
||||||
tmp.double();
|
tmp.double();
|
||||||
delta.add_assign(&tmp);
|
delta.add_assign(&tmp);
|
||||||
|
@ -119,13 +119,13 @@ fn test_mul_associativity<E: JubjubEngine>(params: &E::Params) {
|
|||||||
assert!(res2 == res3);
|
assert!(res2 == res3);
|
||||||
assert!(res3 == res4);
|
assert!(res3 == res4);
|
||||||
|
|
||||||
let (x, y) = res1.into_xy();
|
let (x, y) = res1.to_xy();
|
||||||
assert!(is_on_twisted_edwards_curve(x, y, params));
|
assert!(is_on_twisted_edwards_curve(x, y, params));
|
||||||
|
|
||||||
let (x, y) = res2.into_xy();
|
let (x, y) = res2.to_xy();
|
||||||
assert!(is_on_twisted_edwards_curve(x, y, params));
|
assert!(is_on_twisted_edwards_curve(x, y, params));
|
||||||
|
|
||||||
let (x, y) = res3.into_xy();
|
let (x, y) = res3.to_xy();
|
||||||
assert!(is_on_twisted_edwards_curve(x, y, params));
|
assert!(is_on_twisted_edwards_curve(x, y, params));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -238,7 +238,7 @@ fn test_get_for<E: JubjubEngine>(params: &E::Params) {
|
|||||||
let sign = rng.next_u32() % 2 == 1;
|
let sign = rng.next_u32() % 2 == 1;
|
||||||
|
|
||||||
if let Some(mut p) = edwards::Point::<E, _>::get_for_y(y, sign, params) {
|
if let Some(mut p) = edwards::Point::<E, _>::get_for_y(y, sign, params) {
|
||||||
assert!(p.into_xy().0.into_repr().is_odd() == sign);
|
assert!(p.to_xy().0.into_repr().is_odd() == sign);
|
||||||
p = p.negate();
|
p = p.negate();
|
||||||
assert!(edwards::Point::<E, _>::get_for_y(y, !sign, params).unwrap() == p);
|
assert!(edwards::Point::<E, _>::get_for_y(y, !sign, params).unwrap() == p);
|
||||||
}
|
}
|
||||||
@ -274,12 +274,12 @@ fn test_rand<E: JubjubEngine>(params: &E::Params) {
|
|||||||
let e = edwards::Point::<E, _>::rand(rng, params);
|
let e = edwards::Point::<E, _>::rand(rng, params);
|
||||||
|
|
||||||
{
|
{
|
||||||
let (x, y) = p.into_xy().unwrap();
|
let (x, y) = p.to_xy().unwrap();
|
||||||
assert!(is_on_mont_curve(x, y, params));
|
assert!(is_on_mont_curve(x, y, params));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let (x, y) = e.into_xy();
|
let (x, y) = e.to_xy();
|
||||||
assert!(is_on_twisted_edwards_curve(x, y, params));
|
assert!(is_on_twisted_edwards_curve(x, y, params));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,11 +10,11 @@ use blake2b_simd::{Hash as Blake2bHash, Params as Blake2bParams};
|
|||||||
use ff::{PrimeField, PrimeFieldRepr};
|
use ff::{PrimeField, PrimeFieldRepr};
|
||||||
use std::io::{self, Read, Write};
|
use std::io::{self, Read, Write};
|
||||||
|
|
||||||
pub const PRF_EXPAND_PERSONALIZATION: &'static [u8; 16] = b"Zcash_ExpandSeed";
|
pub const PRF_EXPAND_PERSONALIZATION: &[u8; 16] = b"Zcash_ExpandSeed";
|
||||||
|
|
||||||
/// PRF^expand(sk, t) := BLAKE2b-512("Zcash_ExpandSeed", sk || t)
|
/// PRF^expand(sk, t) := BLAKE2b-512("Zcash_ExpandSeed", sk || t)
|
||||||
pub fn prf_expand(sk: &[u8], t: &[u8]) -> Blake2bHash {
|
pub fn prf_expand(sk: &[u8], t: &[u8]) -> Blake2bHash {
|
||||||
prf_expand_vec(sk, &vec![t])
|
prf_expand_vec(sk, &[t])
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prf_expand_vec(sk: &[u8], ts: &[&[u8]]) -> Blake2bHash {
|
pub fn prf_expand_vec(sk: &[u8], ts: &[&[u8]]) -> Blake2bHash {
|
||||||
@ -111,7 +111,7 @@ impl<E: JubjubEngine> Clone for FullViewingKey<E> {
|
|||||||
ak: self.vk.ak.clone(),
|
ak: self.vk.ak.clone(),
|
||||||
nk: self.vk.nk.clone(),
|
nk: self.vk.nk.clone(),
|
||||||
},
|
},
|
||||||
ovk: self.ovk.clone(),
|
ovk: self.ovk,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -486,8 +486,10 @@ impl<Node: Hashable> CommitmentTreeWitness<Node> {
|
|||||||
// Given the position, let's finish constructing the authentication
|
// Given the position, let's finish constructing the authentication
|
||||||
// path
|
// path
|
||||||
let mut tmp = position;
|
let mut tmp = position;
|
||||||
for i in 0..depth {
|
for entry in auth_path.iter_mut() {
|
||||||
auth_path[i].as_mut().map(|p| p.1 = (tmp & 1) == 1);
|
if let Some(p) = entry {
|
||||||
|
p.1 = (tmp & 1) == 1;
|
||||||
|
}
|
||||||
|
|
||||||
tmp >>= 1;
|
tmp >>= 1;
|
||||||
}
|
}
|
||||||
|
@ -19,8 +19,8 @@ use std::str;
|
|||||||
|
|
||||||
use crate::{keys::OutgoingViewingKey, JUBJUB};
|
use crate::{keys::OutgoingViewingKey, JUBJUB};
|
||||||
|
|
||||||
pub const KDF_SAPLING_PERSONALIZATION: &'static [u8; 16] = b"Zcash_SaplingKDF";
|
pub const KDF_SAPLING_PERSONALIZATION: &[u8; 16] = b"Zcash_SaplingKDF";
|
||||||
pub const PRF_OCK_PERSONALIZATION: &'static [u8; 16] = b"Zcash_Derive_ock";
|
pub const PRF_OCK_PERSONALIZATION: &[u8; 16] = b"Zcash_Derive_ock";
|
||||||
|
|
||||||
const COMPACT_NOTE_SIZE: usize = (
|
const COMPACT_NOTE_SIZE: usize = (
|
||||||
1 + // version
|
1 + // version
|
||||||
@ -85,7 +85,7 @@ impl Default for Memo {
|
|||||||
|
|
||||||
impl PartialEq for Memo {
|
impl PartialEq for Memo {
|
||||||
fn eq(&self, rhs: &Memo) -> bool {
|
fn eq(&self, rhs: &Memo) -> bool {
|
||||||
&self.0[..] == &rhs.0[..]
|
self.0[..] == rhs.0[..]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,11 +106,6 @@ impl Memo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a `Memo` containing the given string, or `None` if the string is too long.
|
|
||||||
pub fn from_str(memo: &str) -> Option<Memo> {
|
|
||||||
Memo::from_bytes(memo.as_bytes())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the underlying bytes of the `Memo`.
|
/// Returns the underlying bytes of the `Memo`.
|
||||||
pub fn as_bytes(&self) -> &[u8] {
|
pub fn as_bytes(&self) -> &[u8] {
|
||||||
&self.0[..]
|
&self.0[..]
|
||||||
@ -134,6 +129,15 @@ impl Memo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl str::FromStr for Memo {
|
||||||
|
type Err = ();
|
||||||
|
|
||||||
|
/// Returns a `Memo` containing the given string, or an error if the string is too long.
|
||||||
|
fn from_str(memo: &str) -> Result<Self, Self::Err> {
|
||||||
|
Memo::from_bytes(memo.as_bytes()).ok_or(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn generate_esk<R: RngCore + CryptoRng>(rng: &mut R) -> Fs {
|
pub fn generate_esk<R: RngCore + CryptoRng>(rng: &mut R) -> Fs {
|
||||||
// create random 64 byte buffer
|
// create random 64 byte buffer
|
||||||
let mut buffer = [0u8; 64];
|
let mut buffer = [0u8; 64];
|
||||||
@ -557,6 +561,7 @@ mod tests {
|
|||||||
use pairing::bls12_381::{Bls12, Fr, FrRepr};
|
use pairing::bls12_381::{Bls12, Fr, FrRepr};
|
||||||
use rand_core::{CryptoRng, RngCore};
|
use rand_core::{CryptoRng, RngCore};
|
||||||
use rand_os::OsRng;
|
use rand_os::OsRng;
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
kdf_sapling, prf_ock, sapling_ka_agree, try_sapling_compact_note_decryption,
|
kdf_sapling, prf_ock, sapling_ka_agree, try_sapling_compact_note_decryption,
|
||||||
@ -661,7 +666,8 @@ mod tests {
|
|||||||
0x74, 0x20, 0x65, 0x6e, 0x6f, 0x75, 0x67, 0x68
|
0x74, 0x20, 0x65, 0x6e, 0x6f, 0x75, 0x67, 0x68
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
assert!(Memo::from_str(
|
assert_eq!(
|
||||||
|
Memo::from_str(
|
||||||
"thiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiis \
|
"thiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiis \
|
||||||
iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiis \
|
iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiis \
|
||||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \
|
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \
|
||||||
@ -669,8 +675,9 @@ mod tests {
|
|||||||
looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong \
|
looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong \
|
||||||
meeeeeeeeeeeeeeeeeeemooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo \
|
meeeeeeeeeeeeeeeeeeemooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo \
|
||||||
but it's now a bit too long"
|
but it's now a bit too long"
|
||||||
)
|
),
|
||||||
.is_none());
|
Err(())
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -39,7 +39,7 @@ pub struct ProofGenerationKey<E: JubjubEngine> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<E: JubjubEngine> ProofGenerationKey<E> {
|
impl<E: JubjubEngine> ProofGenerationKey<E> {
|
||||||
pub fn into_viewing_key(&self, params: &E::Params) -> ViewingKey<E> {
|
pub fn to_viewing_key(&self, params: &E::Params) -> ViewingKey<E> {
|
||||||
ViewingKey {
|
ViewingKey {
|
||||||
ak: self.ak.clone(),
|
ak: self.ak.clone(),
|
||||||
nk: params
|
nk: params
|
||||||
@ -89,7 +89,7 @@ impl<E: JubjubEngine> ViewingKey<E> {
|
|||||||
E::Fs::from_repr(e).expect("should be a valid scalar")
|
E::Fs::from_repr(e).expect("should be a valid scalar")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn into_payment_address(
|
pub fn to_payment_address(
|
||||||
&self,
|
&self,
|
||||||
diversifier: Diversifier,
|
diversifier: Diversifier,
|
||||||
params: &E::Params,
|
params: &E::Params,
|
||||||
@ -97,10 +97,7 @@ impl<E: JubjubEngine> ViewingKey<E> {
|
|||||||
diversifier.g_d(params).map(|g_d| {
|
diversifier.g_d(params).map(|g_d| {
|
||||||
let pk_d = g_d.mul(self.ivk(), params);
|
let pk_d = g_d.mul(self.ivk(), params);
|
||||||
|
|
||||||
PaymentAddress {
|
PaymentAddress { pk_d, diversifier }
|
||||||
pk_d: pk_d,
|
|
||||||
diversifier: diversifier,
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -145,9 +142,9 @@ impl<E: JubjubEngine> PaymentAddress<E> {
|
|||||||
params: &E::Params,
|
params: &E::Params,
|
||||||
) -> Option<Note<E>> {
|
) -> Option<Note<E>> {
|
||||||
self.g_d(params).map(|g_d| Note {
|
self.g_d(params).map(|g_d| Note {
|
||||||
value: value,
|
value,
|
||||||
r: randomness,
|
r: randomness,
|
||||||
g_d: g_d,
|
g_d,
|
||||||
pk_d: self.pk_d.clone(),
|
pk_d: self.pk_d.clone(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -245,6 +242,6 @@ impl<E: JubjubEngine> Note<E> {
|
|||||||
pub fn cm(&self, params: &E::Params) -> E::Fr {
|
pub fn cm(&self, params: &E::Params) -> E::Fr {
|
||||||
// The commitment is in the prime order subgroup, so mapping the
|
// The commitment is in the prime order subgroup, so mapping the
|
||||||
// commitment to the x-coordinate is an injective encoding.
|
// commitment to the x-coordinate is an injective encoding.
|
||||||
self.cm_full_point(params).into_xy().0
|
self.cm_full_point(params).to_xy().0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,12 +37,12 @@ pub fn merkle_hash(depth: usize, lhs: &FrRepr, rhs: &FrRepr) -> FrRepr {
|
|||||||
pedersen_hash::<Bls12, _>(
|
pedersen_hash::<Bls12, _>(
|
||||||
Personalization::MerkleTree(depth),
|
Personalization::MerkleTree(depth),
|
||||||
lhs.iter()
|
lhs.iter()
|
||||||
.map(|&x| x)
|
.copied()
|
||||||
.take(Fr::NUM_BITS as usize)
|
.take(Fr::NUM_BITS as usize)
|
||||||
.chain(rhs.iter().map(|&x| x).take(Fr::NUM_BITS as usize)),
|
.chain(rhs.iter().copied().take(Fr::NUM_BITS as usize)),
|
||||||
&JUBJUB,
|
&JUBJUB,
|
||||||
)
|
)
|
||||||
.into_xy()
|
.to_xy()
|
||||||
.0
|
.0
|
||||||
.into_repr()
|
.into_repr()
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,7 @@ impl Vector {
|
|||||||
F: Fn(&mut R) -> io::Result<E>,
|
F: Fn(&mut R) -> io::Result<E>,
|
||||||
{
|
{
|
||||||
let count = CompactSize::read(&mut reader)?;
|
let count = CompactSize::read(&mut reader)?;
|
||||||
(0..count).into_iter().map(|_| func(&mut reader)).collect()
|
(0..count).map(|_| func(&mut reader)).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write<W: Write, E, F>(mut writer: W, vec: &[E], func: F) -> io::Result<()>
|
pub fn write<W: Write, E, F>(mut writer: W, vec: &[E], func: F) -> io::Result<()>
|
||||||
|
@ -153,7 +153,7 @@ impl TransactionMetadata {
|
|||||||
/// they added (via the first call to [`Builder::add_sapling_spend`]) is the first
|
/// they added (via the first call to [`Builder::add_sapling_spend`]) is the first
|
||||||
/// [`SpendDescription`] in the transaction.
|
/// [`SpendDescription`] in the transaction.
|
||||||
pub fn spend_index(&self, n: usize) -> Option<usize> {
|
pub fn spend_index(&self, n: usize) -> Option<usize> {
|
||||||
self.spend_indices.get(n).map(|i| *i)
|
self.spend_indices.get(n).copied()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the index within the transaction of the [`OutputDescription`] corresponding
|
/// Returns the index within the transaction of the [`OutputDescription`] corresponding
|
||||||
@ -164,7 +164,7 @@ impl TransactionMetadata {
|
|||||||
/// they added (via the first call to [`Builder::add_sapling_output`]) is the first
|
/// they added (via the first call to [`Builder::add_sapling_output`]) is the first
|
||||||
/// [`OutputDescription`] in the transaction.
|
/// [`OutputDescription`] in the transaction.
|
||||||
pub fn output_index(&self, n: usize) -> Option<usize> {
|
pub fn output_index(&self, n: usize) -> Option<usize> {
|
||||||
self.output_indices.get(n).map(|i| *i)
|
self.output_indices.get(n).copied()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -394,7 +394,7 @@ impl<R: RngCore + CryptoRng> Builder<R> {
|
|||||||
|
|
||||||
let mut nullifier = [0u8; 32];
|
let mut nullifier = [0u8; 32];
|
||||||
nullifier.copy_from_slice(&spend.note.nf(
|
nullifier.copy_from_slice(&spend.note.nf(
|
||||||
&proof_generation_key.into_viewing_key(&JUBJUB),
|
&proof_generation_key.to_viewing_key(&JUBJUB),
|
||||||
spend.witness.position,
|
spend.witness.position,
|
||||||
&JUBJUB,
|
&JUBJUB,
|
||||||
));
|
));
|
||||||
@ -414,7 +414,7 @@ impl<R: RngCore + CryptoRng> Builder<R> {
|
|||||||
|
|
||||||
self.mtx.shielded_spends.push(SpendDescription {
|
self.mtx.shielded_spends.push(SpendDescription {
|
||||||
cv,
|
cv,
|
||||||
anchor: anchor,
|
anchor,
|
||||||
nullifier,
|
nullifier,
|
||||||
rk,
|
rk,
|
||||||
zkproof,
|
zkproof,
|
||||||
|
@ -166,12 +166,10 @@ impl SpendDescription {
|
|||||||
writer.write_all(&self.zkproof)?;
|
writer.write_all(&self.zkproof)?;
|
||||||
match self.spend_auth_sig {
|
match self.spend_auth_sig {
|
||||||
Some(sig) => sig.write(&mut writer),
|
Some(sig) => sig.write(&mut writer),
|
||||||
None => {
|
None => Err(io::Error::new(
|
||||||
return Err(io::Error::new(
|
|
||||||
io::ErrorKind::InvalidInput,
|
io::ErrorKind::InvalidInput,
|
||||||
"Missing spend auth signature",
|
"Missing spend auth signature",
|
||||||
));
|
)),
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -347,23 +345,20 @@ impl JSDescription {
|
|||||||
.map(|mac| reader.read_exact(mac))
|
.map(|mac| reader.read_exact(mac))
|
||||||
.collect::<io::Result<()>>()?;
|
.collect::<io::Result<()>>()?;
|
||||||
|
|
||||||
let proof = match use_groth {
|
let proof = if use_groth {
|
||||||
true => {
|
|
||||||
// Consensus rules (§4.3):
|
// Consensus rules (§4.3):
|
||||||
// - Canonical encoding is enforced in librustzcash_sprout_verify()
|
// - Canonical encoding is enforced in librustzcash_sprout_verify()
|
||||||
// - Proof validity is enforced in librustzcash_sprout_verify()
|
// - Proof validity is enforced in librustzcash_sprout_verify()
|
||||||
let mut proof = [0; GROTH_PROOF_SIZE];
|
let mut proof = [0; GROTH_PROOF_SIZE];
|
||||||
reader.read_exact(&mut proof)?;
|
reader.read_exact(&mut proof)?;
|
||||||
SproutProof::Groth(proof)
|
SproutProof::Groth(proof)
|
||||||
}
|
} else {
|
||||||
false => {
|
|
||||||
// Consensus rules (§4.3):
|
// Consensus rules (§4.3):
|
||||||
// - Canonical encoding is enforced by PHGRProof in zcashd
|
// - Canonical encoding is enforced by PHGRProof in zcashd
|
||||||
// - Proof validity is enforced by JSDescription::Verify() in zcashd
|
// - Proof validity is enforced by JSDescription::Verify() in zcashd
|
||||||
let mut proof = [0; PHGR_PROOF_SIZE];
|
let mut proof = [0; PHGR_PROOF_SIZE];
|
||||||
reader.read_exact(&mut proof)?;
|
reader.read_exact(&mut proof)?;
|
||||||
SproutProof::PHGR(proof)
|
SproutProof::PHGR(proof)
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut ciphertexts = [[0; 601]; ZC_NUM_JS_OUTPUTS];
|
let mut ciphertexts = [[0; 601]; ZC_NUM_JS_OUTPUTS];
|
||||||
|
@ -29,7 +29,7 @@ pub struct TxId(pub [u8; 32]);
|
|||||||
|
|
||||||
impl fmt::Display for TxId {
|
impl fmt::Display for TxId {
|
||||||
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
let mut data = self.0.clone();
|
let mut data = self.0;
|
||||||
data.reverse();
|
data.reverse();
|
||||||
formatter.write_str(&hex::encode(data))
|
formatter.write_str(&hex::encode(data))
|
||||||
}
|
}
|
||||||
@ -164,9 +164,10 @@ impl Transaction {
|
|||||||
let overwintered = (header >> 31) == 1;
|
let overwintered = (header >> 31) == 1;
|
||||||
let version = header & 0x7FFFFFFF;
|
let version = header & 0x7FFFFFFF;
|
||||||
|
|
||||||
let version_group_id = match overwintered {
|
let version_group_id = if overwintered {
|
||||||
true => reader.read_u32::<LittleEndian>()?,
|
reader.read_u32::<LittleEndian>()?
|
||||||
false => 0,
|
} else {
|
||||||
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
let is_overwinter_v3 = overwintered
|
let is_overwinter_v3 = overwintered
|
||||||
@ -185,9 +186,10 @@ impl Transaction {
|
|||||||
let vin = Vector::read(&mut reader, TxIn::read)?;
|
let vin = Vector::read(&mut reader, TxIn::read)?;
|
||||||
let vout = Vector::read(&mut reader, TxOut::read)?;
|
let vout = Vector::read(&mut reader, TxOut::read)?;
|
||||||
let lock_time = reader.read_u32::<LittleEndian>()?;
|
let lock_time = reader.read_u32::<LittleEndian>()?;
|
||||||
let expiry_height = match is_overwinter_v3 || is_sapling_v4 {
|
let expiry_height = if is_overwinter_v3 || is_sapling_v4 {
|
||||||
true => reader.read_u32::<LittleEndian>()?,
|
reader.read_u32::<LittleEndian>()?
|
||||||
false => 0,
|
} else {
|
||||||
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
let (value_balance, shielded_spends, shielded_outputs) = if is_sapling_v4 {
|
let (value_balance, shielded_spends, shielded_outputs) = if is_sapling_v4 {
|
||||||
@ -223,9 +225,10 @@ impl Transaction {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let binding_sig =
|
let binding_sig =
|
||||||
match is_sapling_v4 && !(shielded_spends.is_empty() && shielded_outputs.is_empty()) {
|
if is_sapling_v4 && !(shielded_spends.is_empty() && shielded_outputs.is_empty()) {
|
||||||
true => Some(Signature::read(&mut reader)?),
|
Some(Signature::read(&mut reader)?)
|
||||||
false => None,
|
} else {
|
||||||
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
Transaction::from_data(TransactionData {
|
Transaction::from_data(TransactionData {
|
||||||
|
@ -9,13 +9,13 @@ use super::{
|
|||||||
};
|
};
|
||||||
use crate::legacy::Script;
|
use crate::legacy::Script;
|
||||||
|
|
||||||
const ZCASH_SIGHASH_PERSONALIZATION_PREFIX: &'static [u8; 12] = b"ZcashSigHash";
|
const ZCASH_SIGHASH_PERSONALIZATION_PREFIX: &[u8; 12] = b"ZcashSigHash";
|
||||||
const ZCASH_PREVOUTS_HASH_PERSONALIZATION: &'static [u8; 16] = b"ZcashPrevoutHash";
|
const ZCASH_PREVOUTS_HASH_PERSONALIZATION: &[u8; 16] = b"ZcashPrevoutHash";
|
||||||
const ZCASH_SEQUENCE_HASH_PERSONALIZATION: &'static [u8; 16] = b"ZcashSequencHash";
|
const ZCASH_SEQUENCE_HASH_PERSONALIZATION: &[u8; 16] = b"ZcashSequencHash";
|
||||||
const ZCASH_OUTPUTS_HASH_PERSONALIZATION: &'static [u8; 16] = b"ZcashOutputsHash";
|
const ZCASH_OUTPUTS_HASH_PERSONALIZATION: &[u8; 16] = b"ZcashOutputsHash";
|
||||||
const ZCASH_JOINSPLITS_HASH_PERSONALIZATION: &'static [u8; 16] = b"ZcashJSplitsHash";
|
const ZCASH_JOINSPLITS_HASH_PERSONALIZATION: &[u8; 16] = b"ZcashJSplitsHash";
|
||||||
const ZCASH_SHIELDED_SPENDS_HASH_PERSONALIZATION: &'static [u8; 16] = b"ZcashSSpendsHash";
|
const ZCASH_SHIELDED_SPENDS_HASH_PERSONALIZATION: &[u8; 16] = b"ZcashSSpendsHash";
|
||||||
const ZCASH_SHIELDED_OUTPUTS_HASH_PERSONALIZATION: &'static [u8; 16] = b"ZcashSOutputHash";
|
const ZCASH_SHIELDED_OUTPUTS_HASH_PERSONALIZATION: &[u8; 16] = b"ZcashSOutputHash";
|
||||||
|
|
||||||
pub const SIGHASH_ALL: u32 = 1;
|
pub const SIGHASH_ALL: u32 = 1;
|
||||||
const SIGHASH_NONE: u32 = 2;
|
const SIGHASH_NONE: u32 = 2;
|
||||||
|
@ -16,8 +16,8 @@ use crate::{
|
|||||||
JUBJUB,
|
JUBJUB,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const ZIP32_SAPLING_MASTER_PERSONALIZATION: &'static [u8; 16] = b"ZcashIP32Sapling";
|
pub const ZIP32_SAPLING_MASTER_PERSONALIZATION: &[u8; 16] = b"ZcashIP32Sapling";
|
||||||
pub const ZIP32_SAPLING_FVFP_PERSONALIZATION: &'static [u8; 16] = b"ZcashSaplingFVFP";
|
pub const ZIP32_SAPLING_FVFP_PERSONALIZATION: &[u8; 16] = b"ZcashSaplingFVFP";
|
||||||
|
|
||||||
// Common helper functions
|
// Common helper functions
|
||||||
|
|
||||||
@ -83,9 +83,9 @@ impl ChildIndex {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn to_index(&self) -> u32 {
|
fn to_index(&self) -> u32 {
|
||||||
match self {
|
match *self {
|
||||||
&ChildIndex::Hardened(i) => i + (1 << 31),
|
ChildIndex::Hardened(i) => i + (1 << 31),
|
||||||
&ChildIndex::NonHardened(i) => i,
|
ChildIndex::NonHardened(i) => i,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -434,7 +434,7 @@ impl ExtendedFullViewingKey {
|
|||||||
Ok(ret) => ret,
|
Ok(ret) => ret,
|
||||||
Err(()) => return Err(()),
|
Err(()) => return Err(()),
|
||||||
};
|
};
|
||||||
match self.fvk.vk.into_payment_address(d_j, &JUBJUB) {
|
match self.fvk.vk.to_payment_address(d_j, &JUBJUB) {
|
||||||
Some(addr) => Ok((j, addr)),
|
Some(addr) => Ok((j, addr)),
|
||||||
None => Err(()),
|
None => Err(()),
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ fn main() {
|
|||||||
nsk: nsk.clone(),
|
nsk: nsk.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let viewing_key = proof_generation_key.into_viewing_key(jubjub_params);
|
let viewing_key = proof_generation_key.to_viewing_key(jubjub_params);
|
||||||
|
|
||||||
let payment_address;
|
let payment_address;
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ fn main() {
|
|||||||
Diversifier(d)
|
Diversifier(d)
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(p) = viewing_key.into_payment_address(diversifier, jubjub_params) {
|
if let Some(p) = viewing_key.to_payment_address(diversifier, jubjub_params) {
|
||||||
payment_address = p;
|
payment_address = p;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -41,16 +41,16 @@ where
|
|||||||
{
|
{
|
||||||
let chunk_a = chunk
|
let chunk_a = chunk
|
||||||
.get(0)
|
.get(0)
|
||||||
.map(|e| e.clone())
|
.cloned()
|
||||||
.unwrap_or(Boolean::constant(false));
|
.unwrap_or_else(|| Boolean::constant(false));
|
||||||
let chunk_b = chunk
|
let chunk_b = chunk
|
||||||
.get(1)
|
.get(1)
|
||||||
.map(|e| e.clone())
|
.cloned()
|
||||||
.unwrap_or(Boolean::constant(false));
|
.unwrap_or_else(|| Boolean::constant(false));
|
||||||
let chunk_c = chunk
|
let chunk_c = chunk
|
||||||
.get(2)
|
.get(2)
|
||||||
.map(|e| e.clone())
|
.cloned()
|
||||||
.unwrap_or(Boolean::constant(false));
|
.unwrap_or_else(|| Boolean::constant(false));
|
||||||
|
|
||||||
let (x, y) = lookup3_xy(
|
let (x, y) = lookup3_xy(
|
||||||
cs.namespace(|| format!("window table lookup {}", i)),
|
cs.namespace(|| format!("window table lookup {}", i)),
|
||||||
@ -58,7 +58,7 @@ where
|
|||||||
window,
|
window,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let p = EdwardsPoint { x: x, y: y };
|
let p = EdwardsPoint { x, y };
|
||||||
|
|
||||||
if result.is_none() {
|
if result.is_none() {
|
||||||
result = Some(p);
|
result = Some(p);
|
||||||
@ -121,9 +121,9 @@ impl<E: JubjubEngine> EdwardsPoint<E> {
|
|||||||
{
|
{
|
||||||
let mut tmp = vec![];
|
let mut tmp = vec![];
|
||||||
|
|
||||||
let x = self.x.into_bits_le_strict(cs.namespace(|| "unpack x"))?;
|
let x = self.x.to_bits_le_strict(cs.namespace(|| "unpack x"))?;
|
||||||
|
|
||||||
let y = self.y.into_bits_le_strict(cs.namespace(|| "unpack y"))?;
|
let y = self.y.to_bits_le_strict(cs.namespace(|| "unpack y"))?;
|
||||||
|
|
||||||
tmp.extend(y);
|
tmp.extend(y);
|
||||||
tmp.push(x[0].clone());
|
tmp.push(x[0].clone());
|
||||||
@ -141,7 +141,7 @@ impl<E: JubjubEngine> EdwardsPoint<E> {
|
|||||||
where
|
where
|
||||||
CS: ConstraintSystem<E>,
|
CS: ConstraintSystem<E>,
|
||||||
{
|
{
|
||||||
let p = p.map(|p| p.into_xy());
|
let p = p.map(|p| p.to_xy());
|
||||||
|
|
||||||
// Allocate x
|
// Allocate x
|
||||||
let x = AllocatedNum::alloc(cs.namespace(|| "x"), || Ok(p.get()?.0))?;
|
let x = AllocatedNum::alloc(cs.namespace(|| "x"), || Ok(p.get()?.0))?;
|
||||||
@ -508,7 +508,7 @@ impl<E: JubjubEngine> MontgomeryPoint<E> {
|
|||||||
/// a point in the birationally equivalent twisted
|
/// a point in the birationally equivalent twisted
|
||||||
/// Edwards curve.
|
/// Edwards curve.
|
||||||
pub fn into_edwards<CS>(
|
pub fn into_edwards<CS>(
|
||||||
&self,
|
self,
|
||||||
mut cs: CS,
|
mut cs: CS,
|
||||||
params: &E::Params,
|
params: &E::Params,
|
||||||
) -> Result<EdwardsPoint<E>, SynthesisError>
|
) -> Result<EdwardsPoint<E>, SynthesisError>
|
||||||
@ -570,7 +570,7 @@ impl<E: JubjubEngine> MontgomeryPoint<E> {
|
|||||||
/// on the curve. Useful for constants and
|
/// on the curve. Useful for constants and
|
||||||
/// window table lookups.
|
/// window table lookups.
|
||||||
pub fn interpret_unchecked(x: Num<E>, y: Num<E>) -> Self {
|
pub fn interpret_unchecked(x: Num<E>, y: Num<E>) -> Self {
|
||||||
MontgomeryPoint { x: x, y: y }
|
MontgomeryPoint { x, y }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Performs an affine point addition, not defined for
|
/// Performs an affine point addition, not defined for
|
||||||
@ -688,8 +688,8 @@ mod test {
|
|||||||
let mut cs = TestConstraintSystem::<Bls12>::new();
|
let mut cs = TestConstraintSystem::<Bls12>::new();
|
||||||
|
|
||||||
let p = montgomery::Point::<Bls12, _>::rand(rng, params);
|
let p = montgomery::Point::<Bls12, _>::rand(rng, params);
|
||||||
let (u, v) = edwards::Point::from_montgomery(&p, params).into_xy();
|
let (u, v) = edwards::Point::from_montgomery(&p, params).to_xy();
|
||||||
let (x, y) = p.into_xy().unwrap();
|
let (x, y) = p.to_xy().unwrap();
|
||||||
|
|
||||||
let numx = AllocatedNum::alloc(cs.namespace(|| "mont x"), || Ok(x)).unwrap();
|
let numx = AllocatedNum::alloc(cs.namespace(|| "mont x"), || Ok(x)).unwrap();
|
||||||
let numy = AllocatedNum::alloc(cs.namespace(|| "mont y"), || Ok(y)).unwrap();
|
let numy = AllocatedNum::alloc(cs.namespace(|| "mont y"), || Ok(y)).unwrap();
|
||||||
@ -728,7 +728,7 @@ mod test {
|
|||||||
let mut cs = TestConstraintSystem::<Bls12>::new();
|
let mut cs = TestConstraintSystem::<Bls12>::new();
|
||||||
let q = EdwardsPoint::witness(&mut cs, Some(p.clone()), ¶ms).unwrap();
|
let q = EdwardsPoint::witness(&mut cs, Some(p.clone()), ¶ms).unwrap();
|
||||||
|
|
||||||
let p = p.into_xy();
|
let p = p.to_xy();
|
||||||
|
|
||||||
assert!(cs.is_satisfied());
|
assert!(cs.is_satisfied());
|
||||||
assert_eq!(q.x.get_value().unwrap(), p.0);
|
assert_eq!(q.x.get_value().unwrap(), p.0);
|
||||||
@ -737,7 +737,7 @@ mod test {
|
|||||||
|
|
||||||
for _ in 0..100 {
|
for _ in 0..100 {
|
||||||
let p = edwards::Point::<Bls12, _>::rand(rng, ¶ms);
|
let p = edwards::Point::<Bls12, _>::rand(rng, ¶ms);
|
||||||
let (x, y) = p.into_xy();
|
let (x, y) = p.to_xy();
|
||||||
|
|
||||||
let mut cs = TestConstraintSystem::<Bls12>::new();
|
let mut cs = TestConstraintSystem::<Bls12>::new();
|
||||||
let numx = AllocatedNum::alloc(cs.namespace(|| "x"), || Ok(x)).unwrap();
|
let numx = AllocatedNum::alloc(cs.namespace(|| "x"), || Ok(x)).unwrap();
|
||||||
@ -779,7 +779,7 @@ mod test {
|
|||||||
let p = params.generator(FixedGenerators::NoteCommitmentRandomness);
|
let p = params.generator(FixedGenerators::NoteCommitmentRandomness);
|
||||||
let s = Fs::random(rng);
|
let s = Fs::random(rng);
|
||||||
let q = p.mul(s, params);
|
let q = p.mul(s, params);
|
||||||
let (x1, y1) = q.into_xy();
|
let (x1, y1) = q.to_xy();
|
||||||
|
|
||||||
let mut s_bits = BitIterator::new(s.into_repr()).collect::<Vec<_>>();
|
let mut s_bits = BitIterator::new(s.into_repr()).collect::<Vec<_>>();
|
||||||
s_bits.reverse();
|
s_bits.reverse();
|
||||||
@ -823,8 +823,8 @@ mod test {
|
|||||||
let s = Fs::random(rng);
|
let s = Fs::random(rng);
|
||||||
let q = p.mul(s, params);
|
let q = p.mul(s, params);
|
||||||
|
|
||||||
let (x0, y0) = p.into_xy();
|
let (x0, y0) = p.to_xy();
|
||||||
let (x1, y1) = q.into_xy();
|
let (x1, y1) = q.to_xy();
|
||||||
|
|
||||||
let num_x0 = AllocatedNum::alloc(cs.namespace(|| "x0"), || Ok(x0)).unwrap();
|
let num_x0 = AllocatedNum::alloc(cs.namespace(|| "x0"), || Ok(x0)).unwrap();
|
||||||
let num_y0 = AllocatedNum::alloc(cs.namespace(|| "y0"), || Ok(y0)).unwrap();
|
let num_y0 = AllocatedNum::alloc(cs.namespace(|| "y0"), || Ok(y0)).unwrap();
|
||||||
@ -873,7 +873,7 @@ mod test {
|
|||||||
|
|
||||||
let p = edwards::Point::<Bls12, _>::rand(rng, params);
|
let p = edwards::Point::<Bls12, _>::rand(rng, params);
|
||||||
|
|
||||||
let (x0, y0) = p.into_xy();
|
let (x0, y0) = p.to_xy();
|
||||||
|
|
||||||
let num_x0 = AllocatedNum::alloc(cs.namespace(|| "x0"), || Ok(x0)).unwrap();
|
let num_x0 = AllocatedNum::alloc(cs.namespace(|| "x0"), || Ok(x0)).unwrap();
|
||||||
let num_y0 = AllocatedNum::alloc(cs.namespace(|| "y0"), || Ok(y0)).unwrap();
|
let num_y0 = AllocatedNum::alloc(cs.namespace(|| "y0"), || Ok(y0)).unwrap();
|
||||||
@ -941,9 +941,9 @@ mod test {
|
|||||||
|
|
||||||
let p3 = p1.add(&p2, params);
|
let p3 = p1.add(&p2, params);
|
||||||
|
|
||||||
let (x0, y0) = p1.into_xy();
|
let (x0, y0) = p1.to_xy();
|
||||||
let (x1, y1) = p2.into_xy();
|
let (x1, y1) = p2.to_xy();
|
||||||
let (x2, y2) = p3.into_xy();
|
let (x2, y2) = p3.to_xy();
|
||||||
|
|
||||||
let mut cs = TestConstraintSystem::<Bls12>::new();
|
let mut cs = TestConstraintSystem::<Bls12>::new();
|
||||||
|
|
||||||
@ -1002,8 +1002,8 @@ mod test {
|
|||||||
let p1 = edwards::Point::<Bls12, _>::rand(rng, params);
|
let p1 = edwards::Point::<Bls12, _>::rand(rng, params);
|
||||||
let p2 = p1.double(params);
|
let p2 = p1.double(params);
|
||||||
|
|
||||||
let (x0, y0) = p1.into_xy();
|
let (x0, y0) = p1.to_xy();
|
||||||
let (x1, y1) = p2.into_xy();
|
let (x1, y1) = p2.to_xy();
|
||||||
|
|
||||||
let mut cs = TestConstraintSystem::<Bls12>::new();
|
let mut cs = TestConstraintSystem::<Bls12>::new();
|
||||||
|
|
||||||
@ -1053,9 +1053,9 @@ mod test {
|
|||||||
|
|
||||||
let p3 = p1.add(&p2, params);
|
let p3 = p1.add(&p2, params);
|
||||||
|
|
||||||
let (x0, y0) = p1.into_xy().unwrap();
|
let (x0, y0) = p1.to_xy().unwrap();
|
||||||
let (x1, y1) = p2.into_xy().unwrap();
|
let (x1, y1) = p2.to_xy().unwrap();
|
||||||
let (x2, y2) = p3.into_xy().unwrap();
|
let (x2, y2) = p3.to_xy().unwrap();
|
||||||
|
|
||||||
let mut cs = TestConstraintSystem::<Bls12>::new();
|
let mut cs = TestConstraintSystem::<Bls12>::new();
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ fn get_constant_bools(person: &Personalization) -> Vec<Boolean> {
|
|||||||
person
|
person
|
||||||
.get_bits()
|
.get_bits()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|e| Boolean::constant(e))
|
.map(Boolean::constant)
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,7 +65,7 @@ where
|
|||||||
|
|
||||||
segment_windows = &segment_windows[1..];
|
segment_windows = &segment_windows[1..];
|
||||||
|
|
||||||
if segment_windows.len() == 0 {
|
if segment_windows.is_empty() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,7 +189,7 @@ mod test {
|
|||||||
input.clone().into_iter(),
|
input.clone().into_iter(),
|
||||||
params,
|
params,
|
||||||
)
|
)
|
||||||
.into_xy();
|
.to_xy();
|
||||||
|
|
||||||
assert_eq!(res.get_x().get_value().unwrap(), expected.0);
|
assert_eq!(res.get_x().get_value().unwrap(), expected.0);
|
||||||
assert_eq!(res.get_y().get_value().unwrap(), expected.1);
|
assert_eq!(res.get_y().get_value().unwrap(), expected.1);
|
||||||
@ -200,7 +200,7 @@ mod test {
|
|||||||
input.into_iter(),
|
input.into_iter(),
|
||||||
params,
|
params,
|
||||||
)
|
)
|
||||||
.into_xy();
|
.to_xy();
|
||||||
|
|
||||||
assert!(res.get_x().get_value().unwrap() != unexpected.0);
|
assert!(res.get_x().get_value().unwrap() != unexpected.0);
|
||||||
assert!(res.get_y().get_value().unwrap() != unexpected.1);
|
assert!(res.get_y().get_value().unwrap() != unexpected.1);
|
||||||
|
@ -150,7 +150,7 @@ impl<'a, E: JubjubEngine> Circuit<E> for Spend<'a, E> {
|
|||||||
// Witness nsk as bits
|
// Witness nsk as bits
|
||||||
let nsk = boolean::field_into_boolean_vec_le(
|
let nsk = boolean::field_into_boolean_vec_le(
|
||||||
cs.namespace(|| "nsk"),
|
cs.namespace(|| "nsk"),
|
||||||
self.proof_generation_key.as_ref().map(|k| k.nsk.clone()),
|
self.proof_generation_key.as_ref().map(|k| k.nsk),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// NB: We don't ensure that the bit representation of nsk
|
// NB: We don't ensure that the bit representation of nsk
|
||||||
@ -336,8 +336,8 @@ impl<'a, E: JubjubEngine> Circuit<E> for Spend<'a, E> {
|
|||||||
// they will be unable to find an authentication path in the
|
// they will be unable to find an authentication path in the
|
||||||
// tree with high probability.
|
// tree with high probability.
|
||||||
let mut preimage = vec![];
|
let mut preimage = vec![];
|
||||||
preimage.extend(xl.into_bits_le(cs.namespace(|| "xl into bits"))?);
|
preimage.extend(xl.to_bits_le(cs.namespace(|| "xl into bits"))?);
|
||||||
preimage.extend(xr.into_bits_le(cs.namespace(|| "xr into bits"))?);
|
preimage.extend(xr.to_bits_le(cs.namespace(|| "xr into bits"))?);
|
||||||
|
|
||||||
// Compute the new subtree value
|
// Compute the new subtree value
|
||||||
cur = pedersen_hash::pedersen_hash(
|
cur = pedersen_hash::pedersen_hash(
|
||||||
@ -464,7 +464,7 @@ impl<'a, E: JubjubEngine> Circuit<E> for Output<'a, E> {
|
|||||||
// they would like.
|
// they would like.
|
||||||
{
|
{
|
||||||
// Just grab pk_d from the witness
|
// Just grab pk_d from the witness
|
||||||
let pk_d = self.payment_address.as_ref().map(|e| e.pk_d.into_xy());
|
let pk_d = self.payment_address.as_ref().map(|e| e.pk_d.to_xy());
|
||||||
|
|
||||||
// Witness the y-coordinate, encoded as little
|
// Witness the y-coordinate, encoded as little
|
||||||
// endian bits (to match the representation)
|
// endian bits (to match the representation)
|
||||||
@ -567,7 +567,7 @@ fn test_input_circuit_with_bls12_381() {
|
|||||||
nsk: nsk.clone(),
|
nsk: nsk.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let viewing_key = proof_generation_key.into_viewing_key(params);
|
let viewing_key = proof_generation_key.to_viewing_key(params);
|
||||||
|
|
||||||
let payment_address;
|
let payment_address;
|
||||||
|
|
||||||
@ -578,7 +578,7 @@ fn test_input_circuit_with_bls12_381() {
|
|||||||
Diversifier(d)
|
Diversifier(d)
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(p) = viewing_key.into_payment_address(diversifier, params) {
|
if let Some(p) = viewing_key.to_payment_address(diversifier, params) {
|
||||||
payment_address = p;
|
payment_address = p;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -590,8 +590,8 @@ fn test_input_circuit_with_bls12_381() {
|
|||||||
let ar = fs::Fs::random(rng);
|
let ar = fs::Fs::random(rng);
|
||||||
|
|
||||||
{
|
{
|
||||||
let rk = viewing_key.rk(ar, params).into_xy();
|
let rk = viewing_key.rk(ar, params).to_xy();
|
||||||
let expected_value_cm = value_commitment.cm(params).into_xy();
|
let expected_value_cm = value_commitment.cm(params).to_xy();
|
||||||
let note = Note {
|
let note = Note {
|
||||||
value: value_commitment.value,
|
value: value_commitment.value,
|
||||||
g_d: g_d.clone(),
|
g_d: g_d.clone(),
|
||||||
@ -626,7 +626,7 @@ fn test_input_circuit_with_bls12_381() {
|
|||||||
.chain(rhs.into_iter().take(Fr::NUM_BITS as usize)),
|
.chain(rhs.into_iter().take(Fr::NUM_BITS as usize)),
|
||||||
params,
|
params,
|
||||||
)
|
)
|
||||||
.into_xy()
|
.to_xy()
|
||||||
.0;
|
.0;
|
||||||
|
|
||||||
if b {
|
if b {
|
||||||
@ -642,7 +642,7 @@ fn test_input_circuit_with_bls12_381() {
|
|||||||
let mut cs = TestConstraintSystem::<Bls12>::new();
|
let mut cs = TestConstraintSystem::<Bls12>::new();
|
||||||
|
|
||||||
let instance = Spend {
|
let instance = Spend {
|
||||||
params: params,
|
params,
|
||||||
value_commitment: Some(value_commitment.clone()),
|
value_commitment: Some(value_commitment.clone()),
|
||||||
proof_generation_key: Some(proof_generation_key.clone()),
|
proof_generation_key: Some(proof_generation_key.clone()),
|
||||||
payment_address: Some(payment_address.clone()),
|
payment_address: Some(payment_address.clone()),
|
||||||
@ -714,7 +714,7 @@ fn test_output_circuit_with_bls12_381() {
|
|||||||
nsk: nsk.clone(),
|
nsk: nsk.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let viewing_key = proof_generation_key.into_viewing_key(params);
|
let viewing_key = proof_generation_key.to_viewing_key(params);
|
||||||
|
|
||||||
let payment_address;
|
let payment_address;
|
||||||
|
|
||||||
@ -725,7 +725,7 @@ fn test_output_circuit_with_bls12_381() {
|
|||||||
Diversifier(d)
|
Diversifier(d)
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(p) = viewing_key.into_payment_address(diversifier, params) {
|
if let Some(p) = viewing_key.to_payment_address(diversifier, params) {
|
||||||
payment_address = p;
|
payment_address = p;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -738,7 +738,7 @@ fn test_output_circuit_with_bls12_381() {
|
|||||||
let mut cs = TestConstraintSystem::<Bls12>::new();
|
let mut cs = TestConstraintSystem::<Bls12>::new();
|
||||||
|
|
||||||
let instance = Output {
|
let instance = Output {
|
||||||
params: params,
|
params,
|
||||||
value_commitment: Some(value_commitment.clone()),
|
value_commitment: Some(value_commitment.clone()),
|
||||||
payment_address: Some(payment_address.clone()),
|
payment_address: Some(payment_address.clone()),
|
||||||
commitment_randomness: Some(commitment_randomness),
|
commitment_randomness: Some(commitment_randomness),
|
||||||
@ -759,13 +759,13 @@ fn test_output_circuit_with_bls12_381() {
|
|||||||
.expect("should be valid")
|
.expect("should be valid")
|
||||||
.cm(params);
|
.cm(params);
|
||||||
|
|
||||||
let expected_value_cm = value_commitment.cm(params).into_xy();
|
let expected_value_cm = value_commitment.cm(params).to_xy();
|
||||||
|
|
||||||
let expected_epk = payment_address
|
let expected_epk = payment_address
|
||||||
.g_d(params)
|
.g_d(params)
|
||||||
.expect("should be valid")
|
.expect("should be valid")
|
||||||
.mul(esk, params);
|
.mul(esk, params);
|
||||||
let expected_epk_xy = expected_epk.into_xy();
|
let expected_epk_xy = expected_epk.to_xy();
|
||||||
|
|
||||||
assert_eq!(cs.num_inputs(), 6);
|
assert_eq!(cs.num_inputs(), 6);
|
||||||
assert_eq!(cs.get_input(0, "ONE"), Fr::one());
|
assert_eq!(cs.get_input(0, "ONE"), Fr::one());
|
||||||
|
@ -54,7 +54,7 @@ impl InputNote {
|
|||||||
// Witness into the merkle tree
|
// Witness into the merkle tree
|
||||||
let mut cur = cm.clone();
|
let mut cur = cm.clone();
|
||||||
|
|
||||||
for (i, layer) in auth_path.into_iter().enumerate() {
|
for (i, layer) in auth_path.iter().enumerate() {
|
||||||
let cs = &mut cs.namespace(|| format!("layer {}", i));
|
let cs = &mut cs.namespace(|| format!("layer {}", i));
|
||||||
|
|
||||||
let cur_is_right = AllocatedBit::alloc(
|
let cur_is_right = AllocatedBit::alloc(
|
||||||
@ -112,7 +112,7 @@ impl InputNote {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(InputNote { mac: mac, nf: nf })
|
Ok(InputNote { mac, nf })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,10 +234,7 @@ impl NoteValue {
|
|||||||
)?);
|
)?);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(NoteValue {
|
Ok(NoteValue { value, bits })
|
||||||
value: value,
|
|
||||||
bits: bits,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Encodes the bits of the value into little-endian
|
/// Encodes the bits of the value into little-endian
|
||||||
@ -247,7 +244,7 @@ impl NoteValue {
|
|||||||
.chunks(8)
|
.chunks(8)
|
||||||
.flat_map(|v| v.iter().rev())
|
.flat_map(|v| v.iter().rev())
|
||||||
.cloned()
|
.cloned()
|
||||||
.map(|e| Boolean::from(e))
|
.map(Boolean::from)
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -380,11 +377,11 @@ fn test_sprout_constraints() {
|
|||||||
let a_sk = Some(SpendingKey(get_u256(&mut test_vector)));
|
let a_sk = Some(SpendingKey(get_u256(&mut test_vector)));
|
||||||
|
|
||||||
inputs.push(JSInput {
|
inputs.push(JSInput {
|
||||||
value: value,
|
value,
|
||||||
a_sk: a_sk,
|
a_sk,
|
||||||
rho: rho,
|
rho,
|
||||||
r: r,
|
r,
|
||||||
auth_path: auth_path,
|
auth_path,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -396,11 +393,7 @@ fn test_sprout_constraints() {
|
|||||||
get_u256(&mut test_vector);
|
get_u256(&mut test_vector);
|
||||||
let r = Some(CommitmentRandomness(get_u256(&mut test_vector)));
|
let r = Some(CommitmentRandomness(get_u256(&mut test_vector)));
|
||||||
|
|
||||||
outputs.push(JSOutput {
|
outputs.push(JSOutput { value, a_pk, r });
|
||||||
value: value,
|
|
||||||
a_pk: a_pk,
|
|
||||||
r: r,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let vpub_old = Some(test_vector.read_u64::<LittleEndian>().unwrap());
|
let vpub_old = Some(test_vector.read_u64::<LittleEndian>().unwrap());
|
||||||
@ -416,13 +409,13 @@ fn test_sprout_constraints() {
|
|||||||
let mac2 = get_u256(&mut test_vector);
|
let mac2 = get_u256(&mut test_vector);
|
||||||
|
|
||||||
let js = JoinSplit {
|
let js = JoinSplit {
|
||||||
vpub_old: vpub_old,
|
vpub_old,
|
||||||
vpub_new: vpub_new,
|
vpub_new,
|
||||||
h_sig: h_sig,
|
h_sig,
|
||||||
phi: phi,
|
phi,
|
||||||
inputs: inputs,
|
inputs,
|
||||||
outputs: outputs,
|
outputs,
|
||||||
rt: rt,
|
rt,
|
||||||
};
|
};
|
||||||
|
|
||||||
js.synthesize(&mut cs).unwrap();
|
js.synthesize(&mut cs).unwrap();
|
||||||
|
@ -11,7 +11,7 @@ pub struct OutputNote {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl OutputNote {
|
impl OutputNote {
|
||||||
pub fn compute<'a, E, CS>(
|
pub fn compute<E, CS>(
|
||||||
mut cs: CS,
|
mut cs: CS,
|
||||||
a_pk: Option<PayingKey>,
|
a_pk: Option<PayingKey>,
|
||||||
value: &NoteValue,
|
value: &NoteValue,
|
||||||
@ -41,6 +41,6 @@ impl OutputNote {
|
|||||||
&r,
|
&r,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(OutputNote { cm: cm })
|
Ok(OutputNote { cm })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ impl<R: Read> HashReader<R> {
|
|||||||
/// Construct a new `HashReader` given an existing `reader` by value.
|
/// Construct a new `HashReader` given an existing `reader` by value.
|
||||||
pub fn new(reader: R) -> Self {
|
pub fn new(reader: R) -> Self {
|
||||||
HashReader {
|
HashReader {
|
||||||
reader: reader,
|
reader,
|
||||||
hasher: State::new(),
|
hasher: State::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ impl SaplingProvingContext {
|
|||||||
|
|
||||||
// Accumulate the value commitment randomness in the context
|
// Accumulate the value commitment randomness in the context
|
||||||
{
|
{
|
||||||
let mut tmp = rcv.clone();
|
let mut tmp = rcv;
|
||||||
tmp.add_assign(&self.bsk);
|
tmp.add_assign(&self.bsk);
|
||||||
|
|
||||||
// Update the context
|
// Update the context
|
||||||
@ -74,15 +74,15 @@ impl SaplingProvingContext {
|
|||||||
|
|
||||||
// Construct the value commitment
|
// Construct the value commitment
|
||||||
let value_commitment = ValueCommitment::<Bls12> {
|
let value_commitment = ValueCommitment::<Bls12> {
|
||||||
value: value,
|
value,
|
||||||
randomness: rcv,
|
randomness: rcv,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Construct the viewing key
|
// Construct the viewing key
|
||||||
let viewing_key = proof_generation_key.into_viewing_key(params);
|
let viewing_key = proof_generation_key.to_viewing_key(params);
|
||||||
|
|
||||||
// Construct the payment address with the viewing key / diversifier
|
// Construct the payment address with the viewing key / diversifier
|
||||||
let payment_address = match viewing_key.into_payment_address(diversifier, params) {
|
let payment_address = match viewing_key.to_payment_address(diversifier, params) {
|
||||||
Some(p) => p,
|
Some(p) => p,
|
||||||
None => return Err(()),
|
None => return Err(()),
|
||||||
};
|
};
|
||||||
@ -96,7 +96,7 @@ impl SaplingProvingContext {
|
|||||||
|
|
||||||
// Let's compute the nullifier while we have the position
|
// Let's compute the nullifier while we have the position
|
||||||
let note = Note {
|
let note = Note {
|
||||||
value: value,
|
value,
|
||||||
g_d: diversifier
|
g_d: diversifier
|
||||||
.g_d::<Bls12>(params)
|
.g_d::<Bls12>(params)
|
||||||
.expect("was a valid diversifier before"),
|
.expect("was a valid diversifier before"),
|
||||||
@ -130,12 +130,12 @@ impl SaplingProvingContext {
|
|||||||
// Construct public input for circuit
|
// Construct public input for circuit
|
||||||
let mut public_input = [Fr::zero(); 7];
|
let mut public_input = [Fr::zero(); 7];
|
||||||
{
|
{
|
||||||
let (x, y) = rk.0.into_xy();
|
let (x, y) = rk.0.to_xy();
|
||||||
public_input[0] = x;
|
public_input[0] = x;
|
||||||
public_input[1] = y;
|
public_input[1] = y;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
let (x, y) = value_commitment.cm(params).into_xy();
|
let (x, y) = value_commitment.cm(params).to_xy();
|
||||||
public_input[2] = x;
|
public_input[2] = x;
|
||||||
public_input[3] = y;
|
public_input[3] = y;
|
||||||
}
|
}
|
||||||
@ -200,7 +200,7 @@ impl SaplingProvingContext {
|
|||||||
|
|
||||||
// Accumulate the value commitment randomness in the context
|
// Accumulate the value commitment randomness in the context
|
||||||
{
|
{
|
||||||
let mut tmp = rcv.clone();
|
let mut tmp = rcv;
|
||||||
tmp.negate(); // Outputs subtract from the total.
|
tmp.negate(); // Outputs subtract from the total.
|
||||||
tmp.add_assign(&self.bsk);
|
tmp.add_assign(&self.bsk);
|
||||||
|
|
||||||
@ -210,7 +210,7 @@ impl SaplingProvingContext {
|
|||||||
|
|
||||||
// Construct the value commitment for the proof instance
|
// Construct the value commitment for the proof instance
|
||||||
let value_commitment = ValueCommitment::<Bls12> {
|
let value_commitment = ValueCommitment::<Bls12> {
|
||||||
value: value,
|
value,
|
||||||
randomness: rcv,
|
randomness: rcv,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -220,7 +220,7 @@ impl SaplingProvingContext {
|
|||||||
value_commitment: Some(value_commitment.clone()),
|
value_commitment: Some(value_commitment.clone()),
|
||||||
payment_address: Some(payment_address.clone()),
|
payment_address: Some(payment_address.clone()),
|
||||||
commitment_randomness: Some(rcm),
|
commitment_randomness: Some(rcm),
|
||||||
esk: Some(esk.clone()),
|
esk: Some(esk),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create proof
|
// Create proof
|
||||||
|
@ -82,12 +82,12 @@ impl SaplingVerificationContext {
|
|||||||
// Construct public input for circuit
|
// Construct public input for circuit
|
||||||
let mut public_input = [Fr::zero(); 7];
|
let mut public_input = [Fr::zero(); 7];
|
||||||
{
|
{
|
||||||
let (x, y) = rk.0.into_xy();
|
let (x, y) = rk.0.to_xy();
|
||||||
public_input[0] = x;
|
public_input[0] = x;
|
||||||
public_input[1] = y;
|
public_input[1] = y;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
let (x, y) = cv.into_xy();
|
let (x, y) = cv.to_xy();
|
||||||
public_input[2] = x;
|
public_input[2] = x;
|
||||||
public_input[3] = y;
|
public_input[3] = y;
|
||||||
}
|
}
|
||||||
@ -146,12 +146,12 @@ impl SaplingVerificationContext {
|
|||||||
// Construct public input for circuit
|
// Construct public input for circuit
|
||||||
let mut public_input = [Fr::zero(); 5];
|
let mut public_input = [Fr::zero(); 5];
|
||||||
{
|
{
|
||||||
let (x, y) = cv.into_xy();
|
let (x, y) = cv.to_xy();
|
||||||
public_input[0] = x;
|
public_input[0] = x;
|
||||||
public_input[1] = y;
|
public_input[1] = y;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
let (x, y) = epk.into_xy();
|
let (x, y) = epk.to_xy();
|
||||||
public_input[2] = x;
|
public_input[2] = x;
|
||||||
public_input[3] = y;
|
public_input[3] = y;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user