util.rs 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. use blake2b_simd::Params;
  2. use halo2_gadgets::{ecc::chip::FixedPoint, poseidon::primitives as poseidon};
  3. use pasta_curves::{
  4. arithmetic::{CurveExt, FieldExt},
  5. group::ff::PrimeField,
  6. pallas,
  7. };
  8. use super::{
  9. constants::{
  10. fixed_bases::{
  11. VALUE_COMMITMENT_PERSONALIZATION, VALUE_COMMITMENT_R_BYTES, VALUE_COMMITMENT_V_BYTES,
  12. },
  13. util::gen_const_array,
  14. NullifierK,
  15. },
  16. types::*,
  17. };
  18. pub fn hash_to_scalar(persona: &[u8], a: &[u8], b: &[u8]) -> pallas::Scalar {
  19. let mut hasher = Params::new().hash_length(64).personal(persona).to_state();
  20. hasher.update(a);
  21. hasher.update(b);
  22. let ret = hasher.finalize();
  23. pallas::Scalar::from_bytes_wide(ret.as_array())
  24. }
  25. /// Pedersen commitment for a full-width base field element.
  26. #[allow(non_snake_case)]
  27. pub fn pedersen_commitment_base(value: pallas::Base, blind: DrkValueBlind) -> DrkValueCommit {
  28. let hasher = DrkValueCommit::hash_to_curve(VALUE_COMMITMENT_PERSONALIZATION);
  29. let V = NullifierK.generator();
  30. let R = hasher(&VALUE_COMMITMENT_R_BYTES);
  31. V * mod_r_p(value) + R * blind
  32. }
  33. /// Pedersen commitment for a 64-bit value, in the base field.
  34. #[allow(non_snake_case)]
  35. pub fn pedersen_commitment_u64(value: u64, blind: DrkValueBlind) -> DrkValueCommit {
  36. let hasher = DrkValueCommit::hash_to_curve(VALUE_COMMITMENT_PERSONALIZATION);
  37. let V = hasher(&VALUE_COMMITMENT_V_BYTES);
  38. let R = hasher(&VALUE_COMMITMENT_R_BYTES);
  39. V * mod_r_p(DrkValue::from(value)) + R * blind
  40. }
  41. /// Simplified wrapper for poseidon hash function.
  42. pub fn poseidon_hash<const N: usize>(messages: [pallas::Base; N]) -> pallas::Base {
  43. poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<N>, 3, 2>::init()
  44. .hash(messages)
  45. }
  46. /// Converts from pallas::Base to pallas::Scalar (aka $x \pmod{r_\mathbb{P}}$).
  47. ///
  48. /// This requires no modular reduction because Pallas' base field is smaller than its
  49. /// scalar field.
  50. pub fn mod_r_p(x: pallas::Base) -> pallas::Scalar {
  51. pallas::Scalar::from_repr(x.to_repr()).unwrap()
  52. }
  53. /// The sequence of bits representing a u64 in little-endian order.
  54. ///
  55. /// # Panics
  56. ///
  57. /// Panics if the expected length of the sequence `NUM_BITS` exceeds
  58. /// 64.
  59. pub fn i2lebsp<const NUM_BITS: usize>(int: u64) -> [bool; NUM_BITS] {
  60. assert!(NUM_BITS <= 64);
  61. gen_const_array(|mask: usize| (int & (1 << mask)) != 0)
  62. }