lambdaworks_crypto/hash/pedersen/
mod.rs1use lambdaworks_math::{
2 elliptic_curve::short_weierstrass::point::ShortWeierstrassProjectivePoint as Point,
3 field::{
4 element::FieldElement as FE,
5 fields::fft_friendly::stark_252_prime_field::Stark252PrimeField,
6 },
7};
8
9mod constants;
10mod parameters;
11use parameters::PedersenParameters;
12pub use parameters::PedersenStarkCurve;
13
14mod private {
15 use super::*;
16
17 pub trait Sealed {}
18
19 impl<P: PedersenParameters> Sealed for P {}
20}
21
22pub trait Pedersen: PedersenParameters + self::private::Sealed {
23 fn hash(x: &FE<Self::F>, y: &FE<Self::F>) -> FE<Self::F>;
31
32 fn lookup_and_accumulate(acc: &mut Point<Self::EC>, bits: &[bool], prep: &[Point<Self::EC>]);
35}
36
37impl<P: PedersenParameters<F = Stark252PrimeField>> Pedersen for P {
40 fn hash(x: &FE<Self::F>, y: &FE<Self::F>) -> FE<Self::F> {
44 let x = x.to_bits_le();
45 let y = y.to_bits_le();
46 let mut acc = P::SHIFT_POINT.clone();
47
48 Self::lookup_and_accumulate(&mut acc, &x[..248], &P::POINTS_P1); Self::lookup_and_accumulate(&mut acc, &x[248..252], &P::POINTS_P2); Self::lookup_and_accumulate(&mut acc, &y[..248], &P::POINTS_P3); Self::lookup_and_accumulate(&mut acc, &y[248..252], &P::POINTS_P4); *acc.to_affine().x()
54 }
55
56 fn lookup_and_accumulate(acc: &mut Point<Self::EC>, bits: &[bool], prep: &[Point<Self::EC>]) {
57 bits.chunks(P::CURVE_CONST_BITS)
58 .enumerate()
59 .for_each(|(i, v)| {
60 let offset = bools_to_usize_le(v);
61 if offset > 0 {
62 *acc = acc.operate_with_affine(&prep[i * P::TABLE_SIZE + offset - 1]);
64 }
65 })
66 }
67}
68
69#[inline]
70fn bools_to_usize_le(bools: &[bool]) -> usize {
71 let mut result: usize = 0;
72 for (ind, bit) in bools.iter().enumerate() {
73 if *bit {
74 result += 1 << ind;
75 }
76 }
77 result
78}
79
80#[cfg(test)]
81mod tests {
82 use super::*;
83 use crate::hash::pedersen::parameters::PedersenStarkCurve;
84
85 #[test]
89 fn test_stark_curve() {
90 let x = FE::from_hex_unchecked(
91 "03d937c035c878245caf64531a5756109c53068da139362728feb561405371cb",
92 );
93 let y = FE::from_hex_unchecked(
94 "0208a0a10250e382e1e4bbe2880906c2791bf6275695e02fbbc6aeff9cd8b31a",
95 );
96 let hash = PedersenStarkCurve::hash(&x, &y);
97 assert_eq!(
98 hash,
99 FE::from_hex_unchecked(
100 "030e480bed5fe53fa909cc0f8c4d99b8f9f2c016be4c41e13a4848797979c662"
101 )
102 );
103 }
104}