mirror of https://github.com/zcash/orchard.git
Merge pull request #336 from zcash/halo2_proofs-0.2.0
Migrate to `halo2_proofs 0.2.0`
This commit is contained in:
commit
b448f3f4c5
|
@ -6,6 +6,8 @@ and this project adheres to Rust's notion of
|
|||
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
### Changed
|
||||
- Migrated to `halo2_proofs 0.2`.
|
||||
|
||||
## [0.1.0] - 2022-05-10
|
||||
### Changed
|
||||
|
|
|
@ -29,8 +29,8 @@ blake2b_simd = "1"
|
|||
ff = "0.12"
|
||||
fpe = "0.5"
|
||||
group = "0.12"
|
||||
halo2_gadgets = "0.1"
|
||||
halo2_proofs = "0.1"
|
||||
halo2_gadgets = "0.2"
|
||||
halo2_proofs = "0.2"
|
||||
hex = "0.4"
|
||||
lazy_static = "1"
|
||||
memuse = { version = "0.2", features = ["nonempty"] }
|
||||
|
@ -49,7 +49,7 @@ plotters = { version = "0.3.0", optional = true }
|
|||
|
||||
[dev-dependencies]
|
||||
criterion = "0.3"
|
||||
halo2_gadgets = { version = "0.1", features = ["test-dependencies"] }
|
||||
halo2_gadgets = { version = "0.2", features = ["test-dependencies"] }
|
||||
hex = "0.4"
|
||||
proptest = "1.0.0"
|
||||
zcash_note_encryption = { version = "0.1", features = ["pre-zip-212"] }
|
||||
|
|
|
@ -4,6 +4,7 @@ use core::fmt;
|
|||
use core::iter;
|
||||
|
||||
use ff::Field;
|
||||
use halo2_proofs::circuit::Value;
|
||||
use nonempty::NonEmpty;
|
||||
use pasta_curves::pallas;
|
||||
use rand::{prelude::SliceRandom, CryptoRng, RngCore};
|
||||
|
@ -188,25 +189,25 @@ impl ActionInfo {
|
|||
},
|
||||
),
|
||||
Circuit {
|
||||
path: Some(self.spend.merkle_path.auth_path()),
|
||||
pos: Some(self.spend.merkle_path.position()),
|
||||
g_d_old: Some(sender_address.g_d()),
|
||||
pk_d_old: Some(*sender_address.pk_d()),
|
||||
v_old: Some(self.spend.note.value()),
|
||||
rho_old: Some(rho_old),
|
||||
psi_old: Some(psi_old),
|
||||
rcm_old: Some(rcm_old),
|
||||
cm_old: Some(self.spend.note.commitment()),
|
||||
alpha: Some(alpha),
|
||||
ak: Some(ak),
|
||||
nk: Some(*self.spend.fvk.nk()),
|
||||
rivk: Some(self.spend.fvk.rivk(self.spend.scope)),
|
||||
g_d_new: Some(note.recipient().g_d()),
|
||||
pk_d_new: Some(*note.recipient().pk_d()),
|
||||
v_new: Some(note.value()),
|
||||
psi_new: Some(note.rseed().psi(¬e.rho())),
|
||||
rcm_new: Some(note.rseed().rcm(¬e.rho())),
|
||||
rcv: Some(self.rcv),
|
||||
path: Value::known(self.spend.merkle_path.auth_path()),
|
||||
pos: Value::known(self.spend.merkle_path.position()),
|
||||
g_d_old: Value::known(sender_address.g_d()),
|
||||
pk_d_old: Value::known(*sender_address.pk_d()),
|
||||
v_old: Value::known(self.spend.note.value()),
|
||||
rho_old: Value::known(rho_old),
|
||||
psi_old: Value::known(psi_old),
|
||||
rcm_old: Value::known(rcm_old),
|
||||
cm_old: Value::known(self.spend.note.commitment()),
|
||||
alpha: Value::known(alpha),
|
||||
ak: Value::known(ak),
|
||||
nk: Value::known(*self.spend.fvk.nk()),
|
||||
rivk: Value::known(self.spend.fvk.rivk(self.spend.scope)),
|
||||
g_d_new: Value::known(note.recipient().g_d()),
|
||||
pk_d_new: Value::known(*note.recipient().pk_d()),
|
||||
v_new: Value::known(note.value()),
|
||||
psi_new: Value::known(note.rseed().psi(¬e.rho())),
|
||||
rcm_new: Value::known(note.rseed().rcm(¬e.rho())),
|
||||
rcv: Value::known(self.rcv),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
124
src/circuit.rs
124
src/circuit.rs
|
@ -4,7 +4,7 @@ use core::fmt;
|
|||
|
||||
use group::{Curve, GroupEncoding};
|
||||
use halo2_proofs::{
|
||||
circuit::{floor_planner, Layouter},
|
||||
circuit::{floor_planner, Layouter, Value},
|
||||
plonk::{
|
||||
self, Advice, Column, Constraints, Expression, Instance as InstanceColumn, Selector,
|
||||
SingleVerifier,
|
||||
|
@ -99,25 +99,25 @@ pub struct Config {
|
|||
/// The Orchard Action circuit.
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct Circuit {
|
||||
pub(crate) path: Option<[MerkleHashOrchard; MERKLE_DEPTH_ORCHARD]>,
|
||||
pub(crate) pos: Option<u32>,
|
||||
pub(crate) g_d_old: Option<NonIdentityPallasPoint>,
|
||||
pub(crate) pk_d_old: Option<DiversifiedTransmissionKey>,
|
||||
pub(crate) v_old: Option<NoteValue>,
|
||||
pub(crate) rho_old: Option<Nullifier>,
|
||||
pub(crate) psi_old: Option<pallas::Base>,
|
||||
pub(crate) rcm_old: Option<NoteCommitTrapdoor>,
|
||||
pub(crate) cm_old: Option<NoteCommitment>,
|
||||
pub(crate) alpha: Option<pallas::Scalar>,
|
||||
pub(crate) ak: Option<SpendValidatingKey>,
|
||||
pub(crate) nk: Option<NullifierDerivingKey>,
|
||||
pub(crate) rivk: Option<CommitIvkRandomness>,
|
||||
pub(crate) g_d_new: Option<NonIdentityPallasPoint>,
|
||||
pub(crate) pk_d_new: Option<DiversifiedTransmissionKey>,
|
||||
pub(crate) v_new: Option<NoteValue>,
|
||||
pub(crate) psi_new: Option<pallas::Base>,
|
||||
pub(crate) rcm_new: Option<NoteCommitTrapdoor>,
|
||||
pub(crate) rcv: Option<ValueCommitTrapdoor>,
|
||||
pub(crate) path: Value<[MerkleHashOrchard; MERKLE_DEPTH_ORCHARD]>,
|
||||
pub(crate) pos: Value<u32>,
|
||||
pub(crate) g_d_old: Value<NonIdentityPallasPoint>,
|
||||
pub(crate) pk_d_old: Value<DiversifiedTransmissionKey>,
|
||||
pub(crate) v_old: Value<NoteValue>,
|
||||
pub(crate) rho_old: Value<Nullifier>,
|
||||
pub(crate) psi_old: Value<pallas::Base>,
|
||||
pub(crate) rcm_old: Value<NoteCommitTrapdoor>,
|
||||
pub(crate) cm_old: Value<NoteCommitment>,
|
||||
pub(crate) alpha: Value<pallas::Scalar>,
|
||||
pub(crate) ak: Value<SpendValidatingKey>,
|
||||
pub(crate) nk: Value<NullifierDerivingKey>,
|
||||
pub(crate) rivk: Value<CommitIvkRandomness>,
|
||||
pub(crate) g_d_new: Value<NonIdentityPallasPoint>,
|
||||
pub(crate) pk_d_new: Value<DiversifiedTransmissionKey>,
|
||||
pub(crate) v_new: Value<NoteValue>,
|
||||
pub(crate) psi_new: Value<pallas::Base>,
|
||||
pub(crate) rcm_new: Value<NoteCommitTrapdoor>,
|
||||
pub(crate) rcv: Value<ValueCommitTrapdoor>,
|
||||
}
|
||||
|
||||
impl plonk::Circuit<pallas::Base> for Circuit {
|
||||
|
@ -358,7 +358,7 @@ impl plonk::Circuit<pallas::Base> for Circuit {
|
|||
)?;
|
||||
|
||||
// Witness ak_P.
|
||||
let ak_P: Option<pallas::Point> = self.ak.as_ref().map(|ak| ak.into());
|
||||
let ak_P: Value<pallas::Point> = self.ak.as_ref().map(|ak| ak.into());
|
||||
let ak_P = NonIdentityPoint::new(
|
||||
ecc_chip.clone(),
|
||||
layouter.namespace(|| "witness ak_P"),
|
||||
|
@ -408,8 +408,8 @@ impl plonk::Circuit<pallas::Base> for Circuit {
|
|||
let v_net_magnitude_sign = {
|
||||
// Witness the magnitude and sign of v_net = v_old - v_new
|
||||
let v_net_magnitude_sign = {
|
||||
let magnitude_sign = self.v_old.zip(self.v_new).map(|(v_old, v_new)| {
|
||||
let v_net = v_old - v_new;
|
||||
let v_net = self.v_old - self.v_new;
|
||||
let magnitude_sign = v_net.map(|v_net| {
|
||||
let (magnitude, sign) = v_net.magnitude_sign();
|
||||
|
||||
(
|
||||
|
@ -877,7 +877,7 @@ mod tests {
|
|||
use core::iter;
|
||||
|
||||
use ff::Field;
|
||||
use halo2_proofs::dev::MockProver;
|
||||
use halo2_proofs::{circuit::Value, dev::MockProver};
|
||||
use pasta_curves::pallas;
|
||||
use rand::{rngs::OsRng, RngCore};
|
||||
|
||||
|
@ -912,25 +912,25 @@ mod tests {
|
|||
|
||||
(
|
||||
Circuit {
|
||||
path: Some(path.auth_path()),
|
||||
pos: Some(path.position()),
|
||||
g_d_old: Some(sender_address.g_d()),
|
||||
pk_d_old: Some(*sender_address.pk_d()),
|
||||
v_old: Some(spent_note.value()),
|
||||
rho_old: Some(spent_note.rho()),
|
||||
psi_old: Some(spent_note.rseed().psi(&spent_note.rho())),
|
||||
rcm_old: Some(spent_note.rseed().rcm(&spent_note.rho())),
|
||||
cm_old: Some(spent_note.commitment()),
|
||||
alpha: Some(alpha),
|
||||
ak: Some(ak),
|
||||
nk: Some(nk),
|
||||
rivk: Some(rivk),
|
||||
g_d_new: Some(output_note.recipient().g_d()),
|
||||
pk_d_new: Some(*output_note.recipient().pk_d()),
|
||||
v_new: Some(output_note.value()),
|
||||
psi_new: Some(output_note.rseed().psi(&output_note.rho())),
|
||||
rcm_new: Some(output_note.rseed().rcm(&output_note.rho())),
|
||||
rcv: Some(rcv),
|
||||
path: Value::known(path.auth_path()),
|
||||
pos: Value::known(path.position()),
|
||||
g_d_old: Value::known(sender_address.g_d()),
|
||||
pk_d_old: Value::known(*sender_address.pk_d()),
|
||||
v_old: Value::known(spent_note.value()),
|
||||
rho_old: Value::known(spent_note.rho()),
|
||||
psi_old: Value::known(spent_note.rseed().psi(&spent_note.rho())),
|
||||
rcm_old: Value::known(spent_note.rseed().rcm(&spent_note.rho())),
|
||||
cm_old: Value::known(spent_note.commitment()),
|
||||
alpha: Value::known(alpha),
|
||||
ak: Value::known(ak),
|
||||
nk: Value::known(nk),
|
||||
rivk: Value::known(rivk),
|
||||
g_d_new: Value::known(output_note.recipient().g_d()),
|
||||
pk_d_new: Value::known(*output_note.recipient().pk_d()),
|
||||
v_new: Value::known(output_note.value()),
|
||||
psi_new: Value::known(output_note.rseed().psi(&output_note.rho())),
|
||||
rcm_new: Value::known(output_note.rseed().rcm(&output_note.rho())),
|
||||
rcv: Value::known(rcv),
|
||||
},
|
||||
Instance {
|
||||
anchor,
|
||||
|
@ -1098,25 +1098,25 @@ mod tests {
|
|||
.unwrap();
|
||||
|
||||
let circuit = Circuit {
|
||||
path: None,
|
||||
pos: None,
|
||||
g_d_old: None,
|
||||
pk_d_old: None,
|
||||
v_old: None,
|
||||
rho_old: None,
|
||||
psi_old: None,
|
||||
rcm_old: None,
|
||||
cm_old: None,
|
||||
alpha: None,
|
||||
ak: None,
|
||||
nk: None,
|
||||
rivk: None,
|
||||
g_d_new: None,
|
||||
pk_d_new: None,
|
||||
v_new: None,
|
||||
psi_new: None,
|
||||
rcm_new: None,
|
||||
rcv: None,
|
||||
path: Value::unknown(),
|
||||
pos: Value::unknown(),
|
||||
g_d_old: Value::unknown(),
|
||||
pk_d_old: Value::unknown(),
|
||||
v_old: Value::unknown(),
|
||||
rho_old: Value::unknown(),
|
||||
psi_old: Value::unknown(),
|
||||
rcm_old: Value::unknown(),
|
||||
cm_old: Value::unknown(),
|
||||
alpha: Value::unknown(),
|
||||
ak: Value::unknown(),
|
||||
nk: Value::unknown(),
|
||||
rivk: Value::unknown(),
|
||||
g_d_new: Value::unknown(),
|
||||
pk_d_new: Value::unknown(),
|
||||
v_new: Value::unknown(),
|
||||
psi_new: Value::unknown(),
|
||||
rcm_new: Value::unknown(),
|
||||
rcv: Value::unknown(),
|
||||
};
|
||||
halo2_proofs::dev::CircuitLayout::default()
|
||||
.show_labels(false)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use core::iter;
|
||||
|
||||
use halo2_proofs::{
|
||||
circuit::{AssignedCell, Layouter},
|
||||
circuit::{AssignedCell, Layouter, Value},
|
||||
plonk::{Advice, Column, ConstraintSystem, Constraints, Error, Expression, Selector},
|
||||
poly::Rotation,
|
||||
};
|
||||
|
@ -417,11 +417,11 @@ pub(in crate::circuit) mod gadgets {
|
|||
// Decompose the low 130 bits of a_prime = a + 2^130 - t_P, and output
|
||||
// the running sum at the end of it. If a_prime < 2^130, the running sum
|
||||
// will be 0.
|
||||
let a_prime = a.value().map(|a| {
|
||||
let two_pow_130 = pallas::Base::from_u128(1u128 << 65).square();
|
||||
let t_p = pallas::Base::from_u128(T_P);
|
||||
a + two_pow_130 - t_p
|
||||
});
|
||||
let a_prime = {
|
||||
let two_pow_130 = Value::known(pallas::Base::from_u128(1u128 << 65).square());
|
||||
let t_p = Value::known(pallas::Base::from_u128(T_P));
|
||||
a.value() + two_pow_130 - t_p
|
||||
};
|
||||
let zs = lookup_config.witness_check(
|
||||
layouter.namespace(|| "Decompose low 130 bits of (a + 2^130 - t_P)"),
|
||||
a_prime,
|
||||
|
@ -461,12 +461,12 @@ pub(in crate::circuit) mod gadgets {
|
|||
|
||||
// Decompose the low 140 bits of b2_c_prime = b_2 + c * 2^5 + 2^140 - t_P, and output
|
||||
// the running sum at the end of it. If b2_c_prime < 2^140, the running sum will be 0.
|
||||
let b2_c_prime = b_2.inner().value().zip(c.value()).map(|(b_2, c)| {
|
||||
let two_pow_5 = pallas::Base::from(1 << 5);
|
||||
let two_pow_140 = pallas::Base::from_u128(1u128 << 70).square();
|
||||
let t_p = pallas::Base::from_u128(T_P);
|
||||
b_2 + c * two_pow_5 + two_pow_140 - t_p
|
||||
});
|
||||
let b2_c_prime = {
|
||||
let two_pow_5 = Value::known(pallas::Base::from(1 << 5));
|
||||
let two_pow_140 = Value::known(pallas::Base::from_u128(1u128 << 70).square());
|
||||
let t_p = Value::known(pallas::Base::from_u128(T_P));
|
||||
b_2.inner().value() + c.value() * two_pow_5 + two_pow_140 - t_p
|
||||
};
|
||||
let zs = lookup_config.witness_check(
|
||||
layouter.namespace(|| "Decompose low 140 bits of (b_2 + c * 2^5 + 2^140 - t_P)"),
|
||||
b2_c_prime,
|
||||
|
@ -535,7 +535,7 @@ impl CommitIvkConfig {
|
|||
|| "Witness b_1",
|
||||
self.advices[4],
|
||||
offset,
|
||||
|| gate_cells.b_1.inner().ok_or(Error::Synthesis),
|
||||
|| *gate_cells.b_1.inner(),
|
||||
)?;
|
||||
|
||||
// Copy in `b_2`
|
||||
|
@ -603,7 +603,7 @@ impl CommitIvkConfig {
|
|||
|| "Witness d_1",
|
||||
self.advices[4],
|
||||
offset,
|
||||
|| gate_cells.d_1.inner().ok_or(Error::Synthesis),
|
||||
|| *gate_cells.d_1.inner(),
|
||||
)?;
|
||||
|
||||
// Copy in z13_c
|
||||
|
@ -646,10 +646,10 @@ struct GateCells {
|
|||
ak: AssignedCell<pallas::Base, pallas::Base>,
|
||||
nk: AssignedCell<pallas::Base, pallas::Base>,
|
||||
b_0: RangeConstrained<pallas::Base, AssignedCell<pallas::Base, pallas::Base>>,
|
||||
b_1: RangeConstrained<pallas::Base, Option<pallas::Base>>,
|
||||
b_1: RangeConstrained<pallas::Base, Value<pallas::Base>>,
|
||||
b_2: RangeConstrained<pallas::Base, AssignedCell<pallas::Base, pallas::Base>>,
|
||||
d_0: RangeConstrained<pallas::Base, AssignedCell<pallas::Base, pallas::Base>>,
|
||||
d_1: RangeConstrained<pallas::Base, Option<pallas::Base>>,
|
||||
d_1: RangeConstrained<pallas::Base, Value<pallas::Base>>,
|
||||
z13_a: AssignedCell<pallas::Base, pallas::Base>,
|
||||
a_prime: AssignedCell<pallas::Base, pallas::Base>,
|
||||
z13_a_prime: AssignedCell<pallas::Base, pallas::Base>,
|
||||
|
@ -680,7 +680,7 @@ mod tests {
|
|||
utilities::{lookup_range_check::LookupRangeCheckConfig, UtilitiesInstructions},
|
||||
};
|
||||
use halo2_proofs::{
|
||||
circuit::{AssignedCell, Layouter, SimpleFloorPlanner},
|
||||
circuit::{AssignedCell, Layouter, SimpleFloorPlanner, Value},
|
||||
dev::MockProver,
|
||||
plonk::{Circuit, ConstraintSystem, Error},
|
||||
};
|
||||
|
@ -691,8 +691,8 @@ mod tests {
|
|||
fn commit_ivk() {
|
||||
#[derive(Default)]
|
||||
struct MyCircuit {
|
||||
ak: Option<pallas::Base>,
|
||||
nk: Option<pallas::Base>,
|
||||
ak: Value<pallas::Base>,
|
||||
nk: Value<pallas::Base>,
|
||||
}
|
||||
|
||||
impl UtilitiesInstructions<pallas::Base> for MyCircuit {
|
||||
|
@ -809,8 +809,11 @@ mod tests {
|
|||
|
||||
// Use a random scalar for rivk
|
||||
let rivk = pallas::Scalar::random(OsRng);
|
||||
let rivk_gadget =
|
||||
ScalarFixed::new(ecc_chip.clone(), layouter.namespace(|| "rivk"), Some(rivk))?;
|
||||
let rivk_gadget = ScalarFixed::new(
|
||||
ecc_chip.clone(),
|
||||
layouter.namespace(|| "rivk"),
|
||||
Value::known(rivk),
|
||||
)?;
|
||||
|
||||
let ivk = gadgets::commit_ivk(
|
||||
sinsemilla_chip,
|
||||
|
@ -822,34 +825,29 @@ mod tests {
|
|||
rivk_gadget,
|
||||
)?;
|
||||
|
||||
let expected_ivk = {
|
||||
let domain = CommitDomain::new(COMMIT_IVK_PERSONALIZATION);
|
||||
// Hash ak || nk
|
||||
domain
|
||||
.short_commit(
|
||||
iter::empty()
|
||||
.chain(
|
||||
self.ak
|
||||
.unwrap()
|
||||
.to_le_bits()
|
||||
.iter()
|
||||
.by_vals()
|
||||
.take(L_ORCHARD_BASE),
|
||||
self.ak
|
||||
.zip(self.nk)
|
||||
.zip(ivk.inner().value())
|
||||
.assert_if_known(|((ak, nk), ivk)| {
|
||||
let expected_ivk = {
|
||||
let domain = CommitDomain::new(COMMIT_IVK_PERSONALIZATION);
|
||||
// Hash ak || nk
|
||||
domain
|
||||
.short_commit(
|
||||
iter::empty()
|
||||
.chain(
|
||||
ak.to_le_bits().iter().by_vals().take(L_ORCHARD_BASE),
|
||||
)
|
||||
.chain(
|
||||
nk.to_le_bits().iter().by_vals().take(L_ORCHARD_BASE),
|
||||
),
|
||||
&rivk,
|
||||
)
|
||||
.chain(
|
||||
self.nk
|
||||
.unwrap()
|
||||
.to_le_bits()
|
||||
.iter()
|
||||
.by_vals()
|
||||
.take(L_ORCHARD_BASE),
|
||||
),
|
||||
&rivk,
|
||||
)
|
||||
.unwrap()
|
||||
};
|
||||
.unwrap()
|
||||
};
|
||||
|
||||
assert_eq!(&expected_ivk, ivk.inner().value().unwrap());
|
||||
&&expected_ivk == ivk
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -860,38 +858,38 @@ mod tests {
|
|||
let circuits = [
|
||||
// `ak` = 0, `nk` = 0
|
||||
MyCircuit {
|
||||
ak: Some(pallas::Base::zero()),
|
||||
nk: Some(pallas::Base::zero()),
|
||||
ak: Value::known(pallas::Base::zero()),
|
||||
nk: Value::known(pallas::Base::zero()),
|
||||
},
|
||||
// `ak` = T_Q - 1, `nk` = T_Q - 1
|
||||
MyCircuit {
|
||||
ak: Some(pallas::Base::from_u128(T_Q - 1)),
|
||||
nk: Some(pallas::Base::from_u128(T_Q - 1)),
|
||||
ak: Value::known(pallas::Base::from_u128(T_Q - 1)),
|
||||
nk: Value::known(pallas::Base::from_u128(T_Q - 1)),
|
||||
},
|
||||
// `ak` = T_Q, `nk` = T_Q
|
||||
MyCircuit {
|
||||
ak: Some(pallas::Base::from_u128(T_Q)),
|
||||
nk: Some(pallas::Base::from_u128(T_Q)),
|
||||
ak: Value::known(pallas::Base::from_u128(T_Q)),
|
||||
nk: Value::known(pallas::Base::from_u128(T_Q)),
|
||||
},
|
||||
// `ak` = 2^127 - 1, `nk` = 2^127 - 1
|
||||
MyCircuit {
|
||||
ak: Some(pallas::Base::from_u128((1 << 127) - 1)),
|
||||
nk: Some(pallas::Base::from_u128((1 << 127) - 1)),
|
||||
ak: Value::known(pallas::Base::from_u128((1 << 127) - 1)),
|
||||
nk: Value::known(pallas::Base::from_u128((1 << 127) - 1)),
|
||||
},
|
||||
// `ak` = 2^127, `nk` = 2^127
|
||||
MyCircuit {
|
||||
ak: Some(pallas::Base::from_u128(1 << 127)),
|
||||
nk: Some(pallas::Base::from_u128(1 << 127)),
|
||||
ak: Value::known(pallas::Base::from_u128(1 << 127)),
|
||||
nk: Value::known(pallas::Base::from_u128(1 << 127)),
|
||||
},
|
||||
// `ak` = 2^254 - 1, `nk` = 2^254 - 1
|
||||
MyCircuit {
|
||||
ak: Some(two_pow_254 - pallas::Base::one()),
|
||||
nk: Some(two_pow_254 - pallas::Base::one()),
|
||||
ak: Value::known(two_pow_254 - pallas::Base::one()),
|
||||
nk: Value::known(two_pow_254 - pallas::Base::one()),
|
||||
},
|
||||
// `ak` = 2^254, `nk` = 2^254
|
||||
MyCircuit {
|
||||
ak: Some(two_pow_254),
|
||||
nk: Some(two_pow_254),
|
||||
ak: Value::known(two_pow_254),
|
||||
nk: Value::known(two_pow_254),
|
||||
},
|
||||
];
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ use halo2_gadgets::{
|
|||
};
|
||||
use halo2_proofs::{
|
||||
arithmetic::FieldExt,
|
||||
circuit::{AssignedCell, Chip, Layouter},
|
||||
circuit::{AssignedCell, Chip, Layouter, Value},
|
||||
plonk::{self, Advice, Assigned, Column},
|
||||
};
|
||||
|
||||
|
@ -96,21 +96,14 @@ pub(in crate::circuit) trait AddInstruction<F: FieldExt>: Chip<F> {
|
|||
pub(in crate::circuit) fn assign_free_advice<F: Field, V: Copy>(
|
||||
mut layouter: impl Layouter<F>,
|
||||
column: Column<Advice>,
|
||||
value: Option<V>,
|
||||
value: Value<V>,
|
||||
) -> Result<AssignedCell<V, F>, plonk::Error>
|
||||
where
|
||||
for<'v> Assigned<F>: From<&'v V>,
|
||||
{
|
||||
layouter.assign_region(
|
||||
|| "load private",
|
||||
|mut region| {
|
||||
region.assign_advice(
|
||||
|| "load private",
|
||||
column,
|
||||
0,
|
||||
|| value.ok_or(plonk::Error::Synthesis),
|
||||
)
|
||||
},
|
||||
|mut region| region.assign_advice(|| "load private", column, 0, || value),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -74,12 +74,7 @@ impl AddInstruction<pallas::Base> for AddChip {
|
|||
b.copy_advice(|| "copy b", &mut region, self.config.b, 0)?;
|
||||
|
||||
let scalar_val = a.value().zip(b.value()).map(|(a, b)| a + b);
|
||||
region.assign_advice(
|
||||
|| "c",
|
||||
self.config.c,
|
||||
0,
|
||||
|| scalar_val.ok_or(plonk::Error::Synthesis),
|
||||
)
|
||||
region.assign_advice(|| "c", self.config.c, 0, || scalar_val)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use core::iter;
|
||||
|
||||
use halo2_proofs::{
|
||||
circuit::{AssignedCell, Layouter},
|
||||
circuit::{AssignedCell, Layouter, Value},
|
||||
plonk::{Advice, Column, ConstraintSystem, Constraints, Error, Expression, Selector},
|
||||
poly::Rotation,
|
||||
};
|
||||
|
@ -128,8 +128,8 @@ impl DecomposeB {
|
|||
(
|
||||
NoteCommitPiece,
|
||||
RangeConstrained<pallas::Base, AssignedCell<pallas::Base, pallas::Base>>,
|
||||
RangeConstrained<pallas::Base, Option<pallas::Base>>,
|
||||
RangeConstrained<pallas::Base, Option<pallas::Base>>,
|
||||
RangeConstrained<pallas::Base, Value<pallas::Base>>,
|
||||
RangeConstrained<pallas::Base, Value<pallas::Base>>,
|
||||
RangeConstrained<pallas::Base, AssignedCell<pallas::Base, pallas::Base>>,
|
||||
),
|
||||
Error,
|
||||
|
@ -170,7 +170,7 @@ impl DecomposeB {
|
|||
layouter: &mut impl Layouter<pallas::Base>,
|
||||
b: NoteCommitPiece,
|
||||
b_0: RangeConstrained<pallas::Base, AssignedCell<pallas::Base, pallas::Base>>,
|
||||
b_1: RangeConstrained<pallas::Base, Option<pallas::Base>>,
|
||||
b_1: RangeConstrained<pallas::Base, Value<pallas::Base>>,
|
||||
b_2: RangeConstrained<pallas::Base, AssignedCell<pallas::Base, pallas::Base>>,
|
||||
b_3: RangeConstrained<pallas::Base, AssignedCell<pallas::Base, pallas::Base>>,
|
||||
) -> Result<AssignedCell<pallas::Base, pallas::Base>, Error> {
|
||||
|
@ -184,12 +184,7 @@ impl DecomposeB {
|
|||
.copy_advice(|| "b", &mut region, self.col_l, 0)?;
|
||||
b_0.inner()
|
||||
.copy_advice(|| "b_0", &mut region, self.col_m, 0)?;
|
||||
let b_1 = region.assign_advice(
|
||||
|| "b_1",
|
||||
self.col_r,
|
||||
0,
|
||||
|| b_1.inner().ok_or(Error::Synthesis),
|
||||
)?;
|
||||
let b_1 = region.assign_advice(|| "b_1", self.col_r, 0, || *b_1.inner())?;
|
||||
|
||||
b_2.inner()
|
||||
.copy_advice(|| "b_2", &mut region, self.col_m, 1)?;
|
||||
|
@ -277,8 +272,8 @@ impl DecomposeD {
|
|||
) -> Result<
|
||||
(
|
||||
NoteCommitPiece,
|
||||
RangeConstrained<pallas::Base, Option<pallas::Base>>,
|
||||
RangeConstrained<pallas::Base, Option<pallas::Base>>,
|
||||
RangeConstrained<pallas::Base, Value<pallas::Base>>,
|
||||
RangeConstrained<pallas::Base, Value<pallas::Base>>,
|
||||
RangeConstrained<pallas::Base, AssignedCell<pallas::Base, pallas::Base>>,
|
||||
),
|
||||
Error,
|
||||
|
@ -313,7 +308,7 @@ impl DecomposeD {
|
|||
&self,
|
||||
layouter: &mut impl Layouter<pallas::Base>,
|
||||
d: NoteCommitPiece,
|
||||
d_0: RangeConstrained<pallas::Base, Option<pallas::Base>>,
|
||||
d_0: RangeConstrained<pallas::Base, Value<pallas::Base>>,
|
||||
d_1: RangeConstrained<pallas::Base, AssignedCell<pallas::Base, pallas::Base>>,
|
||||
d_2: RangeConstrained<pallas::Base, AssignedCell<pallas::Base, pallas::Base>>,
|
||||
z1_d: AssignedCell<pallas::Base, pallas::Base>,
|
||||
|
@ -326,12 +321,7 @@ impl DecomposeD {
|
|||
d.inner()
|
||||
.cell_value()
|
||||
.copy_advice(|| "d", &mut region, self.col_l, 0)?;
|
||||
let d_0 = region.assign_advice(
|
||||
|| "d_0",
|
||||
self.col_m,
|
||||
0,
|
||||
|| d_0.inner().ok_or(Error::Synthesis),
|
||||
)?;
|
||||
let d_0 = region.assign_advice(|| "d_0", self.col_m, 0, || *d_0.inner())?;
|
||||
d_1.inner()
|
||||
.copy_advice(|| "d_1", &mut region, self.col_r, 0)?;
|
||||
|
||||
|
@ -529,7 +519,7 @@ impl DecomposeG {
|
|||
) -> Result<
|
||||
(
|
||||
NoteCommitPiece,
|
||||
RangeConstrained<pallas::Base, Option<pallas::Base>>,
|
||||
RangeConstrained<pallas::Base, Value<pallas::Base>>,
|
||||
RangeConstrained<pallas::Base, AssignedCell<pallas::Base, pallas::Base>>,
|
||||
),
|
||||
Error,
|
||||
|
@ -561,7 +551,7 @@ impl DecomposeG {
|
|||
&self,
|
||||
layouter: &mut impl Layouter<pallas::Base>,
|
||||
g: NoteCommitPiece,
|
||||
g_0: RangeConstrained<pallas::Base, Option<pallas::Base>>,
|
||||
g_0: RangeConstrained<pallas::Base, Value<pallas::Base>>,
|
||||
g_1: RangeConstrained<pallas::Base, AssignedCell<pallas::Base, pallas::Base>>,
|
||||
z1_g: AssignedCell<pallas::Base, pallas::Base>,
|
||||
) -> Result<AssignedCell<pallas::Base, pallas::Base>, Error> {
|
||||
|
@ -573,12 +563,7 @@ impl DecomposeG {
|
|||
g.inner()
|
||||
.cell_value()
|
||||
.copy_advice(|| "g", &mut region, self.col_l, 0)?;
|
||||
let g_0 = region.assign_advice(
|
||||
|| "g_0",
|
||||
self.col_m,
|
||||
0,
|
||||
|| g_0.inner().ok_or(Error::Synthesis),
|
||||
)?;
|
||||
let g_0 = region.assign_advice(|| "g_0", self.col_m, 0, || *g_0.inner())?;
|
||||
|
||||
g_1.inner()
|
||||
.copy_advice(|| "g_1", &mut region, self.col_l, 1)?;
|
||||
|
@ -656,7 +641,7 @@ impl DecomposeH {
|
|||
(
|
||||
NoteCommitPiece,
|
||||
RangeConstrained<pallas::Base, AssignedCell<pallas::Base, pallas::Base>>,
|
||||
RangeConstrained<pallas::Base, Option<pallas::Base>>,
|
||||
RangeConstrained<pallas::Base, Value<pallas::Base>>,
|
||||
),
|
||||
Error,
|
||||
> {
|
||||
|
@ -677,7 +662,7 @@ impl DecomposeH {
|
|||
[
|
||||
h_0.value(),
|
||||
h_1,
|
||||
RangeConstrained::bitrange_of(Some(&pallas::Base::zero()), 0..4),
|
||||
RangeConstrained::bitrange_of(Value::known(&pallas::Base::zero()), 0..4),
|
||||
],
|
||||
)?;
|
||||
|
||||
|
@ -689,7 +674,7 @@ impl DecomposeH {
|
|||
layouter: &mut impl Layouter<pallas::Base>,
|
||||
h: NoteCommitPiece,
|
||||
h_0: RangeConstrained<pallas::Base, AssignedCell<pallas::Base, pallas::Base>>,
|
||||
h_1: RangeConstrained<pallas::Base, Option<pallas::Base>>,
|
||||
h_1: RangeConstrained<pallas::Base, Value<pallas::Base>>,
|
||||
) -> Result<AssignedCell<pallas::Base, pallas::Base>, Error> {
|
||||
layouter.assign_region(
|
||||
|| "NoteCommit MessagePiece h",
|
||||
|
@ -701,12 +686,7 @@ impl DecomposeH {
|
|||
.copy_advice(|| "h", &mut region, self.col_l, 0)?;
|
||||
h_0.inner()
|
||||
.copy_advice(|| "h_0", &mut region, self.col_m, 0)?;
|
||||
let h_1 = region.assign_advice(
|
||||
|| "h_1",
|
||||
self.col_r,
|
||||
0,
|
||||
|| h_1.inner().ok_or(Error::Synthesis),
|
||||
)?;
|
||||
let h_1 = region.assign_advice(|| "h_1", self.col_r, 0, || *h_1.inner())?;
|
||||
|
||||
Ok(h_1)
|
||||
},
|
||||
|
@ -1357,10 +1337,10 @@ impl YCanonicity {
|
|||
&self,
|
||||
layouter: &mut impl Layouter<pallas::Base>,
|
||||
y: AssignedCell<pallas::Base, pallas::Base>,
|
||||
lsb: RangeConstrained<pallas::Base, Option<pallas::Base>>,
|
||||
lsb: RangeConstrained<pallas::Base, Value<pallas::Base>>,
|
||||
k_0: RangeConstrained<pallas::Base, AssignedCell<pallas::Base, pallas::Base>>,
|
||||
k_2: RangeConstrained<pallas::Base, AssignedCell<pallas::Base, pallas::Base>>,
|
||||
k_3: RangeConstrained<pallas::Base, Option<pallas::Base>>,
|
||||
k_3: RangeConstrained<pallas::Base, Value<pallas::Base>>,
|
||||
j: AssignedCell<pallas::Base, pallas::Base>,
|
||||
z1_j: AssignedCell<pallas::Base, pallas::Base>,
|
||||
z13_j: AssignedCell<pallas::Base, pallas::Base>,
|
||||
|
@ -1381,12 +1361,7 @@ impl YCanonicity {
|
|||
y.copy_advice(|| "copy y", &mut region, self.advices[5], offset)?;
|
||||
// Witness LSB.
|
||||
let lsb = region
|
||||
.assign_advice(
|
||||
|| "witness LSB",
|
||||
self.advices[6],
|
||||
offset,
|
||||
|| lsb.inner().ok_or(Error::Synthesis),
|
||||
)
|
||||
.assign_advice(|| "witness LSB", self.advices[6], offset, || *lsb.inner())
|
||||
// SAFETY: This is sound because we just assigned this cell from a
|
||||
// range-constrained value.
|
||||
.map(|cell| RangeConstrained::unsound_unchecked(cell, lsb.num_bits()))?;
|
||||
|
@ -1401,7 +1376,7 @@ impl YCanonicity {
|
|||
|| "witness k_3",
|
||||
self.advices[9],
|
||||
offset,
|
||||
|| k_3.inner().ok_or(Error::Synthesis),
|
||||
|| *k_3.inner(),
|
||||
)?;
|
||||
|
||||
lsb
|
||||
|
@ -1586,7 +1561,7 @@ impl NoteCommitChip {
|
|||
}
|
||||
|
||||
pub(in crate::circuit) mod gadgets {
|
||||
use halo2_proofs::circuit::Chip;
|
||||
use halo2_proofs::circuit::{Chip, Value};
|
||||
|
||||
use super::*;
|
||||
|
||||
|
@ -1817,11 +1792,11 @@ pub(in crate::circuit) mod gadgets {
|
|||
// Decompose the low 130 bits of a_prime = a + 2^130 - t_P, and output
|
||||
// the running sum at the end of it. If a_prime < 2^130, the running sum
|
||||
// will be 0.
|
||||
let a_prime = a.value().map(|a| {
|
||||
let two_pow_130 = pallas::Base::from_u128(1u128 << 65).square();
|
||||
let t_p = pallas::Base::from_u128(T_P);
|
||||
a + two_pow_130 - t_p
|
||||
});
|
||||
let a_prime = {
|
||||
let two_pow_130 = Value::known(pallas::Base::from_u128(1u128 << 65).square());
|
||||
let t_p = Value::known(pallas::Base::from_u128(T_P));
|
||||
a.value() + two_pow_130 - t_p
|
||||
};
|
||||
let zs = lookup_config.witness_check(
|
||||
layouter.namespace(|| "Decompose low 130 bits of (a + 2^130 - t_P)"),
|
||||
a_prime,
|
||||
|
@ -1856,12 +1831,12 @@ pub(in crate::circuit) mod gadgets {
|
|||
// Decompose the low 140 bits of b3_c_prime = b_3 + 2^4 c + 2^140 - t_P,
|
||||
// and output the running sum at the end of it.
|
||||
// If b3_c_prime < 2^140, the running sum will be 0.
|
||||
let b3_c_prime = b_3.inner().value().zip(c.value()).map(|(b_3, c)| {
|
||||
let two_pow_4 = pallas::Base::from(1u64 << 4);
|
||||
let two_pow_140 = pallas::Base::from_u128(1u128 << 70).square();
|
||||
let t_p = pallas::Base::from_u128(T_P);
|
||||
b_3 + (two_pow_4 * c) + two_pow_140 - t_p
|
||||
});
|
||||
let b3_c_prime = {
|
||||
let two_pow_4 = Value::known(pallas::Base::from(1u64 << 4));
|
||||
let two_pow_140 = Value::known(pallas::Base::from_u128(1u128 << 70).square());
|
||||
let t_p = Value::known(pallas::Base::from_u128(T_P));
|
||||
b_3.inner().value() + (two_pow_4 * c.value()) + two_pow_140 - t_p
|
||||
};
|
||||
|
||||
let zs = lookup_config.witness_check(
|
||||
layouter.namespace(|| "Decompose low 140 bits of (b_3 + 2^4 c + 2^140 - t_P)"),
|
||||
|
@ -1894,12 +1869,12 @@ pub(in crate::circuit) mod gadgets {
|
|||
// to 130 bits. z13_f == 0 is directly checked in the gate.
|
||||
// - 0 ≤ e_1 + 2^4 f + 2^140 - t_P < 2^140 (14 ten-bit lookups)
|
||||
|
||||
let e1_f_prime = e_1.inner().value().zip(f.value()).map(|(e_1, f)| {
|
||||
let two_pow_4 = pallas::Base::from(1u64 << 4);
|
||||
let two_pow_140 = pallas::Base::from_u128(1u128 << 70).square();
|
||||
let t_p = pallas::Base::from_u128(T_P);
|
||||
e_1 + (two_pow_4 * f) + two_pow_140 - t_p
|
||||
});
|
||||
let e1_f_prime = {
|
||||
let two_pow_4 = Value::known(pallas::Base::from(1u64 << 4));
|
||||
let two_pow_140 = Value::known(pallas::Base::from_u128(1u128 << 70).square());
|
||||
let t_p = Value::known(pallas::Base::from_u128(T_P));
|
||||
e_1.inner().value() + (two_pow_4 * f.value()) + two_pow_140 - t_p
|
||||
};
|
||||
|
||||
// Decompose the low 140 bits of e1_f_prime = e_1 + 2^4 f + 2^140 - t_P,
|
||||
// and output the running sum at the end of it.
|
||||
|
@ -1936,12 +1911,12 @@ pub(in crate::circuit) mod gadgets {
|
|||
// Decompose the low 130 bits of g1_g2_prime = g_1 + (2^9)g_2 + 2^130 - t_P,
|
||||
// and output the running sum at the end of it.
|
||||
// If g1_g2_prime < 2^130, the running sum will be 0.
|
||||
let g1_g2_prime = g_1.inner().value().zip(g_2.value()).map(|(g_1, g_2)| {
|
||||
let two_pow_9 = pallas::Base::from(1u64 << 9);
|
||||
let two_pow_130 = pallas::Base::from_u128(1u128 << 65).square();
|
||||
let t_p = pallas::Base::from_u128(T_P);
|
||||
g_1 + (two_pow_9 * g_2) + two_pow_130 - t_p
|
||||
});
|
||||
let g1_g2_prime = {
|
||||
let two_pow_9 = Value::known(pallas::Base::from(1u64 << 9));
|
||||
let two_pow_130 = Value::known(pallas::Base::from_u128(1u128 << 65).square());
|
||||
let t_p = Value::known(pallas::Base::from_u128(T_P));
|
||||
g_1.inner().value() + (two_pow_9 * g_2.value()) + two_pow_130 - t_p
|
||||
};
|
||||
|
||||
let zs = lookup_config.witness_check(
|
||||
layouter.namespace(|| "Decompose low 130 bits of (g_1 + (2^9)g_2 + 2^130 - t_P)"),
|
||||
|
@ -1966,7 +1941,7 @@ pub(in crate::circuit) mod gadgets {
|
|||
y_canon: &YCanonicity,
|
||||
mut layouter: impl Layouter<pallas::Base>,
|
||||
y: AssignedCell<pallas::Base, pallas::Base>,
|
||||
lsb: RangeConstrained<pallas::Base, Option<pallas::Base>>,
|
||||
lsb: RangeConstrained<pallas::Base, Value<pallas::Base>>,
|
||||
) -> Result<RangeConstrained<pallas::Base, AssignedCell<pallas::Base, pallas::Base>>, Error>
|
||||
{
|
||||
// Decompose the field element
|
||||
|
@ -1997,16 +1972,11 @@ pub(in crate::circuit) mod gadgets {
|
|||
|
||||
// Decompose j = LSB + (2)k_0 + (2^10)k_1 using 25 ten-bit lookups.
|
||||
let (j, z1_j, z13_j) = {
|
||||
let j = lsb
|
||||
.inner()
|
||||
.value()
|
||||
.zip(k_0.inner().value())
|
||||
.zip(k_1.inner().value())
|
||||
.map(|((lsb, k_0), k_1)| {
|
||||
let two = pallas::Base::from(2);
|
||||
let two_pow_10 = pallas::Base::from(1 << 10);
|
||||
lsb + two * k_0 + two_pow_10 * k_1
|
||||
});
|
||||
let j = {
|
||||
let two = Value::known(pallas::Base::from(2));
|
||||
let two_pow_10 = Value::known(pallas::Base::from(1 << 10));
|
||||
lsb.inner().value() + two * k_0.inner().value() + two_pow_10 * k_1.inner().value()
|
||||
};
|
||||
let zs = lookup_config.witness_check(
|
||||
layouter.namespace(|| "Decompose j = LSB + (2)k_0 + (2^10)k_1"),
|
||||
j,
|
||||
|
@ -2069,7 +2039,7 @@ mod tests {
|
|||
use ff::{Field, PrimeField, PrimeFieldBits};
|
||||
use group::Curve;
|
||||
use halo2_proofs::{
|
||||
circuit::{Layouter, SimpleFloorPlanner},
|
||||
circuit::{Layouter, SimpleFloorPlanner, Value},
|
||||
dev::MockProver,
|
||||
plonk::{Circuit, ConstraintSystem, Error},
|
||||
};
|
||||
|
@ -2084,12 +2054,12 @@ mod tests {
|
|||
fn note_commit() {
|
||||
#[derive(Default)]
|
||||
struct MyCircuit {
|
||||
gd_x: Option<pallas::Base>,
|
||||
gd_y_lsb: Option<pallas::Base>,
|
||||
pkd_x: Option<pallas::Base>,
|
||||
pkd_y_lsb: Option<pallas::Base>,
|
||||
rho: Option<pallas::Base>,
|
||||
psi: Option<pallas::Base>,
|
||||
gd_x: Value<pallas::Base>,
|
||||
gd_y_lsb: Value<pallas::Base>,
|
||||
pkd_x: Value<pallas::Base>,
|
||||
pkd_y_lsb: Value<pallas::Base>,
|
||||
rho: Value<pallas::Base>,
|
||||
psi: Value<pallas::Base>,
|
||||
}
|
||||
|
||||
impl Circuit<pallas::Base> for MyCircuit {
|
||||
|
@ -2235,7 +2205,7 @@ mod tests {
|
|||
assign_free_advice(
|
||||
layouter.namespace(|| "witness value"),
|
||||
note_commit_config.advices[0],
|
||||
Some(value),
|
||||
Value::known(value),
|
||||
)?
|
||||
};
|
||||
|
||||
|
@ -2254,8 +2224,11 @@ mod tests {
|
|||
)?;
|
||||
|
||||
let rcm = pallas::Scalar::random(OsRng);
|
||||
let rcm_gadget =
|
||||
ScalarFixed::new(ecc_chip.clone(), layouter.namespace(|| "rcm"), Some(rcm))?;
|
||||
let rcm_gadget = ScalarFixed::new(
|
||||
ecc_chip.clone(),
|
||||
layouter.namespace(|| "rcm"),
|
||||
Value::known(rcm),
|
||||
)?;
|
||||
|
||||
let cm = gadgets::note_commit(
|
||||
layouter.namespace(|| "Hash NoteCommit pieces"),
|
||||
|
@ -2273,53 +2246,40 @@ mod tests {
|
|||
let domain = CommitDomain::new(NOTE_COMMITMENT_PERSONALIZATION);
|
||||
// Hash g★_d || pk★_d || i2lebsp_{64}(v) || rho || psi
|
||||
let lsb = |y_lsb: pallas::Base| y_lsb == pallas::Base::one();
|
||||
let point = domain
|
||||
.commit(
|
||||
iter::empty()
|
||||
.chain(
|
||||
self.gd_x
|
||||
.unwrap()
|
||||
.to_le_bits()
|
||||
.iter()
|
||||
.by_vals()
|
||||
.take(L_ORCHARD_BASE),
|
||||
let point = self
|
||||
.gd_x
|
||||
.zip(self.gd_y_lsb)
|
||||
.zip(self.pkd_x.zip(self.pkd_y_lsb))
|
||||
.zip(self.rho.zip(self.psi))
|
||||
.map(|(((gd_x, gd_y_lsb), (pkd_x, pkd_y_lsb)), (rho, psi))| {
|
||||
domain
|
||||
.commit(
|
||||
iter::empty()
|
||||
.chain(
|
||||
gd_x.to_le_bits().iter().by_vals().take(L_ORCHARD_BASE),
|
||||
)
|
||||
.chain(Some(lsb(gd_y_lsb)))
|
||||
.chain(
|
||||
pkd_x
|
||||
.to_le_bits()
|
||||
.iter()
|
||||
.by_vals()
|
||||
.take(L_ORCHARD_BASE),
|
||||
)
|
||||
.chain(Some(lsb(pkd_y_lsb)))
|
||||
.chain(value.to_le_bits().iter().by_vals().take(L_VALUE))
|
||||
.chain(
|
||||
rho.to_le_bits().iter().by_vals().take(L_ORCHARD_BASE),
|
||||
)
|
||||
.chain(
|
||||
psi.to_le_bits().iter().by_vals().take(L_ORCHARD_BASE),
|
||||
),
|
||||
&rcm,
|
||||
)
|
||||
.chain(Some(lsb(self.gd_y_lsb.unwrap())))
|
||||
.chain(
|
||||
self.pkd_x
|
||||
.unwrap()
|
||||
.to_le_bits()
|
||||
.iter()
|
||||
.by_vals()
|
||||
.take(L_ORCHARD_BASE),
|
||||
)
|
||||
.chain(Some(lsb(self.pkd_y_lsb.unwrap())))
|
||||
.chain(value.to_le_bits().iter().by_vals().take(L_VALUE))
|
||||
.chain(
|
||||
self.rho
|
||||
.unwrap()
|
||||
.to_le_bits()
|
||||
.iter()
|
||||
.by_vals()
|
||||
.take(L_ORCHARD_BASE),
|
||||
)
|
||||
.chain(
|
||||
self.psi
|
||||
.unwrap()
|
||||
.to_le_bits()
|
||||
.iter()
|
||||
.by_vals()
|
||||
.take(L_ORCHARD_BASE),
|
||||
),
|
||||
&rcm,
|
||||
)
|
||||
.unwrap()
|
||||
.to_affine();
|
||||
NonIdentityPoint::new(
|
||||
ecc_chip,
|
||||
layouter.namespace(|| "witness cm"),
|
||||
Some(point),
|
||||
)?
|
||||
.unwrap()
|
||||
.to_affine()
|
||||
});
|
||||
NonIdentityPoint::new(ecc_chip, layouter.namespace(|| "witness cm"), point)?
|
||||
};
|
||||
cm.constrain_equal(layouter.namespace(|| "cm == expected cm"), &expected_cm)
|
||||
}
|
||||
|
@ -2331,66 +2291,66 @@ mod tests {
|
|||
// `gd_x` = -1, `pkd_x` = -1 (these have to be x-coordinates of curve points)
|
||||
// `rho` = 0, `psi` = 0
|
||||
MyCircuit {
|
||||
gd_x: Some(-pallas::Base::one()),
|
||||
gd_y_lsb: Some(pallas::Base::one()),
|
||||
pkd_x: Some(-pallas::Base::one()),
|
||||
pkd_y_lsb: Some(pallas::Base::one()),
|
||||
rho: Some(pallas::Base::zero()),
|
||||
psi: Some(pallas::Base::zero()),
|
||||
gd_x: Value::known(-pallas::Base::one()),
|
||||
gd_y_lsb: Value::known(pallas::Base::one()),
|
||||
pkd_x: Value::known(-pallas::Base::one()),
|
||||
pkd_y_lsb: Value::known(pallas::Base::one()),
|
||||
rho: Value::known(pallas::Base::zero()),
|
||||
psi: Value::known(pallas::Base::zero()),
|
||||
},
|
||||
// `rho` = T_Q - 1, `psi` = T_Q - 1
|
||||
MyCircuit {
|
||||
gd_x: Some(-pallas::Base::one()),
|
||||
gd_y_lsb: Some(pallas::Base::zero()),
|
||||
pkd_x: Some(-pallas::Base::one()),
|
||||
pkd_y_lsb: Some(pallas::Base::zero()),
|
||||
rho: Some(pallas::Base::from_u128(T_Q - 1)),
|
||||
psi: Some(pallas::Base::from_u128(T_Q - 1)),
|
||||
gd_x: Value::known(-pallas::Base::one()),
|
||||
gd_y_lsb: Value::known(pallas::Base::zero()),
|
||||
pkd_x: Value::known(-pallas::Base::one()),
|
||||
pkd_y_lsb: Value::known(pallas::Base::zero()),
|
||||
rho: Value::known(pallas::Base::from_u128(T_Q - 1)),
|
||||
psi: Value::known(pallas::Base::from_u128(T_Q - 1)),
|
||||
},
|
||||
// `rho` = T_Q, `psi` = T_Q
|
||||
MyCircuit {
|
||||
gd_x: Some(-pallas::Base::one()),
|
||||
gd_y_lsb: Some(pallas::Base::one()),
|
||||
pkd_x: Some(-pallas::Base::one()),
|
||||
pkd_y_lsb: Some(pallas::Base::zero()),
|
||||
rho: Some(pallas::Base::from_u128(T_Q)),
|
||||
psi: Some(pallas::Base::from_u128(T_Q)),
|
||||
gd_x: Value::known(-pallas::Base::one()),
|
||||
gd_y_lsb: Value::known(pallas::Base::one()),
|
||||
pkd_x: Value::known(-pallas::Base::one()),
|
||||
pkd_y_lsb: Value::known(pallas::Base::zero()),
|
||||
rho: Value::known(pallas::Base::from_u128(T_Q)),
|
||||
psi: Value::known(pallas::Base::from_u128(T_Q)),
|
||||
},
|
||||
// `rho` = 2^127 - 1, `psi` = 2^127 - 1
|
||||
MyCircuit {
|
||||
gd_x: Some(-pallas::Base::one()),
|
||||
gd_y_lsb: Some(pallas::Base::zero()),
|
||||
pkd_x: Some(-pallas::Base::one()),
|
||||
pkd_y_lsb: Some(pallas::Base::one()),
|
||||
rho: Some(pallas::Base::from_u128((1 << 127) - 1)),
|
||||
psi: Some(pallas::Base::from_u128((1 << 127) - 1)),
|
||||
gd_x: Value::known(-pallas::Base::one()),
|
||||
gd_y_lsb: Value::known(pallas::Base::zero()),
|
||||
pkd_x: Value::known(-pallas::Base::one()),
|
||||
pkd_y_lsb: Value::known(pallas::Base::one()),
|
||||
rho: Value::known(pallas::Base::from_u128((1 << 127) - 1)),
|
||||
psi: Value::known(pallas::Base::from_u128((1 << 127) - 1)),
|
||||
},
|
||||
// `rho` = 2^127, `psi` = 2^127
|
||||
MyCircuit {
|
||||
gd_x: Some(-pallas::Base::one()),
|
||||
gd_y_lsb: Some(pallas::Base::zero()),
|
||||
pkd_x: Some(-pallas::Base::one()),
|
||||
pkd_y_lsb: Some(pallas::Base::zero()),
|
||||
rho: Some(pallas::Base::from_u128(1 << 127)),
|
||||
psi: Some(pallas::Base::from_u128(1 << 127)),
|
||||
gd_x: Value::known(-pallas::Base::one()),
|
||||
gd_y_lsb: Value::known(pallas::Base::zero()),
|
||||
pkd_x: Value::known(-pallas::Base::one()),
|
||||
pkd_y_lsb: Value::known(pallas::Base::zero()),
|
||||
rho: Value::known(pallas::Base::from_u128(1 << 127)),
|
||||
psi: Value::known(pallas::Base::from_u128(1 << 127)),
|
||||
},
|
||||
// `rho` = 2^254 - 1, `psi` = 2^254 - 1
|
||||
MyCircuit {
|
||||
gd_x: Some(-pallas::Base::one()),
|
||||
gd_y_lsb: Some(pallas::Base::one()),
|
||||
pkd_x: Some(-pallas::Base::one()),
|
||||
pkd_y_lsb: Some(pallas::Base::one()),
|
||||
rho: Some(two_pow_254 - pallas::Base::one()),
|
||||
psi: Some(two_pow_254 - pallas::Base::one()),
|
||||
gd_x: Value::known(-pallas::Base::one()),
|
||||
gd_y_lsb: Value::known(pallas::Base::one()),
|
||||
pkd_x: Value::known(-pallas::Base::one()),
|
||||
pkd_y_lsb: Value::known(pallas::Base::one()),
|
||||
rho: Value::known(two_pow_254 - pallas::Base::one()),
|
||||
psi: Value::known(two_pow_254 - pallas::Base::one()),
|
||||
},
|
||||
// `rho` = 2^254, `psi` = 2^254
|
||||
MyCircuit {
|
||||
gd_x: Some(-pallas::Base::one()),
|
||||
gd_y_lsb: Some(pallas::Base::one()),
|
||||
pkd_x: Some(-pallas::Base::one()),
|
||||
pkd_y_lsb: Some(pallas::Base::zero()),
|
||||
rho: Some(two_pow_254),
|
||||
psi: Some(two_pow_254),
|
||||
gd_x: Value::known(-pallas::Base::one()),
|
||||
gd_y_lsb: Value::known(pallas::Base::one()),
|
||||
pkd_x: Value::known(-pallas::Base::one()),
|
||||
pkd_y_lsb: Value::known(pallas::Base::zero()),
|
||||
rho: Value::known(two_pow_254),
|
||||
psi: Value::known(two_pow_254),
|
||||
},
|
||||
];
|
||||
|
||||
|
|
Loading…
Reference in New Issue