mirror of https://github.com/zcash/orchard.git
Further fixes.
This commit is contained in:
parent
56225d603a
commit
96504e7162
|
@ -6,6 +6,3 @@ members = [
|
|||
"halo2_poseidon",
|
||||
"sinsemilla",
|
||||
]
|
||||
|
||||
[patch.crates-io]
|
||||
halo2 = { git = "https://github.com/zcash/halo2.git", rev = "27c4187673a9c6ade13fbdbd4f20955530c22d7f" }
|
||||
|
|
|
@ -20,7 +20,7 @@ arrayvec = "0.7.0"
|
|||
bigint = "4"
|
||||
ff = "0.11"
|
||||
group = "0.11"
|
||||
halo2 = "0.0"
|
||||
halo2 = "=0.1.0-beta.1"
|
||||
lazy_static = "1"
|
||||
pasta_curves = "0.2.1"
|
||||
rand = "0.8"
|
||||
|
|
|
@ -86,7 +86,7 @@ impl EccPoint {
|
|||
self.y
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[cfg(feature = "testing")]
|
||||
fn is_identity(&self) -> Option<bool> {
|
||||
self.x.value().map(|x| x == pallas::Base::zero())
|
||||
}
|
||||
|
@ -103,17 +103,6 @@ pub struct NonIdentityEccPoint {
|
|||
}
|
||||
|
||||
impl NonIdentityEccPoint {
|
||||
/// Constructs a point from its coordinates, without checking they are on the curve.
|
||||
///
|
||||
/// This is an internal API that we only use where we know we have a valid non-identity
|
||||
/// curve point (specifically inside Sinsemilla).
|
||||
pub(in crate::circuit::gadget) fn from_coordinates_unchecked(
|
||||
x: CellValue<pallas::Base>,
|
||||
y: CellValue<pallas::Base>,
|
||||
) -> Self {
|
||||
NonIdentityEccPoint { x, y }
|
||||
}
|
||||
|
||||
/// Returns the value of this curve point, if known.
|
||||
pub fn point(&self) -> Option<pallas::Affine> {
|
||||
match (self.x.value(), self.y.value()) {
|
||||
|
@ -447,6 +436,81 @@ impl<Fixed: FixedPoints<pallas::Affine>> EccInstructions<pallas::Affine> for Ecc
|
|||
)
|
||||
}
|
||||
|
||||
fn copy_point(
|
||||
&self,
|
||||
layouter: &mut impl Layouter<pallas::Base>,
|
||||
point: Self::Point,
|
||||
) -> Result<Self::Point, Error> {
|
||||
let config: witness_point::Config = self.config().into();
|
||||
let (x, y) = layouter.assign_region(
|
||||
|| "copy point",
|
||||
|mut region| {
|
||||
let x = {
|
||||
let cell = region.assign_advice(
|
||||
|| "copy x",
|
||||
config.x,
|
||||
0,
|
||||
|| point.x().value().ok_or(Error::SynthesisError),
|
||||
)?;
|
||||
region.constrain_equal(cell, point.x().cell())?;
|
||||
CellValue::new(cell, point.x().value())
|
||||
};
|
||||
let y = {
|
||||
let cell = region.assign_advice(
|
||||
|| "copy y",
|
||||
config.y,
|
||||
0,
|
||||
|| point.y().value().ok_or(Error::SynthesisError),
|
||||
)?;
|
||||
region.constrain_equal(cell, point.y().cell())?;
|
||||
CellValue::new(cell, point.y().value())
|
||||
};
|
||||
|
||||
Ok((x, y))
|
||||
},
|
||||
)?;
|
||||
|
||||
Ok(EccPoint { x, y })
|
||||
}
|
||||
|
||||
fn copy_point_non_id(
|
||||
&self,
|
||||
layouter: &mut impl Layouter<pallas::Base>,
|
||||
x: Self::Var,
|
||||
y: Self::Var,
|
||||
) -> Result<Self::NonIdentityPoint, Error> {
|
||||
let config: witness_point::Config = self.config().into();
|
||||
let (x, y) = layouter.assign_region(
|
||||
|| "copy point",
|
||||
|mut region| {
|
||||
let x = {
|
||||
let cell = region.assign_advice(
|
||||
|| "copy x",
|
||||
config.x,
|
||||
0,
|
||||
|| x.value().ok_or(Error::SynthesisError),
|
||||
)?;
|
||||
region.constrain_equal(cell, x.cell())?;
|
||||
CellValue::new(cell, x.value())
|
||||
};
|
||||
let y = {
|
||||
let cell = region.assign_advice(
|
||||
|| "copy y",
|
||||
config.y,
|
||||
0,
|
||||
|| y.value().ok_or(Error::SynthesisError),
|
||||
)?;
|
||||
region.constrain_equal(cell, y.cell())?;
|
||||
CellValue::new(cell, y.value())
|
||||
};
|
||||
|
||||
Ok((x, y))
|
||||
},
|
||||
)?;
|
||||
|
||||
Ok(NonIdentityEccPoint { x, y })
|
||||
}
|
||||
|
||||
fn extract_p<Point: Into<Self::Point> + Clone>(point: &Point) -> Self::X {
|
||||
let point: EccPoint = (point.clone()).into();
|
||||
point.x()
|
||||
|
|
|
@ -391,7 +391,10 @@ pub mod tests {
|
|||
use halo2::{circuit::Layouter, plonk::Error};
|
||||
use pasta_curves::{arithmetic::CurveExt, pallas};
|
||||
|
||||
use crate::gadget::{EccInstructions, NonIdentityPoint};
|
||||
use crate::{
|
||||
chip::EccPoint,
|
||||
gadget::{EccInstructions, NonIdentityPoint, Point},
|
||||
};
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn test_add<
|
||||
|
|
|
@ -145,11 +145,13 @@ impl Config {
|
|||
|
||||
#[cfg(feature = "testing")]
|
||||
pub mod tests {
|
||||
use group::{prime::PrimeCurveAffine, Curve, Group};
|
||||
use group::{Curve, Group};
|
||||
use halo2::{circuit::Layouter, plonk::Error};
|
||||
use pasta_curves::pallas;
|
||||
|
||||
use crate::gadget::{EccInstructions, NonIdentityPoint};
|
||||
use crate::{
|
||||
gadget::{EccInstructions, NonIdentityPoint},
|
||||
};
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn test_add_incomplete<
|
||||
|
@ -171,15 +173,6 @@ pub mod tests {
|
|||
// Make sure P and Q are not the same point.
|
||||
assert_ne!(p_val, q_val);
|
||||
|
||||
// Generate a (0,0) point to be used in other tests.
|
||||
let zero = {
|
||||
Point::new(
|
||||
chip.clone(),
|
||||
layouter.namespace(|| "identity"),
|
||||
Some(pallas::Affine::identity()),
|
||||
)?
|
||||
};
|
||||
|
||||
// P + Q
|
||||
{
|
||||
let result = p.add_incomplete(layouter.namespace(|| "P + Q"), &q)?;
|
||||
|
|
|
@ -444,7 +444,7 @@ fn decompose_for_scalar_mul(scalar: Option<pallas::Base>) -> Vec<Option<bool>> {
|
|||
|
||||
#[cfg(feature = "testing")]
|
||||
pub mod tests {
|
||||
use group::{prime::PrimeCurveAffine, Curve, Group};
|
||||
use group::{Curve, Group};
|
||||
use halo2::{
|
||||
circuit::{Chip, Layouter},
|
||||
plonk::Error,
|
||||
|
@ -452,7 +452,7 @@ pub mod tests {
|
|||
use pasta_curves::{arithmetic::FieldExt, pallas};
|
||||
|
||||
use crate::{
|
||||
chip::EccChip,
|
||||
chip::{EccChip, EccPoint},
|
||||
gadget::{EccInstructions, FixedPoints, NonIdentityPoint, Point},
|
||||
};
|
||||
use utilities::UtilitiesInstructions;
|
||||
|
@ -465,15 +465,6 @@ pub mod tests {
|
|||
let p_val = pallas::Point::random(rand::rngs::OsRng).to_affine(); // P
|
||||
let p = NonIdentityPoint::new(chip.clone(), layouter.namespace(|| "P"), Some(p_val))?;
|
||||
|
||||
// Generate a (0,0) point to be used in other tests.
|
||||
let zero = {
|
||||
Point::new(
|
||||
chip.clone(),
|
||||
layouter.namespace(|| "identity"),
|
||||
Some(pallas::Affine::identity()),
|
||||
)?
|
||||
};
|
||||
|
||||
let column = chip.config().advices[0];
|
||||
|
||||
fn constrain_equal_non_id<
|
||||
|
|
|
@ -364,7 +364,7 @@ pub mod tests {
|
|||
*magnitude,
|
||||
*sign,
|
||||
)?;
|
||||
value_commit_v.mul_short(layouter.namespace(|| *name), magnitude_sign)?
|
||||
base.mul_short(layouter.namespace(|| *name), magnitude_sign)?
|
||||
};
|
||||
assert!(result.inner().is_identity().unwrap());
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ use halo2::{
|
|||
poly::Rotation,
|
||||
};
|
||||
use pasta_curves::{arithmetic::CurveAffine, pallas};
|
||||
use utilities::copy;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Config {
|
||||
|
@ -147,20 +146,20 @@ impl Config {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[cfg(feature = "testing")]
|
||||
pub mod tests {
|
||||
use halo2::circuit::Layouter;
|
||||
use pasta_curves::pallas;
|
||||
|
||||
use super::*;
|
||||
use crate::circuit::gadget::ecc::{EccInstructions, NonIdentityPoint};
|
||||
use crate::gadget::{EccInstructions, NonIdentityPoint};
|
||||
|
||||
pub fn test_witness_non_id<
|
||||
EccChip: EccInstructions<pallas::Affine> + Clone + Eq + std::fmt::Debug,
|
||||
>(
|
||||
chip: EccChip,
|
||||
mut layouter: impl Layouter<pallas::Base>,
|
||||
) {
|
||||
) -> Result<(), Error> {
|
||||
// Witnessing the identity should return an error.
|
||||
NonIdentityPoint::new(
|
||||
chip,
|
||||
|
@ -168,23 +167,7 @@ pub mod tests {
|
|||
Some(pallas::Affine::identity()),
|
||||
)
|
||||
.expect_err("witnessing 𝒪 should return an error");
|
||||
}
|
||||
|
||||
pub(super) fn copy_point(
|
||||
&self,
|
||||
x: CellValue<pallas::Base>,
|
||||
y: CellValue<pallas::Base>,
|
||||
offset: usize,
|
||||
region: &mut Region<'_, pallas::Base>,
|
||||
) -> Result<EccPoint, Error> {
|
||||
// Enable `q_point` selector
|
||||
self.q_point.enable(region, offset)?;
|
||||
|
||||
// Copy `x` value
|
||||
let x = copy(region, || "x", self.x, offset, &x)?;
|
||||
// Copy `y` value
|
||||
let y = copy(region, || "y", self.y, offset, &y)?;
|
||||
|
||||
Ok(EccPoint { x, y })
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
//! Gadgets for elliptic curve operations.
|
||||
|
||||
use pasta_curves::arithmetic::CurveAffine;
|
||||
use std::fmt::Debug;
|
||||
|
||||
use halo2::{
|
||||
arithmetic::CurveAffine,
|
||||
circuit::{Chip, Layouter},
|
||||
plonk::Error,
|
||||
};
|
||||
|
@ -79,11 +79,19 @@ pub trait EccInstructions<C: CurveAffine>:
|
|||
/// checking that the coordinates indeed belong to a valid point.
|
||||
/// This maps the identity to (0, 0) in affine coordinates.
|
||||
fn copy_point(
|
||||
&self,
|
||||
layouter: &mut impl Layouter<C::Base>,
|
||||
point: Self::Point,
|
||||
) -> Result<Self::Point, Error>;
|
||||
|
||||
/// Copies a point given existing x- and y-coordinate variables,
|
||||
/// checking that the coordinates indeed belong to a valid point.
|
||||
fn copy_point_non_id(
|
||||
&self,
|
||||
layouter: &mut impl Layouter<C::Base>,
|
||||
x: Self::Var,
|
||||
y: Self::Var,
|
||||
) -> Result<Self::Point, Error>;
|
||||
) -> Result<Self::NonIdentityPoint, Error>;
|
||||
|
||||
/// Extracts the x-coordinate of a point.
|
||||
fn extract_p<Point: Into<Self::Point> + Clone>(point: &Point) -> Self::X;
|
||||
|
@ -199,17 +207,6 @@ impl<C: CurveAffine, EccChip: EccInstructions<C>> NonIdentityPoint<C, EccChip> {
|
|||
point.map(|inner| NonIdentityPoint { chip, inner })
|
||||
}
|
||||
|
||||
/// Constructs a new point by copying in its coordinates as `x`, `y` cells.
|
||||
pub fn copy(
|
||||
chip: EccChip,
|
||||
mut layouter: impl Layouter<C::Base>,
|
||||
x: EccChip::Var,
|
||||
y: EccChip::Var,
|
||||
) -> Result<Self, Error> {
|
||||
let point = chip.copy_point(&mut layouter, x, y);
|
||||
point.map(|inner| Point { chip, inner })
|
||||
}
|
||||
|
||||
/// Constrains this point to be equal in value to another point.
|
||||
pub fn constrain_equal<Other: Into<Point<C, EccChip>> + Clone>(
|
||||
&self,
|
||||
|
@ -224,6 +221,17 @@ impl<C: CurveAffine, EccChip: EccInstructions<C>> NonIdentityPoint<C, EccChip> {
|
|||
)
|
||||
}
|
||||
|
||||
/// Constructs a new point by copying in its coordinates as `x`, `y` cells.
|
||||
pub fn copy(
|
||||
chip: EccChip,
|
||||
mut layouter: impl Layouter<C::Base>,
|
||||
x: EccChip::Var,
|
||||
y: EccChip::Var,
|
||||
) -> Result<Self, Error> {
|
||||
let point = chip.copy_point_non_id(&mut layouter, x, y);
|
||||
point.map(|inner| NonIdentityPoint { chip, inner })
|
||||
}
|
||||
|
||||
/// Returns the inner point.
|
||||
pub fn inner(&self) -> &EccChip::NonIdentityPoint {
|
||||
&self.inner
|
||||
|
@ -338,6 +346,16 @@ impl<C: CurveAffine, EccChip: EccInstructions<C> + Clone + Debug + Eq> Point<C,
|
|||
.constrain_equal(&mut layouter, &self.inner, &other.inner)
|
||||
}
|
||||
|
||||
/// Constructs a new point by copying in its coordinates as `x`, `y` cells.
|
||||
pub fn copy(
|
||||
chip: EccChip,
|
||||
mut layouter: impl Layouter<C::Base>,
|
||||
point: EccChip::Point,
|
||||
) -> Result<Self, Error> {
|
||||
let point = chip.copy_point(&mut layouter, point);
|
||||
point.map(|inner| Point { chip, inner })
|
||||
}
|
||||
|
||||
/// Returns the inner point.
|
||||
pub fn inner(&self) -> &EccChip::Point {
|
||||
&self.inner
|
||||
|
|
|
@ -21,7 +21,7 @@ pprof = { version = "0.4.2", features = ["criterion", "flamegraph"] }
|
|||
[dependencies]
|
||||
bitvec = "0.22"
|
||||
ff = "0.11"
|
||||
halo2 = { version = "0.0", optional = true }
|
||||
halo2 = { version = "=0.1.0-beta.1", optional = true }
|
||||
pasta_curves = "0.2.1"
|
||||
rand = "0.8"
|
||||
utilities = { package = "halo2_utilities", version = "0.0", path = "../halo2_utilities" }
|
||||
|
|
|
@ -18,7 +18,7 @@ publish = false
|
|||
[dependencies]
|
||||
bigint = "4"
|
||||
ff = "0.11"
|
||||
halo2 = "0.0"
|
||||
halo2 = "=0.1.0-beta.1"
|
||||
pasta_curves = "0.2.1"
|
||||
proptest = { version = "1.0.0", optional = true }
|
||||
rand = "0.8"
|
||||
|
|
|
@ -22,7 +22,7 @@ pprof = { version = "0.4.2", features = ["criterion", "flamegraph"] }
|
|||
ecc = { package = "halo2_ecc", version = "0.0", path = "../halo2_ecc" }
|
||||
ff = "0.11"
|
||||
group = "0.11"
|
||||
halo2 = { version = "0.0", optional = true }
|
||||
halo2 = { version = "=0.1.0-beta.1", optional = true }
|
||||
lazy_static = "1"
|
||||
pasta_curves = "0.2.1"
|
||||
rand = "0.8"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use super::{
|
||||
gadget::{self, CommitDomains, HashDomains, SinsemillaInstructions},
|
||||
gadget::{CommitDomains, HashDomains, SinsemillaInstructions, Point as PointTrait},
|
||||
message::{Message, MessagePiece},
|
||||
primitive as sinsemilla,
|
||||
};
|
||||
|
@ -26,12 +26,12 @@ mod hash_to_point;
|
|||
|
||||
/// A point output by hash_to_point
|
||||
#[derive(Clone, Debug)]
|
||||
struct Point {
|
||||
pub struct Point {
|
||||
x: CellValue<pallas::Base>,
|
||||
y: CellValue<pallas::Base>,
|
||||
}
|
||||
|
||||
impl gadget::Point<pallas::Affine, CellValue<pallas::Base>> for Point {
|
||||
impl PointTrait<pallas::Affine, CellValue<pallas::Base>> for Point {
|
||||
fn x(&self) -> CellValue<pallas::Base> {
|
||||
self.x
|
||||
}
|
||||
|
|
|
@ -231,7 +231,7 @@ pub struct HashDomain<
|
|||
SinsemillaChip: SinsemillaInstructions<C, K, MAX_WORDS> + Clone + Debug + Eq,
|
||||
EccChip: EccInstructions<
|
||||
C,
|
||||
NonIdentityPoint = <SinsemillaChip as SinsemillaInstructions<C, K, MAX_WORDS>>::NonIdentityPoint,
|
||||
// NonIdentityPoint = <SinsemillaChip as SinsemillaInstructions<C, K, MAX_WORDS>>::NonIdentityPoint,
|
||||
FixedPoints = <SinsemillaChip as SinsemillaInstructions<C, K, MAX_WORDS>>::FixedPoints,
|
||||
Var = SinsemillaChip::Var,
|
||||
> + Clone
|
||||
|
@ -249,7 +249,7 @@ where
|
|||
SinsemillaChip: SinsemillaInstructions<C, K, MAX_WORDS> + Clone + Debug + Eq,
|
||||
EccChip: EccInstructions<
|
||||
C,
|
||||
NonIdentityPoint = <SinsemillaChip as SinsemillaInstructions<C, K, MAX_WORDS>>::NonIdentityPoint,
|
||||
// NonIdentityPoint = <SinsemillaChip as SinsemillaInstructions<C, K, MAX_WORDS>>::NonIdentityPoint,
|
||||
FixedPoints = <SinsemillaChip as SinsemillaInstructions<C, K, MAX_WORDS>>::FixedPoints,
|
||||
Var = SinsemillaChip::Var,
|
||||
> + Clone
|
||||
|
@ -340,7 +340,7 @@ pub struct CommitDomain<
|
|||
SinsemillaChip: SinsemillaInstructions<C, K, MAX_WORDS> + Clone + Debug + Eq,
|
||||
EccChip: EccInstructions<
|
||||
C,
|
||||
NonIdentityPoint = <SinsemillaChip as SinsemillaInstructions<C, K, MAX_WORDS>>::NonIdentityPoint,
|
||||
// NonIdentityPoint = <SinsemillaChip as SinsemillaInstructions<C, K, MAX_WORDS>>::NonIdentityPoint,
|
||||
FixedPoints = <SinsemillaChip as SinsemillaInstructions<C, K, MAX_WORDS>>::FixedPoints,
|
||||
Var = SinsemillaChip::Var,
|
||||
> + Clone
|
||||
|
@ -357,7 +357,7 @@ where
|
|||
SinsemillaChip: SinsemillaInstructions<C, K, MAX_WORDS> + Clone + Debug + Eq,
|
||||
EccChip: EccInstructions<
|
||||
C,
|
||||
NonIdentityPoint = <SinsemillaChip as SinsemillaInstructions<C, K, MAX_WORDS>>::NonIdentityPoint,
|
||||
// NonIdentityPoint = <SinsemillaChip as SinsemillaInstructions<C, K, MAX_WORDS>>::NonIdentityPoint,
|
||||
FixedPoints = <SinsemillaChip as SinsemillaInstructions<C, K, MAX_WORDS>>::FixedPoints,
|
||||
Var = SinsemillaChip::Var,
|
||||
> + Clone
|
||||
|
@ -614,8 +614,8 @@ pub mod testing {
|
|||
None
|
||||
};
|
||||
|
||||
NonIdentityPoint::new(
|
||||
ecc_chip,
|
||||
Point::new(
|
||||
ecc_chip.clone(),
|
||||
layouter.namespace(|| "Witness expected result"),
|
||||
expected_result,
|
||||
)?
|
||||
|
|
|
@ -164,26 +164,20 @@ where
|
|||
pub mod testing {
|
||||
use super::{
|
||||
chip::{MerkleChip, MerkleConfig},
|
||||
i2lebsp, MerklePath, L_PALLAS_BASE, MERKLE_DEPTH,
|
||||
MerklePath, MERKLE_DEPTH,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
chip::SinsemillaChip,
|
||||
gadget::{CommitDomains, HashDomains},
|
||||
primitive::HashDomain,
|
||||
};
|
||||
|
||||
use ecc::gadget::FixedPoints;
|
||||
use utilities::{lookup_range_check::LookupRangeCheckConfig, UtilitiesInstructions, Var};
|
||||
|
||||
use ff::PrimeFieldBits;
|
||||
use group::prime::PrimeCurveAffine;
|
||||
use halo2::{
|
||||
circuit::{Layouter, SimpleFloorPlanner},
|
||||
dev::MockProver,
|
||||
note::commitment::ExtractedNoteCommitment,
|
||||
plonk::{Circuit, ConstraintSystem, Error},
|
||||
tree,
|
||||
};
|
||||
use pasta_curves::pallas;
|
||||
|
||||
|
@ -313,25 +307,29 @@ pub mod testing {
|
|||
path.calculate_root(layouter.namespace(|| "calculate root"), leaf)?;
|
||||
|
||||
if let Some(leaf_pos) = self.leaf_pos {
|
||||
let domain = HashDomain {
|
||||
Q: S::hash_domain().Q().to_curve(),
|
||||
};
|
||||
|
||||
// The expected final root
|
||||
let final_root = {
|
||||
let path = tree::MerklePath::new(leaf_pos, self.merkle_path.unwrap());
|
||||
let leaf = ExtractedNoteCommitment::from_bytes(&self.leaf.unwrap().to_bytes())
|
||||
.unwrap();
|
||||
path.root(leaf)
|
||||
};
|
||||
let final_root = S::root(
|
||||
self.merkle_path.unwrap(),
|
||||
leaf_pos,
|
||||
self.leaf.unwrap(),
|
||||
);
|
||||
|
||||
// Check the computed final root against the expected final root.
|
||||
assert_eq!(computed_final_root.value().unwrap(), final_root.inner());
|
||||
assert_eq!(computed_final_root.value().unwrap(), final_root);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub trait MerkleTest<Hash: HashDomains<pallas::Affine>> {
|
||||
fn hash_domain() -> Hash;
|
||||
fn root(
|
||||
path: [pallas::Base; MERKLE_DEPTH],
|
||||
leaf_pos: u32,
|
||||
leaf: pallas::Base,
|
||||
) -> pallas::Base;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "testing")]
|
||||
|
@ -344,9 +342,11 @@ pub mod tests {
|
|||
|
||||
use crate::{
|
||||
gadget::{CommitDomains, HashDomains},
|
||||
merkle::{i2lebsp, L_PALLAS_BASE, MERKLE_DEPTH},
|
||||
primitive::{CommitDomain, HashDomain},
|
||||
};
|
||||
|
||||
use ff::PrimeFieldBits;
|
||||
use group::Curve;
|
||||
use pasta_curves::pallas;
|
||||
|
||||
|
@ -406,11 +406,50 @@ pub mod tests {
|
|||
fn hash_domain() -> Hash {
|
||||
Hash
|
||||
}
|
||||
|
||||
fn root(path: [pallas::Base; MERKLE_DEPTH],
|
||||
leaf_pos: u32,
|
||||
leaf: pallas::Base,) -> pallas::Base {
|
||||
use group::prime::PrimeCurveAffine;
|
||||
let domain = HashDomain { Q: Self::hash_domain().Q().to_curve() };
|
||||
let pos_bool = i2lebsp::<32>(leaf_pos as u64);
|
||||
|
||||
// Compute the root
|
||||
let mut node = leaf;
|
||||
for (l, (sibling, pos)) in path.iter().zip(pos_bool.iter()).enumerate() {
|
||||
let (left, right) = if *pos {
|
||||
(*sibling, node)
|
||||
} else {
|
||||
(node, *sibling)
|
||||
};
|
||||
|
||||
let l_star = i2lebsp::<10>(l as u64);
|
||||
let left: Vec<_> = left
|
||||
.to_le_bits()
|
||||
.iter()
|
||||
.by_val()
|
||||
.take(L_PALLAS_BASE)
|
||||
.collect();
|
||||
let right: Vec<_> = right
|
||||
.to_le_bits()
|
||||
.iter()
|
||||
.by_val()
|
||||
.take(L_PALLAS_BASE)
|
||||
.collect();
|
||||
|
||||
let mut message = l_star.to_vec();
|
||||
message.extend_from_slice(&left);
|
||||
message.extend_from_slice(&right);
|
||||
|
||||
node = domain.hash(message.into_iter()).unwrap();
|
||||
}
|
||||
node
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn merkle_chip() {
|
||||
use crate::merkle::{i2lebsp, MERKLE_DEPTH};
|
||||
use crate::merkle::{MERKLE_DEPTH};
|
||||
use halo2::dev::MockProver;
|
||||
use pasta_curves::arithmetic::FieldExt;
|
||||
use rand::random;
|
||||
|
|
|
@ -15,8 +15,7 @@ use pasta_curves::{
|
|||
|
||||
use crate::{
|
||||
constants::{
|
||||
util::gen_const_array, OrchardCommitDomains, OrchardFixedBases, OrchardHashDomains,
|
||||
MERKLE_DEPTH_ORCHARD,
|
||||
OrchardCommitDomains, OrchardFixedBases, OrchardHashDomains, MERKLE_DEPTH_ORCHARD,
|
||||
},
|
||||
keys::{
|
||||
CommitIvkRandomness, DiversifiedTransmissionKey, NullifierDerivingKey, SpendValidatingKey,
|
||||
|
@ -48,7 +47,8 @@ use sinsemilla::{
|
|||
},
|
||||
};
|
||||
use utilities::{
|
||||
copy, lookup_range_check::LookupRangeCheckConfig, CellValue, UtilitiesInstructions, Var,
|
||||
copy, gen_const_array, lookup_range_check::LookupRangeCheckConfig, CellValue,
|
||||
UtilitiesInstructions, Var,
|
||||
};
|
||||
|
||||
use std::convert::TryInto;
|
||||
|
@ -411,7 +411,7 @@ impl plonk::Circuit<pallas::Base> for Circuit {
|
|||
config.merkle_chip_2(),
|
||||
OrchardHashDomains::MerkleCrh,
|
||||
self.pos,
|
||||
self.path,
|
||||
path,
|
||||
);
|
||||
let leaf = *cm_old.extract_p().inner();
|
||||
merkle_inputs.calculate_root(layouter.namespace(|| "MerkleCRH"), leaf)?
|
||||
|
|
|
@ -303,6 +303,7 @@ fn test_orchard_domains() {
|
|||
#[cfg(feature = "test-ecc")]
|
||||
#[test]
|
||||
fn test_merkle_crh() {
|
||||
use crate::constants::MERKLE_DEPTH_ORCHARD;
|
||||
use halo2::dev::MockProver;
|
||||
use rand::random;
|
||||
use sinsemilla::merkle::testing;
|
||||
|
@ -313,6 +314,17 @@ fn test_merkle_crh() {
|
|||
fn hash_domain() -> OrchardHashDomains {
|
||||
OrchardHashDomains::MerkleCrh
|
||||
}
|
||||
|
||||
fn root(
|
||||
path: [pallas::Base; MERKLE_DEPTH_ORCHARD],
|
||||
leaf_pos: u32,
|
||||
leaf: pallas::Base,
|
||||
) -> pallas::Base {
|
||||
use crate::{note::ExtractedNoteCommitment, tree::MerklePath};
|
||||
let path = MerklePath::new(leaf_pos, path);
|
||||
let leaf = ExtractedNoteCommitment::from_bytes(&leaf.to_bytes()).unwrap();
|
||||
path.root(leaf).inner()
|
||||
}
|
||||
}
|
||||
|
||||
// Choose a random leaf and position
|
||||
|
|
|
@ -7,10 +7,10 @@ use crate::{
|
|||
},
|
||||
note::commitment::ExtractedNoteCommitment,
|
||||
};
|
||||
use halo2_utilities::utilities::gen_const_array_with_default;
|
||||
use incrementalmerkletree::{Altitude, Hashable};
|
||||
use pasta_curves::{arithmetic::FieldExt, pallas};
|
||||
use sinsemilla::primitive::HashDomain;
|
||||
use utilities::gen_const_array_with_default;
|
||||
|
||||
use ff::{Field, PrimeField, PrimeFieldBits};
|
||||
use lazy_static::lazy_static;
|
||||
|
|
Loading…
Reference in New Issue