sinsemilla::merkle.rs: Implement i2lebsp locally.

Also include gen_const_array helper in gadget::utilities.
This commit is contained in:
therealyingtong 2021-08-20 18:44:39 +08:00
parent 2c3c3cefdc
commit 6c6b5e66f3
2 changed files with 28 additions and 7 deletions

View File

@ -4,14 +4,12 @@ use halo2::{
}; };
use pasta_curves::arithmetic::CurveAffine; use pasta_curves::arithmetic::CurveAffine;
use crate::{ use crate::circuit::gadget::{
circuit::gadget::{ sinsemilla::{HashDomains, SinsemillaInstructions},
sinsemilla::{HashDomains, SinsemillaInstructions}, utilities::{
utilities::{ cond_swap::CondSwapInstructions, gen_const_array, transpose_option_array,
cond_swap::CondSwapInstructions, transpose_option_array, UtilitiesInstructions, UtilitiesInstructions,
},
}, },
spec::i2lebsp,
}; };
use std::iter; use std::iter;
@ -27,6 +25,17 @@ pub(crate) const MERKLE_DEPTH_ORCHARD: usize = 32;
/// Number of bits in a Pallas base field element. /// Number of bits in a Pallas base field element.
pub(crate) const L_ORCHARD_BASE: usize = 255; pub(crate) const L_ORCHARD_BASE: usize = 255;
/// The sequence of bits representing a u64 in little-endian order.
///
/// # Panics
///
/// Panics if the expected length of the sequence `NUM_BITS` exceeds
/// 64.
fn i2lebsp<const NUM_BITS: usize>(int: u64) -> [bool; NUM_BITS] {
assert!(NUM_BITS <= 64);
gen_const_array(|mask: usize| (int & (1 << mask)) != 0)
}
/// Instructions to check the validity of a Merkle path of a given `PATH_LENGTH`. /// Instructions to check the validity of a Merkle path of a given `PATH_LENGTH`.
/// The hash function used is a Sinsemilla instance with `K`-bit words. /// The hash function used is a Sinsemilla instance with `K`-bit words.
/// The hash function can process `MAX_WORDS` words. /// The hash function can process `MAX_WORDS` words.

View File

@ -165,6 +165,18 @@ pub fn decompose_word<F: PrimeFieldBits>(
.collect() .collect()
} }
/// Takes in an FnMut closure and returns a constant-length array with elements of
/// type `Output`.
pub fn gen_const_array<Output: Copy + Default, const LEN: usize>(
mut closure: impl FnMut(usize) -> Output,
) -> [Output; LEN] {
let mut ret: [Output; LEN] = [Default::default(); LEN];
for (bit, val) in ret.iter_mut().zip((0..LEN).map(|idx| closure(idx))) {
*bit = val;
}
ret
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;