Просмотр исходного кода

sdk/crypto: Derive a deterministic nonce for ECVRF

parazyd 2 лет назад
Родитель
Сommit
b82aee8cd3
2 измененных файлов с 16 добавлено и 10 удалено
  1. 1 1
      src/contract/money/src/client/pow_reward_v1.rs
  2. 15 9
      src/sdk/src/crypto/ecvrf.rs

+ 1 - 1
src/contract/money/src/client/pow_reward_v1.rs

@@ -158,7 +158,7 @@ impl PoWRewardCallBuilder {
         vrf_input.extend_from_slice(&pallas::Base::from(self.last_nonce).to_repr());
         vrf_input.extend_from_slice(self.fork_previous_hash.as_bytes());
         vrf_input.extend_from_slice(&pallas::Base::from(self.block_height).to_repr());
-        let vrf_proof = VrfProof::prove(self.secret, &vrf_input, &mut OsRng);
+        let vrf_proof = VrfProof::prove(self.secret, &vrf_input);
 
         let params = MoneyPoWRewardParamsV1 { input: c_input, output: c_output, vrf_proof };
         let debris = PoWRewardCallDebris { params, proofs: vec![proof] };

+ 15 - 9
src/sdk/src/crypto/ecvrf.rs

@@ -26,14 +26,17 @@ use halo2_gadgets::ecc::chip::FixedPoint;
 use pasta_curves::{
     arithmetic::CurveExt,
     group::{
-        ff::{Field, FromUniformBytes},
+        ff::{FromUniformBytes, PrimeField},
         Group, GroupEncoding,
     },
     pallas,
 };
-use rand_core::{CryptoRng, RngCore};
 
-use super::{constants::NullifierK, util::fp_mod_fv, PublicKey, SecretKey};
+use super::{
+    constants::NullifierK,
+    util::{fp_mod_fv, hash_to_scalar},
+    PublicKey, SecretKey,
+};
 
 /// Prefix domain used for `hash_to_curve` calls
 const VRF_DOMAIN: &str = "DarkFi_ECVRF";
@@ -48,8 +51,8 @@ pub struct VrfProof {
 
 impl VrfProof {
     /// Execute the VRF function and create a proof given a `SecretKey`
-    /// a seed input `alpha_string`, and an RNG instance.
-    pub fn prove(x: SecretKey, alpha_string: &[u8], rng: &mut (impl CryptoRng + RngCore)) -> Self {
+    /// and a seed input `alpha_string`.
+    pub fn prove(x: SecretKey, alpha_string: &[u8]) -> Self {
         let Y = PublicKey::from_secret(x);
         assert!(!bool::from(Y.inner().is_identity()));
 
@@ -59,7 +62,9 @@ impl VrfProof {
         let H = pallas::Point::hash_to_curve(VRF_DOMAIN)(&message);
 
         let gamma = H * fp_mod_fv(x.inner());
-        let k = pallas::Scalar::random(rng);
+
+        // Generate a determinnistic nonce
+        let k = hash_to_scalar(VRF_DOMAIN.as_bytes(), &[&x.inner().to_repr(), &H.to_bytes()]);
 
         let mut hasher = blake3::Hasher::new();
         hasher.update(&H.to_bytes());
@@ -106,8 +111,9 @@ impl VrfProof {
         hasher.finalize() == self.c
     }
 
-    /// Returns the VRF output. **It is necessary** to do `VrfProof::verify` first in
-    /// order to trust this function's output.
+    /// Returns the VRF output.
+    /// **It is necessary** to do `VrfProof::verify` first in order to trust this function's output.
+    /// TODO: FIXME: We should enforce verification before getting the output.
     pub fn hash_output(&self) -> blake3::Hash {
         let mut hasher = blake3::Hasher::new();
         hasher.update(VRF_DOMAIN.as_bytes());
@@ -131,7 +137,7 @@ mod tests {
         // VRF input
         let input = [0xde, 0xad, 0xbe, 0xef];
 
-        let proof = VrfProof::prove(secret_key, &input, &mut OsRng);
+        let proof = VrfProof::prove(secret_key, &input);
         assert!(proof.verify(public_key, &input));
 
         // Forged public key