From 6c6b5e66f3e345ceaf4c72646e0f99f93387d5ac Mon Sep 17 00:00:00 2001 From: therealyingtong Date: Fri, 20 Aug 2021 18:44:39 +0800 Subject: [PATCH] sinsemilla::merkle.rs: Implement i2lebsp locally. Also include gen_const_array helper in gadget::utilities. --- src/circuit/gadget/sinsemilla/merkle.rs | 23 ++++++++++++++++------- src/circuit/gadget/utilities.rs | 12 ++++++++++++ 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/circuit/gadget/sinsemilla/merkle.rs b/src/circuit/gadget/sinsemilla/merkle.rs index d52d29dd..e9c1a57c 100644 --- a/src/circuit/gadget/sinsemilla/merkle.rs +++ b/src/circuit/gadget/sinsemilla/merkle.rs @@ -4,14 +4,12 @@ use halo2::{ }; use pasta_curves::arithmetic::CurveAffine; -use crate::{ - circuit::gadget::{ - sinsemilla::{HashDomains, SinsemillaInstructions}, - utilities::{ - cond_swap::CondSwapInstructions, transpose_option_array, UtilitiesInstructions, - }, +use crate::circuit::gadget::{ + sinsemilla::{HashDomains, SinsemillaInstructions}, + utilities::{ + cond_swap::CondSwapInstructions, gen_const_array, transpose_option_array, + UtilitiesInstructions, }, - spec::i2lebsp, }; use std::iter; @@ -27,6 +25,17 @@ pub(crate) const MERKLE_DEPTH_ORCHARD: usize = 32; /// Number of bits in a Pallas base field element. 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(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`. /// The hash function used is a Sinsemilla instance with `K`-bit words. /// The hash function can process `MAX_WORDS` words. diff --git a/src/circuit/gadget/utilities.rs b/src/circuit/gadget/utilities.rs index 79fe8124..11cc0590 100644 --- a/src/circuit/gadget/utilities.rs +++ b/src/circuit/gadget/utilities.rs @@ -165,6 +165,18 @@ pub fn decompose_word( .collect() } +/// Takes in an FnMut closure and returns a constant-length array with elements of +/// type `Output`. +pub fn gen_const_array( + 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)] mod tests { use super::*;