gadget::sinsemilla: Move Orchard-specific inputs into parent folder.

The sinsemilla submodules note_commit and commit_ivk are tailored
for input lengths specific to Orchard. They have been moved out of
the gadget folder and into the parent circuit folder.
This commit is contained in:
therealyingtong 2021-08-18 12:55:23 +08:00
parent c61524ea29
commit 951dd0a108
7 changed files with 69 additions and 63 deletions

View File

@ -46,12 +46,10 @@ use gadget::{
}, },
sinsemilla::{ sinsemilla::{
chip::{SinsemillaChip, SinsemillaConfig, SinsemillaHashDomains}, chip::{SinsemillaChip, SinsemillaConfig, SinsemillaHashDomains},
commit_ivk::CommitIvkConfig,
merkle::{ merkle::{
chip::{MerkleChip, MerkleConfig}, chip::{MerkleChip, MerkleConfig},
MerklePath, MerklePath,
}, },
note_commit::NoteCommitConfig,
}, },
utilities::{copy, CellValue, UtilitiesInstructions, Var}, utilities::{copy, CellValue, UtilitiesInstructions, Var},
}; };
@ -60,7 +58,11 @@ use std::convert::TryInto;
use self::gadget::utilities::lookup_range_check::LookupRangeCheckConfig; use self::gadget::utilities::lookup_range_check::LookupRangeCheckConfig;
mod commit_ivk;
pub(crate) mod gadget; pub(crate) mod gadget;
mod note_commit;
use commit_ivk::CommitIvkConfig;
use note_commit::NoteCommitConfig;
/// Size of the Orchard circuit. /// Size of the Orchard circuit.
const K: u32 = 11; const K: u32 = 11;

View File

@ -8,16 +8,15 @@ use pasta_curves::{arithmetic::FieldExt, pallas};
use crate::{ use crate::{
circuit::gadget::{ circuit::gadget::{
ecc::{chip::EccChip, X}, ecc::{chip::EccChip, X},
sinsemilla::{
chip::{SinsemillaChip, SinsemillaCommitDomains, SinsemillaConfig},
CommitDomain, Message, MessagePiece,
},
utilities::{bitrange_subset, bool_check, copy, CellValue, Var}, utilities::{bitrange_subset, bool_check, copy, CellValue, Var},
}, },
constants::T_P, constants::T_P,
}; };
use super::{
chip::{SinsemillaChip, SinsemillaCommitDomains, SinsemillaConfig},
CommitDomain, Message, MessagePiece,
};
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct CommitIvkConfig { pub struct CommitIvkConfig {
q_commit_ivk: Selector, q_commit_ivk: Selector,
@ -263,13 +262,13 @@ impl CommitIvkConfig {
}); });
// Constrain b_0 to be 4 bits. // Constrain b_0 to be 4 bits.
let b_0 = self.sinsemilla_config.lookup_config.witness_short_check( let b_0 = self.sinsemilla_config.lookup_config().witness_short_check(
layouter.namespace(|| "b_0 is 4 bits"), layouter.namespace(|| "b_0 is 4 bits"),
b_0, b_0,
4, 4,
)?; )?;
// Constrain b_2 to be 5 bits. // Constrain b_2 to be 5 bits.
let b_2 = self.sinsemilla_config.lookup_config.witness_short_check( let b_2 = self.sinsemilla_config.lookup_config().witness_short_check(
layouter.namespace(|| "b_2 is 5 bits"), layouter.namespace(|| "b_2 is 5 bits"),
b_2, b_2,
5, 5,
@ -307,7 +306,7 @@ impl CommitIvkConfig {
.map(|(d_0, d_1)| d_0 + d_1 * pallas::Base::from_u64(1 << 9)); .map(|(d_0, d_1)| d_0 + d_1 * pallas::Base::from_u64(1 << 9));
// Constrain d_0 to be 9 bits. // Constrain d_0 to be 9 bits.
let d_0 = self.sinsemilla_config.lookup_config.witness_short_check( let d_0 = self.sinsemilla_config.lookup_config().witness_short_check(
layouter.namespace(|| "d_0 is 9 bits"), layouter.namespace(|| "d_0 is 9 bits"),
d_0, d_0,
9, 9,
@ -400,7 +399,7 @@ impl CommitIvkConfig {
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 = self.sinsemilla_config.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,
@ -437,7 +436,7 @@ impl CommitIvkConfig {
let t_p = pallas::Base::from_u128(T_P); let t_p = pallas::Base::from_u128(T_P);
b_2 + c * two_pow_5 + two_pow_140 - t_p b_2 + c * two_pow_5 + two_pow_140 - t_p
}); });
let zs = self.sinsemilla_config.lookup_config.witness_check( let zs = self.sinsemilla_config.lookup_config().witness_check(
layouter.namespace(|| "Decompose low 140 bits of (b_2 + c * 2^5 + 2^140 - t_P)"), layouter.namespace(|| "Decompose low 140 bits of (b_2 + c * 2^5 + 2^140 - t_P)"),
b2_c_prime, b2_c_prime,
14, 14,

View File

@ -9,10 +9,8 @@ use pasta_curves::arithmetic::{CurveAffine, FieldExt};
use std::{convert::TryInto, fmt::Debug}; use std::{convert::TryInto, fmt::Debug};
pub mod chip; pub mod chip;
pub mod commit_ivk;
pub mod merkle; pub mod merkle;
mod message; mod message;
pub mod note_commit;
/// The set of circuit instructions required to use the [`Sinsemilla`](https://zcash.github.io/halo2/design/gadgets/sinsemilla.html) gadget. /// The set of circuit instructions required to use the [`Sinsemilla`](https://zcash.github.io/halo2/design/gadgets/sinsemilla.html) gadget.
/// This trait is bounded on two constant parameters: `K`, the number of bits /// This trait is bounded on two constant parameters: `K`, the number of bits
@ -107,7 +105,8 @@ impl<C: CurveAffine, SinsemillaChip, const K: usize, const MAX_WORDS: usize>
where where
SinsemillaChip: SinsemillaInstructions<C, K, MAX_WORDS> + Clone + Debug + Eq, SinsemillaChip: SinsemillaInstructions<C, K, MAX_WORDS> + Clone + Debug + Eq,
{ {
fn from_bitstring( /// Constructs a message from a bitstring.
pub fn from_bitstring(
chip: SinsemillaChip, chip: SinsemillaChip,
mut layouter: impl Layouter<C::Base>, mut layouter: impl Layouter<C::Base>,
bitstring: Vec<Option<bool>>, bitstring: Vec<Option<bool>>,
@ -140,7 +139,7 @@ where
/// Constructs a message from a vector of [`MessagePiece`]s. /// Constructs a message from a vector of [`MessagePiece`]s.
/// ///
/// [`MessagePiece`]: SinsemillaInstructions::MessagePiece /// [`MessagePiece`]: SinsemillaInstructions::MessagePiece
fn from_pieces( pub fn from_pieces(
chip: SinsemillaChip, chip: SinsemillaChip,
pieces: Vec<MessagePiece<C, SinsemillaChip, K, MAX_WORDS>>, pieces: Vec<MessagePiece<C, SinsemillaChip, K, MAX_WORDS>>,
) -> Self { ) -> Self {
@ -169,7 +168,8 @@ impl<C: CurveAffine, SinsemillaChip, const K: usize, const MAX_WORDS: usize>
where where
SinsemillaChip: SinsemillaInstructions<C, K, MAX_WORDS> + Clone + Debug + Eq, SinsemillaChip: SinsemillaInstructions<C, K, MAX_WORDS> + Clone + Debug + Eq,
{ {
fn inner(&self) -> SinsemillaChip::MessagePiece { /// Returns the inner MessagePiece contained in this gadget.
pub fn inner(&self) -> SinsemillaChip::MessagePiece {
self.inner self.inner
} }
} }
@ -179,7 +179,7 @@ impl<C: CurveAffine, SinsemillaChip, const K: usize, const MAX_WORDS: usize>
where where
SinsemillaChip: SinsemillaInstructions<C, K, MAX_WORDS> + Clone + Debug + Eq, SinsemillaChip: SinsemillaInstructions<C, K, MAX_WORDS> + Clone + Debug + Eq,
{ {
fn from_bitstring( pub fn from_bitstring(
chip: SinsemillaChip, chip: SinsemillaChip,
layouter: impl Layouter<C::Base>, layouter: impl Layouter<C::Base>,
bitstring: &[Option<bool>], bitstring: &[Option<bool>],
@ -214,7 +214,7 @@ where
Self::from_field_elem(chip, layouter, piece_value, num_words) Self::from_field_elem(chip, layouter, piece_value, num_words)
} }
fn from_field_elem( pub fn from_field_elem(
chip: SinsemillaChip, chip: SinsemillaChip,
layouter: impl Layouter<C::Base>, layouter: impl Layouter<C::Base>,
field_elem: Option<C::Base>, field_elem: Option<C::Base>,

View File

@ -63,16 +63,21 @@ pub struct SinsemillaConfig {
witness_pieces: Column<Advice>, witness_pieces: Column<Advice>,
/// The lookup table where $(\mathsf{idx}, x_p, y_p)$ are loaded for the $2^K$ /// The lookup table where $(\mathsf{idx}, x_p, y_p)$ are loaded for the $2^K$
/// generators of the Sinsemilla hash. /// generators of the Sinsemilla hash.
pub(super) generator_table: GeneratorTableConfig, generator_table: GeneratorTableConfig,
/// An advice column configured to perform lookup range checks. /// An advice column configured to perform lookup range checks.
pub(super) lookup_config: LookupRangeCheckConfig<pallas::Base, { sinsemilla::K }>, lookup_config: LookupRangeCheckConfig<pallas::Base, { sinsemilla::K }>,
} }
impl SinsemillaConfig { impl SinsemillaConfig {
/// Returns an array of all advice columns in this config, in arbitrary order. /// Returns an array of all advice columns in this config, in arbitrary order.
pub(super) fn advices(&self) -> [Column<Advice>; 5] { pub fn advices(&self) -> [Column<Advice>; 5] {
[self.x_a, self.x_p, self.bits, self.lambda_1, self.lambda_2] [self.x_a, self.x_p, self.bits, self.lambda_1, self.lambda_2]
} }
/// Returns the lookup table config of this Sinsemilla config.
pub fn lookup_config(&self) -> &LookupRangeCheckConfig<pallas::Base, { sinsemilla::K }> {
&self.lookup_config
}
} }
#[derive(Eq, PartialEq, Clone, Debug)] #[derive(Eq, PartialEq, Clone, Debug)]

View File

@ -4,11 +4,12 @@ use halo2::{
}; };
use pasta_curves::arithmetic::CurveAffine; use pasta_curves::arithmetic::CurveAffine;
use super::{HashDomains, SinsemillaInstructions};
use crate::{ use crate::{
circuit::gadget::utilities::{ circuit::gadget::{
cond_swap::CondSwapInstructions, transpose_option_array, UtilitiesInstructions, sinsemilla::{HashDomains, SinsemillaInstructions},
utilities::{
cond_swap::CondSwapInstructions, transpose_option_array, UtilitiesInstructions,
},
}, },
spec::i2lebsp, spec::i2lebsp,
}; };

View File

@ -5,17 +5,19 @@ use halo2::{
}; };
use pasta_curves::{arithmetic::FieldExt, pallas}; use pasta_curves::{arithmetic::FieldExt, pallas};
use super::super::{
chip::{SinsemillaChip, SinsemillaConfig},
SinsemillaInstructions,
};
use super::MerkleInstructions; use super::MerkleInstructions;
use crate::{ use crate::{
circuit::gadget::utilities::{ circuit::gadget::{
bitrange_subset, sinsemilla::{
cond_swap::{CondSwapChip, CondSwapConfig, CondSwapInstructions}, chip::{SinsemillaChip, SinsemillaConfig},
copy, CellValue, UtilitiesInstructions, Var, SinsemillaInstructions,
},
utilities::{
bitrange_subset,
cond_swap::{CondSwapChip, CondSwapConfig, CondSwapInstructions},
copy, CellValue, UtilitiesInstructions, Var,
},
}, },
constants::{L_ORCHARD_BASE, MERKLE_DEPTH_ORCHARD}, constants::{L_ORCHARD_BASE, MERKLE_DEPTH_ORCHARD},
primitives::sinsemilla, primitives::sinsemilla,
@ -209,11 +211,10 @@ impl MerkleInstructions<pallas::Affine, MERKLE_DEPTH_ORCHARD, { sinsemilla::K },
.value() .value()
.map(|value| bitrange_subset(value, 250..L_ORCHARD_BASE)); .map(|value| bitrange_subset(value, 250..L_ORCHARD_BASE));
config.sinsemilla_config.lookup_config.witness_short_check( config
layouter.namespace(|| "Constrain b_1 to 5 bits"), .sinsemilla_config
b_1, .lookup_config()
5, .witness_short_check(layouter.namespace(|| "Constrain b_1 to 5 bits"), b_1, 5)?
)?
}; };
// b_2 = (bits 0..=4 of `right`) // b_2 = (bits 0..=4 of `right`)
@ -221,11 +222,10 @@ impl MerkleInstructions<pallas::Affine, MERKLE_DEPTH_ORCHARD, { sinsemilla::K },
let b_2 = { let b_2 = {
let b_2 = right.value().map(|value| bitrange_subset(value, 0..5)); let b_2 = right.value().map(|value| bitrange_subset(value, 0..5));
config.sinsemilla_config.lookup_config.witness_short_check( config
layouter.namespace(|| "Constrain b_2 to 5 bits"), .sinsemilla_config
b_2, .lookup_config()
5, .witness_short_check(layouter.namespace(|| "Constrain b_2 to 5 bits"), b_2, 5)?
)?
}; };
let b = { let b = {

View File

@ -11,16 +11,15 @@ use crate::{
chip::{EccChip, NonIdentityEccPoint}, chip::{EccChip, NonIdentityEccPoint},
Point, Point,
}, },
sinsemilla::{
chip::{SinsemillaChip, SinsemillaCommitDomains, SinsemillaConfig},
CommitDomain, Message, MessagePiece,
},
utilities::{bitrange_subset, bool_check, copy, CellValue, Var}, utilities::{bitrange_subset, bool_check, copy, CellValue, Var},
}, },
constants::T_P, constants::T_P,
}; };
use super::{
chip::{SinsemillaChip, SinsemillaCommitDomains, SinsemillaConfig},
CommitDomain, Message, MessagePiece,
};
/* /*
<https://zips.z.cash/protocol/nu5.pdf#concretesinsemillacommit> <https://zips.z.cash/protocol/nu5.pdf#concretesinsemillacommit>
We need to hash g_d || pk_d || i2lebsp_{64}(v) || rho || psi, We need to hash g_d || pk_d || i2lebsp_{64}(v) || rho || psi,
@ -552,14 +551,14 @@ impl NoteCommitConfig {
let b_3 = pkd_x.map(|pkd_x| bitrange_subset(pkd_x, 0..4)); let b_3 = pkd_x.map(|pkd_x| bitrange_subset(pkd_x, 0..4));
// Constrain b_0 to be 4 bits // Constrain b_0 to be 4 bits
let b_0 = self.sinsemilla_config.lookup_config.witness_short_check( let b_0 = self.sinsemilla_config.lookup_config().witness_short_check(
layouter.namespace(|| "b_0 is 4 bits"), layouter.namespace(|| "b_0 is 4 bits"),
b_0, b_0,
4, 4,
)?; )?;
// Constrain b_3 to be 4 bits // Constrain b_3 to be 4 bits
let b_3 = self.sinsemilla_config.lookup_config.witness_short_check( let b_3 = self.sinsemilla_config.lookup_config().witness_short_check(
layouter.namespace(|| "b_3 is 4 bits"), layouter.namespace(|| "b_3 is 4 bits"),
b_3, b_3,
4, 4,
@ -597,7 +596,7 @@ impl NoteCommitConfig {
let d_3 = value_val.map(|value| bitrange_subset(value, 8..58)); let d_3 = value_val.map(|value| bitrange_subset(value, 8..58));
// Constrain d_2 to be 8 bits // Constrain d_2 to be 8 bits
let d_2 = self.sinsemilla_config.lookup_config.witness_short_check( let d_2 = self.sinsemilla_config.lookup_config().witness_short_check(
layouter.namespace(|| "d_2 is 8 bits"), layouter.namespace(|| "d_2 is 8 bits"),
d_2, d_2,
8, 8,
@ -628,14 +627,14 @@ impl NoteCommitConfig {
let e_1 = rho_val.map(|rho| bitrange_subset(rho, 0..4)); let e_1 = rho_val.map(|rho| bitrange_subset(rho, 0..4));
// Constrain e_0 to be 6 bits. // Constrain e_0 to be 6 bits.
let e_0 = self.sinsemilla_config.lookup_config.witness_short_check( let e_0 = self.sinsemilla_config.lookup_config().witness_short_check(
layouter.namespace(|| "e_0 is 6 bits"), layouter.namespace(|| "e_0 is 6 bits"),
e_0, e_0,
6, 6,
)?; )?;
// Constrain e_1 to be 4 bits. // Constrain e_1 to be 4 bits.
let e_1 = self.sinsemilla_config.lookup_config.witness_short_check( let e_1 = self.sinsemilla_config.lookup_config().witness_short_check(
layouter.namespace(|| "e_1 is 4 bits"), layouter.namespace(|| "e_1 is 4 bits"),
e_1, e_1,
4, 4,
@ -664,7 +663,7 @@ impl NoteCommitConfig {
let g_2 = psi_val.map(|psi| bitrange_subset(psi, 9..249)); let g_2 = psi_val.map(|psi| bitrange_subset(psi, 9..249));
// Constrain g_1 to be 9 bits. // Constrain g_1 to be 9 bits.
let g_1 = self.sinsemilla_config.lookup_config.witness_short_check( let g_1 = self.sinsemilla_config.lookup_config().witness_short_check(
layouter.namespace(|| "g_1 is 9 bits"), layouter.namespace(|| "g_1 is 9 bits"),
g_1, g_1,
9, 9,
@ -690,7 +689,7 @@ impl NoteCommitConfig {
let h_1 = psi_val.map(|psi| bitrange_subset(psi, 254..255)); let h_1 = psi_val.map(|psi| bitrange_subset(psi, 254..255));
// Constrain h_0 to be 5 bits. // Constrain h_0 to be 5 bits.
let h_0 = self.sinsemilla_config.lookup_config.witness_short_check( let h_0 = self.sinsemilla_config.lookup_config().witness_short_check(
layouter.namespace(|| "h_0 is 5 bits"), layouter.namespace(|| "h_0 is 5 bits"),
h_0, h_0,
5, 5,
@ -835,7 +834,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 = self.sinsemilla_config.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,
@ -874,7 +873,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 = self.sinsemilla_config.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,
@ -914,7 +913,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 = self.sinsemilla_config.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,
@ -951,7 +950,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 = self.sinsemilla_config.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,
@ -984,14 +983,14 @@ impl NoteCommitConfig {
}; };
// Range-constrain k_0 to be 9 bits. // Range-constrain k_0 to be 9 bits.
let k_0 = self.sinsemilla_config.lookup_config.witness_short_check( let k_0 = self.sinsemilla_config.lookup_config().witness_short_check(
layouter.namespace(|| "Constrain k_0 to be 9 bits"), layouter.namespace(|| "Constrain k_0 to be 9 bits"),
k_0, k_0,
9, 9,
)?; )?;
// Range-constrain k_2 to be 4 bits. // Range-constrain k_2 to be 4 bits.
let k_2 = self.sinsemilla_config.lookup_config.witness_short_check( let k_2 = self.sinsemilla_config.lookup_config().witness_short_check(
layouter.namespace(|| "Constrain k_2 to be 4 bits"), layouter.namespace(|| "Constrain k_2 to be 4 bits"),
k_2, k_2,
4, 4,
@ -1004,7 +1003,7 @@ impl NoteCommitConfig {
let two_pow_10 = pallas::Base::from_u64(1 << 10); let two_pow_10 = pallas::Base::from_u64(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 = self.sinsemilla_config.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,