diffie_hellman.rs 1.4 KB

123456789101112131415161718192021222324252627282930313233343536
  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
  14. // of bits instead of individual bits).
  15. // We want that to be fast because it's in the hot path for trial decryption of
  16. // notes on chain.
  17. let mut wnaf = group::Wnaf::new();
  18. wnaf.scalar(esk).base(*pk_d).clear_cofactor()
  19. }
  20. /// Sapling KDF for note encryption.
  21. ///
  22. /// Implements section 5.4.4.4 of the Zcash Protocol Specification.
  23. pub fn kdf_sapling(dhsecret: jubjub::SubgroupPoint, epk: &jubjub::ExtendedPoint) -> Blake2bHash {
  24. Blake2bParams::new()
  25. .hash_length(32)
  26. .personal(KDF_SAPLING_PERSONALIZATION)
  27. .to_state()
  28. .update(&dhsecret.to_bytes())
  29. .update(&epk.to_bytes())
  30. .finalize()
  31. }