diffie_hellman.rs 1.4 KB

1234567891011121314151617181920212223242526272829303132333435
  1. use blake2b_simd::{Hash as Blake2bHash, Params as Blake2bParams};
  2. use group::{cofactor::CofactorGroup, GroupEncoding};
  3. pub const KDF_SAPLING_PERSONALIZATION: &[u8; 16] = b"DarkFiSaplingKDF";
  4. /// Functions used for encrypting the note in transaction outputs.
  5. /// Sapling key agreement for note encryption.
  6. ///
  7. /// Implements section 5.4.4.3 of the Zcash Protocol Specification.
  8. pub fn sapling_ka_agree(esk: &jubjub::Fr, pk_d: &jubjub::ExtendedPoint) -> jubjub::SubgroupPoint {
  9. // [8 esk] pk_d
  10. // <ExtendedPoint as CofactorGroup>::clear_cofactor is implemented using
  11. // ExtendedPoint::mul_by_cofactor in the jubjub crate.
  12. // ExtendedPoint::multiply currently just implements double-and-add,
  13. // so using wNAF is a concrete speed improvement (as it operates over a window of bits
  14. // instead of individual bits).
  15. // We want that to be fast because it's in the hot path for trial decryption of notes on chain.
  16. let mut wnaf = group::Wnaf::new();
  17. wnaf.scalar(esk).base(*pk_d).clear_cofactor()
  18. }
  19. /// Sapling KDF for note encryption.
  20. ///
  21. /// Implements section 5.4.4.4 of the Zcash Protocol Specification.
  22. pub fn kdf_sapling(dhsecret: jubjub::SubgroupPoint, epk: &jubjub::ExtendedPoint) -> Blake2bHash {
  23. Blake2bParams::new()
  24. .hash_length(32)
  25. .personal(KDF_SAPLING_PERSONALIZATION)
  26. .to_state()
  27. .update(&dhsecret.to_bytes())
  28. .update(&epk.to_bytes())
  29. .finalize()
  30. }