Add spec::i2lebsp and constants::MERKLE_DEPTH_ORCHARD

This commit is contained in:
therealyingtong 2021-06-05 00:51:01 +08:00
parent 12cef17559
commit 1ac3541505
2 changed files with 59 additions and 4 deletions

View File

@ -4,8 +4,7 @@ use halo2::arithmetic::CurveExt;
use pasta_curves::pallas;
use subtle::CtOption;
use crate::constants::util::gen_const_array;
use crate::spec::extract_p_bottom;
use crate::spec::{extract_p_bottom, i2lebsp};
mod addition;
use self::addition::IncompletePoint;
@ -25,7 +24,7 @@ pub(crate) fn lebs2ip_k(bits: &[bool]) -> u32 {
/// up to `2^K` - 1.
pub fn i2lebsp_k(int: usize) -> [bool; K] {
assert!(int < (1 << K));
gen_const_array(|mask: usize| (int & (1 << mask)) != 0)
i2lebsp(int as u64)
}
/// Pads the given iterator (which MUST have length $\leq K * C$) with zero-bits to a

View File

@ -11,7 +11,7 @@ use pasta_curves::pallas;
use subtle::{ConditionallySelectable, CtOption};
use crate::{
constants::L_ORCHARD_BASE,
constants::{util::gen_const_array, L_ORCHARD_BASE},
primitives::{poseidon, sinsemilla},
};
@ -252,11 +252,26 @@ pub fn lebs2ip<const L: usize>(bits: &[bool; L]) -> u64 {
.fold(0u64, |acc, (i, b)| acc + if *b { 1 << i } else { 0 })
}
/// The sequence of bits representing a u64 in little-endian order.
///
/// # Panics
///
/// Panics if the expected length of the sequence `NUM_BITS` exceeds
/// 64.
pub fn i2lebsp<const NUM_BITS: usize>(int: u64) -> [bool; NUM_BITS] {
assert!(NUM_BITS <= 64);
gen_const_array(|mask: usize| (int & (1 << mask)) != 0)
}
#[cfg(test)]
mod tests {
use super::{i2lebsp, lebs2ip};
use group::Group;
use halo2::arithmetic::CurveExt;
use pasta_curves::pallas;
use rand::{rngs::OsRng, RngCore};
use std::convert::TryInto;
#[test]
fn diversify_hash_substitution() {
@ -264,4 +279,45 @@ mod tests {
pallas::Point::hash_to_curve("z.cash:Orchard-gd")(&[]).is_identity()
));
}
#[test]
fn lebs2ip_round_trip() {
let mut rng = OsRng;
{
let int = rng.next_u64();
assert_eq!(lebs2ip::<64>(&i2lebsp(int)), int);
}
assert_eq!(lebs2ip::<64>(&i2lebsp(0)), 0);
assert_eq!(
lebs2ip::<64>(&i2lebsp(0xFFFFFFFFFFFFFFFF)),
0xFFFFFFFFFFFFFFFF
);
}
#[test]
fn i2lebsp_round_trip() {
{
let bitstring = (0..64).map(|_| rand::random()).collect::<Vec<_>>();
assert_eq!(
i2lebsp::<64>(lebs2ip::<64>(&bitstring.clone().try_into().unwrap())).to_vec(),
bitstring
);
}
{
let bitstring = [false; 64];
assert_eq!(i2lebsp(lebs2ip(&bitstring)), bitstring);
}
{
let bitstring = [true; 64];
assert_eq!(i2lebsp(lebs2ip(&bitstring)), bitstring);
}
{
let bitstring = [];
assert_eq!(i2lebsp(lebs2ip(&bitstring)), bitstring);
}
}
}