Batch pedersen hash
This commit is contained in:
parent
81836eae13
commit
cbe4737439
|
@ -1,6 +1,6 @@
|
|||
use ff::PrimeField;
|
||||
use group::Curve;
|
||||
use jubjub::{ExtendedPoint, Fr};
|
||||
use jubjub::{AffinePoint, ExtendedPoint, Fr};
|
||||
use zcash_primitives::constants::PEDERSEN_HASH_CHUNKS_PER_GENERATOR;
|
||||
use crate::sync::{Hasher, Node};
|
||||
use super::GENERATORS_EXP;
|
||||
|
@ -35,6 +35,14 @@ fn accumulate_generator(acc: &Fr, idx_generator: u32) -> ExtendedPoint {
|
|||
}
|
||||
|
||||
pub fn hash_combine(depth: u8, left: &[u8; 32], right: &[u8; 32]) -> [u8; 32] {
|
||||
let p = hash_combine_inner(depth, left, right);
|
||||
p
|
||||
.to_affine()
|
||||
.get_u()
|
||||
.to_repr()
|
||||
}
|
||||
|
||||
pub fn hash_combine_inner(depth: u8, left: &[u8; 32], right: &[u8; 32]) -> ExtendedPoint {
|
||||
let mut hash = ExtendedPoint::identity();
|
||||
let mut acc = Fr::zero();
|
||||
let mut cur = Fr::one();
|
||||
|
@ -95,10 +103,6 @@ pub fn hash_combine(depth: u8, left: &[u8; 32], right: &[u8; 32]) -> [u8; 32] {
|
|||
}
|
||||
hash += accumulate_generator(&acc, idx_generator);
|
||||
|
||||
let hash = hash
|
||||
.to_affine()
|
||||
.get_u()
|
||||
.to_repr();
|
||||
hash
|
||||
}
|
||||
|
||||
|
@ -106,6 +110,8 @@ pub fn hash_combine(depth: u8, left: &[u8; 32], right: &[u8; 32]) -> [u8; 32] {
|
|||
pub struct SaplingHasher {}
|
||||
|
||||
impl Hasher for SaplingHasher {
|
||||
type Extended = ExtendedPoint;
|
||||
|
||||
fn uncommited_node() -> Node {
|
||||
[0u8; 32]
|
||||
}
|
||||
|
@ -113,8 +119,20 @@ impl Hasher for SaplingHasher {
|
|||
fn node_combine(&self, depth: u8, left: &Node, right: &Node) -> Node {
|
||||
hash_combine(depth, left, right)
|
||||
}
|
||||
|
||||
fn node_combine_extended(&self, depth: u8, left: &Node, right: &Node) -> Self::Extended {
|
||||
hash_combine_inner(depth, left, right)
|
||||
}
|
||||
|
||||
fn normalize(&self, extended: &[Self::Extended]) -> Vec<Node> {
|
||||
let mut hash_affine: Vec<AffinePoint> = vec![AffinePoint::identity(); extended.len()];
|
||||
ExtendedPoint::batch_normalize(extended, &mut hash_affine);
|
||||
hash_affine
|
||||
.iter()
|
||||
.map(|p| p.get_u().to_repr())
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
|
|
@ -2,13 +2,19 @@ use rayon::prelude::*;
|
|||
use std::io::{Read, Write};
|
||||
use std::marker::PhantomData;
|
||||
use byteorder::WriteBytesExt;
|
||||
use group::Curve;
|
||||
use zcash_encoding::{Optional, Vector};
|
||||
|
||||
pub type Node = [u8; 32];
|
||||
|
||||
pub trait Hasher: Clone + Sync {
|
||||
type Extended: Curve + Clone + Send;
|
||||
|
||||
fn uncommited_node() -> Node;
|
||||
fn node_combine(&self, depth: u8, left: &Node, right: &Node) -> Node;
|
||||
|
||||
fn node_combine_extended(&self, depth: u8, left: &Node, right: &Node) -> Self::Extended;
|
||||
fn normalize(&self, extended: &[Self::Extended]) -> Vec<Node>;
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
|
@ -388,9 +394,34 @@ fn combine_level<H: Hasher>(
|
|||
) -> usize {
|
||||
assert_eq!(n % 2, 0);
|
||||
|
||||
// TODO: Support batch hash combine
|
||||
let nn = n / 2;
|
||||
let next_level: Vec<_> = (0..nn)
|
||||
let next_level = if nn > 100 {
|
||||
batch_level_combine(commitments, offset, nn, depth, hasher)
|
||||
}
|
||||
else {
|
||||
single_level_combine(commitments, offset, nn, depth, hasher)
|
||||
};
|
||||
|
||||
commitments[0..nn].copy_from_slice(&next_level);
|
||||
nn
|
||||
}
|
||||
|
||||
fn batch_level_combine<H: Hasher>(commitments: &mut [Node], offset: Option<Node>, nn: usize, depth: u8, hasher: &H) -> Vec<Node> {
|
||||
let hash_extended: Vec<_> = (0..nn)
|
||||
.into_par_iter()
|
||||
.map(|i| {
|
||||
hasher.node_combine_extended(
|
||||
depth,
|
||||
CTreeBuilder::<H>::get(commitments, 2 * i, &offset),
|
||||
CTreeBuilder::<H>::get(commitments, 2 * i + 1, &offset),
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
hasher.normalize(&hash_extended)
|
||||
}
|
||||
|
||||
fn single_level_combine<H: Hasher>(commitments: &mut [Node], offset: Option<Node>, nn: usize, depth: u8, hasher: &H) -> Vec<Node> {
|
||||
(0..nn)
|
||||
.into_par_iter()
|
||||
.map(|i| {
|
||||
hasher.node_combine(
|
||||
|
@ -399,10 +430,7 @@ fn combine_level<H: Hasher>(
|
|||
CTreeBuilder::<H>::get(commitments, 2 * i + 1, &offset),
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
|
||||
commitments[0..nn].copy_from_slice(&next_level);
|
||||
nn
|
||||
.collect()
|
||||
}
|
||||
|
||||
struct WitnessBuilder<H: Hasher> {
|
||||
|
|
Loading…
Reference in New Issue