use jubjub::*; use pairing::*; pub fn pedersen_hash( bits: I, params: &E::Params ) -> edwards::Point where I: IntoIterator, E: JubjubEngine { let mut bits = bits.into_iter(); let mut result = edwards::Point::zero(); let mut generators = params.pedersen_hash_generators().iter(); loop { let mut acc = E::Fs::zero(); let mut cur = E::Fs::one(); let mut chunks_remaining = params.pedersen_hash_chunks_per_generator(); let mut encountered_bits = false; // Grab three bits from the input while let Some(a) = bits.next() { encountered_bits = true; let b = bits.next().unwrap_or(false); let c = bits.next().unwrap_or(false); // Start computing this portion of the scalar let mut tmp = cur; if a { tmp.add_assign(&cur); } cur.double(); // 2^1 * cur if b { tmp.add_assign(&cur); } // conditionally negate if c { tmp.negate(); } acc.add_assign(&tmp); chunks_remaining -= 1; if chunks_remaining == 0 { break; } else { cur.double(); // 2^2 * cur cur.double(); // 2^3 * cur cur.double(); // 2^4 * cur } } if !encountered_bits { break; } let mut tmp = generators.next().expect("we don't have enough generators").clone(); tmp = tmp.mul(acc, params); result = result.add(&tmp, params); } result }