mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-07 16:23:12 +00:00
Move hashes to their specific files
This commit is contained in:
parent
314a5845b7
commit
a0a42e4bef
@ -1,7 +1,15 @@
|
|||||||
|
use plonky2_field::extension_field::Extendable;
|
||||||
use plonky2_field::field_types::Field;
|
use plonky2_field::field_types::Field;
|
||||||
use plonky2_field::goldilocks_field::GoldilocksField;
|
use plonky2_field::goldilocks_field::GoldilocksField;
|
||||||
use unroll::unroll_for_loops;
|
use unroll::unroll_for_loops;
|
||||||
|
|
||||||
|
use crate::gates::gmimc::GMiMCGate;
|
||||||
|
use crate::hash::hash_types::{HashOut, RichField};
|
||||||
|
use crate::hash::hashing::{compress, hash_n_to_hash, GMiMCPermutation, SPONGE_WIDTH};
|
||||||
|
use crate::iop::target::{BoolTarget, Target};
|
||||||
|
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||||
|
use crate::plonk::config::{AlgebraicHasher, Hasher};
|
||||||
|
|
||||||
pub(crate) const NUM_ROUNDS: usize = 101;
|
pub(crate) const NUM_ROUNDS: usize = 101;
|
||||||
|
|
||||||
pub trait GMiMC<const WIDTH: usize>: Field
|
pub trait GMiMC<const WIDTH: usize>: Field
|
||||||
@ -85,6 +93,54 @@ impl GMiMC<12> for GoldilocksField {
|
|||||||
const ROUND_CONSTANTS: [u64; NUM_ROUNDS] = GOLDILOCKS_ROUND_CONSTANTS;
|
const ROUND_CONSTANTS: [u64; NUM_ROUNDS] = GOLDILOCKS_ROUND_CONSTANTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||||
|
pub struct GMiMCHash;
|
||||||
|
impl<F: RichField> Hasher<F> for GMiMCHash {
|
||||||
|
const HASH_SIZE: usize = 4 * 8;
|
||||||
|
type Hash = HashOut<F>;
|
||||||
|
type Permutation = GMiMCPermutation;
|
||||||
|
|
||||||
|
fn hash(input: Vec<F>, pad: bool) -> Self::Hash {
|
||||||
|
hash_n_to_hash::<F, Self::Permutation>(input, pad)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn two_to_one(left: Self::Hash, right: Self::Hash) -> Self::Hash {
|
||||||
|
compress::<F, Self::Permutation>(left, right)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<F: RichField> AlgebraicHasher<F> for GMiMCHash {
|
||||||
|
fn permute_swapped<const D: usize>(
|
||||||
|
inputs: [Target; SPONGE_WIDTH],
|
||||||
|
swap: BoolTarget,
|
||||||
|
builder: &mut CircuitBuilder<F, D>,
|
||||||
|
) -> [Target; SPONGE_WIDTH]
|
||||||
|
where
|
||||||
|
F: RichField + Extendable<D>,
|
||||||
|
{
|
||||||
|
let gate_type = GMiMCGate::<F, D, SPONGE_WIDTH>::new();
|
||||||
|
let gate = builder.add_gate(gate_type, vec![]);
|
||||||
|
|
||||||
|
let swap_wire = GMiMCGate::<F, D, SPONGE_WIDTH>::WIRE_SWAP;
|
||||||
|
let swap_wire = Target::wire(gate, swap_wire);
|
||||||
|
builder.connect(swap.target, swap_wire);
|
||||||
|
|
||||||
|
// Route input wires.
|
||||||
|
for i in 0..SPONGE_WIDTH {
|
||||||
|
let in_wire = GMiMCGate::<F, D, SPONGE_WIDTH>::wire_input(i);
|
||||||
|
let in_wire = Target::wire(gate, in_wire);
|
||||||
|
builder.connect(inputs[i], in_wire);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collect output wires.
|
||||||
|
(0..SPONGE_WIDTH)
|
||||||
|
.map(|i| Target::wire(gate, GMiMCGate::<F, D, SPONGE_WIDTH>::wire_output(i)))
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.try_into()
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use plonky2_field::goldilocks_field::GoldilocksField;
|
use plonky2_field::goldilocks_field::GoldilocksField;
|
||||||
|
|||||||
65
plonky2/src/hash/keccak.rs
Normal file
65
plonky2/src/hash/keccak.rs
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
use keccak_hash::keccak;
|
||||||
|
|
||||||
|
use crate::hash::hash_types::{BytesHash, RichField};
|
||||||
|
use crate::hash::hashing::{PlonkyPermutation, SPONGE_WIDTH};
|
||||||
|
use crate::plonk::config::Hasher;
|
||||||
|
use crate::util::serialization::Buffer;
|
||||||
|
|
||||||
|
/// Keccak-256 permutation used in the challenger.
|
||||||
|
pub struct KeccakPermutation;
|
||||||
|
impl<F: RichField> PlonkyPermutation<F> for KeccakPermutation {
|
||||||
|
fn permute(input: [F; SPONGE_WIDTH]) -> [F; SPONGE_WIDTH] {
|
||||||
|
// Fill a byte array with the little-endian representation of the field array.
|
||||||
|
let mut buffer = [0u8; SPONGE_WIDTH * std::mem::size_of::<u64>()];
|
||||||
|
for i in 0..SPONGE_WIDTH {
|
||||||
|
buffer[i * std::mem::size_of::<F>()..(i + 1) * std::mem::size_of::<F>()]
|
||||||
|
.copy_from_slice(&input[i].to_canonical_u64().to_le_bytes());
|
||||||
|
}
|
||||||
|
// Concatenate `H(input), H(H(input)), H(H(H(input)))`.
|
||||||
|
let permutated_input_bytes = {
|
||||||
|
let mut ans = [0u8; 96];
|
||||||
|
ans[0..32].copy_from_slice(&keccak(buffer).0);
|
||||||
|
ans[32..64].copy_from_slice(&keccak(keccak(buffer).0).0);
|
||||||
|
ans[64..96].copy_from_slice(&keccak(keccak(keccak(buffer).0).0).0);
|
||||||
|
ans
|
||||||
|
};
|
||||||
|
// Write the hashed byte array to a field array.
|
||||||
|
let mut permutated_input = [F::ZERO; SPONGE_WIDTH];
|
||||||
|
for i in 0..SPONGE_WIDTH {
|
||||||
|
permutated_input[i] = F::from_noncanonical_u64(u64::from_le_bytes(
|
||||||
|
permutated_input_bytes
|
||||||
|
[i * std::mem::size_of::<F>()..(i + 1) * std::mem::size_of::<F>()]
|
||||||
|
.try_into()
|
||||||
|
.unwrap(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
permutated_input
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Keccak-256 hash function.
|
||||||
|
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||||
|
pub struct KeccakHash<const N: usize>;
|
||||||
|
impl<F: RichField, const N: usize> Hasher<F> for KeccakHash<N> {
|
||||||
|
const HASH_SIZE: usize = N;
|
||||||
|
type Hash = BytesHash<N>;
|
||||||
|
type Permutation = KeccakPermutation;
|
||||||
|
|
||||||
|
fn hash(input: Vec<F>, _pad: bool) -> Self::Hash {
|
||||||
|
let mut buffer = Buffer::new(Vec::new());
|
||||||
|
buffer.write_field_vec(&input).unwrap();
|
||||||
|
let mut arr = [0; N];
|
||||||
|
let hash_bytes = keccak(buffer.bytes()).0;
|
||||||
|
arr.copy_from_slice(&hash_bytes[..N]);
|
||||||
|
BytesHash(arr)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn two_to_one(left: Self::Hash, right: Self::Hash) -> Self::Hash {
|
||||||
|
let mut v = vec![0; N * 2];
|
||||||
|
v[0..N].copy_from_slice(&left.0);
|
||||||
|
v[N..].copy_from_slice(&right.0);
|
||||||
|
let mut arr = [0; N];
|
||||||
|
arr.copy_from_slice(&keccak(v).0[..N]);
|
||||||
|
BytesHash(arr)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,6 +2,7 @@ mod arch;
|
|||||||
pub mod gmimc;
|
pub mod gmimc;
|
||||||
pub mod hash_types;
|
pub mod hash_types;
|
||||||
pub mod hashing;
|
pub mod hashing;
|
||||||
|
pub mod keccak;
|
||||||
pub mod merkle_proofs;
|
pub mod merkle_proofs;
|
||||||
pub mod merkle_tree;
|
pub mod merkle_tree;
|
||||||
pub mod path_compression;
|
pub mod path_compression;
|
||||||
|
|||||||
@ -6,11 +6,14 @@ use plonky2_field::field_types::{Field, PrimeField};
|
|||||||
use unroll::unroll_for_loops;
|
use unroll::unroll_for_loops;
|
||||||
|
|
||||||
use crate::gates::gate::Gate;
|
use crate::gates::gate::Gate;
|
||||||
|
use crate::gates::poseidon::PoseidonGate;
|
||||||
use crate::gates::poseidon_mds::PoseidonMdsGate;
|
use crate::gates::poseidon_mds::PoseidonMdsGate;
|
||||||
use crate::hash::hash_types::RichField;
|
use crate::hash::hash_types::{HashOut, RichField};
|
||||||
use crate::hash::hashing::SPONGE_WIDTH;
|
use crate::hash::hashing::{compress, hash_n_to_hash, PoseidonPermutation, SPONGE_WIDTH};
|
||||||
use crate::iop::ext_target::ExtensionTarget;
|
use crate::iop::ext_target::ExtensionTarget;
|
||||||
|
use crate::iop::target::{BoolTarget, Target};
|
||||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||||
|
use crate::plonk::config::{AlgebraicHasher, Hasher};
|
||||||
|
|
||||||
// The number of full rounds and partial rounds is given by the
|
// The number of full rounds and partial rounds is given by the
|
||||||
// calc_round_numbers.py script. They happen to be the same for both
|
// calc_round_numbers.py script. They happen to be the same for both
|
||||||
@ -615,6 +618,55 @@ pub trait Poseidon: PrimeField {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Poseidon hash function.
|
||||||
|
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||||
|
pub struct PoseidonHash;
|
||||||
|
impl<F: RichField> Hasher<F> for PoseidonHash {
|
||||||
|
const HASH_SIZE: usize = 4 * 8;
|
||||||
|
type Hash = HashOut<F>;
|
||||||
|
type Permutation = PoseidonPermutation;
|
||||||
|
|
||||||
|
fn hash(input: Vec<F>, pad: bool) -> Self::Hash {
|
||||||
|
hash_n_to_hash::<F, Self::Permutation>(input, pad)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn two_to_one(left: Self::Hash, right: Self::Hash) -> Self::Hash {
|
||||||
|
compress::<F, Self::Permutation>(left, right)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<F: RichField> AlgebraicHasher<F> for PoseidonHash {
|
||||||
|
fn permute_swapped<const D: usize>(
|
||||||
|
inputs: [Target; SPONGE_WIDTH],
|
||||||
|
swap: BoolTarget,
|
||||||
|
builder: &mut CircuitBuilder<F, D>,
|
||||||
|
) -> [Target; SPONGE_WIDTH]
|
||||||
|
where
|
||||||
|
F: RichField + Extendable<D>,
|
||||||
|
{
|
||||||
|
let gate_type = PoseidonGate::<F, D>::new();
|
||||||
|
let gate = builder.add_gate(gate_type, vec![]);
|
||||||
|
|
||||||
|
let swap_wire = PoseidonGate::<F, D>::WIRE_SWAP;
|
||||||
|
let swap_wire = Target::wire(gate, swap_wire);
|
||||||
|
builder.connect(swap.target, swap_wire);
|
||||||
|
|
||||||
|
// Route input wires.
|
||||||
|
for i in 0..SPONGE_WIDTH {
|
||||||
|
let in_wire = PoseidonGate::<F, D>::wire_input(i);
|
||||||
|
let in_wire = Target::wire(gate, in_wire);
|
||||||
|
builder.connect(inputs[i], in_wire);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collect output wires.
|
||||||
|
(0..SPONGE_WIDTH)
|
||||||
|
.map(|i| Target::wire(gate, PoseidonGate::<F, D>::wire_output(i)))
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.try_into()
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub(crate) mod test_helpers {
|
pub(crate) mod test_helpers {
|
||||||
use plonky2_field::field_types::Field;
|
use plonky2_field::field_types::Field;
|
||||||
|
|||||||
@ -1,23 +1,18 @@
|
|||||||
use std::convert::TryInto;
|
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
use keccak_hash::keccak;
|
|
||||||
use plonky2_field::extension_field::quadratic::QuadraticExtension;
|
use plonky2_field::extension_field::quadratic::QuadraticExtension;
|
||||||
use plonky2_field::extension_field::{Extendable, FieldExtension};
|
use plonky2_field::extension_field::{Extendable, FieldExtension};
|
||||||
use plonky2_field::goldilocks_field::GoldilocksField;
|
use plonky2_field::goldilocks_field::GoldilocksField;
|
||||||
use serde::{de::DeserializeOwned, Serialize};
|
use serde::{de::DeserializeOwned, Serialize};
|
||||||
|
|
||||||
use crate::gates::gmimc::GMiMCGate;
|
use crate::hash::gmimc::GMiMCHash;
|
||||||
use crate::gates::poseidon::PoseidonGate;
|
use crate::hash::hash_types::HashOut;
|
||||||
use crate::hash::hash_types::RichField;
|
use crate::hash::hash_types::RichField;
|
||||||
use crate::hash::hash_types::{BytesHash, HashOut};
|
use crate::hash::hashing::{PlonkyPermutation, SPONGE_WIDTH};
|
||||||
use crate::hash::hashing::{
|
use crate::hash::keccak::KeccakHash;
|
||||||
compress, hash_n_to_hash, GMiMCPermutation, PlonkyPermutation, PoseidonPermutation,
|
use crate::hash::poseidon::PoseidonHash;
|
||||||
SPONGE_WIDTH,
|
|
||||||
};
|
|
||||||
use crate::iop::target::{BoolTarget, Target};
|
use crate::iop::target::{BoolTarget, Target};
|
||||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||||
use crate::util::serialization::Buffer;
|
|
||||||
|
|
||||||
pub trait GenericHashOut<F: RichField>:
|
pub trait GenericHashOut<F: RichField>:
|
||||||
Copy + Clone + Debug + Eq + PartialEq + Send + Sync + Serialize + DeserializeOwned
|
Copy + Clone + Debug + Eq + PartialEq + Send + Sync + Serialize + DeserializeOwned
|
||||||
@ -57,162 +52,6 @@ pub trait AlgebraicHasher<F: RichField>: Hasher<F, Hash = HashOut<F>> {
|
|||||||
F: RichField + Extendable<D>;
|
F: RichField + Extendable<D>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Poseidon hash function.
|
|
||||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
|
||||||
pub struct PoseidonHash;
|
|
||||||
impl<F: RichField> Hasher<F> for PoseidonHash {
|
|
||||||
const HASH_SIZE: usize = 4 * 8;
|
|
||||||
type Hash = HashOut<F>;
|
|
||||||
type Permutation = PoseidonPermutation;
|
|
||||||
|
|
||||||
fn hash(input: Vec<F>, pad: bool) -> Self::Hash {
|
|
||||||
hash_n_to_hash::<F, Self::Permutation>(input, pad)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn two_to_one(left: Self::Hash, right: Self::Hash) -> Self::Hash {
|
|
||||||
compress::<F, Self::Permutation>(left, right)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<F: RichField> AlgebraicHasher<F> for PoseidonHash {
|
|
||||||
fn permute_swapped<const D: usize>(
|
|
||||||
inputs: [Target; SPONGE_WIDTH],
|
|
||||||
swap: BoolTarget,
|
|
||||||
builder: &mut CircuitBuilder<F, D>,
|
|
||||||
) -> [Target; SPONGE_WIDTH]
|
|
||||||
where
|
|
||||||
F: RichField + Extendable<D>,
|
|
||||||
{
|
|
||||||
let gate_type = PoseidonGate::<F, D>::new();
|
|
||||||
let gate = builder.add_gate(gate_type, vec![]);
|
|
||||||
|
|
||||||
let swap_wire = PoseidonGate::<F, D>::WIRE_SWAP;
|
|
||||||
let swap_wire = Target::wire(gate, swap_wire);
|
|
||||||
builder.connect(swap.target, swap_wire);
|
|
||||||
|
|
||||||
// Route input wires.
|
|
||||||
for i in 0..SPONGE_WIDTH {
|
|
||||||
let in_wire = PoseidonGate::<F, D>::wire_input(i);
|
|
||||||
let in_wire = Target::wire(gate, in_wire);
|
|
||||||
builder.connect(inputs[i], in_wire);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Collect output wires.
|
|
||||||
(0..SPONGE_WIDTH)
|
|
||||||
.map(|i| Target::wire(gate, PoseidonGate::<F, D>::wire_output(i)))
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.try_into()
|
|
||||||
.unwrap()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
|
||||||
pub struct GMiMCHash;
|
|
||||||
impl<F: RichField> Hasher<F> for GMiMCHash {
|
|
||||||
const HASH_SIZE: usize = 4 * 8;
|
|
||||||
type Hash = HashOut<F>;
|
|
||||||
type Permutation = GMiMCPermutation;
|
|
||||||
|
|
||||||
fn hash(input: Vec<F>, pad: bool) -> Self::Hash {
|
|
||||||
hash_n_to_hash::<F, Self::Permutation>(input, pad)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn two_to_one(left: Self::Hash, right: Self::Hash) -> Self::Hash {
|
|
||||||
compress::<F, Self::Permutation>(left, right)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<F: RichField> AlgebraicHasher<F> for GMiMCHash {
|
|
||||||
fn permute_swapped<const D: usize>(
|
|
||||||
inputs: [Target; SPONGE_WIDTH],
|
|
||||||
swap: BoolTarget,
|
|
||||||
builder: &mut CircuitBuilder<F, D>,
|
|
||||||
) -> [Target; SPONGE_WIDTH]
|
|
||||||
where
|
|
||||||
F: RichField + Extendable<D>,
|
|
||||||
{
|
|
||||||
let gate_type = GMiMCGate::<F, D, SPONGE_WIDTH>::new();
|
|
||||||
let gate = builder.add_gate(gate_type, vec![]);
|
|
||||||
|
|
||||||
let swap_wire = GMiMCGate::<F, D, SPONGE_WIDTH>::WIRE_SWAP;
|
|
||||||
let swap_wire = Target::wire(gate, swap_wire);
|
|
||||||
builder.connect(swap.target, swap_wire);
|
|
||||||
|
|
||||||
// Route input wires.
|
|
||||||
for i in 0..SPONGE_WIDTH {
|
|
||||||
let in_wire = GMiMCGate::<F, D, SPONGE_WIDTH>::wire_input(i);
|
|
||||||
let in_wire = Target::wire(gate, in_wire);
|
|
||||||
builder.connect(inputs[i], in_wire);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Collect output wires.
|
|
||||||
(0..SPONGE_WIDTH)
|
|
||||||
.map(|i| Target::wire(gate, GMiMCGate::<F, D, SPONGE_WIDTH>::wire_output(i)))
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.try_into()
|
|
||||||
.unwrap()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Keccak-256 permutation used in the challenger.
|
|
||||||
pub struct KeccakPermutation;
|
|
||||||
impl<F: RichField> PlonkyPermutation<F> for KeccakPermutation {
|
|
||||||
fn permute(input: [F; SPONGE_WIDTH]) -> [F; SPONGE_WIDTH] {
|
|
||||||
// Fill a byte array with the little-endian representation of the field array.
|
|
||||||
let mut buffer = [0u8; SPONGE_WIDTH * std::mem::size_of::<u64>()];
|
|
||||||
for i in 0..SPONGE_WIDTH {
|
|
||||||
buffer[i * std::mem::size_of::<F>()..(i + 1) * std::mem::size_of::<F>()]
|
|
||||||
.copy_from_slice(&input[i].to_canonical_u64().to_le_bytes());
|
|
||||||
}
|
|
||||||
// Concatenate `H(input), H(H(input)), H(H(H(input)))`.
|
|
||||||
let permutated_input_bytes = {
|
|
||||||
let mut ans = [0u8; 96];
|
|
||||||
ans[0..32].copy_from_slice(&keccak(buffer).0);
|
|
||||||
ans[32..64].copy_from_slice(&keccak(keccak(buffer).0).0);
|
|
||||||
ans[64..96].copy_from_slice(&keccak(keccak(keccak(buffer).0).0).0);
|
|
||||||
ans
|
|
||||||
};
|
|
||||||
// Write the hashed byte array to a field array.
|
|
||||||
let mut permutated_input = [F::ZERO; SPONGE_WIDTH];
|
|
||||||
for i in 0..SPONGE_WIDTH {
|
|
||||||
permutated_input[i] = F::from_noncanonical_u64(u64::from_le_bytes(
|
|
||||||
permutated_input_bytes
|
|
||||||
[i * std::mem::size_of::<F>()..(i + 1) * std::mem::size_of::<F>()]
|
|
||||||
.try_into()
|
|
||||||
.unwrap(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
permutated_input
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Keccak-256 hash function.
|
|
||||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
|
||||||
pub struct KeccakHash<const N: usize>;
|
|
||||||
impl<F: RichField, const N: usize> Hasher<F> for KeccakHash<N> {
|
|
||||||
const HASH_SIZE: usize = N;
|
|
||||||
type Hash = BytesHash<N>;
|
|
||||||
type Permutation = KeccakPermutation;
|
|
||||||
|
|
||||||
fn hash(input: Vec<F>, _pad: bool) -> Self::Hash {
|
|
||||||
let mut buffer = Buffer::new(Vec::new());
|
|
||||||
buffer.write_field_vec(&input).unwrap();
|
|
||||||
let mut arr = [0; N];
|
|
||||||
let hash_bytes = keccak(buffer.bytes()).0;
|
|
||||||
arr.copy_from_slice(&hash_bytes[..N]);
|
|
||||||
BytesHash(arr)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn two_to_one(left: Self::Hash, right: Self::Hash) -> Self::Hash {
|
|
||||||
let mut v = vec![0; N * 2];
|
|
||||||
v[0..N].copy_from_slice(&left.0);
|
|
||||||
v[N..].copy_from_slice(&right.0);
|
|
||||||
let mut arr = [0; N];
|
|
||||||
arr.copy_from_slice(&keccak(v).0[..N]);
|
|
||||||
BytesHash(arr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Generic configuration trait.
|
/// Generic configuration trait.
|
||||||
pub trait GenericConfig<const D: usize>:
|
pub trait GenericConfig<const D: usize>:
|
||||||
Debug + Clone + Sync + Sized + Send + Eq + PartialEq
|
Debug + Clone + Sync + Sized + Send + Eq + PartialEq
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user