2025-01-10 11:29:03 +01:00
|
|
|
use plonky2::hash::hash_types::{ HashOutTarget, RichField, NUM_HASH_OUT_ELTS};
|
2024-11-03 11:48:35 +01:00
|
|
|
use plonky2::hash::hashing::PlonkyPermutation;
|
|
|
|
|
use plonky2::iop::target::Target;
|
|
|
|
|
use plonky2::plonk::circuit_builder::CircuitBuilder;
|
2025-01-10 11:29:03 +01:00
|
|
|
use plonky2::plonk::config::AlgebraicHasher;
|
2024-11-03 11:48:35 +01:00
|
|
|
use plonky2_field::extension::Extendable;
|
|
|
|
|
use plonky2_poseidon2::poseidon2_hash::poseidon2::Poseidon2;
|
|
|
|
|
|
2025-01-10 11:29:03 +01:00
|
|
|
/// Compression function which takes two 256 bit inputs (HashOutTarget) and key Target
|
|
|
|
|
/// and returns a 256 bit output (HashOutTarget / 4 Targets).
|
2024-11-03 11:48:35 +01:00
|
|
|
pub fn key_compress_circuit<
|
|
|
|
|
F: RichField + Extendable<D> + Poseidon2,
|
|
|
|
|
const D: usize,
|
|
|
|
|
H: AlgebraicHasher<F>,
|
|
|
|
|
>(
|
|
|
|
|
builder: &mut CircuitBuilder<F, D>,
|
2025-01-10 11:29:03 +01:00
|
|
|
x: HashOutTarget,
|
|
|
|
|
y: HashOutTarget,
|
2024-11-03 11:48:35 +01:00
|
|
|
key: Target,
|
|
|
|
|
) -> HashOutTarget {
|
|
|
|
|
let zero = builder.zero();
|
|
|
|
|
let mut state = H::AlgebraicPermutation::new(core::iter::repeat(zero));
|
|
|
|
|
|
2025-01-10 11:29:03 +01:00
|
|
|
state.set_from_slice(&x.elements, 0);
|
|
|
|
|
state.set_from_slice(&y.elements, NUM_HASH_OUT_ELTS);
|
2024-11-03 11:48:35 +01:00
|
|
|
state.set_elt(key, NUM_HASH_OUT_ELTS*2);
|
|
|
|
|
|
|
|
|
|
state = builder.permute::<H>(state);
|
|
|
|
|
|
|
|
|
|
HashOutTarget {
|
|
|
|
|
elements: state.squeeze()[..NUM_HASH_OUT_ELTS].try_into().unwrap(),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|