mirror of https://github.com/zcash/orchard.git
Adjust APIs of NoteCommit circuit impl to separate gadget and chip
The separation isn't quite complete, as we removed the `GateCells` abstraction, but it makes the outer APIs clearer.
This commit is contained in:
parent
8f15db1d01
commit
903f9e8160
|
@ -22,7 +22,7 @@ use self::{
|
||||||
add_chip::{AddChip, AddConfig},
|
add_chip::{AddChip, AddConfig},
|
||||||
assign_free_advice,
|
assign_free_advice,
|
||||||
},
|
},
|
||||||
note_commit::NoteCommitConfig,
|
note_commit::{NoteCommitChip, NoteCommitConfig},
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
constants::{
|
constants::{
|
||||||
|
@ -292,12 +292,12 @@ impl plonk::Circuit<pallas::Base> for Circuit {
|
||||||
// Configuration to handle decomposition and canonicity checking
|
// Configuration to handle decomposition and canonicity checking
|
||||||
// for NoteCommit_old.
|
// for NoteCommit_old.
|
||||||
let old_note_commit_config =
|
let old_note_commit_config =
|
||||||
NoteCommitConfig::configure(meta, advices, sinsemilla_config_1.clone());
|
NoteCommitChip::configure(meta, advices, sinsemilla_config_1.clone());
|
||||||
|
|
||||||
// Configuration to handle decomposition and canonicity checking
|
// Configuration to handle decomposition and canonicity checking
|
||||||
// for NoteCommit_new.
|
// for NoteCommit_new.
|
||||||
let new_note_commit_config =
|
let new_note_commit_config =
|
||||||
NoteCommitConfig::configure(meta, advices, sinsemilla_config_2.clone());
|
NoteCommitChip::configure(meta, advices, sinsemilla_config_2.clone());
|
||||||
|
|
||||||
Config {
|
Config {
|
||||||
primary,
|
primary,
|
||||||
|
@ -530,17 +530,16 @@ impl plonk::Circuit<pallas::Base> for Circuit {
|
||||||
|
|
||||||
// Old note commitment integrity.
|
// Old note commitment integrity.
|
||||||
{
|
{
|
||||||
let old_note_commit_config = config.old_note_commit_config.clone();
|
|
||||||
|
|
||||||
let rcm_old = self.rcm_old.as_ref().map(|rcm_old| rcm_old.inner());
|
let rcm_old = self.rcm_old.as_ref().map(|rcm_old| rcm_old.inner());
|
||||||
|
|
||||||
// g★_d || pk★_d || i2lebsp_{64}(v) || i2lebsp_{255}(rho) || i2lebsp_{255}(psi)
|
// g★_d || pk★_d || i2lebsp_{64}(v) || i2lebsp_{255}(rho) || i2lebsp_{255}(psi)
|
||||||
let derived_cm_old = old_note_commit_config.assign_region(
|
let derived_cm_old = gadget::note_commit(
|
||||||
layouter.namespace(|| {
|
layouter.namespace(|| {
|
||||||
"g★_d || pk★_d || i2lebsp_{64}(v) || i2lebsp_{255}(rho) || i2lebsp_{255}(psi)"
|
"g★_d || pk★_d || i2lebsp_{64}(v) || i2lebsp_{255}(rho) || i2lebsp_{255}(psi)"
|
||||||
}),
|
}),
|
||||||
config.sinsemilla_chip_1(),
|
config.sinsemilla_chip_1(),
|
||||||
config.ecc_chip(),
|
config.ecc_chip(),
|
||||||
|
config.note_commit_chip_old(),
|
||||||
g_d_old.inner(),
|
g_d_old.inner(),
|
||||||
pk_d_old.inner(),
|
pk_d_old.inner(),
|
||||||
v_old.clone(),
|
v_old.clone(),
|
||||||
|
@ -555,8 +554,6 @@ impl plonk::Circuit<pallas::Base> for Circuit {
|
||||||
|
|
||||||
// New note commitment integrity.
|
// New note commitment integrity.
|
||||||
{
|
{
|
||||||
let new_note_commit_config = config.new_note_commit_config.clone();
|
|
||||||
|
|
||||||
// Witness g_d_new
|
// Witness g_d_new
|
||||||
let g_d_new = {
|
let g_d_new = {
|
||||||
let g_d_new = self.g_d_new.map(|g_d_new| g_d_new.to_affine());
|
let g_d_new = self.g_d_new.map(|g_d_new| g_d_new.to_affine());
|
||||||
|
@ -590,12 +587,13 @@ impl plonk::Circuit<pallas::Base> for Circuit {
|
||||||
let rcm_new = self.rcm_new.as_ref().map(|rcm_new| rcm_new.inner());
|
let rcm_new = self.rcm_new.as_ref().map(|rcm_new| rcm_new.inner());
|
||||||
|
|
||||||
// g★_d || pk★_d || i2lebsp_{64}(v) || i2lebsp_{255}(rho) || i2lebsp_{255}(psi)
|
// g★_d || pk★_d || i2lebsp_{64}(v) || i2lebsp_{255}(rho) || i2lebsp_{255}(psi)
|
||||||
let cm_new = new_note_commit_config.assign_region(
|
let cm_new = gadget::note_commit(
|
||||||
layouter.namespace(|| {
|
layouter.namespace(|| {
|
||||||
"g★_d || pk★_d || i2lebsp_{64}(v) || i2lebsp_{255}(rho) || i2lebsp_{255}(psi)"
|
"g★_d || pk★_d || i2lebsp_{64}(v) || i2lebsp_{255}(rho) || i2lebsp_{255}(psi)"
|
||||||
}),
|
}),
|
||||||
config.sinsemilla_chip_2(),
|
config.sinsemilla_chip_2(),
|
||||||
config.ecc_chip(),
|
config.ecc_chip(),
|
||||||
|
config.note_commit_chip_new(),
|
||||||
g_d_new.inner(),
|
g_d_new.inner(),
|
||||||
pk_d_new.inner(),
|
pk_d_new.inner(),
|
||||||
v_new.clone(),
|
v_new.clone(),
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
use ff::Field;
|
use ff::Field;
|
||||||
use pasta_curves::pallas;
|
use pasta_curves::pallas;
|
||||||
|
|
||||||
use super::commit_ivk::CommitIvkChip;
|
use super::{commit_ivk::CommitIvkChip, note_commit::NoteCommitChip};
|
||||||
use crate::constants::{
|
use crate::constants::{
|
||||||
NullifierK, OrchardCommitDomains, OrchardFixedBases, OrchardFixedBasesFull, OrchardHashDomains,
|
NullifierK, OrchardCommitDomains, OrchardFixedBases, OrchardFixedBasesFull, OrchardHashDomains,
|
||||||
ValueCommitV,
|
ValueCommitV,
|
||||||
|
@ -64,6 +64,14 @@ impl super::Config {
|
||||||
pub(super) fn poseidon_chip(&self) -> PoseidonChip<pallas::Base, 3, 2> {
|
pub(super) fn poseidon_chip(&self) -> PoseidonChip<pallas::Base, 3, 2> {
|
||||||
PoseidonChip::construct(self.poseidon_config.clone())
|
PoseidonChip::construct(self.poseidon_config.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(super) fn note_commit_chip_new(&self) -> NoteCommitChip {
|
||||||
|
NoteCommitChip::construct(self.new_note_commit_config.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) fn note_commit_chip_old(&self) -> NoteCommitChip {
|
||||||
|
NoteCommitChip::construct(self.old_note_commit_config.clone())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An instruction set for adding two circuit words (field elements).
|
/// An instruction set for adding two circuit words (field elements).
|
||||||
|
@ -200,3 +208,4 @@ pub(in crate::circuit) fn derive_nullifier<
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(in crate::circuit) use crate::circuit::commit_ivk::gadgets::commit_ivk;
|
pub(in crate::circuit) use crate::circuit::commit_ivk::gadgets::commit_ivk;
|
||||||
|
pub(in crate::circuit) use crate::circuit::note_commit::gadgets::note_commit;
|
||||||
|
|
|
@ -1431,7 +1431,12 @@ pub struct NoteCommitConfig {
|
||||||
SinsemillaConfig<OrchardHashDomains, OrchardCommitDomains, OrchardFixedBases>,
|
SinsemillaConfig<OrchardHashDomains, OrchardCommitDomains, OrchardFixedBases>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NoteCommitConfig {
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct NoteCommitChip {
|
||||||
|
config: NoteCommitConfig,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NoteCommitChip {
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
#[allow(clippy::many_single_char_names)]
|
#[allow(clippy::many_single_char_names)]
|
||||||
pub(in crate::circuit) fn configure(
|
pub(in crate::circuit) fn configure(
|
||||||
|
@ -1442,7 +1447,7 @@ impl NoteCommitConfig {
|
||||||
OrchardCommitDomains,
|
OrchardCommitDomains,
|
||||||
OrchardFixedBases,
|
OrchardFixedBases,
|
||||||
>,
|
>,
|
||||||
) -> Self {
|
) -> NoteCommitConfig {
|
||||||
// Useful constants
|
// Useful constants
|
||||||
let two = pallas::Base::from(2);
|
let two = pallas::Base::from(2);
|
||||||
let two_pow_2 = pallas::Base::from(1 << 2);
|
let two_pow_2 = pallas::Base::from(1 << 2);
|
||||||
|
@ -1536,7 +1541,7 @@ impl NoteCommitConfig {
|
||||||
t_p,
|
t_p,
|
||||||
);
|
);
|
||||||
|
|
||||||
Self {
|
NoteCommitConfig {
|
||||||
b,
|
b,
|
||||||
d,
|
d,
|
||||||
e,
|
e,
|
||||||
|
@ -1553,14 +1558,24 @@ impl NoteCommitConfig {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(in crate::circuit) fn construct(config: NoteCommitConfig) -> Self {
|
||||||
|
Self { config }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(in crate::circuit) mod gadgets {
|
||||||
|
use halo2_proofs::circuit::Chip;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
#[allow(clippy::many_single_char_names)]
|
#[allow(clippy::many_single_char_names)]
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub(in crate::circuit) fn assign_region(
|
pub(in crate::circuit) fn note_commit(
|
||||||
&self,
|
|
||||||
mut layouter: impl Layouter<pallas::Base>,
|
mut layouter: impl Layouter<pallas::Base>,
|
||||||
chip: SinsemillaChip<OrchardHashDomains, OrchardCommitDomains, OrchardFixedBases>,
|
chip: SinsemillaChip<OrchardHashDomains, OrchardCommitDomains, OrchardFixedBases>,
|
||||||
ecc_chip: EccChip<OrchardFixedBases>,
|
ecc_chip: EccChip<OrchardFixedBases>,
|
||||||
|
note_commit_chip: NoteCommitChip,
|
||||||
g_d: &NonIdentityEccPoint,
|
g_d: &NonIdentityEccPoint,
|
||||||
pk_d: &NonIdentityEccPoint,
|
pk_d: &NonIdentityEccPoint,
|
||||||
value: AssignedCell<NoteValue, pallas::Base>,
|
value: AssignedCell<NoteValue, pallas::Base>,
|
||||||
|
@ -1568,7 +1583,7 @@ impl NoteCommitConfig {
|
||||||
psi: AssignedCell<pallas::Base, pallas::Base>,
|
psi: AssignedCell<pallas::Base, pallas::Base>,
|
||||||
rcm: Option<pallas::Scalar>,
|
rcm: Option<pallas::Scalar>,
|
||||||
) -> Result<Point<pallas::Affine, EccChip<OrchardFixedBases>>, Error> {
|
) -> Result<Point<pallas::Affine, EccChip<OrchardFixedBases>>, Error> {
|
||||||
let lookup_config = self.sinsemilla_config.lookup_config();
|
let lookup_config = chip.config().lookup_config();
|
||||||
|
|
||||||
// `a` = bits 0..=249 of `x(g_d)`
|
// `a` = bits 0..=249 of `x(g_d)`
|
||||||
let a = MessagePiece::from_subpieces(
|
let a = MessagePiece::from_subpieces(
|
||||||
|
@ -1616,9 +1631,17 @@ impl NoteCommitConfig {
|
||||||
DecomposeH::decompose(&lookup_config, chip.clone(), &mut layouter, &psi)?;
|
DecomposeH::decompose(&lookup_config, chip.clone(), &mut layouter, &psi)?;
|
||||||
|
|
||||||
// Check decomposition of `y(g_d)`.
|
// Check decomposition of `y(g_d)`.
|
||||||
let b_2 = self.y_canonicity(layouter.namespace(|| "y(g_d) decomposition"), g_d.y(), b_2)?;
|
let b_2 = y_canonicity(
|
||||||
|
&lookup_config,
|
||||||
|
¬e_commit_chip.config.y_canon,
|
||||||
|
layouter.namespace(|| "y(g_d) decomposition"),
|
||||||
|
g_d.y(),
|
||||||
|
b_2,
|
||||||
|
)?;
|
||||||
// Check decomposition of `y(pk_d)`.
|
// Check decomposition of `y(pk_d)`.
|
||||||
let d_1 = self.y_canonicity(
|
let d_1 = y_canonicity(
|
||||||
|
&lookup_config,
|
||||||
|
¬e_commit_chip.config.y_canon,
|
||||||
layouter.namespace(|| "y(pk_d) decomposition"),
|
layouter.namespace(|| "y(pk_d) decomposition"),
|
||||||
pk_d.y(),
|
pk_d.y(),
|
||||||
d_1,
|
d_1,
|
||||||
|
@ -1654,46 +1677,55 @@ impl NoteCommitConfig {
|
||||||
let g_2 = z1_g.clone();
|
let g_2 = z1_g.clone();
|
||||||
let z13_g = zs[6][13].clone();
|
let z13_g = zs[6][13].clone();
|
||||||
|
|
||||||
let (a_prime, z13_a_prime) = self.canon_bitshift_130(
|
let (a_prime, z13_a_prime) = canon_bitshift_130(
|
||||||
|
&lookup_config,
|
||||||
layouter.namespace(|| "x(g_d) canonicity"),
|
layouter.namespace(|| "x(g_d) canonicity"),
|
||||||
a.inner().cell_value(),
|
a.inner().cell_value(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let (b3_c_prime, z14_b3_c_prime) = self.pkd_x_canonicity(
|
let (b3_c_prime, z14_b3_c_prime) = pkd_x_canonicity(
|
||||||
|
&lookup_config,
|
||||||
layouter.namespace(|| "x(pk_d) canonicity"),
|
layouter.namespace(|| "x(pk_d) canonicity"),
|
||||||
b_3.clone(),
|
b_3.clone(),
|
||||||
c.inner().cell_value(),
|
c.inner().cell_value(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let (e1_f_prime, z14_e1_f_prime) = self.rho_canonicity(
|
let (e1_f_prime, z14_e1_f_prime) = rho_canonicity(
|
||||||
|
&lookup_config,
|
||||||
layouter.namespace(|| "rho canonicity"),
|
layouter.namespace(|| "rho canonicity"),
|
||||||
e_1.clone(),
|
e_1.clone(),
|
||||||
f.inner().cell_value(),
|
f.inner().cell_value(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let (g1_g2_prime, z13_g1_g2_prime) =
|
let (g1_g2_prime, z13_g1_g2_prime) = psi_canonicity(
|
||||||
self.psi_canonicity(layouter.namespace(|| "psi canonicity"), g_1.clone(), g_2)?;
|
&lookup_config,
|
||||||
|
layouter.namespace(|| "psi canonicity"),
|
||||||
|
g_1.clone(),
|
||||||
|
g_2,
|
||||||
|
)?;
|
||||||
|
|
||||||
let b_1 = self
|
let cfg = note_commit_chip.config;
|
||||||
|
|
||||||
|
let b_1 = cfg
|
||||||
.b
|
.b
|
||||||
.assign(&mut layouter, b, b_0.clone(), b_1, b_2, b_3.clone())?;
|
.assign(&mut layouter, b, b_0.clone(), b_1, b_2, b_3.clone())?;
|
||||||
|
|
||||||
let d_0 = self
|
let d_0 = cfg
|
||||||
.d
|
.d
|
||||||
.assign(&mut layouter, d, d_0, d_1, d_2.clone(), z1_d.clone())?;
|
.assign(&mut layouter, d, d_0, d_1, d_2.clone(), z1_d.clone())?;
|
||||||
|
|
||||||
self.e.assign(&mut layouter, e, e_0.clone(), e_1.clone())?;
|
cfg.e.assign(&mut layouter, e, e_0.clone(), e_1.clone())?;
|
||||||
|
|
||||||
let g_0 = self
|
let g_0 = cfg
|
||||||
.g
|
.g
|
||||||
.assign(&mut layouter, g, g_0, g_1.clone(), z1_g.clone())?;
|
.assign(&mut layouter, g, g_0, g_1.clone(), z1_g.clone())?;
|
||||||
|
|
||||||
let h_1 = self.h.assign(&mut layouter, h, h_0.clone(), h_1)?;
|
let h_1 = cfg.h.assign(&mut layouter, h, h_0.clone(), h_1)?;
|
||||||
|
|
||||||
self.g_d
|
cfg.g_d
|
||||||
.assign(&mut layouter, g_d, a, b_0, b_1, a_prime, z13_a, z13_a_prime)?;
|
.assign(&mut layouter, g_d, a, b_0, b_1, a_prime, z13_a, z13_a_prime)?;
|
||||||
|
|
||||||
self.pk_d.assign(
|
cfg.pk_d.assign(
|
||||||
&mut layouter,
|
&mut layouter,
|
||||||
pk_d,
|
pk_d,
|
||||||
b_3,
|
b_3,
|
||||||
|
@ -1704,9 +1736,9 @@ impl NoteCommitConfig {
|
||||||
z14_b3_c_prime,
|
z14_b3_c_prime,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
self.value.assign(&mut layouter, value, d_2, z1_d, e_0)?;
|
cfg.value.assign(&mut layouter, value, d_2, z1_d, e_0)?;
|
||||||
|
|
||||||
self.rho.assign(
|
cfg.rho.assign(
|
||||||
&mut layouter,
|
&mut layouter,
|
||||||
rho,
|
rho,
|
||||||
e_1,
|
e_1,
|
||||||
|
@ -1717,7 +1749,7 @@ impl NoteCommitConfig {
|
||||||
z14_e1_f_prime,
|
z14_e1_f_prime,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
self.psi.assign(
|
cfg.psi.assign(
|
||||||
&mut layouter,
|
&mut layouter,
|
||||||
psi,
|
psi,
|
||||||
g_1,
|
g_1,
|
||||||
|
@ -1734,7 +1766,7 @@ impl NoteCommitConfig {
|
||||||
|
|
||||||
// A canonicity check helper used in checking x(g_d), y(g_d), and y(pk_d).
|
// A canonicity check helper used in checking x(g_d), y(g_d), and y(pk_d).
|
||||||
fn canon_bitshift_130(
|
fn canon_bitshift_130(
|
||||||
&self,
|
lookup_config: &LookupRangeCheckConfig<pallas::Base, 10>,
|
||||||
mut layouter: impl Layouter<pallas::Base>,
|
mut layouter: impl Layouter<pallas::Base>,
|
||||||
a: AssignedCell<pallas::Base, pallas::Base>,
|
a: AssignedCell<pallas::Base, pallas::Base>,
|
||||||
) -> Result<CanonicityBounds, Error> {
|
) -> Result<CanonicityBounds, Error> {
|
||||||
|
@ -1752,7 +1784,7 @@ impl NoteCommitConfig {
|
||||||
let t_p = pallas::Base::from_u128(T_P);
|
let t_p = pallas::Base::from_u128(T_P);
|
||||||
a + two_pow_130 - t_p
|
a + two_pow_130 - t_p
|
||||||
});
|
});
|
||||||
let zs = self.sinsemilla_config.lookup_config().witness_check(
|
let zs = lookup_config.witness_check(
|
||||||
layouter.namespace(|| "Decompose low 130 bits of (a + 2^130 - t_P)"),
|
layouter.namespace(|| "Decompose low 130 bits of (a + 2^130 - t_P)"),
|
||||||
a_prime,
|
a_prime,
|
||||||
13,
|
13,
|
||||||
|
@ -1766,7 +1798,7 @@ impl NoteCommitConfig {
|
||||||
|
|
||||||
// Check canonicity of `x(pk_d)` encoding
|
// Check canonicity of `x(pk_d)` encoding
|
||||||
fn pkd_x_canonicity(
|
fn pkd_x_canonicity(
|
||||||
&self,
|
lookup_config: &LookupRangeCheckConfig<pallas::Base, 10>,
|
||||||
mut layouter: impl Layouter<pallas::Base>,
|
mut layouter: impl Layouter<pallas::Base>,
|
||||||
b_3: RangeConstrained<pallas::Base, AssignedCell<pallas::Base, pallas::Base>>,
|
b_3: RangeConstrained<pallas::Base, AssignedCell<pallas::Base, pallas::Base>>,
|
||||||
c: AssignedCell<pallas::Base, pallas::Base>,
|
c: AssignedCell<pallas::Base, pallas::Base>,
|
||||||
|
@ -1791,7 +1823,7 @@ impl NoteCommitConfig {
|
||||||
b_3 + (two_pow_4 * c) + two_pow_140 - t_p
|
b_3 + (two_pow_4 * c) + two_pow_140 - t_p
|
||||||
});
|
});
|
||||||
|
|
||||||
let zs = self.sinsemilla_config.lookup_config().witness_check(
|
let zs = lookup_config.witness_check(
|
||||||
layouter.namespace(|| "Decompose low 140 bits of (b_3 + 2^4 c + 2^140 - t_P)"),
|
layouter.namespace(|| "Decompose low 140 bits of (b_3 + 2^4 c + 2^140 - t_P)"),
|
||||||
b3_c_prime,
|
b3_c_prime,
|
||||||
14,
|
14,
|
||||||
|
@ -1805,7 +1837,7 @@ impl NoteCommitConfig {
|
||||||
|
|
||||||
// Check canonicity of `rho` encoding
|
// Check canonicity of `rho` encoding
|
||||||
fn rho_canonicity(
|
fn rho_canonicity(
|
||||||
&self,
|
lookup_config: &LookupRangeCheckConfig<pallas::Base, 10>,
|
||||||
mut layouter: impl Layouter<pallas::Base>,
|
mut layouter: impl Layouter<pallas::Base>,
|
||||||
e_1: RangeConstrained<pallas::Base, AssignedCell<pallas::Base, pallas::Base>>,
|
e_1: RangeConstrained<pallas::Base, AssignedCell<pallas::Base, pallas::Base>>,
|
||||||
f: AssignedCell<pallas::Base, pallas::Base>,
|
f: AssignedCell<pallas::Base, pallas::Base>,
|
||||||
|
@ -1830,7 +1862,7 @@ impl NoteCommitConfig {
|
||||||
// Decompose the low 140 bits of e1_f_prime = e_1 + 2^4 f + 2^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.
|
// and output the running sum at the end of it.
|
||||||
// If e1_f_prime < 2^140, the running sum will be 0.
|
// If e1_f_prime < 2^140, the running sum will be 0.
|
||||||
let zs = self.sinsemilla_config.lookup_config().witness_check(
|
let zs = lookup_config.witness_check(
|
||||||
layouter.namespace(|| "Decompose low 140 bits of (e_1 + 2^4 f + 2^140 - t_P)"),
|
layouter.namespace(|| "Decompose low 140 bits of (e_1 + 2^4 f + 2^140 - t_P)"),
|
||||||
e1_f_prime,
|
e1_f_prime,
|
||||||
14,
|
14,
|
||||||
|
@ -1844,7 +1876,7 @@ impl NoteCommitConfig {
|
||||||
|
|
||||||
// Check canonicity of `psi` encoding
|
// Check canonicity of `psi` encoding
|
||||||
fn psi_canonicity(
|
fn psi_canonicity(
|
||||||
&self,
|
lookup_config: &LookupRangeCheckConfig<pallas::Base, 10>,
|
||||||
mut layouter: impl Layouter<pallas::Base>,
|
mut layouter: impl Layouter<pallas::Base>,
|
||||||
g_1: RangeConstrained<pallas::Base, AssignedCell<pallas::Base, pallas::Base>>,
|
g_1: RangeConstrained<pallas::Base, AssignedCell<pallas::Base, pallas::Base>>,
|
||||||
g_2: AssignedCell<pallas::Base, pallas::Base>,
|
g_2: AssignedCell<pallas::Base, pallas::Base>,
|
||||||
|
@ -1867,7 +1899,7 @@ impl NoteCommitConfig {
|
||||||
g_1 + (two_pow_9 * g_2) + two_pow_130 - t_p
|
g_1 + (two_pow_9 * g_2) + two_pow_130 - t_p
|
||||||
});
|
});
|
||||||
|
|
||||||
let zs = self.sinsemilla_config.lookup_config().witness_check(
|
let zs = lookup_config.witness_check(
|
||||||
layouter.namespace(|| "Decompose low 130 bits of (g_1 + (2^9)g_2 + 2^130 - t_P)"),
|
layouter.namespace(|| "Decompose low 130 bits of (g_1 + (2^9)g_2 + 2^130 - t_P)"),
|
||||||
g1_g2_prime,
|
g1_g2_prime,
|
||||||
13,
|
13,
|
||||||
|
@ -1882,7 +1914,8 @@ impl NoteCommitConfig {
|
||||||
// Check canonicity of y-coordinate given its LSB as a value.
|
// Check canonicity of y-coordinate given its LSB as a value.
|
||||||
// Also, witness the LSB and return the witnessed cell.
|
// Also, witness the LSB and return the witnessed cell.
|
||||||
fn y_canonicity(
|
fn y_canonicity(
|
||||||
&self,
|
lookup_config: &LookupRangeCheckConfig<pallas::Base, 10>,
|
||||||
|
y_canon: &YCanonicity,
|
||||||
mut layouter: impl Layouter<pallas::Base>,
|
mut layouter: impl Layouter<pallas::Base>,
|
||||||
y: AssignedCell<pallas::Base, pallas::Base>,
|
y: AssignedCell<pallas::Base, pallas::Base>,
|
||||||
lsb: RangeConstrained<pallas::Base, Option<pallas::Base>>,
|
lsb: RangeConstrained<pallas::Base, Option<pallas::Base>>,
|
||||||
|
@ -1894,7 +1927,7 @@ impl NoteCommitConfig {
|
||||||
|
|
||||||
// Range-constrain k_0 to be 9 bits.
|
// Range-constrain k_0 to be 9 bits.
|
||||||
let k_0 = RangeConstrained::witness_short(
|
let k_0 = RangeConstrained::witness_short(
|
||||||
&self.sinsemilla_config.lookup_config(),
|
lookup_config,
|
||||||
layouter.namespace(|| "k_0"),
|
layouter.namespace(|| "k_0"),
|
||||||
y.value(),
|
y.value(),
|
||||||
1..10,
|
1..10,
|
||||||
|
@ -1905,7 +1938,7 @@ impl NoteCommitConfig {
|
||||||
|
|
||||||
// Range-constrain k_2 to be 4 bits.
|
// Range-constrain k_2 to be 4 bits.
|
||||||
let k_2 = RangeConstrained::witness_short(
|
let k_2 = RangeConstrained::witness_short(
|
||||||
&self.sinsemilla_config.lookup_config(),
|
lookup_config,
|
||||||
layouter.namespace(|| "k_2"),
|
layouter.namespace(|| "k_2"),
|
||||||
y.value(),
|
y.value(),
|
||||||
250..254,
|
250..254,
|
||||||
|
@ -1926,7 +1959,7 @@ impl NoteCommitConfig {
|
||||||
let two_pow_10 = pallas::Base::from(1 << 10);
|
let two_pow_10 = pallas::Base::from(1 << 10);
|
||||||
lsb + two * k_0 + two_pow_10 * k_1
|
lsb + two * k_0 + two_pow_10 * k_1
|
||||||
});
|
});
|
||||||
let zs = self.sinsemilla_config.lookup_config().witness_check(
|
let zs = lookup_config.witness_check(
|
||||||
layouter.namespace(|| "Decompose j = LSB + (2)k_0 + (2^10)k_1"),
|
layouter.namespace(|| "Decompose j = LSB + (2)k_0 + (2^10)k_1"),
|
||||||
j,
|
j,
|
||||||
25,
|
25,
|
||||||
|
@ -1937,12 +1970,13 @@ impl NoteCommitConfig {
|
||||||
|
|
||||||
// Decompose j_prime = j + 2^130 - t_P using 13 ten-bit lookups.
|
// Decompose j_prime = j + 2^130 - t_P using 13 ten-bit lookups.
|
||||||
// We can reuse the canon_bitshift_130 logic here.
|
// We can reuse the canon_bitshift_130 logic here.
|
||||||
let (j_prime, z13_j_prime) = self.canon_bitshift_130(
|
let (j_prime, z13_j_prime) = canon_bitshift_130(
|
||||||
|
lookup_config,
|
||||||
layouter.namespace(|| "j_prime = j + 2^130 - t_P"),
|
layouter.namespace(|| "j_prime = j + 2^130 - t_P"),
|
||||||
j.clone(),
|
j.clone(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
self.y_canon.assign(
|
y_canon.assign(
|
||||||
&mut layouter,
|
&mut layouter,
|
||||||
y,
|
y,
|
||||||
lsb,
|
lsb,
|
||||||
|
@ -1964,7 +1998,10 @@ mod tests {
|
||||||
|
|
||||||
use super::NoteCommitConfig;
|
use super::NoteCommitConfig;
|
||||||
use crate::{
|
use crate::{
|
||||||
circuit::gadget::assign_free_advice,
|
circuit::{
|
||||||
|
gadget::assign_free_advice,
|
||||||
|
note_commit::{gadgets, NoteCommitChip},
|
||||||
|
},
|
||||||
constants::{
|
constants::{
|
||||||
fixed_bases::NOTE_COMMITMENT_PERSONALIZATION, OrchardCommitDomains, OrchardFixedBases,
|
fixed_bases::NOTE_COMMITMENT_PERSONALIZATION, OrchardCommitDomains, OrchardFixedBases,
|
||||||
OrchardHashDomains, L_ORCHARD_BASE, L_VALUE, T_Q,
|
OrchardHashDomains, L_ORCHARD_BASE, L_VALUE, T_Q,
|
||||||
|
@ -2068,7 +2105,7 @@ mod tests {
|
||||||
range_check,
|
range_check,
|
||||||
);
|
);
|
||||||
let note_commit_config =
|
let note_commit_config =
|
||||||
NoteCommitConfig::configure(meta, advices, sinsemilla_config);
|
NoteCommitChip::configure(meta, advices, sinsemilla_config);
|
||||||
|
|
||||||
let ecc_config = EccChip::<OrchardFixedBases>::configure(
|
let ecc_config = EccChip::<OrchardFixedBases>::configure(
|
||||||
meta,
|
meta,
|
||||||
|
@ -2101,6 +2138,9 @@ mod tests {
|
||||||
// Construct an ECC chip
|
// Construct an ECC chip
|
||||||
let ecc_chip = EccChip::construct(ecc_config);
|
let ecc_chip = EccChip::construct(ecc_config);
|
||||||
|
|
||||||
|
// Construct a NoteCommit chip
|
||||||
|
let note_commit_chip = NoteCommitChip::construct(note_commit_config.clone());
|
||||||
|
|
||||||
// Witness g_d
|
// Witness g_d
|
||||||
let g_d = {
|
let g_d = {
|
||||||
let g_d = self.gd_x.zip(self.gd_y_lsb).map(|(x, y_lsb)| {
|
let g_d = self.gd_x.zip(self.gd_y_lsb).map(|(x, y_lsb)| {
|
||||||
|
@ -2167,10 +2207,11 @@ mod tests {
|
||||||
|
|
||||||
let rcm = pallas::Scalar::random(OsRng);
|
let rcm = pallas::Scalar::random(OsRng);
|
||||||
|
|
||||||
let cm = note_commit_config.assign_region(
|
let cm = gadgets::note_commit(
|
||||||
layouter.namespace(|| "Hash NoteCommit pieces"),
|
layouter.namespace(|| "Hash NoteCommit pieces"),
|
||||||
sinsemilla_chip,
|
sinsemilla_chip,
|
||||||
ecc_chip.clone(),
|
ecc_chip.clone(),
|
||||||
|
note_commit_chip,
|
||||||
g_d.inner(),
|
g_d.inner(),
|
||||||
pk_d.inner(),
|
pk_d.inner(),
|
||||||
value_var,
|
value_var,
|
||||||
|
|
Loading…
Reference in New Issue