diff --git a/Cargo.lock b/Cargo.lock index c551113f1b..f81b88d768 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1521,7 +1521,7 @@ dependencies = [ [[package]] name = "ironfish-frost" version = "0.1.0" -source = "git+https://github.com/iron-fish/ironfish-frost.git?branch=main#b91defc5ef61a402d02425505eafa27b2d2a9f71" +source = "git+https://github.com/iron-fish/ironfish-frost.git?branch=main#226a07caf5c119446d1409122243a2d2335ca8e6" dependencies = [ "blake3", "chacha20 0.9.1", diff --git a/ironfish-rust-nodejs/src/frost.rs b/ironfish-rust-nodejs/src/frost.rs index 4415cb9e9c..300f3272ad 100644 --- a/ironfish-rust-nodejs/src/frost.rs +++ b/ironfish-rust-nodejs/src/frost.rs @@ -8,15 +8,15 @@ use crate::{ }; use ironfish::{ frost::{keys::KeyPackage, round1::SigningCommitments, round2, Randomizer}, - frost_utils::{ - signature_share::SignatureShare, signing_commitment::SigningCommitment, - signing_package::SigningPackage, split_spender_key::split_spender_key, - }, + frost_utils::{signing_package::SigningPackage, split_spender_key::split_spender_key}, participant::{Identity, Secret}, serializing::{bytes_to_hex, fr::FrSerializable, hex_to_bytes, hex_to_vec_bytes}, SaplingKey, }; -use ironfish_frost::nonces::deterministic_signing_nonces; +use ironfish_frost::{ + nonces::deterministic_signing_nonces, signature_share::SignatureShare, + signing_commitment::SigningCommitment, +}; use napi::{bindgen_prelude::*, JsBuffer}; use napi_derive::napi; use rand::thread_rng; @@ -60,13 +60,12 @@ pub fn create_signing_commitment( deterministic_signing_nonces(key_package.signing_share(), &transaction_hash, &signers); let commitments = SigningCommitments::from(&nonces); - let signing_commitment = SigningCommitment { - identity, - hiding: *commitments.hiding(), - binding: *commitments.binding(), - }; + let signing_commitment = + SigningCommitment::from_frost(identity, *commitments.hiding(), *commitments.binding()); + + let bytes = signing_commitment.serialize()?; - Ok(bytes_to_hex(&signing_commitment.serialize())) + Ok(bytes_to_hex(&bytes[..])) } #[napi] @@ -113,12 +112,10 @@ pub fn create_signature_share( ) .map_err(to_napi_err)?; - let signature_share = SignatureShare { - identity, - signature_share, - }; + let signature_share = SignatureShare::from_frost(signature_share, identity); + let bytes = signature_share.serialize()?; - Ok(bytes_to_hex(&signature_share.serialize())) + Ok(bytes_to_hex(&bytes[..])) } #[napi] diff --git a/ironfish-rust-nodejs/src/structs/transaction.rs b/ironfish-rust-nodejs/src/structs/transaction.rs index 6895fddf06..d14dd55b1b 100644 --- a/ironfish-rust-nodejs/src/structs/transaction.rs +++ b/ironfish-rust-nodejs/src/structs/transaction.rs @@ -11,12 +11,10 @@ use ironfish::assets::asset_identifier::AssetIdentifier; use ironfish::frost::round1::SigningCommitments; use ironfish::frost::round2::SignatureShare as FrostSignatureShare; use ironfish::frost::Identifier; -use ironfish::frost_utils::signature_share::SignatureShare; -use ironfish::frost_utils::signing_commitment::SigningCommitment; use ironfish::frost_utils::signing_package::SigningPackage; +use ironfish::serializing::bytes_to_hex; use ironfish::serializing::fr::FrSerializable; use ironfish::serializing::hex_to_vec_bytes; -use ironfish::serializing::{bytes_to_hex, hex_to_bytes}; use ironfish::transaction::unsigned::UnsignedTransaction; use ironfish::transaction::{ batch_verify_transactions, TransactionVersion, TRANSACTION_EXPIRATION_SIZE, @@ -27,6 +25,8 @@ use ironfish::{ ViewKey, }; use ironfish_frost::keys::PublicKeyPackage; +use ironfish_frost::signature_share::SignatureShare; +use ironfish_frost::signing_commitment::SigningCommitment; use napi::{ bindgen_prelude::{i64n, BigInt, Buffer, Env, Object, Result, Undefined}, JsBuffer, @@ -437,12 +437,15 @@ impl NativeUnsignedTransaction { for identifier_commitment in native_identifer_commitments { let bytes = hex_to_vec_bytes(&identifier_commitment).map_err(to_napi_err)?; - let signing_commitment = SigningCommitment::read(&bytes[..]).map_err(to_napi_err)?; + let signing_commitment = + SigningCommitment::deserialize_from(&bytes[..]).map_err(to_napi_err)?; - let commitment = - SigningCommitments::new(signing_commitment.hiding, signing_commitment.binding); + let commitment = SigningCommitments::new( + *signing_commitment.hiding(), + *signing_commitment.binding(), + ); - commitments.push((signing_commitment.identity, commitment)); + commitments.push((signing_commitment.identity().clone(), commitment)); } let signing_package = self @@ -487,9 +490,14 @@ pub fn aggregate_signature_shares( let mut signature_shares = BTreeMap::::new(); for signature_share in signature_shares_arr.iter() { - let iss = SignatureShare::deserialize(&hex_to_bytes(signature_share).map_err(to_napi_err)?) - .map_err(to_napi_err)?; - signature_shares.insert(iss.identity.to_frost_identifier(), iss.signature_share); + let iss = SignatureShare::deserialize_from( + &hex_to_vec_bytes(signature_share).map_err(to_napi_err)?[..], + ) + .map_err(to_napi_err)?; + signature_shares.insert( + iss.identity().to_frost_identifier(), + *iss.frost_signature_share(), + ); } let signed_transaction = unsigned_transaction diff --git a/ironfish-rust/src/frost_utils/mod.rs b/ironfish-rust/src/frost_utils/mod.rs index 72d702abb9..5d98b42310 100644 --- a/ironfish-rust/src/frost_utils/mod.rs +++ b/ironfish-rust/src/frost_utils/mod.rs @@ -2,8 +2,6 @@ * 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/. */ -pub mod signature_share; -pub mod signing_commitment; pub mod signing_package; pub mod split_secret; pub mod split_spender_key; diff --git a/ironfish-rust/src/frost_utils/signature_share.rs b/ironfish-rust/src/frost_utils/signature_share.rs deleted file mode 100644 index 755229cc0e..0000000000 --- a/ironfish-rust/src/frost_utils/signature_share.rs +++ /dev/null @@ -1,49 +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 ironfish_frost::{ - frost::round2::SignatureShare as FrostSignatureShare, - participant::{Identity, IDENTITY_LEN}, -}; - -use crate::errors::{IronfishError, IronfishErrorKind}; - -const FROST_SIGNATURE_SHARE_LEN: usize = 32; -const SIGNATURE_SHARE_LEN: usize = IDENTITY_LEN + FROST_SIGNATURE_SHARE_LEN; - -type SignatureShareSerialization = [u8; SIGNATURE_SHARE_LEN]; - -pub struct SignatureShare { - pub identity: Identity, - pub signature_share: FrostSignatureShare, -} - -impl SignatureShare { - pub fn serialize(&self) -> SignatureShareSerialization { - let identity_bytes = self.identity.serialize(); - let signature_share_bytes = self.signature_share.serialize(); - let mut serialization = [0u8; SIGNATURE_SHARE_LEN]; - serialization[..IDENTITY_LEN].copy_from_slice(&identity_bytes); - serialization[IDENTITY_LEN..].copy_from_slice(&signature_share_bytes); - serialization - } - - pub fn deserialize(bytes: &SignatureShareSerialization) -> Result { - let mut identity_bytes = [0u8; IDENTITY_LEN]; - let mut signature_share_bytes = [0u8; FROST_SIGNATURE_SHARE_LEN]; - identity_bytes.copy_from_slice(&bytes[..IDENTITY_LEN]); - signature_share_bytes.copy_from_slice(&bytes[IDENTITY_LEN..]); - - Ok(SignatureShare { - identity: Identity::deserialize_from(&identity_bytes[..]).map_err(|e| { - IronfishError::new_with_source(IronfishErrorKind::InvalidFrostIdentifier, e) - })?, - signature_share: FrostSignatureShare::deserialize(signature_share_bytes).map_err( - |e| { - IronfishError::new_with_source(IronfishErrorKind::InvalidFrostSignatureShare, e) - }, - )?, - }) - } -} diff --git a/ironfish-rust/src/frost_utils/signing_commitment.rs b/ironfish-rust/src/frost_utils/signing_commitment.rs deleted file mode 100644 index b5814f4031..0000000000 --- a/ironfish-rust/src/frost_utils/signing_commitment.rs +++ /dev/null @@ -1,84 +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 std::io; - -use ironfish_frost::{ - frost::round1::NonceCommitment, - participant::{Identity, IDENTITY_LEN}, -}; - -use crate::errors::IronfishError; - -const SIGNING_COMMITMENT_LENGTH: usize = IDENTITY_LEN + 96; - -#[derive(Clone, PartialEq, Eq, Debug)] -pub struct SigningCommitment { - pub identity: Identity, - pub hiding: NonceCommitment, - pub binding: NonceCommitment, -} - -impl SigningCommitment { - pub fn serialize(&self) -> [u8; SIGNING_COMMITMENT_LENGTH] { - let mut bytes = [0u8; SIGNING_COMMITMENT_LENGTH]; - self.write(&mut bytes[..]).unwrap(); - bytes - } - - pub fn read(mut reader: R) -> Result { - let identity = Identity::deserialize_from(&mut reader)?; - - let mut hiding = [0u8; 32]; - reader.read_exact(&mut hiding)?; - let hiding = NonceCommitment::deserialize(hiding)?; - - let mut binding = [0u8; 32]; - reader.read_exact(&mut binding)?; - let binding = NonceCommitment::deserialize(binding)?; - - Ok(SigningCommitment { - identity, - hiding, - binding, - }) - } - - fn write(&self, mut writer: W) -> Result<(), IronfishError> { - writer.write_all(&self.identity.serialize())?; - writer.write_all(&self.hiding.serialize())?; - writer.write_all(&self.binding.serialize())?; - Ok(()) - } -} - -#[cfg(test)] -mod tests { - use super::SigningCommitment; - use ironfish_frost::{ - frost::{keys::SigningShare, round1::SigningNonces}, - participant::Secret, - }; - use rand::thread_rng; - - #[test] - fn serialization_round_trip() { - let mut rng = thread_rng(); - - let signing_share = SigningShare::default(); - let identity = Secret::random(&mut rng).to_identity(); - let nonces = SigningNonces::new(&signing_share, &mut rng); - - let signing_commitment = SigningCommitment { - identity, - hiding: nonces.hiding().into(), - binding: nonces.binding().into(), - }; - let serialized = signing_commitment.serialize(); - let deserialized = - SigningCommitment::read(&serialized[..]).expect("deserialization failed"); - - assert_eq!(deserialized, signing_commitment); - } -}