diff --git a/src/circuit/mod.rs b/src/circuit/mod.rs index c4f0db251..30a84c08c 100644 --- a/src/circuit/mod.rs +++ b/src/circuit/mod.rs @@ -30,7 +30,9 @@ use jubjub::{ use constants; use primitives::{ - ValueCommitment + ValueCommitment, + ProofGenerationKey, + PaymentAddress }; @@ -113,21 +115,14 @@ pub struct Spend<'a, E: JubjubEngine> { /// Pedersen commitment to the value being spent pub value_commitment: Option>, - /// Key which allows the proof to be constructed - /// as defense-in-depth against a flaw in the - /// protocol that would otherwise be exploitable - /// by a holder of a viewing key. - pub rsk: Option, + /// Key required to construct proofs for spending notes + /// for a particular spending key + pub proof_generation_key: Option>, - /// The public key that will be re-randomized for - /// use as a nullifier and signing key for the - /// transaction. - pub ak: Option>, + /// The payment address associated with the note + pub payment_address: Option>, - /// The diversified base used to compute pk_d. - pub g_d: Option>, - - /// The randomness used to hide the note commitment data + /// The randomness of the note commitment pub commitment_randomness: Option, /// The authentication path of the commitment in the tree @@ -149,7 +144,7 @@ impl<'a, E: JubjubEngine> Circuit for Spend<'a, E> { // Witness rsk as bits let rsk = boolean::field_into_boolean_vec_le( cs.namespace(|| "rsk"), - self.rsk + self.proof_generation_key.as_ref().map(|k| k.rsk.clone()) )?; // NB: We don't ensure that the bit representation of rsk @@ -169,7 +164,7 @@ impl<'a, E: JubjubEngine> Circuit for Spend<'a, E> { // Prover witnesses ak (ensures that it's on the curve) let ak = ecc::EdwardsPoint::witness( cs.namespace(|| "ak"), - self.ak, + self.proof_generation_key.as_ref().map(|k| k.ak.clone()), self.params )?; @@ -226,11 +221,20 @@ impl<'a, E: JubjubEngine> Circuit for Spend<'a, E> { // already guaranteed this. // TODO: We might as well just perform the // check again here, since it's not expensive. - let g_d = ecc::EdwardsPoint::witness( - cs.namespace(|| "witness g_d"), - self.g_d, - self.params - )?; + let g_d = { + // This binding is to avoid a weird edge case in Rust's + // ownership/borrowing rules. self is partially moved + // above, but the closure for and_then will have to + // move self (or a reference to self) to reference + // self.params, so we have to copy self.params here. + let params = self.params; + + ecc::EdwardsPoint::witness( + cs.namespace(|| "witness g_d"), + self.payment_address.as_ref().and_then(|a| a.g_d(params)), + self.params + )? + }; // Compute pk_d = g_d^ivk let pk_d = g_d.mul( @@ -614,9 +618,8 @@ fn test_input_circuit_with_bls12_381() { let instance = Spend { params: params, value_commitment: Some(value_commitment.clone()), - rsk: Some(rsk), - ak: Some(ak), - g_d: Some(g_d.clone()), + proof_generation_key: Some(proof_generation_key.clone()), + payment_address: Some(payment_address.clone()), commitment_randomness: Some(commitment_randomness), auth_path: auth_path.clone() }; diff --git a/src/primitives/mod.rs b/src/primitives/mod.rs index 6c12892d9..028c6b738 100644 --- a/src/primitives/mod.rs +++ b/src/primitives/mod.rs @@ -49,6 +49,7 @@ impl ValueCommitment { } } +#[derive(Clone)] pub struct ProofGenerationKey { pub ak: edwards::Point, pub rsk: E::Fs @@ -119,11 +120,22 @@ impl Diversifier { } } +#[derive(Clone)] pub struct PaymentAddress { pub pk_d: edwards::Point, pub diversifier: Diversifier } +impl PaymentAddress { + pub fn g_d( + &self, + params: &E::Params + ) -> Option> + { + self.diversifier.g_d(params) + } +} + pub struct Note { /// The value of the note pub value: u64,