Skip to content

Commit

Permalink
Adopt frost-core 2.0.0-rc.0
Browse files Browse the repository at this point in the history
support FROST v2 reddsa
  • Loading branch information
pacu committed Sep 24, 2024
1 parent 5b15498 commit 5703f7f
Show file tree
Hide file tree
Showing 10 changed files with 82 additions and 75 deletions.
6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ resolver = "2"
uniffi = "0.25.0"
async-trait = "0.1.77"
eyre = "0.6.12"
frost-core = { version = "1.0.0", features = ["serde"] }
frost-ed25519 = { version = "1.0.0", features = ["serde"] }
reddsa = { git = "https://github.com/ZcashFoundation/reddsa.git", rev = "81c649c412e5b6ba56d491d2857f91fbd28adbc7", features = ["frost", "serde"] }
frost-core = { version = "2.0.0-rc.0", features = ["serde"] }
frost-ed25519 = { version = "2.0.0-rc.0", features = ["serde"] }
reddsa = { git = "https://github.com/ZcashFoundation/reddsa.git", rev = "ed49e9ca0699a6450f6d4a9fe62ff168f5ea1ead", features = ["frost", "serde"] }
hex = { version = "0.4", features = ["serde"] }
thiserror = "1.0"
rand = "0.8"
Expand Down
30 changes: 20 additions & 10 deletions frost-uniffi-sdk/src/coordinator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,20 @@ pub fn aggregate(
.into_public_key_package()
.map_err(|_| CoordinationError::PublicKeyPackageDeserializationError)?;

frost::aggregate(&signing_package, &shares, &public_key_package)
.map_err(|e| CoordinationError::SignatureShareAggregationFailed {
message: e.to_string(),
})
.map(FrostSignature::from_signature)
let signature =
frost::aggregate(&signing_package, &shares, &public_key_package).map_err(|e| {
CoordinationError::SignatureShareAggregationFailed {
message: e.to_string(),
}
})?;

Ok(FrostSignature {
data: signature.serialize().map_err(|e| {
CoordinationError::SignatureShareAggregationFailed {
message: e.to_string(),
}
})?,
})
}

#[derive(Debug, uniffi::Error, thiserror::Error)]
Expand Down Expand Up @@ -154,13 +163,14 @@ impl FrostSignature {
let bytes: [u8; 64] = self.data[0..64]
.try_into()
.map_err(|_| Error::DeserializationError)?;
Signature::<E>::deserialize(bytes)
Signature::<E>::deserialize(&bytes)
}

pub fn from_signature<C: Ciphersuite>(signature: Signature<C>) -> FrostSignature {
FrostSignature {
data: signature.serialize().as_ref().to_vec(),
}
pub fn from_signature<C: Ciphersuite>(
signature: Signature<C>,
) -> Result<FrostSignature, Error<C>> {
let data = signature.serialize()?;
Ok(FrostSignature { data })
}
}

Expand Down
8 changes: 4 additions & 4 deletions frost-uniffi-sdk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ type E = reddsa::frost::redpallas::PallasBlake2b512;
pub mod coordinator;
pub mod dkg;
pub mod error;
pub mod orchard;
pub mod participant;
#[cfg(feature = "redpallas")]
pub mod randomized;
pub mod serialization;
pub mod trusted_dealer;
pub mod orchard;
use crate::trusted_dealer::{trusted_dealer_keygen, trusted_dealer_keygen_from_configuration};

use frost_core::{
Expand Down Expand Up @@ -377,13 +377,13 @@ impl FrostPublicKeyPackage {
for (k, v) in verifying_shares {
shares.insert(
ParticipantIdentifier::from_identifier(*k)?,
hex::encode(v.serialize()),
hex::encode(v.serialize()?),
);
}

Ok(Self {
verifying_shares: shares,
verifying_key: hex::encode(verifying_key.serialize()),
verifying_key: hex::encode(verifying_key.serialize()?),
})
}

Expand All @@ -408,7 +408,7 @@ impl FrostPublicKeyPackage {
.try_into()
.map_err(|_| Error::DeserializationError)?;

let verifying_share = VerifyingShare::deserialize(verifying_share_bytes)?;
let verifying_share = VerifyingShare::deserialize(&verifying_share_bytes)?;

btree_map.insert(identifier, verifying_share);
}
Expand Down
66 changes: 31 additions & 35 deletions frost-uniffi-sdk/src/orchard/keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ use std::sync::Arc;
use uniffi::{self};

use orchard::keys::{
CommitIvkRandomness, FullViewingKey, NullifierDerivingKey,
SpendValidatingKey, SpendingKey,
CommitIvkRandomness, FullViewingKey, NullifierDerivingKey, SpendValidatingKey, SpendingKey,
};
use zcash_address::unified::{Address, Encoding, Receiver};
use zcash_keys::keys::UnifiedFullViewingKey;
Expand Down Expand Up @@ -70,7 +69,7 @@ pub enum OrchardKeyError {
}

/// This responds to Backup and DKG requirements
/// for FROST.
/// for FROST.
///
/// - Note: See [FROST Book backup section](https://frost.zfnd.org/zcash/technical-details.html#backing-up-key-shares)
#[derive(uniffi::Object, Clone)]
Expand All @@ -81,23 +80,25 @@ pub struct OrchardKeyParts {

#[uniffi::export]
impl OrchardKeyParts {

/// Creates a Random `nk` and `rivk` from a random Spending Key
/// Creates a Random `nk` and `rivk` from a random Spending Key
/// originated from a random 24-word Mnemonic seed which is tossed
/// away.
/// away.
/// This responds to Backup and DKG requirements
/// for FROST.
/// for FROST.
///
/// - Note: See [FROST Book backup section](https://frost.zfnd.org/zcash/technical-details.html#backing-up-key-shares)
#[uniffi::constructor]
fn random(network: ZcashNetwork) -> Result<Arc<OrchardKeyParts>, OrchardKeyError> {
let mnemonic = Mnemonic::<English>::generate(bip0039::Count::Words24);
let random_entropy = mnemonic.entropy();
let spending_key =
SpendingKey::from_zip32_seed(random_entropy, network.to_network_parameters().coin_type(), AccountId::ZERO)
.map_err(|e| OrchardKeyError::KeyDerivationError {
message: e.to_string(),
})?;
let spending_key = SpendingKey::from_zip32_seed(
random_entropy,
network.to_network_parameters().coin_type(),
AccountId::ZERO,
)
.map_err(|e| OrchardKeyError::KeyDerivationError {
message: e.to_string(),
})?;

let nk = NullifierDerivingKey::from(&spending_key);
let rivk = CommitIvkRandomness::from(&spending_key);
Expand All @@ -109,7 +110,6 @@ impl OrchardKeyParts {
}
}


/// An Zcash Orchard Address and its associated network type.
#[derive(uniffi::Object)]
pub struct OrchardAddress {
Expand Down Expand Up @@ -198,7 +198,7 @@ impl OrchardFullViewingKey {
}

/// Creates an [`OrchardFullViewingKey`] from its checked composing parts
/// and its associated Network constant.
/// and its associated Network constant.
#[uniffi::constructor]
pub fn new_from_checked_parts(
ak: Arc<OrchardSpendValidatingKey>,
Expand Down Expand Up @@ -240,15 +240,14 @@ impl OrchardFullViewingKey {

/// Encodes a [`OrchardFullViewingKey`] to its Unified Full Viewing Key
/// string-encoded format. If this operation fails, it returns
/// `Err(OrchardKeyError::DeserializationError)`. This should be straight
/// `Err(OrchardKeyError::DeserializationError)`. This should be straight
/// forward and an error thrown could indicate another kind of issue like a
/// PEBKAC.
fn encode(&self) -> Result<String, OrchardKeyError> {
let ufvk = UnifiedFullViewingKey::from_orchard_fvk(
self.fvk.clone()
)
.map_err(|e| OrchardKeyError::KeyDerivationError {
message: e.to_string(),
let ufvk = UnifiedFullViewingKey::from_orchard_fvk(self.fvk.clone()).map_err(|e| {
OrchardKeyError::KeyDerivationError {
message: e.to_string(),
}
})?;

Ok(ufvk.encode(&self.network.to_network_parameters()))
Expand All @@ -271,17 +270,15 @@ impl OrchardFullViewingKey {

// Returns the [`OrchardNullifierDerivingKey`] component of this FVK
pub fn nk(&self) -> Arc<OrchardNullifierDerivingKey> {
let nk = OrchardNullifierDerivingKey {
nk: *self.fvk.nk()
};
let nk = OrchardNullifierDerivingKey { nk: *self.fvk.nk() };

Arc::new(nk)
}

/// Returns the External Scope of this FVK
pub fn rivk(&self) -> Arc<OrchardCommitIvkRandomness> {
let rivk = OrchardCommitIvkRandomness {
rivk: self.fvk.rivk(Scope::External)
rivk: self.fvk.rivk(Scope::External),
};

Arc::new(rivk)
Expand All @@ -290,11 +287,11 @@ impl OrchardFullViewingKey {
/// Returns the Spend Validating Key component of this Orchard FVK
pub fn ak(&self) -> Arc<OrchardSpendValidatingKey> {
let ak = OrchardSpendValidatingKey {
key: self.fvk.ak().clone()
key: self.fvk.ak().clone(),
};

Arc::new(ak)
}
}
}

impl OrchardFullViewingKey {
Expand All @@ -316,7 +313,7 @@ impl OrchardFullViewingKey {
}
}

/// The `ak` component of an Orchard Full Viewing key. This shall be
/// The `ak` component of an Orchard Full Viewing key. This shall be
/// derived from the Spend Authorizing Key `ask`
#[derive(uniffi::Object)]
pub struct OrchardSpendValidatingKey {
Expand All @@ -328,8 +325,8 @@ impl OrchardSpendValidatingKey {
/// Deserialized the [`OrchardSpendValidatingKey`] into bytes for
/// backup purposes.
/// - Note: See [ZF FROST Book - Technical Details](https://frost.zfnd.org/zcash/technical-details.html)
/// to serialize use the `OrchardSpendValidatingKey::to_bytes`
/// constructor
/// to serialize use the `OrchardSpendValidatingKey::to_bytes`
/// constructor
#[uniffi::constructor]
pub fn from_bytes(bytes: Vec<u8>) -> Result<Arc<OrchardSpendValidatingKey>, OrchardKeyError> {
match SpendValidatingKey::from_bytes(&bytes) {
Expand All @@ -341,16 +338,15 @@ impl OrchardSpendValidatingKey {
/// Serialized the [`OrchardSpendValidatingKey`] into bytes for
/// backup purposes.
/// - Note: See [ZF FROST Book - Technical Details](https://frost.zfnd.org/zcash/technical-details.html)
/// to deserialize use the `OrchardSpendValidatingKey::from_bytes`
/// constructor
/// to deserialize use the `OrchardSpendValidatingKey::from_bytes`
/// constructor
pub fn to_bytes(&self) -> Vec<u8> {
self.key.to_bytes().to_vec()
}
}


/// The Orchard Nullifier Deriving Key component of an
/// Orchard full viewing key. This is intended for key backup
/// Orchard full viewing key. This is intended for key backup
/// purposes.
/// - Note: See [ZF FROST Book - Technical Details](https://frost.zfnd.org/zcash/technical-details.html)
#[derive(uniffi::Object)]
Expand Down Expand Up @@ -378,8 +374,8 @@ impl OrchardNullifierDerivingKey {
}

/// The `rivk` component of an Orchard Full Viewing Key.
/// This is intended for key backup purposes.
///- Note: See [ZF FROST Book - Technical Details](https://frost.zfnd.org/zcash/technical-details.html)
/// This is intended for key backup purposes.
/// - Note: See [ZF FROST Book - Technical Details](https://frost.zfnd.org/zcash/technical-details.html)
#[derive(uniffi::Object, Clone)]
pub struct OrchardCommitIvkRandomness {
rivk: CommitIvkRandomness,
Expand Down
2 changes: 1 addition & 1 deletion frost-uniffi-sdk/src/orchard/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
mod keys;
pub use self::keys::*;
pub use self::keys::*;
4 changes: 2 additions & 2 deletions frost-uniffi-sdk/src/participant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ impl FrostSignatureShare {
.map_err(|_| Error::DeserializationError)?;

// TODO: Do not define the underlying curve inside the function
SignatureShare::<E>::deserialize(bytes)
SignatureShare::<E>::deserialize(&bytes)
}

pub fn from_signature_share<C: Ciphersuite>(
Expand All @@ -138,7 +138,7 @@ impl FrostSignatureShare {
) -> Result<FrostSignatureShare, Error<C>> {
Ok(FrostSignatureShare {
identifier: ParticipantIdentifier::from_identifier(identifier)?,
data: share.serialize().as_ref().to_vec(),
data: share.serialize(),
})
}
}
Expand Down
8 changes: 5 additions & 3 deletions frost-uniffi-sdk/src/randomized/coordinator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ pub fn aggregate(
.into_randomizer::<E>()
.map_err(|_| CoordinationError::InvalidRandomizer)?;

frost::aggregate(
let signature = frost::aggregate(
&signing_package,
&shares,
&public_key_package,
Expand All @@ -67,8 +67,10 @@ pub fn aggregate(
)
.map_err(|e| CoordinationError::SignatureShareAggregationFailed {
message: e.to_string(),
})
.map(FrostSignature::from_signature)
})?;

FrostSignature::from_signature(signature)
.map_err(|_| CoordinationError::SigningPackageSerializationError)
}

#[uniffi::export]
Expand Down
10 changes: 3 additions & 7 deletions frost-uniffi-sdk/src/randomized/randomizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use std::sync::Arc;
use rand::thread_rng;
use reddsa::frost::redpallas as frost;

use crate::randomized::randomizer::frost::Randomizer;
use crate::{coordinator::FrostSigningPackage, FrostError, FrostPublicKeyPackage};
use frost::round2::Randomizer;
use frost::RandomizedParams;
use frost_core::{Ciphersuite, Error};
use uniffi;
Expand Down Expand Up @@ -77,18 +77,14 @@ pub fn from_hex_string(hex_string: String) -> Result<FrostRandomizer, FrostError
.try_into()
.map_err(|_| FrostError::DeserializationError)?;

let randomizer = frost::round2::Randomizer::deserialize(&buf).map_err(FrostError::map_err)?;
let randomizer = Randomizer::deserialize(&buf).map_err(FrostError::map_err)?;

FrostRandomizer::from_randomizer::<E>(randomizer).map_err(FrostError::map_err)
}

impl FrostRandomizer {
pub fn into_randomizer<C: Ciphersuite>(&self) -> Result<Randomizer, Error<E>> {
let raw_randomizer = &self.data[0..32]
.try_into()
.map_err(|_| Error::DeserializationError)?;

Randomizer::deserialize(raw_randomizer)
Randomizer::deserialize(&self.data)
}

pub fn from_randomizer<C: Ciphersuite>(
Expand Down
Loading

0 comments on commit 5703f7f

Please sign in to comment.