From 3e00045efc8e7292a87ac4b9425b9046e06a6d8f Mon Sep 17 00:00:00 2001 From: Joe Date: Thu, 17 Oct 2024 11:26:56 -0700 Subject: [PATCH] move proof generation key extension to ironfish-zkp --- ironfish-rust/src/keys/mod.rs | 3 +- .../src/keys/proof_generation_key.rs | 170 ------------------ ironfish-zkp/src/primitives/mod.rs | 1 + .../src/primitives/proof_generation_key.rs | 64 +++++++ 4 files changed, 66 insertions(+), 172 deletions(-) delete mode 100644 ironfish-rust/src/keys/proof_generation_key.rs create mode 100644 ironfish-zkp/src/primitives/proof_generation_key.rs diff --git a/ironfish-rust/src/keys/mod.rs b/ironfish-rust/src/keys/mod.rs index 9e4313cda6..f912b365af 100644 --- a/ironfish-rust/src/keys/mod.rs +++ b/ironfish-rust/src/keys/mod.rs @@ -13,6 +13,7 @@ use group::GroupEncoding; use ironfish_zkp::constants::{ CRH_IVK_PERSONALIZATION, PROOF_GENERATION_KEY_GENERATOR, SPENDING_KEY_GENERATOR, }; +pub use ironfish_zkp::ProofGenerationKey; use jubjub::SubgroupPoint; use rand::prelude::*; @@ -26,8 +27,6 @@ mod view_keys; pub use view_keys::*; mod util; pub use util::*; -pub mod proof_generation_key; -pub use proof_generation_key::*; #[cfg(test)] mod test; diff --git a/ironfish-rust/src/keys/proof_generation_key.rs b/ironfish-rust/src/keys/proof_generation_key.rs deleted file mode 100644 index ac19cf0119..0000000000 --- a/ironfish-rust/src/keys/proof_generation_key.rs +++ /dev/null @@ -1,170 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ - -use group::GroupEncoding; -pub use ironfish_zkp::ProofGenerationKey; -use jubjub::{Fr, SubgroupPoint}; - -use crate::{ - errors::{IronfishError, IronfishErrorKind}, - serializing::{bytes_to_hex, hex_to_bytes}, -}; - -pub trait ProofGenerationKeySerializable { - fn serialize(&self) -> [u8; 64]; - fn deserialize(bytes: [u8; 64]) -> Result; - fn hex_key(&self) -> String; - fn from_hex(hex_key: &str) -> Result; -} - -impl ProofGenerationKeySerializable for ProofGenerationKey { - fn serialize(&self) -> [u8; 64] { - let mut proof_generation_key_bytes: [u8; 64] = [0; 64]; - proof_generation_key_bytes[0..32].copy_from_slice(&self.ak.to_bytes()); - proof_generation_key_bytes[32..].copy_from_slice(&self.nsk.to_bytes()); - proof_generation_key_bytes - } - - fn deserialize(proof_generation_key_bytes: [u8; 64]) -> Result { - let mut ak_bytes: [u8; 32] = [0; 32]; - let mut nsk_bytes: [u8; 32] = [0; 32]; - - ak_bytes[0..32].copy_from_slice(&proof_generation_key_bytes[0..32]); - nsk_bytes[0..32].copy_from_slice(&proof_generation_key_bytes[32..64]); - - let ak = match SubgroupPoint::from_bytes(&ak_bytes).into() { - Some(ak) => ak, - None => return Err(IronfishError::new(IronfishErrorKind::InvalidAuthorizingKey)), - }; - - let nsk = match Fr::from_bytes(&nsk_bytes).into() { - Some(nsk) => nsk, - None => { - return Err(IronfishError::new( - IronfishErrorKind::InvalidNullifierDerivingKey, - )) - } - }; - - Ok(ProofGenerationKey { ak, nsk }) - } - - fn hex_key(&self) -> String { - let serialized_bytes = self.serialize(); - bytes_to_hex(&serialized_bytes[..]) - } - - fn from_hex(hex_key: &str) -> Result { - let bytes = hex_to_bytes(hex_key)?; - ProofGenerationKey::deserialize(bytes) - } -} - -#[cfg(test)] -mod test { - use crate::errors::IronfishErrorKind; - use ff::Field; - use group::{Group, GroupEncoding}; - use ironfish_zkp::ProofGenerationKey; - - use super::ProofGenerationKeySerializable; - use jubjub; - use rand::{rngs::StdRng, SeedableRng}; - - #[test] - fn test_serialize() { - let mut rng = StdRng::seed_from_u64(0); - - let proof_generation_key = ProofGenerationKey { - ak: jubjub::SubgroupPoint::random(&mut rng), - nsk: jubjub::Fr::random(&mut rng), - }; - - let serialized_bytes = proof_generation_key.serialize(); - - assert_eq!(serialized_bytes.len(), 64); - } - - #[test] - fn test_deserialize_ak_error() { - let mut proof_generation_key_bytes: [u8; 64] = [0; 64]; - proof_generation_key_bytes[0..32].fill(0xFF); - - let result = ProofGenerationKey::deserialize(proof_generation_key_bytes); - - assert!(result.is_err()); - - let err = result.err().unwrap(); - - assert!(matches!(err.kind, IronfishErrorKind::InvalidAuthorizingKey)); - } - - #[test] - fn test_deserialize_nsk_error() { - let mut proof_generation_key_bytes: [u8; 64] = [0; 64]; - // Populate with valid bytes for ak and invalid bytes for nsk - let valid_ak = jubjub::SubgroupPoint::random(&mut StdRng::seed_from_u64(0)); - proof_generation_key_bytes[0..32].copy_from_slice(&valid_ak.to_bytes()); // Assuming these are valid bytes for ak - proof_generation_key_bytes[32..64].fill(0xFF); // Invalid bytes for nsk - - let result = ProofGenerationKey::deserialize(proof_generation_key_bytes); - - assert!(result.is_err()); - - let err = result.err().unwrap(); - - assert!(matches!( - err.kind, - IronfishErrorKind::InvalidNullifierDerivingKey - )); - } - - #[test] - fn test_deserialize() { - let mut rng = StdRng::seed_from_u64(0); - - let proof_generation_key = ProofGenerationKey { - ak: jubjub::SubgroupPoint::random(&mut rng), - nsk: jubjub::Fr::random(&mut rng), - }; - - let serialized_bytes = proof_generation_key.serialize(); - - let deserialized_proof_generation_key = - ProofGenerationKey::deserialize(serialized_bytes).expect("deserialization successful"); - - assert_eq!( - proof_generation_key.ak, - deserialized_proof_generation_key.ak - ); - assert_eq!( - proof_generation_key.nsk, - deserialized_proof_generation_key.nsk - ); - } - - #[test] - fn test_hex() { - let mut rng = StdRng::seed_from_u64(0); - - let proof_generation_key = ProofGenerationKey { - ak: jubjub::SubgroupPoint::random(&mut rng), - nsk: jubjub::Fr::random(&mut rng), - }; - - let hex_key = proof_generation_key.hex_key(); - - let deserialized_proof_generation_key = - ProofGenerationKey::from_hex(&hex_key).expect("deserialization successful"); - - assert_eq!( - proof_generation_key.ak, - deserialized_proof_generation_key.ak - ); - assert_eq!( - proof_generation_key.nsk, - deserialized_proof_generation_key.nsk - ); - } -} diff --git a/ironfish-zkp/src/primitives/mod.rs b/ironfish-zkp/src/primitives/mod.rs index 1c9e55b29d..313c427ed1 100644 --- a/ironfish-zkp/src/primitives/mod.rs +++ b/ironfish-zkp/src/primitives/mod.rs @@ -1,2 +1,3 @@ mod value_commitment; +pub mod proof_generation_key; pub use value_commitment::ValueCommitment; diff --git a/ironfish-zkp/src/primitives/proof_generation_key.rs b/ironfish-zkp/src/primitives/proof_generation_key.rs new file mode 100644 index 0000000000..6b1913c76c --- /dev/null +++ b/ironfish-zkp/src/primitives/proof_generation_key.rs @@ -0,0 +1,64 @@ +use group::GroupEncoding; +use jubjub::{Fr, SubgroupPoint}; +use zcash_primitives::sapling::ProofGenerationKey as ZcashProofGenerationKey; +use std::fmt; +use std::error::Error; +use std::ops::Deref; + +#[derive(Debug)] +pub enum ProofGenerationKeyError { + InvalidAuthorizingKey, + InvalidNullifierDerivingKey, + HexConversionError, +} + +impl fmt::Display for ProofGenerationKeyError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + ProofGenerationKeyError::InvalidAuthorizingKey => write!(f, "Invalid authorizing key"), + ProofGenerationKeyError::InvalidNullifierDerivingKey => write!(f, "Invalid nullifier deriving key"), + ProofGenerationKeyError::HexConversionError => write!(f, "Hex conversion error"), + } + } +} + +impl Error for ProofGenerationKeyError {} + +pub struct ProofGenerationKey(ZcashProofGenerationKey); + +impl ProofGenerationKey { + pub fn to_bytes(&self) -> [u8; 64] { + let mut proof_generation_key_bytes: [u8; 64] = [0; 64]; + proof_generation_key_bytes[0..32].copy_from_slice(&self.0.ak.to_bytes()); + proof_generation_key_bytes[32..].copy_from_slice(&self.0.nsk.to_bytes()); + proof_generation_key_bytes + } + + pub fn from_bytes(proof_generation_key_bytes: [u8; 64]) -> Result { + let mut ak_bytes: [u8; 32] = [0; 32]; + let mut nsk_bytes: [u8; 32] = [0; 32]; + + ak_bytes[0..32].copy_from_slice(&proof_generation_key_bytes[0..32]); + nsk_bytes[0..32].copy_from_slice(&proof_generation_key_bytes[32..64]); + + let ak = match SubgroupPoint::from_bytes(&ak_bytes).into() { + Some(ak) => ak, + None => return Err(ProofGenerationKeyError::InvalidAuthorizingKey), + }; + + let nsk = match Fr::from_bytes(&nsk_bytes).into() { + Some(nsk) => nsk, + None => return Err(ProofGenerationKeyError::InvalidNullifierDerivingKey), + }; + + Ok(ProofGenerationKey(ZcashProofGenerationKey { ak, nsk })) + } +} + +impl Deref for ProofGenerationKey { + type Target = ZcashProofGenerationKey; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} \ No newline at end of file