From 4f8a4a4a5bfe9e69dcb2c3e5ae2183955347dad5 Mon Sep 17 00:00:00 2001 From: emmorais Date: Mon, 15 Jul 2024 09:48:18 -0300 Subject: [PATCH 01/36] Create curve_point file --- src/auxinfo/info.rs | 2 +- src/auxinfo/output.rs | 2 +- src/auxinfo/participant.rs | 2 +- src/auxinfo/proof.rs | 2 +- src/curve_point.rs | 327 +++++++++++++++++++ src/keygen/keygen_commit.rs | 2 +- src/keygen/keyshare.rs | 5 +- src/keygen/output.rs | 5 +- src/keygen/participant.rs | 2 +- src/keyrefresh/input.rs | 2 +- src/keyrefresh/keyrefresh_commit.rs | 2 +- src/keyrefresh/keyshare.rs | 4 +- src/keyrefresh/participant.rs | 2 +- src/lib.rs | 1 + src/local_storage.rs | 2 +- src/paillier.rs | 6 +- src/presign/input.rs | 2 +- src/presign/participant.rs | 7 +- src/presign/record.rs | 5 +- src/presign/round_three.rs | 2 +- src/presign/round_two.rs | 2 +- src/protocol.rs | 6 +- src/ring_pedersen.rs | 3 +- src/sign/interactive_sign/participant.rs | 2 +- src/sign/non_interactive_sign/participant.rs | 4 +- src/utils.rs | 291 +---------------- src/zkp/piaffg.rs | 10 +- src/zkp/pienc.rs | 6 +- src/zkp/pifac.rs | 3 +- src/zkp/pilog.rs | 7 +- src/zkp/pimod.rs | 3 +- src/zkp/piprm.rs | 2 +- src/zkp/pisch.rs | 7 +- src/zkstar.rs | 6 +- 34 files changed, 393 insertions(+), 343 deletions(-) create mode 100644 src/curve_point.rs diff --git a/src/auxinfo/info.rs b/src/auxinfo/info.rs index c061d597..10a1614a 100644 --- a/src/auxinfo/info.rs +++ b/src/auxinfo/info.rs @@ -210,7 +210,7 @@ impl Debug for AuxInfoWitnesses { #[cfg(test)] mod tests { - use crate::{paillier::DecryptionKey, utils::testing::init_testing}; + use crate::{paillier::DecryptionKey, curve_point::testing::init_testing}; use super::{AuxInfoPrivate, AUXINFO_TAG}; diff --git a/src/auxinfo/output.rs b/src/auxinfo/output.rs index 35031e9a..2e6a21bc 100644 --- a/src/auxinfo/output.rs +++ b/src/auxinfo/output.rs @@ -103,7 +103,7 @@ impl Output { mod tests { use super::*; use crate::{ - paillier::DecryptionKey, ring_pedersen::VerifiedRingPedersen, utils::testing::init_testing, + paillier::DecryptionKey, ring_pedersen::VerifiedRingPedersen, curve_point::testing::init_testing, ParticipantConfig, }; diff --git a/src/auxinfo/participant.rs b/src/auxinfo/participant.rs index b9cd2697..c0d18af0 100644 --- a/src/auxinfo/participant.rs +++ b/src/auxinfo/participant.rs @@ -621,7 +621,7 @@ impl AuxInfoParticipant { #[cfg(test)] mod tests { use super::*; - use crate::{utils::testing::init_testing, Identifier, ParticipantConfig}; + use crate::{curve_point::testing::init_testing, Identifier, ParticipantConfig}; use rand::{CryptoRng, Rng, RngCore}; use std::collections::HashMap; diff --git a/src/auxinfo/proof.rs b/src/auxinfo/proof.rs index 01f178e5..37498950 100644 --- a/src/auxinfo/proof.rs +++ b/src/auxinfo/proof.rs @@ -198,7 +198,7 @@ impl AuxInfoProof { #[cfg(test)] mod tests { use super::*; - use crate::{paillier::prime_gen, protocol::SharedContext, utils::testing::init_testing}; + use crate::{paillier::prime_gen, protocol::SharedContext, curve_point::testing::init_testing}; use rand::{rngs::StdRng, Rng, SeedableRng}; fn random_auxinfo_proof( diff --git a/src/curve_point.rs b/src/curve_point.rs new file mode 100644 index 00000000..58d9fa22 --- /dev/null +++ b/src/curve_point.rs @@ -0,0 +1,327 @@ +// Copyright (c) Facebook, Inc. and its affiliates. +// Modifications Copyright (c) 2022-2023 Bolt Labs Holdings, Inc +// +// This source code is licensed under both the MIT license found in the +// LICENSE-MIT file in the root directory of this source tree and the Apache +// License, Version 2.0 found in the LICENSE-APACHE file in the root directory +// of this source tree. + +use crate::utils::CRYPTOGRAPHIC_RETRY_MAX; +use crate::errors::{CallerError, InternalError, Result}; +use generic_array::GenericArray; +use k256::{ + elliptic_curve::{ + bigint::Encoding, + group::{ff::PrimeField, GroupEncoding}, + point::AffineCoordinates, + AffinePoint, Curve, + }, + EncodedPoint, FieldBytes, Scalar, Secp256k1, +}; +use libpaillier::unknown_order::BigNumber; +use rand::{CryptoRng, RngCore}; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; +use std::fmt::Debug; +use tracing::error; +use zeroize::Zeroize; + +/// Wrapper around k256::ProjectivePoint so that we can define our own +/// serialization/deserialization for it +/// +/// Note that this type derives [`Debug`]; if a [`CurvePoint`] is used in a +/// private type, `Debug` should be manually implemented with the field of this +/// type explicitly redacted! +#[derive(Eq, PartialEq, Debug, Clone, Copy, Zeroize)] +pub(crate) struct CurvePoint(k256::ProjectivePoint); + +impl From for EncodedPoint { + fn from(value: CurvePoint) -> EncodedPoint { + value.0.to_affine().into() + } +} + +impl AsRef for CurvePoint { + fn as_ref(&self) -> &CurvePoint { + self + } +} + +impl CurvePoint { + pub fn x_affine(&self) -> FieldBytes { + self.0.to_affine().x() + } + #[cfg(test)] + pub(crate) fn random(rng: impl RngCore) -> Self { + use k256::{elliptic_curve::Group, ProjectivePoint}; + let random_point = ProjectivePoint::random(rng); + CurvePoint(random_point) + } + pub(crate) const GENERATOR: Self = CurvePoint(k256::ProjectivePoint::GENERATOR); + /// The identity point, used to initialize the aggregation of a verification + /// key + pub const IDENTITY: Self = CurvePoint(k256::ProjectivePoint::IDENTITY); + + /// Multiply `self` by a [`BigNumber`] point, which is first converted to + /// the secp256k1 [`Scalar`] field (taken mod `q`, where `q` is the + /// order of the curve). + /// + /// Note: This method ends up cloning the `point` value in the process of + /// converting it. This may be insecure if the point contains private + /// data. + pub(crate) fn multiply_by_bignum(&self, point: &BigNumber) -> Result { + //Ok(self.multiply_by_scalar(&bn_to_scalar::(point)?)) + Ok(self.multiply_by_scalar(&bn_to_scalar(point)?)) + } + + pub(crate) fn multiply_by_scalar(&self, point: &Scalar) -> Self { + Self(self.0 * point) + } + + /// Serialize the `CurvePoint` as an affine-encoded secp256k1 byte array. + pub(crate) fn to_bytes(self) -> Vec { + let mut generic_array = AffinePoint::::from(self.0).to_bytes(); + let bytes = generic_array.to_vec(); + generic_array.zeroize(); + bytes + } + + pub(crate) fn try_from_bytes(bytes: &[u8]) -> Result { + let mut fixed_len_bytes: [u8; 33] = bytes.try_into().map_err(|_| { + error!("Failed to encode bytes as a curve point"); + CallerError::DeserializationFailed + })?; + + let point: Option> = + AffinePoint::::from_bytes(&fixed_len_bytes.into()).into(); + fixed_len_bytes.zeroize(); + + match point { + Some(point) => Ok(Self(point.into())), + None => { + error!("Failed to encode bytes as a curve point"); + Err(CallerError::DeserializationFailed)? + } + } + } +} + +impl std::ops::Add for CurvePoint { + type Output = Self; + + fn add(self, rhs: Self) -> Self::Output { + Self(self.0 + rhs.0) + } +} + +impl From for CurvePoint { + fn from(p: k256::ProjectivePoint) -> Self { + Self(p) + } +} + +impl Serialize for CurvePoint { + fn serialize(&self, serializer: S) -> std::result::Result + where + S: Serializer, + { + let afp = AffinePoint::::from(self.0); + afp.serialize(serializer) + } +} + +impl<'de> Deserialize<'de> for CurvePoint { + fn deserialize(deserializer: D) -> std::result::Result + where + D: Deserializer<'de>, + { + let p = AffinePoint::::deserialize(deserializer)?; + Ok(Self(p.into())) + } +} + +#[cfg(test)] +mod curve_point_tests { + use crate::curve_point::{testing::init_testing, CurvePoint}; + use k256::elliptic_curve::Group; + + #[test] + fn curve_point_byte_conversion_works() { + let rng = &mut init_testing(); + let point = CurvePoint(k256::ProjectivePoint::random(rng)); + let bytes = point.to_bytes(); + let reconstructed = CurvePoint::try_from_bytes(&bytes).unwrap(); + assert_eq!(point, reconstructed); + } +} + +/// Generate a random `BigNumber` that is in the multiplicative group of +/// integers modulo `n`. +/// +/// Note: In this application, `n` is typically the product of two primes. If +/// the drawn element is not coprime with `n` and is not `0 mod n`, then the +/// caller has accidentally stumbled upon the factorization of `n`! +/// This is a security issue when `n` is someone else's Paillier modulus, but +/// the chance of this happening is basically 0 and we drop the element anyway. +pub(crate) fn random_bn_in_z_star( + rng: &mut R, + n: &BigNumber, +) -> Result { + // Try up to `CRYPTOGRAPHIC_RETRY_MAX` times to draw a non-zero element. This + // should virtually never error, though. + std::iter::repeat_with(|| BigNumber::from_rng(n, rng)) + .take(CRYPTOGRAPHIC_RETRY_MAX) + .find(|result| result != &BigNumber::zero() && result.gcd(n) == BigNumber::one()) + .ok_or(InternalError::CallingApplicationMistake( + CallerError::RetryFailed, + )) +} + +pub(crate) trait CurveTrait { + fn generator() -> CurvePoint; + fn identity() -> CurvePoint; + + /// return the order of the curve + fn curve_order() -> BigNumber; +} + +/// Implement the CurveTrait for the CurvePoint +impl CurveTrait for CurvePoint { + fn generator() -> CurvePoint { + CurvePoint::GENERATOR + } + + fn identity() -> CurvePoint { + CurvePoint::IDENTITY + } + + fn curve_order() -> BigNumber { + k256_order() + } +} + +// Returns x: BigNumber as a k256::Scalar mod k256_order +//pub(crate) fn bn_to_scalar(x: &BigNumber) -> Result { +pub(crate) fn bn_to_scalar(x: &BigNumber) -> Result { + // Take (mod q) + //let order = C::curve_order(); + // Call curve_order() to get the order of the curve + let order = k256_order(); + + let x_modded = x % order; + let bytes = x_modded.to_bytes(); + + let mut slice = vec![0u8; 32 - bytes.len()]; + slice.extend_from_slice(&bytes); + let mut ret: k256::Scalar = Option::from(k256::Scalar::from_repr( + GenericArray::clone_from_slice(&slice), + )) + .ok_or_else(|| { + error!("Failed to convert BigNumber into k256::Scalar"); + InternalError::InternalInvariantFailed + })?; + + // Make sure to negate the scalar if the original input was negative + if x < &BigNumber::zero() { + ret = ret.negate(); + } + + Ok(ret) +} + +pub(crate) fn k256_order() -> BigNumber { + // Set order = q + let order_bytes: [u8; 32] = k256::Secp256k1::ORDER.to_be_bytes(); + BigNumber::from_slice(order_bytes) +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::utils::random_plusminus_by_size; + use crate::curve_point::testing::init_testing; + + #[test] + fn test_random_bn_in_range() { + let mut rng = init_testing(); + // Statistical tests -- should generate random numbers that are long enough + let mut max_len = 0; + let num_bytes = 100; + + for _ in 0..1000 { + let bn = random_plusminus_by_size(&mut rng, num_bytes * 8); + let len = bn.to_bytes().len(); + if max_len < len { + max_len = len; + } + } + + assert!(max_len > num_bytes - 2); + } + + #[test] + fn test_bn_to_scalar_neg() { + let _rng = init_testing(); + let neg1 = BigNumber::zero() - BigNumber::one(); + + //let scalar = bn_to_scalar::(&neg1).unwrap(); + let scalar = bn_to_scalar(&neg1).unwrap(); + assert_eq!(k256::Scalar::ZERO, scalar.add(&k256::Scalar::ONE)); + } +} + +//////////////////////////// +// Test Utility Functions // +//////////////////////////// + +/// Returns an rng to be used for testing. This will print the rng seed +/// to stderr so that if a test fails, the failing seed can be recovered +/// and used for debugging. +#[cfg(test)] +pub(crate) mod testing { + use rand::{ + rngs::{OsRng, StdRng}, + Rng, SeedableRng, + }; + use tracing_subscriber::{ + filter::Targets, layer::SubscriberExt, util::SubscriberInitExt, EnvFilter, Layer, + }; + + /// Initialize any fields necessary for our tests. This should be called at + /// the top of all our tests. This function is idempotent. + /// + /// This will print the rng seed to stderr so that if a test fails, the + /// failing seed can be recovered and used for debugging. + pub(crate) fn init_testing() -> StdRng { + let mut seeder = OsRng; + let seed = seeder.gen(); + eprintln!( + "To re-run test with the same randomness, use init_testing_with_seed() with the following seed:" + ); + eprintln!("\t{seed:?}"); + StdRng::from_seed(seed) + } + + /// A seeded version of init_testing. Additionally, turns on logging by + /// default. + #[allow(unused)] + pub(crate) fn init_testing_with_seed(seed: [u8; 32]) -> StdRng { + let logging_level = EnvFilter::from_default_env() + .max_level_hint() + .unwrap() + .into_level() + .unwrap(); + + // Only capture logging events from tss_ecdsa crate. + let targets = Targets::new().with_target("tss_ecdsa", logging_level); + let stdout_layer = tracing_subscriber::fmt::layer() + .pretty() + .with_filter(targets); + + // It's okay if this fails. It just means logging has already been set up for + // this thread. + let _ = tracing_subscriber::registry().with(stdout_layer).try_init(); + + // Return RNG + StdRng::from_seed(seed) + } +} diff --git a/src/keygen/keygen_commit.rs b/src/keygen/keygen_commit.rs index eeb49f07..557a258b 100644 --- a/src/keygen/keygen_commit.rs +++ b/src/keygen/keygen_commit.rs @@ -11,7 +11,7 @@ use crate::{ keygen::keyshare::KeySharePublic, messages::{KeygenMessageType, Message, MessageType}, protocol::{Identifier, ParticipantIdentifier}, - utils::CurvePoint, + curve_point::CurvePoint, zkp::pisch::PiSchPrecommit, }; use merlin::Transcript; diff --git a/src/keygen/keyshare.rs b/src/keygen/keyshare.rs index 47793ab5..28144c8b 100644 --- a/src/keygen/keyshare.rs +++ b/src/keygen/keyshare.rs @@ -8,7 +8,8 @@ use crate::{ errors::{CallerError, Result}, - utils::{k256_order, CurvePoint, ParseBytes}, + curve_point::{k256_order, CurvePoint}, + utils::ParseBytes, ParticipantIdentifier, }; use libpaillier::unknown_order::BigNumber; @@ -188,7 +189,7 @@ impl AsRef for KeySharePublic { mod tests { use crate::{ keygen::{keyshare::KEYSHARE_TAG, KeySharePrivate}, - utils::{k256_order, testing::init_testing}, + curve_point::{k256_order, testing::init_testing}, }; #[test] diff --git a/src/keygen/output.rs b/src/keygen/output.rs index 0406ad50..9250090e 100644 --- a/src/keygen/output.rs +++ b/src/keygen/output.rs @@ -10,7 +10,7 @@ use std::collections::HashSet; use crate::{ errors::{CallerError, InternalError, Result}, keygen::keyshare::{KeySharePrivate, KeySharePublic}, - utils::CurvePoint, + curve_point::CurvePoint, ParticipantIdentifier, }; @@ -129,7 +129,8 @@ impl Output { #[cfg(test)] mod tests { use super::*; - use crate::{utils::testing::init_testing, ParticipantConfig, ParticipantIdentifier}; + use crate::curve_point::testing::init_testing; + use crate::{ParticipantConfig, ParticipantIdentifier}; use rand::{CryptoRng, Rng, RngCore}; impl Output { diff --git a/src/keygen/participant.rs b/src/keygen/participant.rs index 59c7acaa..528e7791 100644 --- a/src/keygen/participant.rs +++ b/src/keygen/participant.rs @@ -592,7 +592,7 @@ fn schnorr_proof_transcript( mod tests { use super::*; use crate::{ - utils::{testing::init_testing, CurvePoint}, + curve_point::{testing::init_testing, CurvePoint}, Identifier, ParticipantConfig, }; use rand::{CryptoRng, Rng, RngCore}; diff --git a/src/keyrefresh/input.rs b/src/keyrefresh/input.rs index b0cba89a..89b2e4e7 100644 --- a/src/keyrefresh/input.rs +++ b/src/keyrefresh/input.rs @@ -125,7 +125,7 @@ mod test { errors::{CallerError, InternalError, Result}, keygen, keyrefresh::KeyrefreshParticipant, - utils::testing::init_testing, + curve_point::testing::init_testing, Identifier, ParticipantConfig, ParticipantIdentifier, ProtocolParticipant, }; diff --git a/src/keyrefresh/keyrefresh_commit.rs b/src/keyrefresh/keyrefresh_commit.rs index 69689186..a2f00ecf 100644 --- a/src/keyrefresh/keyrefresh_commit.rs +++ b/src/keyrefresh/keyrefresh_commit.rs @@ -11,7 +11,7 @@ use crate::{ keyrefresh::keyshare::KeyUpdatePublic, messages::{KeyrefreshMessageType, Message, MessageType}, protocol::{Identifier, ParticipantIdentifier}, - utils::CurvePoint, + curve_point::CurvePoint, }; use merlin::Transcript; use rand::{CryptoRng, RngCore}; diff --git a/src/keyrefresh/keyshare.rs b/src/keyrefresh/keyshare.rs index 505c4c02..307d39a0 100644 --- a/src/keyrefresh/keyshare.rs +++ b/src/keyrefresh/keyshare.rs @@ -10,7 +10,7 @@ use crate::{ errors::{CallerError, InternalError, Result}, keygen::{KeySharePrivate, KeySharePublic}, paillier::{Ciphertext, DecryptionKey, EncryptionKey}, - utils::{k256_order, CurvePoint}, + curve_point::{k256_order, CurvePoint}, ParticipantIdentifier, }; use libpaillier::unknown_order::BigNumber; @@ -177,7 +177,7 @@ mod tests { use super::*; use crate::{ auxinfo, - utils::{k256_order, testing::init_testing}, + curve_point::{k256_order, testing::init_testing}, }; use rand::rngs::StdRng; diff --git a/src/keyrefresh/participant.rs b/src/keyrefresh/participant.rs index 7ca6b010..ef6af133 100644 --- a/src/keyrefresh/participant.rs +++ b/src/keyrefresh/participant.rs @@ -874,7 +874,7 @@ mod tests { use crate::{ auxinfo, keygen, keyrefresh::input::Input, - utils::{testing::init_testing, CurvePoint}, + curve_point::{testing::init_testing, CurvePoint}, Identifier, ParticipantConfig, }; use rand::{CryptoRng, Rng, RngCore}; diff --git a/src/lib.rs b/src/lib.rs index 8e48edac..91b45e0e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -221,6 +221,7 @@ mod protocol; mod ring_pedersen; pub mod sign; mod utils; +mod curve_point; mod zkp; mod zkstar; diff --git a/src/local_storage.rs b/src/local_storage.rs index c2c33acb..ae2aef76 100644 --- a/src/local_storage.rs +++ b/src/local_storage.rs @@ -188,7 +188,7 @@ impl LocalStorage { #[cfg(test)] mod tests { use super::*; - use crate::{message_queue::MessageQueue, utils::testing::init_testing}; + use crate::{message_queue::MessageQueue, curve_point::testing::init_testing}; #[test] fn local_storage_store_once() -> Result<()> { diff --git a/src/paillier.rs b/src/paillier.rs index d7130af6..2ca3c8b9 100644 --- a/src/paillier.rs +++ b/src/paillier.rs @@ -7,7 +7,8 @@ use crate::{ parameters::PRIME_BITS, - utils::{modpow, random_bn_in_z_star, CRYPTOGRAPHIC_RETRY_MAX}, + curve_point::random_bn_in_z_star, + utils::{modpow, CRYPTOGRAPHIC_RETRY_MAX}, }; use libpaillier::unknown_order::BigNumber; use rand::{CryptoRng, RngCore}; @@ -458,7 +459,8 @@ mod test { use crate::{ paillier::Ciphertext, parameters::PRIME_BITS, - utils::{random_plusminus, testing::init_testing}, + curve_point::testing::init_testing, + utils::random_plusminus, }; use super::{prime_gen, DecryptionKey, EncryptionKey}; diff --git a/src/presign/input.rs b/src/presign/input.rs index c127cabc..d39524f9 100644 --- a/src/presign/input.rs +++ b/src/presign/input.rs @@ -161,7 +161,7 @@ mod test { auxinfo, errors::{CallerError, InternalError, Result}, keygen, - utils::testing::init_testing, + curve_point::testing::init_testing, Identifier, ParticipantConfig, ParticipantIdentifier, PresignParticipant, ProtocolParticipant, }; diff --git a/src/presign/participant.rs b/src/presign/participant.rs index 3963c0ac..1394ed2b 100644 --- a/src/presign/participant.rs +++ b/src/presign/participant.rs @@ -24,7 +24,8 @@ use crate::{ }, protocol::{ParticipantIdentifier, ProtocolType, SharedContext}, run_only_once, - utils::{bn_to_scalar, k256_order, random_plusminus_by_size, random_positive_bn, CurvePoint}, + curve_point::{bn_to_scalar, k256_order, CurvePoint}, + utils::{random_plusminus_by_size, random_positive_bn}, zkp::{ piaffg::{PiAffgInput, PiAffgProof, PiAffgSecret}, pienc::{PiEncInput, PiEncProof, PiEncSecret}, @@ -1229,7 +1230,7 @@ mod test { messages::{Message, MessageType, PresignMessageType}, participant::{ProcessOutcome, Status}, presign::{Input, PresignRecord}, - utils::{self, testing::init_testing, CurvePoint}, + curve_point::{self, testing::init_testing, CurvePoint}, Identifier, ParticipantConfig, ParticipantIdentifier, ProtocolParticipant, }; @@ -1307,7 +1308,7 @@ mod test { .map(|output| output.private_key_share()) .fold(BigNumber::zero(), |sum, key_share| sum + key_share.as_ref()); // Converting to scalars automatically gets us the mod q - assert_eq!(masked_key, utils::bn_to_scalar(&secret_key).unwrap() * mask); + assert_eq!(masked_key, curve_point::bn_to_scalar(&secret_key).unwrap() * mask); } #[test] diff --git a/src/presign/record.rs b/src/presign/record.rs index 0054d1fa..52d07c7c 100644 --- a/src/presign/record.rs +++ b/src/presign/record.rs @@ -13,7 +13,8 @@ use crate::{ Result, }, presign::round_three::{Private as RoundThreePrivate, Public as RoundThreePublic}, - utils::{bn_to_scalar, CurvePoint, ParseBytes}, + curve_point::{bn_to_scalar, CurvePoint}, + utils::ParseBytes, }; use k256::{elliptic_curve::PrimeField, Scalar}; use std::fmt::Debug; @@ -255,7 +256,7 @@ mod tests { use crate::{ keygen, presign::{participant::presign_record_set_is_valid, record::RECORD_TAG}, - utils::{bn_to_scalar, testing::init_testing, CurvePoint}, + curve_point::{bn_to_scalar, testing::init_testing, CurvePoint}, ParticipantConfig, PresignRecord, }; diff --git a/src/presign/round_three.rs b/src/presign/round_three.rs index b648cdd9..05f7f211 100644 --- a/src/presign/round_three.rs +++ b/src/presign/round_three.rs @@ -15,7 +15,7 @@ use crate::{ round_one::PublicBroadcast as RoundOnePublicBroadcast, round_two::{Private as RoundTwoPrivate, Public as RoundTwoPublic}, }, - utils::CurvePoint, + curve_point::CurvePoint, zkp::{ pilog::{CommonInput, PiLogProof}, Proof, diff --git a/src/presign/round_two.rs b/src/presign/round_two.rs index 422d22b0..02e9b920 100644 --- a/src/presign/round_two.rs +++ b/src/presign/round_two.rs @@ -16,7 +16,7 @@ use crate::{ participant::ParticipantPresignContext, round_one::{Private as RoundOnePrivate, PublicBroadcast as RoundOnePublicBroadcast}, }, - utils::CurvePoint, + curve_point::CurvePoint, zkp::{ piaffg::{PiAffgInput, PiAffgProof}, pilog::{CommonInput, PiLogProof}, diff --git a/src/protocol.rs b/src/protocol.rs index 14a88092..c4edd702 100644 --- a/src/protocol.rs +++ b/src/protocol.rs @@ -15,7 +15,7 @@ use crate::{ messages::{Message, MessageType}, participant::{InnerProtocolParticipant, ProtocolParticipant, Status}, protocol::participant_config::ParticipantConfig, - utils::{k256_order, CurvePoint}, + curve_point::{k256_order, CurvePoint}, zkp::ProofContext, }; use libpaillier::unknown_order::BigNumber; @@ -336,7 +336,7 @@ pub(crate) mod participant_config { #[cfg(test)] mod tests { use super::*; - use crate::utils::testing::init_testing; + use crate::curve_point::testing::init_testing; #[test] fn participant_config_must_have_at_least_two_participants() { @@ -608,7 +608,7 @@ mod tests { participant::Status, presign, sign::{self, InteractiveSignParticipant, SignParticipant}, - utils::testing::init_testing, + curve_point::testing::init_testing, PresignParticipant, }; use k256::ecdsa::signature::DigestVerifier; diff --git a/src/ring_pedersen.rs b/src/ring_pedersen.rs index 1aefd9a5..79cc8fcc 100644 --- a/src/ring_pedersen.rs +++ b/src/ring_pedersen.rs @@ -330,7 +330,8 @@ impl RingPedersen { #[cfg(test)] mod tests { - use crate::utils::{random_plusminus_by_size, testing::init_testing}; + use crate::curve_point::testing::init_testing; + use crate::utils::random_plusminus_by_size; use super::*; diff --git a/src/sign/interactive_sign/participant.rs b/src/sign/interactive_sign/participant.rs index 01273383..fb7ea250 100644 --- a/src/sign/interactive_sign/participant.rs +++ b/src/sign/interactive_sign/participant.rs @@ -352,7 +352,7 @@ mod tests { messages::{Message, MessageType}, participant::ProcessOutcome, sign::Signature, - utils::testing::init_testing, + curve_point::testing::init_testing, Identifier, ParticipantConfig, ParticipantIdentifier, ProtocolParticipant, }; diff --git a/src/sign/non_interactive_sign/participant.rs b/src/sign/non_interactive_sign/participant.rs index 737178be..f008dea4 100644 --- a/src/sign/non_interactive_sign/participant.rs +++ b/src/sign/non_interactive_sign/participant.rs @@ -27,7 +27,7 @@ use crate::{ protocol::{ProtocolType, SharedContext}, run_only_once, sign::{non_interactive_sign::share::SignatureShare, Signature}, - utils::CurvePoint, + curve_point::CurvePoint, zkp::ProofContext, Identifier, ParticipantConfig, ParticipantIdentifier, PresignRecord, ProtocolParticipant, }; @@ -449,7 +449,7 @@ mod test { participant::{ProcessOutcome, Status}, presign::PresignRecord, sign::{self, Signature}, - utils::{bn_to_scalar, testing::init_testing}, + curve_point::{bn_to_scalar, testing::init_testing}, Identifier, ParticipantConfig, ProtocolParticipant, }; diff --git a/src/utils.rs b/src/utils.rs index 90844703..bfcb46c8 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -6,156 +6,16 @@ // License, Version 2.0 found in the LICENSE-APACHE file in the root directory // of this source tree. +use crate::curve_point::k256_order; use crate::errors::{CallerError, InternalError, Result}; -use generic_array::GenericArray; -use k256::{ - elliptic_curve::{ - bigint::Encoding, - group::{ff::PrimeField, GroupEncoding}, - point::AffineCoordinates, - AffinePoint, Curve, - }, - EncodedPoint, FieldBytes, Scalar, Secp256k1, -}; use libpaillier::unknown_order::BigNumber; use merlin::Transcript; use rand::{CryptoRng, Rng, RngCore}; -use serde::{Deserialize, Deserializer, Serialize, Serializer}; -use std::fmt::Debug; use tracing::error; -use zeroize::{Zeroize, Zeroizing}; +use zeroize::Zeroize; pub(crate) const CRYPTOGRAPHIC_RETRY_MAX: usize = 500usize; -/// Wrapper around k256::ProjectivePoint so that we can define our own -/// serialization/deserialization for it -/// -/// Note that this type derives [`Debug`]; if a [`CurvePoint`] is used in a -/// private type, `Debug` should be manually implemented with the field of this -/// type explicitly redacted! -#[derive(Eq, PartialEq, Debug, Clone, Copy, Zeroize)] -pub(crate) struct CurvePoint(k256::ProjectivePoint); - -impl From for EncodedPoint { - fn from(value: CurvePoint) -> EncodedPoint { - value.0.to_affine().into() - } -} - -impl AsRef for CurvePoint { - fn as_ref(&self) -> &CurvePoint { - self - } -} - -impl CurvePoint { - pub fn x_affine(&self) -> FieldBytes { - self.0.to_affine().x() - } - #[cfg(test)] - pub(crate) fn random(rng: impl RngCore) -> Self { - use k256::{elliptic_curve::Group, ProjectivePoint}; - let random_point = ProjectivePoint::random(rng); - CurvePoint(random_point) - } - pub(crate) const GENERATOR: Self = CurvePoint(k256::ProjectivePoint::GENERATOR); - /// The identity point, used to initialize the aggregation of a verification - /// key - pub const IDENTITY: Self = CurvePoint(k256::ProjectivePoint::IDENTITY); - - /// Multiply `self` by a [`BigNumber`] point, which is first converted to - /// the secp256k1 [`Scalar`] field (taken mod `q`, where `q` is the - /// order of the curve). - /// - /// Note: This method ends up cloning the `point` value in the process of - /// converting it. This may be insecure if the point contains private - /// data. - pub(crate) fn multiply_by_bignum(&self, point: &BigNumber) -> Result { - let s = Zeroizing::new(bn_to_scalar(point)?); - let p = self.multiply_by_scalar(&s); - Ok(p) - } - - pub(crate) fn multiply_by_scalar(&self, point: &Scalar) -> Self { - Self(self.0 * point) - } - - /// Serialize the `CurvePoint` as an affine-encoded secp256k1 byte array. - pub(crate) fn to_bytes(self) -> Vec { - let mut generic_array = AffinePoint::::from(self.0).to_bytes(); - let bytes = generic_array.to_vec(); - generic_array.zeroize(); - bytes - } - - pub(crate) fn try_from_bytes(bytes: &[u8]) -> Result { - let mut fixed_len_bytes: [u8; 33] = bytes.try_into().map_err(|_| { - error!("Failed to encode bytes as a curve point"); - CallerError::DeserializationFailed - })?; - - let point: Option> = - AffinePoint::::from_bytes(&fixed_len_bytes.into()).into(); - fixed_len_bytes.zeroize(); - - match point { - Some(point) => Ok(Self(point.into())), - None => { - error!("Failed to encode bytes as a curve point"); - Err(CallerError::DeserializationFailed)? - } - } - } -} - -impl std::ops::Add for CurvePoint { - type Output = Self; - - fn add(self, rhs: Self) -> Self::Output { - Self(self.0 + rhs.0) - } -} - -impl From for CurvePoint { - fn from(p: k256::ProjectivePoint) -> Self { - Self(p) - } -} - -impl Serialize for CurvePoint { - fn serialize(&self, serializer: S) -> std::result::Result - where - S: Serializer, - { - let afp = AffinePoint::::from(self.0); - afp.serialize(serializer) - } -} - -impl<'de> Deserialize<'de> for CurvePoint { - fn deserialize(deserializer: D) -> std::result::Result - where - D: Deserializer<'de>, - { - let p = AffinePoint::::deserialize(deserializer)?; - Ok(Self(p.into())) - } -} - -#[cfg(test)] -mod curve_point_tests { - use crate::utils::{testing::init_testing, CurvePoint}; - use k256::elliptic_curve::Group; - - #[test] - fn curve_point_byte_conversion_works() { - let rng = &mut init_testing(); - let point = CurvePoint(k256::ProjectivePoint::random(rng)); - let bytes = point.to_bytes(); - let reconstructed = CurvePoint::try_from_bytes(&bytes).unwrap(); - assert_eq!(point, reconstructed); - } -} /// Helper type for parsing byte array into slices. /// @@ -303,7 +163,7 @@ pub(crate) fn plusminus_challenge_from_transcript( }) } -/// Derive a deterministic pseduorandom value in `[0, n)` from the +/// Derive a deterministic pseudorandom value in `[0, n)` from the /// [`Transcript`]. pub(crate) fn positive_challenge_from_transcript( transcript: &mut Transcript, @@ -323,148 +183,3 @@ pub(crate) fn positive_challenge_from_transcript( } Err(CallerError::RetryFailed)? } - -/// Generate a random `BigNumber` that is in the multiplicative group of -/// integers modulo `n`. -/// -/// Note: In this application, `n` is typically the product of two primes. If -/// the drawn element is not coprime with `n` and is not `0 mod n`, then the -/// caller has accidentally stumbled upon the factorization of `n`! -/// This is a security issue when `n` is someone else's Paillier modulus, but -/// the chance of this happening is basically 0 and we drop the element anyway. -pub(crate) fn random_bn_in_z_star( - rng: &mut R, - n: &BigNumber, -) -> Result { - // Try up to `CRYPTOGRAPHIC_RETRY_MAX` times to draw a non-zero element. This - // should virtually never error, though. - std::iter::repeat_with(|| BigNumber::from_rng(n, rng)) - .take(CRYPTOGRAPHIC_RETRY_MAX) - .find(|result| result != &BigNumber::zero() && result.gcd(n) == BigNumber::one()) - .ok_or(InternalError::CallingApplicationMistake( - CallerError::RetryFailed, - )) -} - -// Returns x: BigNumber as a k256::Scalar mod k256_order -pub(crate) fn bn_to_scalar(x: &BigNumber) -> Result { - // Take (mod q) - let order = k256_order(); - - let x_modded = x % order; - - let bytes = Zeroizing::new(x_modded.to_bytes()); - let mut slice = Zeroizing::new(vec![0u8; 32 - bytes.len()]); - slice.extend_from_slice(&bytes); - - let mut ret: k256::Scalar = Option::from(k256::Scalar::from_repr( - GenericArray::clone_from_slice(&slice), - )) - .ok_or_else(|| { - error!("Failed to convert BigNumber into k256::Scalar"); - InternalError::InternalInvariantFailed - })?; - - // Make sure to negate the scalar if the original input was negative - if x < &BigNumber::zero() { - ret = ret.negate(); - } - - Ok(ret) -} - -pub(crate) fn k256_order() -> BigNumber { - // Set order = q - let order_bytes: [u8; 32] = k256::Secp256k1::ORDER.to_be_bytes(); - BigNumber::from_slice(order_bytes) -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::utils::testing::init_testing; - - #[test] - fn test_random_bn_in_range() { - let mut rng = init_testing(); - // Statistical tests -- should generate random numbers that are long enough - let mut max_len = 0; - let num_bytes = 100; - - for _ in 0..1000 { - let bn = random_plusminus_by_size(&mut rng, num_bytes * 8); - let len = bn.to_bytes().len(); - if max_len < len { - max_len = len; - } - } - - assert!(max_len > num_bytes - 2); - } - - #[test] - fn test_bn_to_scalar_neg() { - let _rng = init_testing(); - let neg1 = BigNumber::zero() - BigNumber::one(); - - let scalar = bn_to_scalar(&neg1).unwrap(); - assert_eq!(k256::Scalar::ZERO, scalar.add(&k256::Scalar::ONE)); - } -} - -//////////////////////////// -// Test Utility Functions // -//////////////////////////// - -/// Returns an rng to be used for testing. This will print the rng seed -/// to stderr so that if a test fails, the failing seed can be recovered -/// and used for debugging. -#[cfg(test)] -pub(crate) mod testing { - use rand::{ - rngs::{OsRng, StdRng}, - Rng, SeedableRng, - }; - use tracing_subscriber::{ - filter::Targets, layer::SubscriberExt, util::SubscriberInitExt, EnvFilter, Layer, - }; - - /// Initialize any fields necessary for our tests. This should be called at - /// the top of all our tests. This function is idempotent. - /// - /// This will print the rng seed to stderr so that if a test fails, the - /// failing seed can be recovered and used for debugging. - pub(crate) fn init_testing() -> StdRng { - let mut seeder = OsRng; - let seed = seeder.gen(); - eprintln!( - "To re-run test with the same randomness, use init_testing_with_seed() with the following seed:" - ); - eprintln!("\t{seed:?}"); - StdRng::from_seed(seed) - } - - /// A seeded version of init_testing. Additionally, turns on logging by - /// default. - #[allow(unused)] - pub(crate) fn init_testing_with_seed(seed: [u8; 32]) -> StdRng { - let logging_level = EnvFilter::from_default_env() - .max_level_hint() - .unwrap() - .into_level() - .unwrap(); - - // Only capture logging events from tss_ecdsa crate. - let targets = Targets::new().with_target("tss_ecdsa", logging_level); - let stdout_layer = tracing_subscriber::fmt::layer() - .pretty() - .with_filter(targets); - - // It's okay if this fails. It just means logging has already been set up for - // this thread. - let _ = tracing_subscriber::registry().with(stdout_layer).try_init(); - - // Return RNG - StdRng::from_seed(seed) - } -} diff --git a/src/zkp/piaffg.rs b/src/zkp/piaffg.rs index 5fa7a247..cb02f526 100644 --- a/src/zkp/piaffg.rs +++ b/src/zkp/piaffg.rs @@ -44,7 +44,7 @@ use crate::{ parameters::{ELL, ELL_PRIME, EPSILON}, ring_pedersen::{Commitment, MaskedRandomness, VerifiedRingPedersen}, utils::{ - self, plusminus_challenge_from_transcript, random_plusminus_by_size, within_bound_by_size, + plusminus_challenge_from_transcript, random_plusminus_by_size, within_bound_by_size, }, zkp::{Proof, ProofContext}, }; @@ -54,7 +54,7 @@ use rand::{CryptoRng, RngCore}; use serde::{Deserialize, Serialize}; use std::fmt::Debug; use tracing::error; -use utils::CurvePoint; +use crate::curve_point::CurvePoint; /// Zero-knowledge proof of knowledge of a Paillier affine operation with a /// group commitment where the encrypted and committed values are in a given @@ -549,10 +549,8 @@ mod tests { use super::*; use crate::{ paillier::DecryptionKey, - utils::{ - k256_order, random_plusminus, random_plusminus_by_size_with_minimum, - testing::init_testing, - }, + curve_point::{k256_order, testing::init_testing}, + utils::{random_plusminus, random_plusminus_by_size_with_minimum}, zkp::BadContext, }; use rand::{rngs::StdRng, Rng, SeedableRng}; diff --git a/src/zkp/pienc.rs b/src/zkp/pienc.rs index 66f4aaa6..797320cf 100644 --- a/src/zkp/pienc.rs +++ b/src/zkp/pienc.rs @@ -294,10 +294,8 @@ mod tests { use super::*; use crate::{ paillier::DecryptionKey, - utils::{ - k256_order, random_plusminus, random_plusminus_by_size_with_minimum, - random_positive_bn, testing::init_testing, - }, + curve_point::{k256_order, testing::init_testing}, + utils::{random_plusminus, random_plusminus_by_size_with_minimum, random_positive_bn}, zkp::BadContext, }; use rand::{rngs::StdRng, Rng, SeedableRng}; diff --git a/src/zkp/pifac.rs b/src/zkp/pifac.rs index a4ed215b..9b174bc8 100644 --- a/src/zkp/pifac.rs +++ b/src/zkp/pifac.rs @@ -333,7 +333,8 @@ fn sqrt(num: &BigNumber) -> BigNumber { mod tests { use crate::{ paillier::prime_gen, - utils::{k256_order, random_positive_bn, testing::init_testing}, + curve_point::{k256_order, testing::init_testing}, + utils::random_positive_bn, zkp::BadContext, }; use rand::{prelude::StdRng, Rng, SeedableRng}; diff --git a/src/zkp/pilog.rs b/src/zkp/pilog.rs index 86e071ca..28e73a93 100644 --- a/src/zkp/pilog.rs +++ b/src/zkp/pilog.rs @@ -23,7 +23,7 @@ use crate::{ parameters::{ELL, EPSILON}, ring_pedersen::{Commitment, MaskedRandomness, RingPedersen}, utils::{ - self, plusminus_challenge_from_transcript, random_plusminus_by_size, within_bound_by_size, + plusminus_challenge_from_transcript, random_plusminus_by_size, within_bound_by_size, }, zkp::{Proof, ProofContext}, }; @@ -33,7 +33,7 @@ use rand::{CryptoRng, RngCore}; use serde::{Deserialize, Serialize}; use std::fmt::Debug; use tracing::error; -use utils::CurvePoint; +use crate::curve_point::CurvePoint; /// Proof of knowledge that: /// 1. the committed value in a discrete log commitment and the plaintext value @@ -354,7 +354,8 @@ mod tests { use crate::{ paillier::{DecryptionKey, Nonce}, ring_pedersen::VerifiedRingPedersen, - utils::{random_plusminus_by_size_with_minimum, testing::init_testing}, + curve_point::testing::init_testing, + utils::random_plusminus_by_size_with_minimum, zkp::BadContext, }; use rand::{rngs::StdRng, Rng, SeedableRng}; diff --git a/src/zkp/pimod.rs b/src/zkp/pimod.rs index 513554cf..f4a8cd28 100644 --- a/src/zkp/pimod.rs +++ b/src/zkp/pimod.rs @@ -477,12 +477,13 @@ fn y_prime_combinations( #[cfg(test)] mod tests { use rand::{rngs::StdRng, Rng}; + use crate::curve_point::k256_order; use super::*; use crate::{ paillier::{prime_gen, DecryptionKey}, parameters::SOUNDNESS_PARAMETER, - utils::testing::init_testing, + curve_point::testing::init_testing, zkp::BadContext, }; diff --git a/src/zkp/piprm.rs b/src/zkp/piprm.rs index 9b8363a1..87415d2c 100644 --- a/src/zkp/piprm.rs +++ b/src/zkp/piprm.rs @@ -188,7 +188,7 @@ impl Proof for PiPrmProof { #[cfg(test)] mod tests { use super::*; - use crate::{paillier::DecryptionKey, utils::testing::init_testing, zkp::BadContext}; + use crate::{paillier::DecryptionKey, curve_point::testing::init_testing, zkp::BadContext}; use rand::Rng; /// Make a transcript for PiPrmProof. diff --git a/src/zkp/pisch.rs b/src/zkp/pisch.rs index 6eb5530b..82f4e18e 100644 --- a/src/zkp/pisch.rs +++ b/src/zkp/pisch.rs @@ -29,7 +29,8 @@ use crate::{ errors::*, messages::{KeygenMessageType, KeyrefreshMessageType, Message, MessageType}, - utils::{self, k256_order, positive_challenge_from_transcript, random_positive_bn}, + curve_point::k256_order, + utils::{positive_challenge_from_transcript, random_positive_bn}, zkp::{Proof, ProofContext}, }; use libpaillier::unknown_order::BigNumber; @@ -38,7 +39,7 @@ use rand::{CryptoRng, RngCore}; use serde::{Deserialize, Serialize}; use std::{convert::AsRef, fmt::Debug}; use tracing::error; -use utils::CurvePoint; +use crate::curve_point::CurvePoint; /// Proof of knowledge of discrete logarithm of a group element which is the /// commitment to the secret. @@ -265,7 +266,7 @@ impl PiSchProof { #[cfg(test)] mod tests { use super::*; - use crate::{utils::testing::init_testing, zkp::BadContext}; + use crate::{curve_point::testing::init_testing, zkp::BadContext}; fn transcript() -> Transcript { Transcript::new(b"PiSchProof Test") } diff --git a/src/zkstar.rs b/src/zkstar.rs index 53cb579e..836f2ac7 100644 --- a/src/zkstar.rs +++ b/src/zkstar.rs @@ -1,4 +1,4 @@ -use crate::{errors::InternalError, utils}; +use crate::{curve_point, errors::InternalError}; use libpaillier::unknown_order::BigNumber; use rand::{CryptoRng, RngCore}; use serde::{Deserialize, Serialize}; @@ -81,7 +81,7 @@ impl<'a> ZStarN<'a> { builder: &'a ZStarNBuilder, rng: &mut R, ) -> Result { - utils::random_bn_in_z_star(rng, builder.modulus()).map(|value| Self { value, builder }) + curve_point::random_bn_in_z_star(rng, builder.modulus()).map(|value| Self { value, builder }) } } /// Unverified, deserialized value that claims to be in the multiplicative @@ -105,7 +105,7 @@ impl ZStarNUnverified { #[cfg(test)] mod test { - use crate::{paillier::DecryptionKey, utils::testing::init_testing, zkstar::*}; + use crate::{paillier::DecryptionKey, curve_point::testing::init_testing, zkstar::*}; #[test] fn zkstar_verification_works() { From b0af9f5a7ae2a280db4395b9a241be72a9ebeba8 Mon Sep 17 00:00:00 2001 From: emmorais Date: Mon, 15 Jul 2024 14:37:24 -0300 Subject: [PATCH 02/36] Minimal use of CurveTrait in pilog.rs --- src/zkp/pilog.rs | 44 ++++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/src/zkp/pilog.rs b/src/zkp/pilog.rs index 28e73a93..590d4a25 100644 --- a/src/zkp/pilog.rs +++ b/src/zkp/pilog.rs @@ -352,11 +352,7 @@ impl Proof for PiLogProof { mod tests { use super::*; use crate::{ - paillier::{DecryptionKey, Nonce}, - ring_pedersen::VerifiedRingPedersen, - curve_point::testing::init_testing, - utils::random_plusminus_by_size_with_minimum, - zkp::BadContext, + curve_point::{testing::init_testing, CurveTrait}, paillier::{DecryptionKey, Nonce}, ring_pedersen::VerifiedRingPedersen, utils::random_plusminus_by_size_with_minimum, zkp::BadContext }; use rand::{rngs::StdRng, Rng, SeedableRng}; @@ -364,7 +360,7 @@ mod tests { Transcript::new(b"PiLogProof Test") } - fn with_random_paillier_log_proof( + fn with_random_paillier_log_proof( rng: &mut R, x: &BigNumber, mut f: impl FnMut(PiLogProof, CommonInput) -> Result<()>, @@ -372,7 +368,7 @@ mod tests { let (decryption_key, _, _) = DecryptionKey::new(rng).unwrap(); let pk = decryption_key.encryption_key(); - let g = CurvePoint::GENERATOR; + let g = C::generator(); let X = g.multiply_by_bignum(x)?; let (ciphertext, rho) = pk.encrypt(rng, x).unwrap(); @@ -391,7 +387,7 @@ mod tests { f(proof, input) } - fn random_paillier_log_proof_verification( + fn random_paillier_log_proof_verification( rng: &mut R, x: &BigNumber, ) -> Result<()> { @@ -399,11 +395,15 @@ mod tests { proof.verify(input, &(), &mut transcript())?; Ok(()) }; - with_random_paillier_log_proof(rng, x, f) + with_random_paillier_log_proof::(rng, x, f) } #[test] - fn pilog_proof_with_consistent_secret_inputs_out_of_range() -> Result<()> { + fn test_pilog_proof_with_consistent_secret_inputs_out_of_range(){ + pilog_proof_with_consistent_secret_inputs_out_of_range::().unwrap(); + } + + fn pilog_proof_with_consistent_secret_inputs_out_of_range() -> Result<()> { let mut rng = init_testing(); let upper_bound = BigNumber::one() << (ELL + EPSILON); loop { @@ -420,11 +420,11 @@ mod tests { assert!(bad_proof.verify(input, &(), &mut transcript()).is_err()); Ok(()) }; - with_random_paillier_log_proof(&mut rng, &too_large, f)?; + with_random_paillier_log_proof::(&mut rng, &too_large, f)?; // If the value is smaller than the bottom of the range, the proof won't verify let too_small = -too_large; - with_random_paillier_log_proof(&mut rng, &too_small, f)?; + with_random_paillier_log_proof::(&mut rng, &too_small, f)?; break; } } @@ -590,7 +590,11 @@ mod tests { } #[test] - fn negative_test_swap_proof_elements() -> Result<()> { + fn test_negative_test_swap_proof_elements() { + negative_test_swap_proof_elements::().unwrap(); + } + + fn negative_test_swap_proof_elements() -> Result<()> { let mut rng = init_testing(); // `rng` will be borrowed. We make another rng to be captured by the closure. let mut rng2 = StdRng::from_seed(rng.gen()); @@ -664,12 +668,16 @@ mod tests { Ok(()) }; - with_random_paillier_log_proof(&mut rng2, &x, f)?; + with_random_paillier_log_proof::(&mut rng2, &x, f)?; Ok(()) } #[test] - fn pilog_proof_context_must_be_correct() -> Result<()> { + fn test_pilog_proof_context_must_be_correct() { + pilog_proof_context_must_be_correct::().unwrap(); + } + + fn pilog_proof_context_must_be_correct() -> Result<()> { let mut rng = init_testing(); let context = BadContext {}; @@ -680,7 +688,7 @@ mod tests { Ok(()) }; - with_random_paillier_log_proof(&mut rng, &x_small, f) + with_random_paillier_log_proof::(&mut rng, &x_small, f) } #[test] @@ -692,11 +700,11 @@ mod tests { random_plusminus_by_size_with_minimum(&mut rng, ELL + EPSILON + 1, ELL + EPSILON)?; // Sampling x in the range 2^ELL should always succeed - assert!(random_paillier_log_proof_verification(&mut rng, &x_small).is_ok()); + assert!(random_paillier_log_proof_verification::(&mut rng, &x_small).is_ok()); // Sampling x in the range (2^{ELL + EPSILON}, 2^{ELL + EPSILON + 1}] should // fail - assert!(random_paillier_log_proof_verification(&mut rng, &x_large).is_err()); + assert!(random_paillier_log_proof_verification::(&mut rng, &x_large).is_err()); Ok(()) } From e0fec6dc26c7e16e9ed61d5ee5f83619d3070aab Mon Sep 17 00:00:00 2001 From: emmorais Date: Mon, 15 Jul 2024 14:46:31 -0300 Subject: [PATCH 03/36] Cover all usage of generator in pilog --- src/zkp/pilog.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/zkp/pilog.rs b/src/zkp/pilog.rs index 590d4a25..c810fe73 100644 --- a/src/zkp/pilog.rs +++ b/src/zkp/pilog.rs @@ -432,12 +432,16 @@ mod tests { } #[test] - fn pilog_proof_with_different_setup_parameters() -> Result<()> { + fn test_pilog_proof_with_different_setup_parameters() { + let _ = pilog_proof_with_different_setup_parameters::(); + } + + fn pilog_proof_with_different_setup_parameters() -> Result<()> { let mut rng = init_testing(); let x = random_plusminus_by_size(&mut rng, ELL); let (decryption_key, _, _) = DecryptionKey::new(&mut rng).unwrap(); let pk = decryption_key.encryption_key(); - let g = CurvePoint::GENERATOR; + let g = C::generator(); let dlog_commit = g.multiply_by_bignum(&x)?; let (ciphertext, rho) = pk.encrypt(&mut rng, &x).unwrap(); let setup_params = VerifiedRingPedersen::gen(&mut rng, &())?; @@ -545,14 +549,18 @@ mod tests { } #[test] - fn pilog_proof_with_inconsistent_secret_inputs() -> Result<()> { + fn test_pilof_proof_with_inconsistent_secret_inputs() { + let _ = pilog_proof_with_inconsistent_secret_inputs::(); + } + + fn pilog_proof_with_inconsistent_secret_inputs() -> Result<()> { let mut rng = init_testing(); // Make a valid secret let x = random_plusminus_by_size(&mut rng, ELL); let (decryption_key, _, _) = DecryptionKey::new(&mut rng).unwrap(); let pk = decryption_key.encryption_key(); - let g = CurvePoint::GENERATOR; + let g = C::generator(); // Make a valid common input let dlog_commit = g.multiply_by_bignum(&x)?; From 2d054f9acca97ae91ef2ebd43c943d93cae328c4 Mon Sep 17 00:00:00 2001 From: emmorais Date: Tue, 16 Jul 2024 09:26:16 -0300 Subject: [PATCH 04/36] Using generator from trait in pisch.rs --- src/keygen/participant.rs | 21 ++++--------- src/keyrefresh/participant.rs | 21 ++++--------- src/zkp/pisch.rs | 55 ++++++++++++++++++----------------- 3 files changed, 41 insertions(+), 56 deletions(-) diff --git a/src/keygen/participant.rs b/src/keygen/participant.rs index 528e7791..13f32b2b 100644 --- a/src/keygen/participant.rs +++ b/src/keygen/participant.rs @@ -9,22 +9,13 @@ // of this source tree. use crate::{ - broadcast::participant::{BroadcastOutput, BroadcastParticipant, BroadcastTag}, - errors::{CallerError, InternalError, Result}, - keygen::{ + broadcast::participant::{BroadcastOutput, BroadcastParticipant, BroadcastTag}, curve_point::CurvePoint, errors::{CallerError, InternalError, Result}, keygen::{ keygen_commit::{KeygenCommit, KeygenDecommit}, keyshare::{KeySharePrivate, KeySharePublic}, output::Output, - }, - local_storage::LocalStorage, - messages::{KeygenMessageType, Message, MessageType}, - participant::{ + }, local_storage::LocalStorage, messages::{KeygenMessageType, Message, MessageType}, participant::{ Broadcast, InnerProtocolParticipant, ProcessOutcome, ProtocolParticipant, Status, - }, - protocol::{ParticipantIdentifier, ProtocolType, SharedContext}, - run_only_once, - zkp::pisch::{CommonInput, PiSchPrecommit, PiSchProof, ProverSecret}, - Identifier, + }, protocol::{ParticipantIdentifier, ProtocolType, SharedContext}, run_only_once, zkp::pisch::{CommonInput, PiSchPrecommit, PiSchProof, ProverSecret}, Identifier }; use merlin::Transcript; @@ -274,7 +265,7 @@ impl KeygenParticipant { let (keyshare_private, keyshare_public) = KeySharePublic::new_keyshare(self.id(), rng)?; // This corresponds to `A_i` in the paper. - let sch_precom = PiSchProof::precommit(rng)?; + let sch_precom = PiSchProof::::precommit(rng)?; let decom = KeygenDecommit::new(rng, &sid, &self.id, &keyshare_public, &sch_precom); // This corresponds to `V_i` in the paper. let com = decom.commit()?; @@ -498,7 +489,7 @@ impl KeygenParticipant { .local_storage .retrieve::(self.id)?; - let proof = PiSchProof::prove_from_precommit( + let proof = PiSchProof::::prove_from_precommit( &self.retrieve_context(), precom, &input, @@ -531,7 +522,7 @@ impl KeygenParticipant { self.stash_message(message)?; return Ok(ProcessOutcome::Incomplete); } - let proof = PiSchProof::from_message(message)?; + let proof = PiSchProof::::from_message(message)?; let global_rid = *self.local_storage.retrieve::(self.id)?; let decom = self .local_storage diff --git a/src/keyrefresh/participant.rs b/src/keyrefresh/participant.rs index ef6af133..3e6c220d 100644 --- a/src/keyrefresh/participant.rs +++ b/src/keyrefresh/participant.rs @@ -9,21 +9,12 @@ // of this source tree. use crate::{ - broadcast::participant::{BroadcastOutput, BroadcastParticipant, BroadcastTag}, - errors::{CallerError, InternalError, Result}, - keyrefresh::{ + broadcast::participant::{BroadcastOutput, BroadcastParticipant, BroadcastTag}, curve_point::CurvePoint, errors::{CallerError, InternalError, Result}, keyrefresh::{ keyrefresh_commit::{KeyrefreshCommit, KeyrefreshDecommit}, keyshare::{KeyUpdateEncrypted, KeyUpdatePrivate, KeyUpdatePublic}, - }, - local_storage::LocalStorage, - messages::{KeyrefreshMessageType, Message, MessageType}, - participant::{ + }, local_storage::LocalStorage, messages::{KeyrefreshMessageType, Message, MessageType}, participant::{ Broadcast, InnerProtocolParticipant, ProcessOutcome, ProtocolParticipant, Status, - }, - protocol::{ParticipantIdentifier, ProtocolType, SharedContext}, - run_only_once, - zkp::pisch::{CommonInput, PiSchPrecommit, PiSchProof, ProverSecret}, - Identifier, ParticipantConfig, + }, protocol::{ParticipantIdentifier, ProtocolType, SharedContext}, run_only_once, zkp::pisch::{CommonInput, PiSchPrecommit, PiSchProof, ProverSecret}, Identifier, ParticipantConfig }; use merlin::Transcript; @@ -308,7 +299,7 @@ impl KeyrefreshParticipant { // This corresponds to `A_ij` in the paper. let sch_precoms = (0..update_publics.len()) - .map(|_| PiSchProof::precommit(rng)) + .map(|_| PiSchProof::::precommit(rng)) .collect::>>()?; let decom = KeyrefreshDecommit::new( @@ -572,7 +563,7 @@ impl KeyrefreshParticipant { .local_storage .retrieve::(self.id())?; - let mut proofs: Vec = vec![]; + let mut proofs: Vec> = vec![]; for i in 0..precoms.len() { let pk = &decom.update_publics[i]; let input = CommonInput::new(pk); @@ -654,7 +645,7 @@ impl KeyrefreshParticipant { .local_storage .retrieve::(self.id())?; - let proofs = PiSchProof::from_message_multi(message)?; + let proofs = PiSchProof::::from_message_multi(message)?; let decom = self .local_storage .retrieve::(message.from())?; diff --git a/src/zkp/pisch.rs b/src/zkp/pisch.rs index 82f4e18e..3d9138a7 100644 --- a/src/zkp/pisch.rs +++ b/src/zkp/pisch.rs @@ -27,11 +27,7 @@ //! UC Non-Interactive, Proactive, Threshold ECDSA with Identifiable Aborts. //! [EPrint archive, 2021](https://eprint.iacr.org/2021/060.pdf). use crate::{ - errors::*, - messages::{KeygenMessageType, KeyrefreshMessageType, Message, MessageType}, - curve_point::k256_order, - utils::{positive_challenge_from_transcript, random_positive_bn}, - zkp::{Proof, ProofContext}, + curve_point::{k256_order, CurveTrait}, errors::*, messages::{KeygenMessageType, KeyrefreshMessageType, Message, MessageType}, utils::{positive_challenge_from_transcript, random_positive_bn}, zkp::{Proof, ProofContext} }; use libpaillier::unknown_order::BigNumber; use merlin::Transcript; @@ -44,7 +40,9 @@ use crate::curve_point::CurvePoint; /// Proof of knowledge of discrete logarithm of a group element which is the /// commitment to the secret. #[derive(Debug, Serialize, Deserialize)] -pub(crate) struct PiSchProof { +pub(crate) struct PiSchProof + where C: CurveTrait +{ /// Commitment to the secret (`A` in the paper). commitment: CurvePoint, /// Fiat-Shamir challenge (`e` in the paper). @@ -52,6 +50,8 @@ pub(crate) struct PiSchProof { /// Response binding the commitment randomness used in the commitment (`z` /// in the paper). response: BigNumber, + /// Marker to pin the curve type. + curve: std::marker::PhantomData, } /// Commitment to the mask selected in the commitment phase of the proof. @@ -110,7 +110,9 @@ impl<'a> ProverSecret<'a> { } } -impl Proof for PiSchProof { +impl Proof for PiSchProof + where C: CurveTrait +{ type CommonInput<'a> = CommonInput<'a>; type ProverSecret<'a> = ProverSecret<'a>; #[cfg_attr(feature = "flame_it", flame("PiSchProof"))] @@ -121,7 +123,7 @@ impl Proof for PiSchProof { transcript: &mut Transcript, rng: &mut R, ) -> Result { - let com = PiSchProof::precommit(rng)?; + let com = PiSchProof::::precommit(rng)?; let proof = PiSchProof::prove_from_precommit(context, &com, &input, &secret, transcript)?; Ok(proof) } @@ -159,7 +161,7 @@ impl Proof for PiSchProof { } } -impl PiSchProof { +impl PiSchProof { /// "Commitment" phase of the PiSch proof. pub fn precommit(rng: &mut R) -> Result { // Sample alpha from F_q @@ -199,6 +201,7 @@ impl PiSchProof { commitment, challenge, response, + curve: std::marker::PhantomData, }; Ok(proof) } @@ -222,7 +225,7 @@ impl PiSchProof { pub(crate) fn from_message_multi(message: &Message) -> Result> { message.check_type(MessageType::Keyrefresh(KeyrefreshMessageType::R3Proofs))?; - let pisch_proofs: Vec = deserialize!(&message.unverified_bytes)?; + let pisch_proofs: Vec> = deserialize!(&message.unverified_bytes)?; for pisch_proof in &pisch_proofs { if pisch_proof.challenge >= k256_order() { error!("the challenge is not in the field"); @@ -239,7 +242,7 @@ impl PiSchProof { pub(crate) fn from_message(message: &Message) -> Result { message.check_type(MessageType::Keygen(KeygenMessageType::R3Proof))?; - let pisch_proof: PiSchProof = deserialize!(&message.unverified_bytes)?; + let pisch_proof: PiSchProof = deserialize!(&message.unverified_bytes)?; if pisch_proof.challenge >= k256_order() { error!("the challenge is not in the field"); return Err(InternalError::ProtocolError(None)); @@ -271,12 +274,12 @@ mod tests { Transcript::new(b"PiSchProof Test") } - type TestFn = fn(PiSchProof, CommonInput) -> Result<()>; + type TestFn = fn(PiSchProof, CommonInput) -> Result<()>; fn with_random_schnorr_proof( rng: &mut R, additive: bool, - test_code: impl Fn(PiSchProof, CommonInput) -> Result<()>, + test_code: impl Fn(PiSchProof, CommonInput) -> Result<()>, ) -> Result<()> { let q = k256_order(); let g = CurvePoint::GENERATOR; @@ -312,8 +315,8 @@ mod tests { let y_commit = g.multiply_by_bignum(&y)?; let input = CommonInput::new(&x_commit); - let com = PiSchProof::precommit(&mut rng)?; - let mut proof = PiSchProof::prove_from_precommit( + let com = PiSchProof::::precommit(&mut rng)?; + let mut proof = PiSchProof::::prove_from_precommit( &(), &com, &input, @@ -337,8 +340,8 @@ mod tests { let x_commit = g.multiply_by_bignum(&x)?; let input = CommonInput::new(&x_commit); - let com = PiSchProof::precommit(&mut rng)?; - let mut proof = PiSchProof::prove_from_precommit( + let com = PiSchProof::::precommit(&mut rng)?; + let mut proof = PiSchProof::::prove_from_precommit( &(), &com, &input, @@ -363,8 +366,8 @@ mod tests { let bad_generator = x_commit.multiply_by_bignum(&x)?; let input = CommonInput::new(&bad_generator); - let com = PiSchProof::precommit(&mut rng)?; - let proof = PiSchProof::prove_from_precommit( + let com = PiSchProof::::precommit(&mut rng)?; + let proof = PiSchProof::::prove_from_precommit( &(), &com, &input, @@ -391,8 +394,8 @@ mod tests { assert_ne!(x, y); let input = CommonInput::new(&x_commit); - let com = PiSchProof::precommit(&mut rng)?; - let proof = PiSchProof::prove_from_precommit( + let com = PiSchProof::::precommit(&mut rng)?; + let proof = PiSchProof::::prove_from_precommit( &(), &com, &input, @@ -422,8 +425,8 @@ mod tests { assert_ne!(x_commit, y_commit); let input = CommonInput::new(&x_commit); - let com = PiSchProof::precommit(&mut rng)?; - let proof = PiSchProof::prove_from_precommit( + let com = PiSchProof::::precommit(&mut rng)?; + let proof = PiSchProof::::prove_from_precommit( &(), &com, &input, @@ -480,8 +483,8 @@ mod tests { let x_commit = g.multiply_by_bignum(&x)?; let input = CommonInput::new(&x_commit); - let com = PiSchProof::precommit(&mut rng)?; - let proof = PiSchProof::prove_from_precommit( + let com = PiSchProof::::precommit(&mut rng)?; + let proof = PiSchProof::::prove_from_precommit( &(), &com, &input, @@ -492,7 +495,7 @@ mod tests { //test transcript mismatch let transcript2 = Transcript::new(b"some other external proof stuff"); - let proof3 = PiSchProof::prove_from_precommit( + let proof3 = PiSchProof::::prove_from_precommit( &(), &com, &input, From cd3cb2c8b4bf18904ddeeb9cfe8aec428b14f8ce Mon Sep 17 00:00:00 2001 From: emmorais Date: Wed, 17 Jul 2024 07:21:44 -0300 Subject: [PATCH 05/36] Use CurveTrait in more places, not compiling yet --- src/keyrefresh/keyrefresh_commit.rs | 22 ++++------ src/keyrefresh/keyshare.rs | 22 +++++----- src/keyrefresh/participant.rs | 67 ++++++++++++++++------------- 3 files changed, 57 insertions(+), 54 deletions(-) diff --git a/src/keyrefresh/keyrefresh_commit.rs b/src/keyrefresh/keyrefresh_commit.rs index a2f00ecf..3b8bc8b3 100644 --- a/src/keyrefresh/keyrefresh_commit.rs +++ b/src/keyrefresh/keyrefresh_commit.rs @@ -7,11 +7,7 @@ // of this source tree. use crate::{ - errors::{InternalError, Result}, - keyrefresh::keyshare::KeyUpdatePublic, - messages::{KeyrefreshMessageType, Message, MessageType}, - protocol::{Identifier, ParticipantIdentifier}, - curve_point::CurvePoint, + curve_point::{CurvePoint, CurveTrait}, errors::{InternalError, Result}, keyrefresh::keyshare::KeyUpdatePublic, messages::{KeyrefreshMessageType, Message, MessageType}, protocol::{Identifier, ParticipantIdentifier} }; use merlin::Transcript; use rand::{CryptoRng, RngCore}; @@ -33,23 +29,23 @@ impl KeyrefreshCommit { /// Decommitment published in round 2. #[derive(Serialize, Deserialize, Clone)] -pub(crate) struct KeyrefreshDecommit { +pub(crate) struct KeyrefreshDecommit { sid: Identifier, sender: ParticipantIdentifier, u_i: [u8; 32], // The blinding factor is never read but it is included in the commitment. pub rid: [u8; 32], - pub update_publics: Vec, - pub As: Vec, + pub update_publics: Vec>, + pub As: Vec, } -impl KeyrefreshDecommit { +impl KeyrefreshDecommit { ///`sid` corresponds to a unique session identifier. pub(crate) fn new( rng: &mut R, sid: &Identifier, sender: &ParticipantIdentifier, - update_publics: Vec, - sch_precoms: Vec, + update_publics: Vec>, + sch_precoms: Vec, ) -> Self { let mut rid = [0u8; 32]; let mut u_i = [0u8; 32]; @@ -72,7 +68,7 @@ impl KeyrefreshDecommit { participant_ids: &[ParticipantIdentifier], ) -> Result { message.check_type(MessageType::Keyrefresh(KeyrefreshMessageType::R2Decommit))?; - let keyrefresh_decommit: KeyrefreshDecommit = deserialize!(&message.unverified_bytes)?; + let keyrefresh_decommit: KeyrefreshDecommit = deserialize!(&message.unverified_bytes)?; keyrefresh_decommit.verify(message.id(), message.from(), com, participant_ids)?; Ok(keyrefresh_decommit) } @@ -142,7 +138,7 @@ impl KeyrefreshDecommit { } // Implement custom Debug to avoid leaking secret information. -impl std::fmt::Debug for KeyrefreshDecommit { +impl std::fmt::Debug for KeyrefreshDecommit { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("KeyrefreshDecommit") .field("sid", &self.sid) diff --git a/src/keyrefresh/keyshare.rs b/src/keyrefresh/keyshare.rs index 307d39a0..0973801a 100644 --- a/src/keyrefresh/keyshare.rs +++ b/src/keyrefresh/keyshare.rs @@ -7,11 +7,7 @@ // of this source tree. use crate::{ - errors::{CallerError, InternalError, Result}, - keygen::{KeySharePrivate, KeySharePublic}, - paillier::{Ciphertext, DecryptionKey, EncryptionKey}, - curve_point::{k256_order, CurvePoint}, - ParticipantIdentifier, + curve_point::{k256_order, CurvePoint, CurveTrait}, errors::{CallerError, InternalError, Result}, keygen::{KeySharePrivate, KeySharePublic}, paillier::{Ciphertext, DecryptionKey, EncryptionKey}, ParticipantIdentifier }; use libpaillier::unknown_order::BigNumber; use rand::{CryptoRng, RngCore}; @@ -118,16 +114,19 @@ impl AsRef for KeyUpdatePrivate { /// A curve point representing a given [`Participant`](crate::Participant)'s /// public key. #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] -pub struct KeyUpdatePublic { +pub struct KeyUpdatePublic { participant: ParticipantIdentifier, X: CurvePoint, + /// Marker to pin the generic type `C`. + _curve: std::marker::PhantomData, } -impl KeyUpdatePublic { +impl KeyUpdatePublic { pub(crate) fn new(participant: ParticipantIdentifier, share: CurvePoint) -> Self { Self { participant, X: share, + _curve: std::marker::PhantomData, } } @@ -141,21 +140,22 @@ impl KeyUpdatePublic { pub(crate) fn new_keyshare( participant: ParticipantIdentifier, rng: &mut R, - ) -> Result<(KeyUpdatePrivate, KeyUpdatePublic)> { + ) -> Result<(KeyUpdatePrivate, KeyUpdatePublic)> { let private_share = KeyUpdatePrivate::random(rng); let public_share = private_share.public_point()?; Ok(( private_share, - KeyUpdatePublic::new(participant, public_share), + KeyUpdatePublic::::new(participant, public_share), )) } pub(crate) fn sum(participant: ParticipantIdentifier, shares: &[Self]) -> Self { - let sum = shares.iter().fold(CurvePoint::IDENTITY, |sum, o| sum + o.X); + let sum = shares.iter().fold(C::identity(), |sum, o| sum + o.X); Self { participant, X: sum, + _curve: std::marker::PhantomData, } } @@ -165,7 +165,7 @@ impl KeyUpdatePublic { } } -impl AsRef for KeyUpdatePublic { +impl AsRef for KeyUpdatePublic { /// Get the public curvepoint which is the public key share. fn as_ref(&self) -> &CurvePoint { &self.X diff --git a/src/keyrefresh/participant.rs b/src/keyrefresh/participant.rs index 3e6c220d..c7d17002 100644 --- a/src/keyrefresh/participant.rs +++ b/src/keyrefresh/participant.rs @@ -9,7 +9,7 @@ // of this source tree. use crate::{ - broadcast::participant::{BroadcastOutput, BroadcastParticipant, BroadcastTag}, curve_point::CurvePoint, errors::{CallerError, InternalError, Result}, keyrefresh::{ + broadcast::participant::{BroadcastOutput, BroadcastParticipant, BroadcastTag}, curve_point::{CurvePoint, CurveTrait}, errors::{CallerError, InternalError, Result}, keyrefresh::{ keyrefresh_commit::{KeyrefreshCommit, KeyrefreshDecommit}, keyshare::{KeyUpdateEncrypted, KeyUpdatePrivate, KeyUpdatePublic}, }, local_storage::LocalStorage, messages::{KeyrefreshMessageType, Message, MessageType}, participant::{ @@ -17,6 +17,7 @@ use crate::{ }, protocol::{ParticipantIdentifier, ProtocolType, SharedContext}, run_only_once, zkp::pisch::{CommonInput, PiSchPrecommit, PiSchProof, ProverSecret}, Identifier, ParticipantConfig }; +use k256::elliptic_curve::Curve; use merlin::Transcript; use rand::{CryptoRng, RngCore}; use tracing::{error, info, instrument, warn}; @@ -31,9 +32,12 @@ mod storage { impl TypeTag for Commit { type Value = KeyrefreshCommit; } - pub(super) struct Decommit; - impl TypeTag for Decommit { - type Value = KeyrefreshDecommit; + pub(super) struct Decommit { + /// Marker for the curve type. + curve: std::marker::PhantomData, + } + impl TypeTag for Decommit { + type Value = KeyrefreshDecommit; } pub(super) struct VecSchnorrPrecom; impl TypeTag for VecSchnorrPrecom { @@ -47,9 +51,12 @@ mod storage { impl TypeTag for PrivateUpdatesForOthers { type Value = Vec; } - pub(super) struct ValidPublicUpdates; - impl TypeTag for ValidPublicUpdates { - type Value = Vec; + pub(super) struct ValidPublicUpdates { + /// Marker for the curve type. + curve: std::marker::PhantomData, + } + impl TypeTag for ValidPublicUpdates { + type Value = Vec>; } pub(super) struct ValidPrivateUpdate; impl TypeTag for ValidPrivateUpdate { @@ -319,7 +326,7 @@ impl KeyrefreshParticipant { // Mark our own public updates as verified. self.local_storage - .store::(self.id(), decom.update_publics.clone()); + .store::>(self.id(), decom.update_publics.clone()); // Store the private update from ourselves to ourselves. self.local_storage.store::( @@ -338,7 +345,7 @@ impl KeyrefreshParticipant { // Store our committed values so we can open the commitment later. self.local_storage - .store::(self.id(), decom); + .store::>(self.id(), decom); let messages = self.broadcast( rng, @@ -430,14 +437,14 @@ impl KeyrefreshParticipant { // `PublicKeyshare` and `Decommit`). This check forces that behavior. // Without it we'll get a `InternalInvariantFailed` error when trying to // retrieve `Decommit` below. - if !self.local_storage.contains::(self.id()) { + if !self.local_storage.contains::>(self.id()) { let more_messages = run_only_once!(self.gen_round_one_msgs(rng, sid))?; messages.extend_from_slice(&more_messages); } let decom = self .local_storage - .retrieve::(self.id())?; + .retrieve::>(self.id())?; let more_messages = self.message_for_other_participants( MessageType::Keyrefresh(KeyrefreshMessageType::R2Decommit), decom, @@ -456,7 +463,7 @@ impl KeyrefreshParticipant { rng: &mut R, message: &Message, ) -> Result::Output>> { - self.check_for_duplicate_msg::(message.from())?; + self.check_for_duplicate_msg::>(message.from())?; info!("Handling round two keyrefresh message."); // We must receive all commitments in round 1 before we start processing @@ -476,12 +483,12 @@ impl KeyrefreshParticipant { .retrieve::(message.from())?; let decom = KeyrefreshDecommit::from_message(message, com, &self.all_participants())?; self.local_storage - .store_once::(message.from(), decom)?; + .store_once::>(message.from(), decom)?; // Check if we've received all the decommits let r2_done = self .local_storage - .contains_for_all_ids::(&self.all_participants()); + .contains_for_all_ids::>(&self.all_participants()); if r2_done { // Generate messages for round 3... @@ -526,7 +533,7 @@ impl KeyrefreshParticipant { // Construct `global rid` out of each participant's `rid`s. let my_rid = self .local_storage - .retrieve::(self.id())? + .retrieve::>(self.id())? .rid; let rids: Vec<[u8; 32]> = self .other_ids() @@ -534,7 +541,7 @@ impl KeyrefreshParticipant { .map(|&other_participant_id| { let decom = self .local_storage - .retrieve::(other_participant_id)?; + .retrieve::>(other_participant_id)?; Ok(decom.rid) }) .collect::>>()?; @@ -550,7 +557,7 @@ impl KeyrefreshParticipant { let decom = self .local_storage - .retrieve::(self.id())?; + .retrieve::>(self.id())?; let transcript = schnorr_proof_transcript(self.sid(), &global_rid, self.id())?; @@ -632,7 +639,7 @@ impl KeyrefreshParticipant { &mut self, message: &Message, ) -> Result::Output>> { - self.check_for_duplicate_msg::(message.from())?; + self.check_for_duplicate_msg::>(message.from())?; if !self.can_handle_round_three_msg() { info!("Not yet ready to handle round three keyrefresh broadcast message."); @@ -648,7 +655,7 @@ impl KeyrefreshParticipant { let proofs = PiSchProof::::from_message_multi(message)?; let decom = self .local_storage - .retrieve::(message.from())?; + .retrieve::>(message.from())?; // Check that there is one proof per participant. if proofs.len() != self.all_participants().len() { @@ -672,7 +679,7 @@ impl KeyrefreshParticipant { // Only if the proof verifies do we store the participant's updates. self.local_storage - .store_once::( + .store_once::>( message.from(), decom.update_publics.clone(), )?; @@ -714,7 +721,7 @@ impl KeyrefreshParticipant { let implied_public = update_private.public_point()?; let decom = self .local_storage - .retrieve::(message.from())?; + .retrieve::>(message.from())?; let expected_public = decom .update_publics .iter() @@ -736,7 +743,7 @@ impl KeyrefreshParticipant { // Have we validated and stored the public updates from everybody to everybody? let got_all_public_updates = self .local_storage - .contains_for_all_ids::(&self.all_participants()); + .contains_for_all_ids::>(&self.all_participants()); // Have we got the private updates from everybody to us? let got_all_private_updates = self @@ -751,7 +758,7 @@ impl KeyrefreshParticipant { .iter() .map(|pid| { self.local_storage - .remove::(*pid) + .remove::>(*pid) }) .collect::>>()?; let all_public_updates = @@ -812,10 +819,10 @@ impl KeyrefreshParticipant { KeyUpdatePrivate::sum(update_privates) } - fn aggregate_public_updates( + fn aggregate_public_updates( participants: &[ParticipantIdentifier], - from_all_to_all: &[Vec], - ) -> Result> { + from_all_to_all: &[Vec>], + ) -> Result>> { participants .iter() .map(|p_i| { @@ -827,14 +834,14 @@ impl KeyrefreshParticipant { .collect() } - fn find_updates_for_participant( + fn find_updates_for_participant( p_i: ParticipantIdentifier, - from_all_to_all: &[Vec], - ) -> Result> { + from_all_to_all: &[Vec>], + ) -> Result>> { let from_all_to_i = from_all_to_all .iter() .map(|from_j_to_all| { - let from_j_to_i = from_j_to_all + let from_j_to_i = &from_j_to_all .iter() .find(|from_j_to_x| from_j_to_x.participant() == p_i) .cloned() From d50f9bdb43cfab23e1ac37e258ce8131ad5196d4 Mon Sep 17 00:00:00 2001 From: emmorais Date: Wed, 17 Jul 2024 10:36:05 -0300 Subject: [PATCH 06/36] Fix small issue --- src/keyrefresh/participant.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/keyrefresh/participant.rs b/src/keyrefresh/participant.rs index c7d17002..806e7cd8 100644 --- a/src/keyrefresh/participant.rs +++ b/src/keyrefresh/participant.rs @@ -841,7 +841,7 @@ impl KeyrefreshParticipant { let from_all_to_i = from_all_to_all .iter() .map(|from_j_to_all| { - let from_j_to_i = &from_j_to_all + let from_j_to_i = from_j_to_all .iter() .find(|from_j_to_x| from_j_to_x.participant() == p_i) .cloned() From b2bff55c572475b6f9e7c016b6512d98a9dc3fd2 Mon Sep 17 00:00:00 2001 From: emmorais Date: Wed, 17 Jul 2024 11:32:34 -0300 Subject: [PATCH 07/36] Compiling, but wrong implementation of deserialize --- src/keyrefresh/keyrefresh_commit.rs | 27 +++++++++++++++++++++++++-- src/keyrefresh/keyshare.rs | 25 +++++++++++++++++++++++-- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/src/keyrefresh/keyrefresh_commit.rs b/src/keyrefresh/keyrefresh_commit.rs index 3b8bc8b3..82fbcea9 100644 --- a/src/keyrefresh/keyrefresh_commit.rs +++ b/src/keyrefresh/keyrefresh_commit.rs @@ -11,7 +11,7 @@ use crate::{ }; use merlin::Transcript; use rand::{CryptoRng, RngCore}; -use serde::{Deserialize, Serialize}; +use serde::{ser::SerializeStruct, Deserialize, Serialize}; use tracing::error; /// Public commitment to `KeyrefreshDecommit` in round 1. @@ -28,7 +28,7 @@ impl KeyrefreshCommit { } /// Decommitment published in round 2. -#[derive(Serialize, Deserialize, Clone)] +#[derive(Clone)] pub(crate) struct KeyrefreshDecommit { sid: Identifier, sender: ParticipantIdentifier, @@ -38,6 +38,29 @@ pub(crate) struct KeyrefreshDecommit { pub As: Vec, } +/// Implement custom serialization for KeyrefreshDecommit. +impl Serialize for KeyrefreshDecommit { + fn serialize(&self, s: S) -> std::result::Result { + let mut ser = s.serialize_struct("KeyrefreshDecommit", 5)?; + ser.serialize_field("sid", &self.sid)?; + ser.serialize_field("sender", &self.sender)?; + ser.serialize_field("u_i", &self.u_i)?; + ser.serialize_field("rid", &self.rid)?; + ser.serialize_field("update_publics", &self.update_publics)?; + ser.end() + } +} + +/// FIXME: Next function is calling itself, causing overflow in the stack. But code finally compiles. +impl<'de, C: CurveTrait> Deserialize<'de> for KeyrefreshDecommit { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de> { + let keyrefresh_decommit: KeyrefreshDecommit = serde::Deserialize::deserialize(deserializer)?; + Ok(keyrefresh_decommit) + } +} + impl KeyrefreshDecommit { ///`sid` corresponds to a unique session identifier. pub(crate) fn new( diff --git a/src/keyrefresh/keyshare.rs b/src/keyrefresh/keyshare.rs index 0973801a..bd87fbda 100644 --- a/src/keyrefresh/keyshare.rs +++ b/src/keyrefresh/keyshare.rs @@ -11,7 +11,7 @@ use crate::{ }; use libpaillier::unknown_order::BigNumber; use rand::{CryptoRng, RngCore}; -use serde::{Deserialize, Serialize}; +use serde::{ser::SerializeStruct, Deserialize, Serialize}; use std::fmt::Debug; use tracing::error; use zeroize::{Zeroize, ZeroizeOnDrop}; @@ -113,7 +113,7 @@ impl AsRef for KeyUpdatePrivate { /// A curve point representing a given [`Participant`](crate::Participant)'s /// public key. -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +#[derive(Debug, Deserialize, PartialEq, Eq)] pub struct KeyUpdatePublic { participant: ParticipantIdentifier, X: CurvePoint, @@ -121,6 +121,27 @@ pub struct KeyUpdatePublic { _curve: std::marker::PhantomData, } +/// Implement Clone manually to avoid the `C: Clone` bound. +impl Clone for KeyUpdatePublic { + fn clone(&self) -> Self { + Self { + participant: self.participant, + X: self.X.clone(), + _curve: std::marker::PhantomData, + } + } +} + +/// Implement Serialize manually to avoid the `C: Serialize` bound. +impl Serialize for KeyUpdatePublic { + fn serialize(&self, serializer: S) -> std::result::Result { + let mut state = serializer.serialize_struct("KeyUpdatePublic", 2)?; + state.serialize_field("participant", &self.participant)?; + state.serialize_field("X", &self.X.to_bytes())?; + state.end() + } +} + impl KeyUpdatePublic { pub(crate) fn new(participant: ParticipantIdentifier, share: CurvePoint) -> Self { Self { From 520798bbce00a708e2ab04f20ec8b105f32659ed Mon Sep 17 00:00:00 2001 From: emmorais Date: Wed, 17 Jul 2024 14:18:27 -0300 Subject: [PATCH 08/36] Testing passing after partial use of CurveTrait --- src/curve_point.rs | 2 +- src/keyrefresh/keyrefresh_commit.rs | 107 +++++++++++++++++++++++++--- src/keyrefresh/participant.rs | 1 - 3 files changed, 100 insertions(+), 10 deletions(-) diff --git a/src/curve_point.rs b/src/curve_point.rs index 58d9fa22..0ac058da 100644 --- a/src/curve_point.rs +++ b/src/curve_point.rs @@ -46,7 +46,7 @@ impl AsRef for CurvePoint { } } -impl CurvePoint { +impl<'de> CurvePoint { pub fn x_affine(&self) -> FieldBytes { self.0.to_affine().x() } diff --git a/src/keyrefresh/keyrefresh_commit.rs b/src/keyrefresh/keyrefresh_commit.rs index 82fbcea9..eb65ff2f 100644 --- a/src/keyrefresh/keyrefresh_commit.rs +++ b/src/keyrefresh/keyrefresh_commit.rs @@ -11,7 +11,7 @@ use crate::{ }; use merlin::Transcript; use rand::{CryptoRng, RngCore}; -use serde::{ser::SerializeStruct, Deserialize, Serialize}; +use serde::{Deserialize, Serialize}; use tracing::error; /// Public commitment to `KeyrefreshDecommit` in round 1. @@ -28,7 +28,7 @@ impl KeyrefreshCommit { } /// Decommitment published in round 2. -#[derive(Clone)] +#[derive(Serialize, Deserialize, Clone)] pub(crate) struct KeyrefreshDecommit { sid: Identifier, sender: ParticipantIdentifier, @@ -39,7 +39,7 @@ pub(crate) struct KeyrefreshDecommit { } /// Implement custom serialization for KeyrefreshDecommit. -impl Serialize for KeyrefreshDecommit { +/*impl Serialize for KeyrefreshDecommit { fn serialize(&self, s: S) -> std::result::Result { let mut ser = s.serialize_struct("KeyrefreshDecommit", 5)?; ser.serialize_field("sid", &self.sid)?; @@ -49,19 +49,110 @@ impl Serialize for KeyrefreshDecommit { ser.serialize_field("update_publics", &self.update_publics)?; ser.end() } -} +}*/ /// FIXME: Next function is calling itself, causing overflow in the stack. But code finally compiles. -impl<'de, C: CurveTrait> Deserialize<'de> for KeyrefreshDecommit { +/*impl<'de, C: CurveTrait> Deserialize<'de> for KeyrefreshDecommit { fn deserialize(deserializer: D) -> std::result::Result where D: serde::Deserializer<'de> { let keyrefresh_decommit: KeyrefreshDecommit = serde::Deserialize::deserialize(deserializer)?; Ok(keyrefresh_decommit) } -} +}*/ + +/// Deserialize by deserializing each field individually in order to avoid C: CurveTrait bound. +/*impl<'de, C: CurveTrait> Deserialize<'de> for KeyrefreshDecommit { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de> { + struct KeyrefreshDecommitVisitor { + marker: std::marker::PhantomData, + } + + impl<'de, C: CurveTrait> serde::de::Visitor<'de> for KeyrefreshDecommitVisitor { + type Value = KeyrefreshDecommit; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("struct KeyrefreshDecommit") + } + + fn visit_map(self, mut map: A) -> std::result::Result + where + A: serde::de::MapAccess<'de>, + { + let mut sid = None; + let mut sender = None; + let mut u_i = None; + let mut rid = None; + let mut update_publics = None; + + while let Some(key) = map.next_key()? { + match key { + "sid" => { + if sid.is_some() { + return Err(serde::de::Error::duplicate_field("sid")); + } + sid = Some(map.next_value()?); + } + "sender" => { + if sender.is_some() { + return Err(serde::de::Error::duplicate_field("sender")); + } + sender = Some(map.next_value()?); + } + "u_i" => { + if u_i.is_some() { + return Err(serde::de::Error::duplicate_field("u_i")); + } + u_i = Some(map.next_value()?); + } + "rid" => { + if rid.is_some() { + return Err(serde::de::Error::duplicate_field("rid")); + } + rid = Some(map.next_value()?); + } + "update_publics" => { + if update_publics.is_some() { + return Err(serde::de::Error::duplicate_field("update_publics")); + } + update_publics = Some(map.next_value()?); + } + _ => { + return Err(serde::de::Error::unknown_field( + key, + &["sid", + "sender", + "u_i", + "rid", + "update_publics"])); + } + } + } + + let sid = sid.ok_or_else(|| serde::de::Error::missing_field("sid"))?; + let sender = sender.ok_or_else(|| serde::de::Error::missing_field("sender"))?; + let u_i = u_i.ok_or_else(|| serde::de::Error::missing_field("u_i"))?; + let rid = rid.ok_or_else(|| serde::de::Error::missing_field("rid"))?; + let update_publics = update_publics.ok_or_else(|| serde::de::Error::missing_field("update_publics"))?; + + Ok(KeyrefreshDecommit { + sid, + sender, + u_i, + rid, + update_publics, + As: Vec::new(), + }) + } + } + + deserializer.deserialize_struct("KeyrefreshDecommit", &["sid", "sender", "u_i", "rid", "update_publics"], KeyrefreshDecommitVisitor { marker: std::marker::PhantomData }) + } +}*/ -impl KeyrefreshDecommit { +impl<'de, C: CurveTrait + Serialize + Deserialize<'de>> KeyrefreshDecommit { ///`sid` corresponds to a unique session identifier. pub(crate) fn new( rng: &mut R, @@ -86,7 +177,7 @@ impl KeyrefreshDecommit { /// Deserialize a KeyrefreshDecommit from a message and verify it. pub(crate) fn from_message( - message: &Message, + message: &'de Message, com: &KeyrefreshCommit, participant_ids: &[ParticipantIdentifier], ) -> Result { diff --git a/src/keyrefresh/participant.rs b/src/keyrefresh/participant.rs index 806e7cd8..d82a8b82 100644 --- a/src/keyrefresh/participant.rs +++ b/src/keyrefresh/participant.rs @@ -17,7 +17,6 @@ use crate::{ }, protocol::{ParticipantIdentifier, ProtocolType, SharedContext}, run_only_once, zkp::pisch::{CommonInput, PiSchPrecommit, PiSchProof, ProverSecret}, Identifier, ParticipantConfig }; -use k256::elliptic_curve::Curve; use merlin::Transcript; use rand::{CryptoRng, RngCore}; use tracing::{error, info, instrument, warn}; From 9a633989f2a8740dff0af12f7fcc8cddf0bb1f66 Mon Sep 17 00:00:00 2001 From: emmorais Date: Wed, 17 Jul 2024 14:29:41 -0300 Subject: [PATCH 09/36] Remove commented code --- src/keyrefresh/keyrefresh_commit.rs | 114 ---------------------------- 1 file changed, 114 deletions(-) diff --git a/src/keyrefresh/keyrefresh_commit.rs b/src/keyrefresh/keyrefresh_commit.rs index eb65ff2f..66bc5f7b 100644 --- a/src/keyrefresh/keyrefresh_commit.rs +++ b/src/keyrefresh/keyrefresh_commit.rs @@ -38,120 +38,6 @@ pub(crate) struct KeyrefreshDecommit { pub As: Vec, } -/// Implement custom serialization for KeyrefreshDecommit. -/*impl Serialize for KeyrefreshDecommit { - fn serialize(&self, s: S) -> std::result::Result { - let mut ser = s.serialize_struct("KeyrefreshDecommit", 5)?; - ser.serialize_field("sid", &self.sid)?; - ser.serialize_field("sender", &self.sender)?; - ser.serialize_field("u_i", &self.u_i)?; - ser.serialize_field("rid", &self.rid)?; - ser.serialize_field("update_publics", &self.update_publics)?; - ser.end() - } -}*/ - -/// FIXME: Next function is calling itself, causing overflow in the stack. But code finally compiles. -/*impl<'de, C: CurveTrait> Deserialize<'de> for KeyrefreshDecommit { - fn deserialize(deserializer: D) -> std::result::Result - where - D: serde::Deserializer<'de> { - let keyrefresh_decommit: KeyrefreshDecommit = serde::Deserialize::deserialize(deserializer)?; - Ok(keyrefresh_decommit) - } -}*/ - -/// Deserialize by deserializing each field individually in order to avoid C: CurveTrait bound. -/*impl<'de, C: CurveTrait> Deserialize<'de> for KeyrefreshDecommit { - fn deserialize(deserializer: D) -> std::result::Result - where - D: serde::Deserializer<'de> { - struct KeyrefreshDecommitVisitor { - marker: std::marker::PhantomData, - } - - impl<'de, C: CurveTrait> serde::de::Visitor<'de> for KeyrefreshDecommitVisitor { - type Value = KeyrefreshDecommit; - - fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { - formatter.write_str("struct KeyrefreshDecommit") - } - - fn visit_map(self, mut map: A) -> std::result::Result - where - A: serde::de::MapAccess<'de>, - { - let mut sid = None; - let mut sender = None; - let mut u_i = None; - let mut rid = None; - let mut update_publics = None; - - while let Some(key) = map.next_key()? { - match key { - "sid" => { - if sid.is_some() { - return Err(serde::de::Error::duplicate_field("sid")); - } - sid = Some(map.next_value()?); - } - "sender" => { - if sender.is_some() { - return Err(serde::de::Error::duplicate_field("sender")); - } - sender = Some(map.next_value()?); - } - "u_i" => { - if u_i.is_some() { - return Err(serde::de::Error::duplicate_field("u_i")); - } - u_i = Some(map.next_value()?); - } - "rid" => { - if rid.is_some() { - return Err(serde::de::Error::duplicate_field("rid")); - } - rid = Some(map.next_value()?); - } - "update_publics" => { - if update_publics.is_some() { - return Err(serde::de::Error::duplicate_field("update_publics")); - } - update_publics = Some(map.next_value()?); - } - _ => { - return Err(serde::de::Error::unknown_field( - key, - &["sid", - "sender", - "u_i", - "rid", - "update_publics"])); - } - } - } - - let sid = sid.ok_or_else(|| serde::de::Error::missing_field("sid"))?; - let sender = sender.ok_or_else(|| serde::de::Error::missing_field("sender"))?; - let u_i = u_i.ok_or_else(|| serde::de::Error::missing_field("u_i"))?; - let rid = rid.ok_or_else(|| serde::de::Error::missing_field("rid"))?; - let update_publics = update_publics.ok_or_else(|| serde::de::Error::missing_field("update_publics"))?; - - Ok(KeyrefreshDecommit { - sid, - sender, - u_i, - rid, - update_publics, - As: Vec::new(), - }) - } - } - - deserializer.deserialize_struct("KeyrefreshDecommit", &["sid", "sender", "u_i", "rid", "update_publics"], KeyrefreshDecommitVisitor { marker: std::marker::PhantomData }) - } -}*/ - impl<'de, C: CurveTrait + Serialize + Deserialize<'de>> KeyrefreshDecommit { ///`sid` corresponds to a unique session identifier. pub(crate) fn new( From 897e388fd384d16a4c18135bcdbea7e1e395e07a Mon Sep 17 00:00:00 2001 From: emmorais Date: Wed, 17 Jul 2024 14:46:33 -0300 Subject: [PATCH 10/36] Replace IDENTITY call in keyrefresh_commit.rs --- src/keyrefresh/keyrefresh_commit.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/keyrefresh/keyrefresh_commit.rs b/src/keyrefresh/keyrefresh_commit.rs index 66bc5f7b..b94ccbab 100644 --- a/src/keyrefresh/keyrefresh_commit.rs +++ b/src/keyrefresh/keyrefresh_commit.rs @@ -128,7 +128,7 @@ impl<'de, C: CurveTrait + Serialize + Deserialize<'de>> KeyrefreshDecommit { // Check that the sum of key updates is identity, i.e. it will not change our // public key. let sum = KeyUpdatePublic::sum(sender, &self.update_publics); - if sum.as_ref() != &CurvePoint::IDENTITY { + if sum.as_ref() != &C::identity() { error!("Sum of key updates is not identity"); return Err(InternalError::ProtocolError(Some(sender))); } From ed642c9d018bd156f3d44ff9fb1db35416045a08 Mon Sep 17 00:00:00 2001 From: emmorais Date: Wed, 17 Jul 2024 16:48:24 -0300 Subject: [PATCH 11/36] Call identity() in keygen/output.rs --- examples/threaded_example/threaded.rs | 2 +- src/curve_point.rs | 8 ++++-- src/keygen/output.rs | 26 ++++++++++---------- src/keygen/participant.rs | 4 +-- src/keyrefresh/input.rs | 11 +++------ src/keyrefresh/keyrefresh_commit.rs | 2 +- src/keyrefresh/participant.rs | 4 +-- src/lib.rs | 3 ++- src/presign/input.rs | 9 +++---- src/presign/participant.rs | 2 +- src/presign/record.rs | 2 +- src/sign/interactive_sign/participant.rs | 13 ++-------- src/sign/non_interactive_sign/participant.rs | 11 ++------- 13 files changed, 40 insertions(+), 57 deletions(-) diff --git a/examples/threaded_example/threaded.rs b/examples/threaded_example/threaded.rs index 2e4f938f..9110848d 100644 --- a/examples/threaded_example/threaded.rs +++ b/examples/threaded_example/threaded.rs @@ -411,7 +411,7 @@ impl Worker { fn new_auxinfo(&mut self, sid: SessionId, key_id: KeyId) -> anyhow::Result<()> { // Note: Missing inputs to aux-info see issues // #242 and #243. - let _output: &Output = self.key_gen_material.retrieve(&key_id); + let _output: &Output = self.key_gen_material.retrieve(&key_id); self.new_sub_protocol::(sid, (), key_id) } diff --git a/src/curve_point.rs b/src/curve_point.rs index 0ac058da..5cea1ae0 100644 --- a/src/curve_point.rs +++ b/src/curve_point.rs @@ -32,7 +32,7 @@ use zeroize::Zeroize; /// private type, `Debug` should be manually implemented with the field of this /// type explicitly redacted! #[derive(Eq, PartialEq, Debug, Clone, Copy, Zeroize)] -pub(crate) struct CurvePoint(k256::ProjectivePoint); +pub struct CurvePoint(k256::ProjectivePoint); impl From for EncodedPoint { fn from(value: CurvePoint) -> EncodedPoint { @@ -47,6 +47,7 @@ impl AsRef for CurvePoint { } impl<'de> CurvePoint { + /// Get the x-coordinate of the curve point in affine representation. pub fn x_affine(&self) -> FieldBytes { self.0.to_affine().x() } @@ -176,8 +177,11 @@ pub(crate) fn random_bn_in_z_star( )) } -pub(crate) trait CurveTrait { +/// Common trait for curves +pub trait CurveTrait { + /// Returns the generator of the curve fn generator() -> CurvePoint; + /// Returns the identity element of the curve fn identity() -> CurvePoint; /// return the order of the curve diff --git a/src/keygen/output.rs b/src/keygen/output.rs index 9250090e..69f4c41e 100644 --- a/src/keygen/output.rs +++ b/src/keygen/output.rs @@ -8,10 +8,7 @@ use std::collections::HashSet; use crate::{ - errors::{CallerError, InternalError, Result}, - keygen::keyshare::{KeySharePrivate, KeySharePublic}, - curve_point::CurvePoint, - ParticipantIdentifier, + curve_point::{CurveTrait}, errors::{CallerError, InternalError, Result}, keygen::keyshare::{KeySharePrivate, KeySharePublic}, ParticipantIdentifier }; use k256::ecdsa::VerifyingKey; @@ -20,20 +17,21 @@ use tracing::error; /// Output type from key generation, including all parties' public key shares, /// this party's private key share, and a bit of global randomness. #[derive(Debug, Clone)] -pub struct Output { +pub struct Output { public_key_shares: Vec, private_key_share: KeySharePrivate, rid: [u8; 32], + _curve: std::marker::PhantomData, } -impl Output { +impl Output { /// Construct the generated public key. pub fn public_key(&self) -> Result { // Add up all the key shares let public_key_point = self .public_key_shares .iter() - .fold(CurvePoint::IDENTITY, |sum, share| sum + *share.as_ref()); + .fold(C::identity(), |sum, share| sum + *share.as_ref()); VerifyingKey::from_encoded_point(&public_key_point.into()).map_err(|_| { error!("Keygen output does not produce a valid public key."); @@ -109,6 +107,7 @@ impl Output { public_key_shares, private_key_share, rid, + _curve: std::marker::PhantomData, }) } @@ -132,8 +131,9 @@ mod tests { use crate::curve_point::testing::init_testing; use crate::{ParticipantConfig, ParticipantIdentifier}; use rand::{CryptoRng, Rng, RngCore}; + use crate::curve_point::CurvePoint; - impl Output { + impl Output { /// Simulate the valid output of a keygen run with the given /// participants. /// @@ -195,10 +195,10 @@ mod tests { let pids = std::iter::repeat_with(|| ParticipantIdentifier::random(rng)) .take(5) .collect::>(); - let output = Output::simulate(&pids, rng); + let output: Output = Output::simulate(&pids, rng); let (public, private, rid) = output.into_parts(); - assert!(Output::from_parts(public, private, rid).is_ok()); + assert!(Output::::from_parts(public, private, rid).is_ok()); } #[test] @@ -209,14 +209,14 @@ mod tests { .collect::>(); // Use the simulate function to get a set of valid public components - let output = Output::simulate(&pids, rng); + let output = Output::::simulate(&pids, rng); // Create a random private share. It's legally possible for this to match one of // the public keys but it's so unlikely that we won't check it. let bad_private_key_share = KeySharePrivate::random(rng); assert!( - Output::from_parts(output.public_key_shares, bad_private_key_share, output.rid) + Output::::from_parts(output.public_key_shares, bad_private_key_share, output.rid) .is_err() ) } @@ -245,7 +245,7 @@ mod tests { let rid = rng.gen(); assert!( - Output::from_parts(public_key_shares, private_key_shares.pop().unwrap(), rid).is_err() + Output::::from_parts(public_key_shares, private_key_shares.pop().unwrap(), rid).is_err() ); } } diff --git a/src/keygen/participant.rs b/src/keygen/participant.rs index 13f32b2b..29f95920 100644 --- a/src/keygen/participant.rs +++ b/src/keygen/participant.rs @@ -109,7 +109,7 @@ pub struct KeygenParticipant { impl ProtocolParticipant for KeygenParticipant { type Input = (); - type Output = Output; + type Output = Output; fn new( sid: Identifier, @@ -641,7 +641,7 @@ mod tests { quorum: &mut [KeygenParticipant], inboxes: &mut HashMap>, rng: &mut R, - ) -> Option<(usize, ProcessOutcome)> { + ) -> Option<(usize, ProcessOutcome>)> { // Pick a random participant to process let index = rng.gen_range(0..quorum.len()); let participant = quorum.get_mut(index).unwrap(); diff --git a/src/keyrefresh/input.rs b/src/keyrefresh/input.rs index 89b2e4e7..ea8db8bc 100644 --- a/src/keyrefresh/input.rs +++ b/src/keyrefresh/input.rs @@ -9,10 +9,7 @@ use std::collections::HashSet; use tracing::error; use crate::{ - auxinfo::{self, AuxInfoPrivate, AuxInfoPublic}, - errors::{CallerError, InternalError, Result}, - keygen::{self, KeySharePrivate, KeySharePublic}, - ParticipantConfig, ParticipantIdentifier, + auxinfo::{self, AuxInfoPrivate, AuxInfoPublic}, curve_point::CurvePoint, errors::{CallerError, InternalError, Result}, keygen::{self, KeySharePrivate, KeySharePublic}, ParticipantConfig, ParticipantIdentifier }; /// Input needed for a @@ -20,7 +17,7 @@ use crate::{ #[derive(Debug, Clone)] pub struct Input { /// The key share material for the key that will be refreshed. - keygen_output: keygen::Output, + keygen_output: keygen::Output, /// The auxiliary info to encrypt/decrypt messages with other participants. auxinfo_output: auxinfo::Output, } @@ -29,7 +26,7 @@ impl Input { /// Creates a new [`Input`] from the outputs of the /// [`auxinfo`](crate::auxinfo::AuxInfoParticipant) and /// [`keygen`](crate::keygen::KeygenParticipant) protocols. - pub fn new(auxinfo_output: auxinfo::Output, keygen_output: keygen::Output) -> Result { + pub fn new(auxinfo_output: auxinfo::Output, keygen_output: keygen::Output) -> Result { // The constructors for keygen and auxinfo output already check other important // properties, like that the private component maps to one of public // components for each one. @@ -54,7 +51,7 @@ impl Input { Ok(input) } - pub fn keygen_output(&self) -> &keygen::Output { + pub fn keygen_output(&self) -> &keygen::Output { &self.keygen_output } diff --git a/src/keyrefresh/keyrefresh_commit.rs b/src/keyrefresh/keyrefresh_commit.rs index b94ccbab..f799042a 100644 --- a/src/keyrefresh/keyrefresh_commit.rs +++ b/src/keyrefresh/keyrefresh_commit.rs @@ -7,7 +7,7 @@ // of this source tree. use crate::{ - curve_point::{CurvePoint, CurveTrait}, errors::{InternalError, Result}, keyrefresh::keyshare::KeyUpdatePublic, messages::{KeyrefreshMessageType, Message, MessageType}, protocol::{Identifier, ParticipantIdentifier} + curve_point::{CurveTrait}, errors::{InternalError, Result}, keyrefresh::keyshare::KeyUpdatePublic, messages::{KeyrefreshMessageType, Message, MessageType}, protocol::{Identifier, ParticipantIdentifier} }; use merlin::Transcript; use rand::{CryptoRng, RngCore}; diff --git a/src/keyrefresh/participant.rs b/src/keyrefresh/participant.rs index d82a8b82..c3a31ae7 100644 --- a/src/keyrefresh/participant.rs +++ b/src/keyrefresh/participant.rs @@ -123,7 +123,7 @@ pub struct KeyrefreshParticipant { impl ProtocolParticipant for KeyrefreshParticipant { type Input = Input; - type Output = Output; + type Output = Output; fn new( sid: Identifier, @@ -944,7 +944,7 @@ mod tests { quorum: &mut [KeyrefreshParticipant], inboxes: &mut HashMap>, rng: &mut R, - ) -> Option<(usize, ProcessOutcome)> { + ) -> Option<(usize, ProcessOutcome>)> { // Pick a random participant to process let index = rng.gen_range(0..quorum.len()); let participant = quorum.get_mut(index).unwrap(); diff --git a/src/lib.rs b/src/lib.rs index 91b45e0e..6271f7da 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -221,7 +221,8 @@ mod protocol; mod ring_pedersen; pub mod sign; mod utils; -mod curve_point; +/// Interface for the curve point operations. +pub mod curve_point; mod zkp; mod zkstar; diff --git a/src/presign/input.rs b/src/presign/input.rs index d39524f9..22276c9b 100644 --- a/src/presign/input.rs +++ b/src/presign/input.rs @@ -9,10 +9,7 @@ use std::collections::HashSet; use tracing::error; use crate::{ - auxinfo::{self, AuxInfoPrivate, AuxInfoPublic}, - errors::{CallerError, InternalError, Result}, - keygen::{self, KeySharePrivate, KeySharePublic}, - ParticipantIdentifier, + auxinfo::{self, AuxInfoPrivate, AuxInfoPublic}, curve_point::CurvePoint, errors::{CallerError, InternalError, Result}, keygen::{self, KeySharePrivate, KeySharePublic}, ParticipantIdentifier }; /// Input needed for a @@ -20,7 +17,7 @@ use crate::{ #[derive(Debug, Clone)] pub struct Input { /// The key share material for the key that will be used in the presign run. - keygen_output: keygen::Output, + keygen_output: keygen::Output, /// The auxiliary info for the key that will be used in the presign run. auxinfo_output: auxinfo::Output, } @@ -29,7 +26,7 @@ impl Input { /// Creates a new [`Input`] from the outputs of the /// [`auxinfo`](crate::auxinfo::AuxInfoParticipant) and /// [`keygen`](crate::keygen::KeygenParticipant) protocols. - pub fn new(auxinfo_output: auxinfo::Output, keygen_output: keygen::Output) -> Result { + pub fn new(auxinfo_output: auxinfo::Output, keygen_output: keygen::Output) -> Result { if auxinfo_output.public_auxinfo().len() != keygen_output.public_key_shares().len() { error!( "Number of auxinfo ({:?}) and keyshare ({:?}) public entries is not equal", diff --git a/src/presign/participant.rs b/src/presign/participant.rs index 1394ed2b..04b9803c 100644 --- a/src/presign/participant.rs +++ b/src/presign/participant.rs @@ -1275,7 +1275,7 @@ mod test { pub(crate) fn presign_record_set_is_valid( records: Vec, - keygen_outputs: Vec, + keygen_outputs: Vec>, ) { // Every presign record has the same `R` value // We don't stick this in a HashSet because `CurvePoint`s can't be hashed :( diff --git a/src/presign/record.rs b/src/presign/record.rs index 52d07c7c..16eb748e 100644 --- a/src/presign/record.rs +++ b/src/presign/record.rs @@ -285,7 +285,7 @@ mod tests { /// For testing only; this does not check that the keygen output set is /// consistent or complete. pub(crate) fn simulate_set( - keygen_outputs: &[keygen::Output], + keygen_outputs: &[keygen::Output], rng: &mut (impl CryptoRng + RngCore), ) -> Vec { // Note: using slightly-biased generation for faster tests diff --git a/src/sign/interactive_sign/participant.rs b/src/sign/interactive_sign/participant.rs index fb7ea250..17950e8d 100644 --- a/src/sign/interactive_sign/participant.rs +++ b/src/sign/interactive_sign/participant.rs @@ -10,16 +10,7 @@ use sha3::{Digest, Keccak256}; use tracing::{error, info}; use crate::{ - auxinfo, - errors::{CallerError, InternalError, Result}, - keygen::{self, KeySharePublic}, - message_queue::MessageQueue, - messages::{Message, MessageType, SignMessageType}, - participant::{ProcessOutcome, Status}, - presign::{self, PresignParticipant, PresignRecord}, - protocol::ProtocolType, - sign::{self, non_interactive_sign::participant::SignParticipant, Signature}, - Identifier, ParticipantIdentifier, ProtocolParticipant, + auxinfo, curve_point::CurvePoint, errors::{CallerError, InternalError, Result}, keygen::{self, KeySharePublic}, message_queue::MessageQueue, messages::{Message, MessageType, SignMessageType}, participant::{ProcessOutcome, Status}, presign::{self, PresignParticipant, PresignRecord}, protocol::ProtocolType, sign::{self, non_interactive_sign::participant::SignParticipant, Signature}, Identifier, ParticipantIdentifier, ProtocolParticipant }; /// A participant that runs the interactive signing protocol in @@ -161,7 +152,7 @@ impl Input { /// "pre-hash" the message. It is hashed here using SHA2-256. pub fn new( message: &[u8], - keygen_output: keygen::Output, + keygen_output: keygen::Output, auxinfo_output: auxinfo::Output, ) -> Result { let presign_input = presign::Input::new(auxinfo_output, keygen_output)?; diff --git a/src/sign/non_interactive_sign/participant.rs b/src/sign/non_interactive_sign/participant.rs index f008dea4..04f10a06 100644 --- a/src/sign/non_interactive_sign/participant.rs +++ b/src/sign/non_interactive_sign/participant.rs @@ -443,14 +443,7 @@ mod test { use tracing::debug; use crate::{ - errors::Result, - keygen, - messages::{Message, MessageType}, - participant::{ProcessOutcome, Status}, - presign::PresignRecord, - sign::{self, Signature}, - curve_point::{bn_to_scalar, testing::init_testing}, - Identifier, ParticipantConfig, ProtocolParticipant, + curve_point::{bn_to_scalar, testing::init_testing, CurvePoint}, errors::Result, keygen, messages::{Message, MessageType}, participant::{ProcessOutcome, Status}, presign::PresignRecord, sign::{self, Signature}, Identifier, ParticipantConfig, ProtocolParticipant }; use super::SignParticipant; @@ -497,7 +490,7 @@ mod test { fn compute_non_distributed_ecdsa( message: &[u8], records: &[PresignRecord], - keygen_outputs: &[keygen::Output], + keygen_outputs: &[keygen::Output], ) -> k256::ecdsa::Signature { let k = records .iter() From c5db00cde337184bb767409383a7d1ec6433e46b Mon Sep 17 00:00:00 2001 From: emmorais Date: Wed, 17 Jul 2024 17:26:53 -0300 Subject: [PATCH 12/36] Replace IDENTITY by identity() --- examples/threaded_example/threaded.rs | 13 ++--- src/protocol.rs | 2 +- src/sign/interactive_sign/participant.rs | 4 +- src/sign/non_interactive_sign/participant.rs | 51 +++++++++----------- 4 files changed, 30 insertions(+), 40 deletions(-) diff --git a/examples/threaded_example/threaded.rs b/examples/threaded_example/threaded.rs index 9110848d..fa0fe255 100644 --- a/examples/threaded_example/threaded.rs +++ b/examples/threaded_example/threaded.rs @@ -36,12 +36,7 @@ use std::{ use tracing::{debug, info, instrument, span, trace, Level}; use tracing_subscriber::{self, EnvFilter}; use tss_ecdsa::{ - auxinfo::AuxInfoParticipant, - keygen::{KeygenParticipant, Output}, - messages::Message, - presign::{self, PresignParticipant}, - sign::{self, SignParticipant}, - Identifier, Participant, ParticipantConfig, ParticipantIdentifier, ProtocolParticipant, + auxinfo::AuxInfoParticipant, curve_point::CurvePoint, keygen::{KeygenParticipant, Output}, messages::Message, presign::{self, PresignParticipant}, sign::{self, SignParticipant}, Identifier, Participant, ParticipantConfig, ParticipantIdentifier, ProtocolParticipant }; use utils::{MessageFromWorker, SubProtocol}; use uuid::Uuid; @@ -326,7 +321,7 @@ struct Worker { /// Outputs of successful presign. presign_records: StoredOutput, /// Signatures generated from successful signing runs. - signatures: StoredOutput, + signatures: StoredOutput>, /// Channel for sending messages to the coordinator. outgoing: Sender, } @@ -428,7 +423,7 @@ impl Worker { let record = self.presign_records.take(&key_id); let inputs = sign::Input::new(b"hello world", record, key_shares.to_vec()); - self.new_sub_protocol::(sid, inputs, key_id) + self.new_sub_protocol::>(sid, inputs, key_id) } } @@ -462,7 +457,7 @@ impl Worker { } fn process_sign(&mut self, sid: SessionId, incoming: Message) -> anyhow::Result<()> { - let (p, key_id) = self.participants.get_mut::(&sid); + let (p, key_id) = self.participants.get_mut::>(&sid); Self::process_message(p, key_id, incoming, &mut self.signatures, &self.outgoing) } } diff --git a/src/protocol.rs b/src/protocol.rs index c4edd702..81ca4340 100644 --- a/src/protocol.rs +++ b/src/protocol.rs @@ -973,7 +973,7 @@ mod tests { .map(|config| { let record = presign_outputs.remove(&config.id()).unwrap(); let input = sign::Input::new(message, record, public_key_shares.clone()); - Participant::::from_config(config, sign_sid, input) + Participant::>::from_config(config, sign_sid, input) }) .collect::>>()?; diff --git a/src/sign/interactive_sign/participant.rs b/src/sign/interactive_sign/participant.rs index 17950e8d..f4d62d1a 100644 --- a/src/sign/interactive_sign/participant.rs +++ b/src/sign/interactive_sign/participant.rs @@ -71,7 +71,7 @@ enum SigningMaterial { }, Signer { // Boxed at the behest of compiler. This type is quite large. - signer: Box, + signer: Box>, }, } @@ -120,7 +120,7 @@ impl SigningMaterial { } } - fn as_mut_signer(&mut self) -> Result<&mut SignParticipant> { + fn as_mut_signer(&mut self) -> Result<&mut SignParticipant> { match self { SigningMaterial::Signer { ref mut signer } => Ok(signer), _ => { diff --git a/src/sign/non_interactive_sign/participant.rs b/src/sign/non_interactive_sign/participant.rs index 04f10a06..47244734 100644 --- a/src/sign/non_interactive_sign/participant.rs +++ b/src/sign/non_interactive_sign/participant.rs @@ -5,7 +5,7 @@ // License, Version 2.0 found in the LICENSE-APACHE file in the root directory // of this source tree. -use std::collections::HashSet; +use std::{collections::HashSet, marker::PhantomData}; use generic_array::{typenum::U32, GenericArray}; use k256::{ @@ -19,17 +19,7 @@ use tracing::{error, info}; use zeroize::Zeroize; use crate::{ - errors::{CallerError, InternalError, Result}, - keygen::KeySharePublic, - local_storage::LocalStorage, - messages::{Message, MessageType, SignMessageType}, - participant::{InnerProtocolParticipant, ProcessOutcome, Status}, - protocol::{ProtocolType, SharedContext}, - run_only_once, - sign::{non_interactive_sign::share::SignatureShare, Signature}, - curve_point::CurvePoint, - zkp::ProofContext, - Identifier, ParticipantConfig, ParticipantIdentifier, PresignRecord, ProtocolParticipant, + curve_point::{CurveTrait}, errors::{CallerError, InternalError, Result}, keygen::KeySharePublic, local_storage::LocalStorage, messages::{Message, MessageType, SignMessageType}, participant::{InnerProtocolParticipant, ProcessOutcome, Status}, protocol::{ProtocolType, SharedContext}, run_only_once, sign::{non_interactive_sign::share::SignatureShare, Signature}, zkp::ProofContext, Identifier, ParticipantConfig, ParticipantIdentifier, PresignRecord, ProtocolParticipant }; /// A participant that runs the non-interactive signing protocol in Figure 8 of @@ -65,23 +55,24 @@ use crate::{ /// with Identifiable Aborts. [EPrint archive, /// 2021](https://eprint.iacr.org/2021/060.pdf). #[derive(Debug)] -pub struct SignParticipant { +pub struct SignParticipant { sid: Identifier, storage: LocalStorage, - input: Input, + input: Input, config: ParticipantConfig, status: Status, } /// Input for the non-interactive signing protocol. #[derive(Debug)] -pub struct Input { +pub struct Input { digest: Keccak256, presign_record: PresignRecord, public_key_shares: Vec, + _curve: std::marker::PhantomData, } -impl Input { +impl Input { /// Construct a new input for signing. /// /// The `public_key_shares` should be the same ones used to generate the @@ -95,6 +86,7 @@ impl Input { digest: Keccak256::new_with_prefix(message), presign_record: record, public_key_shares, + _curve: std::marker::PhantomData::, } } @@ -111,6 +103,7 @@ impl Input { digest, presign_record: record, public_key_shares, + _curve: std::marker::PhantomData::, } } @@ -130,7 +123,7 @@ impl Input { let public_key_point = self .public_key_shares .iter() - .fold(CurvePoint::IDENTITY, |sum, share| sum + *share.as_ref()); + .fold(C::identity(), |sum, share| sum + *share.as_ref()); VerifyingKey::from_encoded_point(&public_key_point.into()).map_err(|_| { error!("Keygen output does not produce a valid public key"); @@ -145,12 +138,13 @@ impl Input { /// Note that this is only used in the case of identifiable abort, which is not /// yet implemented. A correct execution of signing does not involve any ZK /// proofs. -pub(crate) struct SignContext { +pub(crate) struct SignContext { shared_context: SharedContext, message_digest: [u8; 32], + _curve: PhantomData, } -impl ProofContext for SignContext { +impl ProofContext for SignContext { fn as_bytes(&self) -> Result> { Ok([ self.shared_context.as_bytes()?, @@ -160,12 +154,13 @@ impl ProofContext for SignContext { } } -impl SignContext { +impl SignContext { /// Build a [`SignContext`] from a [`SignParticipant`]. - pub(crate) fn collect(p: &SignParticipant) -> Self { + pub(crate) fn collect(p: &SignParticipant) -> Self { Self { shared_context: SharedContext::collect(p), message_digest: p.input.digest_hash().into(), + _curve: PhantomData::, } } } @@ -186,8 +181,8 @@ mod storage { } } -impl ProtocolParticipant for SignParticipant { - type Input = Input; +impl ProtocolParticipant for SignParticipant { + type Input = Input; type Output = Signature; fn ready_type() -> MessageType { @@ -280,8 +275,8 @@ impl ProtocolParticipant for SignParticipant { } } -impl InnerProtocolParticipant for SignParticipant { - type Context = SignContext; +impl InnerProtocolParticipant for SignParticipant { + type Context = SignContext; fn retrieve_context(&self) -> Self::Context { SignContext::collect(self) @@ -300,7 +295,7 @@ impl InnerProtocolParticipant for SignParticipant { } } -impl SignParticipant { +impl SignParticipant { /// Handle a "Ready" message from ourselves. /// /// Once a "Ready" message has been received, continue to generate the round @@ -451,10 +446,10 @@ mod test { /// Pick a random incoming message and have the correct participant process /// it. fn process_messages<'a, R: RngCore + CryptoRng>( - quorum: &'a mut [SignParticipant], + quorum: &'a mut [SignParticipant], inbox: &mut Vec, rng: &mut R, - ) -> Option<(&'a SignParticipant, ProcessOutcome)> { + ) -> Option<(&'a SignParticipant, ProcessOutcome)> { // Pick a random message to process if inbox.is_empty() { return None; From 93f35b8fb09a319f24f733be70c83e60461f09e0 Mon Sep 17 00:00:00 2001 From: emmorais Date: Thu, 18 Jul 2024 16:52:20 -0300 Subject: [PATCH 13/36] More use of CurveTrait, not compiling --- src/auxinfo/participant.rs | 17 +++--------- src/broadcast/participant.rs | 10 ++----- src/keygen/participant.rs | 2 +- src/keyrefresh/keyrefresh_commit.rs | 2 +- src/keyrefresh/keyshare.rs | 29 ++++++++++---------- src/keyrefresh/participant.rs | 8 +++--- src/presign/participant.rs | 2 +- src/protocol.rs | 28 ++++++++----------- src/sign/non_interactive_sign/participant.rs | 4 +-- src/zkp/pisch.rs | 4 +-- 10 files changed, 44 insertions(+), 62 deletions(-) diff --git a/src/auxinfo/participant.rs b/src/auxinfo/participant.rs index c0d18af0..eecffa30 100644 --- a/src/auxinfo/participant.rs +++ b/src/auxinfo/participant.rs @@ -15,18 +15,9 @@ use crate::{ info::{AuxInfoPrivate, AuxInfoPublic, AuxInfoWitnesses}, proof::{AuxInfoProof, CommonInput}, Output, - }, - broadcast::participant::{BroadcastOutput, BroadcastParticipant, BroadcastTag}, - errors::{CallerError, InternalError, Result}, - local_storage::LocalStorage, - messages::{AuxinfoMessageType, Message, MessageType}, - paillier::DecryptionKey, - participant::{ + }, broadcast::participant::{BroadcastOutput, BroadcastParticipant, BroadcastTag}, curve_point::CurvePoint, errors::{CallerError, InternalError, Result}, local_storage::LocalStorage, messages::{AuxinfoMessageType, Message, MessageType}, paillier::DecryptionKey, participant::{ Broadcast, InnerProtocolParticipant, ProcessOutcome, ProtocolParticipant, Status, - }, - protocol::{Identifier, ParticipantIdentifier, ProtocolType, SharedContext}, - ring_pedersen::VerifiedRingPedersen, - run_only_once, + }, protocol::{Identifier, ParticipantIdentifier, ProtocolType, SharedContext}, ring_pedersen::VerifiedRingPedersen, run_only_once }; use rand::{CryptoRng, RngCore}; use tracing::{debug, error, info, instrument}; @@ -221,7 +212,7 @@ impl ProtocolParticipant for AuxInfoParticipant { } impl InnerProtocolParticipant for AuxInfoParticipant { - type Context = SharedContext; + type Context = SharedContext; fn retrieve_context(&self) -> ::Context { SharedContext::collect(self) @@ -761,7 +752,7 @@ mod tests { assert_eq!(outputs.len(), QUORUM_SIZE); let participant_ids = quorum[0].all_participants(); - let context = SharedContext::fill_context(participant_ids, sid); + let context: SharedContext = SharedContext::fill_context(participant_ids, sid); // Check returned outputs // // Every participant should have a public output from every other participant diff --git a/src/broadcast/participant.rs b/src/broadcast/participant.rs index b62235ca..aa3469be 100644 --- a/src/broadcast/participant.rs +++ b/src/broadcast/participant.rs @@ -7,13 +7,7 @@ // of this source tree. use crate::{ - broadcast::data::BroadcastData, - errors::{CallerError, InternalError, Result}, - local_storage::LocalStorage, - messages::{BroadcastMessageType, Message, MessageType}, - participant::{InnerProtocolParticipant, ProcessOutcome, ProtocolParticipant}, - protocol::{ParticipantIdentifier, ProtocolType, SharedContext}, - run_only_once_per_tag, Identifier, + broadcast::data::BroadcastData, curve_point::CurvePoint, errors::{CallerError, InternalError, Result}, local_storage::LocalStorage, messages::{BroadcastMessageType, Message, MessageType}, participant::{InnerProtocolParticipant, ProcessOutcome, ProtocolParticipant}, protocol::{ParticipantIdentifier, ProtocolType, SharedContext}, run_only_once_per_tag, Identifier }; use crate::participant::Status; @@ -170,7 +164,7 @@ impl ProtocolParticipant for BroadcastParticipant { } impl InnerProtocolParticipant for BroadcastParticipant { - type Context = SharedContext; + type Context = SharedContext; /// This method is never used. fn retrieve_context(&self) -> ::Context { diff --git a/src/keygen/participant.rs b/src/keygen/participant.rs index 29f95920..b7694b4d 100644 --- a/src/keygen/participant.rs +++ b/src/keygen/participant.rs @@ -203,7 +203,7 @@ impl ProtocolParticipant for KeygenParticipant { } impl InnerProtocolParticipant for KeygenParticipant { - type Context = SharedContext; + type Context = SharedContext; fn retrieve_context(&self) -> ::Context { SharedContext::collect(self) diff --git a/src/keyrefresh/keyrefresh_commit.rs b/src/keyrefresh/keyrefresh_commit.rs index f799042a..b94ccbab 100644 --- a/src/keyrefresh/keyrefresh_commit.rs +++ b/src/keyrefresh/keyrefresh_commit.rs @@ -7,7 +7,7 @@ // of this source tree. use crate::{ - curve_point::{CurveTrait}, errors::{InternalError, Result}, keyrefresh::keyshare::KeyUpdatePublic, messages::{KeyrefreshMessageType, Message, MessageType}, protocol::{Identifier, ParticipantIdentifier} + curve_point::{CurvePoint, CurveTrait}, errors::{InternalError, Result}, keyrefresh::keyshare::KeyUpdatePublic, messages::{KeyrefreshMessageType, Message, MessageType}, protocol::{Identifier, ParticipantIdentifier} }; use merlin::Transcript; use rand::{CryptoRng, RngCore}; diff --git a/src/keyrefresh/keyshare.rs b/src/keyrefresh/keyshare.rs index bd87fbda..37e1322c 100644 --- a/src/keyrefresh/keyshare.rs +++ b/src/keyrefresh/keyshare.rs @@ -24,7 +24,7 @@ pub struct KeyUpdateEncrypted { impl KeyUpdateEncrypted { pub fn encrypt( - update: &KeyUpdatePrivate, + update: &KeyUpdatePrivate, pk: &EncryptionKey, rng: &mut R, ) -> Result { @@ -40,7 +40,7 @@ impl KeyUpdateEncrypted { Ok(KeyUpdateEncrypted { ciphertext }) } - pub fn decrypt(&self, dk: &DecryptionKey) -> Result { + pub fn decrypt(&self, dk: &DecryptionKey) -> Result> { let x = dk.decrypt(&self.ciphertext).map_err(|_| { error!("KeyUpdateEncrypted decryption failed, ciphertext out of range",); CallerError::DeserializationFailed @@ -49,28 +49,29 @@ impl KeyUpdateEncrypted { error!("KeyUpdateEncrypted decryption failed, plaintext out of range"); Err(CallerError::DeserializationFailed)?; } - Ok(KeyUpdatePrivate { x }) + Ok(KeyUpdatePrivate { x, _curve: std::marker::PhantomData }) } } /// Private update corresponding to a given /// [`Participant`](crate::Participant)'s. #[derive(Clone, ZeroizeOnDrop, PartialEq, Eq, Serialize, Deserialize)] -pub struct KeyUpdatePrivate { +pub struct KeyUpdatePrivate { x: BigNumber, // in the range [1, q) + _curve: std::marker::PhantomData, } -impl Debug for KeyUpdatePrivate { +impl Debug for KeyUpdatePrivate { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.write_str("KeyUpdatePrivate([redacted])") } } -impl KeyUpdatePrivate { +impl KeyUpdatePrivate { /// Sample a private key share uniformly at random. pub(crate) fn random(rng: &mut (impl CryptoRng + RngCore)) -> Self { let random_bn = BigNumber::from_rng(&k256_order(), rng); - KeyUpdatePrivate { x: random_bn } + KeyUpdatePrivate { x: random_bn, _curve: std::marker::PhantomData } } /// Compute a private key share such that the sum of all shares equals 0 mod @@ -80,7 +81,7 @@ impl KeyUpdatePrivate { .iter() .fold(BigNumber::zero(), |sum, o| sum + o.x.clone()); let balance = (-sum).nmod(&k256_order()); - KeyUpdatePrivate { x: balance } + KeyUpdatePrivate { x: balance, _curve: std::marker::PhantomData } } pub(crate) fn sum(shares: &[Self]) -> Self { @@ -88,7 +89,7 @@ impl KeyUpdatePrivate { .iter() .fold(BigNumber::zero(), |sum, o| sum + o.x.clone()) .nmod(&k256_order()); - KeyUpdatePrivate { x: sum } + KeyUpdatePrivate { x: sum, _curve: std::marker::PhantomData } } pub(crate) fn apply(self, current_sk: &KeySharePrivate) -> KeySharePrivate { @@ -100,11 +101,11 @@ impl KeyUpdatePrivate { /// Computes the "raw" curve point corresponding to this private key. pub(crate) fn public_point(&self) -> Result { - CurvePoint::GENERATOR.multiply_by_bignum(&self.x) + C::generator().multiply_by_bignum(&self.x) } } -impl AsRef for KeyUpdatePrivate { +impl AsRef for KeyUpdatePrivate { /// Get the private key share. fn as_ref(&self) -> &BigNumber { &self.x @@ -161,7 +162,7 @@ impl KeyUpdatePublic { pub(crate) fn new_keyshare( participant: ParticipantIdentifier, rng: &mut R, - ) -> Result<(KeyUpdatePrivate, KeyUpdatePublic)> { + ) -> Result<(KeyUpdatePrivate, KeyUpdatePublic)> { let private_share = KeyUpdatePrivate::random(rng); let public_share = private_share.public_point()?; @@ -236,7 +237,7 @@ mod tests { // Encrypt invalid shares. for x in [BigNumber::zero(), -BigNumber::one(), k256_order()].iter() { - let share = KeyUpdatePrivate { x: x.clone() }; + let share = KeyUpdatePrivate:: { x: x.clone(), _curve: std::marker::PhantomData }; let encrypted = KeyUpdateEncrypted::encrypt(&share, &pk, rng).expect("encryption failed"); // Decryption reports an error. @@ -250,7 +251,7 @@ mod tests { // Random shares do not sum to zero. let rng = &mut init_testing(); let mut shares = (0..5) - .map(|_| KeyUpdatePrivate::random(rng)) + .map(|_| KeyUpdatePrivate::::random(rng)) .collect::>(); assert_ne!(KeyUpdatePrivate::sum(&shares).x, BigNumber::zero()); diff --git a/src/keyrefresh/participant.rs b/src/keyrefresh/participant.rs index c3a31ae7..5eabb897 100644 --- a/src/keyrefresh/participant.rs +++ b/src/keyrefresh/participant.rs @@ -48,7 +48,7 @@ mod storage { } pub(super) struct PrivateUpdatesForOthers; impl TypeTag for PrivateUpdatesForOthers { - type Value = Vec; + type Value = Vec>; } pub(super) struct ValidPublicUpdates { /// Marker for the curve type. @@ -59,7 +59,7 @@ mod storage { } pub(super) struct ValidPrivateUpdate; impl TypeTag for ValidPrivateUpdate { - type Value = super::KeyUpdatePrivate; + type Value = super::KeyUpdatePrivate; } } @@ -222,7 +222,7 @@ impl ProtocolParticipant for KeyrefreshParticipant { } impl InnerProtocolParticipant for KeyrefreshParticipant { - type Context = SharedContext; + type Context = SharedContext; fn retrieve_context(&self) -> ::Context { SharedContext::collect(self) @@ -814,7 +814,7 @@ impl KeyrefreshParticipant { } } - fn aggregate_private_updates(update_privates: &[KeyUpdatePrivate]) -> KeyUpdatePrivate { + fn aggregate_private_updates(update_privates: &[KeyUpdatePrivate]) -> KeyUpdatePrivate { KeyUpdatePrivate::sum(update_privates) } diff --git a/src/presign/participant.rs b/src/presign/participant.rs index 04b9803c..e89c833c 100644 --- a/src/presign/participant.rs +++ b/src/presign/participant.rs @@ -79,7 +79,7 @@ mod storage { /// (including this participant). #[derive(Debug)] pub(crate) struct PresignContext { - shared_context: SharedContext, + shared_context: SharedContext, rid: [u8; 32], auxinfo_public: Vec, } diff --git a/src/protocol.rs b/src/protocol.rs index 81ca4340..2c4f4668 100644 --- a/src/protocol.rs +++ b/src/protocol.rs @@ -11,12 +11,7 @@ //! This module includes the main [`Participant`] driver. use crate::{ - errors::{CallerError, InternalError, Result}, - messages::{Message, MessageType}, - participant::{InnerProtocolParticipant, ProtocolParticipant, Status}, - protocol::participant_config::ParticipantConfig, - curve_point::{k256_order, CurvePoint}, - zkp::ProofContext, + curve_point::{k256_order, CurvePoint, CurveTrait}, errors::{CallerError, InternalError, Result}, messages::{Message, MessageType}, participant::{InnerProtocolParticipant, ProtocolParticipant, Status}, protocol::participant_config::ParticipantConfig, zkp::ProofContext }; use libpaillier::unknown_order::BigNumber; use rand::{CryptoRng, Rng, RngCore}; @@ -424,14 +419,14 @@ impl ParticipantIdentifier { /// The `SharedContext` contains fixed known parameters across the entire /// protocol. It does not however contain the entire protocol context. #[derive(Debug, Clone)] -pub(crate) struct SharedContext { +pub(crate) struct SharedContext { sid: Identifier, participants: Vec, - generator: CurvePoint, + generator: C, order: BigNumber, } -impl ProofContext for SharedContext { +impl ProofContext for SharedContext { fn as_bytes(&self) -> Result> { Ok([ self.sid.0.to_be_bytes().into_iter().collect(), @@ -447,7 +442,7 @@ impl ProofContext for SharedContext { } } -impl SharedContext { +impl SharedContext { /// This function should not be used outside of the tests. #[cfg(test)] pub fn random(rng: &mut R) -> Self { @@ -455,9 +450,9 @@ impl SharedContext { let participant = ParticipantIdentifier::random(rng); let participant2 = ParticipantIdentifier::random(rng); let participants = vec![participant, participant2]; - let generator = CurvePoint::GENERATOR; + let generator = C::generator(); let order = k256_order(); - SharedContext { + SharedContext:: { sid, participants, generator, @@ -468,9 +463,9 @@ impl SharedContext { pub(crate) fn collect(p: &P) -> Self { let mut participants = p.all_participants(); participants.sort(); - let generator = CurvePoint::GENERATOR; + let generator = C::generator(); let order = k256_order(); - SharedContext { + SharedContext:: { sid: p.sid(), participants, generator, @@ -480,10 +475,11 @@ impl SharedContext { #[cfg(test)] pub fn fill_context(mut participants: Vec, sid: Identifier) -> Self { participants.sort(); - SharedContext { + let generator = C::generator(); + SharedContext:: { sid, participants, - generator: CurvePoint::GENERATOR, + generator, order: k256_order(), } } diff --git a/src/sign/non_interactive_sign/participant.rs b/src/sign/non_interactive_sign/participant.rs index 47244734..011330ba 100644 --- a/src/sign/non_interactive_sign/participant.rs +++ b/src/sign/non_interactive_sign/participant.rs @@ -19,7 +19,7 @@ use tracing::{error, info}; use zeroize::Zeroize; use crate::{ - curve_point::{CurveTrait}, errors::{CallerError, InternalError, Result}, keygen::KeySharePublic, local_storage::LocalStorage, messages::{Message, MessageType, SignMessageType}, participant::{InnerProtocolParticipant, ProcessOutcome, Status}, protocol::{ProtocolType, SharedContext}, run_only_once, sign::{non_interactive_sign::share::SignatureShare, Signature}, zkp::ProofContext, Identifier, ParticipantConfig, ParticipantIdentifier, PresignRecord, ProtocolParticipant + curve_point::{CurvePoint, CurveTrait}, errors::{CallerError, InternalError, Result}, keygen::KeySharePublic, local_storage::LocalStorage, messages::{Message, MessageType, SignMessageType}, participant::{InnerProtocolParticipant, ProcessOutcome, Status}, protocol::{ProtocolType, SharedContext}, run_only_once, sign::{non_interactive_sign::share::SignatureShare, Signature}, zkp::ProofContext, Identifier, ParticipantConfig, ParticipantIdentifier, PresignRecord, ProtocolParticipant }; /// A participant that runs the non-interactive signing protocol in Figure 8 of @@ -139,7 +139,7 @@ impl Input { /// yet implemented. A correct execution of signing does not involve any ZK /// proofs. pub(crate) struct SignContext { - shared_context: SharedContext, + shared_context: SharedContext, message_digest: [u8; 32], _curve: PhantomData, } diff --git a/src/zkp/pisch.rs b/src/zkp/pisch.rs index 3d9138a7..2beb61ee 100644 --- a/src/zkp/pisch.rs +++ b/src/zkp/pisch.rs @@ -148,7 +148,7 @@ impl Proof for PiSchProof // Do equality checks let response_matches_commitment = { - let lhs = CurvePoint::GENERATOR.multiply_by_bignum(&self.response)?; + let lhs = C::generator().multiply_by_bignum(&self.response)?; let rhs = self.commitment + input.x_commitment.multiply_by_bignum(&self.challenge)?; lhs == rhs }; @@ -167,7 +167,7 @@ impl PiSchProof { // Sample alpha from F_q let randomness_for_commitment = random_positive_bn(rng, &k256_order()); // Form a commitment to the mask - let precommitment = CurvePoint::GENERATOR.multiply_by_bignum(&randomness_for_commitment)?; + let precommitment = C::generator().multiply_by_bignum(&randomness_for_commitment)?; Ok(PiSchPrecommit { precommitment, randomness_for_commitment, From ec97694dee13fc0aeb2a78305d5308508bdc1029 Mon Sep 17 00:00:00 2001 From: emmorais Date: Mon, 22 Jul 2024 10:19:29 -0300 Subject: [PATCH 14/36] Associated type Point in CurveTrait --- src/curve_point.rs | 15 ++++- src/keygen/keygen_commit.rs | 2 +- src/keygen/output.rs | 2 +- src/keygen/participant.rs | 2 +- src/keyrefresh/keyrefresh_commit.rs | 2 +- src/keyrefresh/keyshare.rs | 2 +- src/keyrefresh/participant.rs | 2 +- src/protocol.rs | 2 +- src/sign/non_interactive_sign/participant.rs | 2 +- src/zkp/mod.rs | 8 +-- src/zkp/piaffg.rs | 15 ++--- src/zkp/pienc.rs | 13 ++--- src/zkp/pifac.rs | 12 ++-- src/zkp/pilog.rs | 59 ++++++++++---------- src/zkp/pimod.rs | 10 ++-- src/zkp/piprm.rs | 11 ++-- src/zkp/pisch.rs | 23 ++++---- 17 files changed, 85 insertions(+), 97 deletions(-) diff --git a/src/curve_point.rs b/src/curve_point.rs index 5cea1ae0..3b7fa240 100644 --- a/src/curve_point.rs +++ b/src/curve_point.rs @@ -179,17 +179,24 @@ pub(crate) fn random_bn_in_z_star( /// Common trait for curves pub trait CurveTrait { + /// The type of the point on the curve + type Point; /// Returns the generator of the curve - fn generator() -> CurvePoint; + fn generator() -> Self::Point; /// Returns the identity element of the curve - fn identity() -> CurvePoint; + fn identity() -> Self::Point; /// return the order of the curve fn curve_order() -> BigNumber; + + fn multiply_by_bignum(&self, point: &BigNumber) -> Result where Self: Sized; } /// Implement the CurveTrait for the CurvePoint impl CurveTrait for CurvePoint { + + type Point = CurvePoint; + fn generator() -> CurvePoint { CurvePoint::GENERATOR } @@ -201,6 +208,10 @@ impl CurveTrait for CurvePoint { fn curve_order() -> BigNumber { k256_order() } + + fn multiply_by_bignum(&self, point: &BigNumber) -> Result { + self.multiply_by_bignum(point) + } } // Returns x: BigNumber as a k256::Scalar mod k256_order diff --git a/src/keygen/keygen_commit.rs b/src/keygen/keygen_commit.rs index 557a258b..df903f5f 100644 --- a/src/keygen/keygen_commit.rs +++ b/src/keygen/keygen_commit.rs @@ -49,7 +49,7 @@ impl KeygenDecommit { sid: &Identifier, sender: &ParticipantIdentifier, pk: &KeySharePublic, - sch_precom: &PiSchPrecommit, + sch_precom: &PiSchPrecommit, ) -> Self { let mut rid = [0u8; 32]; let mut u_i = [0u8; 32]; diff --git a/src/keygen/output.rs b/src/keygen/output.rs index 69f4c41e..d2525ad7 100644 --- a/src/keygen/output.rs +++ b/src/keygen/output.rs @@ -24,7 +24,7 @@ pub struct Output { _curve: std::marker::PhantomData, } -impl Output { +impl> Output { /// Construct the generated public key. pub fn public_key(&self) -> Result { // Add up all the key shares diff --git a/src/keygen/participant.rs b/src/keygen/participant.rs index b7694b4d..6280257a 100644 --- a/src/keygen/participant.rs +++ b/src/keygen/participant.rs @@ -36,7 +36,7 @@ mod storage { } pub(super) struct SchnorrPrecom; impl TypeTag for SchnorrPrecom { - type Value = PiSchPrecommit; + type Value = PiSchPrecommit; } pub(super) struct GlobalRid; impl TypeTag for GlobalRid { diff --git a/src/keyrefresh/keyrefresh_commit.rs b/src/keyrefresh/keyrefresh_commit.rs index b94ccbab..05ac6ddf 100644 --- a/src/keyrefresh/keyrefresh_commit.rs +++ b/src/keyrefresh/keyrefresh_commit.rs @@ -38,7 +38,7 @@ pub(crate) struct KeyrefreshDecommit { pub As: Vec, } -impl<'de, C: CurveTrait + Serialize + Deserialize<'de>> KeyrefreshDecommit { +impl<'de, C: CurveTrait + Serialize + Deserialize<'de>> KeyrefreshDecommit { ///`sid` corresponds to a unique session identifier. pub(crate) fn new( rng: &mut R, diff --git a/src/keyrefresh/keyshare.rs b/src/keyrefresh/keyshare.rs index 37e1322c..27d1284a 100644 --- a/src/keyrefresh/keyshare.rs +++ b/src/keyrefresh/keyshare.rs @@ -143,7 +143,7 @@ impl Serialize for KeyUpdatePublic { } } -impl KeyUpdatePublic { +impl> KeyUpdatePublic { pub(crate) fn new(participant: ParticipantIdentifier, share: CurvePoint) -> Self { Self { participant, diff --git a/src/keyrefresh/participant.rs b/src/keyrefresh/participant.rs index 5eabb897..bab61cc2 100644 --- a/src/keyrefresh/participant.rs +++ b/src/keyrefresh/participant.rs @@ -40,7 +40,7 @@ mod storage { } pub(super) struct VecSchnorrPrecom; impl TypeTag for VecSchnorrPrecom { - type Value = Vec; + type Value = Vec>; } pub(super) struct GlobalRid; impl TypeTag for GlobalRid { diff --git a/src/protocol.rs b/src/protocol.rs index 2c4f4668..a70df189 100644 --- a/src/protocol.rs +++ b/src/protocol.rs @@ -442,7 +442,7 @@ impl ProofContext for SharedContext { } } -impl SharedContext { +impl> SharedContext { /// This function should not be used outside of the tests. #[cfg(test)] pub fn random(rng: &mut R) -> Self { diff --git a/src/sign/non_interactive_sign/participant.rs b/src/sign/non_interactive_sign/participant.rs index 011330ba..8c72370a 100644 --- a/src/sign/non_interactive_sign/participant.rs +++ b/src/sign/non_interactive_sign/participant.rs @@ -72,7 +72,7 @@ pub struct Input { _curve: std::marker::PhantomData, } -impl Input { +impl> Input { /// Construct a new input for signing. /// /// The `public_key_shares` should be the same ones used to generate the diff --git a/src/zkp/mod.rs b/src/zkp/mod.rs index 4535cd87..0affc55d 100644 --- a/src/zkp/mod.rs +++ b/src/zkp/mod.rs @@ -21,7 +21,7 @@ pub(crate) mod pimod; pub(crate) mod piprm; pub(crate) mod pisch; -use crate::errors::Result; +use crate::{curve_point::{CurvePoint, CurveTrait}, errors::Result}; use merlin::Transcript; use rand::{CryptoRng, RngCore}; use serde::{de::DeserializeOwned, Serialize}; @@ -55,13 +55,13 @@ impl ProofContext for BadContext { /// the prover and verifier, and the associated type [`Proof::ProverSecret`] /// denotes the data known only to the prover. pub(crate) trait Proof: Sized + Serialize + DeserializeOwned { - type CommonInput<'a>; + type CommonInput<'a, C: CurveTrait> where C: 'a; type ProverSecret<'a>; /// Constructs a zero knowledge proof over [`Proof::ProverSecret`] and /// [`Proof::CommonInput`] using the provided [`Transcript`]. fn prove( - input: Self::CommonInput<'_>, + input: Self::CommonInput<'_, CurvePoint>, secret: Self::ProverSecret<'_>, context: &impl ProofContext, transcript: &mut Transcript, @@ -72,7 +72,7 @@ pub(crate) trait Proof: Sized + Serialize + DeserializeOwned { /// [`Proof::CommonInput`] and [`Transcript`]. fn verify( self, - input: Self::CommonInput<'_>, + input: Self::CommonInput<'_, CurvePoint>, context: &impl ProofContext, transcript: &mut Transcript, ) -> Result<()>; diff --git a/src/zkp/piaffg.rs b/src/zkp/piaffg.rs index cb02f526..d00598a3 100644 --- a/src/zkp/piaffg.rs +++ b/src/zkp/piaffg.rs @@ -39,14 +39,9 @@ //! 2021](https://eprint.iacr.org/2021/060.pdf). use crate::{ - errors::*, - paillier::{Ciphertext, EncryptionKey, MaskedNonce, Nonce, PaillierError}, - parameters::{ELL, ELL_PRIME, EPSILON}, - ring_pedersen::{Commitment, MaskedRandomness, VerifiedRingPedersen}, - utils::{ + curve_point, errors::*, paillier::{Ciphertext, EncryptionKey, MaskedNonce, Nonce, PaillierError}, parameters::{ELL, ELL_PRIME, EPSILON}, ring_pedersen::{Commitment, MaskedRandomness, VerifiedRingPedersen}, utils::{ plusminus_challenge_from_transcript, random_plusminus_by_size, within_bound_by_size, - }, - zkp::{Proof, ProofContext}, + }, zkp::{Proof, ProofContext} }; use libpaillier::unknown_order::BigNumber; use merlin::Transcript; @@ -198,12 +193,12 @@ impl<'a> PiAffgSecret<'a> { } impl Proof for PiAffgProof { - type CommonInput<'a> = PiAffgInput<'a>; + type CommonInput<'a, CurvePoint: curve_point::CurveTrait + 'a> = PiAffgInput<'a>; type ProverSecret<'b> = PiAffgSecret<'b>; #[cfg_attr(feature = "flame_it", flame("PiAffgProof"))] fn prove( - input: Self::CommonInput<'_>, + input: Self::CommonInput<'_, CurvePoint>, secret: Self::ProverSecret<'_>, context: &impl ProofContext, transcript: &mut Transcript, @@ -376,7 +371,7 @@ impl Proof for PiAffgProof { #[cfg_attr(feature = "flame_it", flame("PiAffgProof"))] fn verify( self, - input: Self::CommonInput<'_>, + input: Self::CommonInput<'_, CurvePoint>, context: &impl ProofContext, transcript: &mut Transcript, ) -> Result<()> { diff --git a/src/zkp/pienc.rs b/src/zkp/pienc.rs index 797320cf..e5e29e11 100644 --- a/src/zkp/pienc.rs +++ b/src/zkp/pienc.rs @@ -26,12 +26,7 @@ //! UC Non-Interactive, Proactive, Threshold ECDSA with Identifiable Aborts. //! [EPrint archive, 2021](https://eprint.iacr.org/2021/060.pdf). use crate::{ - errors::*, - paillier::{Ciphertext, EncryptionKey, MaskedNonce, Nonce}, - parameters::{ELL, EPSILON}, - ring_pedersen::{Commitment, MaskedRandomness, VerifiedRingPedersen}, - utils::{plusminus_challenge_from_transcript, random_plusminus_by_size}, - zkp::{Proof, ProofContext}, + curve_point::{self, CurvePoint}, errors::*, paillier::{Ciphertext, EncryptionKey, MaskedNonce, Nonce}, parameters::{ELL, EPSILON}, ring_pedersen::{Commitment, MaskedRandomness, VerifiedRingPedersen}, utils::{plusminus_challenge_from_transcript, random_plusminus_by_size}, zkp::{Proof, ProofContext} }; use libpaillier::unknown_order::BigNumber; use merlin::Transcript; @@ -125,11 +120,11 @@ impl<'a> PiEncSecret<'a> { } impl Proof for PiEncProof { - type CommonInput<'a> = PiEncInput<'a>; + type CommonInput<'a, CurvePoint: curve_point::CurveTrait + 'a> = PiEncInput<'a>; type ProverSecret<'b> = PiEncSecret<'b>; #[cfg_attr(feature = "flame_it", flame("PiEncProof"))] fn prove( - input: Self::CommonInput<'_>, + input: Self::CommonInput<'_, CurvePoint>, secret: Self::ProverSecret<'_>, context: &impl ProofContext, transcript: &mut Transcript, @@ -192,7 +187,7 @@ impl Proof for PiEncProof { #[cfg_attr(feature = "flame_it", flame("PiEncProof"))] fn verify( self, - input: Self::CommonInput<'_>, + input: Self::CommonInput<'_, CurvePoint>, context: &impl ProofContext, transcript: &mut Transcript, ) -> Result<()> { diff --git a/src/zkp/pifac.rs b/src/zkp/pifac.rs index 9b174bc8..be5c2f3e 100644 --- a/src/zkp/pifac.rs +++ b/src/zkp/pifac.rs @@ -18,11 +18,7 @@ //! [EPrint archive, 2021](https://eprint.iacr.org/2021/060.pdf). use crate::{ - errors::*, - parameters::{ELL, EPSILON}, - ring_pedersen::{Commitment, CommitmentRandomness, MaskedRandomness, VerifiedRingPedersen}, - utils::{plusminus_challenge_from_transcript, random_plusminus_scaled}, - zkp::{Proof, ProofContext}, + curve_point::{self, CurvePoint}, errors::*, parameters::{ELL, EPSILON}, ring_pedersen::{Commitment, CommitmentRandomness, MaskedRandomness, VerifiedRingPedersen}, utils::{plusminus_challenge_from_transcript, random_plusminus_scaled}, zkp::{Proof, ProofContext} }; use libpaillier::unknown_order::BigNumber; use merlin::Transcript; @@ -115,12 +111,12 @@ impl<'a> ProverSecret<'a> { } impl Proof for PiFacProof { - type CommonInput<'a> = CommonInput<'a>; + type CommonInput<'a, CurvePoint: curve_point::CurveTrait + 'a> = CommonInput<'a>; type ProverSecret<'a> = ProverSecret<'a>; #[cfg_attr(feature = "flame_it", flame("PiFacProof"))] fn prove<'a, R: RngCore + CryptoRng>( - input: Self::CommonInput<'a>, + input: Self::CommonInput<'a, CurvePoint>, secret: Self::ProverSecret<'a>, context: &impl ProofContext, transcript: &mut Transcript, @@ -198,7 +194,7 @@ impl Proof for PiFacProof { fn verify( self, - input: Self::CommonInput<'_>, + input: Self::CommonInput<'_, CurvePoint>, context: &impl ProofContext, transcript: &mut Transcript, ) -> Result<()> { diff --git a/src/zkp/pilog.rs b/src/zkp/pilog.rs index c810fe73..8a06ad83 100644 --- a/src/zkp/pilog.rs +++ b/src/zkp/pilog.rs @@ -18,15 +18,11 @@ //! [EPrint archive, 2021](https://eprint.iacr.org/2021/060.pdf). use crate::{ - errors::*, - paillier::{Ciphertext, EncryptionKey, MaskedNonce, Nonce}, - parameters::{ELL, EPSILON}, - ring_pedersen::{Commitment, MaskedRandomness, RingPedersen}, - utils::{ + curve_point::{self, CurveTrait}, errors::*, paillier::{Ciphertext, EncryptionKey, MaskedNonce, Nonce}, parameters::{ELL, EPSILON}, ring_pedersen::{Commitment, MaskedRandomness, RingPedersen}, utils::{ plusminus_challenge_from_transcript, random_plusminus_by_size, within_bound_by_size, - }, - zkp::{Proof, ProofContext}, + }, zkp::{Proof, ProofContext} }; +use k256::elliptic_curve::Curve; use libpaillier::unknown_order::BigNumber; use merlin::Transcript; use rand::{CryptoRng, RngCore}; @@ -68,22 +64,22 @@ pub(crate) struct PiLogProof { /// Copying/Cloning references is harmless and sometimes necessary. So we /// implement Clone and Copy for this type. #[derive(Serialize, Clone, Copy)] -pub(crate) struct CommonInput<'a> { +pub(crate) struct CommonInput<'a, C: CurveTrait> { /// Claimed ciphertext of the (secret) [plaintext](ProverSecret::plaintext) /// (`C` in the paper). ciphertext: &'a Ciphertext, /// Claimed discrete log commitment of the (secret) /// [plaintext](ProverSecret::plaintext) (`X` in the paper). - dlog_commit: &'a CurvePoint, + dlog_commit: &'a C::Point, /// Ring-Pedersen commitment scheme (`(Nhat, s, t)` in the paper). ring_pedersen: &'a RingPedersen, /// Paillier public key (`N_0` in the paper). prover_encryption_key: &'a EncryptionKey, // Group generator for discrete log commitments (`g` in the paper). - generator: &'a CurvePoint, + generator: &'a C::Point, } -impl<'a> CommonInput<'a> { +impl<'a, C: CurveTrait> CommonInput<'a, C> { /// Collect common parameters for proving or verifying a [`PiLogProof`] /// about `ciphertext` and `dlog_commit`. /// @@ -95,11 +91,11 @@ impl<'a> CommonInput<'a> { /// 3. `generator` is a group generator. pub(crate) fn new( ciphertext: &'a Ciphertext, - dlog_commit: &'a CurvePoint, + dlog_commit: &'a C::Point, verifier_ring_pedersen: &'a RingPedersen, prover_encryption_key: &'a EncryptionKey, - generator: &'a CurvePoint, - ) -> CommonInput<'a> { + generator: &'a C::Point, + ) -> CommonInput<'a, C::Point> where ::Point: curve_point::CurveTrait { Self { ciphertext, dlog_commit, @@ -139,7 +135,7 @@ impl<'a> ProverSecret<'a> { fn generate_challenge( transcript: &mut Transcript, context: &dyn ProofContext, - common_input: CommonInput, + common_input: CommonInput, plaintext_commit: &Commitment, mask_encryption: &Ciphertext, mask_dlog_commit: &CurvePoint, @@ -164,11 +160,11 @@ fn generate_challenge( } impl Proof for PiLogProof { - type CommonInput<'a> = CommonInput<'a>; + type CommonInput<'a, CurvePoint: curve_point::CurveTrait + 'a> = CommonInput<'a, CurvePoint>; type ProverSecret<'a> = ProverSecret<'a>; #[cfg_attr(feature = "flame_it", flame("PiLogProof"))] fn prove<'a, R: RngCore + CryptoRng>( - input: Self::CommonInput<'a>, + input: Self::CommonInput<'a, CurvePoint>, secret: Self::ProverSecret<'a>, context: &impl ProofContext, transcript: &mut Transcript, @@ -267,7 +263,7 @@ impl Proof for PiLogProof { #[cfg_attr(feature = "flame_it", flame("PiLogProof"))] fn verify<'a>( self, - input: Self::CommonInput<'_>, + input: Self::CommonInput<'_, CurvePoint>, context: &impl ProofContext, transcript: &mut Transcript, ) -> Result<()> { @@ -360,10 +356,10 @@ mod tests { Transcript::new(b"PiLogProof Test") } - fn with_random_paillier_log_proof( + fn with_random_paillier_log_proof>( rng: &mut R, x: &BigNumber, - mut f: impl FnMut(PiLogProof, CommonInput) -> Result<()>, + mut f: impl FnMut(PiLogProof, CommonInput) -> Result<()>, ) -> Result<()> { let (decryption_key, _, _) = DecryptionKey::new(rng).unwrap(); let pk = decryption_key.encryption_key(); @@ -387,11 +383,11 @@ mod tests { f(proof, input) } - fn random_paillier_log_proof_verification( + fn random_paillier_log_proof_verification>( rng: &mut R, x: &BigNumber, ) -> Result<()> { - let f = |proof: PiLogProof, input: CommonInput| { + let f = |proof: PiLogProof, input: CommonInput| { proof.verify(input, &(), &mut transcript())?; Ok(()) }; @@ -403,7 +399,7 @@ mod tests { pilog_proof_with_consistent_secret_inputs_out_of_range::().unwrap(); } - fn pilog_proof_with_consistent_secret_inputs_out_of_range() -> Result<()> { + fn pilog_proof_with_consistent_secret_inputs_out_of_range>() -> Result<()> { let mut rng = init_testing(); let upper_bound = BigNumber::one() << (ELL + EPSILON); loop { @@ -416,7 +412,7 @@ mod tests { // If the input value is larger than the top of the range, the proof won't // verify if too_large > upper_bound { - let f = |bad_proof: PiLogProof, input: CommonInput| { + let f = |bad_proof: PiLogProof, input: CommonInput| { assert!(bad_proof.verify(input, &(), &mut transcript()).is_err()); Ok(()) }; @@ -436,7 +432,7 @@ mod tests { let _ = pilog_proof_with_different_setup_parameters::(); } - fn pilog_proof_with_different_setup_parameters() -> Result<()> { + fn pilog_proof_with_different_setup_parameters>() -> Result<()> { let mut rng = init_testing(); let x = random_plusminus_by_size(&mut rng, ELL); let (decryption_key, _, _) = DecryptionKey::new(&mut rng).unwrap(); @@ -553,7 +549,8 @@ mod tests { let _ = pilog_proof_with_inconsistent_secret_inputs::(); } - fn pilog_proof_with_inconsistent_secret_inputs() -> Result<()> { + fn pilog_proof_with_inconsistent_secret_inputs>() -> Result<()> + { let mut rng = init_testing(); // Make a valid secret @@ -566,7 +563,7 @@ mod tests { let dlog_commit = g.multiply_by_bignum(&x)?; let (ciphertext, rho) = pk.encrypt(&mut rng, &x).unwrap(); let setup_params = VerifiedRingPedersen::gen(&mut rng, &())?; - let input = CommonInput::new(&ciphertext, &dlog_commit, setup_params.scheme(), &pk, &g); + let input = CommonInput::::new(&ciphertext, &dlog_commit, setup_params.scheme(), &pk, &g); // Generate a random plaintext for the secret let bad_x = random_plusminus_by_size(&mut rng, ELL); @@ -602,13 +599,13 @@ mod tests { negative_test_swap_proof_elements::().unwrap(); } - fn negative_test_swap_proof_elements() -> Result<()> { + fn negative_test_swap_proof_elements>() -> Result<()> { let mut rng = init_testing(); // `rng` will be borrowed. We make another rng to be captured by the closure. let mut rng2 = StdRng::from_seed(rng.gen()); let x = random_plusminus_by_size(&mut rng2, ELL); - let f = |proof: PiLogProof, input: CommonInput| { + let f = |proof: PiLogProof, input: CommonInput| { let setup_params = VerifiedRingPedersen::gen(&mut rng, &())?; // Generate some random elements to use as replacements @@ -685,12 +682,12 @@ mod tests { pilog_proof_context_must_be_correct::().unwrap(); } - fn pilog_proof_context_must_be_correct() -> Result<()> { + fn pilog_proof_context_must_be_correct>() -> Result<()> { let mut rng = init_testing(); let context = BadContext {}; let x_small = random_plusminus_by_size(&mut rng, ELL); - let f = |proof: PiLogProof, input: CommonInput| { + let f = |proof: PiLogProof, input: CommonInput| { let result = proof.verify(input, &context, &mut transcript()); assert!(result.is_err()); Ok(()) diff --git a/src/zkp/pimod.rs b/src/zkp/pimod.rs index f4a8cd28..88cd56f9 100644 --- a/src/zkp/pimod.rs +++ b/src/zkp/pimod.rs @@ -33,9 +33,7 @@ //! December 8-12, 2019, Proceedings, Part III, pages 700–727, 2019. use crate::{ - errors::*, - utils::*, - zkp::{Proof, ProofContext}, + curve_point::{self, CurvePoint}, errors::*, utils::*, zkp::{Proof, ProofContext} }; use libpaillier::unknown_order::BigNumber; use merlin::Transcript; @@ -106,14 +104,14 @@ impl<'a> ProverSecret<'a> { } impl Proof for PiModProof { - type CommonInput<'a> = CommonInput<'a>; + type CommonInput<'a, CurvePoint: curve_point::CurveTrait + 'a> = CommonInput<'a>; type ProverSecret<'a> = ProverSecret<'a>; /// Generated by the prover, requires public input N and secrets (p,q) /// Prover generates a random w in Z_N of Jacobi symbol -1 #[allow(clippy::many_single_char_names)] #[cfg_attr(feature = "flame_it", flame("PaillierBlumModulusProof"))] fn prove( - input: Self::CommonInput<'_>, + input: Self::CommonInput<'_, CurvePoint>, secret: Self::ProverSecret<'_>, context: &impl ProofContext, transcript: &mut Transcript, @@ -163,7 +161,7 @@ impl Proof for PiModProof { #[cfg_attr(feature = "flame_it", flame("PaillierBlumModulusProof"))] fn verify( self, - input: Self::CommonInput<'_>, + input: Self::CommonInput<'_, CurvePoint>, context: &impl ProofContext, transcript: &mut Transcript, ) -> Result<()> { diff --git a/src/zkp/piprm.rs b/src/zkp/piprm.rs index 87415d2c..46608543 100644 --- a/src/zkp/piprm.rs +++ b/src/zkp/piprm.rs @@ -23,10 +23,7 @@ //! [EPrint archive, 2021](https://eprint.iacr.org/2021/060.pdf). use crate::{ - errors::*, - ring_pedersen::RingPedersen, - utils::*, - zkp::{Proof, ProofContext}, + curve_point::{self, CurvePoint}, errors::*, ring_pedersen::RingPedersen, utils::*, zkp::{Proof, ProofContext} }; use libpaillier::unknown_order::BigNumber; use merlin::Transcript; @@ -97,11 +94,11 @@ fn generate_challenge_bytes( } impl Proof for PiPrmProof { - type CommonInput<'a> = &'a RingPedersen; + type CommonInput<'a, CurvePoint: curve_point::CurveTrait + 'a> = &'a RingPedersen; type ProverSecret<'a> = PiPrmSecret<'a>; #[cfg_attr(feature = "flame_it", flame("PiPrmProof"))] fn prove( - input: Self::CommonInput<'_>, + input: Self::CommonInput<'_, CurvePoint>, secret: Self::ProverSecret<'_>, context: &impl ProofContext, transcript: &mut Transcript, @@ -141,7 +138,7 @@ impl Proof for PiPrmProof { #[cfg_attr(feature = "flame_it", flame("PiPrmProof"))] fn verify( self, - input: Self::CommonInput<'_>, + input: Self::CommonInput<'_, CurvePoint>, context: &impl ProofContext, transcript: &mut Transcript, ) -> Result<()> { diff --git a/src/zkp/pisch.rs b/src/zkp/pisch.rs index 2beb61ee..3f752ef7 100644 --- a/src/zkp/pisch.rs +++ b/src/zkp/pisch.rs @@ -27,7 +27,7 @@ //! UC Non-Interactive, Proactive, Threshold ECDSA with Identifiable Aborts. //! [EPrint archive, 2021](https://eprint.iacr.org/2021/060.pdf). use crate::{ - curve_point::{k256_order, CurveTrait}, errors::*, messages::{KeygenMessageType, KeyrefreshMessageType, Message, MessageType}, utils::{positive_challenge_from_transcript, random_positive_bn}, zkp::{Proof, ProofContext} + curve_point::{self, k256_order, CurveTrait}, errors::*, messages::{KeygenMessageType, KeyrefreshMessageType, Message, MessageType}, utils::{positive_challenge_from_transcript, random_positive_bn}, zkp::{Proof, ProofContext} }; use libpaillier::unknown_order::BigNumber; use merlin::Transcript; @@ -60,9 +60,9 @@ pub(crate) struct PiSchProof /// convenience; the mask must not be sent to the verifier at any point as this /// breaks the security of the proof. #[derive(Debug, Serialize, Deserialize)] -pub(crate) struct PiSchPrecommit { +pub(crate) struct PiSchPrecommit { /// Precommitment value (`A` in the paper). - precommitment: CurvePoint, + precommitment: C, /// Randomness mask for commitment (`alpha` in the paper). randomness_for_commitment: BigNumber, } @@ -76,7 +76,7 @@ pub(crate) struct CommonInput<'a> { x_commitment: &'a CurvePoint, } -impl PiSchPrecommit { +impl> PiSchPrecommit { pub(crate) fn precommitment(&self) -> &CurvePoint { &self.precommitment } @@ -110,14 +110,13 @@ impl<'a> ProverSecret<'a> { } } -impl Proof for PiSchProof - where C: CurveTrait +impl> Proof for PiSchProof { - type CommonInput<'a> = CommonInput<'a>; + type CommonInput<'a, CurvePoint: curve_point::CurveTrait + 'a> = CommonInput<'a>; type ProverSecret<'a> = ProverSecret<'a>; #[cfg_attr(feature = "flame_it", flame("PiSchProof"))] fn prove( - input: Self::CommonInput<'_>, + input: Self::CommonInput<'_, CurvePoint>, secret: Self::ProverSecret<'_>, context: &impl ProofContext, transcript: &mut Transcript, @@ -131,7 +130,7 @@ impl Proof for PiSchProof #[cfg_attr(feature = "flame_it", flame("PiSchProof"))] fn verify( self, - input: Self::CommonInput<'_>, + input: Self::CommonInput<'_, CurvePoint>, context: &impl ProofContext, transcript: &mut Transcript, ) -> Result<()> { @@ -161,9 +160,9 @@ impl Proof for PiSchProof } } -impl PiSchProof { +impl> PiSchProof { /// "Commitment" phase of the PiSch proof. - pub fn precommit(rng: &mut R) -> Result { + pub fn precommit(rng: &mut R) -> Result> { // Sample alpha from F_q let randomness_for_commitment = random_positive_bn(rng, &k256_order()); // Form a commitment to the mask @@ -177,7 +176,7 @@ impl PiSchProof { /// "Challenge" and "Response" phases of the PiSch proof. pub fn prove_from_precommit( context: &impl ProofContext, - com: &PiSchPrecommit, + com: &PiSchPrecommit, input: &CommonInput, secret: &ProverSecret, transcript: &Transcript, From 4162354b7f887f420f2c7e3d030d20e2fdf60728 Mon Sep 17 00:00:00 2001 From: emmorais Date: Tue, 23 Jul 2024 11:50:42 -0300 Subject: [PATCH 15/36] Continuation, Deserialization missing --- src/curve_point.rs | 10 ++++++---- src/presign/round_three.rs | 2 +- src/presign/round_two.rs | 2 +- src/zkp/pilog.rs | 12 ++++++------ src/zkp/pisch.rs | 4 ++-- 5 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/curve_point.rs b/src/curve_point.rs index 3b7fa240..1696183c 100644 --- a/src/curve_point.rs +++ b/src/curve_point.rs @@ -20,8 +20,10 @@ use k256::{ }; use libpaillier::unknown_order::BigNumber; use rand::{CryptoRng, RngCore}; +use serde::de::DeserializeOwned; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use std::fmt::Debug; +use std::ops::Add; use tracing::error; use zeroize::Zeroize; @@ -178,9 +180,9 @@ pub(crate) fn random_bn_in_z_star( } /// Common trait for curves -pub trait CurveTrait { +pub trait CurveTrait: Serialize + DeserializeOwned + Clone + Debug + Eq + PartialEq + Zeroize + Add { /// The type of the point on the curve - type Point; + type Point: Serialize + DeserializeOwned + Clone + Debug + Eq + PartialEq + Zeroize + Add; /// Returns the generator of the curve fn generator() -> Self::Point; /// Returns the identity element of the curve @@ -197,11 +199,11 @@ impl CurveTrait for CurvePoint { type Point = CurvePoint; - fn generator() -> CurvePoint { + fn generator() -> Self::Point { CurvePoint::GENERATOR } - fn identity() -> CurvePoint { + fn identity() -> Self::Point { CurvePoint::IDENTITY } diff --git a/src/presign/round_three.rs b/src/presign/round_three.rs index 05f7f211..e4afe1b0 100644 --- a/src/presign/round_three.rs +++ b/src/presign/round_three.rs @@ -65,7 +65,7 @@ impl Debug for Private { pub(crate) struct Public { pub delta: Scalar, pub Delta: CurvePoint, - pub psi_double_prime: PiLogProof, + pub psi_double_prime: PiLogProof, /// Gamma value included for convenience pub Gamma: CurvePoint, } diff --git a/src/presign/round_two.rs b/src/presign/round_two.rs index 02e9b920..a0f0d962 100644 --- a/src/presign/round_two.rs +++ b/src/presign/round_two.rs @@ -59,7 +59,7 @@ pub(crate) struct Public { pub Gamma: CurvePoint, pub psi: PiAffgProof, pub psi_hat: PiAffgProof, - pub psi_prime: PiLogProof, + pub psi_prime: PiLogProof, } impl Public { diff --git a/src/zkp/pilog.rs b/src/zkp/pilog.rs index 8a06ad83..6ffac05d 100644 --- a/src/zkp/pilog.rs +++ b/src/zkp/pilog.rs @@ -36,14 +36,14 @@ use crate::curve_point::CurvePoint; /// of a Paillier encryption are equal, and /// 2. the plaintext value is in the valid range (in this case `± 2^{ℓ + ε}`). #[derive(Debug, Clone, Serialize, Deserialize)] -pub(crate) struct PiLogProof { +pub(crate) struct PiLogProof { /// Commitment to the (secret) [plaintext](ProverSecret::plaintext) (`S` in /// the paper). plaintext_commit: Commitment, /// Paillier encryption of mask value (`A` in the paper). mask_ciphertext: Ciphertext, /// Discrete log commitment of mask value (`Y` in the paper). - mask_dlog_commit: CurvePoint, + mask_dlog_commit: C, /// Ring-Pedersen commitment of mask value (`D` in the paper). mask_commit: Commitment, /// Fiat-Shamir challenge (`e` in the paper). @@ -159,8 +159,8 @@ fn generate_challenge( Ok(challenge) } -impl Proof for PiLogProof { - type CommonInput<'a, CurvePoint: curve_point::CurveTrait + 'a> = CommonInput<'a, CurvePoint>; +impl> Proof for PiLogProof { + type CommonInput<'a, CurvePoint: CurveTrait + 'a> = CommonInput<'a, CurvePoint>; type ProverSecret<'a> = ProverSecret<'a>; #[cfg_attr(feature = "flame_it", flame("PiLogProof"))] fn prove<'a, R: RngCore + CryptoRng>( @@ -359,7 +359,7 @@ mod tests { fn with_random_paillier_log_proof>( rng: &mut R, x: &BigNumber, - mut f: impl FnMut(PiLogProof, CommonInput) -> Result<()>, + mut f: impl FnMut(PiLogProof, CommonInput) -> Result<()>, ) -> Result<()> { let (decryption_key, _, _) = DecryptionKey::new(rng).unwrap(); let pk = decryption_key.encryption_key(); @@ -563,7 +563,7 @@ mod tests { let dlog_commit = g.multiply_by_bignum(&x)?; let (ciphertext, rho) = pk.encrypt(&mut rng, &x).unwrap(); let setup_params = VerifiedRingPedersen::gen(&mut rng, &())?; - let input = CommonInput::::new(&ciphertext, &dlog_commit, setup_params.scheme(), &pk, &g); + let input = CommonInput::::new(&ciphertext, &dlog_commit, setup_params.scheme(), &pk, &g); // Generate a random plaintext for the secret let bad_x = random_plusminus_by_size(&mut rng, ELL); diff --git a/src/zkp/pisch.rs b/src/zkp/pisch.rs index 3f752ef7..8101cab1 100644 --- a/src/zkp/pisch.rs +++ b/src/zkp/pisch.rs @@ -44,7 +44,7 @@ pub(crate) struct PiSchProof where C: CurveTrait { /// Commitment to the secret (`A` in the paper). - commitment: CurvePoint, + commitment: C, /// Fiat-Shamir challenge (`e` in the paper). challenge: BigNumber, /// Response binding the commitment randomness used in the commitment (`z` @@ -122,7 +122,7 @@ impl> Proof for PiSchProof transcript: &mut Transcript, rng: &mut R, ) -> Result { - let com = PiSchProof::::precommit(rng)?; + let com = PiSchProof::::precommit(rng)?; let proof = PiSchProof::prove_from_precommit(context, &com, &input, &secret, transcript)?; Ok(proof) } From c074c3929af981a924d783f3d7e59af558201ecb Mon Sep 17 00:00:00 2001 From: emmorais Date: Thu, 25 Jul 2024 09:41:22 -0300 Subject: [PATCH 16/36] Small improvements --- src/curve_point.rs | 5 ++--- src/keyrefresh/keyrefresh_commit.rs | 3 ++- src/protocol.rs | 3 ++- src/zkp/pilog.rs | 3 +-- src/zkp/pisch.rs | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/curve_point.rs b/src/curve_point.rs index 1696183c..91c7dde0 100644 --- a/src/curve_point.rs +++ b/src/curve_point.rs @@ -20,7 +20,6 @@ use k256::{ }; use libpaillier::unknown_order::BigNumber; use rand::{CryptoRng, RngCore}; -use serde::de::DeserializeOwned; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use std::fmt::Debug; use std::ops::Add; @@ -180,9 +179,9 @@ pub(crate) fn random_bn_in_z_star( } /// Common trait for curves -pub trait CurveTrait: Serialize + DeserializeOwned + Clone + Debug + Eq + PartialEq + Zeroize + Add { +pub trait CurveTrait: Serialize + Clone + Debug + Eq + PartialEq + Zeroize + Add { /// The type of the point on the curve - type Point: Serialize + DeserializeOwned + Clone + Debug + Eq + PartialEq + Zeroize + Add; + type Point: Serialize + Clone + Debug + Eq + PartialEq + Zeroize + Add; /// Returns the generator of the curve fn generator() -> Self::Point; /// Returns the identity element of the curve diff --git a/src/keyrefresh/keyrefresh_commit.rs b/src/keyrefresh/keyrefresh_commit.rs index 05ac6ddf..7c4a066f 100644 --- a/src/keyrefresh/keyrefresh_commit.rs +++ b/src/keyrefresh/keyrefresh_commit.rs @@ -7,7 +7,8 @@ // of this source tree. use crate::{ - curve_point::{CurvePoint, CurveTrait}, errors::{InternalError, Result}, keyrefresh::keyshare::KeyUpdatePublic, messages::{KeyrefreshMessageType, Message, MessageType}, protocol::{Identifier, ParticipantIdentifier} + curve_point::CurveTrait, + errors::{InternalError, Result}, keyrefresh::keyshare::KeyUpdatePublic, messages::{KeyrefreshMessageType, Message, MessageType}, protocol::{Identifier, ParticipantIdentifier} }; use merlin::Transcript; use rand::{CryptoRng, RngCore}; diff --git a/src/protocol.rs b/src/protocol.rs index a70df189..283dbb90 100644 --- a/src/protocol.rs +++ b/src/protocol.rs @@ -11,7 +11,7 @@ //! This module includes the main [`Participant`] driver. use crate::{ - curve_point::{k256_order, CurvePoint, CurveTrait}, errors::{CallerError, InternalError, Result}, messages::{Message, MessageType}, participant::{InnerProtocolParticipant, ProtocolParticipant, Status}, protocol::participant_config::ParticipantConfig, zkp::ProofContext + curve_point::{k256_order, CurveTrait}, errors::{CallerError, InternalError, Result}, messages::{Message, MessageType}, participant::{InnerProtocolParticipant, ProtocolParticipant, Status}, protocol::participant_config::ParticipantConfig, zkp::ProofContext }; use libpaillier::unknown_order::BigNumber; use rand::{CryptoRng, Rng, RngCore}; @@ -600,6 +600,7 @@ mod tests { use super::*; use crate::{ auxinfo::AuxInfoParticipant, + curve_point::CurvePoint, keygen::KeygenParticipant, participant::Status, presign, diff --git a/src/zkp/pilog.rs b/src/zkp/pilog.rs index 6ffac05d..75e003c2 100644 --- a/src/zkp/pilog.rs +++ b/src/zkp/pilog.rs @@ -22,7 +22,6 @@ use crate::{ plusminus_challenge_from_transcript, random_plusminus_by_size, within_bound_by_size, }, zkp::{Proof, ProofContext} }; -use k256::elliptic_curve::Curve; use libpaillier::unknown_order::BigNumber; use merlin::Transcript; use rand::{CryptoRng, RngCore}; @@ -159,7 +158,7 @@ fn generate_challenge( Ok(challenge) } -impl> Proof for PiLogProof { +impl<'de, C: CurveTrait + Deserialize<'de>> Proof for PiLogProof { type CommonInput<'a, CurvePoint: CurveTrait + 'a> = CommonInput<'a, CurvePoint>; type ProverSecret<'a> = ProverSecret<'a>; #[cfg_attr(feature = "flame_it", flame("PiLogProof"))] diff --git a/src/zkp/pisch.rs b/src/zkp/pisch.rs index 8101cab1..4ec5cab9 100644 --- a/src/zkp/pisch.rs +++ b/src/zkp/pisch.rs @@ -110,7 +110,7 @@ impl<'a> ProverSecret<'a> { } } -impl> Proof for PiSchProof +impl<'de, C: CurveTrait + Deserialize<'de>> Proof for PiSchProof { type CommonInput<'a, CurvePoint: curve_point::CurveTrait + 'a> = CommonInput<'a>; type ProverSecret<'a> = ProverSecret<'a>; From b1aae029a12fd59d0b672ee5c043e21400242e6b Mon Sep 17 00:00:00 2001 From: emmorais Date: Tue, 30 Jul 2024 14:49:57 -0300 Subject: [PATCH 17/36] Propagate CurveTrait to all places --- src/auxinfo/auxinfo_commit.rs | 23 ++-- src/auxinfo/info.rs | 17 ++- src/auxinfo/output.rs | 20 ++-- src/auxinfo/participant.rs | 32 +++--- src/auxinfo/proof.rs | 53 +++++----- src/curve_point.rs | 15 +-- src/keygen/keygen_commit.rs | 25 ++--- src/keygen/keyshare.rs | 35 +++---- src/keygen/output.rs | 21 ++-- src/keygen/participant.rs | 6 +- src/keyrefresh/input.rs | 18 ++-- src/keyrefresh/keyrefresh_commit.rs | 2 +- src/keyrefresh/keyshare.rs | 6 +- src/keyrefresh/participant.rs | 28 ++--- src/presign/input.rs | 24 ++--- src/presign/participant.rs | 104 ++++++++----------- src/presign/record.rs | 36 +++---- src/presign/round_one.rs | 24 ++--- src/presign/round_three.rs | 33 +++--- src/presign/round_two.rs | 35 +++---- src/protocol.rs | 2 +- src/ring_pedersen.rs | 17 ++- src/sign/interactive_sign/participant.rs | 49 ++++----- src/sign/non_interactive_sign/participant.rs | 18 ++-- src/zkp/mod.rs | 10 +- src/zkp/piaffg.rs | 40 +++---- src/zkp/pienc.rs | 37 ++++--- src/zkp/pifac.rs | 33 +++--- src/zkp/pilog.rs | 42 ++++---- src/zkp/pimod.rs | 24 +++-- src/zkp/piprm.rs | 18 ++-- src/zkp/pisch.rs | 18 ++-- 32 files changed, 397 insertions(+), 468 deletions(-) diff --git a/src/auxinfo/auxinfo_commit.rs b/src/auxinfo/auxinfo_commit.rs index 096c6b79..3c72be80 100644 --- a/src/auxinfo/auxinfo_commit.rs +++ b/src/auxinfo/auxinfo_commit.rs @@ -7,12 +7,7 @@ // of this source tree. use crate::{ - auxinfo::{info::AuxInfoPublic, participant::AuxInfoParticipant}, - errors::{InternalError, Result}, - messages::{AuxinfoMessageType, Message, MessageType}, - parameters::PRIME_BITS, - participant::{InnerProtocolParticipant, ProtocolParticipant}, - protocol::{Identifier, ParticipantIdentifier}, + auxinfo::{info::AuxInfoPublic, participant::AuxInfoParticipant}, curve_point::CurveTrait, errors::{InternalError, Result}, messages::{AuxinfoMessageType, Message, MessageType}, parameters::PRIME_BITS, participant::{InnerProtocolParticipant, ProtocolParticipant}, protocol::{Identifier, ParticipantIdentifier} }; use libpaillier::unknown_order::BigNumber; use merlin::Transcript; @@ -42,14 +37,14 @@ impl Commitment { /// to send decommit to a validly produced [`Commitment`] one needs to send /// [`CommitmentScheme`] itself. #[derive(Serialize, Deserialize, Clone)] -pub(crate) struct CommitmentScheme { +pub(crate) struct CommitmentScheme { /// A unique session identifier (`ssid` in the paper). sid: Identifier, /// This participant's [`ParticipantIdentifier`] (`i` in the paper). pid: ParticipantIdentifier, /// This participant's [`AuxInfoPublic`] (`N_i, s_i, t_i, ψhat_i` in the /// paper). - public_key: AuxInfoPublic, + public_key: AuxInfoPublic, /// This participant's randomness (`ρ_i` in the paper). /// /// This randomness is combined with all other participants' randomness and @@ -62,7 +57,7 @@ pub(crate) struct CommitmentScheme { commit_randomness: [u8; 32], } -impl Debug for CommitmentScheme { +impl Debug for CommitmentScheme { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { // Redacting randomness and commit_randomness because I'm not sure how // sensitive they are. If later analysis suggests they're fine to print, @@ -77,7 +72,7 @@ impl Debug for CommitmentScheme { } } -impl CommitmentScheme { +impl CommitmentScheme { /// Construct a new [`CommitmentScheme`] using the provided unique session /// [`Identifier`], [`AuxInfoParticipant`], and [`AuxInfoPublic`]. /// @@ -86,8 +81,8 @@ impl CommitmentScheme { /// [`AuxInfoParticipant`]. pub(crate) fn new( sid: Identifier, - auxinfo_participant: &AuxInfoParticipant, - public_key: AuxInfoPublic, + auxinfo_participant: &AuxInfoParticipant, + public_key: AuxInfoPublic, rng: &mut R, ) -> Result { let mut rid = [0u8; 32]; @@ -117,7 +112,7 @@ impl CommitmentScheme { /// This method verifies all the internal [`CommitmentScheme`] values. pub(crate) fn from_message( message: &Message, - context: &::Context, + context: & as InnerProtocolParticipant>::Context, ) -> Result { message.check_type(MessageType::Auxinfo(AuxinfoMessageType::R2Decommit))?; let scheme: CommitmentScheme = deserialize!(&message.unverified_bytes)?; @@ -169,7 +164,7 @@ impl CommitmentScheme { self.randomness } - pub(crate) fn into_public(self) -> AuxInfoPublic { + pub(crate) fn into_public(self) -> AuxInfoPublic { self.public_key } diff --git a/src/auxinfo/info.rs b/src/auxinfo/info.rs index 10a1614a..9d61cb86 100644 --- a/src/auxinfo/info.rs +++ b/src/auxinfo/info.rs @@ -7,12 +7,7 @@ // of this source tree. use crate::{ - errors::{CallerError, InternalError, Result}, - paillier::{DecryptionKey, EncryptionKey}, - ring_pedersen::VerifiedRingPedersen, - utils::ParseBytes, - zkp::ProofContext, - ParticipantIdentifier, + curve_point::CurveTrait, errors::{CallerError, InternalError, Result}, paillier::{DecryptionKey, EncryptionKey}, ring_pedersen::VerifiedRingPedersen, utils::ParseBytes, zkp::ProofContext, ParticipantIdentifier }; use k256::elliptic_curve::zeroize::ZeroizeOnDrop; use libpaillier::unknown_order::BigNumber; @@ -144,21 +139,21 @@ impl Debug for AuxInfoPrivate { /// This includes a Paillier encryption key and corresponding ring-Pedersen /// commitment parameters. #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] -pub struct AuxInfoPublic { +pub struct AuxInfoPublic { /// The participant's identifier. participant: ParticipantIdentifier, /// The participant's Paillier public key. pk: EncryptionKey, /// The participant's (verified) ring-Pedersen parameters. - params: VerifiedRingPedersen, + params: VerifiedRingPedersen, } -impl AuxInfoPublic { +impl AuxInfoPublic { pub(crate) fn new( context: &impl ProofContext, participant: ParticipantIdentifier, encryption_key: EncryptionKey, - params: VerifiedRingPedersen, + params: VerifiedRingPedersen, ) -> Result { let public = Self { participant, @@ -173,7 +168,7 @@ impl AuxInfoPublic { &self.pk } - pub(crate) fn params(&self) -> &VerifiedRingPedersen { + pub(crate) fn params(&self) -> &VerifiedRingPedersen { &self.params } diff --git a/src/auxinfo/output.rs b/src/auxinfo/output.rs index 2e6a21bc..7535b7cd 100644 --- a/src/auxinfo/output.rs +++ b/src/auxinfo/output.rs @@ -3,9 +3,7 @@ use std::collections::HashSet; use crate::{ - auxinfo::info::{AuxInfoPrivate, AuxInfoPublic}, - errors::{CallerError, InternalError, Result}, - protocol::ParticipantIdentifier, + auxinfo::info::{AuxInfoPrivate, AuxInfoPublic}, curve_point::CurveTrait, errors::{CallerError, InternalError, Result}, protocol::ParticipantIdentifier }; use tracing::error; @@ -16,19 +14,19 @@ use rand::{CryptoRng, RngCore}; /// This should include an [`AuxInfoPublic`] for every protocol participant /// and an [`AuxInfoPrivate`] for participant that receives this output. #[derive(Debug, Clone)] -pub struct Output { - public_auxinfo: Vec, +pub struct Output { + public_auxinfo: Vec>, private_auxinfo: AuxInfoPrivate, } -impl Output { +impl Output { /// Create a new `Output` from its constituent parts. /// /// The parts must constitute a valid output: /// - the public components should be from a unique set of participants; /// - the private component should have a corresponding public component. pub fn from_parts( - public_auxinfo: Vec, + public_auxinfo: Vec>, private_auxinfo: AuxInfoPrivate, ) -> Result { let pids = public_auxinfo @@ -65,11 +63,11 @@ impl Output { /// after it's securely stored. /// /// The public components can be stored in the clear. - pub fn into_parts(self) -> (Vec, AuxInfoPrivate) { + pub fn into_parts(self) -> (Vec>, AuxInfoPrivate) { (self.public_auxinfo, self.private_auxinfo) } - pub(crate) fn public_auxinfo(&self) -> &[AuxInfoPublic] { + pub(crate) fn public_auxinfo(&self) -> &[AuxInfoPublic] { &self.public_auxinfo } @@ -88,7 +86,7 @@ impl Output { } } - pub(crate) fn find_public(&self, pid: ParticipantIdentifier) -> Option<&AuxInfoPublic> { + pub(crate) fn find_public(&self, pid: ParticipantIdentifier) -> Option<&AuxInfoPublic> { self.public_auxinfo .iter() .find(|public_key| public_key.participant() == pid) @@ -107,7 +105,7 @@ mod tests { ParticipantConfig, }; - impl Output { + impl Output { /// Simulate the valid output of an auxinfo run with the given /// participants. /// diff --git a/src/auxinfo/participant.rs b/src/auxinfo/participant.rs index eecffa30..94a783f5 100644 --- a/src/auxinfo/participant.rs +++ b/src/auxinfo/participant.rs @@ -15,7 +15,7 @@ use crate::{ info::{AuxInfoPrivate, AuxInfoPublic, AuxInfoWitnesses}, proof::{AuxInfoProof, CommonInput}, Output, - }, broadcast::participant::{BroadcastOutput, BroadcastParticipant, BroadcastTag}, curve_point::CurvePoint, errors::{CallerError, InternalError, Result}, local_storage::LocalStorage, messages::{AuxinfoMessageType, Message, MessageType}, paillier::DecryptionKey, participant::{ + }, broadcast::participant::{BroadcastOutput, BroadcastParticipant, BroadcastTag}, curve_point::{CurvePoint, CurveTrait}, errors::{CallerError, InternalError, Result}, local_storage::LocalStorage, messages::{AuxinfoMessageType, Message, MessageType}, paillier::DecryptionKey, participant::{ Broadcast, InnerProtocolParticipant, ProcessOutcome, ProtocolParticipant, Status, }, protocol::{Identifier, ParticipantIdentifier, ProtocolType, SharedContext}, ring_pedersen::VerifiedRingPedersen, run_only_once }; @@ -33,7 +33,7 @@ mod storage { } pub(super) struct Public; impl TypeTag for Public { - type Value = AuxInfoPublic; + type Value = AuxInfoPublic; } pub(super) struct Commit; impl TypeTag for Commit { @@ -41,7 +41,7 @@ mod storage { } pub(super) struct Decommit; impl TypeTag for Decommit { - type Value = CommitmentScheme; + type Value = CommitmentScheme; } pub(super) struct GlobalRid; impl TypeTag for GlobalRid { @@ -101,7 +101,7 @@ mod storage { /// not include the key-refresh steps included in Figure 6. #[derive(Debug)] -pub struct AuxInfoParticipant { +pub struct AuxInfoParticipant { /// The current session identifier sid: Identifier, /// A unique identifier for this participant @@ -115,13 +115,15 @@ pub struct AuxInfoParticipant { broadcast_participant: BroadcastParticipant, /// The status of the protocol execution status: Status, + /// Marker for the curve type + curve_type: std::marker::PhantomData, } -impl ProtocolParticipant for AuxInfoParticipant { +impl ProtocolParticipant for AuxInfoParticipant { type Input = (); // The output type includes `AuxInfoPublic` material for all participants // (including ourselves) and `AuxInfoPrivate` for ourselves. - type Output = Output; + type Output = Output; fn new( sid: Identifier, @@ -211,8 +213,8 @@ impl ProtocolParticipant for AuxInfoParticipant { } } -impl InnerProtocolParticipant for AuxInfoParticipant { - type Context = SharedContext; +impl InnerProtocolParticipant for AuxInfoParticipant { + type Context = SharedContext; fn retrieve_context(&self) -> ::Context { SharedContext::collect(self) @@ -231,13 +233,13 @@ impl InnerProtocolParticipant for AuxInfoParticipant { } } -impl Broadcast for AuxInfoParticipant { +impl Broadcast for AuxInfoParticipant { fn broadcast_participant(&mut self) -> &mut BroadcastParticipant { &mut self.broadcast_participant } } -impl AuxInfoParticipant { +impl AuxInfoParticipant { /// Handle "Ready" messages from the protocol participants. /// /// Once "Ready" messages have been received from all participants, this @@ -591,7 +593,7 @@ impl AuxInfoParticipant { fn new_auxinfo( &self, rng: &mut R, - ) -> Result<(AuxInfoPrivate, AuxInfoPublic, AuxInfoWitnesses)> { + ) -> Result<(AuxInfoPrivate, AuxInfoPublic, AuxInfoWitnesses)> { debug!("Creating new auxinfo."); let (decryption_key, p, q) = DecryptionKey::new(rng).map_err(|_| { @@ -616,7 +618,7 @@ mod tests { use rand::{CryptoRng, Rng, RngCore}; use std::collections::HashMap; - impl AuxInfoParticipant { + impl AuxInfoParticipant { pub fn new_quorum( sid: Identifier, input: (), @@ -657,7 +659,7 @@ mod tests { } } - fn is_auxinfo_done(quorum: &[AuxInfoParticipant]) -> bool { + fn is_auxinfo_done(quorum: &[AuxInfoParticipant]) -> bool { for participant in quorum { if *participant.status() != Status::TerminatedSuccessfully { return false; @@ -671,10 +673,10 @@ mod tests { /// /// Returns None if there are no messages for the selected participant. fn process_messages( - quorum: &mut [AuxInfoParticipant], + quorum: &mut [AuxInfoParticipant], inboxes: &mut HashMap>, rng: &mut R, - ) -> Option<(usize, ProcessOutcome)> { + ) -> Option<(usize, ProcessOutcome>)> { // Pick a random participant to process let index = rng.gen_range(0..quorum.len()); let participant = quorum.get_mut(index).unwrap(); diff --git a/src/auxinfo/proof.rs b/src/auxinfo/proof.rs index 37498950..2b0cdd60 100644 --- a/src/auxinfo/proof.rs +++ b/src/auxinfo/proof.rs @@ -7,12 +7,7 @@ // of this source tree. use crate::{ - auxinfo::participant::AuxInfoParticipant, - errors::Result, - messages::{AuxinfoMessageType, Message, MessageType}, - participant::InnerProtocolParticipant, - ring_pedersen::VerifiedRingPedersen, - Identifier, ParticipantIdentifier, + auxinfo::participant::AuxInfoParticipant, curve_point::CurveTrait, errors::Result, messages::{AuxinfoMessageType, Message, MessageType}, participant::InnerProtocolParticipant, ring_pedersen::VerifiedRingPedersen, Identifier, ParticipantIdentifier }; use crate::zkp::{pifac, pimod, Proof, ProofContext}; @@ -26,32 +21,32 @@ use serde::{Deserialize, Serialize}; /// /// This type includes proofs for `𝚷[fac]` and `𝚷[mod]`. #[derive(Serialize, Deserialize, Clone)] -pub(crate) struct AuxInfoProof { - pimod: pimod::PiModProof, - pifac: pifac::PiFacProof, +pub(crate) struct AuxInfoProof { + pimod: pimod::PiModProof::, + pifac: pifac::PiFacProof::, } /// Common input and setup parameters known to both the prover and the verifier. #[derive(Clone)] -pub(crate) struct CommonInput<'a> { - shared_context: &'a ::Context, +pub(crate) struct CommonInput<'a, C: CurveTrait> { + shared_context: &'a as InnerProtocolParticipant>::Context, sid: Identifier, rho: [u8; 32], pid: ParticipantIdentifier, - setup_parameters: &'a VerifiedRingPedersen, + setup_parameters: &'a VerifiedRingPedersen, modulus: &'a BigNumber, } -impl<'a> CommonInput<'a> { +impl<'a, C: CurveTrait> CommonInput<'a, C> { /// Collect common parameters for proving or verifying a [`AuxInfoProof`] pub(crate) fn new( - shared_context: &'a ::Context, + shared_context: &'a as InnerProtocolParticipant>::Context, sid: Identifier, rho: [u8; 32], pid: ParticipantIdentifier, - verifier_setup_parameters: &'a VerifiedRingPedersen, + verifier_setup_parameters: &'a VerifiedRingPedersen, modulus: &'a BigNumber, - ) -> CommonInput<'a> { + ) -> CommonInput<'a, C> { Self { shared_context, sid, @@ -63,7 +58,7 @@ impl<'a> CommonInput<'a> { } } -impl AuxInfoProof { +impl AuxInfoProof { /// Generate a fresh transcript to be used in [`AuxInfoProof`]. fn new_transcript() -> Transcript { Transcript::new(b"AuxInfoProof") @@ -88,7 +83,7 @@ impl AuxInfoProof { #[allow(clippy::too_many_arguments)] pub(crate) fn prove( rng: &mut R, - common_input: &CommonInput, + common_input: &CommonInput, p: &BigNumber, q: &BigNumber, ) -> Result { @@ -100,7 +95,7 @@ impl AuxInfoProof { common_input.rho, common_input.pid, )?; - let pimod = pimod::PiModProof::prove( + let pimod: pimod::PiModProof:: = pimod::PiModProof::::prove( pimod::CommonInput::new(common_input.modulus), pimod::ProverSecret::new(p, q), common_input.shared_context, @@ -114,7 +109,7 @@ impl AuxInfoProof { common_input.rho, common_input.pid, )?; - let pifac = pifac::PiFacProof::prove( + let pifac = pifac::PiFacProof::::prove( pifac::CommonInput::new(common_input.setup_parameters, common_input.modulus), pifac::ProverSecret::new(p, q), common_input.shared_context, @@ -131,7 +126,7 @@ impl AuxInfoProof { /// /// Note: The [`VerifiedRingPedersen`] argument **must be** provided by the /// verifier! - pub(crate) fn verify(self, common_input: &CommonInput) -> Result<()> { + pub(crate) fn verify(self, common_input: &CommonInput) -> Result<()> { let mut transcript = Self::new_transcript(); Self::append_pimod_transcript( &mut transcript, @@ -164,7 +159,7 @@ impl AuxInfoProof { /// [`Transcript`]. fn append_pimod_transcript( transcript: &mut Transcript, - context: &::Context, + context: & as InnerProtocolParticipant>::Context, sid: Identifier, rho: [u8; 32], pid: ParticipantIdentifier, @@ -181,7 +176,7 @@ impl AuxInfoProof { /// [`Transcript`]. fn append_pifac_transcript( transcript: &mut Transcript, - context: &::Context, + context: & as InnerProtocolParticipant>::Context, sid: Identifier, rho: [u8; 32], pid: ParticipantIdentifier, @@ -198,23 +193,23 @@ impl AuxInfoProof { #[cfg(test)] mod tests { use super::*; - use crate::{paillier::prime_gen, protocol::SharedContext, curve_point::testing::init_testing}; + use crate::{curve_point::{testing::init_testing, CurvePoint}, paillier::prime_gen, protocol::SharedContext}; use rand::{rngs::StdRng, Rng, SeedableRng}; fn random_auxinfo_proof( rng: &mut R, - test_code: impl FnOnce(CommonInput, AuxInfoProof) -> Result<()>, + test_code: impl FnOnce(CommonInput, AuxInfoProof) -> Result<()>, ) -> Result<()> { let sid = Identifier::random(rng); let rho = rng.gen(); let pid = ParticipantIdentifier::random(rng); - let setup_params = VerifiedRingPedersen::gen(rng, &()).unwrap(); + let setup_params = VerifiedRingPedersen::::gen(rng, &()).unwrap(); let (p, q) = prime_gen::get_prime_pair_from_pool_insecure(rng).unwrap(); let modulus = &p * &q; let shared_context = SharedContext::random(rng); let common_input = CommonInput::new(&shared_context, sid, rho, pid, &setup_params, &modulus); - let proof = AuxInfoProof::prove(rng, &common_input, &p, &q).unwrap(); + let proof = AuxInfoProof::::prove(rng, &common_input, &p, &q).unwrap(); test_code(common_input, proof) } @@ -224,13 +219,13 @@ mod tests { let sid = Identifier::random(&mut rng); let rho = rng.gen(); let pid = ParticipantIdentifier::random(&mut rng); - let setup_params = VerifiedRingPedersen::gen(&mut rng, &())?; + let setup_params = VerifiedRingPedersen::::gen(&mut rng, &())?; let (p, q) = prime_gen::get_prime_pair_from_pool_insecure(&mut rng).unwrap(); let modulus = &p * &q; let shared_context = SharedContext::random(&mut rng); let common_input = CommonInput::new(&shared_context, sid, rho, pid, &setup_params, &modulus); - let proof = AuxInfoProof::prove(&mut rng, &common_input, &p, &q)?; + let proof = AuxInfoProof::::prove(&mut rng, &common_input, &p, &q)?; assert!(proof.verify(&common_input).is_ok()); Ok(()) } diff --git a/src/curve_point.rs b/src/curve_point.rs index 91c7dde0..157af3a4 100644 --- a/src/curve_point.rs +++ b/src/curve_point.rs @@ -71,7 +71,6 @@ impl<'de> CurvePoint { /// converting it. This may be insecure if the point contains private /// data. pub(crate) fn multiply_by_bignum(&self, point: &BigNumber) -> Result { - //Ok(self.multiply_by_scalar(&bn_to_scalar::(point)?)) Ok(self.multiply_by_scalar(&bn_to_scalar(point)?)) } @@ -110,7 +109,7 @@ impl<'de> CurvePoint { impl std::ops::Add for CurvePoint { type Output = Self; - fn add(self, rhs: Self) -> Self::Output { + fn add(self, rhs: Self) -> Self { Self(self.0 + rhs.0) } } @@ -180,12 +179,10 @@ pub(crate) fn random_bn_in_z_star( /// Common trait for curves pub trait CurveTrait: Serialize + Clone + Debug + Eq + PartialEq + Zeroize + Add { - /// The type of the point on the curve - type Point: Serialize + Clone + Debug + Eq + PartialEq + Zeroize + Add; /// Returns the generator of the curve - fn generator() -> Self::Point; + fn generator() -> Self; /// Returns the identity element of the curve - fn identity() -> Self::Point; + fn identity() -> Self; /// return the order of the curve fn curve_order() -> BigNumber; @@ -196,13 +193,11 @@ pub trait CurveTrait: Serialize + Clone + Debug + Eq + PartialEq + Zeroize + Add /// Implement the CurveTrait for the CurvePoint impl CurveTrait for CurvePoint { - type Point = CurvePoint; - - fn generator() -> Self::Point { + fn generator() -> Self { CurvePoint::GENERATOR } - fn identity() -> Self::Point { + fn identity() -> Self { CurvePoint::IDENTITY } diff --git a/src/keygen/keygen_commit.rs b/src/keygen/keygen_commit.rs index df903f5f..88e2c103 100644 --- a/src/keygen/keygen_commit.rs +++ b/src/keygen/keygen_commit.rs @@ -7,16 +7,11 @@ // of this source tree. use crate::{ - errors::{InternalError, Result}, - keygen::keyshare::KeySharePublic, - messages::{KeygenMessageType, Message, MessageType}, - protocol::{Identifier, ParticipantIdentifier}, - curve_point::CurvePoint, - zkp::pisch::PiSchPrecommit, + curve_point::CurveTrait, errors::{InternalError, Result}, keygen::keyshare::KeySharePublic, messages::{KeygenMessageType, Message, MessageType}, protocol::{Identifier, ParticipantIdentifier}, zkp::pisch::PiSchPrecommit }; use merlin::Transcript; use rand::{CryptoRng, RngCore}; -use serde::{Deserialize, Serialize}; +use serde::{de::DeserializeOwned, Deserialize, Serialize}; use tracing::{error, instrument}; #[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)] @@ -32,24 +27,24 @@ impl KeygenCommit { } #[derive(Debug, Serialize, Deserialize, Clone)] -pub(crate) struct KeygenDecommit { +pub(crate) struct KeygenDecommit { ///`sid` corresponds to a unique session identifier. pub sid: Identifier, pub sender: ParticipantIdentifier, pub rid: [u8; 32], pub u_i: [u8; 32], - pub pk: KeySharePublic, - pub A: CurvePoint, + pub pk: KeySharePublic, + pub A: C, } -impl KeygenDecommit { +impl KeygenDecommit { ///`sid` corresponds to a unique session identifier. pub(crate) fn new( rng: &mut R, sid: &Identifier, sender: &ParticipantIdentifier, - pk: &KeySharePublic, - sch_precom: &PiSchPrecommit, + pk: &KeySharePublic, + sch_precom: &PiSchPrecommit, ) -> Self { let mut rid = [0u8; 32]; let mut u_i = [0u8; 32]; @@ -68,12 +63,12 @@ impl KeygenDecommit { /// Deserialize a KeygenDecommit from a message and verify it. pub(crate) fn from_message(message: &Message, com: &KeygenCommit) -> Result { message.check_type(MessageType::Keygen(KeygenMessageType::R2Decommit))?; - let keygen_decommit: KeygenDecommit = deserialize!(&message.unverified_bytes)?; + let keygen_decommit: KeygenDecommit = deserialize!(&message.unverified_bytes)?; keygen_decommit.verify(message.id(), message.from(), com)?; Ok(keygen_decommit) } - pub(crate) fn get_keyshare(&self) -> &KeySharePublic { + pub(crate) fn get_keyshare(&self) -> &KeySharePublic { &self.pk } diff --git a/src/keygen/keyshare.rs b/src/keygen/keyshare.rs index 28144c8b..b244f9bc 100644 --- a/src/keygen/keyshare.rs +++ b/src/keygen/keyshare.rs @@ -7,10 +7,7 @@ // of this source tree. use crate::{ - errors::{CallerError, Result}, - curve_point::{k256_order, CurvePoint}, - utils::ParseBytes, - ParticipantIdentifier, + curve_point::{k256_order, CurveTrait}, errors::{CallerError, Result}, utils::ParseBytes, ParticipantIdentifier }; use libpaillier::unknown_order::BigNumber; use rand::{CryptoRng, RngCore}; @@ -27,17 +24,19 @@ const KEYSHARE_TAG: &[u8] = b"KeySharePrivate"; /// # 🔒 Storage requirements /// This type must be stored securely by the calling application. #[derive(Clone, PartialEq, Eq)] -pub struct KeySharePrivate { +pub struct KeySharePrivate { x: BigNumber, // in the range [1, q) + /// Marker to pin the generic type. + curve: std::marker::PhantomData, } -impl Debug for KeySharePrivate { +impl Debug for KeySharePrivate { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.write_str("KeySharePrivate([redacted])") } } -impl KeySharePrivate { +impl KeySharePrivate { /// Sample a private key share uniformly at random. pub(crate) fn random(rng: &mut (impl CryptoRng + RngCore)) -> Self { let random_bn = BigNumber::from_rng(&k256_order(), rng); @@ -52,8 +51,8 @@ impl KeySharePrivate { } /// Computes the "raw" curve point corresponding to this private key. - pub(crate) fn public_share(&self) -> Result { - CurvePoint::GENERATOR.multiply_by_bignum(&self.x) + pub(crate) fn public_share(&self) -> Result { + C::generator().multiply_by_bignum(&self.x) } /// Convert private material into bytes. @@ -134,7 +133,7 @@ impl KeySharePrivate { } } -impl AsRef for KeySharePrivate { +impl AsRef for KeySharePrivate { /// Get the private key share. fn as_ref(&self) -> &BigNumber { &self.x @@ -144,13 +143,13 @@ impl AsRef for KeySharePrivate { /// A curve point representing a given [`Participant`](crate::Participant)'s /// public key. #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] -pub struct KeySharePublic { +pub struct KeySharePublic { participant: ParticipantIdentifier, - X: CurvePoint, + X: C, } -impl KeySharePublic { - pub(crate) fn new(participant: ParticipantIdentifier, share: CurvePoint) -> Self { +impl KeySharePublic { + pub(crate) fn new(participant: ParticipantIdentifier, share: C) -> Self { Self { participant, X: share, @@ -167,20 +166,20 @@ impl KeySharePublic { pub(crate) fn new_keyshare( participant: ParticipantIdentifier, rng: &mut R, - ) -> Result<(KeySharePrivate, KeySharePublic)> { + ) -> Result<(KeySharePrivate, KeySharePublic)> { let private_share = KeySharePrivate::random(rng); let public_share = private_share.public_share()?; Ok(( private_share, - KeySharePublic::new(participant, public_share), + KeySharePublic::::new(participant, public_share), )) } } -impl AsRef for KeySharePublic { +impl AsRef for KeySharePublic { /// Get the public curvepoint which is the public key share. - fn as_ref(&self) -> &CurvePoint { + fn as_ref(&self) -> &C { &self.X } } diff --git a/src/keygen/output.rs b/src/keygen/output.rs index d2525ad7..6f86265e 100644 --- a/src/keygen/output.rs +++ b/src/keygen/output.rs @@ -8,7 +8,7 @@ use std::collections::HashSet; use crate::{ - curve_point::{CurveTrait}, errors::{CallerError, InternalError, Result}, keygen::keyshare::{KeySharePrivate, KeySharePublic}, ParticipantIdentifier + curve_point::CurveTrait, errors::{CallerError, InternalError, Result}, keygen::keyshare::{KeySharePrivate, KeySharePublic}, ParticipantIdentifier }; use k256::ecdsa::VerifyingKey; @@ -18,13 +18,12 @@ use tracing::error; /// this party's private key share, and a bit of global randomness. #[derive(Debug, Clone)] pub struct Output { - public_key_shares: Vec, - private_key_share: KeySharePrivate, + public_key_shares: Vec>, + private_key_share: KeySharePrivate, rid: [u8; 32], - _curve: std::marker::PhantomData, } -impl> Output { +impl Output { /// Construct the generated public key. pub fn public_key(&self) -> Result { // Add up all the key shares @@ -40,11 +39,11 @@ impl> Output { } /// Get the individual shares of the public key. - pub fn public_key_shares(&self) -> &[KeySharePublic] { + pub fn public_key_shares(&self) -> &[KeySharePublic] { &self.public_key_shares } - pub(crate) fn private_key_share(&self) -> &KeySharePrivate { + pub(crate) fn private_key_share(&self) -> &KeySharePrivate { &self.private_key_share } @@ -81,13 +80,13 @@ impl> Output { /// the private key share must be contained in the list of public shares. /// - The public key shares must be from a unique set of participants pub fn from_parts( - public_key_shares: Vec, - private_key_share: KeySharePrivate, + public_key_shares: Vec>, + private_key_share: KeySharePrivate, rid: [u8; 32], ) -> Result { let pids = public_key_shares .iter() - .map(KeySharePublic::participant) + .map(KeySharePublic::::participant) .collect::>(); if pids.len() != public_key_shares.len() { error!("Tried to create a keygen output using a set of public material from non-unique participants"); @@ -120,7 +119,7 @@ impl> Output { /// /// The public components (including the byte array and the public key /// shares) can be stored in the clear. - pub fn into_parts(self) -> (Vec, KeySharePrivate, [u8; 32]) { + pub fn into_parts(self) -> (Vec>, KeySharePrivate, [u8; 32]) { (self.public_key_shares, self.private_key_share, self.rid) } } diff --git a/src/keygen/participant.rs b/src/keygen/participant.rs index 6280257a..852d0d68 100644 --- a/src/keygen/participant.rs +++ b/src/keygen/participant.rs @@ -32,7 +32,7 @@ mod storage { } pub(super) struct Decommit; impl TypeTag for Decommit { - type Value = KeygenDecommit; + type Value = KeygenDecommit; } pub(super) struct SchnorrPrecom; impl TypeTag for SchnorrPrecom { @@ -44,11 +44,11 @@ mod storage { } pub(super) struct PrivateKeyshare; impl TypeTag for PrivateKeyshare { - type Value = KeySharePrivate; + type Value = KeySharePrivate; } pub(super) struct PublicKeyshare; impl TypeTag for PublicKeyshare { - type Value = KeySharePublic; + type Value = KeySharePublic; } } diff --git a/src/keyrefresh/input.rs b/src/keyrefresh/input.rs index ea8db8bc..f299d092 100644 --- a/src/keyrefresh/input.rs +++ b/src/keyrefresh/input.rs @@ -9,24 +9,24 @@ use std::collections::HashSet; use tracing::error; use crate::{ - auxinfo::{self, AuxInfoPrivate, AuxInfoPublic}, curve_point::CurvePoint, errors::{CallerError, InternalError, Result}, keygen::{self, KeySharePrivate, KeySharePublic}, ParticipantConfig, ParticipantIdentifier + auxinfo::{self, AuxInfoPrivate, AuxInfoPublic}, curve_point::{CurvePoint, CurveTrait}, errors::{CallerError, InternalError, Result}, keygen::{self, KeySharePrivate, KeySharePublic}, ParticipantConfig, ParticipantIdentifier }; /// Input needed for a /// [`KeyrefreshParticipant`](crate::keyrefresh::KeyrefreshParticipant) to run. #[derive(Debug, Clone)] -pub struct Input { +pub struct Input { /// The key share material for the key that will be refreshed. - keygen_output: keygen::Output, + keygen_output: keygen::Output, /// The auxiliary info to encrypt/decrypt messages with other participants. - auxinfo_output: auxinfo::Output, + auxinfo_output: auxinfo::Output, } -impl Input { +impl Input { /// Creates a new [`Input`] from the outputs of the /// [`auxinfo`](crate::auxinfo::AuxInfoParticipant) and /// [`keygen`](crate::keygen::KeygenParticipant) protocols. - pub fn new(auxinfo_output: auxinfo::Output, keygen_output: keygen::Output) -> Result { + pub fn new(auxinfo_output: auxinfo::Output, keygen_output: keygen::Output) -> Result { // The constructors for keygen and auxinfo output already check other important // properties, like that the private component maps to one of public // components for each one. @@ -91,7 +91,7 @@ impl Input { Ok(()) } - pub(crate) fn public_key_shares(&self) -> &[KeySharePublic] { + pub(crate) fn public_key_shares(&self) -> &[KeySharePublic] { self.keygen_output.public_key_shares() } @@ -101,7 +101,7 @@ impl Input { /// Returns the [`AuxInfoPublic`] associated with the given /// [`ParticipantIdentifier`]. - pub(crate) fn find_auxinfo_public(&self, pid: ParticipantIdentifier) -> Result<&AuxInfoPublic> { + pub(crate) fn find_auxinfo_public(&self, pid: ParticipantIdentifier) -> Result<&AuxInfoPublic> { self.auxinfo_output.find_public(pid) .ok_or_else(|| { error!("Presign input doesn't contain a public auxinfo for {}, even though we checked for it at construction.", pid); @@ -109,7 +109,7 @@ impl Input { }) } - pub(crate) fn private_key_share(&self) -> &KeySharePrivate { + pub(crate) fn private_key_share(&self) -> &KeySharePrivate { self.keygen_output.private_key_share() } } diff --git a/src/keyrefresh/keyrefresh_commit.rs b/src/keyrefresh/keyrefresh_commit.rs index 7c4a066f..a281fa32 100644 --- a/src/keyrefresh/keyrefresh_commit.rs +++ b/src/keyrefresh/keyrefresh_commit.rs @@ -39,7 +39,7 @@ pub(crate) struct KeyrefreshDecommit { pub As: Vec, } -impl<'de, C: CurveTrait + Serialize + Deserialize<'de>> KeyrefreshDecommit { +impl<'de, C: CurveTrait + Serialize + Deserialize<'de>> KeyrefreshDecommit { ///`sid` corresponds to a unique session identifier. pub(crate) fn new( rng: &mut R, diff --git a/src/keyrefresh/keyshare.rs b/src/keyrefresh/keyshare.rs index 27d1284a..e7d652de 100644 --- a/src/keyrefresh/keyshare.rs +++ b/src/keyrefresh/keyshare.rs @@ -92,7 +92,7 @@ impl KeyUpdatePrivate { KeyUpdatePrivate { x: sum, _curve: std::marker::PhantomData } } - pub(crate) fn apply(self, current_sk: &KeySharePrivate) -> KeySharePrivate { + pub(crate) fn apply(self, current_sk: &KeySharePrivate) -> KeySharePrivate { let mut sum = current_sk.as_ref() + &self.x; let share = KeySharePrivate::from_bigint(&sum); sum.zeroize(); @@ -143,7 +143,7 @@ impl Serialize for KeyUpdatePublic { } } -impl> KeyUpdatePublic { +impl KeyUpdatePublic { pub(crate) fn new(participant: ParticipantIdentifier, share: CurvePoint) -> Self { Self { participant, @@ -181,7 +181,7 @@ impl> KeyUpdatePublic { } } - pub(crate) fn apply(&self, current_pk: &KeySharePublic) -> KeySharePublic { + pub(crate) fn apply(&self, current_pk: &KeySharePublic) -> KeySharePublic { let sum = *current_pk.as_ref() + self.X; KeySharePublic::new(current_pk.participant(), sum) } diff --git a/src/keyrefresh/participant.rs b/src/keyrefresh/participant.rs index bab61cc2..d6c65bad 100644 --- a/src/keyrefresh/participant.rs +++ b/src/keyrefresh/participant.rs @@ -103,11 +103,11 @@ with Identifiable Aborts. [EPrint archive, 2021](https://eprint.iacr.org/2021/060.pdf). Figure 6. */ #[derive(Debug)] -pub struct KeyrefreshParticipant { +pub struct KeyrefreshParticipant { /// The current session identifier sid: Identifier, /// The current protocol input. - input: Input, + input: Input, /// A unique identifier for this participant. id: ParticipantIdentifier, /// A list of all other participant identifiers participating in the @@ -121,9 +121,9 @@ pub struct KeyrefreshParticipant { status: Status, } -impl ProtocolParticipant for KeyrefreshParticipant { - type Input = Input; - type Output = Output; +impl ProtocolParticipant for KeyrefreshParticipant { + type Input = Input; + type Output = Output; fn new( sid: Identifier, @@ -221,8 +221,8 @@ impl ProtocolParticipant for KeyrefreshParticipant { } } -impl InnerProtocolParticipant for KeyrefreshParticipant { - type Context = SharedContext; +impl InnerProtocolParticipant for KeyrefreshParticipant { + type Context = SharedContext; fn retrieve_context(&self) -> ::Context { SharedContext::collect(self) @@ -241,13 +241,13 @@ impl InnerProtocolParticipant for KeyrefreshParticipant { } } -impl Broadcast for KeyrefreshParticipant { +impl Broadcast for KeyrefreshParticipant { fn broadcast_participant(&mut self) -> &mut BroadcastParticipant { &mut self.broadcast_participant } } -impl KeyrefreshParticipant { +impl KeyrefreshParticipant { /// Handle "Ready" messages from the protocol participants. /// /// Once "Ready" messages have been received from all participants, this @@ -818,7 +818,7 @@ impl KeyrefreshParticipant { KeyUpdatePrivate::sum(update_privates) } - fn aggregate_public_updates( + fn aggregate_public_updates( participants: &[ParticipantIdentifier], from_all_to_all: &[Vec>], ) -> Result>> { @@ -833,7 +833,7 @@ impl KeyrefreshParticipant { .collect() } - fn find_updates_for_participant( + fn find_updates_for_participant( p_i: ParticipantIdentifier, from_all_to_all: &[Vec>], ) -> Result>> { @@ -881,7 +881,7 @@ mod tests { }; use tracing::debug; - impl KeyrefreshParticipant { + impl KeyrefreshParticipant { pub fn new_quorum( sid: Identifier, quorum_size: usize, @@ -930,7 +930,7 @@ mod tests { } } - fn is_keyrefresh_done(quorum: &[KeyrefreshParticipant]) -> bool { + fn is_keyrefresh_done(quorum: &[KeyrefreshParticipant]) -> bool { for participant in quorum { if *participant.status() != Status::TerminatedSuccessfully { return false; @@ -941,7 +941,7 @@ mod tests { #[allow(clippy::type_complexity)] fn process_messages( - quorum: &mut [KeyrefreshParticipant], + quorum: &mut [KeyrefreshParticipant], inboxes: &mut HashMap>, rng: &mut R, ) -> Option<(usize, ProcessOutcome>)> { diff --git a/src/presign/input.rs b/src/presign/input.rs index 22276c9b..9be3aa17 100644 --- a/src/presign/input.rs +++ b/src/presign/input.rs @@ -9,24 +9,24 @@ use std::collections::HashSet; use tracing::error; use crate::{ - auxinfo::{self, AuxInfoPrivate, AuxInfoPublic}, curve_point::CurvePoint, errors::{CallerError, InternalError, Result}, keygen::{self, KeySharePrivate, KeySharePublic}, ParticipantIdentifier + auxinfo::{self, AuxInfoPrivate, AuxInfoPublic}, curve_point::CurveTrait, errors::{CallerError, InternalError, Result}, keygen::{self, KeySharePrivate, KeySharePublic}, ParticipantIdentifier }; /// Input needed for a /// [`PresignParticipant`](crate::presign::PresignParticipant) to run. #[derive(Debug, Clone)] -pub struct Input { +pub struct Input { /// The key share material for the key that will be used in the presign run. - keygen_output: keygen::Output, + keygen_output: keygen::Output, /// The auxiliary info for the key that will be used in the presign run. - auxinfo_output: auxinfo::Output, + auxinfo_output: auxinfo::Output, } -impl Input { +impl Input { /// Creates a new [`Input`] from the outputs of the /// [`auxinfo`](crate::auxinfo::AuxInfoParticipant) and /// [`keygen`](crate::keygen::KeygenParticipant) protocols. - pub fn new(auxinfo_output: auxinfo::Output, keygen_output: keygen::Output) -> Result { + pub fn new(auxinfo_output: auxinfo::Output, keygen_output: keygen::Output) -> Result { if auxinfo_output.public_auxinfo().len() != keygen_output.public_key_shares().len() { error!( "Number of auxinfo ({:?}) and keyshare ({:?}) public entries is not equal", @@ -82,7 +82,7 @@ impl Input { self.keygen_output.rid() } - pub(crate) fn public_key_shares(&self) -> &[KeySharePublic] { + pub(crate) fn public_key_shares(&self) -> &[KeySharePublic] { self.keygen_output.public_key_shares() } @@ -104,7 +104,7 @@ impl Input { /// Returns the [`AuxInfoPublic`] associated with the given /// [`ParticipantIdentifier`]. - pub(crate) fn find_auxinfo_public(&self, pid: ParticipantIdentifier) -> Result<&AuxInfoPublic> { + pub(crate) fn find_auxinfo_public(&self, pid: ParticipantIdentifier) -> Result<&AuxInfoPublic> { self.auxinfo_output.find_public(pid) .ok_or_else(|| { error!("Presign input doesn't contain a public auxinfo for {}, even though we checked for it at construction.", pid); @@ -112,7 +112,7 @@ impl Input { }) } - pub(crate) fn private_key_share(&self) -> &KeySharePrivate { + pub(crate) fn private_key_share(&self) -> &KeySharePrivate { self.keygen_output.private_key_share() } @@ -121,7 +121,7 @@ impl Input { pub(crate) fn find_keyshare_public( &self, pid: ParticipantIdentifier, - ) -> Result<&KeySharePublic> { + ) -> Result<&KeySharePublic> { self.keygen_output .public_key_shares() .iter() @@ -137,7 +137,7 @@ impl Input { pub(crate) fn all_but_one_auxinfo_public( &self, pid: ParticipantIdentifier, - ) -> Vec<&AuxInfoPublic> { + ) -> Vec<&AuxInfoPublic> { self.auxinfo_output .public_auxinfo() .iter() @@ -146,7 +146,7 @@ impl Input { } /// Returns a copy of the [`AuxInfoPublic`]s associated with all the /// participants (including this participant). - pub(crate) fn to_public_auxinfo(&self) -> Vec { + pub(crate) fn to_public_auxinfo(&self) -> Vec> { self.auxinfo_output.public_auxinfo().to_vec() } } diff --git a/src/presign/participant.rs b/src/presign/participant.rs index e89c833c..e64d3e83 100644 --- a/src/presign/participant.rs +++ b/src/presign/participant.rs @@ -9,30 +9,16 @@ // of this source tree. use crate::{ - auxinfo::{AuxInfoPrivate, AuxInfoPublic}, - broadcast::participant::{BroadcastOutput, BroadcastParticipant, BroadcastTag}, - errors::{CallerError, InternalError, Result}, - keygen::{KeySharePrivate, KeySharePublic}, - local_storage::LocalStorage, - messages::{Message, MessageType, PresignMessageType}, - parameters::ELL_PRIME, - participant::{Broadcast, InnerProtocolParticipant, ProcessOutcome, ProtocolParticipant}, - presign::{ + auxinfo::{AuxInfoPrivate, AuxInfoPublic}, broadcast::participant::{BroadcastOutput, BroadcastParticipant, BroadcastTag}, curve_point::{bn_to_scalar, k256_order, CurvePoint, CurveTrait}, errors::{CallerError, InternalError, Result}, keygen::{KeySharePrivate, KeySharePublic}, local_storage::LocalStorage, messages::{Message, MessageType, PresignMessageType}, parameters::ELL_PRIME, participant::{Broadcast, InnerProtocolParticipant, ProcessOutcome, ProtocolParticipant}, presign::{ input::Input, record::{PresignRecord, RecordPair}, round_one, round_three, round_two, - }, - protocol::{ParticipantIdentifier, ProtocolType, SharedContext}, - run_only_once, - curve_point::{bn_to_scalar, k256_order, CurvePoint}, - utils::{random_plusminus_by_size, random_positive_bn}, - zkp::{ + }, protocol::{ParticipantIdentifier, ProtocolType, SharedContext}, run_only_once, utils::{random_plusminus_by_size, random_positive_bn}, zkp::{ piaffg::{PiAffgInput, PiAffgProof, PiAffgSecret}, pienc::{PiEncInput, PiEncProof, PiEncSecret}, pilog::{CommonInput, PiLogProof, ProverSecret}, Proof, ProofContext, - }, - Identifier, + }, Identifier }; use libpaillier::unknown_order::BigNumber; use merlin::Transcript; @@ -42,7 +28,7 @@ use tracing::{error, info, instrument}; // Local storage data types. mod storage { - use crate::local_storage::TypeTag; + use crate::{curve_point::CurvePoint, local_storage::TypeTag}; pub(super) struct RoundOnePrivate; impl TypeTag for RoundOnePrivate { @@ -62,7 +48,7 @@ mod storage { } pub(super) struct RoundTwoPublic; impl TypeTag for RoundTwoPublic { - type Value = crate::presign::round_two::Public; + type Value = crate::presign::round_two::Public; } pub(super) struct RoundThreePrivate; impl TypeTag for RoundThreePrivate { @@ -70,7 +56,7 @@ mod storage { } pub(super) struct RoundThreePublic; impl TypeTag for RoundThreePublic { - type Value = crate::presign::round_three::Public; + type Value = crate::presign::round_three::Public; } } @@ -78,13 +64,13 @@ mod storage { /// and includes [`SharedContext`] and [`AuxInfoPublic`]s for all participants /// (including this participant). #[derive(Debug)] -pub(crate) struct PresignContext { - shared_context: SharedContext, +pub(crate) struct PresignContext { + shared_context: SharedContext, rid: [u8; 32], - auxinfo_public: Vec, + auxinfo_public: Vec>, } -impl ProofContext for PresignContext { +impl ProofContext for PresignContext { fn as_bytes(&self) -> Result> { Ok([ self.shared_context.as_bytes()?, @@ -96,9 +82,9 @@ impl ProofContext for PresignContext { } } -impl PresignContext { +impl PresignContext { /// Build a [`PresignContext`] from a [`PresignParticipant`]. - pub(crate) fn collect(p: &PresignParticipant) -> Self { + pub(crate) fn collect(p: &PresignParticipant) -> Self { let mut auxinfo_public = p.input().to_public_auxinfo(); auxinfo_public.sort_by_key(AuxInfoPublic::participant); Self { @@ -108,7 +94,7 @@ impl PresignContext { } } - fn for_participant(self, pid: ParticipantIdentifier) -> ParticipantPresignContext { + fn for_participant(self, pid: ParticipantIdentifier) -> ParticipantPresignContext { ParticipantPresignContext { presign_context: self, participant_id: pid, @@ -116,12 +102,12 @@ impl PresignContext { } } -pub struct ParticipantPresignContext { - presign_context: PresignContext, +pub struct ParticipantPresignContext { + presign_context: PresignContext, participant_id: ParticipantIdentifier, } -impl ProofContext for ParticipantPresignContext { +impl ProofContext for ParticipantPresignContext { fn as_bytes(&self) -> Result> { Ok([ self.presign_context.as_bytes()?, @@ -224,11 +210,11 @@ impl ProofContext for ParticipantPresignContext { /// with Identifiable Aborts. [EPrint archive, /// 2021](https://eprint.iacr.org/2021/060.pdf). Figure 7. #[derive(Debug)] -pub struct PresignParticipant { +pub struct PresignParticipant { /// The current session identifier. sid: Identifier, /// The current protocol input. - input: Input, + input: Input, /// A unique identifier for this participant. id: ParticipantIdentifier, /// A list of all other participant identifiers participating in the @@ -242,9 +228,9 @@ pub struct PresignParticipant { status: Status, } -impl ProtocolParticipant for PresignParticipant { - type Input = Input; - type Output = PresignRecord; +impl ProtocolParticipant for PresignParticipant { + type Input = Input; + type Output = PresignRecord; fn new( sid: Identifier, @@ -360,8 +346,8 @@ impl ProtocolParticipant for PresignParticipant { } } -impl InnerProtocolParticipant for PresignParticipant { - type Context = PresignContext; +impl InnerProtocolParticipant for PresignParticipant { + type Context = PresignContext; fn retrieve_context(&self) -> ::Context { PresignContext::collect(self) @@ -380,14 +366,14 @@ impl InnerProtocolParticipant for PresignParticipant { } } -impl Broadcast for PresignParticipant { +impl Broadcast for PresignParticipant { fn broadcast_participant(&mut self) -> &mut BroadcastParticipant { &mut self.broadcast_participant } } -impl PresignParticipant { - fn input(&self) -> &Input { +impl PresignParticipant { + fn input(&self) -> &Input { &self.input } @@ -793,7 +779,7 @@ impl PresignParticipant { /// Finish the presign protocol. #[cfg_attr(feature = "flame_it", flame("presign"))] #[instrument(skip_all, err(Debug))] - fn do_presign_finish(&mut self) -> Result { + fn do_presign_finish(&mut self) -> Result> { info!("Doing presign finish. Creating presign record."); // Collect the other participants' round three public values from storage. let r3_pubs = self @@ -893,15 +879,15 @@ impl PresignParticipant { /// the current participant. /// /// TODO: Refactor as specified in #246. -pub(crate) struct PresignKeyShareAndInfo { - pub(crate) keyshare_private: KeySharePrivate, - pub(crate) keyshare_public: KeySharePublic, +pub(crate) struct PresignKeyShareAndInfo { + pub(crate) keyshare_private: KeySharePrivate, + pub(crate) keyshare_public: KeySharePublic, pub(crate) aux_info_private: AuxInfoPrivate, - pub(crate) aux_info_public: AuxInfoPublic, + pub(crate) aux_info_public: AuxInfoPublic, } -impl PresignKeyShareAndInfo { - fn new(id: ParticipantIdentifier, input: &Input) -> Result { +impl PresignKeyShareAndInfo { + fn new(id: ParticipantIdentifier, input: &Input) -> Result { Ok(Self { aux_info_private: input.private_auxinfo().clone(), aux_info_public: input.find_auxinfo_public(id)?.clone(), @@ -922,11 +908,11 @@ impl PresignKeyShareAndInfo { fn round_one( &self, rng: &mut R, - context: &ParticipantPresignContext, - other_auxinfos: &[&AuxInfoPublic], + context: &ParticipantPresignContext, + other_auxinfos: &[&AuxInfoPublic], ) -> Result<( round_one::Private, - HashMap, + HashMap>, round_one::PublicBroadcast, )> { let order = k256_order(); @@ -983,11 +969,11 @@ impl PresignKeyShareAndInfo { fn round_two( &self, rng: &mut R, - context: &ParticipantPresignContext, - receiver_aux_info: &AuxInfoPublic, + context: &ParticipantPresignContext, + receiver_aux_info: &AuxInfoPublic, sender_r1_priv: &round_one::Private, receiver_r1_pub_broadcast: &round_one::PublicBroadcast, - ) -> Result<(round_two::Private, round_two::Public)> { + ) -> Result<(round_two::Private, round_two::Public::)> { let beta = random_plusminus_by_size(rng, ELL_PRIME); let beta_hat = random_plusminus_by_size(rng, ELL_PRIME); @@ -1113,12 +1099,12 @@ impl PresignKeyShareAndInfo { fn round_three( &self, rng: &mut R, - context: &ParticipantPresignContext, + context: &ParticipantPresignContext, sender_r1_priv: &round_one::Private, - other_participant_inputs: &HashMap, + other_participant_inputs: &HashMap>, ) -> Result<( round_three::Private, - HashMap, + HashMap>, )> { let order = k256_order(); let g = CurvePoint::GENERATOR; @@ -1250,10 +1236,10 @@ mod test { #[allow(clippy::type_complexity)] fn process_messages( - quorum: &mut [PresignParticipant], + quorum: &mut [PresignParticipant], inboxes: &mut HashMap>, rng: &mut R, - ) -> Option<(usize, ProcessOutcome)> { + ) -> Option<(usize, ProcessOutcome>)> { // Pick a random participant to process let index = rng.gen_range(0..quorum.len()); let participant = quorum.get_mut(index).unwrap(); @@ -1274,7 +1260,7 @@ mod test { } pub(crate) fn presign_record_set_is_valid( - records: Vec, + records: Vec>, keygen_outputs: Vec>, ) { // Every presign record has the same `R` value diff --git a/src/presign/record.rs b/src/presign/record.rs index 16eb748e..01063f55 100644 --- a/src/presign/record.rs +++ b/src/presign/record.rs @@ -7,23 +7,20 @@ // of this source tree. use crate::{ - errors::{ + curve_point::{bn_to_scalar, CurvePoint, CurveTrait}, errors::{ CallerError, InternalError::{InternalInvariantFailed, ProtocolError}, Result, - }, - presign::round_three::{Private as RoundThreePrivate, Public as RoundThreePublic}, - curve_point::{bn_to_scalar, CurvePoint}, - utils::ParseBytes, + }, presign::round_three::{Private as RoundThreePrivate, Public as RoundThreePublic}, utils::ParseBytes }; use k256::{elliptic_curve::PrimeField, Scalar}; use std::fmt::Debug; use tracing::error; use zeroize::{Zeroize, ZeroizeOnDrop}; -pub(crate) struct RecordPair { +pub(crate) struct RecordPair { pub(crate) private: RoundThreePrivate, - pub(crate) publics: Vec, + pub(crate) publics: Vec>, } /// The precomputation used to create a partial signature. @@ -53,15 +50,15 @@ pub(crate) struct RecordPair { /// /// [^cite]: [Wikipedia](https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm#Signature_generation_algorithm) #[derive(Zeroize, ZeroizeOnDrop, PartialEq, Eq)] -pub struct PresignRecord { - R: CurvePoint, +pub struct PresignRecord { + R: C, k: Scalar, chi: Scalar, } const RECORD_TAG: &[u8] = b"Presign Record"; -impl Debug for PresignRecord { +impl Debug for PresignRecord { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { // Redacting all the fields because I'm not sure how sensitive they are. If // later analysis suggests they're fine to print, please udpate @@ -74,9 +71,9 @@ impl Debug for PresignRecord { } } -impl TryFrom for PresignRecord { +impl TryFrom> for PresignRecord { type Error = crate::errors::InternalError; - fn try_from(RecordPair { private, publics }: RecordPair) -> Result { + fn try_from(RecordPair { private, publics }: RecordPair) -> Result { let mut delta = private.delta; let mut Delta = private.Delta; for p in publics { @@ -104,7 +101,7 @@ impl TryFrom for PresignRecord { } } -impl PresignRecord { +impl PresignRecord { /// Get the mask share (`k` in the paper) from the record. pub(crate) fn mask_share(&self) -> &Scalar { &self.k @@ -254,21 +251,18 @@ mod tests { use rand::{rngs::StdRng, CryptoRng, Rng, RngCore, SeedableRng}; use crate::{ - keygen, - presign::{participant::presign_record_set_is_valid, record::RECORD_TAG}, - curve_point::{bn_to_scalar, testing::init_testing, CurvePoint}, - ParticipantConfig, PresignRecord, + curve_point::{bn_to_scalar, testing::init_testing, CurvePoint, CurveTrait}, keygen, presign::{participant::presign_record_set_is_valid, record::RECORD_TAG}, ParticipantConfig, PresignRecord }; - impl PresignRecord { - pub(crate) fn mask_point(&self) -> &CurvePoint { + impl PresignRecord { + pub(crate) fn mask_point(&self) -> &C { &self.R } /// Simulate creation of a random presign record. Do not use outside of /// testing. - fn simulate(rng: &mut StdRng) -> PresignRecord { - let mask_point = CurvePoint::random(StdRng::from_seed(rng.gen())); + fn simulate(rng: &mut StdRng) -> PresignRecord { + let mask_point = C::random(StdRng::from_seed(rng.gen())); let mask_share = Scalar::random(StdRng::from_seed(rng.gen())); let masked_key_share = Scalar::random(rng); diff --git a/src/presign/round_one.rs b/src/presign/round_one.rs index 6c805db2..4bc6a67b 100644 --- a/src/presign/round_one.rs +++ b/src/presign/round_one.rs @@ -8,14 +8,10 @@ use super::participant::ParticipantPresignContext; use crate::{ - errors::{InternalError, Result}, - messages::{Message, MessageType, PresignMessageType}, - paillier::{Ciphertext, EncryptionKey, Nonce}, - ring_pedersen::VerifiedRingPedersen, - zkp::{ + curve_point::CurveTrait, errors::{InternalError, Result}, messages::{Message, MessageType, PresignMessageType}, paillier::{Ciphertext, EncryptionKey, Nonce}, ring_pedersen::VerifiedRingPedersen, zkp::{ pienc::{PiEncInput, PiEncProof}, Proof, - }, + } }; use libpaillier::unknown_order::BigNumber; use merlin::Transcript; @@ -56,12 +52,12 @@ impl Debug for Private { /// necessarily valid (i.e., that all the components are valid with respect to /// each other); use [`Public::verify`] to check this latter condition. #[derive(Debug, Serialize, Deserialize)] -pub(crate) struct Public { - proof: PiEncProof, +pub(crate) struct Public { + proof: PiEncProof, } -impl From for Public { - fn from(proof: PiEncProof) -> Self { +impl From> for Public { + fn from(proof: PiEncProof) -> Self { Self { proof } } } @@ -73,7 +69,7 @@ pub(crate) struct PublicBroadcast { pub G: Ciphertext, } -impl Public { +impl Public { /// Verify the validity of [`Public`] against the prover's [`EncryptionKey`] /// and [`PublicBroadcast`] values. /// @@ -81,8 +77,8 @@ impl Public { /// (i.e., the verifier). pub(crate) fn verify( self, - context: &ParticipantPresignContext, - verifier_setup_params: &VerifiedRingPedersen, + context: &ParticipantPresignContext, + verifier_setup_params: &VerifiedRingPedersen, prover_pk: &EncryptionKey, prover_public_broadcast: &PublicBroadcast, ) -> Result<()> { @@ -92,7 +88,7 @@ impl Public { } } -impl TryFrom<&Message> for Public { +impl TryFrom<&Message> for Public { type Error = InternalError; fn try_from(message: &Message) -> std::result::Result { diff --git a/src/presign/round_three.rs b/src/presign/round_three.rs index e4afe1b0..dad6fabb 100644 --- a/src/presign/round_three.rs +++ b/src/presign/round_three.rs @@ -7,19 +7,14 @@ // of this source tree. use crate::{ - auxinfo::AuxInfoPublic, - errors::{InternalError, Result}, - messages::{Message, MessageType, PresignMessageType}, - presign::{ + auxinfo::AuxInfoPublic, curve_point::{CurvePoint, CurveTrait}, errors::{InternalError, Result}, messages::{Message, MessageType, PresignMessageType}, presign::{ participant::ParticipantPresignContext, round_one::PublicBroadcast as RoundOnePublicBroadcast, round_two::{Private as RoundTwoPrivate, Public as RoundTwoPublic}, - }, - curve_point::CurvePoint, - zkp::{ + }, zkp::{ pilog::{CommonInput, PiLogProof}, Proof, - }, + } }; use k256::{elliptic_curve::PrimeField, Scalar}; use libpaillier::unknown_order::BigNumber; @@ -62,23 +57,23 @@ impl Debug for Private { /// necessarily valid (i.e., that all the components are valid with respect to /// each other); use [`Public::verify`] to check this latter condition. #[derive(Clone, Serialize, Deserialize)] -pub(crate) struct Public { +pub(crate) struct Public { pub delta: Scalar, - pub Delta: CurvePoint, + pub Delta: C, pub psi_double_prime: PiLogProof, /// Gamma value included for convenience - pub Gamma: CurvePoint, + pub Gamma: C, } -impl Public { +impl Public { /// Verify the validity of [`Public`] against the prover's [`AuxInfoPublic`] /// and [`PublicBroadcast`](crate::presign::round_one::PublicBroadcast) /// values. pub(crate) fn verify( self, - context: &ParticipantPresignContext, - verifier_auxinfo_public: &AuxInfoPublic, - prover_auxinfo_public: &AuxInfoPublic, + context: &ParticipantPresignContext, + verifier_auxinfo_public: &AuxInfoPublic, + prover_auxinfo_public: &AuxInfoPublic, prover_r1_public_broadcast: &RoundOnePublicBroadcast, ) -> Result<()> { let mut transcript = Transcript::new(b"PiLogProof"); @@ -96,7 +91,7 @@ impl Public { } } -impl TryFrom<&Message> for Public { +impl TryFrom<&Message> for Public { type Error = InternalError; fn try_from(message: &Message) -> std::result::Result { @@ -115,8 +110,8 @@ impl TryFrom<&Message> for Public { } /// Used to bundle the inputs passed to round_three() together -pub(crate) struct Input { - pub auxinfo_public: AuxInfoPublic, +pub(crate) struct Input { + pub auxinfo_public: AuxInfoPublic, pub r2_private: RoundTwoPrivate, - pub r2_public: RoundTwoPublic, + pub r2_public: RoundTwoPublic, } diff --git a/src/presign/round_two.rs b/src/presign/round_two.rs index a0f0d962..91cbbc1b 100644 --- a/src/presign/round_two.rs +++ b/src/presign/round_two.rs @@ -7,21 +7,14 @@ // of this source tree. use crate::{ - auxinfo::AuxInfoPublic, - errors::{InternalError, Result}, - keygen::KeySharePublic, - messages::{Message, MessageType, PresignMessageType}, - paillier::Ciphertext, - presign::{ + auxinfo::AuxInfoPublic, curve_point::{CurvePoint, CurveTrait}, errors::{InternalError, Result}, keygen::KeySharePublic, messages::{Message, MessageType, PresignMessageType}, paillier::Ciphertext, presign::{ participant::ParticipantPresignContext, round_one::{Private as RoundOnePrivate, PublicBroadcast as RoundOnePublicBroadcast}, - }, - curve_point::CurvePoint, - zkp::{ + }, zkp::{ piaffg::{PiAffgInput, PiAffgProof}, pilog::{CommonInput, PiLogProof}, Proof, - }, + } }; use libpaillier::unknown_order::BigNumber; use merlin::Transcript; @@ -51,28 +44,28 @@ impl Debug for Private { /// necessarily valid (i.e., that all the components are valid with respect to /// each other); use [`Public::verify`] to check this latter condition. #[derive(Clone, Serialize, Deserialize)] -pub(crate) struct Public { +pub(crate) struct Public { pub D: Ciphertext, pub D_hat: Ciphertext, pub F: Ciphertext, pub F_hat: Ciphertext, - pub Gamma: CurvePoint, - pub psi: PiAffgProof, - pub psi_hat: PiAffgProof, - pub psi_prime: PiLogProof, + pub Gamma: C, + pub psi: PiAffgProof, + pub psi_hat: PiAffgProof, + pub psi_prime: PiLogProof, } -impl Public { +impl Public { /// Verify the validity of [`Public`] against the sender's /// [`AuxInfoPublic`], [`KeySharePublic`], and /// [`PublicBroadcast`](crate::presign::round_one::PublicBroadcast) values. pub(crate) fn verify( self, - context: &ParticipantPresignContext, - verifier_auxinfo_public: &AuxInfoPublic, + context: &ParticipantPresignContext, + verifier_auxinfo_public: &AuxInfoPublic, verifier_r1_private: &RoundOnePrivate, - prover_auxinfo_public: &AuxInfoPublic, - prover_keyshare_public: &KeySharePublic, + prover_auxinfo_public: &AuxInfoPublic, + prover_keyshare_public: &KeySharePublic, prover_r1_public_broadcast: &RoundOnePublicBroadcast, ) -> Result<()> { let g = CurvePoint::GENERATOR; @@ -121,7 +114,7 @@ impl Public { } } -impl TryFrom<&Message> for Public { +impl TryFrom<&Message> for Public { type Error = InternalError; fn try_from(message: &Message) -> std::result::Result { diff --git a/src/protocol.rs b/src/protocol.rs index 283dbb90..672f2bcb 100644 --- a/src/protocol.rs +++ b/src/protocol.rs @@ -442,7 +442,7 @@ impl ProofContext for SharedContext { } } -impl> SharedContext { +impl SharedContext { /// This function should not be used outside of the tests. #[cfg(test)] pub fn random(rng: &mut R) -> Self { diff --git a/src/ring_pedersen.rs b/src/ring_pedersen.rs index 79cc8fcc..c3cb67ee 100644 --- a/src/ring_pedersen.rs +++ b/src/ring_pedersen.rs @@ -12,13 +12,10 @@ //! that the commitment scheme parameters were constructed correctly. use crate::{ - errors::Result, - paillier::DecryptionKey, - utils::{modpow, random_plusminus_scaled, random_positive_bn}, - zkp::{ + curve_point::CurveTrait, errors::Result, paillier::DecryptionKey, utils::{modpow, random_plusminus_scaled, random_positive_bn}, zkp::{ piprm::{PiPrmProof, PiPrmSecret}, Proof, ProofContext, - }, + } }; use bytemuck::TransparentWrapper; use bytemuck_derive::TransparentWrapper; @@ -44,20 +41,20 @@ pub(crate) struct RingPedersen { /// A [`RingPedersen`] commitment scheme alongside a zero knowledge proof that /// the commitment scheme was constructed correctly. #[derive(Clone, Debug, Serialize, Deserialize)] -pub(crate) struct VerifiedRingPedersen { +pub(crate) struct VerifiedRingPedersen { /// The underlying commitment scheme. scheme: RingPedersen, /// The zero knowledge proof that validates the correctness of /// [`VerifiedRingPedersen::scheme`]. - proof: PiPrmProof, + proof: PiPrmProof, } -impl PartialEq for VerifiedRingPedersen { +impl PartialEq for VerifiedRingPedersen { fn eq(&self, other: &Self) -> bool { self.scheme == other.scheme } } -impl Eq for VerifiedRingPedersen {} +impl Eq for VerifiedRingPedersen {} /// A commitment produced by [`RingPedersen::commit`]. #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] @@ -142,7 +139,7 @@ impl MaskedRandomness { } } -impl VerifiedRingPedersen { +impl VerifiedRingPedersen { /// Extracts a [`VerifiedRingPedersen`] object from a [`DecryptionKey`]. /// /// In more detail, `sk` is used to derive a diff --git a/src/sign/interactive_sign/participant.rs b/src/sign/interactive_sign/participant.rs index f4d62d1a..4014dadd 100644 --- a/src/sign/interactive_sign/participant.rs +++ b/src/sign/interactive_sign/participant.rs @@ -10,7 +10,7 @@ use sha3::{Digest, Keccak256}; use tracing::{error, info}; use crate::{ - auxinfo, curve_point::CurvePoint, errors::{CallerError, InternalError, Result}, keygen::{self, KeySharePublic}, message_queue::MessageQueue, messages::{Message, MessageType, SignMessageType}, participant::{ProcessOutcome, Status}, presign::{self, PresignParticipant, PresignRecord}, protocol::ProtocolType, sign::{self, non_interactive_sign::participant::SignParticipant, Signature}, Identifier, ParticipantIdentifier, ProtocolParticipant + auxinfo, curve_point::{CurvePoint, CurveTrait}, errors::{CallerError, InternalError, Result}, keygen::{self, KeySharePublic}, message_queue::MessageQueue, messages::{Message, MessageType, SignMessageType}, participant::{ProcessOutcome, Status}, presign::{self, PresignParticipant, PresignRecord}, protocol::ProtocolType, sign::{self, non_interactive_sign::participant::SignParticipant, Signature}, Identifier, ParticipantIdentifier, ProtocolParticipant }; /// A participant that runs the interactive signing protocol in @@ -50,9 +50,9 @@ use crate::{ /// with Identifiable Aborts. [EPrint archive, /// 2021](https://eprint.iacr.org/2021/060.pdf). #[derive(Debug)] -pub struct InteractiveSignParticipant { - signing_material: SigningMaterial, - presigner: PresignParticipant, +pub struct InteractiveSignParticipant { + signing_material: SigningMaterial, + presigner: PresignParticipant, signing_message_storage: MessageQueue, } @@ -61,22 +61,22 @@ pub struct InteractiveSignParticipant { /// Either we have not yet started the signing protocol, so we are only saving /// the input, or we are actively running signing. #[derive(Debug)] -enum SigningMaterial { +enum SigningMaterial { /// When we create the `signer`, we'll need to pass this input, plus the /// output of `presign`. PartialInput { // Boxed at the behest of compiler. This type is quite large. digest: Box, - public_keys: Vec, + public_keys: Vec>, }, Signer { // Boxed at the behest of compiler. This type is quite large. - signer: Box>, + signer: Box>, }, } -impl SigningMaterial { - fn new_partial_input(digest: Keccak256, public_keys: Vec) -> Self { +impl SigningMaterial { + fn new_partial_input(digest: Keccak256, public_keys: Vec>) -> Self { Self::PartialInput { digest: Box::new(digest), public_keys, @@ -86,7 +86,7 @@ impl SigningMaterial { /// Update from `PartialInput` to `Signer`. fn update( &mut self, - record: PresignRecord, + record: PresignRecord, id: ParticipantIdentifier, other_ids: Vec, sid: Identifier, @@ -133,12 +133,12 @@ impl SigningMaterial { /// Input for the interactive signing protocol. #[derive(Debug)] -pub struct Input { +pub struct Input { message_digest: Keccak256, - presign_input: presign::Input, + presign_input: presign::Input, } -impl Input { +impl Input { /// Construct a new input for interactive signing from the outputs of the /// [`auxinfo`](crate::auxinfo::AuxInfoParticipant) and /// [`keygen`](crate::keygen::KeygenParticipant) protocols. @@ -152,8 +152,8 @@ impl Input { /// "pre-hash" the message. It is hashed here using SHA2-256. pub fn new( message: &[u8], - keygen_output: keygen::Output, - auxinfo_output: auxinfo::Output, + keygen_output: keygen::Output, + auxinfo_output: auxinfo::Output, ) -> Result { let presign_input = presign::Input::new(auxinfo_output, keygen_output)?; let message_digest = Keccak256::new_with_prefix(message); @@ -164,8 +164,8 @@ impl Input { } } -impl ProtocolParticipant for InteractiveSignParticipant { - type Input = Input; +impl ProtocolParticipant for InteractiveSignParticipant { + type Input = Input; type Output = Signature; fn ready_type() -> MessageType { @@ -266,7 +266,7 @@ impl ProtocolParticipant for InteractiveSignParticipant { } } -impl InteractiveSignParticipant { +impl InteractiveSignParticipant { fn handle_sign_message( &mut self, rng: &mut (impl CryptoRng + RngCore), @@ -337,14 +337,7 @@ mod tests { use tracing::debug; use crate::{ - auxinfo, - errors::Result, - keygen, - messages::{Message, MessageType}, - participant::ProcessOutcome, - sign::Signature, - curve_point::testing::init_testing, - Identifier, ParticipantConfig, ParticipantIdentifier, ProtocolParticipant, + auxinfo, curve_point::{testing::init_testing, CurvePoint}, errors::Result, keygen, messages::{Message, MessageType}, participant::ProcessOutcome, sign::Signature, Identifier, ParticipantConfig, ParticipantIdentifier, ProtocolParticipant }; use super::{Input, InteractiveSignParticipant, Status}; @@ -364,10 +357,10 @@ mod tests { /// Pick a random incoming message and have the correct participant process /// it. fn process_messages<'a>( - quorum: &'a mut [InteractiveSignParticipant], + quorum: &'a mut [InteractiveSignParticipant], inbox: &mut Vec, rng: &mut StdRng, - ) -> (&'a InteractiveSignParticipant, ProcessOutcome) { + ) -> (&'a InteractiveSignParticipant, ProcessOutcome) { // Make sure test doesn't loop forever if we have a control flow problem if inbox.is_empty() { panic!("Protocol isn't done but there are no more messages!") diff --git a/src/sign/non_interactive_sign/participant.rs b/src/sign/non_interactive_sign/participant.rs index 8c72370a..4de2d365 100644 --- a/src/sign/non_interactive_sign/participant.rs +++ b/src/sign/non_interactive_sign/participant.rs @@ -67,20 +67,20 @@ pub struct SignParticipant { #[derive(Debug)] pub struct Input { digest: Keccak256, - presign_record: PresignRecord, - public_key_shares: Vec, + presign_record: PresignRecord, + public_key_shares: Vec>, _curve: std::marker::PhantomData, } -impl> Input { +impl Input { /// Construct a new input for signing. /// /// The `public_key_shares` should be the same ones used to generate the /// [`PresignRecord`]. pub fn new( message: &[u8], - record: PresignRecord, - public_key_shares: Vec, + record: PresignRecord, + public_key_shares: Vec>, ) -> Self { Self { digest: Keccak256::new_with_prefix(message), @@ -96,8 +96,8 @@ impl> Input { /// they receive it, rather that waiting until presigning completes. pub(crate) fn new_from_digest( digest: Keccak256, - record: PresignRecord, - public_key_shares: Vec, + record: PresignRecord, + public_key_shares: Vec>, ) -> Self { Self { digest, @@ -108,7 +108,7 @@ impl> Input { } /// Retrieve the presign record. - pub(crate) fn presign_record(&self) -> &PresignRecord { + pub(crate) fn presign_record(&self) -> &PresignRecord { &self.presign_record } @@ -484,7 +484,7 @@ mod test { /// correctly according to the presign record. fn compute_non_distributed_ecdsa( message: &[u8], - records: &[PresignRecord], + records: &[PresignRecord], keygen_outputs: &[keygen::Output], ) -> k256::ecdsa::Signature { let k = records diff --git a/src/zkp/mod.rs b/src/zkp/mod.rs index 0affc55d..38fabc39 100644 --- a/src/zkp/mod.rs +++ b/src/zkp/mod.rs @@ -21,7 +21,7 @@ pub(crate) mod pimod; pub(crate) mod piprm; pub(crate) mod pisch; -use crate::{curve_point::{CurvePoint, CurveTrait}, errors::Result}; +use crate::{curve_point::CurveTrait, errors::Result}; use merlin::Transcript; use rand::{CryptoRng, RngCore}; use serde::{de::DeserializeOwned, Serialize}; @@ -54,14 +54,14 @@ impl ProofContext for BadContext { /// The associated type [`Proof::CommonInput`] denotes the data known to both /// the prover and verifier, and the associated type [`Proof::ProverSecret`] /// denotes the data known only to the prover. -pub(crate) trait Proof: Sized + Serialize + DeserializeOwned { - type CommonInput<'a, C: CurveTrait> where C: 'a; +pub(crate) trait Proof: Sized + Serialize + DeserializeOwned { + type CommonInput<'a>; type ProverSecret<'a>; /// Constructs a zero knowledge proof over [`Proof::ProverSecret`] and /// [`Proof::CommonInput`] using the provided [`Transcript`]. fn prove( - input: Self::CommonInput<'_, CurvePoint>, + input: Self::CommonInput<'_>, secret: Self::ProverSecret<'_>, context: &impl ProofContext, transcript: &mut Transcript, @@ -72,7 +72,7 @@ pub(crate) trait Proof: Sized + Serialize + DeserializeOwned { /// [`Proof::CommonInput`] and [`Transcript`]. fn verify( self, - input: Self::CommonInput<'_, CurvePoint>, + input: Self::CommonInput<'_>, context: &impl ProofContext, transcript: &mut Transcript, ) -> Result<()>; diff --git a/src/zkp/piaffg.rs b/src/zkp/piaffg.rs index d00598a3..e3cadbf0 100644 --- a/src/zkp/piaffg.rs +++ b/src/zkp/piaffg.rs @@ -39,14 +39,14 @@ //! 2021](https://eprint.iacr.org/2021/060.pdf). use crate::{ - curve_point, errors::*, paillier::{Ciphertext, EncryptionKey, MaskedNonce, Nonce, PaillierError}, parameters::{ELL, ELL_PRIME, EPSILON}, ring_pedersen::{Commitment, MaskedRandomness, VerifiedRingPedersen}, utils::{ + curve_point::CurveTrait, errors::*, paillier::{Ciphertext, EncryptionKey, MaskedNonce, Nonce, PaillierError}, parameters::{ELL, ELL_PRIME, EPSILON}, ring_pedersen::{Commitment, MaskedRandomness, VerifiedRingPedersen}, utils::{ plusminus_challenge_from_transcript, random_plusminus_by_size, within_bound_by_size, }, zkp::{Proof, ProofContext} }; use libpaillier::unknown_order::BigNumber; use merlin::Transcript; use rand::{CryptoRng, RngCore}; -use serde::{Deserialize, Serialize}; +use serde::{de::DeserializeOwned, Deserialize, Serialize}; use std::fmt::Debug; use tracing::error; use crate::curve_point::CurvePoint; @@ -57,7 +57,7 @@ use crate::curve_point::CurvePoint; /// /// See the [module-level documentation](crate::zkp::piaffg) for more details. #[derive(Debug, Clone, Serialize, Deserialize)] -pub(crate) struct PiAffgProof { +pub(crate) struct PiAffgProof { /// A ring-Pedersen commitment to the multiplicative coefficient (`S` in the /// paper). mult_coeff_commit: Commitment, @@ -70,7 +70,7 @@ pub(crate) struct PiAffgProof { random_affine_ciphertext_verifier: Ciphertext, /// A group exponentiation of the random multiplicative coefficient (`B_x` /// in the paper). - random_mult_coeff_exp: CurvePoint, + random_mult_coeff_exp: C, /// A Paillier ciphertext, under the prover's encryption key, of the /// random additive coefficient (`B_y` in the paper). random_add_coeff_ciphertext_prover: Ciphertext, @@ -106,9 +106,9 @@ pub(crate) struct PiAffgProof { /// Copying/Cloning references is harmless and sometimes necessary. So we /// implement Clone and Copy for this type. #[derive(Serialize, Clone, Copy)] -pub(crate) struct PiAffgInput<'a> { +pub(crate) struct PiAffgInput<'a, C: CurveTrait> { /// The verifier's commitment parameters (`(Nhat, s, t)` in the paper). - verifier_setup_params: &'a VerifiedRingPedersen, + verifier_setup_params: &'a VerifiedRingPedersen, /// The verifier's Paillier encryption key (`N_0` in the paper). verifier_encryption_key: &'a EncryptionKey, /// The prover's Paillier encryption key (`N_1` in the paper). @@ -124,20 +124,20 @@ pub(crate) struct PiAffgInput<'a> { add_coeff_ciphertext_prover: &'a Ciphertext, /// Exponentiation of the prover's multiplicative coefficient (`X` in the /// paper). - mult_coeff_exp: &'a CurvePoint, + mult_coeff_exp: &'a C, } -impl<'a> PiAffgInput<'a> { +impl<'a, C: CurveTrait> PiAffgInput<'a, C> { /// Construct a new [`PiAffgInput`] type. pub(crate) fn new( - verifier_setup_params: &'a VerifiedRingPedersen, + verifier_setup_params: &'a VerifiedRingPedersen, verifier_encryption_key: &'a EncryptionKey, prover_encryption_key: &'a EncryptionKey, original_ciphertext_verifier: &'a Ciphertext, transformed_ciphertext_verifier: &'a Ciphertext, add_coeff_ciphertext_prover: &'a Ciphertext, - mult_coeff_exp: &'a CurvePoint, - ) -> PiAffgInput<'a> { + mult_coeff_exp: &'a C, + ) -> PiAffgInput<'a, C> { Self { verifier_setup_params, verifier_encryption_key, @@ -192,13 +192,13 @@ impl<'a> PiAffgSecret<'a> { } } -impl Proof for PiAffgProof { - type CommonInput<'a, CurvePoint: curve_point::CurveTrait + 'a> = PiAffgInput<'a>; +impl Proof for PiAffgProof { + type CommonInput<'a> = PiAffgInput<'a, C>; type ProverSecret<'b> = PiAffgSecret<'b>; #[cfg_attr(feature = "flame_it", flame("PiAffgProof"))] fn prove( - input: Self::CommonInput<'_, CurvePoint>, + input: Self::CommonInput<'_>, secret: Self::ProverSecret<'_>, context: &impl ProofContext, transcript: &mut Transcript, @@ -371,7 +371,7 @@ impl Proof for PiAffgProof { #[cfg_attr(feature = "flame_it", flame("PiAffgProof"))] fn verify( self, - input: Self::CommonInput<'_, CurvePoint>, + input: Self::CommonInput<'_>, context: &impl ProofContext, transcript: &mut Transcript, ) -> Result<()> { @@ -499,16 +499,16 @@ impl Proof for PiAffgProof { } } -impl PiAffgProof { +impl PiAffgProof { #[allow(clippy::too_many_arguments)] fn generate_challenge( transcript: &mut Transcript, context: &impl ProofContext, - input: &PiAffgInput, + input: &PiAffgInput, mult_coeff_commit: &Commitment, add_coeff_commit: &Commitment, random_affine_ciphertext: &Ciphertext, - random_mult_coeff_exp: &CurvePoint, + random_mult_coeff_exp: &C, random_add_coeff_ciphertext_prover: &Ciphertext, random_mult_coeff_commit: &Commitment, random_add_coeff_commit: &Commitment, @@ -551,7 +551,7 @@ mod tests { use rand::{rngs::StdRng, Rng, SeedableRng}; // Type of expected function for our code testing. - type TestFn = fn(PiAffgProof, PiAffgInput) -> Result<()>; + type TestFn = fn(PiAffgProof, PiAffgInput) -> Result<()>; fn transcript() -> Transcript { Transcript::new(b"random_paillier_affg_proof") @@ -561,7 +561,7 @@ mod tests { rng: &mut R, x: &BigNumber, y: &BigNumber, - mut test_code: impl FnMut(PiAffgProof, PiAffgInput) -> Result<()>, + mut test_code: impl FnMut(PiAffgProof, PiAffgInput) -> Result<()>, ) -> Result<()> { let (decryption_key_0, _, _) = DecryptionKey::new(rng).unwrap(); let pk0 = decryption_key_0.encryption_key(); diff --git a/src/zkp/pienc.rs b/src/zkp/pienc.rs index e5e29e11..35547560 100644 --- a/src/zkp/pienc.rs +++ b/src/zkp/pienc.rs @@ -26,7 +26,7 @@ //! UC Non-Interactive, Proactive, Threshold ECDSA with Identifiable Aborts. //! [EPrint archive, 2021](https://eprint.iacr.org/2021/060.pdf). use crate::{ - curve_point::{self, CurvePoint}, errors::*, paillier::{Ciphertext, EncryptionKey, MaskedNonce, Nonce}, parameters::{ELL, EPSILON}, ring_pedersen::{Commitment, MaskedRandomness, VerifiedRingPedersen}, utils::{plusminus_challenge_from_transcript, random_plusminus_by_size}, zkp::{Proof, ProofContext} + curve_point::{CurveTrait}, errors::*, paillier::{Ciphertext, EncryptionKey, MaskedNonce, Nonce}, parameters::{ELL, EPSILON}, ring_pedersen::{Commitment, MaskedRandomness, VerifiedRingPedersen}, utils::{plusminus_challenge_from_transcript, random_plusminus_by_size}, zkp::{Proof, ProofContext} }; use libpaillier::unknown_order::BigNumber; use merlin::Transcript; @@ -38,7 +38,7 @@ use tracing::error; /// Proof of knowledge of the plaintext value of a ciphertext, where the value /// is within a desired range. #[derive(Debug, Clone, Serialize, Deserialize)] -pub(crate) struct PiEncProof { +pub(crate) struct PiEncProof { /// Commitment to the plaintext value of the ciphertext (`S` in the paper). plaintext_commit: Commitment, /// Masking ciphertext (`A` in the paper). @@ -57,6 +57,8 @@ pub(crate) struct PiEncProof { /// Response binding the commitment randomness used in the two commitments /// (`z3` in the paper). randomness_response: MaskedRandomness, + /// Marker to pin the curve type `C`. + _marker: std::marker::PhantomData, } /// Common input and setup parameters known to both the prover and verifier. @@ -64,23 +66,23 @@ pub(crate) struct PiEncProof { /// Copying/Cloning references is harmless and sometimes necessary. So we /// implement Clone and Copy for this type. #[derive(Serialize, Copy, Clone)] -pub(crate) struct PiEncInput<'a> { +pub(crate) struct PiEncInput<'a, C: CurveTrait> { /// The verifier's commitment parameters (`(N^hat, s, t)` in the paper). - setup_params: &'a VerifiedRingPedersen, + setup_params: &'a VerifiedRingPedersen, /// The prover's encryption key (`N_0` in the paper). encryption_key: &'a EncryptionKey, /// Ciphertext about which we are proving properties (`K` in the paper). ciphertext: &'a Ciphertext, } -impl<'a> PiEncInput<'a> { +impl<'a, C: CurveTrait> PiEncInput<'a, C> { /// Generate public input for proving or verifying a [`PiEncProof`] about /// `ciphertext`. pub(crate) fn new( - verifer_setup_params: &'a VerifiedRingPedersen, + verifer_setup_params: &'a VerifiedRingPedersen, prover_encryption_key: &'a EncryptionKey, ciphertext: &'a Ciphertext, - ) -> PiEncInput<'a> { + ) -> PiEncInput<'a, C> { Self { setup_params: verifer_setup_params, encryption_key: prover_encryption_key, @@ -119,12 +121,12 @@ impl<'a> PiEncSecret<'a> { } } -impl Proof for PiEncProof { - type CommonInput<'a, CurvePoint: curve_point::CurveTrait + 'a> = PiEncInput<'a>; +impl Proof for PiEncProof { + type CommonInput<'a> = PiEncInput<'a, C>; type ProverSecret<'b> = PiEncSecret<'b>; #[cfg_attr(feature = "flame_it", flame("PiEncProof"))] fn prove( - input: Self::CommonInput<'_, CurvePoint>, + input: Self::CommonInput<'_>, secret: Self::ProverSecret<'_>, context: &impl ProofContext, transcript: &mut Transcript, @@ -187,7 +189,7 @@ impl Proof for PiEncProof { #[cfg_attr(feature = "flame_it", flame("PiEncProof"))] fn verify( self, - input: Self::CommonInput<'_, CurvePoint>, + input: Self::CommonInput<'_>, context: &impl ProofContext, transcript: &mut Transcript, ) -> Result<()> { @@ -258,13 +260,13 @@ impl Proof for PiEncProof { } } -impl PiEncProof { +impl PiEncProof { /// Update the [`Transcript`] with all the commitment values used in the /// proof. fn fill_transcript( transcript: &mut Transcript, context: &impl ProofContext, - input: &PiEncInput, + input: &PiEncInput, plaintext_commit: &Commitment, ciphertext_mask: &Ciphertext, plaintext_mask_commit: &Commitment, @@ -288,10 +290,7 @@ impl PiEncProof { mod tests { use super::*; use crate::{ - paillier::DecryptionKey, - curve_point::{k256_order, testing::init_testing}, - utils::{random_plusminus, random_plusminus_by_size_with_minimum, random_positive_bn}, - zkp::BadContext, + curve_point::{k256_order, testing::init_testing, CurvePoint}, paillier::DecryptionKey, utils::{random_plusminus, random_plusminus_by_size_with_minimum, random_positive_bn}, zkp::BadContext }; use rand::{rngs::StdRng, Rng, SeedableRng}; @@ -301,14 +300,14 @@ mod tests { // Shorthand to avoid putting types for closure arguments. // Note: This does not work on closures that capture variables. - type ProofTest = fn(PiEncProof, PiEncInput) -> Result<()>; + type ProofTest = fn(PiEncProof, PiEncInput) -> Result<()>; /// Generate a [`PiEncProof`] and [`PiEncInput`] and pass them to the /// `test_code` closure. fn with_random_proof( rng: &mut R, plaintext: BigNumber, - mut test_code: impl FnMut(PiEncProof, PiEncInput) -> Result<()>, + mut test_code: impl FnMut(PiEncProof, PiEncInput) -> Result<()>, ) -> Result<()> { let (decryption_key, _, _) = DecryptionKey::new(rng).unwrap(); let encryption_key = decryption_key.encryption_key(); diff --git a/src/zkp/pifac.rs b/src/zkp/pifac.rs index be5c2f3e..c56cc124 100644 --- a/src/zkp/pifac.rs +++ b/src/zkp/pifac.rs @@ -18,7 +18,7 @@ //! [EPrint archive, 2021](https://eprint.iacr.org/2021/060.pdf). use crate::{ - curve_point::{self, CurvePoint}, errors::*, parameters::{ELL, EPSILON}, ring_pedersen::{Commitment, CommitmentRandomness, MaskedRandomness, VerifiedRingPedersen}, utils::{plusminus_challenge_from_transcript, random_plusminus_scaled}, zkp::{Proof, ProofContext} + curve_point::CurveTrait, errors::*, parameters::{ELL, EPSILON}, ring_pedersen::{Commitment, CommitmentRandomness, MaskedRandomness, VerifiedRingPedersen}, utils::{plusminus_challenge_from_transcript, random_plusminus_scaled}, zkp::{Proof, ProofContext} }; use libpaillier::unknown_order::BigNumber; use merlin::Transcript; @@ -31,7 +31,7 @@ use tracing::error; /// Proof that the modulus `N` can be factored into two numbers greater than /// `2^ℓ` for a parameter `ℓ`. #[derive(Debug, Serialize, Deserialize, Clone)] -pub(crate) struct PiFacProof { +pub(crate) struct PiFacProof { /// Commitment to the factor `p` (`P` in the paper). p_commitment: Commitment, /// Commitment to the factor `q` (`Q` in the paper). @@ -58,6 +58,8 @@ pub(crate) struct PiFacProof { /// Masked commitment randomness linking `p` to the commitment randomness /// used in `q_commitment` (`v` in the paper). masked_p_link: MaskedRandomness, + /// Marker to pin the curve type. + curve_type: std::marker::PhantomData, } /// Common input and setup parameters known to both the prover and verifier. @@ -65,16 +67,16 @@ pub(crate) struct PiFacProof { /// Copying/Cloning references is harmless and sometimes necessary. So we /// implement Clone and Copy for this type. #[derive(Serialize, Copy, Clone)] -pub(crate) struct CommonInput<'a> { - setup_params: &'a VerifiedRingPedersen, +pub(crate) struct CommonInput<'a, C: CurveTrait> { + setup_params: &'a VerifiedRingPedersen, modulus: &'a BigNumber, } -impl<'a> CommonInput<'a> { +impl<'a, C: CurveTrait> CommonInput<'a, C> { /// Generate public input for proving and verifying [`PiFacProof`] about /// `N`. pub(crate) fn new( - verifier_commitment_params: &'a VerifiedRingPedersen, + verifier_commitment_params: &'a VerifiedRingPedersen, prover_modulus: &'a BigNumber, ) -> Self { Self { @@ -110,13 +112,13 @@ impl<'a> ProverSecret<'a> { } } -impl Proof for PiFacProof { - type CommonInput<'a, CurvePoint: curve_point::CurveTrait + 'a> = CommonInput<'a>; +impl Proof for PiFacProof { + type CommonInput<'a> = CommonInput<'a, C>; type ProverSecret<'a> = ProverSecret<'a>; #[cfg_attr(feature = "flame_it", flame("PiFacProof"))] fn prove<'a, R: RngCore + CryptoRng>( - input: Self::CommonInput<'a, CurvePoint>, + input: Self::CommonInput<'a>, secret: Self::ProverSecret<'a>, context: &impl ProofContext, transcript: &mut Transcript, @@ -194,7 +196,7 @@ impl Proof for PiFacProof { fn verify( self, - input: Self::CommonInput<'_, CurvePoint>, + input: Self::CommonInput<'_>, context: &impl ProofContext, transcript: &mut Transcript, ) -> Result<()> { @@ -286,12 +288,12 @@ impl Proof for PiFacProof { } } -impl PiFacProof { +impl PiFacProof { #[allow(clippy::too_many_arguments)] fn fill_transcript( transcript: &mut Transcript, context: &impl ProofContext, - input: &CommonInput, + input: &CommonInput, P: &Commitment, Q: &Commitment, A: &Commitment, @@ -328,10 +330,7 @@ fn sqrt(num: &BigNumber) -> BigNumber { #[cfg(test)] mod tests { use crate::{ - paillier::prime_gen, - curve_point::{k256_order, testing::init_testing}, - utils::random_positive_bn, - zkp::BadContext, + curve_point::{k256_order, testing::init_testing, CurvePoint}, paillier::prime_gen, utils::random_positive_bn, zkp::BadContext }; use rand::{prelude::StdRng, Rng, SeedableRng}; @@ -343,7 +342,7 @@ mod tests { fn with_random_no_small_factors_proof( rng: &mut R, - mut test_code: impl FnMut(CommonInput, PiFacProof) -> Result<()>, + mut test_code: impl FnMut(CommonInput::, PiFacProof::) -> Result<()>, ) -> Result<()> { let (p0, q0) = prime_gen::get_prime_pair_from_pool_insecure(rng).unwrap(); let N0 = &p0 * &q0; diff --git a/src/zkp/pilog.rs b/src/zkp/pilog.rs index 75e003c2..3523bddf 100644 --- a/src/zkp/pilog.rs +++ b/src/zkp/pilog.rs @@ -18,14 +18,14 @@ //! [EPrint archive, 2021](https://eprint.iacr.org/2021/060.pdf). use crate::{ - curve_point::{self, CurveTrait}, errors::*, paillier::{Ciphertext, EncryptionKey, MaskedNonce, Nonce}, parameters::{ELL, EPSILON}, ring_pedersen::{Commitment, MaskedRandomness, RingPedersen}, utils::{ + curve_point::CurveTrait, errors::*, paillier::{Ciphertext, EncryptionKey, MaskedNonce, Nonce}, parameters::{ELL, EPSILON}, ring_pedersen::{Commitment, MaskedRandomness, RingPedersen}, utils::{ plusminus_challenge_from_transcript, random_plusminus_by_size, within_bound_by_size, }, zkp::{Proof, ProofContext} }; use libpaillier::unknown_order::BigNumber; use merlin::Transcript; use rand::{CryptoRng, RngCore}; -use serde::{Deserialize, Serialize}; +use serde::{de::DeserializeOwned, Deserialize, Serialize}; use std::fmt::Debug; use tracing::error; use crate::curve_point::CurvePoint; @@ -69,16 +69,16 @@ pub(crate) struct CommonInput<'a, C: CurveTrait> { ciphertext: &'a Ciphertext, /// Claimed discrete log commitment of the (secret) /// [plaintext](ProverSecret::plaintext) (`X` in the paper). - dlog_commit: &'a C::Point, + dlog_commit: &'a C, /// Ring-Pedersen commitment scheme (`(Nhat, s, t)` in the paper). ring_pedersen: &'a RingPedersen, /// Paillier public key (`N_0` in the paper). prover_encryption_key: &'a EncryptionKey, // Group generator for discrete log commitments (`g` in the paper). - generator: &'a C::Point, + generator: &'a C, } -impl<'a, C: CurveTrait> CommonInput<'a, C> { +impl<'a, C: CurveTrait> CommonInput<'a, C> { /// Collect common parameters for proving or verifying a [`PiLogProof`] /// about `ciphertext` and `dlog_commit`. /// @@ -90,11 +90,11 @@ impl<'a, C: CurveTrait> CommonInput<'a, C> { /// 3. `generator` is a group generator. pub(crate) fn new( ciphertext: &'a Ciphertext, - dlog_commit: &'a C::Point, + dlog_commit: &'a C, verifier_ring_pedersen: &'a RingPedersen, prover_encryption_key: &'a EncryptionKey, - generator: &'a C::Point, - ) -> CommonInput<'a, C::Point> where ::Point: curve_point::CurveTrait { + generator: &'a C, + ) -> CommonInput<'a, C> where C: CurveTrait { Self { ciphertext, dlog_commit, @@ -158,12 +158,12 @@ fn generate_challenge( Ok(challenge) } -impl<'de, C: CurveTrait + Deserialize<'de>> Proof for PiLogProof { - type CommonInput<'a, CurvePoint: CurveTrait + 'a> = CommonInput<'a, CurvePoint>; +impl Proof for PiLogProof { + type CommonInput<'a> = CommonInput<'a, CurvePoint>; type ProverSecret<'a> = ProverSecret<'a>; #[cfg_attr(feature = "flame_it", flame("PiLogProof"))] fn prove<'a, R: RngCore + CryptoRng>( - input: Self::CommonInput<'a, CurvePoint>, + input: Self::CommonInput<'a>, secret: Self::ProverSecret<'a>, context: &impl ProofContext, transcript: &mut Transcript, @@ -262,7 +262,7 @@ impl<'de, C: CurveTrait + Deserialize<'de>> Proof for PiLogProof { #[cfg_attr(feature = "flame_it", flame("PiLogProof"))] fn verify<'a>( self, - input: Self::CommonInput<'_, CurvePoint>, + input: Self::CommonInput<'_>, context: &impl ProofContext, transcript: &mut Transcript, ) -> Result<()> { @@ -355,7 +355,7 @@ mod tests { Transcript::new(b"PiLogProof Test") } - fn with_random_paillier_log_proof>( + fn with_random_paillier_log_proof( rng: &mut R, x: &BigNumber, mut f: impl FnMut(PiLogProof, CommonInput) -> Result<()>, @@ -382,7 +382,7 @@ mod tests { f(proof, input) } - fn random_paillier_log_proof_verification>( + fn random_paillier_log_proof_verification( rng: &mut R, x: &BigNumber, ) -> Result<()> { @@ -398,7 +398,7 @@ mod tests { pilog_proof_with_consistent_secret_inputs_out_of_range::().unwrap(); } - fn pilog_proof_with_consistent_secret_inputs_out_of_range>() -> Result<()> { + fn pilog_proof_with_consistent_secret_inputs_out_of_range() -> Result<()> { let mut rng = init_testing(); let upper_bound = BigNumber::one() << (ELL + EPSILON); loop { @@ -431,7 +431,7 @@ mod tests { let _ = pilog_proof_with_different_setup_parameters::(); } - fn pilog_proof_with_different_setup_parameters>() -> Result<()> { + fn pilog_proof_with_different_setup_parameters() -> Result<()> { let mut rng = init_testing(); let x = random_plusminus_by_size(&mut rng, ELL); let (decryption_key, _, _) = DecryptionKey::new(&mut rng).unwrap(); @@ -548,7 +548,7 @@ mod tests { let _ = pilog_proof_with_inconsistent_secret_inputs::(); } - fn pilog_proof_with_inconsistent_secret_inputs>() -> Result<()> + fn pilog_proof_with_inconsistent_secret_inputs() -> Result<()> { let mut rng = init_testing(); @@ -598,13 +598,13 @@ mod tests { negative_test_swap_proof_elements::().unwrap(); } - fn negative_test_swap_proof_elements>() -> Result<()> { + fn negative_test_swap_proof_elements() -> Result<()> { let mut rng = init_testing(); // `rng` will be borrowed. We make another rng to be captured by the closure. let mut rng2 = StdRng::from_seed(rng.gen()); let x = random_plusminus_by_size(&mut rng2, ELL); - let f = |proof: PiLogProof, input: CommonInput| { + let f = |proof: PiLogProof, input: CommonInput| { let setup_params = VerifiedRingPedersen::gen(&mut rng, &())?; // Generate some random elements to use as replacements @@ -681,12 +681,12 @@ mod tests { pilog_proof_context_must_be_correct::().unwrap(); } - fn pilog_proof_context_must_be_correct>() -> Result<()> { + fn pilog_proof_context_must_be_correct() -> Result<()> { let mut rng = init_testing(); let context = BadContext {}; let x_small = random_plusminus_by_size(&mut rng, ELL); - let f = |proof: PiLogProof, input: CommonInput| { + let f = |proof: PiLogProof, input: CommonInput| { let result = proof.verify(input, &context, &mut transcript()); assert!(result.is_err()); Ok(()) diff --git a/src/zkp/pimod.rs b/src/zkp/pimod.rs index 88cd56f9..3a9027b5 100644 --- a/src/zkp/pimod.rs +++ b/src/zkp/pimod.rs @@ -33,7 +33,7 @@ //! December 8-12, 2019, Proceedings, Part III, pages 700–727, 2019. use crate::{ - curve_point::{self, CurvePoint}, errors::*, utils::*, zkp::{Proof, ProofContext} + curve_point::CurveTrait, errors::*, utils::*, zkp::{Proof, ProofContext} }; use libpaillier::unknown_order::BigNumber; use merlin::Transcript; @@ -46,10 +46,12 @@ use tracing::error; static LAMBDA: usize = crate::parameters::SOUNDNESS_PARAMETER; #[derive(Debug, Clone, Serialize, Deserialize)] -pub(crate) struct PiModProof { +pub(crate) struct PiModProof { random_jacobi_one: BigNumber, // (x, a, b, z), elements: Vec, + /// Marker to pin the curve type + curve: std::marker::PhantomData, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -103,15 +105,15 @@ impl<'a> ProverSecret<'a> { } } -impl Proof for PiModProof { - type CommonInput<'a, CurvePoint: curve_point::CurveTrait + 'a> = CommonInput<'a>; +impl Proof for PiModProof { + type CommonInput<'a> = CommonInput<'a>; type ProverSecret<'a> = ProverSecret<'a>; /// Generated by the prover, requires public input N and secrets (p,q) /// Prover generates a random w in Z_N of Jacobi symbol -1 #[allow(clippy::many_single_char_names)] #[cfg_attr(feature = "flame_it", flame("PaillierBlumModulusProof"))] fn prove( - input: Self::CommonInput<'_, CurvePoint>, + input: Self::CommonInput<'_>, secret: Self::ProverSecret<'_>, context: &impl ProofContext, transcript: &mut Transcript, @@ -161,7 +163,7 @@ impl Proof for PiModProof { #[cfg_attr(feature = "flame_it", flame("PaillierBlumModulusProof"))] fn verify( self, - input: Self::CommonInput<'_, CurvePoint>, + input: Self::CommonInput<'_>, context: &impl ProofContext, transcript: &mut Transcript, ) -> Result<()> { @@ -243,7 +245,7 @@ impl Proof for PiModProof { } } -impl PiModProof { +impl PiModProof { fn fill_transcript( transcript: &mut Transcript, context: &impl ProofContext, @@ -475,7 +477,7 @@ fn y_prime_combinations( #[cfg(test)] mod tests { use rand::{rngs::StdRng, Rng}; - use crate::curve_point::k256_order; + use crate::curve_point::{k256_order, CurvePoint}; use super::*; use crate::{ @@ -783,11 +785,11 @@ mod tests { assert_eq!(buf, bincode::serialize(&roundtrip_pbmp).unwrap()); } - type TestFn = fn(PiModProof, CommonInput, &mut StdRng) -> Result<()>; + type TestFn = fn(PiModProof::, CommonInput, &mut StdRng) -> Result<()>; fn with_random_pimod_proof( rng: &mut StdRng, - mut test_code: impl FnMut(PiModProof, CommonInput, &mut StdRng) -> Result<()>, + mut test_code: impl FnMut(PiModProof::, CommonInput, &mut StdRng) -> Result<()>, ) -> Result<()> { let (decryption_key, p, q) = DecryptionKey::new(rng).unwrap(); @@ -796,7 +798,7 @@ mod tests { }; let secret = ProverSecret { p: &p, q: &q }; - let proof_result = PiModProof::prove(input, secret, &(), &mut transcript(), rng); + let proof_result = PiModProof::::prove(input, secret, &(), &mut transcript(), rng); assert!(proof_result.is_ok()); test_code(proof_result.unwrap(), input, rng) diff --git a/src/zkp/piprm.rs b/src/zkp/piprm.rs index 46608543..75f73187 100644 --- a/src/zkp/piprm.rs +++ b/src/zkp/piprm.rs @@ -23,7 +23,7 @@ //! [EPrint archive, 2021](https://eprint.iacr.org/2021/060.pdf). use crate::{ - curve_point::{self, CurvePoint}, errors::*, ring_pedersen::RingPedersen, utils::*, zkp::{Proof, ProofContext} + curve_point::CurveTrait, errors::*, ring_pedersen::RingPedersen, utils::*, zkp::{Proof, ProofContext} }; use libpaillier::unknown_order::BigNumber; use merlin::Transcript; @@ -38,13 +38,15 @@ const SOUNDNESS: usize = crate::parameters::SOUNDNESS_PARAMETER; /// Proof that externally provided [`RingPedersen`] parameters are constructed /// correctly. #[derive(Debug, Clone, Serialize, Deserialize)] -pub(crate) struct PiPrmProof { +pub(crate) struct PiPrmProof { /// The commitments computed by the prover (`A_i` in the paper). commitments: Vec, /// The randomized challenge bytes (`e_i` in the paper). challenge_bytes: Vec, /// The prover responses (`z_i` in the paper). responses: Vec, + /// Marker to pin the curve type. + curve: std::marker::PhantomData, } /// The prover's secret knowledge. @@ -93,12 +95,12 @@ fn generate_challenge_bytes( Ok(challenges.into()) } -impl Proof for PiPrmProof { - type CommonInput<'a, CurvePoint: curve_point::CurveTrait + 'a> = &'a RingPedersen; +impl Proof for PiPrmProof { + type CommonInput<'a> = &'a RingPedersen; type ProverSecret<'a> = PiPrmSecret<'a>; #[cfg_attr(feature = "flame_it", flame("PiPrmProof"))] fn prove( - input: Self::CommonInput<'_, CurvePoint>, + input: Self::CommonInput<'_>, secret: Self::ProverSecret<'_>, context: &impl ProofContext, transcript: &mut Transcript, @@ -138,7 +140,7 @@ impl Proof for PiPrmProof { #[cfg_attr(feature = "flame_it", flame("PiPrmProof"))] fn verify( self, - input: Self::CommonInput<'_, CurvePoint>, + input: Self::CommonInput<'_>, context: &impl ProofContext, transcript: &mut Transcript, ) -> Result<()> { @@ -185,7 +187,7 @@ impl Proof for PiPrmProof { #[cfg(test)] mod tests { use super::*; - use crate::{paillier::DecryptionKey, curve_point::testing::init_testing, zkp::BadContext}; + use crate::{curve_point::{testing::init_testing, CurvePoint}, paillier::DecryptionKey, zkp::BadContext}; use rand::Rng; /// Make a transcript for PiPrmProof. @@ -195,7 +197,7 @@ mod tests { fn random_ring_pedersen_proof( rng: &mut R, - ) -> Result<(RingPedersen, PiPrmProof, BigNumber, BigNumber)> { + ) -> Result<(RingPedersen, PiPrmProof::, BigNumber, BigNumber)> { let (sk, _, _) = DecryptionKey::new(rng).unwrap(); let (scheme, lambda, totient) = RingPedersen::extract(&sk, rng)?; let secrets = PiPrmSecret::new(&lambda, &totient); diff --git a/src/zkp/pisch.rs b/src/zkp/pisch.rs index 4ec5cab9..76a01e8f 100644 --- a/src/zkp/pisch.rs +++ b/src/zkp/pisch.rs @@ -27,12 +27,12 @@ //! UC Non-Interactive, Proactive, Threshold ECDSA with Identifiable Aborts. //! [EPrint archive, 2021](https://eprint.iacr.org/2021/060.pdf). use crate::{ - curve_point::{self, k256_order, CurveTrait}, errors::*, messages::{KeygenMessageType, KeyrefreshMessageType, Message, MessageType}, utils::{positive_challenge_from_transcript, random_positive_bn}, zkp::{Proof, ProofContext} + curve_point::{k256_order, CurveTrait}, errors::*, messages::{KeygenMessageType, KeyrefreshMessageType, Message, MessageType}, utils::{positive_challenge_from_transcript, random_positive_bn}, zkp::{Proof, ProofContext} }; use libpaillier::unknown_order::BigNumber; use merlin::Transcript; use rand::{CryptoRng, RngCore}; -use serde::{Deserialize, Serialize}; +use serde::{de::DeserializeOwned, Deserialize, Serialize}; use std::{convert::AsRef, fmt::Debug}; use tracing::error; use crate::curve_point::CurvePoint; @@ -76,8 +76,8 @@ pub(crate) struct CommonInput<'a> { x_commitment: &'a CurvePoint, } -impl> PiSchPrecommit { - pub(crate) fn precommitment(&self) -> &CurvePoint { +impl PiSchPrecommit { + pub(crate) fn precommitment(&self) -> &C { &self.precommitment } } @@ -110,13 +110,13 @@ impl<'a> ProverSecret<'a> { } } -impl<'de, C: CurveTrait + Deserialize<'de>> Proof for PiSchProof +impl Proof for PiSchProof { - type CommonInput<'a, CurvePoint: curve_point::CurveTrait + 'a> = CommonInput<'a>; + type CommonInput<'a> = CommonInput<'a>; type ProverSecret<'a> = ProverSecret<'a>; #[cfg_attr(feature = "flame_it", flame("PiSchProof"))] fn prove( - input: Self::CommonInput<'_, CurvePoint>, + input: Self::CommonInput<'_>, secret: Self::ProverSecret<'_>, context: &impl ProofContext, transcript: &mut Transcript, @@ -130,7 +130,7 @@ impl<'de, C: CurveTrait + Deserialize<'de>> Proof for PiSchProof #[cfg_attr(feature = "flame_it", flame("PiSchProof"))] fn verify( self, - input: Self::CommonInput<'_, CurvePoint>, + input: Self::CommonInput<'_>, context: &impl ProofContext, transcript: &mut Transcript, ) -> Result<()> { @@ -160,7 +160,7 @@ impl<'de, C: CurveTrait + Deserialize<'de>> Proof for PiSchProof } } -impl> PiSchProof { +impl PiSchProof { /// "Commitment" phase of the PiSch proof. pub fn precommit(rng: &mut R) -> Result> { // Sample alpha from F_q From 61071cf6e1a54ac43a97a3548356b21267bf9eb0 Mon Sep 17 00:00:00 2001 From: emmorais Date: Mon, 5 Aug 2024 08:48:06 -0300 Subject: [PATCH 18/36] Intermediate state of fixing errors --- src/auxinfo/auxinfo_commit.rs | 18 +++--- src/auxinfo/info.rs | 12 ++-- src/auxinfo/output.rs | 18 +++--- src/auxinfo/participant.rs | 38 ++++++------- src/auxinfo/proof.rs | 70 ++++++++++++------------ src/keygen/keyshare.rs | 17 +++--- src/keygen/output.rs | 9 ++- src/keygen/participant.rs | 2 +- src/keyrefresh/input.rs | 12 ++-- src/keyrefresh/keyrefresh_commit.rs | 2 +- src/keyrefresh/keyshare.rs | 12 ++-- src/presign/input.rs | 12 ++-- src/presign/participant.rs | 12 ++-- src/presign/record.rs | 30 +++++----- src/presign/round_one.rs | 18 +++--- src/presign/round_three.rs | 6 +- src/presign/round_two.rs | 4 +- src/protocol.rs | 6 +- src/ring_pedersen.rs | 13 +++-- src/sign/interactive_sign/participant.rs | 8 +-- src/zkp/mod.rs | 4 +- src/zkp/piaffg.rs | 12 ++-- src/zkp/pienc.rs | 30 +++++----- src/zkp/pifac.rs | 26 ++++----- src/zkp/pilog.rs | 28 +++++----- src/zkp/pimod.rs | 18 +++--- src/zkp/piprm.rs | 12 ++-- src/zkp/pisch.rs | 4 +- 28 files changed, 220 insertions(+), 233 deletions(-) diff --git a/src/auxinfo/auxinfo_commit.rs b/src/auxinfo/auxinfo_commit.rs index 3c72be80..df0b4980 100644 --- a/src/auxinfo/auxinfo_commit.rs +++ b/src/auxinfo/auxinfo_commit.rs @@ -7,7 +7,7 @@ // of this source tree. use crate::{ - auxinfo::{info::AuxInfoPublic, participant::AuxInfoParticipant}, curve_point::CurveTrait, errors::{InternalError, Result}, messages::{AuxinfoMessageType, Message, MessageType}, parameters::PRIME_BITS, participant::{InnerProtocolParticipant, ProtocolParticipant}, protocol::{Identifier, ParticipantIdentifier} + auxinfo::{info::AuxInfoPublic, participant::AuxInfoParticipant}, errors::{InternalError, Result}, messages::{AuxinfoMessageType, Message, MessageType}, parameters::PRIME_BITS, participant::{InnerProtocolParticipant, ProtocolParticipant}, protocol::{Identifier, ParticipantIdentifier} }; use libpaillier::unknown_order::BigNumber; use merlin::Transcript; @@ -37,14 +37,14 @@ impl Commitment { /// to send decommit to a validly produced [`Commitment`] one needs to send /// [`CommitmentScheme`] itself. #[derive(Serialize, Deserialize, Clone)] -pub(crate) struct CommitmentScheme { +pub(crate) struct CommitmentScheme { /// A unique session identifier (`ssid` in the paper). sid: Identifier, /// This participant's [`ParticipantIdentifier`] (`i` in the paper). pid: ParticipantIdentifier, /// This participant's [`AuxInfoPublic`] (`N_i, s_i, t_i, ψhat_i` in the /// paper). - public_key: AuxInfoPublic, + public_key: AuxInfoPublic, /// This participant's randomness (`ρ_i` in the paper). /// /// This randomness is combined with all other participants' randomness and @@ -57,7 +57,7 @@ pub(crate) struct CommitmentScheme { commit_randomness: [u8; 32], } -impl Debug for CommitmentScheme { +impl Debug for CommitmentScheme { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { // Redacting randomness and commit_randomness because I'm not sure how // sensitive they are. If later analysis suggests they're fine to print, @@ -72,7 +72,7 @@ impl Debug for CommitmentScheme { } } -impl CommitmentScheme { +impl CommitmentScheme { /// Construct a new [`CommitmentScheme`] using the provided unique session /// [`Identifier`], [`AuxInfoParticipant`], and [`AuxInfoPublic`]. /// @@ -81,8 +81,8 @@ impl CommitmentScheme { /// [`AuxInfoParticipant`]. pub(crate) fn new( sid: Identifier, - auxinfo_participant: &AuxInfoParticipant, - public_key: AuxInfoPublic, + auxinfo_participant: &AuxInfoParticipant, + public_key: AuxInfoPublic, rng: &mut R, ) -> Result { let mut rid = [0u8; 32]; @@ -112,7 +112,7 @@ impl CommitmentScheme { /// This method verifies all the internal [`CommitmentScheme`] values. pub(crate) fn from_message( message: &Message, - context: & as InnerProtocolParticipant>::Context, + context: &::Context, ) -> Result { message.check_type(MessageType::Auxinfo(AuxinfoMessageType::R2Decommit))?; let scheme: CommitmentScheme = deserialize!(&message.unverified_bytes)?; @@ -164,7 +164,7 @@ impl CommitmentScheme { self.randomness } - pub(crate) fn into_public(self) -> AuxInfoPublic { + pub(crate) fn into_public(self) -> AuxInfoPublic { self.public_key } diff --git a/src/auxinfo/info.rs b/src/auxinfo/info.rs index 9d61cb86..e0b45c48 100644 --- a/src/auxinfo/info.rs +++ b/src/auxinfo/info.rs @@ -7,7 +7,7 @@ // of this source tree. use crate::{ - curve_point::CurveTrait, errors::{CallerError, InternalError, Result}, paillier::{DecryptionKey, EncryptionKey}, ring_pedersen::VerifiedRingPedersen, utils::ParseBytes, zkp::ProofContext, ParticipantIdentifier + errors::{CallerError, InternalError, Result}, paillier::{DecryptionKey, EncryptionKey}, ring_pedersen::VerifiedRingPedersen, utils::ParseBytes, zkp::ProofContext, ParticipantIdentifier }; use k256::elliptic_curve::zeroize::ZeroizeOnDrop; use libpaillier::unknown_order::BigNumber; @@ -139,21 +139,21 @@ impl Debug for AuxInfoPrivate { /// This includes a Paillier encryption key and corresponding ring-Pedersen /// commitment parameters. #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] -pub struct AuxInfoPublic { +pub struct AuxInfoPublic { /// The participant's identifier. participant: ParticipantIdentifier, /// The participant's Paillier public key. pk: EncryptionKey, /// The participant's (verified) ring-Pedersen parameters. - params: VerifiedRingPedersen, + params: VerifiedRingPedersen, } -impl AuxInfoPublic { +impl AuxInfoPublic { pub(crate) fn new( context: &impl ProofContext, participant: ParticipantIdentifier, encryption_key: EncryptionKey, - params: VerifiedRingPedersen, + params: VerifiedRingPedersen, ) -> Result { let public = Self { participant, @@ -168,7 +168,7 @@ impl AuxInfoPublic { &self.pk } - pub(crate) fn params(&self) -> &VerifiedRingPedersen { + pub(crate) fn params(&self) -> &VerifiedRingPedersen { &self.params } diff --git a/src/auxinfo/output.rs b/src/auxinfo/output.rs index 7535b7cd..de0818ee 100644 --- a/src/auxinfo/output.rs +++ b/src/auxinfo/output.rs @@ -3,7 +3,7 @@ use std::collections::HashSet; use crate::{ - auxinfo::info::{AuxInfoPrivate, AuxInfoPublic}, curve_point::CurveTrait, errors::{CallerError, InternalError, Result}, protocol::ParticipantIdentifier + auxinfo::info::{AuxInfoPrivate, AuxInfoPublic}, errors::{CallerError, InternalError, Result}, protocol::ParticipantIdentifier }; use tracing::error; @@ -14,19 +14,19 @@ use rand::{CryptoRng, RngCore}; /// This should include an [`AuxInfoPublic`] for every protocol participant /// and an [`AuxInfoPrivate`] for participant that receives this output. #[derive(Debug, Clone)] -pub struct Output { - public_auxinfo: Vec>, +pub struct Output { + public_auxinfo: Vec, private_auxinfo: AuxInfoPrivate, } -impl Output { +impl Output { /// Create a new `Output` from its constituent parts. /// /// The parts must constitute a valid output: /// - the public components should be from a unique set of participants; /// - the private component should have a corresponding public component. pub fn from_parts( - public_auxinfo: Vec>, + public_auxinfo: Vec, private_auxinfo: AuxInfoPrivate, ) -> Result { let pids = public_auxinfo @@ -63,11 +63,11 @@ impl Output { /// after it's securely stored. /// /// The public components can be stored in the clear. - pub fn into_parts(self) -> (Vec>, AuxInfoPrivate) { + pub fn into_parts(self) -> (Vec, AuxInfoPrivate) { (self.public_auxinfo, self.private_auxinfo) } - pub(crate) fn public_auxinfo(&self) -> &[AuxInfoPublic] { + pub(crate) fn public_auxinfo(&self) -> &[AuxInfoPublic] { &self.public_auxinfo } @@ -86,7 +86,7 @@ impl Output { } } - pub(crate) fn find_public(&self, pid: ParticipantIdentifier) -> Option<&AuxInfoPublic> { + pub(crate) fn find_public(&self, pid: ParticipantIdentifier) -> Option<&AuxInfoPublic> { self.public_auxinfo .iter() .find(|public_key| public_key.participant() == pid) @@ -105,7 +105,7 @@ mod tests { ParticipantConfig, }; - impl Output { + impl Output { /// Simulate the valid output of an auxinfo run with the given /// participants. /// diff --git a/src/auxinfo/participant.rs b/src/auxinfo/participant.rs index 94a783f5..3f5fcd2c 100644 --- a/src/auxinfo/participant.rs +++ b/src/auxinfo/participant.rs @@ -15,7 +15,7 @@ use crate::{ info::{AuxInfoPrivate, AuxInfoPublic, AuxInfoWitnesses}, proof::{AuxInfoProof, CommonInput}, Output, - }, broadcast::participant::{BroadcastOutput, BroadcastParticipant, BroadcastTag}, curve_point::{CurvePoint, CurveTrait}, errors::{CallerError, InternalError, Result}, local_storage::LocalStorage, messages::{AuxinfoMessageType, Message, MessageType}, paillier::DecryptionKey, participant::{ + }, broadcast::participant::{BroadcastOutput, BroadcastParticipant, BroadcastTag}, curve_point::CurvePoint, errors::{CallerError, InternalError, Result}, local_storage::LocalStorage, messages::{AuxinfoMessageType, Message, MessageType}, paillier::DecryptionKey, participant::{ Broadcast, InnerProtocolParticipant, ProcessOutcome, ProtocolParticipant, Status, }, protocol::{Identifier, ParticipantIdentifier, ProtocolType, SharedContext}, ring_pedersen::VerifiedRingPedersen, run_only_once }; @@ -33,7 +33,7 @@ mod storage { } pub(super) struct Public; impl TypeTag for Public { - type Value = AuxInfoPublic; + type Value = AuxInfoPublic; } pub(super) struct Commit; impl TypeTag for Commit { @@ -41,7 +41,7 @@ mod storage { } pub(super) struct Decommit; impl TypeTag for Decommit { - type Value = CommitmentScheme; + type Value = CommitmentScheme; } pub(super) struct GlobalRid; impl TypeTag for GlobalRid { @@ -101,7 +101,7 @@ mod storage { /// not include the key-refresh steps included in Figure 6. #[derive(Debug)] -pub struct AuxInfoParticipant { +pub struct AuxInfoParticipant { /// The current session identifier sid: Identifier, /// A unique identifier for this participant @@ -115,15 +115,13 @@ pub struct AuxInfoParticipant { broadcast_participant: BroadcastParticipant, /// The status of the protocol execution status: Status, - /// Marker for the curve type - curve_type: std::marker::PhantomData, } -impl ProtocolParticipant for AuxInfoParticipant { +impl ProtocolParticipant for AuxInfoParticipant { type Input = (); // The output type includes `AuxInfoPublic` material for all participants // (including ourselves) and `AuxInfoPrivate` for ourselves. - type Output = Output; + type Output = Output; fn new( sid: Identifier, @@ -213,8 +211,8 @@ impl ProtocolParticipant for AuxInfoParticipant { } } -impl InnerProtocolParticipant for AuxInfoParticipant { - type Context = SharedContext; +impl InnerProtocolParticipant for AuxInfoParticipant { + type Context = SharedContext; fn retrieve_context(&self) -> ::Context { SharedContext::collect(self) @@ -233,13 +231,13 @@ impl InnerProtocolParticipant for AuxInfoParticipant { } } -impl Broadcast for AuxInfoParticipant { +impl Broadcast for AuxInfoParticipant { fn broadcast_participant(&mut self) -> &mut BroadcastParticipant { &mut self.broadcast_participant } } -impl AuxInfoParticipant { +impl AuxInfoParticipant { /// Handle "Ready" messages from the protocol participants. /// /// Once "Ready" messages have been received from all participants, this @@ -499,7 +497,7 @@ impl AuxInfoParticipant { // ... and use its setup parameters in the proof. let common_input = CommonInput::new(shared_context, sid, global_rid, self.id(), params, &product); - let proof = AuxInfoProof::prove(rng, &common_input, &witness.p, &witness.q)?; + let proof = AuxInfoProof::prove::(rng, &common_input, &witness.p, &witness.q)?; Message::new( MessageType::Auxinfo(AuxinfoMessageType::R3Proof), sid, @@ -554,7 +552,7 @@ impl AuxInfoParticipant { ); // Verify the public parameters for the given participant. Note that // this verification verifies _both_ the `𝚷[mod]` and `𝚷[fac]` proofs. - proof.verify(&common_input)?; + proof.verify::(&common_input)?; self.local_storage .store_once::(message.from(), auxinfo_pub)?; @@ -593,7 +591,7 @@ impl AuxInfoParticipant { fn new_auxinfo( &self, rng: &mut R, - ) -> Result<(AuxInfoPrivate, AuxInfoPublic, AuxInfoWitnesses)> { + ) -> Result<(AuxInfoPrivate, AuxInfoPublic, AuxInfoWitnesses)> { debug!("Creating new auxinfo."); let (decryption_key, p, q) = DecryptionKey::new(rng).map_err(|_| { @@ -614,11 +612,11 @@ impl AuxInfoParticipant { #[cfg(test)] mod tests { use super::*; - use crate::{curve_point::testing::init_testing, Identifier, ParticipantConfig}; + use crate::{curve_point::{testing::init_testing, CurvePoint}, Identifier, ParticipantConfig}; use rand::{CryptoRng, Rng, RngCore}; use std::collections::HashMap; - impl AuxInfoParticipant { + impl AuxInfoParticipant { pub fn new_quorum( sid: Identifier, input: (), @@ -659,7 +657,7 @@ mod tests { } } - fn is_auxinfo_done(quorum: &[AuxInfoParticipant]) -> bool { + fn is_auxinfo_done(quorum: &[AuxInfoParticipant]) -> bool { for participant in quorum { if *participant.status() != Status::TerminatedSuccessfully { return false; @@ -673,10 +671,10 @@ mod tests { /// /// Returns None if there are no messages for the selected participant. fn process_messages( - quorum: &mut [AuxInfoParticipant], + quorum: &mut [AuxInfoParticipant], inboxes: &mut HashMap>, rng: &mut R, - ) -> Option<(usize, ProcessOutcome>)> { + ) -> Option<(usize, ProcessOutcome)> { // Pick a random participant to process let index = rng.gen_range(0..quorum.len()); let participant = quorum.get_mut(index).unwrap(); diff --git a/src/auxinfo/proof.rs b/src/auxinfo/proof.rs index 2b0cdd60..cce1c0bd 100644 --- a/src/auxinfo/proof.rs +++ b/src/auxinfo/proof.rs @@ -7,7 +7,7 @@ // of this source tree. use crate::{ - auxinfo::participant::AuxInfoParticipant, curve_point::CurveTrait, errors::Result, messages::{AuxinfoMessageType, Message, MessageType}, participant::InnerProtocolParticipant, ring_pedersen::VerifiedRingPedersen, Identifier, ParticipantIdentifier + auxinfo::participant::AuxInfoParticipant, curve_point::{CurvePoint, CurveTrait}, errors::Result, messages::{AuxinfoMessageType, Message, MessageType}, participant::InnerProtocolParticipant, ring_pedersen::VerifiedRingPedersen, Identifier, ParticipantIdentifier }; use crate::zkp::{pifac, pimod, Proof, ProofContext}; @@ -21,32 +21,32 @@ use serde::{Deserialize, Serialize}; /// /// This type includes proofs for `𝚷[fac]` and `𝚷[mod]`. #[derive(Serialize, Deserialize, Clone)] -pub(crate) struct AuxInfoProof { - pimod: pimod::PiModProof::, - pifac: pifac::PiFacProof::, +pub(crate) struct AuxInfoProof { + pimod: pimod::PiModProof, + pifac: pifac::PiFacProof, } /// Common input and setup parameters known to both the prover and the verifier. #[derive(Clone)] -pub(crate) struct CommonInput<'a, C: CurveTrait> { - shared_context: &'a as InnerProtocolParticipant>::Context, +pub(crate) struct CommonInput<'a> { + shared_context: &'a ::Context, sid: Identifier, rho: [u8; 32], pid: ParticipantIdentifier, - setup_parameters: &'a VerifiedRingPedersen, + setup_parameters: &'a VerifiedRingPedersen, modulus: &'a BigNumber, } -impl<'a, C: CurveTrait> CommonInput<'a, C> { +impl<'a> CommonInput<'a> { /// Collect common parameters for proving or verifying a [`AuxInfoProof`] pub(crate) fn new( - shared_context: &'a as InnerProtocolParticipant>::Context, + shared_context: &'a ::Context, sid: Identifier, rho: [u8; 32], pid: ParticipantIdentifier, - verifier_setup_parameters: &'a VerifiedRingPedersen, + verifier_setup_parameters: &'a VerifiedRingPedersen, modulus: &'a BigNumber, - ) -> CommonInput<'a, C> { + ) -> CommonInput<'a> { Self { shared_context, sid, @@ -58,7 +58,7 @@ impl<'a, C: CurveTrait> CommonInput<'a, C> { } } -impl AuxInfoProof { +impl AuxInfoProof { /// Generate a fresh transcript to be used in [`AuxInfoProof`]. fn new_transcript() -> Transcript { Transcript::new(b"AuxInfoProof") @@ -81,35 +81,35 @@ impl AuxInfoProof { /// Note: The [`VerifiedRingPedersen`] argument **must be** provided by the /// verifier! #[allow(clippy::too_many_arguments)] - pub(crate) fn prove( + pub(crate) fn prove( rng: &mut R, - common_input: &CommonInput, + common_input: &CommonInput, p: &BigNumber, q: &BigNumber, ) -> Result { let mut transcript = Self::new_transcript(); - Self::append_pimod_transcript( + Self::append_pimod_transcript::( &mut transcript, common_input.shared_context, common_input.sid, common_input.rho, common_input.pid, )?; - let pimod: pimod::PiModProof:: = pimod::PiModProof::::prove( + let pimod: pimod::PiModProof = pimod::PiModProof::prove( pimod::CommonInput::new(common_input.modulus), pimod::ProverSecret::new(p, q), common_input.shared_context, &mut transcript, rng, )?; - Self::append_pifac_transcript( + Self::append_pifac_transcript::( &mut transcript, common_input.shared_context, common_input.sid, common_input.rho, common_input.pid, )?; - let pifac = pifac::PiFacProof::::prove( + let pifac = pifac::PiFacProof::prove( pifac::CommonInput::new(common_input.setup_parameters, common_input.modulus), pifac::ProverSecret::new(p, q), common_input.shared_context, @@ -126,9 +126,9 @@ impl AuxInfoProof { /// /// Note: The [`VerifiedRingPedersen`] argument **must be** provided by the /// verifier! - pub(crate) fn verify(self, common_input: &CommonInput) -> Result<()> { + pub(crate) fn verify(self, common_input: &CommonInput) -> Result<()> { let mut transcript = Self::new_transcript(); - Self::append_pimod_transcript( + Self::append_pimod_transcript::( &mut transcript, common_input.shared_context, common_input.sid, @@ -140,7 +140,7 @@ impl AuxInfoProof { common_input.shared_context, &mut transcript, )?; - Self::append_pifac_transcript( + Self::append_pifac_transcript::( &mut transcript, common_input.shared_context, common_input.sid, @@ -157,9 +157,9 @@ impl AuxInfoProof { /// Append info relevant to the `𝚷[mod]` proof to the provided /// [`Transcript`]. - fn append_pimod_transcript( + fn append_pimod_transcript( transcript: &mut Transcript, - context: & as InnerProtocolParticipant>::Context, + context: &::Context, sid: Identifier, rho: [u8; 32], pid: ParticipantIdentifier, @@ -174,9 +174,9 @@ impl AuxInfoProof { /// Append info relevant to the `𝚷[fac]` proof to the provided /// [`Transcript`]. - fn append_pifac_transcript( + fn append_pifac_transcript( transcript: &mut Transcript, - context: & as InnerProtocolParticipant>::Context, + context: &::Context, sid: Identifier, rho: [u8; 32], pid: ParticipantIdentifier, @@ -198,18 +198,18 @@ mod tests { fn random_auxinfo_proof( rng: &mut R, - test_code: impl FnOnce(CommonInput, AuxInfoProof) -> Result<()>, + test_code: impl FnOnce(CommonInput, AuxInfoProof) -> Result<()>, ) -> Result<()> { let sid = Identifier::random(rng); let rho = rng.gen(); let pid = ParticipantIdentifier::random(rng); - let setup_params = VerifiedRingPedersen::::gen(rng, &()).unwrap(); + let setup_params = VerifiedRingPedersen::gen(rng, &()).unwrap(); let (p, q) = prime_gen::get_prime_pair_from_pool_insecure(rng).unwrap(); let modulus = &p * &q; let shared_context = SharedContext::random(rng); let common_input = CommonInput::new(&shared_context, sid, rho, pid, &setup_params, &modulus); - let proof = AuxInfoProof::::prove(rng, &common_input, &p, &q).unwrap(); + let proof = AuxInfoProof::prove::(rng, &common_input, &p, &q).unwrap(); test_code(common_input, proof) } @@ -219,14 +219,14 @@ mod tests { let sid = Identifier::random(&mut rng); let rho = rng.gen(); let pid = ParticipantIdentifier::random(&mut rng); - let setup_params = VerifiedRingPedersen::::gen(&mut rng, &())?; + let setup_params = VerifiedRingPedersen::gen(&mut rng, &())?; let (p, q) = prime_gen::get_prime_pair_from_pool_insecure(&mut rng).unwrap(); let modulus = &p * &q; let shared_context = SharedContext::random(&mut rng); let common_input = CommonInput::new(&shared_context, sid, rho, pid, &setup_params, &modulus); - let proof = AuxInfoProof::::prove(&mut rng, &common_input, &p, &q)?; - assert!(proof.verify(&common_input).is_ok()); + let proof = AuxInfoProof::prove::(&mut rng, &common_input, &p, &q)?; + assert!(proof.verify::(&common_input).is_ok()); Ok(()) } @@ -244,8 +244,8 @@ mod tests { pifac: proof1.pifac, pimod: proof.pimod, }; - assert!(mix_one.verify(&input).is_err()); - assert!(mix_two.verify(&input1).is_err()); + assert!(mix_one.verify::(&input).is_err()); + assert!(mix_two.verify::(&input1).is_err()); Ok(()) }; random_auxinfo_proof(&mut rng2, f1)?; @@ -267,8 +267,8 @@ mod tests { let modulus = &p * &q; let shared_context = &SharedContext::random(&mut rng); let common_input = CommonInput::new(shared_context, sid, rho, pid, &setup_params, &modulus); - match AuxInfoProof::prove(&mut rng, &common_input, &p1, &q1) { - Ok(proof) => assert!(proof.verify(&common_input).is_err()), + match AuxInfoProof::prove::(&mut rng, &common_input, &p1, &q1) { + Ok(proof) => assert!(proof.verify::(&common_input).is_err()), Err(_) => return Ok(()), } Ok(()) diff --git a/src/keygen/keyshare.rs b/src/keygen/keyshare.rs index b244f9bc..09096abd 100644 --- a/src/keygen/keyshare.rs +++ b/src/keygen/keyshare.rs @@ -24,19 +24,17 @@ const KEYSHARE_TAG: &[u8] = b"KeySharePrivate"; /// # 🔒 Storage requirements /// This type must be stored securely by the calling application. #[derive(Clone, PartialEq, Eq)] -pub struct KeySharePrivate { +pub struct KeySharePrivate { x: BigNumber, // in the range [1, q) - /// Marker to pin the generic type. - curve: std::marker::PhantomData, } -impl Debug for KeySharePrivate { +impl Debug for KeySharePrivate { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.write_str("KeySharePrivate([redacted])") } } -impl KeySharePrivate { +impl KeySharePrivate { /// Sample a private key share uniformly at random. pub(crate) fn random(rng: &mut (impl CryptoRng + RngCore)) -> Self { let random_bn = BigNumber::from_rng(&k256_order(), rng); @@ -133,7 +131,7 @@ impl KeySharePrivate { } } -impl AsRef for KeySharePrivate { +impl AsRef for KeySharePrivate { /// Get the private key share. fn as_ref(&self) -> &BigNumber { &self.x @@ -166,7 +164,7 @@ impl KeySharePublic { pub(crate) fn new_keyshare( participant: ParticipantIdentifier, rng: &mut R, - ) -> Result<(KeySharePrivate, KeySharePublic)> { + ) -> Result<(KeySharePrivate, KeySharePublic)> { let private_share = KeySharePrivate::random(rng); let public_share = private_share.public_share()?; @@ -187,14 +185,13 @@ impl AsRef for KeySharePublic { #[cfg(test)] mod tests { use crate::{ - keygen::{keyshare::KEYSHARE_TAG, KeySharePrivate}, - curve_point::{k256_order, testing::init_testing}, + curve_point::{k256_order, testing::init_testing, CurvePoint}, keygen::{keyshare::KEYSHARE_TAG, KeySharePrivate} }; #[test] fn keyshare_private_bytes_conversion_works() { let rng = &mut init_testing(); - let share = KeySharePrivate::random(rng); + let share: KeySharePrivate = KeySharePrivate::random(rng); let bytes = share.clone().into_bytes(); let reconstructed = KeySharePrivate::try_from_bytes(bytes); diff --git a/src/keygen/output.rs b/src/keygen/output.rs index 6f86265e..9052753e 100644 --- a/src/keygen/output.rs +++ b/src/keygen/output.rs @@ -19,7 +19,7 @@ use tracing::error; #[derive(Debug, Clone)] pub struct Output { public_key_shares: Vec>, - private_key_share: KeySharePrivate, + private_key_share: KeySharePrivate, rid: [u8; 32], } @@ -43,7 +43,7 @@ impl Output { &self.public_key_shares } - pub(crate) fn private_key_share(&self) -> &KeySharePrivate { + pub(crate) fn private_key_share(&self) -> &KeySharePrivate { &self.private_key_share } @@ -81,7 +81,7 @@ impl Output { /// - The public key shares must be from a unique set of participants pub fn from_parts( public_key_shares: Vec>, - private_key_share: KeySharePrivate, + private_key_share: KeySharePrivate, rid: [u8; 32], ) -> Result { let pids = public_key_shares @@ -106,7 +106,6 @@ impl Output { public_key_shares, private_key_share, rid, - _curve: std::marker::PhantomData, }) } @@ -119,7 +118,7 @@ impl Output { /// /// The public components (including the byte array and the public key /// shares) can be stored in the clear. - pub fn into_parts(self) -> (Vec>, KeySharePrivate, [u8; 32]) { + pub fn into_parts(self) -> (Vec>, KeySharePrivate, [u8; 32]) { (self.public_key_shares, self.private_key_share, self.rid) } } diff --git a/src/keygen/participant.rs b/src/keygen/participant.rs index 852d0d68..9acde976 100644 --- a/src/keygen/participant.rs +++ b/src/keygen/participant.rs @@ -44,7 +44,7 @@ mod storage { } pub(super) struct PrivateKeyshare; impl TypeTag for PrivateKeyshare { - type Value = KeySharePrivate; + type Value = KeySharePrivate; } pub(super) struct PublicKeyshare; impl TypeTag for PublicKeyshare { diff --git a/src/keyrefresh/input.rs b/src/keyrefresh/input.rs index f299d092..f938708b 100644 --- a/src/keyrefresh/input.rs +++ b/src/keyrefresh/input.rs @@ -9,7 +9,7 @@ use std::collections::HashSet; use tracing::error; use crate::{ - auxinfo::{self, AuxInfoPrivate, AuxInfoPublic}, curve_point::{CurvePoint, CurveTrait}, errors::{CallerError, InternalError, Result}, keygen::{self, KeySharePrivate, KeySharePublic}, ParticipantConfig, ParticipantIdentifier + auxinfo::{self, AuxInfoPrivate, AuxInfoPublic}, curve_point::CurveTrait, errors::{CallerError, InternalError, Result}, keygen::{self, KeySharePrivate, KeySharePublic}, ParticipantConfig, ParticipantIdentifier }; /// Input needed for a @@ -19,14 +19,14 @@ pub struct Input { /// The key share material for the key that will be refreshed. keygen_output: keygen::Output, /// The auxiliary info to encrypt/decrypt messages with other participants. - auxinfo_output: auxinfo::Output, + auxinfo_output: auxinfo::Output, } impl Input { /// Creates a new [`Input`] from the outputs of the /// [`auxinfo`](crate::auxinfo::AuxInfoParticipant) and /// [`keygen`](crate::keygen::KeygenParticipant) protocols. - pub fn new(auxinfo_output: auxinfo::Output, keygen_output: keygen::Output) -> Result { + pub fn new(auxinfo_output: auxinfo::Output, keygen_output: keygen::Output) -> Result { // The constructors for keygen and auxinfo output already check other important // properties, like that the private component maps to one of public // components for each one. @@ -51,7 +51,7 @@ impl Input { Ok(input) } - pub fn keygen_output(&self) -> &keygen::Output { + pub fn keygen_output(&self) -> &keygen::Output { &self.keygen_output } @@ -101,7 +101,7 @@ impl Input { /// Returns the [`AuxInfoPublic`] associated with the given /// [`ParticipantIdentifier`]. - pub(crate) fn find_auxinfo_public(&self, pid: ParticipantIdentifier) -> Result<&AuxInfoPublic> { + pub(crate) fn find_auxinfo_public(&self, pid: ParticipantIdentifier) -> Result<&AuxInfoPublic> { self.auxinfo_output.find_public(pid) .ok_or_else(|| { error!("Presign input doesn't contain a public auxinfo for {}, even though we checked for it at construction.", pid); @@ -109,7 +109,7 @@ impl Input { }) } - pub(crate) fn private_key_share(&self) -> &KeySharePrivate { + pub(crate) fn private_key_share(&self) -> &KeySharePrivate { self.keygen_output.private_key_share() } } diff --git a/src/keyrefresh/keyrefresh_commit.rs b/src/keyrefresh/keyrefresh_commit.rs index a281fa32..0107c7c5 100644 --- a/src/keyrefresh/keyrefresh_commit.rs +++ b/src/keyrefresh/keyrefresh_commit.rs @@ -39,7 +39,7 @@ pub(crate) struct KeyrefreshDecommit { pub As: Vec, } -impl<'de, C: CurveTrait + Serialize + Deserialize<'de>> KeyrefreshDecommit { +impl<'de, C: CurveTrait + Serialize + Deserialize<'de> + PartialEq> KeyrefreshDecommit { ///`sid` corresponds to a unique session identifier. pub(crate) fn new( rng: &mut R, diff --git a/src/keyrefresh/keyshare.rs b/src/keyrefresh/keyshare.rs index e7d652de..a87def12 100644 --- a/src/keyrefresh/keyshare.rs +++ b/src/keyrefresh/keyshare.rs @@ -92,7 +92,7 @@ impl KeyUpdatePrivate { KeyUpdatePrivate { x: sum, _curve: std::marker::PhantomData } } - pub(crate) fn apply(self, current_sk: &KeySharePrivate) -> KeySharePrivate { + pub(crate) fn apply(self, current_sk: &KeySharePrivate) -> KeySharePrivate { let mut sum = current_sk.as_ref() + &self.x; let share = KeySharePrivate::from_bigint(&sum); sum.zeroize(); @@ -100,7 +100,7 @@ impl KeyUpdatePrivate { } /// Computes the "raw" curve point corresponding to this private key. - pub(crate) fn public_point(&self) -> Result { + pub(crate) fn public_point(&self) -> Result { C::generator().multiply_by_bignum(&self.x) } } @@ -117,7 +117,7 @@ impl AsRef for KeyUpdatePrivate { #[derive(Debug, Deserialize, PartialEq, Eq)] pub struct KeyUpdatePublic { participant: ParticipantIdentifier, - X: CurvePoint, + X: C, /// Marker to pin the generic type `C`. _curve: std::marker::PhantomData, } @@ -144,7 +144,7 @@ impl Serialize for KeyUpdatePublic { } impl KeyUpdatePublic { - pub(crate) fn new(participant: ParticipantIdentifier, share: CurvePoint) -> Self { + pub(crate) fn new(participant: ParticipantIdentifier, share: C) -> Self { Self { participant, X: share, @@ -187,9 +187,9 @@ impl KeyUpdatePublic { } } -impl AsRef for KeyUpdatePublic { +impl AsRef for KeyUpdatePublic { /// Get the public curvepoint which is the public key share. - fn as_ref(&self) -> &CurvePoint { + fn as_ref(&self) -> &C { &self.X } } diff --git a/src/presign/input.rs b/src/presign/input.rs index 9be3aa17..9e7317cf 100644 --- a/src/presign/input.rs +++ b/src/presign/input.rs @@ -19,14 +19,14 @@ pub struct Input { /// The key share material for the key that will be used in the presign run. keygen_output: keygen::Output, /// The auxiliary info for the key that will be used in the presign run. - auxinfo_output: auxinfo::Output, + auxinfo_output: auxinfo::Output, } impl Input { /// Creates a new [`Input`] from the outputs of the /// [`auxinfo`](crate::auxinfo::AuxInfoParticipant) and /// [`keygen`](crate::keygen::KeygenParticipant) protocols. - pub fn new(auxinfo_output: auxinfo::Output, keygen_output: keygen::Output) -> Result { + pub fn new(auxinfo_output: auxinfo::Output, keygen_output: keygen::Output) -> Result { if auxinfo_output.public_auxinfo().len() != keygen_output.public_key_shares().len() { error!( "Number of auxinfo ({:?}) and keyshare ({:?}) public entries is not equal", @@ -104,7 +104,7 @@ impl Input { /// Returns the [`AuxInfoPublic`] associated with the given /// [`ParticipantIdentifier`]. - pub(crate) fn find_auxinfo_public(&self, pid: ParticipantIdentifier) -> Result<&AuxInfoPublic> { + pub(crate) fn find_auxinfo_public(&self, pid: ParticipantIdentifier) -> Result<&AuxInfoPublic> { self.auxinfo_output.find_public(pid) .ok_or_else(|| { error!("Presign input doesn't contain a public auxinfo for {}, even though we checked for it at construction.", pid); @@ -112,7 +112,7 @@ impl Input { }) } - pub(crate) fn private_key_share(&self) -> &KeySharePrivate { + pub(crate) fn private_key_share(&self) -> &KeySharePrivate { self.keygen_output.private_key_share() } @@ -137,7 +137,7 @@ impl Input { pub(crate) fn all_but_one_auxinfo_public( &self, pid: ParticipantIdentifier, - ) -> Vec<&AuxInfoPublic> { + ) -> Vec<&AuxInfoPublic> { self.auxinfo_output .public_auxinfo() .iter() @@ -146,7 +146,7 @@ impl Input { } /// Returns a copy of the [`AuxInfoPublic`]s associated with all the /// participants (including this participant). - pub(crate) fn to_public_auxinfo(&self) -> Vec> { + pub(crate) fn to_public_auxinfo(&self) -> Vec { self.auxinfo_output.public_auxinfo().to_vec() } } diff --git a/src/presign/participant.rs b/src/presign/participant.rs index e64d3e83..91231bcd 100644 --- a/src/presign/participant.rs +++ b/src/presign/participant.rs @@ -67,7 +67,7 @@ mod storage { pub(crate) struct PresignContext { shared_context: SharedContext, rid: [u8; 32], - auxinfo_public: Vec>, + auxinfo_public: Vec, } impl ProofContext for PresignContext { @@ -880,10 +880,10 @@ impl PresignParticipant { /// /// TODO: Refactor as specified in #246. pub(crate) struct PresignKeyShareAndInfo { - pub(crate) keyshare_private: KeySharePrivate, + pub(crate) keyshare_private: KeySharePrivate, pub(crate) keyshare_public: KeySharePublic, pub(crate) aux_info_private: AuxInfoPrivate, - pub(crate) aux_info_public: AuxInfoPublic, + pub(crate) aux_info_public: AuxInfoPublic, } impl PresignKeyShareAndInfo { @@ -909,10 +909,10 @@ impl PresignKeyShareAndInfo { &self, rng: &mut R, context: &ParticipantPresignContext, - other_auxinfos: &[&AuxInfoPublic], + other_auxinfos: &[&AuxInfoPublic], ) -> Result<( round_one::Private, - HashMap>, + HashMap, round_one::PublicBroadcast, )> { let order = k256_order(); @@ -970,7 +970,7 @@ impl PresignKeyShareAndInfo { &self, rng: &mut R, context: &ParticipantPresignContext, - receiver_aux_info: &AuxInfoPublic, + receiver_aux_info: &AuxInfoPublic, sender_r1_priv: &round_one::Private, receiver_r1_pub_broadcast: &round_one::PublicBroadcast, ) -> Result<(round_two::Private, round_two::Public::)> { diff --git a/src/presign/record.rs b/src/presign/record.rs index 01063f55..0d34feb2 100644 --- a/src/presign/record.rs +++ b/src/presign/record.rs @@ -330,7 +330,7 @@ mod tests { let clone = PresignRecord { ..record }; let bytes = record.into_bytes(); - let reconstructed = PresignRecord::try_from_bytes(bytes); + let reconstructed = PresignRecord::::try_from_bytes(bytes); assert!(reconstructed.is_ok()); assert_eq!(reconstructed.unwrap(), clone); @@ -339,7 +339,7 @@ mod tests { #[test] fn deserialized_record_tag_must_be_correct() { let rng = &mut init_testing(); - let record = PresignRecord::simulate(rng); + let record = PresignRecord::::simulate(rng); // Cut out the tag from the serialized bytes for convenience. let share_bytes = &record.into_bytes()[RECORD_TAG.len()..]; @@ -348,48 +348,48 @@ mod tests { let wrong_tag = b"NotTheRightTag"; assert_eq!(wrong_tag.len(), RECORD_TAG.len()); let bad_bytes = [wrong_tag.as_slice(), share_bytes].concat(); - assert!(PresignRecord::try_from_bytes(bad_bytes).is_err()); + assert!(PresignRecord::::try_from_bytes(bad_bytes).is_err()); // Tag must be correct length (too short, too long) let short_tag = &RECORD_TAG[..5]; let bad_bytes = [short_tag, share_bytes].concat(); - assert!(PresignRecord::try_from_bytes(bad_bytes).is_err()); + assert!(PresignRecord::::try_from_bytes(bad_bytes).is_err()); let bad_bytes = [RECORD_TAG, b"TAG EXTENSION!", share_bytes].concat(); - assert!(PresignRecord::try_from_bytes(bad_bytes).is_err()); + assert!(PresignRecord::::try_from_bytes(bad_bytes).is_err()); // Normal serialization works let bytes = [RECORD_TAG, share_bytes].concat(); - assert!(PresignRecord::try_from_bytes(bytes).is_ok()); + assert!(PresignRecord::::try_from_bytes(bytes).is_ok()); } fn test_length_field(front: &[u8], len: usize, back: &[u8]) { // Length must be specified let bad_bytes = [front, back].concat(); - assert!(PresignRecord::try_from_bytes(bad_bytes).is_err()); + assert!(PresignRecord::::try_from_bytes(bad_bytes).is_err()); // Length must be little endian let bad_bytes = [front, &len.to_be_bytes(), back].concat(); - assert!(PresignRecord::try_from_bytes(bad_bytes).is_err()); + assert!(PresignRecord::::try_from_bytes(bad_bytes).is_err()); // Length must be correct (too long, too short) let too_short = (len - 5).to_le_bytes(); let bad_bytes = [front, &too_short, back].concat(); - assert!(PresignRecord::try_from_bytes(bad_bytes).is_err()); + assert!(PresignRecord::::try_from_bytes(bad_bytes).is_err()); let too_long = (len + 5).to_le_bytes(); let bad_bytes = [front, &too_long, back].concat(); - assert!(PresignRecord::try_from_bytes(bad_bytes).is_err()); + assert!(PresignRecord::::try_from_bytes(bad_bytes).is_err()); // Correct length works let bytes = [front, &len.to_le_bytes(), back].concat(); - assert!(PresignRecord::try_from_bytes(bytes).is_ok()); + assert!(PresignRecord::::try_from_bytes(bytes).is_ok()); } #[test] fn point_field_must_have_length_prepended() { let rng = &mut init_testing(); - let PresignRecord { R, k, chi } = PresignRecord::simulate(rng); + let PresignRecord { R, k, chi }: record::PresignRecord = PresignRecord::simulate(rng); let point = R.to_bytes(); @@ -414,7 +414,7 @@ mod tests { #[test] fn k_field_must_have_length_prepended() { let rng = &mut init_testing(); - let PresignRecord { R, k, chi } = PresignRecord::simulate(rng); + let PresignRecord { R, k, chi }: record::PresignRecord = PresignRecord::simulate(rng); let point = R.to_bytes(); let point_len = point.len().to_le_bytes(); @@ -433,7 +433,7 @@ mod tests { #[test] fn chi_field_must_have_length_prepended() { let rng = &mut init_testing(); - let PresignRecord { R, k, chi } = PresignRecord::simulate(rng); + let PresignRecord { R, k, chi }: record::PresignRecord = PresignRecord::simulate(rng); let point = R.to_bytes(); let point_len = point.len().to_le_bytes(); @@ -464,7 +464,7 @@ mod tests { assert!(PresignRecord::try_from_bytes(bytes.to_vec()).is_err()); assert!(PresignRecord::try_from_bytes(RECORD_TAG.to_vec()).is_err()); - let PresignRecord { R, k, chi } = PresignRecord::simulate(rng); + let PresignRecord { R, k, chi }: record::PresignRecord = PresignRecord::simulate(rng); let point = R.to_bytes(); let point_len = point.len().to_le_bytes(); diff --git a/src/presign/round_one.rs b/src/presign/round_one.rs index 4bc6a67b..be1bf333 100644 --- a/src/presign/round_one.rs +++ b/src/presign/round_one.rs @@ -8,7 +8,7 @@ use super::participant::ParticipantPresignContext; use crate::{ - curve_point::CurveTrait, errors::{InternalError, Result}, messages::{Message, MessageType, PresignMessageType}, paillier::{Ciphertext, EncryptionKey, Nonce}, ring_pedersen::VerifiedRingPedersen, zkp::{ + curve_point::CurvePoint, errors::{InternalError, Result}, messages::{Message, MessageType, PresignMessageType}, paillier::{Ciphertext, EncryptionKey, Nonce}, ring_pedersen::VerifiedRingPedersen, zkp::{ pienc::{PiEncInput, PiEncProof}, Proof, } @@ -52,12 +52,12 @@ impl Debug for Private { /// necessarily valid (i.e., that all the components are valid with respect to /// each other); use [`Public::verify`] to check this latter condition. #[derive(Debug, Serialize, Deserialize)] -pub(crate) struct Public { - proof: PiEncProof, +pub(crate) struct Public { + proof: PiEncProof, } -impl From> for Public { - fn from(proof: PiEncProof) -> Self { +impl From for Public { + fn from(proof: PiEncProof) -> Self { Self { proof } } } @@ -69,7 +69,7 @@ pub(crate) struct PublicBroadcast { pub G: Ciphertext, } -impl Public { +impl Public { /// Verify the validity of [`Public`] against the prover's [`EncryptionKey`] /// and [`PublicBroadcast`] values. /// @@ -77,8 +77,8 @@ impl Public { /// (i.e., the verifier). pub(crate) fn verify( self, - context: &ParticipantPresignContext, - verifier_setup_params: &VerifiedRingPedersen, + context: &ParticipantPresignContext, + verifier_setup_params: &VerifiedRingPedersen, prover_pk: &EncryptionKey, prover_public_broadcast: &PublicBroadcast, ) -> Result<()> { @@ -88,7 +88,7 @@ impl Public { } } -impl TryFrom<&Message> for Public { +impl TryFrom<&Message> for Public { type Error = InternalError; fn try_from(message: &Message) -> std::result::Result { diff --git a/src/presign/round_three.rs b/src/presign/round_three.rs index dad6fabb..ed1eca8e 100644 --- a/src/presign/round_three.rs +++ b/src/presign/round_three.rs @@ -72,8 +72,8 @@ impl Public { pub(crate) fn verify( self, context: &ParticipantPresignContext, - verifier_auxinfo_public: &AuxInfoPublic, - prover_auxinfo_public: &AuxInfoPublic, + verifier_auxinfo_public: &AuxInfoPublic, + prover_auxinfo_public: &AuxInfoPublic, prover_r1_public_broadcast: &RoundOnePublicBroadcast, ) -> Result<()> { let mut transcript = Transcript::new(b"PiLogProof"); @@ -111,7 +111,7 @@ impl TryFrom<&Message> for Public { /// Used to bundle the inputs passed to round_three() together pub(crate) struct Input { - pub auxinfo_public: AuxInfoPublic, + pub auxinfo_public: AuxInfoPublic, pub r2_private: RoundTwoPrivate, pub r2_public: RoundTwoPublic, } diff --git a/src/presign/round_two.rs b/src/presign/round_two.rs index 91cbbc1b..8a761ec3 100644 --- a/src/presign/round_two.rs +++ b/src/presign/round_two.rs @@ -62,9 +62,9 @@ impl Public { pub(crate) fn verify( self, context: &ParticipantPresignContext, - verifier_auxinfo_public: &AuxInfoPublic, + verifier_auxinfo_public: &AuxInfoPublic, verifier_r1_private: &RoundOnePrivate, - prover_auxinfo_public: &AuxInfoPublic, + prover_auxinfo_public: &AuxInfoPublic, prover_keyshare_public: &KeySharePublic, prover_r1_public_broadcast: &RoundOnePublicBroadcast, ) -> Result<()> { diff --git a/src/protocol.rs b/src/protocol.rs index 672f2bcb..04d90d65 100644 --- a/src/protocol.rs +++ b/src/protocol.rs @@ -929,12 +929,12 @@ mod tests { .into_iter() .zip(presign_inputs) .map(|(config, input)| { - Participant::::from_config(config, presign_sid, input).unwrap() + Participant::>::from_config(config, presign_sid, input).unwrap() }) .collect::>(); let mut presign_outputs: HashMap< ParticipantIdentifier, - ::Output, + as ProtocolParticipant>::Output, > = HashMap::new(); for participant in &mut presign_quorum { @@ -1143,7 +1143,7 @@ mod tests { let sign_sid = Identifier::random(rng); let mut sign_quorum = std::iter::zip(configs, sign_inputs) .map(|(config, input)| { - Participant::::from_config(config, sign_sid, input) + Participant::>::from_config(config, sign_sid, input) }) .collect::>>()?; diff --git a/src/ring_pedersen.rs b/src/ring_pedersen.rs index c3cb67ee..f93c8941 100644 --- a/src/ring_pedersen.rs +++ b/src/ring_pedersen.rs @@ -12,7 +12,7 @@ //! that the commitment scheme parameters were constructed correctly. use crate::{ - curve_point::CurveTrait, errors::Result, paillier::DecryptionKey, utils::{modpow, random_plusminus_scaled, random_positive_bn}, zkp::{ + errors::Result, paillier::DecryptionKey, utils::{modpow, random_plusminus_scaled, random_positive_bn}, zkp::{ piprm::{PiPrmProof, PiPrmSecret}, Proof, ProofContext, } @@ -41,20 +41,21 @@ pub(crate) struct RingPedersen { /// A [`RingPedersen`] commitment scheme alongside a zero knowledge proof that /// the commitment scheme was constructed correctly. #[derive(Clone, Debug, Serialize, Deserialize)] -pub(crate) struct VerifiedRingPedersen { +pub(crate) struct VerifiedRingPedersen { /// The underlying commitment scheme. scheme: RingPedersen, /// The zero knowledge proof that validates the correctness of /// [`VerifiedRingPedersen::scheme`]. - proof: PiPrmProof, + proof: PiPrmProof, } -impl PartialEq for VerifiedRingPedersen { +impl PartialEq for VerifiedRingPedersen { fn eq(&self, other: &Self) -> bool { self.scheme == other.scheme } } -impl Eq for VerifiedRingPedersen {} + +impl Eq for VerifiedRingPedersen {} /// A commitment produced by [`RingPedersen::commit`]. #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] @@ -139,7 +140,7 @@ impl MaskedRandomness { } } -impl VerifiedRingPedersen { +impl VerifiedRingPedersen { /// Extracts a [`VerifiedRingPedersen`] object from a [`DecryptionKey`]. /// /// In more detail, `sk` is used to derive a diff --git a/src/sign/interactive_sign/participant.rs b/src/sign/interactive_sign/participant.rs index 4014dadd..f73d1caf 100644 --- a/src/sign/interactive_sign/participant.rs +++ b/src/sign/interactive_sign/participant.rs @@ -153,7 +153,7 @@ impl Input { pub fn new( message: &[u8], keygen_output: keygen::Output, - auxinfo_output: auxinfo::Output, + auxinfo_output: auxinfo::Output, ) -> Result { let presign_input = presign::Input::new(auxinfo_output, keygen_output)?; let message_digest = Keccak256::new_with_prefix(message); @@ -169,7 +169,7 @@ impl ProtocolParticipant for InteractiveSignParticipant { type Output = Signature; fn ready_type() -> MessageType { - PresignParticipant::ready_type() + PresignParticipant::::ready_type() } fn protocol_type() -> ProtocolType { @@ -337,7 +337,7 @@ mod tests { use tracing::debug; use crate::{ - auxinfo, curve_point::{testing::init_testing, CurvePoint}, errors::Result, keygen, messages::{Message, MessageType}, participant::ProcessOutcome, sign::Signature, Identifier, ParticipantConfig, ParticipantIdentifier, ProtocolParticipant + auxinfo, curve_point::{testing::init_testing, CurvePoint}, errors::Result, keygen::{self, Output}, messages::{Message, MessageType}, participant::ProcessOutcome, sign::Signature, Identifier, ParticipantConfig, ParticipantIdentifier, ProtocolParticipant }; use super::{Input, InteractiveSignParticipant, Status}; @@ -348,7 +348,7 @@ mod tests { let pids = std::iter::repeat_with(|| ParticipantIdentifier::random(rng)) .take(5) .collect::>(); - let keygen_output = keygen::Output::simulate(&pids, rng); + let keygen_output: Output = keygen::Output::simulate(&pids, rng); let auxinfo_output = auxinfo::Output::simulate(&pids, rng); let message = b"greetings from the new world"; assert!(Input::new(message, keygen_output, auxinfo_output).is_ok()) diff --git a/src/zkp/mod.rs b/src/zkp/mod.rs index 38fabc39..4535cd87 100644 --- a/src/zkp/mod.rs +++ b/src/zkp/mod.rs @@ -21,7 +21,7 @@ pub(crate) mod pimod; pub(crate) mod piprm; pub(crate) mod pisch; -use crate::{curve_point::CurveTrait, errors::Result}; +use crate::errors::Result; use merlin::Transcript; use rand::{CryptoRng, RngCore}; use serde::{de::DeserializeOwned, Serialize}; @@ -54,7 +54,7 @@ impl ProofContext for BadContext { /// The associated type [`Proof::CommonInput`] denotes the data known to both /// the prover and verifier, and the associated type [`Proof::ProverSecret`] /// denotes the data known only to the prover. -pub(crate) trait Proof: Sized + Serialize + DeserializeOwned { +pub(crate) trait Proof: Sized + Serialize + DeserializeOwned { type CommonInput<'a>; type ProverSecret<'a>; diff --git a/src/zkp/piaffg.rs b/src/zkp/piaffg.rs index e3cadbf0..b15e5ef8 100644 --- a/src/zkp/piaffg.rs +++ b/src/zkp/piaffg.rs @@ -108,7 +108,7 @@ pub(crate) struct PiAffgProof { #[derive(Serialize, Clone, Copy)] pub(crate) struct PiAffgInput<'a, C: CurveTrait> { /// The verifier's commitment parameters (`(Nhat, s, t)` in the paper). - verifier_setup_params: &'a VerifiedRingPedersen, + verifier_setup_params: &'a VerifiedRingPedersen, /// The verifier's Paillier encryption key (`N_0` in the paper). verifier_encryption_key: &'a EncryptionKey, /// The prover's Paillier encryption key (`N_1` in the paper). @@ -130,7 +130,7 @@ pub(crate) struct PiAffgInput<'a, C: CurveTrait> { impl<'a, C: CurveTrait> PiAffgInput<'a, C> { /// Construct a new [`PiAffgInput`] type. pub(crate) fn new( - verifier_setup_params: &'a VerifiedRingPedersen, + verifier_setup_params: &'a VerifiedRingPedersen, verifier_encryption_key: &'a EncryptionKey, prover_encryption_key: &'a EncryptionKey, original_ciphertext_verifier: &'a Ciphertext, @@ -192,8 +192,8 @@ impl<'a> PiAffgSecret<'a> { } } -impl Proof for PiAffgProof { - type CommonInput<'a> = PiAffgInput<'a, C>; +impl Proof for PiAffgProof { + type CommonInput<'a> = PiAffgInput<'a, C> where C: 'a; type ProverSecret<'b> = PiAffgSecret<'b>; #[cfg_attr(feature = "flame_it", flame("PiAffgProof"))] @@ -652,7 +652,7 @@ mod tests { let y = random_plusminus_by_size(&mut rng, ELL_PRIME); let rng2 = &mut StdRng::from_seed(rng.gen()); - let f = |proof: PiAffgProof, input: PiAffgInput| { + let f = |proof: PiAffgProof::, input: PiAffgInput::| { // Swap verifier setup parameters with a random [`VerifiedRingPedersen`] let bad_setup_params = VerifiedRingPedersen::gen(&mut rng, &())?; assert_ne!(bad_setup_params, input.verifier_setup_params.clone()); @@ -875,7 +875,7 @@ mod tests { let y = random_plusminus_by_size(&mut rng, ELL_PRIME); let rng2 = &mut StdRng::from_seed(rng.gen()); - let f = |proof: PiAffgProof, input: PiAffgInput| { + let f = |proof: PiAffgProof::, input: PiAffgInput::| { let setup_params = VerifiedRingPedersen::gen(&mut rng, &())?; // Generate some random elements to use as replacements diff --git a/src/zkp/pienc.rs b/src/zkp/pienc.rs index 35547560..3c680f20 100644 --- a/src/zkp/pienc.rs +++ b/src/zkp/pienc.rs @@ -26,7 +26,7 @@ //! UC Non-Interactive, Proactive, Threshold ECDSA with Identifiable Aborts. //! [EPrint archive, 2021](https://eprint.iacr.org/2021/060.pdf). use crate::{ - curve_point::{CurveTrait}, errors::*, paillier::{Ciphertext, EncryptionKey, MaskedNonce, Nonce}, parameters::{ELL, EPSILON}, ring_pedersen::{Commitment, MaskedRandomness, VerifiedRingPedersen}, utils::{plusminus_challenge_from_transcript, random_plusminus_by_size}, zkp::{Proof, ProofContext} + errors::*, paillier::{Ciphertext, EncryptionKey, MaskedNonce, Nonce}, parameters::{ELL, EPSILON}, ring_pedersen::{Commitment, MaskedRandomness, VerifiedRingPedersen}, utils::{plusminus_challenge_from_transcript, random_plusminus_by_size}, zkp::{Proof, ProofContext} }; use libpaillier::unknown_order::BigNumber; use merlin::Transcript; @@ -38,7 +38,7 @@ use tracing::error; /// Proof of knowledge of the plaintext value of a ciphertext, where the value /// is within a desired range. #[derive(Debug, Clone, Serialize, Deserialize)] -pub(crate) struct PiEncProof { +pub(crate) struct PiEncProof { /// Commitment to the plaintext value of the ciphertext (`S` in the paper). plaintext_commit: Commitment, /// Masking ciphertext (`A` in the paper). @@ -57,8 +57,6 @@ pub(crate) struct PiEncProof { /// Response binding the commitment randomness used in the two commitments /// (`z3` in the paper). randomness_response: MaskedRandomness, - /// Marker to pin the curve type `C`. - _marker: std::marker::PhantomData, } /// Common input and setup parameters known to both the prover and verifier. @@ -66,23 +64,23 @@ pub(crate) struct PiEncProof { /// Copying/Cloning references is harmless and sometimes necessary. So we /// implement Clone and Copy for this type. #[derive(Serialize, Copy, Clone)] -pub(crate) struct PiEncInput<'a, C: CurveTrait> { +pub(crate) struct PiEncInput<'a> { /// The verifier's commitment parameters (`(N^hat, s, t)` in the paper). - setup_params: &'a VerifiedRingPedersen, + setup_params: &'a VerifiedRingPedersen, /// The prover's encryption key (`N_0` in the paper). encryption_key: &'a EncryptionKey, /// Ciphertext about which we are proving properties (`K` in the paper). ciphertext: &'a Ciphertext, } -impl<'a, C: CurveTrait> PiEncInput<'a, C> { +impl<'a> PiEncInput<'a> { /// Generate public input for proving or verifying a [`PiEncProof`] about /// `ciphertext`. pub(crate) fn new( - verifer_setup_params: &'a VerifiedRingPedersen, + verifer_setup_params: &'a VerifiedRingPedersen, prover_encryption_key: &'a EncryptionKey, ciphertext: &'a Ciphertext, - ) -> PiEncInput<'a, C> { + ) -> PiEncInput<'a> { Self { setup_params: verifer_setup_params, encryption_key: prover_encryption_key, @@ -121,8 +119,8 @@ impl<'a> PiEncSecret<'a> { } } -impl Proof for PiEncProof { - type CommonInput<'a> = PiEncInput<'a, C>; +impl Proof for PiEncProof { + type CommonInput<'a> = PiEncInput<'a>; type ProverSecret<'b> = PiEncSecret<'b>; #[cfg_attr(feature = "flame_it", flame("PiEncProof"))] fn prove( @@ -260,13 +258,13 @@ impl Proof for PiEncProof { } } -impl PiEncProof { +impl PiEncProof { /// Update the [`Transcript`] with all the commitment values used in the /// proof. fn fill_transcript( transcript: &mut Transcript, context: &impl ProofContext, - input: &PiEncInput, + input: &PiEncInput, plaintext_commit: &Commitment, ciphertext_mask: &Ciphertext, plaintext_mask_commit: &Commitment, @@ -290,7 +288,7 @@ impl PiEncProof { mod tests { use super::*; use crate::{ - curve_point::{k256_order, testing::init_testing, CurvePoint}, paillier::DecryptionKey, utils::{random_plusminus, random_plusminus_by_size_with_minimum, random_positive_bn}, zkp::BadContext + curve_point::{k256_order, testing::init_testing}, paillier::DecryptionKey, utils::{random_plusminus, random_plusminus_by_size_with_minimum, random_positive_bn}, zkp::BadContext }; use rand::{rngs::StdRng, Rng, SeedableRng}; @@ -300,14 +298,14 @@ mod tests { // Shorthand to avoid putting types for closure arguments. // Note: This does not work on closures that capture variables. - type ProofTest = fn(PiEncProof, PiEncInput) -> Result<()>; + type ProofTest = fn(PiEncProof, PiEncInput) -> Result<()>; /// Generate a [`PiEncProof`] and [`PiEncInput`] and pass them to the /// `test_code` closure. fn with_random_proof( rng: &mut R, plaintext: BigNumber, - mut test_code: impl FnMut(PiEncProof, PiEncInput) -> Result<()>, + mut test_code: impl FnMut(PiEncProof, PiEncInput) -> Result<()>, ) -> Result<()> { let (decryption_key, _, _) = DecryptionKey::new(rng).unwrap(); let encryption_key = decryption_key.encryption_key(); diff --git a/src/zkp/pifac.rs b/src/zkp/pifac.rs index c56cc124..86f27b8f 100644 --- a/src/zkp/pifac.rs +++ b/src/zkp/pifac.rs @@ -18,7 +18,7 @@ //! [EPrint archive, 2021](https://eprint.iacr.org/2021/060.pdf). use crate::{ - curve_point::CurveTrait, errors::*, parameters::{ELL, EPSILON}, ring_pedersen::{Commitment, CommitmentRandomness, MaskedRandomness, VerifiedRingPedersen}, utils::{plusminus_challenge_from_transcript, random_plusminus_scaled}, zkp::{Proof, ProofContext} + errors::*, parameters::{ELL, EPSILON}, ring_pedersen::{Commitment, CommitmentRandomness, MaskedRandomness, VerifiedRingPedersen}, utils::{plusminus_challenge_from_transcript, random_plusminus_scaled}, zkp::{Proof, ProofContext} }; use libpaillier::unknown_order::BigNumber; use merlin::Transcript; @@ -31,7 +31,7 @@ use tracing::error; /// Proof that the modulus `N` can be factored into two numbers greater than /// `2^ℓ` for a parameter `ℓ`. #[derive(Debug, Serialize, Deserialize, Clone)] -pub(crate) struct PiFacProof { +pub(crate) struct PiFacProof { /// Commitment to the factor `p` (`P` in the paper). p_commitment: Commitment, /// Commitment to the factor `q` (`Q` in the paper). @@ -58,8 +58,6 @@ pub(crate) struct PiFacProof { /// Masked commitment randomness linking `p` to the commitment randomness /// used in `q_commitment` (`v` in the paper). masked_p_link: MaskedRandomness, - /// Marker to pin the curve type. - curve_type: std::marker::PhantomData, } /// Common input and setup parameters known to both the prover and verifier. @@ -67,16 +65,16 @@ pub(crate) struct PiFacProof { /// Copying/Cloning references is harmless and sometimes necessary. So we /// implement Clone and Copy for this type. #[derive(Serialize, Copy, Clone)] -pub(crate) struct CommonInput<'a, C: CurveTrait> { - setup_params: &'a VerifiedRingPedersen, +pub(crate) struct CommonInput<'a> { + setup_params: &'a VerifiedRingPedersen, modulus: &'a BigNumber, } -impl<'a, C: CurveTrait> CommonInput<'a, C> { +impl<'a> CommonInput<'a> { /// Generate public input for proving and verifying [`PiFacProof`] about /// `N`. pub(crate) fn new( - verifier_commitment_params: &'a VerifiedRingPedersen, + verifier_commitment_params: &'a VerifiedRingPedersen, prover_modulus: &'a BigNumber, ) -> Self { Self { @@ -112,8 +110,8 @@ impl<'a> ProverSecret<'a> { } } -impl Proof for PiFacProof { - type CommonInput<'a> = CommonInput<'a, C>; +impl Proof for PiFacProof { + type CommonInput<'a> = CommonInput<'a>; type ProverSecret<'a> = ProverSecret<'a>; #[cfg_attr(feature = "flame_it", flame("PiFacProof"))] @@ -288,12 +286,12 @@ impl Proof for PiFacProof { } } -impl PiFacProof { +impl PiFacProof { #[allow(clippy::too_many_arguments)] fn fill_transcript( transcript: &mut Transcript, context: &impl ProofContext, - input: &CommonInput, + input: &CommonInput, P: &Commitment, Q: &Commitment, A: &Commitment, @@ -330,7 +328,7 @@ fn sqrt(num: &BigNumber) -> BigNumber { #[cfg(test)] mod tests { use crate::{ - curve_point::{k256_order, testing::init_testing, CurvePoint}, paillier::prime_gen, utils::random_positive_bn, zkp::BadContext + curve_point::{k256_order, testing::init_testing}, paillier::prime_gen, utils::random_positive_bn, zkp::BadContext }; use rand::{prelude::StdRng, Rng, SeedableRng}; @@ -342,7 +340,7 @@ mod tests { fn with_random_no_small_factors_proof( rng: &mut R, - mut test_code: impl FnMut(CommonInput::, PiFacProof::) -> Result<()>, + mut test_code: impl FnMut(CommonInput, PiFacProof) -> Result<()>, ) -> Result<()> { let (p0, q0) = prime_gen::get_prime_pair_from_pool_insecure(rng).unwrap(); let N0 = &p0 * &q0; diff --git a/src/zkp/pilog.rs b/src/zkp/pilog.rs index 3523bddf..14d157b8 100644 --- a/src/zkp/pilog.rs +++ b/src/zkp/pilog.rs @@ -158,8 +158,8 @@ fn generate_challenge( Ok(challenge) } -impl Proof for PiLogProof { - type CommonInput<'a> = CommonInput<'a, CurvePoint>; +impl Proof for PiLogProof { + type CommonInput<'a> = CommonInput<'a, C> where C: 'a; type ProverSecret<'a> = ProverSecret<'a>; #[cfg_attr(feature = "flame_it", flame("PiLogProof"))] fn prove<'a, R: RngCore + CryptoRng>( @@ -355,10 +355,10 @@ mod tests { Transcript::new(b"PiLogProof Test") } - fn with_random_paillier_log_proof( + fn with_random_paillier_log_proof( rng: &mut R, x: &BigNumber, - mut f: impl FnMut(PiLogProof, CommonInput) -> Result<()>, + mut f: impl FnMut(PiLogProof, CommonInput) -> Result<()>, ) -> Result<()> { let (decryption_key, _, _) = DecryptionKey::new(rng).unwrap(); let pk = decryption_key.encryption_key(); @@ -382,11 +382,11 @@ mod tests { f(proof, input) } - fn random_paillier_log_proof_verification( + fn random_paillier_log_proof_verification( rng: &mut R, x: &BigNumber, ) -> Result<()> { - let f = |proof: PiLogProof, input: CommonInput| { + let f = |proof: PiLogProof, input: CommonInput| { proof.verify(input, &(), &mut transcript())?; Ok(()) }; @@ -398,7 +398,7 @@ mod tests { pilog_proof_with_consistent_secret_inputs_out_of_range::().unwrap(); } - fn pilog_proof_with_consistent_secret_inputs_out_of_range() -> Result<()> { + fn pilog_proof_with_consistent_secret_inputs_out_of_range() -> Result<()> { let mut rng = init_testing(); let upper_bound = BigNumber::one() << (ELL + EPSILON); loop { @@ -411,7 +411,7 @@ mod tests { // If the input value is larger than the top of the range, the proof won't // verify if too_large > upper_bound { - let f = |bad_proof: PiLogProof, input: CommonInput| { + let f = |bad_proof: PiLogProof, input: CommonInput| { assert!(bad_proof.verify(input, &(), &mut transcript()).is_err()); Ok(()) }; @@ -431,7 +431,7 @@ mod tests { let _ = pilog_proof_with_different_setup_parameters::(); } - fn pilog_proof_with_different_setup_parameters() -> Result<()> { + fn pilog_proof_with_different_setup_parameters() -> Result<()> { let mut rng = init_testing(); let x = random_plusminus_by_size(&mut rng, ELL); let (decryption_key, _, _) = DecryptionKey::new(&mut rng).unwrap(); @@ -548,7 +548,7 @@ mod tests { let _ = pilog_proof_with_inconsistent_secret_inputs::(); } - fn pilog_proof_with_inconsistent_secret_inputs() -> Result<()> + fn pilog_proof_with_inconsistent_secret_inputs() -> Result<()> { let mut rng = init_testing(); @@ -598,13 +598,13 @@ mod tests { negative_test_swap_proof_elements::().unwrap(); } - fn negative_test_swap_proof_elements() -> Result<()> { + fn negative_test_swap_proof_elements() -> Result<()> { let mut rng = init_testing(); // `rng` will be borrowed. We make another rng to be captured by the closure. let mut rng2 = StdRng::from_seed(rng.gen()); let x = random_plusminus_by_size(&mut rng2, ELL); - let f = |proof: PiLogProof, input: CommonInput| { + let f = |proof: PiLogProof, input: CommonInput| { let setup_params = VerifiedRingPedersen::gen(&mut rng, &())?; // Generate some random elements to use as replacements @@ -681,12 +681,12 @@ mod tests { pilog_proof_context_must_be_correct::().unwrap(); } - fn pilog_proof_context_must_be_correct() -> Result<()> { + fn pilog_proof_context_must_be_correct() -> Result<()> { let mut rng = init_testing(); let context = BadContext {}; let x_small = random_plusminus_by_size(&mut rng, ELL); - let f = |proof: PiLogProof, input: CommonInput| { + let f = |proof: PiLogProof, input: CommonInput| { let result = proof.verify(input, &context, &mut transcript()); assert!(result.is_err()); Ok(()) diff --git a/src/zkp/pimod.rs b/src/zkp/pimod.rs index 3a9027b5..a6a6d58c 100644 --- a/src/zkp/pimod.rs +++ b/src/zkp/pimod.rs @@ -33,7 +33,7 @@ //! December 8-12, 2019, Proceedings, Part III, pages 700–727, 2019. use crate::{ - curve_point::CurveTrait, errors::*, utils::*, zkp::{Proof, ProofContext} + errors::*, utils::*, zkp::{Proof, ProofContext} }; use libpaillier::unknown_order::BigNumber; use merlin::Transcript; @@ -46,12 +46,10 @@ use tracing::error; static LAMBDA: usize = crate::parameters::SOUNDNESS_PARAMETER; #[derive(Debug, Clone, Serialize, Deserialize)] -pub(crate) struct PiModProof { +pub(crate) struct PiModProof { random_jacobi_one: BigNumber, // (x, a, b, z), elements: Vec, - /// Marker to pin the curve type - curve: std::marker::PhantomData, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -105,7 +103,7 @@ impl<'a> ProverSecret<'a> { } } -impl Proof for PiModProof { +impl Proof for PiModProof { type CommonInput<'a> = CommonInput<'a>; type ProverSecret<'a> = ProverSecret<'a>; /// Generated by the prover, requires public input N and secrets (p,q) @@ -245,7 +243,7 @@ impl Proof for PiModProof { } } -impl PiModProof { +impl PiModProof { fn fill_transcript( transcript: &mut Transcript, context: &impl ProofContext, @@ -477,7 +475,7 @@ fn y_prime_combinations( #[cfg(test)] mod tests { use rand::{rngs::StdRng, Rng}; - use crate::curve_point::{k256_order, CurvePoint}; + use crate::curve_point::k256_order; use super::*; use crate::{ @@ -785,11 +783,11 @@ mod tests { assert_eq!(buf, bincode::serialize(&roundtrip_pbmp).unwrap()); } - type TestFn = fn(PiModProof::, CommonInput, &mut StdRng) -> Result<()>; + type TestFn = fn(PiModProof, CommonInput, &mut StdRng) -> Result<()>; fn with_random_pimod_proof( rng: &mut StdRng, - mut test_code: impl FnMut(PiModProof::, CommonInput, &mut StdRng) -> Result<()>, + mut test_code: impl FnMut(PiModProof, CommonInput, &mut StdRng) -> Result<()>, ) -> Result<()> { let (decryption_key, p, q) = DecryptionKey::new(rng).unwrap(); @@ -798,7 +796,7 @@ mod tests { }; let secret = ProverSecret { p: &p, q: &q }; - let proof_result = PiModProof::::prove(input, secret, &(), &mut transcript(), rng); + let proof_result = PiModProof::prove(input, secret, &(), &mut transcript(), rng); assert!(proof_result.is_ok()); test_code(proof_result.unwrap(), input, rng) diff --git a/src/zkp/piprm.rs b/src/zkp/piprm.rs index 75f73187..5099ea63 100644 --- a/src/zkp/piprm.rs +++ b/src/zkp/piprm.rs @@ -23,7 +23,7 @@ //! [EPrint archive, 2021](https://eprint.iacr.org/2021/060.pdf). use crate::{ - curve_point::CurveTrait, errors::*, ring_pedersen::RingPedersen, utils::*, zkp::{Proof, ProofContext} + errors::*, ring_pedersen::RingPedersen, utils::*, zkp::{Proof, ProofContext} }; use libpaillier::unknown_order::BigNumber; use merlin::Transcript; @@ -38,15 +38,13 @@ const SOUNDNESS: usize = crate::parameters::SOUNDNESS_PARAMETER; /// Proof that externally provided [`RingPedersen`] parameters are constructed /// correctly. #[derive(Debug, Clone, Serialize, Deserialize)] -pub(crate) struct PiPrmProof { +pub(crate) struct PiPrmProof { /// The commitments computed by the prover (`A_i` in the paper). commitments: Vec, /// The randomized challenge bytes (`e_i` in the paper). challenge_bytes: Vec, /// The prover responses (`z_i` in the paper). responses: Vec, - /// Marker to pin the curve type. - curve: std::marker::PhantomData, } /// The prover's secret knowledge. @@ -95,7 +93,7 @@ fn generate_challenge_bytes( Ok(challenges.into()) } -impl Proof for PiPrmProof { +impl Proof for PiPrmProof { type CommonInput<'a> = &'a RingPedersen; type ProverSecret<'a> = PiPrmSecret<'a>; #[cfg_attr(feature = "flame_it", flame("PiPrmProof"))] @@ -187,7 +185,7 @@ impl Proof for PiPrmProof { #[cfg(test)] mod tests { use super::*; - use crate::{curve_point::{testing::init_testing, CurvePoint}, paillier::DecryptionKey, zkp::BadContext}; + use crate::{curve_point::testing::init_testing, paillier::DecryptionKey, zkp::BadContext}; use rand::Rng; /// Make a transcript for PiPrmProof. @@ -197,7 +195,7 @@ mod tests { fn random_ring_pedersen_proof( rng: &mut R, - ) -> Result<(RingPedersen, PiPrmProof::, BigNumber, BigNumber)> { + ) -> Result<(RingPedersen, PiPrmProof, BigNumber, BigNumber)> { let (sk, _, _) = DecryptionKey::new(rng).unwrap(); let (scheme, lambda, totient) = RingPedersen::extract(&sk, rng)?; let secrets = PiPrmSecret::new(&lambda, &totient); diff --git a/src/zkp/pisch.rs b/src/zkp/pisch.rs index 76a01e8f..04354a14 100644 --- a/src/zkp/pisch.rs +++ b/src/zkp/pisch.rs @@ -110,7 +110,7 @@ impl<'a> ProverSecret<'a> { } } -impl Proof for PiSchProof +impl Proof for PiSchProof { type CommonInput<'a> = CommonInput<'a>; type ProverSecret<'a> = ProverSecret<'a>; @@ -211,7 +211,7 @@ impl PiSchProof { input: CommonInput, context: &impl ProofContext, transcript: &mut Transcript, - commitment: &CurvePoint, + commitment: &C, ) -> Result<()> { if commitment != &self.commitment { error!("the proof does not match the previous commitment"); From e58422d19a9f57447930e7aecd1ef55c87a05745 Mon Sep 17 00:00:00 2001 From: emmorais Date: Mon, 5 Aug 2024 09:14:47 -0300 Subject: [PATCH 19/36] Fixing more errors --- src/keygen/keyshare.rs | 2 +- src/keyrefresh/input.rs | 11 +++-------- src/presign/input.rs | 13 ++++--------- src/presign/record.rs | 4 ++-- src/presign/round_two.rs | 3 +-- src/zkp/pilog.rs | 6 +++--- src/zkp/pisch.rs | 2 +- 7 files changed, 15 insertions(+), 26 deletions(-) diff --git a/src/keygen/keyshare.rs b/src/keygen/keyshare.rs index 09096abd..37a22ee9 100644 --- a/src/keygen/keyshare.rs +++ b/src/keygen/keyshare.rs @@ -191,7 +191,7 @@ mod tests { #[test] fn keyshare_private_bytes_conversion_works() { let rng = &mut init_testing(); - let share: KeySharePrivate = KeySharePrivate::random(rng); + let share: KeySharePrivate = KeySharePrivate::random(rng); let bytes = share.clone().into_bytes(); let reconstructed = KeySharePrivate::try_from_bytes(bytes); diff --git a/src/keyrefresh/input.rs b/src/keyrefresh/input.rs index f938708b..6322dd01 100644 --- a/src/keyrefresh/input.rs +++ b/src/keyrefresh/input.rs @@ -118,12 +118,7 @@ impl Input { mod test { use super::Input; use crate::{ - auxinfo, - errors::{CallerError, InternalError, Result}, - keygen, - keyrefresh::KeyrefreshParticipant, - curve_point::testing::init_testing, - Identifier, ParticipantConfig, ParticipantIdentifier, ProtocolParticipant, + auxinfo, curve_point::{testing::init_testing, CurvePoint}, errors::{CallerError, InternalError, Result}, keygen::{self, Output}, keyrefresh::KeyrefreshParticipant, Identifier, ParticipantConfig, ParticipantIdentifier, ProtocolParticipant }; #[test] @@ -170,7 +165,7 @@ mod test { let keygen_pids = std::iter::repeat_with(|| ParticipantIdentifier::random(rng)) .take(5) .collect::>(); - let keygen_output = keygen::Output::simulate(&keygen_pids, rng); + let keygen_output: Output = keygen::Output::simulate(&keygen_pids, rng); let result = Input::new(auxinfo_output, keygen_output); assert!(result.is_err()); @@ -187,7 +182,7 @@ mod test { // Create valid input set with random PIDs let config = ParticipantConfig::random(5, rng); - let keygen_output = keygen::Output::simulate(&config.all_participants(), rng); + let keygen_output: Output = keygen::Output::simulate(&config.all_participants(), rng); let auxinfo_output = auxinfo::Output::simulate(&config.all_participants(), rng); let input = Input::new(auxinfo_output, keygen_output)?; diff --git a/src/presign/input.rs b/src/presign/input.rs index 9e7317cf..9452000d 100644 --- a/src/presign/input.rs +++ b/src/presign/input.rs @@ -155,12 +155,7 @@ impl Input { mod test { use super::Input; use crate::{ - auxinfo, - errors::{CallerError, InternalError, Result}, - keygen, - curve_point::testing::init_testing, - Identifier, ParticipantConfig, ParticipantIdentifier, PresignParticipant, - ProtocolParticipant, + auxinfo, curve_point::{testing::init_testing, CurvePoint}, errors::{CallerError, InternalError, Result}, keygen::{self, Output}, Identifier, ParticipantConfig, ParticipantIdentifier, PresignParticipant, ProtocolParticipant }; #[test] @@ -170,7 +165,7 @@ mod test { let pids = std::iter::repeat_with(|| ParticipantIdentifier::random(rng)) .take(5) .collect::>(); - let keygen_output = keygen::Output::simulate(&pids, rng); + let keygen_output: Output = keygen::Output::simulate(&pids, rng); let auxinfo_output = auxinfo::Output::simulate(&pids, rng); // Same length works @@ -208,7 +203,7 @@ mod test { let keygen_pids = std::iter::repeat_with(|| ParticipantIdentifier::random(rng)) .take(5) .collect::>(); - let keygen_output = keygen::Output::simulate(&keygen_pids, rng); + let keygen_output: Output = keygen::Output::simulate(&keygen_pids, rng); let result = Input::new(auxinfo_output, keygen_output); assert!(result.is_err()); @@ -227,7 +222,7 @@ mod test { let input_pids = std::iter::repeat_with(|| ParticipantIdentifier::random(rng)) .take(SIZE) .collect::>(); - let keygen_output = keygen::Output::simulate(&input_pids, rng); + let keygen_output: Output = keygen::Output::simulate(&input_pids, rng); let auxinfo_output = auxinfo::Output::simulate(&input_pids, rng); let input = Input::new(auxinfo_output, keygen_output)?; diff --git a/src/presign/record.rs b/src/presign/record.rs index 0d34feb2..daa4de4b 100644 --- a/src/presign/record.rs +++ b/src/presign/record.rs @@ -279,7 +279,7 @@ mod tests { /// For testing only; this does not check that the keygen output set is /// consistent or complete. pub(crate) fn simulate_set( - keygen_outputs: &[keygen::Output], + keygen_outputs: &[keygen::Output], rng: &mut (impl CryptoRng + RngCore), ) -> Vec { // Note: using slightly-biased generation for faster tests @@ -291,7 +291,7 @@ mod tests { .fold(Scalar::ZERO, |sum, mask_share| sum + mask_share); let mask_inversion = Option::::from(mask.invert()).unwrap(); // `R` in the paper. - let mask_point = CurvePoint::GENERATOR.multiply_by_scalar(&mask_inversion); + let mask_point = C::generator().multiply_by_scalar(&mask_inversion); // Compute the masked key shares as (secret_key_share * mask) let masked_key_shares = keygen_outputs diff --git a/src/presign/round_two.rs b/src/presign/round_two.rs index 8a761ec3..7d32e618 100644 --- a/src/presign/round_two.rs +++ b/src/presign/round_two.rs @@ -13,7 +13,6 @@ use crate::{ }, zkp::{ piaffg::{PiAffgInput, PiAffgProof}, pilog::{CommonInput, PiLogProof}, - Proof, } }; use libpaillier::unknown_order::BigNumber; @@ -68,7 +67,7 @@ impl Public { prover_keyshare_public: &KeySharePublic, prover_r1_public_broadcast: &RoundOnePublicBroadcast, ) -> Result<()> { - let g = CurvePoint::GENERATOR; + let g = C::generator(); // Verify the psi proof let psi_input = PiAffgInput::new( diff --git a/src/zkp/pilog.rs b/src/zkp/pilog.rs index 14d157b8..4659948f 100644 --- a/src/zkp/pilog.rs +++ b/src/zkp/pilog.rs @@ -131,13 +131,13 @@ impl<'a> ProverSecret<'a> { /// Generates a challenge from a [`Transcript`] and the values generated in the /// proof. -fn generate_challenge( +fn generate_challenge( transcript: &mut Transcript, context: &dyn ProofContext, - common_input: CommonInput, + common_input: CommonInput, plaintext_commit: &Commitment, mask_encryption: &Ciphertext, - mask_dlog_commit: &CurvePoint, + mask_dlog_commit: &C, mask_commit: &Commitment, ) -> Result { transcript.append_message(b"PiLog ProofContext", &context.as_bytes()?); diff --git a/src/zkp/pisch.rs b/src/zkp/pisch.rs index 04354a14..be883859 100644 --- a/src/zkp/pisch.rs +++ b/src/zkp/pisch.rs @@ -256,7 +256,7 @@ impl PiSchProof { transcript: &mut Transcript, context: &impl ProofContext, input: &CommonInput, - commitment: &CurvePoint, + commitment: &C, ) -> Result<()> { transcript.append_message(b"PiSch ProofContext", &context.as_bytes()?); transcript.append_message(b"PiSch CommonInput", &serialize!(&input)?); From 2b3de7bd9e142bbc3764b8a97e5c3d8ce32ad384 Mon Sep 17 00:00:00 2001 From: emmorais Date: Mon, 5 Aug 2024 09:15:14 -0300 Subject: [PATCH 20/36] Fixing errors --- src/zkp/piaffg.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zkp/piaffg.rs b/src/zkp/piaffg.rs index b15e5ef8..8a92c491 100644 --- a/src/zkp/piaffg.rs +++ b/src/zkp/piaffg.rs @@ -279,7 +279,7 @@ impl Proof for PiAffgProof { .map_err(|_| InternalError::InternalInvariantFailed)?; // Compute the exponentiation of the random multiplicative coefficient // (producing `B_x` in the paper) - let random_mult_coeff_exp = CurvePoint::GENERATOR.multiply_by_bignum(&random_mult_coeff)?; + let random_mult_coeff_exp = C::generator().multiply_by_bignum(&random_mult_coeff)?; // Encrypt the random additive coefficient using the 1st encryption key // (producing `B_y` in the paper). let (random_add_coeff_ciphertext_prover, random_add_coeff_nonce_prover) = input From 8ed35d41a2b667afaf94a4c1244c3cdc902df4ca Mon Sep 17 00:00:00 2001 From: emmorais Date: Mon, 5 Aug 2024 09:55:26 -0300 Subject: [PATCH 21/36] More error fixing --- src/auxinfo/proof.rs | 4 ++-- src/keygen/keyshare.rs | 28 +++++++++++++++------------- src/keygen/output.rs | 8 ++++---- src/keygen/participant.rs | 2 +- src/keyrefresh/input.rs | 2 +- src/keyrefresh/keyshare.rs | 2 +- src/presign/input.rs | 2 +- src/presign/participant.rs | 2 +- src/presign/record.rs | 21 +++++++++++---------- 9 files changed, 37 insertions(+), 34 deletions(-) diff --git a/src/auxinfo/proof.rs b/src/auxinfo/proof.rs index cce1c0bd..8c9e92d9 100644 --- a/src/auxinfo/proof.rs +++ b/src/auxinfo/proof.rs @@ -301,8 +301,8 @@ mod tests { setup_parameters: &setup_params, modulus: &modulus, }; - match AuxInfoProof::prove(&mut rng, &common_input, &p, &q) { - Ok(proof) => assert!(proof.verify(&bad_common_input).is_err()), + match AuxInfoProof::prove::(&mut rng, &common_input, &p, &q) { + Ok(proof) => assert!(proof.verify::(&bad_common_input).is_err()), Err(_) => return Ok(()), } Ok(()) diff --git a/src/keygen/keyshare.rs b/src/keygen/keyshare.rs index 37a22ee9..90a7c1ca 100644 --- a/src/keygen/keyshare.rs +++ b/src/keygen/keyshare.rs @@ -7,7 +7,7 @@ // of this source tree. use crate::{ - curve_point::{k256_order, CurveTrait}, errors::{CallerError, Result}, utils::ParseBytes, ParticipantIdentifier + curve_point::{k256_order, CurvePoint, CurveTrait}, errors::{CallerError, Result}, utils::ParseBytes, ParticipantIdentifier }; use libpaillier::unknown_order::BigNumber; use rand::{CryptoRng, RngCore}; @@ -24,28 +24,30 @@ const KEYSHARE_TAG: &[u8] = b"KeySharePrivate"; /// # 🔒 Storage requirements /// This type must be stored securely by the calling application. #[derive(Clone, PartialEq, Eq)] -pub struct KeySharePrivate { +pub struct KeySharePrivate { x: BigNumber, // in the range [1, q) + /// Marker to pin the generic type. + curve: std::marker::PhantomData, } -impl Debug for KeySharePrivate { +impl Debug for KeySharePrivate { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.write_str("KeySharePrivate([redacted])") } } -impl KeySharePrivate { +impl KeySharePrivate { /// Sample a private key share uniformly at random. pub(crate) fn random(rng: &mut (impl CryptoRng + RngCore)) -> Self { let random_bn = BigNumber::from_rng(&k256_order(), rng); - KeySharePrivate { x: random_bn } + KeySharePrivate:: { x: random_bn, curve: std::marker::PhantomData } } /// Take a [`BigNumber`] as [`KeySharePrivate`]. `x_int` will be reduced /// modulo `q`. pub(crate) fn from_bigint(x_int: &BigNumber) -> Self { let x = x_int.nmod(&k256_order()); - Self { x } + Self { x, curve: std::marker::PhantomData } } /// Computes the "raw" curve point corresponding to this private key. @@ -108,7 +110,7 @@ impl KeySharePrivate { Err(CallerError::DeserializationFailed)? } - Ok(Self { x: share }) + Ok(Self { x: share, curve: std::marker::PhantomData }) }; let result = parse(); @@ -131,7 +133,7 @@ impl KeySharePrivate { } } -impl AsRef for KeySharePrivate { +impl AsRef for KeySharePrivate { /// Get the private key share. fn as_ref(&self) -> &BigNumber { &self.x @@ -164,7 +166,7 @@ impl KeySharePublic { pub(crate) fn new_keyshare( participant: ParticipantIdentifier, rng: &mut R, - ) -> Result<(KeySharePrivate, KeySharePublic)> { + ) -> Result<(KeySharePrivate, KeySharePublic)> { let private_share = KeySharePrivate::random(rng); let public_share = private_share.public_share()?; @@ -191,7 +193,7 @@ mod tests { #[test] fn keyshare_private_bytes_conversion_works() { let rng = &mut init_testing(); - let share: KeySharePrivate = KeySharePrivate::random(rng); + let share: KeySharePrivate:: = KeySharePrivate::::random(rng); let bytes = share.clone().into_bytes(); let reconstructed = KeySharePrivate::try_from_bytes(bytes); @@ -203,9 +205,9 @@ mod tests { #[test] fn keyshare_private_bytes_must_be_in_range() { // Share must be < k256_order() - let too_big = KeySharePrivate { x: k256_order() }; + let too_big = KeySharePrivate:: { x: k256_order(), curve: std::marker::PhantomData }; let bytes = too_big.into_bytes(); - assert!(KeySharePrivate::try_from_bytes(bytes).is_err()); + assert!(KeySharePrivate::::try_from_bytes(bytes).is_err()); // Note: I tried testing the negative case but it seems like the // unknown_order crate's `from_bytes` method always interprets @@ -217,7 +219,7 @@ mod tests { #[test] fn deserialized_keyshare_private_tag_must_be_correct() { let rng = &mut init_testing(); - let key_share = KeySharePrivate::random(rng); + let key_share = KeySharePrivate::::random(rng); // Cut out the tag from the serialized bytes for convenience. let share_bytes = &key_share.into_bytes()[KEYSHARE_TAG.len()..]; diff --git a/src/keygen/output.rs b/src/keygen/output.rs index 9052753e..cbdae34b 100644 --- a/src/keygen/output.rs +++ b/src/keygen/output.rs @@ -19,7 +19,7 @@ use tracing::error; #[derive(Debug, Clone)] pub struct Output { public_key_shares: Vec>, - private_key_share: KeySharePrivate, + private_key_share: KeySharePrivate, rid: [u8; 32], } @@ -43,7 +43,7 @@ impl Output { &self.public_key_shares } - pub(crate) fn private_key_share(&self) -> &KeySharePrivate { + pub(crate) fn private_key_share(&self) -> &KeySharePrivate { &self.private_key_share } @@ -81,7 +81,7 @@ impl Output { /// - The public key shares must be from a unique set of participants pub fn from_parts( public_key_shares: Vec>, - private_key_share: KeySharePrivate, + private_key_share: KeySharePrivate, rid: [u8; 32], ) -> Result { let pids = public_key_shares @@ -118,7 +118,7 @@ impl Output { /// /// The public components (including the byte array and the public key /// shares) can be stored in the clear. - pub fn into_parts(self) -> (Vec>, KeySharePrivate, [u8; 32]) { + pub fn into_parts(self) -> (Vec>, KeySharePrivate, [u8; 32]) { (self.public_key_shares, self.private_key_share, self.rid) } } diff --git a/src/keygen/participant.rs b/src/keygen/participant.rs index 9acde976..852d0d68 100644 --- a/src/keygen/participant.rs +++ b/src/keygen/participant.rs @@ -44,7 +44,7 @@ mod storage { } pub(super) struct PrivateKeyshare; impl TypeTag for PrivateKeyshare { - type Value = KeySharePrivate; + type Value = KeySharePrivate; } pub(super) struct PublicKeyshare; impl TypeTag for PublicKeyshare { diff --git a/src/keyrefresh/input.rs b/src/keyrefresh/input.rs index 6322dd01..26c534ba 100644 --- a/src/keyrefresh/input.rs +++ b/src/keyrefresh/input.rs @@ -109,7 +109,7 @@ impl Input { }) } - pub(crate) fn private_key_share(&self) -> &KeySharePrivate { + pub(crate) fn private_key_share(&self) -> &KeySharePrivate { self.keygen_output.private_key_share() } } diff --git a/src/keyrefresh/keyshare.rs b/src/keyrefresh/keyshare.rs index a87def12..a6a3dc8a 100644 --- a/src/keyrefresh/keyshare.rs +++ b/src/keyrefresh/keyshare.rs @@ -92,7 +92,7 @@ impl KeyUpdatePrivate { KeyUpdatePrivate { x: sum, _curve: std::marker::PhantomData } } - pub(crate) fn apply(self, current_sk: &KeySharePrivate) -> KeySharePrivate { + pub(crate) fn apply(self, current_sk: &KeySharePrivate) -> KeySharePrivate { let mut sum = current_sk.as_ref() + &self.x; let share = KeySharePrivate::from_bigint(&sum); sum.zeroize(); diff --git a/src/presign/input.rs b/src/presign/input.rs index 9452000d..a87f0da2 100644 --- a/src/presign/input.rs +++ b/src/presign/input.rs @@ -112,7 +112,7 @@ impl Input { }) } - pub(crate) fn private_key_share(&self) -> &KeySharePrivate { + pub(crate) fn private_key_share(&self) -> &KeySharePrivate { self.keygen_output.private_key_share() } diff --git a/src/presign/participant.rs b/src/presign/participant.rs index 91231bcd..6c33b43f 100644 --- a/src/presign/participant.rs +++ b/src/presign/participant.rs @@ -880,7 +880,7 @@ impl PresignParticipant { /// /// TODO: Refactor as specified in #246. pub(crate) struct PresignKeyShareAndInfo { - pub(crate) keyshare_private: KeySharePrivate, + pub(crate) keyshare_private: KeySharePrivate, pub(crate) keyshare_public: KeySharePublic, pub(crate) aux_info_private: AuxInfoPrivate, pub(crate) aux_info_public: AuxInfoPublic, diff --git a/src/presign/record.rs b/src/presign/record.rs index daa4de4b..e02abd99 100644 --- a/src/presign/record.rs +++ b/src/presign/record.rs @@ -247,6 +247,7 @@ impl PresignRecord { #[cfg(test)] mod tests { + use crate::presign::record; use k256::{elliptic_curve::Field, Scalar}; use rand::{rngs::StdRng, CryptoRng, Rng, RngCore, SeedableRng}; @@ -461,10 +462,10 @@ mod tests { // Part of a tag or the whole tag alone doesn't pass let bytes = &RECORD_TAG[..3]; - assert!(PresignRecord::try_from_bytes(bytes.to_vec()).is_err()); - assert!(PresignRecord::try_from_bytes(RECORD_TAG.to_vec()).is_err()); + assert!(PresignRecord::::try_from_bytes(bytes.to_vec()).is_err()); + assert!(PresignRecord::::try_from_bytes(RECORD_TAG.to_vec()).is_err()); - let PresignRecord { R, k, chi }: record::PresignRecord = PresignRecord::simulate(rng); + let PresignRecord:: { R, k, chi }: record::PresignRecord = PresignRecord::::simulate(rng); let point = R.to_bytes(); let point_len = point.len().to_le_bytes(); @@ -479,18 +480,18 @@ mod tests { // Length with no curve point following doesn't pass let bytes = [RECORD_TAG, &point_len].concat(); - assert!(PresignRecord::try_from_bytes(bytes).is_err()); + assert!(PresignRecord::::try_from_bytes(bytes).is_err()); // Zero-length doesn't pass let bytes = [RECORD_TAG, &zero_len].concat(); - assert!(PresignRecord::try_from_bytes(bytes).is_err()); + assert!(PresignRecord::::try_from_bytes(bytes).is_err()); // Length with no randomness share following doesn't pass let bytes = [RECORD_TAG, &point_len, &point, &random_share_len].concat(); - assert!(PresignRecord::try_from_bytes(bytes).is_err()); + assert!(PresignRecord::::try_from_bytes(bytes).is_err()); let bytes = [RECORD_TAG, &point_len, &point, &zero_len].concat(); - assert!(PresignRecord::try_from_bytes(bytes).is_err()); + assert!(PresignRecord::::try_from_bytes(bytes).is_err()); // Length with no chi share following doesn't pass let bytes = [ @@ -502,7 +503,7 @@ mod tests { &chi_share_len, ] .concat(); - assert!(PresignRecord::try_from_bytes(bytes).is_err()); + assert!(PresignRecord::::try_from_bytes(bytes).is_err()); let bytes = [ RECORD_TAG, @@ -513,7 +514,7 @@ mod tests { &zero_len, ] .concat(); - assert!(PresignRecord::try_from_bytes(bytes).is_err()); + assert!(PresignRecord::::try_from_bytes(bytes).is_err()); // Full thing works (e.g. the encoding scheme used above is correct) let bytes = [ @@ -526,6 +527,6 @@ mod tests { chi_share.as_ref(), ] .concat(); - assert!(PresignRecord::try_from_bytes(bytes).is_ok()); + assert!(PresignRecord::::try_from_bytes(bytes).is_ok()); } } From dc064e7389d7dafe65eef047c2c8a36ba895573a Mon Sep 17 00:00:00 2001 From: emmorais Date: Mon, 5 Aug 2024 10:13:01 -0300 Subject: [PATCH 22/36] 43 errors missing --- src/keygen/keyshare.rs | 30 +++++++++++++++--------------- src/presign/participant.rs | 2 +- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/keygen/keyshare.rs b/src/keygen/keyshare.rs index 90a7c1ca..c3a831d3 100644 --- a/src/keygen/keyshare.rs +++ b/src/keygen/keyshare.rs @@ -228,65 +228,65 @@ mod tests { let wrong_tag = b"NotTheRightTag!"; assert_eq!(wrong_tag.len(), KEYSHARE_TAG.len()); let bad_bytes = [wrong_tag.as_slice(), share_bytes].concat(); - assert!(KeySharePrivate::try_from_bytes(bad_bytes).is_err()); + assert!(KeySharePrivate::::try_from_bytes(bad_bytes).is_err()); // Tag must be correct length (too short, too long) let short_tag = &KEYSHARE_TAG[..5]; let bad_bytes = [short_tag, share_bytes].concat(); - assert!(KeySharePrivate::try_from_bytes(bad_bytes).is_err()); + assert!(KeySharePrivate::::try_from_bytes(bad_bytes).is_err()); let bad_bytes = [KEYSHARE_TAG, b"TAG EXTENSION!", share_bytes].concat(); - assert!(KeySharePrivate::try_from_bytes(bad_bytes).is_err()); + assert!(KeySharePrivate::::try_from_bytes(bad_bytes).is_err()); // Normal serialization works let bytes = [KEYSHARE_TAG, share_bytes].concat(); - assert!(KeySharePrivate::try_from_bytes(bytes).is_ok()); + assert!(KeySharePrivate::::try_from_bytes(bytes).is_ok()); } #[test] fn deserialized_keyshare_private_length_field_must_be_correct() { let rng = &mut init_testing(); - let share_bytes = KeySharePrivate::random(rng).x.to_bytes(); + let share_bytes = KeySharePrivate::::random(rng).x.to_bytes(); // Length must be specified let bad_bytes = [KEYSHARE_TAG, &share_bytes].concat(); - assert!(KeySharePrivate::try_from_bytes(bad_bytes).is_err()); + assert!(KeySharePrivate::::try_from_bytes(bad_bytes).is_err()); // Length must be little endian let share_len = share_bytes.len().to_be_bytes(); let bad_bytes = [KEYSHARE_TAG, &share_len, &share_bytes].concat(); - assert!(KeySharePrivate::try_from_bytes(bad_bytes).is_err()); + assert!(KeySharePrivate::::try_from_bytes(bad_bytes).is_err()); // Length must be correct (too long, too short) let too_short = (share_bytes.len() - 5).to_le_bytes(); let bad_bytes = [KEYSHARE_TAG, &too_short, &share_bytes].concat(); - assert!(KeySharePrivate::try_from_bytes(bad_bytes).is_err()); + assert!(KeySharePrivate::::try_from_bytes(bad_bytes).is_err()); let too_long = (share_bytes.len() + 5).to_le_bytes(); let bad_bytes = [KEYSHARE_TAG, &too_long, &share_bytes].concat(); - assert!(KeySharePrivate::try_from_bytes(bad_bytes).is_err()); + assert!(KeySharePrivate::::try_from_bytes(bad_bytes).is_err()); // Correct length works let share_len = share_bytes.len().to_le_bytes(); let bytes = [KEYSHARE_TAG, &share_len, &share_bytes].concat(); - assert!(KeySharePrivate::try_from_bytes(bytes).is_ok()); + assert!(KeySharePrivate::::try_from_bytes(bytes).is_ok()); } #[test] fn deserialized_keyshare_private_requires_all_fields() { // Part of a tag or the whole tag alone doesn't pass let bytes = &KEYSHARE_TAG[..3]; - assert!(KeySharePrivate::try_from_bytes(bytes.to_vec()).is_err()); - assert!(KeySharePrivate::try_from_bytes(KEYSHARE_TAG.to_vec()).is_err()); + assert!(KeySharePrivate::::try_from_bytes(bytes.to_vec()).is_err()); + assert!(KeySharePrivate::::try_from_bytes(KEYSHARE_TAG.to_vec()).is_err()); // Length with no secret following doesn't pass let share_len = k256_order().bit_length() / 8; let bytes = [KEYSHARE_TAG, &share_len.to_le_bytes()].concat(); - assert!(KeySharePrivate::try_from_bytes(bytes).is_err()); + assert!(KeySharePrivate::::try_from_bytes(bytes).is_err()); // Zero-length doesn't pass let bytes = [KEYSHARE_TAG, &0usize.to_le_bytes()].concat(); - assert!(KeySharePrivate::try_from_bytes(bytes).is_err()); + assert!(KeySharePrivate::::try_from_bytes(bytes).is_err()); } use crate::enable_zeroize; @@ -306,7 +306,7 @@ mod tests { // Generate a secret. let rng = &mut StdRng::from_seed([0; 32]); - let mut share = KeySharePrivate::random(rng); + let mut share = KeySharePrivate::::random(rng); // Pre-hack validation. assert!( diff --git a/src/presign/participant.rs b/src/presign/participant.rs index 6c33b43f..8364c457 100644 --- a/src/presign/participant.rs +++ b/src/presign/participant.rs @@ -1025,7 +1025,7 @@ impl PresignKeyShareAndInfo { .encrypt(rng, &beta_hat) .map_err(|_| InternalError::InternalInvariantFailed)?; - let g = CurvePoint::GENERATOR; + let g = C::generator(); let Gamma = g.multiply_by_bignum(&sender_r1_priv.gamma)?; // Generate the proofs. From 1c1e236618611c560e49dd782135afcc46e5bc5b Mon Sep 17 00:00:00 2001 From: emmorais Date: Mon, 5 Aug 2024 10:40:44 -0300 Subject: [PATCH 23/36] 37 errors --- src/curve_point.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/curve_point.rs b/src/curve_point.rs index 157af3a4..b8f9cf70 100644 --- a/src/curve_point.rs +++ b/src/curve_point.rs @@ -178,7 +178,7 @@ pub(crate) fn random_bn_in_z_star( } /// Common trait for curves -pub trait CurveTrait: Serialize + Clone + Debug + Eq + PartialEq + Zeroize + Add { +pub trait CurveTrait: Serialize + Clone + Debug + Eq + PartialEq + Zeroize + Add { /// Returns the generator of the curve fn generator() -> Self; /// Returns the identity element of the curve From 69666a810803595994d9f941af3a9acf755b11df Mon Sep 17 00:00:00 2001 From: emmorais Date: Tue, 6 Aug 2024 09:27:38 -0300 Subject: [PATCH 24/36] 3 errors --- src/curve_point.rs | 1 + src/keygen/keygen_commit.rs | 6 +++--- src/keygen/keyshare.rs | 6 +++--- src/keyrefresh/keyrefresh_commit.rs | 4 ++-- src/keyrefresh/keyshare.rs | 2 +- src/keyrefresh/participant.rs | 4 ++-- src/presign/participant.rs | 2 +- src/presign/round_three.rs | 4 ++-- src/presign/round_two.rs | 6 +++--- src/zkp/pilog.rs | 17 ++++++++--------- src/zkp/pisch.rs | 22 +++++++++++----------- 11 files changed, 37 insertions(+), 37 deletions(-) diff --git a/src/curve_point.rs b/src/curve_point.rs index b8f9cf70..29b67752 100644 --- a/src/curve_point.rs +++ b/src/curve_point.rs @@ -20,6 +20,7 @@ use k256::{ }; use libpaillier::unknown_order::BigNumber; use rand::{CryptoRng, RngCore}; +use serde::de::DeserializeOwned; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use std::fmt::Debug; use std::ops::Add; diff --git a/src/keygen/keygen_commit.rs b/src/keygen/keygen_commit.rs index 88e2c103..9ba8b732 100644 --- a/src/keygen/keygen_commit.rs +++ b/src/keygen/keygen_commit.rs @@ -11,7 +11,7 @@ use crate::{ }; use merlin::Transcript; use rand::{CryptoRng, RngCore}; -use serde::{de::DeserializeOwned, Deserialize, Serialize}; +use serde::{Deserialize, Serialize}; use tracing::{error, instrument}; #[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)] @@ -26,7 +26,7 @@ impl KeygenCommit { } } -#[derive(Debug, Serialize, Deserialize, Clone)] +#[derive(Debug, Serialize, Clone)] pub(crate) struct KeygenDecommit { ///`sid` corresponds to a unique session identifier. pub sid: Identifier, @@ -37,7 +37,7 @@ pub(crate) struct KeygenDecommit { pub A: C, } -impl KeygenDecommit { +impl KeygenDecommit { ///`sid` corresponds to a unique session identifier. pub(crate) fn new( rng: &mut R, diff --git a/src/keygen/keyshare.rs b/src/keygen/keyshare.rs index c3a831d3..1b96d53c 100644 --- a/src/keygen/keyshare.rs +++ b/src/keygen/keyshare.rs @@ -7,11 +7,11 @@ // of this source tree. use crate::{ - curve_point::{k256_order, CurvePoint, CurveTrait}, errors::{CallerError, Result}, utils::ParseBytes, ParticipantIdentifier + curve_point::{k256_order, CurveTrait}, errors::{CallerError, Result}, utils::ParseBytes, ParticipantIdentifier }; use libpaillier::unknown_order::BigNumber; use rand::{CryptoRng, RngCore}; -use serde::{Deserialize, Serialize}; +use serde::Serialize; use std::fmt::Debug; use tracing::error; use zeroize::Zeroize; @@ -142,7 +142,7 @@ impl AsRef for KeySharePrivate { /// A curve point representing a given [`Participant`](crate::Participant)'s /// public key. -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +#[derive(Debug, Clone, Serialize, PartialEq, Eq)] pub struct KeySharePublic { participant: ParticipantIdentifier, X: C, diff --git a/src/keyrefresh/keyrefresh_commit.rs b/src/keyrefresh/keyrefresh_commit.rs index 0107c7c5..31f70049 100644 --- a/src/keyrefresh/keyrefresh_commit.rs +++ b/src/keyrefresh/keyrefresh_commit.rs @@ -29,7 +29,7 @@ impl KeyrefreshCommit { } /// Decommitment published in round 2. -#[derive(Serialize, Deserialize, Clone)] +#[derive(Serialize, Clone)] pub(crate) struct KeyrefreshDecommit { sid: Identifier, sender: ParticipantIdentifier, @@ -39,7 +39,7 @@ pub(crate) struct KeyrefreshDecommit { pub As: Vec, } -impl<'de, C: CurveTrait + Serialize + Deserialize<'de> + PartialEq> KeyrefreshDecommit { +impl<'de, C: CurveTrait + Serialize + PartialEq> KeyrefreshDecommit { ///`sid` corresponds to a unique session identifier. pub(crate) fn new( rng: &mut R, diff --git a/src/keyrefresh/keyshare.rs b/src/keyrefresh/keyshare.rs index a6a3dc8a..5224164e 100644 --- a/src/keyrefresh/keyshare.rs +++ b/src/keyrefresh/keyshare.rs @@ -114,7 +114,7 @@ impl AsRef for KeyUpdatePrivate { /// A curve point representing a given [`Participant`](crate::Participant)'s /// public key. -#[derive(Debug, Deserialize, PartialEq, Eq)] +#[derive(Debug, PartialEq, Eq)] pub struct KeyUpdatePublic { participant: ParticipantIdentifier, X: C, diff --git a/src/keyrefresh/participant.rs b/src/keyrefresh/participant.rs index d6c65bad..062fb167 100644 --- a/src/keyrefresh/participant.rs +++ b/src/keyrefresh/participant.rs @@ -757,7 +757,7 @@ impl KeyrefreshParticipant { .iter() .map(|pid| { self.local_storage - .remove::>(*pid) + .remove::>(*pid) }) .collect::>>()?; let all_public_updates = @@ -814,7 +814,7 @@ impl KeyrefreshParticipant { } } - fn aggregate_private_updates(update_privates: &[KeyUpdatePrivate]) -> KeyUpdatePrivate { + fn aggregate_private_updates(update_privates: &[KeyUpdatePrivate]) -> KeyUpdatePrivate { KeyUpdatePrivate::sum(update_privates) } diff --git a/src/presign/participant.rs b/src/presign/participant.rs index 8364c457..40f112df 100644 --- a/src/presign/participant.rs +++ b/src/presign/participant.rs @@ -1107,7 +1107,7 @@ impl PresignKeyShareAndInfo { HashMap>, )> { let order = k256_order(); - let g = CurvePoint::GENERATOR; + let g = C::generator(); let mut delta: BigNumber = sender_r1_priv.gamma.modmul(&sender_r1_priv.k, &order); let mut chi: BigNumber = self diff --git a/src/presign/round_three.rs b/src/presign/round_three.rs index ed1eca8e..bbc9b45c 100644 --- a/src/presign/round_three.rs +++ b/src/presign/round_three.rs @@ -19,7 +19,7 @@ use crate::{ use k256::{elliptic_curve::PrimeField, Scalar}; use libpaillier::unknown_order::BigNumber; use merlin::Transcript; -use serde::{Deserialize, Serialize}; +use serde::Serialize; use std::fmt::Debug; use tracing::error; use zeroize::ZeroizeOnDrop; @@ -56,7 +56,7 @@ impl Debug for Private { /// [`Message`] is a valid serialization of `Public`, but _not_ that `Public` is /// necessarily valid (i.e., that all the components are valid with respect to /// each other); use [`Public::verify`] to check this latter condition. -#[derive(Clone, Serialize, Deserialize)] +#[derive(Clone, Serialize)] pub(crate) struct Public { pub delta: Scalar, pub Delta: C, diff --git a/src/presign/round_two.rs b/src/presign/round_two.rs index 7d32e618..fb066891 100644 --- a/src/presign/round_two.rs +++ b/src/presign/round_two.rs @@ -7,7 +7,7 @@ // of this source tree. use crate::{ - auxinfo::AuxInfoPublic, curve_point::{CurvePoint, CurveTrait}, errors::{InternalError, Result}, keygen::KeySharePublic, messages::{Message, MessageType, PresignMessageType}, paillier::Ciphertext, presign::{ + auxinfo::AuxInfoPublic, curve_point::CurveTrait, errors::{InternalError, Result}, keygen::KeySharePublic, messages::{Message, MessageType, PresignMessageType}, paillier::Ciphertext, presign::{ participant::ParticipantPresignContext, round_one::{Private as RoundOnePrivate, PublicBroadcast as RoundOnePublicBroadcast}, }, zkp::{ @@ -17,7 +17,7 @@ use crate::{ }; use libpaillier::unknown_order::BigNumber; use merlin::Transcript; -use serde::{Deserialize, Serialize}; +use serde::Serialize; use std::fmt::Debug; use zeroize::ZeroizeOnDrop; @@ -42,7 +42,7 @@ impl Debug for Private { /// [`Message`] is a valid serialization of `Public`, but _not_ that `Public` is /// necessarily valid (i.e., that all the components are valid with respect to /// each other); use [`Public::verify`] to check this latter condition. -#[derive(Clone, Serialize, Deserialize)] +#[derive(Clone, Serialize)] pub(crate) struct Public { pub D: Ciphertext, pub D_hat: Ciphertext, diff --git a/src/zkp/pilog.rs b/src/zkp/pilog.rs index 4659948f..b95d6b44 100644 --- a/src/zkp/pilog.rs +++ b/src/zkp/pilog.rs @@ -28,7 +28,6 @@ use rand::{CryptoRng, RngCore}; use serde::{de::DeserializeOwned, Deserialize, Serialize}; use std::fmt::Debug; use tracing::error; -use crate::curve_point::CurvePoint; /// Proof of knowledge that: /// 1. the committed value in a discrete log commitment and the plaintext value @@ -347,7 +346,7 @@ impl Proof for PiLogProof { mod tests { use super::*; use crate::{ - curve_point::{testing::init_testing, CurveTrait}, paillier::{DecryptionKey, Nonce}, ring_pedersen::VerifiedRingPedersen, utils::random_plusminus_by_size_with_minimum, zkp::BadContext + curve_point::{testing::init_testing, CurvePoint, CurveTrait}, paillier::{DecryptionKey, Nonce}, ring_pedersen::VerifiedRingPedersen, utils::random_plusminus_by_size_with_minimum, zkp::BadContext }; use rand::{rngs::StdRng, Rng, SeedableRng}; @@ -355,7 +354,7 @@ mod tests { Transcript::new(b"PiLogProof Test") } - fn with_random_paillier_log_proof( + fn with_random_paillier_log_proof( rng: &mut R, x: &BigNumber, mut f: impl FnMut(PiLogProof, CommonInput) -> Result<()>, @@ -382,7 +381,7 @@ mod tests { f(proof, input) } - fn random_paillier_log_proof_verification( + fn random_paillier_log_proof_verification( rng: &mut R, x: &BigNumber, ) -> Result<()> { @@ -398,7 +397,7 @@ mod tests { pilog_proof_with_consistent_secret_inputs_out_of_range::().unwrap(); } - fn pilog_proof_with_consistent_secret_inputs_out_of_range() -> Result<()> { + fn pilog_proof_with_consistent_secret_inputs_out_of_range() -> Result<()> { let mut rng = init_testing(); let upper_bound = BigNumber::one() << (ELL + EPSILON); loop { @@ -431,7 +430,7 @@ mod tests { let _ = pilog_proof_with_different_setup_parameters::(); } - fn pilog_proof_with_different_setup_parameters() -> Result<()> { + fn pilog_proof_with_different_setup_parameters() -> Result<()> { let mut rng = init_testing(); let x = random_plusminus_by_size(&mut rng, ELL); let (decryption_key, _, _) = DecryptionKey::new(&mut rng).unwrap(); @@ -548,7 +547,7 @@ mod tests { let _ = pilog_proof_with_inconsistent_secret_inputs::(); } - fn pilog_proof_with_inconsistent_secret_inputs() -> Result<()> + fn pilog_proof_with_inconsistent_secret_inputs() -> Result<()> { let mut rng = init_testing(); @@ -598,7 +597,7 @@ mod tests { negative_test_swap_proof_elements::().unwrap(); } - fn negative_test_swap_proof_elements() -> Result<()> { + fn negative_test_swap_proof_elements() -> Result<()> { let mut rng = init_testing(); // `rng` will be borrowed. We make another rng to be captured by the closure. let mut rng2 = StdRng::from_seed(rng.gen()); @@ -681,7 +680,7 @@ mod tests { pilog_proof_context_must_be_correct::().unwrap(); } - fn pilog_proof_context_must_be_correct() -> Result<()> { + fn pilog_proof_context_must_be_correct() -> Result<()> { let mut rng = init_testing(); let context = BadContext {}; diff --git a/src/zkp/pisch.rs b/src/zkp/pisch.rs index be883859..ab523ddc 100644 --- a/src/zkp/pisch.rs +++ b/src/zkp/pisch.rs @@ -59,7 +59,7 @@ pub(crate) struct PiSchProof /// Implementation note: this type includes the mask itself. This is for /// convenience; the mask must not be sent to the verifier at any point as this /// breaks the security of the proof. -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Serialize)] pub(crate) struct PiSchPrecommit { /// Precommitment value (`A` in the paper). precommitment: C, @@ -72,8 +72,8 @@ pub(crate) struct PiSchPrecommit { /// Copying/Cloning references is harmless and sometimes necessary. So we /// implement Clone and Copy for this type. #[derive(Serialize, Copy, Clone)] -pub(crate) struct CommonInput<'a> { - x_commitment: &'a CurvePoint, +pub(crate) struct CommonInput<'a, C: CurveTrait> { + x_commitment: &'a C, } impl PiSchPrecommit { @@ -82,8 +82,8 @@ impl PiSchPrecommit { } } -impl<'a> CommonInput<'a> { - pub(crate) fn new(x_commitment: &'a impl AsRef) -> CommonInput<'a> { +impl<'a, C: CurveTrait> CommonInput<'a, C> { + pub(crate) fn new(x_commitment: &'a impl AsRef) -> CommonInput<'a, C> { Self { x_commitment: x_commitment.as_ref(), } @@ -112,7 +112,7 @@ impl<'a> ProverSecret<'a> { impl Proof for PiSchProof { - type CommonInput<'a> = CommonInput<'a>; + type CommonInput<'a> = CommonInput<'a, C>; type ProverSecret<'a> = ProverSecret<'a>; #[cfg_attr(feature = "flame_it", flame("PiSchProof"))] fn prove( @@ -177,7 +177,7 @@ impl PiSchProof { pub fn prove_from_precommit( context: &impl ProofContext, com: &PiSchPrecommit, - input: &CommonInput, + input: &CommonInput, secret: &ProverSecret, transcript: &Transcript, ) -> Result { @@ -208,7 +208,7 @@ impl PiSchProof { /// Verify that the proof is valid and that it matches a precommitment. pub fn verify_with_precommit( self, - input: CommonInput, + input: CommonInput, context: &impl ProofContext, transcript: &mut Transcript, commitment: &C, @@ -255,7 +255,7 @@ impl PiSchProof { fn fill_transcript( transcript: &mut Transcript, context: &impl ProofContext, - input: &CommonInput, + input: &CommonInput, commitment: &C, ) -> Result<()> { transcript.append_message(b"PiSch ProofContext", &context.as_bytes()?); @@ -273,12 +273,12 @@ mod tests { Transcript::new(b"PiSchProof Test") } - type TestFn = fn(PiSchProof, CommonInput) -> Result<()>; + type TestFn = fn(PiSchProof, CommonInput) -> Result<()>; fn with_random_schnorr_proof( rng: &mut R, additive: bool, - test_code: impl Fn(PiSchProof, CommonInput) -> Result<()>, + test_code: impl Fn(PiSchProof, CommonInput) -> Result<()>, ) -> Result<()> { let q = k256_order(); let g = CurvePoint::GENERATOR; From b1560f87e6924214e23235d98dfad30803b9968c Mon Sep 17 00:00:00 2001 From: emmorais Date: Tue, 6 Aug 2024 09:30:12 -0300 Subject: [PATCH 25/36] Undo "where C: 'a" in pilog and piaffg --- src/zkp/piaffg.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zkp/piaffg.rs b/src/zkp/piaffg.rs index 8a92c491..b35f8b4b 100644 --- a/src/zkp/piaffg.rs +++ b/src/zkp/piaffg.rs @@ -193,7 +193,7 @@ impl<'a> PiAffgSecret<'a> { } impl Proof for PiAffgProof { - type CommonInput<'a> = PiAffgInput<'a, C> where C: 'a; + type CommonInput<'a> = PiAffgInput<'a, C>; type ProverSecret<'b> = PiAffgSecret<'b>; #[cfg_attr(feature = "flame_it", flame("PiAffgProof"))] From 35b25b0dce9595ca5d51f2fb9a6adae41521d754 Mon Sep 17 00:00:00 2001 From: emmorais Date: Tue, 6 Aug 2024 09:32:00 -0300 Subject: [PATCH 26/36] Undo changes to src/zkp/pilog.rs --- src/zkp/pilog.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zkp/pilog.rs b/src/zkp/pilog.rs index b95d6b44..27836a4c 100644 --- a/src/zkp/pilog.rs +++ b/src/zkp/pilog.rs @@ -158,7 +158,7 @@ fn generate_challenge( } impl Proof for PiLogProof { - type CommonInput<'a> = CommonInput<'a, C> where C: 'a; + type CommonInput<'a> = CommonInput<'a, C>; type ProverSecret<'a> = ProverSecret<'a>; #[cfg_attr(feature = "flame_it", flame("PiLogProof"))] fn prove<'a, R: RngCore + CryptoRng>( From 22c1c5edcea2ae12c6348594e847b1bd276afbc1 Mon Sep 17 00:00:00 2001 From: emmorais Date: Tue, 6 Aug 2024 09:33:48 -0300 Subject: [PATCH 27/36] Warnings --- src/curve_point.rs | 1 - src/zkp/pisch.rs | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/curve_point.rs b/src/curve_point.rs index 29b67752..b8f9cf70 100644 --- a/src/curve_point.rs +++ b/src/curve_point.rs @@ -20,7 +20,6 @@ use k256::{ }; use libpaillier::unknown_order::BigNumber; use rand::{CryptoRng, RngCore}; -use serde::de::DeserializeOwned; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use std::fmt::Debug; use std::ops::Add; diff --git a/src/zkp/pisch.rs b/src/zkp/pisch.rs index ab523ddc..e0ed74f7 100644 --- a/src/zkp/pisch.rs +++ b/src/zkp/pisch.rs @@ -35,7 +35,6 @@ use rand::{CryptoRng, RngCore}; use serde::{de::DeserializeOwned, Deserialize, Serialize}; use std::{convert::AsRef, fmt::Debug}; use tracing::error; -use crate::curve_point::CurvePoint; /// Proof of knowledge of discrete logarithm of a group element which is the /// commitment to the secret. @@ -268,7 +267,7 @@ impl PiSchProof { #[cfg(test)] mod tests { use super::*; - use crate::{curve_point::testing::init_testing, zkp::BadContext}; + use crate::{curve_point::{testing::init_testing, CurvePoint}, zkp::BadContext}; fn transcript() -> Transcript { Transcript::new(b"PiSchProof Test") } From 19186518d70cdbcff23c7f15cdc76a1dc83620ec Mon Sep 17 00:00:00 2001 From: emmorais Date: Wed, 7 Aug 2024 09:29:32 -0300 Subject: [PATCH 28/36] Replace curve order in pisch.rs --- src/zkp/pisch.rs | 46 ++++++++++++++++++++++------------------------ 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/src/zkp/pisch.rs b/src/zkp/pisch.rs index e0ed74f7..97987bab 100644 --- a/src/zkp/pisch.rs +++ b/src/zkp/pisch.rs @@ -49,8 +49,6 @@ pub(crate) struct PiSchProof /// Response binding the commitment randomness used in the commitment (`z` /// in the paper). response: BigNumber, - /// Marker to pin the curve type. - curve: std::marker::PhantomData, } /// Commitment to the mask selected in the commitment phase of the proof. @@ -163,7 +161,7 @@ impl PiSchProof { /// "Commitment" phase of the PiSch proof. pub fn precommit(rng: &mut R) -> Result> { // Sample alpha from F_q - let randomness_for_commitment = random_positive_bn(rng, &k256_order()); + let randomness_for_commitment = random_positive_bn(rng, &C::curve_order()); // Form a commitment to the mask let precommitment = C::generator().multiply_by_bignum(&randomness_for_commitment)?; Ok(PiSchPrecommit { @@ -186,12 +184,12 @@ impl PiSchProof { Self::fill_transcript(&mut local_transcript, context, input, &commitment)?; // Verifier samples e in F_q - let challenge = positive_challenge_from_transcript(&mut local_transcript, &k256_order())?; + let challenge = positive_challenge_from_transcript(&mut local_transcript, &C::curve_order())?; // Create a response by masking the secret with the challenge and mask let response = com.randomness_for_commitment.modadd( - &challenge.modmul(secret.discrete_logarithm, &k256_order()), - &k256_order(), + &challenge.modmul(secret.discrete_logarithm, &C::curve_order()), + &C::curve_order(), ); // Proof consists of all 3 messages in the 3 rounds @@ -225,11 +223,11 @@ impl PiSchProof { let pisch_proofs: Vec> = deserialize!(&message.unverified_bytes)?; for pisch_proof in &pisch_proofs { - if pisch_proof.challenge >= k256_order() { + if pisch_proof.challenge >= C::curve_order() { error!("the challenge is not in the field"); return Err(InternalError::ProtocolError(None)); } - if pisch_proof.response >= k256_order() { + if pisch_proof.response >= C::curve_order() { error!("the response is not in the field"); return Err(InternalError::ProtocolError(None)); } @@ -241,11 +239,11 @@ impl PiSchProof { message.check_type(MessageType::Keygen(KeygenMessageType::R3Proof))?; let pisch_proof: PiSchProof = deserialize!(&message.unverified_bytes)?; - if pisch_proof.challenge >= k256_order() { + if pisch_proof.challenge >= C::curve_order() { error!("the challenge is not in the field"); return Err(InternalError::ProtocolError(None)); } - if pisch_proof.response >= k256_order() { + if pisch_proof.response >= C::curve_order() { error!("the response is not in the field"); return Err(InternalError::ProtocolError(None)); } @@ -279,8 +277,8 @@ mod tests { additive: bool, test_code: impl Fn(PiSchProof, CommonInput) -> Result<()>, ) -> Result<()> { - let q = k256_order(); - let g = CurvePoint::GENERATOR; + let q = CurvePoint::curve_order(); + let g = CurvePoint::generator(); let mut x = random_positive_bn(rng, &q); let x_commit = g.multiply_by_bignum(&x)?; @@ -301,8 +299,8 @@ mod tests { fn proof_commitment_field_must_match_input() -> Result<()> { let mut rng = init_testing(); - let q = k256_order(); - let g = CurvePoint::GENERATOR; + let q = CurvePoint::curve_order(); + let g = CurvePoint::generator(); let x = random_positive_bn(&mut rng, &q); @@ -330,8 +328,8 @@ mod tests { fn proof_response_field_must_match_input() -> Result<()> { let mut rng = init_testing(); - let q = k256_order(); - let g = CurvePoint::GENERATOR; + let q = CurvePoint::curve_order(); + let g = CurvePoint::generator(); let x = random_positive_bn(&mut rng, &q); @@ -355,8 +353,8 @@ mod tests { fn generator_must_be_correct() -> Result<()> { let mut rng = init_testing(); - let q = k256_order(); - let g = CurvePoint::GENERATOR; + let q = CurvePoint::curve_order(); + let g = CurvePoint::generator(); let x = random_positive_bn(&mut rng, &q); @@ -380,8 +378,8 @@ mod tests { fn secret_input_must_be_the_same_proving_and_verifying() -> Result<()> { let mut rng = init_testing(); - let q = k256_order(); - let g = CurvePoint::GENERATOR; + let q = CurvePoint::curve_order(); + let g = CurvePoint::generator(); let x = random_positive_bn(&mut rng, &q); @@ -409,8 +407,8 @@ mod tests { fn common_input_must_be_the_same_proving_and_verifying() -> Result<()> { let mut rng = init_testing(); - let q = k256_order(); - let g = CurvePoint::GENERATOR; + let q = CurvePoint::curve_order(); + let g = CurvePoint::generator(); let x = random_positive_bn(&mut rng, &q); @@ -474,8 +472,8 @@ mod tests { fn test_precommit_proof() -> Result<()> { let mut rng = init_testing(); - let q = k256_order(); - let g = CurvePoint::GENERATOR; + let q = CurvePoint::curve_order(); + let g = CurvePoint::generator(); let x = random_positive_bn(&mut rng, &q); let x_commit = g.multiply_by_bignum(&x)?; From 8d35c4c89b01c954763144df064cdda50d24482d Mon Sep 17 00:00:00 2001 From: emmorais Date: Wed, 7 Aug 2024 09:31:48 -0300 Subject: [PATCH 29/36] Finish curve order replacement in pisch.rs --- src/zkp/pisch.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/zkp/pisch.rs b/src/zkp/pisch.rs index 97987bab..9c04a199 100644 --- a/src/zkp/pisch.rs +++ b/src/zkp/pisch.rs @@ -27,7 +27,7 @@ //! UC Non-Interactive, Proactive, Threshold ECDSA with Identifiable Aborts. //! [EPrint archive, 2021](https://eprint.iacr.org/2021/060.pdf). use crate::{ - curve_point::{k256_order, CurveTrait}, errors::*, messages::{KeygenMessageType, KeyrefreshMessageType, Message, MessageType}, utils::{positive_challenge_from_transcript, random_positive_bn}, zkp::{Proof, ProofContext} + curve_point::CurveTrait, errors::*, messages::{KeygenMessageType, KeyrefreshMessageType, Message, MessageType}, utils::{positive_challenge_from_transcript, random_positive_bn}, zkp::{Proof, ProofContext} }; use libpaillier::unknown_order::BigNumber; use merlin::Transcript; @@ -135,7 +135,7 @@ impl Proof for PiSchProof Self::fill_transcript(transcript, context, &input, &self.commitment)?; // Verifier samples e in F_q - let challenge = positive_challenge_from_transcript(transcript, &k256_order())?; + let challenge = positive_challenge_from_transcript(transcript, &C::curve_order())?; if challenge != self.challenge { error!("Fiat-Shamir consistency check failed"); return Err(InternalError::ProtocolError(None)); From 47d8a297ac809d3f784adf66ae6cabf904129972 Mon Sep 17 00:00:00 2001 From: emmorais Date: Wed, 7 Aug 2024 13:33:07 -0300 Subject: [PATCH 30/36] Replace order function in other places --- src/keygen/keyshare.rs | 14 +++++++------- src/keyrefresh/keyshare.rs | 24 ++++++++++++------------ src/presign/participant.rs | 4 ++-- src/protocol.rs | 10 ++++++---- src/utils.rs | 4 ++-- src/zkp/piaffg.rs | 6 +++--- src/zkp/pienc.rs | 4 ++-- src/zkp/pifac.rs | 4 ++-- src/zkp/pimod.rs | 16 ++++++---------- 9 files changed, 42 insertions(+), 44 deletions(-) diff --git a/src/keygen/keyshare.rs b/src/keygen/keyshare.rs index 1b96d53c..0ca34c5d 100644 --- a/src/keygen/keyshare.rs +++ b/src/keygen/keyshare.rs @@ -7,7 +7,7 @@ // of this source tree. use crate::{ - curve_point::{k256_order, CurveTrait}, errors::{CallerError, Result}, utils::ParseBytes, ParticipantIdentifier + curve_point::CurveTrait, errors::{CallerError, Result}, utils::ParseBytes, ParticipantIdentifier }; use libpaillier::unknown_order::BigNumber; use rand::{CryptoRng, RngCore}; @@ -39,14 +39,14 @@ impl Debug for KeySharePrivate { impl KeySharePrivate { /// Sample a private key share uniformly at random. pub(crate) fn random(rng: &mut (impl CryptoRng + RngCore)) -> Self { - let random_bn = BigNumber::from_rng(&k256_order(), rng); + let random_bn = BigNumber::from_rng(&C::curve_order(), rng); KeySharePrivate:: { x: random_bn, curve: std::marker::PhantomData } } /// Take a [`BigNumber`] as [`KeySharePrivate`]. `x_int` will be reduced /// modulo `q`. pub(crate) fn from_bigint(x_int: &BigNumber) -> Self { - let x = x_int.nmod(&k256_order()); + let x = x_int.nmod(&C::curve_order()); Self { x, curve: std::marker::PhantomData } } @@ -106,7 +106,7 @@ impl KeySharePrivate { // Check that the share itself is valid let share = BigNumber::from_slice(share_bytes); - if share >= k256_order() || share < BigNumber::one() { + if share >= C::curve_order() || share < BigNumber::one() { Err(CallerError::DeserializationFailed)? } @@ -187,7 +187,7 @@ impl AsRef for KeySharePublic { #[cfg(test)] mod tests { use crate::{ - curve_point::{k256_order, testing::init_testing, CurvePoint}, keygen::{keyshare::KEYSHARE_TAG, KeySharePrivate} + curve_point::{testing::init_testing, CurvePoint}, keygen::{keyshare::KEYSHARE_TAG, KeySharePrivate} }; #[test] @@ -205,7 +205,7 @@ mod tests { #[test] fn keyshare_private_bytes_must_be_in_range() { // Share must be < k256_order() - let too_big = KeySharePrivate:: { x: k256_order(), curve: std::marker::PhantomData }; + let too_big = KeySharePrivate:: { x: CurvePoint::curve_order(), curve: std::marker::PhantomData }; let bytes = too_big.into_bytes(); assert!(KeySharePrivate::::try_from_bytes(bytes).is_err()); @@ -280,7 +280,7 @@ mod tests { assert!(KeySharePrivate::::try_from_bytes(KEYSHARE_TAG.to_vec()).is_err()); // Length with no secret following doesn't pass - let share_len = k256_order().bit_length() / 8; + let share_len = CurvePoint::curve_order().bit_length() / 8; let bytes = [KEYSHARE_TAG, &share_len.to_le_bytes()].concat(); assert!(KeySharePrivate::::try_from_bytes(bytes).is_err()); diff --git a/src/keyrefresh/keyshare.rs b/src/keyrefresh/keyshare.rs index 5224164e..db4b3a97 100644 --- a/src/keyrefresh/keyshare.rs +++ b/src/keyrefresh/keyshare.rs @@ -7,7 +7,7 @@ // of this source tree. use crate::{ - curve_point::{k256_order, CurvePoint, CurveTrait}, errors::{CallerError, InternalError, Result}, keygen::{KeySharePrivate, KeySharePublic}, paillier::{Ciphertext, DecryptionKey, EncryptionKey}, ParticipantIdentifier + curve_point::{CurvePoint, CurveTrait}, errors::{CallerError, InternalError, Result}, keygen::{KeySharePrivate, KeySharePublic}, paillier::{Ciphertext, DecryptionKey, EncryptionKey}, ParticipantIdentifier }; use libpaillier::unknown_order::BigNumber; use rand::{CryptoRng, RngCore}; @@ -23,12 +23,12 @@ pub struct KeyUpdateEncrypted { } impl KeyUpdateEncrypted { - pub fn encrypt( - update: &KeyUpdatePrivate, + pub fn encrypt( + update: &KeyUpdatePrivate, pk: &EncryptionKey, rng: &mut R, ) -> Result { - if &(k256_order() * 2) >= pk.modulus() { + if &(C::curve_order() * 2) >= pk.modulus() { error!("KeyUpdateEncrypted encryption failed, pk.modulus() is too small"); Err(InternalError::InternalInvariantFailed)?; } @@ -40,12 +40,12 @@ impl KeyUpdateEncrypted { Ok(KeyUpdateEncrypted { ciphertext }) } - pub fn decrypt(&self, dk: &DecryptionKey) -> Result> { + pub fn decrypt(&self, dk: &DecryptionKey) -> Result> { let x = dk.decrypt(&self.ciphertext).map_err(|_| { error!("KeyUpdateEncrypted decryption failed, ciphertext out of range",); CallerError::DeserializationFailed })?; - if x >= k256_order() || x < BigNumber::one() { + if x >= C::curve_order() || x < BigNumber::one() { error!("KeyUpdateEncrypted decryption failed, plaintext out of range"); Err(CallerError::DeserializationFailed)?; } @@ -70,7 +70,7 @@ impl Debug for KeyUpdatePrivate { impl KeyUpdatePrivate { /// Sample a private key share uniformly at random. pub(crate) fn random(rng: &mut (impl CryptoRng + RngCore)) -> Self { - let random_bn = BigNumber::from_rng(&k256_order(), rng); + let random_bn = BigNumber::from_rng(&C::curve_order(), rng); KeyUpdatePrivate { x: random_bn, _curve: std::marker::PhantomData } } @@ -80,7 +80,7 @@ impl KeyUpdatePrivate { let sum = others .iter() .fold(BigNumber::zero(), |sum, o| sum + o.x.clone()); - let balance = (-sum).nmod(&k256_order()); + let balance = (-sum).nmod(&C::curve_order()); KeyUpdatePrivate { x: balance, _curve: std::marker::PhantomData } } @@ -88,7 +88,7 @@ impl KeyUpdatePrivate { let sum = shares .iter() .fold(BigNumber::zero(), |sum, o| sum + o.x.clone()) - .nmod(&k256_order()); + .nmod(&C::curve_order()); KeyUpdatePrivate { x: sum, _curve: std::marker::PhantomData } } @@ -199,7 +199,7 @@ mod tests { use super::*; use crate::{ auxinfo, - curve_point::{k256_order, testing::init_testing}, + curve_point::testing::init_testing, }; use rand::rngs::StdRng; @@ -211,7 +211,7 @@ mod tests { let dk = auxinfo.private_auxinfo().decryption_key(); let pk = auxinfo.find_public(pid).unwrap().pk(); assert!( - &(k256_order() * 2) < pk.modulus(), + &(CurvePoint::curve_order() * 2) < pk.modulus(), "the Paillier modulus is supposed to be much larger than the k256 order" ); (rng, pk.clone(), dk.clone()) @@ -236,7 +236,7 @@ mod tests { let rng = &mut rng; // Encrypt invalid shares. - for x in [BigNumber::zero(), -BigNumber::one(), k256_order()].iter() { + for x in [BigNumber::zero(), -BigNumber::one(), CurvePoint::curve_order()].iter() { let share = KeyUpdatePrivate:: { x: x.clone(), _curve: std::marker::PhantomData }; let encrypted = KeyUpdateEncrypted::encrypt(&share, &pk, rng).expect("encryption failed"); diff --git a/src/presign/participant.rs b/src/presign/participant.rs index 40f112df..c23f888e 100644 --- a/src/presign/participant.rs +++ b/src/presign/participant.rs @@ -915,7 +915,7 @@ impl PresignKeyShareAndInfo { HashMap, round_one::PublicBroadcast, )> { - let order = k256_order(); + let order = C::curve_order(); let k = random_positive_bn(rng, &order); let gamma = random_positive_bn(rng, &order); @@ -1106,7 +1106,7 @@ impl PresignKeyShareAndInfo { round_three::Private, HashMap>, )> { - let order = k256_order(); + let order = C::curve_order(); let g = C::generator(); let mut delta: BigNumber = sender_r1_priv.gamma.modmul(&sender_r1_priv.k, &order); diff --git a/src/protocol.rs b/src/protocol.rs index 04d90d65..0f1aa099 100644 --- a/src/protocol.rs +++ b/src/protocol.rs @@ -11,7 +11,7 @@ //! This module includes the main [`Participant`] driver. use crate::{ - curve_point::{k256_order, CurveTrait}, errors::{CallerError, InternalError, Result}, messages::{Message, MessageType}, participant::{InnerProtocolParticipant, ProtocolParticipant, Status}, protocol::participant_config::ParticipantConfig, zkp::ProofContext + curve_point::CurveTrait, errors::{CallerError, InternalError, Result}, messages::{Message, MessageType}, participant::{InnerProtocolParticipant, ProtocolParticipant, Status}, protocol::participant_config::ParticipantConfig, zkp::ProofContext }; use libpaillier::unknown_order::BigNumber; use rand::{CryptoRng, Rng, RngCore}; @@ -451,7 +451,7 @@ impl SharedContext { let participant2 = ParticipantIdentifier::random(rng); let participants = vec![participant, participant2]; let generator = C::generator(); - let order = k256_order(); + let order = C::curve_order(); SharedContext:: { sid, participants, @@ -464,7 +464,7 @@ impl SharedContext { let mut participants = p.all_participants(); participants.sort(); let generator = C::generator(); - let order = k256_order(); + let order = C::curve_order(); SharedContext:: { sid: p.sid(), participants, @@ -474,13 +474,15 @@ impl SharedContext { } #[cfg(test)] pub fn fill_context(mut participants: Vec, sid: Identifier) -> Self { + use crate::curve_point::CurvePoint; + participants.sort(); let generator = C::generator(); SharedContext:: { sid, participants, generator, - order: k256_order(), + order: CurvePoint::curve_order(), } } } diff --git a/src/utils.rs b/src/utils.rs index bfcb46c8..4d5eb043 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -6,7 +6,7 @@ // License, Version 2.0 found in the LICENSE-APACHE file in the root directory // of this source tree. -use crate::curve_point::k256_order; +use crate::curve_point::CurvePoint; use crate::errors::{CallerError, InternalError, Result}; use libpaillier::unknown_order::BigNumber; use merlin::Transcript; @@ -154,7 +154,7 @@ pub(crate) fn plusminus_challenge_from_transcript( // The sampling method samples from the open interval, so add 1 to sample from // the _closed_ interval we want here. - let q = k256_order(); + let q = CurvePoint::curve_order(); let open_interval_max = &q + 1; let b = positive_challenge_from_transcript(transcript, &open_interval_max)?; Ok(match is_neg { diff --git a/src/zkp/piaffg.rs b/src/zkp/piaffg.rs index b35f8b4b..84bf5e72 100644 --- a/src/zkp/piaffg.rs +++ b/src/zkp/piaffg.rs @@ -544,7 +544,7 @@ mod tests { use super::*; use crate::{ paillier::DecryptionKey, - curve_point::{k256_order, testing::init_testing}, + curve_point::testing::init_testing, utils::{random_plusminus, random_plusminus_by_size_with_minimum}, zkp::BadContext, }; @@ -839,7 +839,7 @@ mod tests { let secret = PiAffgSecret::new(&x, &y, &rho, &rho_y); // Generate some random elements to use as replacements - let random_bignumber = random_plusminus(&mut rng, &k256_order()); + let random_bignumber = random_plusminus(&mut rng, &CurvePoint::curve_order()); let random_nonce = Nonce::random(&mut rng, input.prover_encryption_key.modulus()); // Swap multi coefficient with a random [`BigNumber`] @@ -915,7 +915,7 @@ mod tests { // Swap challenge with a random [`Bignumber`] let mut bad_proof = proof.clone(); - bad_proof.challenge = random_plusminus(&mut rng, &k256_order()); + bad_proof.challenge = random_plusminus(&mut rng, &CurvePoint::curve_order()); assert_ne!(bad_proof.challenge, proof.challenge); assert!(bad_proof.verify(input, &(), &mut transcript()).is_err()); diff --git a/src/zkp/pienc.rs b/src/zkp/pienc.rs index 3c680f20..e932a1bc 100644 --- a/src/zkp/pienc.rs +++ b/src/zkp/pienc.rs @@ -288,7 +288,7 @@ impl PiEncProof { mod tests { use super::*; use crate::{ - curve_point::{k256_order, testing::init_testing}, paillier::DecryptionKey, utils::{random_plusminus, random_plusminus_by_size_with_minimum, random_positive_bn}, zkp::BadContext + curve_point::{testing::init_testing, CurvePoint}, paillier::DecryptionKey, utils::{random_plusminus, random_plusminus_by_size_with_minimum, random_positive_bn}, zkp::BadContext }; use rand::{rngs::StdRng, Rng, SeedableRng}; @@ -456,7 +456,7 @@ mod tests { // Bad challenge fails { let mut bad_proof = proof.clone(); - bad_proof.challenge = random_plusminus(rng2, &k256_order()); + bad_proof.challenge = random_plusminus(rng2, &CurvePoint::curve_order()); assert_ne!(bad_proof.challenge, proof.challenge); assert!(bad_proof.verify(input, &(), &mut transcript()).is_err()); } diff --git a/src/zkp/pifac.rs b/src/zkp/pifac.rs index 86f27b8f..cfe15d20 100644 --- a/src/zkp/pifac.rs +++ b/src/zkp/pifac.rs @@ -328,7 +328,7 @@ fn sqrt(num: &BigNumber) -> BigNumber { #[cfg(test)] mod tests { use crate::{ - curve_point::{k256_order, testing::init_testing}, paillier::prime_gen, utils::random_positive_bn, zkp::BadContext + curve_point::{testing::init_testing, CurvePoint}, paillier::prime_gen, utils::random_positive_bn, zkp::BadContext }; use rand::{prelude::StdRng, Rng, SeedableRng}; @@ -522,7 +522,7 @@ mod tests { let mut rng2 = StdRng::from_seed(rng.gen()); let proof_elements_must_be_correct = |input: CommonInput, proof: PiFacProof| { let mut incorrect_proof = proof.clone(); - let random_bignumber = random_positive_bn(&mut rng, &k256_order()); + let random_bignumber = random_positive_bn(&mut rng, &CurvePoint::curve_order()); incorrect_proof.p_masked = random_bignumber.clone(); assert!(incorrect_proof .verify(input, &(), &mut transcript()) diff --git a/src/zkp/pimod.rs b/src/zkp/pimod.rs index a6a6d58c..2d7b7ab2 100644 --- a/src/zkp/pimod.rs +++ b/src/zkp/pimod.rs @@ -475,14 +475,10 @@ fn y_prime_combinations( #[cfg(test)] mod tests { use rand::{rngs::StdRng, Rng}; - use crate::curve_point::k256_order; use super::*; use crate::{ - paillier::{prime_gen, DecryptionKey}, - parameters::SOUNDNESS_PARAMETER, - curve_point::testing::init_testing, - zkp::BadContext, + curve_point::{testing::init_testing, CurvePoint}, paillier::{prime_gen, DecryptionKey}, parameters::SOUNDNESS_PARAMETER, zkp::BadContext }; fn transcript() -> Transcript { @@ -824,7 +820,7 @@ mod tests { #[test] fn challenges_must_be_derived_from_transcript() -> Result<()> { let test_fn: TestFn = |mut proof, input, mut rng| { - let new_challenge = random_positive_bn(&mut rng, &k256_order()); + let new_challenge = random_positive_bn(&mut rng, &CurvePoint::curve_order()); if let Some(first_element) = proof.elements.get_mut(0) { first_element.challenge = new_challenge; } else { @@ -841,7 +837,7 @@ mod tests { #[test] fn commitment_must_be_correct() -> Result<()> { let test_fn: TestFn = |mut proof: PiModProof, input, mut rng| { - proof.random_jacobi_one = random_positive_bn(&mut rng, &k256_order()); + proof.random_jacobi_one = random_positive_bn(&mut rng, &CurvePoint::curve_order()); assert!(proof.verify(input, &(), &mut transcript()).is_err()); Ok(()) }; @@ -854,7 +850,7 @@ mod tests { fn responses_must_be_correct() -> Result<()> { let test_fn: TestFn = |proof: PiModProof, input: CommonInput, mut rng| { // Challenge-secret link must be correct - let new_challenge_secret_link = random_positive_bn(&mut rng, &k256_order()); + let new_challenge_secret_link = random_positive_bn(&mut rng, &CurvePoint::curve_order()); let mut bad_proof = proof.clone(); if let Some(first_element) = bad_proof.elements.get_mut(0) { first_element.challenge_secret_link = new_challenge_secret_link; @@ -884,7 +880,7 @@ mod tests { assert!(bad_proof.verify(input, &(), &mut transcript()).is_err()); // Fourth root must be correct - let new_fourth_root = random_positive_bn(&mut rng, &k256_order()); + let new_fourth_root = random_positive_bn(&mut rng, &CurvePoint::curve_order()); let mut bad_proof = proof.clone(); if let Some(first_element) = bad_proof.elements.get_mut(0) { first_element.fourth_root = new_fourth_root; @@ -901,7 +897,7 @@ mod tests { #[test] fn common_input_must_be_same_for_proving_and_verifying() -> Result<()> { let test_fn: TestFn = |proof: PiModProof, input, mut rng| { - let random_bn = random_positive_bn(&mut rng, &k256_order()); + let random_bn = random_positive_bn(&mut rng, &CurvePoint::curve_order()); let bad_input = CommonInput::new(&random_bn); assert_ne!(input, bad_input); assert!(proof.verify(bad_input, &(), &mut transcript()).is_err()); From 273c11c72ecbe0f42a9c390c4bb1b40914eadecc Mon Sep 17 00:00:00 2001 From: emmorais Date: Wed, 7 Aug 2024 13:41:42 -0300 Subject: [PATCH 31/36] Finish replacement of order function --- src/curve_point.rs | 4 +++- src/keyrefresh/keyshare.rs | 4 ++-- src/presign/participant.rs | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/curve_point.rs b/src/curve_point.rs index b8f9cf70..7ea9153b 100644 --- a/src/curve_point.rs +++ b/src/curve_point.rs @@ -202,7 +202,9 @@ impl CurveTrait for CurvePoint { } fn curve_order() -> BigNumber { - k256_order() + // Set order = q + let order_bytes: [u8; 32] = CurvePoint::ORDER.to_be_bytes(); + BigNumber::from_slice(order_bytes) } fn multiply_by_bignum(&self, point: &BigNumber) -> Result { diff --git a/src/keyrefresh/keyshare.rs b/src/keyrefresh/keyshare.rs index db4b3a97..860830ca 100644 --- a/src/keyrefresh/keyshare.rs +++ b/src/keyrefresh/keyshare.rs @@ -7,7 +7,7 @@ // of this source tree. use crate::{ - curve_point::{CurvePoint, CurveTrait}, errors::{CallerError, InternalError, Result}, keygen::{KeySharePrivate, KeySharePublic}, paillier::{Ciphertext, DecryptionKey, EncryptionKey}, ParticipantIdentifier + curve_point::CurveTrait, errors::{CallerError, InternalError, Result}, keygen::{KeySharePrivate, KeySharePublic}, paillier::{Ciphertext, DecryptionKey, EncryptionKey}, ParticipantIdentifier }; use libpaillier::unknown_order::BigNumber; use rand::{CryptoRng, RngCore}; @@ -199,7 +199,7 @@ mod tests { use super::*; use crate::{ auxinfo, - curve_point::testing::init_testing, + curve_point::{testing::init_testing, CurvePoint}, }; use rand::rngs::StdRng; diff --git a/src/presign/participant.rs b/src/presign/participant.rs index c23f888e..e44fabc2 100644 --- a/src/presign/participant.rs +++ b/src/presign/participant.rs @@ -9,7 +9,7 @@ // of this source tree. use crate::{ - auxinfo::{AuxInfoPrivate, AuxInfoPublic}, broadcast::participant::{BroadcastOutput, BroadcastParticipant, BroadcastTag}, curve_point::{bn_to_scalar, k256_order, CurvePoint, CurveTrait}, errors::{CallerError, InternalError, Result}, keygen::{KeySharePrivate, KeySharePublic}, local_storage::LocalStorage, messages::{Message, MessageType, PresignMessageType}, parameters::ELL_PRIME, participant::{Broadcast, InnerProtocolParticipant, ProcessOutcome, ProtocolParticipant}, presign::{ + auxinfo::{AuxInfoPrivate, AuxInfoPublic}, broadcast::participant::{BroadcastOutput, BroadcastParticipant, BroadcastTag}, curve_point::{bn_to_scalar, CurvePoint, CurveTrait}, errors::{CallerError, InternalError, Result}, keygen::{KeySharePrivate, KeySharePublic}, local_storage::LocalStorage, messages::{Message, MessageType, PresignMessageType}, parameters::ELL_PRIME, participant::{Broadcast, InnerProtocolParticipant, ProcessOutcome, ProtocolParticipant}, presign::{ input::Input, record::{PresignRecord, RecordPair}, round_one, round_three, round_two, From 0bf3db44655abe2b1613d271c93663765e7bbd77 Mon Sep 17 00:00:00 2001 From: emmorais Date: Wed, 7 Aug 2024 14:22:45 -0300 Subject: [PATCH 32/36] Abstract bn_to_scalar in CurveTrait --- src/curve_point.rs | 41 ++++++++++++++++++-- src/presign/participant.rs | 10 ++--- src/presign/record.rs | 8 ++-- src/sign/non_interactive_sign/participant.rs | 4 +- 4 files changed, 48 insertions(+), 15 deletions(-) diff --git a/src/curve_point.rs b/src/curve_point.rs index 7ea9153b..9a605c55 100644 --- a/src/curve_point.rs +++ b/src/curve_point.rs @@ -71,13 +71,40 @@ impl<'de> CurvePoint { /// converting it. This may be insecure if the point contains private /// data. pub(crate) fn multiply_by_bignum(&self, point: &BigNumber) -> Result { - Ok(self.multiply_by_scalar(&bn_to_scalar(point)?)) + Ok(self.multiply_by_scalar(&Self::bn_to_scalar(point)?)) } pub(crate) fn multiply_by_scalar(&self, point: &Scalar) -> Self { Self(self.0 * point) } + fn bn_to_scalar(x: &BigNumber) -> Result { + + // Take (mod q) + let order = Self::curve_order(); + + let x_modded = x % order; + let bytes = x_modded.to_bytes(); + + let mut slice = vec![0u8; 32 - bytes.len()]; + slice.extend_from_slice(&bytes); + let mut ret: k256::Scalar = Option::from(k256::Scalar::from_repr( + GenericArray::clone_from_slice(&slice), + )) + .ok_or_else(|| { + error!("Failed to convert BigNumber into k256::Scalar"); + InternalError::InternalInvariantFailed + })?; + + // Make sure to negate the scalar if the original input was negative + if x < &BigNumber::zero() { + ret = ret.negate(); + } + + Ok(ret) + + } + /// Serialize the `CurvePoint` as an affine-encoded secp256k1 byte array. pub(crate) fn to_bytes(self) -> Vec { let mut generic_array = AffinePoint::::from(self.0).to_bytes(); @@ -188,6 +215,8 @@ pub trait CurveTrait: Serialize + Clone + Debug + Eq + PartialEq + Zeroize + Add fn curve_order() -> BigNumber; fn multiply_by_bignum(&self, point: &BigNumber) -> Result where Self: Sized; + + fn bn_to_scalar(x: &BigNumber) -> Result; } /// Implement the CurveTrait for the CurvePoint @@ -210,11 +239,15 @@ impl CurveTrait for CurvePoint { fn multiply_by_bignum(&self, point: &BigNumber) -> Result { self.multiply_by_bignum(point) } + + fn bn_to_scalar(x: &BigNumber) -> Result { + CurvePoint::bn_to_scalar(x) + } } // Returns x: BigNumber as a k256::Scalar mod k256_order //pub(crate) fn bn_to_scalar(x: &BigNumber) -> Result { -pub(crate) fn bn_to_scalar(x: &BigNumber) -> Result { +/*pub(crate) fn bn_to_scalar(x: &BigNumber) -> Result { // Take (mod q) //let order = C::curve_order(); // Call curve_order() to get the order of the curve @@ -239,7 +272,7 @@ pub(crate) fn bn_to_scalar(x: &BigNumber) -> Result { } Ok(ret) -} +}*/ pub(crate) fn k256_order() -> BigNumber { // Set order = q @@ -277,7 +310,7 @@ mod tests { let neg1 = BigNumber::zero() - BigNumber::one(); //let scalar = bn_to_scalar::(&neg1).unwrap(); - let scalar = bn_to_scalar(&neg1).unwrap(); + let scalar = CurvePoint::bn_to_scalar(&neg1).unwrap(); assert_eq!(k256::Scalar::ZERO, scalar.add(&k256::Scalar::ONE)); } } diff --git a/src/presign/participant.rs b/src/presign/participant.rs index e44fabc2..3fc41720 100644 --- a/src/presign/participant.rs +++ b/src/presign/participant.rs @@ -9,7 +9,7 @@ // of this source tree. use crate::{ - auxinfo::{AuxInfoPrivate, AuxInfoPublic}, broadcast::participant::{BroadcastOutput, BroadcastParticipant, BroadcastTag}, curve_point::{bn_to_scalar, CurvePoint, CurveTrait}, errors::{CallerError, InternalError, Result}, keygen::{KeySharePrivate, KeySharePublic}, local_storage::LocalStorage, messages::{Message, MessageType, PresignMessageType}, parameters::ELL_PRIME, participant::{Broadcast, InnerProtocolParticipant, ProcessOutcome, ProtocolParticipant}, presign::{ + auxinfo::{AuxInfoPrivate, AuxInfoPublic}, broadcast::participant::{BroadcastOutput, BroadcastParticipant, BroadcastTag}, curve_point::{CurvePoint, CurveTrait}, errors::{CallerError, InternalError, Result}, keygen::{KeySharePrivate, KeySharePublic}, local_storage::LocalStorage, messages::{Message, MessageType, PresignMessageType}, parameters::ELL_PRIME, participant::{Broadcast, InnerProtocolParticipant, ProcessOutcome, ProtocolParticipant}, presign::{ input::Input, record::{PresignRecord, RecordPair}, round_one, round_three, round_two, @@ -1154,8 +1154,8 @@ impl PresignKeyShareAndInfo { let Delta = Gamma.multiply_by_bignum(&sender_r1_priv.k)?; - let delta_scalar = bn_to_scalar(&delta)?; - let chi_scalar = bn_to_scalar(&chi)?; + let delta_scalar = C::bn_to_scalar(&delta)?; + let chi_scalar = C::bn_to_scalar(&chi)?; let mut ret_publics = HashMap::new(); for (other_id, round_three_input) in other_participant_inputs { @@ -1216,7 +1216,7 @@ mod test { messages::{Message, MessageType, PresignMessageType}, participant::{ProcessOutcome, Status}, presign::{Input, PresignRecord}, - curve_point::{self, testing::init_testing, CurvePoint}, + curve_point::{testing::init_testing, CurvePoint}, Identifier, ParticipantConfig, ParticipantIdentifier, ProtocolParticipant, }; @@ -1294,7 +1294,7 @@ mod test { .map(|output| output.private_key_share()) .fold(BigNumber::zero(), |sum, key_share| sum + key_share.as_ref()); // Converting to scalars automatically gets us the mod q - assert_eq!(masked_key, curve_point::bn_to_scalar(&secret_key).unwrap() * mask); + assert_eq!(masked_key, CurvePoint::bn_to_scalar(&secret_key).unwrap() * mask); } #[test] diff --git a/src/presign/record.rs b/src/presign/record.rs index e02abd99..7da41b10 100644 --- a/src/presign/record.rs +++ b/src/presign/record.rs @@ -7,7 +7,7 @@ // of this source tree. use crate::{ - curve_point::{bn_to_scalar, CurvePoint, CurveTrait}, errors::{ + curve_point::{CurvePoint, CurveTrait}, errors::{ CallerError, InternalError::{InternalInvariantFailed, ProtocolError}, Result, @@ -95,7 +95,7 @@ impl TryFrom> for PresignRecord { Ok(PresignRecord { R, - k: bn_to_scalar(&private.k)?, + k: C::bn_to_scalar(&private.k)?, chi: private.chi, }) } @@ -252,7 +252,7 @@ mod tests { use rand::{rngs::StdRng, CryptoRng, Rng, RngCore, SeedableRng}; use crate::{ - curve_point::{bn_to_scalar, testing::init_testing, CurvePoint, CurveTrait}, keygen, presign::{participant::presign_record_set_is_valid, record::RECORD_TAG}, ParticipantConfig, PresignRecord + curve_point::{testing::init_testing, CurvePoint, CurveTrait}, keygen, presign::{participant::presign_record_set_is_valid, record::RECORD_TAG}, ParticipantConfig, PresignRecord }; impl PresignRecord { @@ -297,7 +297,7 @@ mod tests { // Compute the masked key shares as (secret_key_share * mask) let masked_key_shares = keygen_outputs .iter() - .map(|output| bn_to_scalar(output.private_key_share().as_ref()).unwrap()) + .map(|output| CurvePoint::bn_to_scalar(output.private_key_share().as_ref()).unwrap()) .map(|secret_key_share| secret_key_share * mask); assert_eq!(masked_key_shares.len(), keygen_outputs.len()); diff --git a/src/sign/non_interactive_sign/participant.rs b/src/sign/non_interactive_sign/participant.rs index 4de2d365..a2805e18 100644 --- a/src/sign/non_interactive_sign/participant.rs +++ b/src/sign/non_interactive_sign/participant.rs @@ -438,7 +438,7 @@ mod test { use tracing::debug; use crate::{ - curve_point::{bn_to_scalar, testing::init_testing, CurvePoint}, errors::Result, keygen, messages::{Message, MessageType}, participant::{ProcessOutcome, Status}, presign::PresignRecord, sign::{self, Signature}, Identifier, ParticipantConfig, ProtocolParticipant + curve_point::{testing::init_testing, CurvePoint}, errors::Result, keygen, messages::{Message, MessageType}, participant::{ProcessOutcome, Status}, presign::PresignRecord, sign::{self, Signature}, Identifier, ParticipantConfig, ProtocolParticipant }; use super::SignParticipant; @@ -494,7 +494,7 @@ mod test { let secret_key = keygen_outputs .iter() - .map(|output| bn_to_scalar(output.private_key_share().as_ref()).unwrap()) + .map(|output| CurvePoint::bn_to_scalar(output.private_key_share().as_ref()).unwrap()) .fold(Scalar::ZERO, |a, b| a + b); let r = records[0].x_projection().unwrap(); From 5b7fbca389efa2238f2b5346027300d643b6002d Mon Sep 17 00:00:00 2001 From: emmorais Date: Wed, 7 Aug 2024 14:27:27 -0300 Subject: [PATCH 33/36] Remove unneeded code --- src/curve_point.rs | 36 +----------------------------------- 1 file changed, 1 insertion(+), 35 deletions(-) diff --git a/src/curve_point.rs b/src/curve_point.rs index 9a605c55..427d9eac 100644 --- a/src/curve_point.rs +++ b/src/curve_point.rs @@ -78,6 +78,7 @@ impl<'de> CurvePoint { Self(self.0 * point) } + // Returns x: BigNumber as a k256::Scalar mod k256_order fn bn_to_scalar(x: &BigNumber) -> Result { // Take (mod q) @@ -245,41 +246,6 @@ impl CurveTrait for CurvePoint { } } -// Returns x: BigNumber as a k256::Scalar mod k256_order -//pub(crate) fn bn_to_scalar(x: &BigNumber) -> Result { -/*pub(crate) fn bn_to_scalar(x: &BigNumber) -> Result { - // Take (mod q) - //let order = C::curve_order(); - // Call curve_order() to get the order of the curve - let order = k256_order(); - - let x_modded = x % order; - let bytes = x_modded.to_bytes(); - - let mut slice = vec![0u8; 32 - bytes.len()]; - slice.extend_from_slice(&bytes); - let mut ret: k256::Scalar = Option::from(k256::Scalar::from_repr( - GenericArray::clone_from_slice(&slice), - )) - .ok_or_else(|| { - error!("Failed to convert BigNumber into k256::Scalar"); - InternalError::InternalInvariantFailed - })?; - - // Make sure to negate the scalar if the original input was negative - if x < &BigNumber::zero() { - ret = ret.negate(); - } - - Ok(ret) -}*/ - -pub(crate) fn k256_order() -> BigNumber { - // Set order = q - let order_bytes: [u8; 32] = k256::Secp256k1::ORDER.to_be_bytes(); - BigNumber::from_slice(order_bytes) -} - #[cfg(test)] mod tests { use super::*; From f49fe20b8f16d694a7d814633f102cd183c3e11f Mon Sep 17 00:00:00 2001 From: emmorais Date: Wed, 7 Aug 2024 18:15:49 -0300 Subject: [PATCH 34/36] Some adjustments --- src/presign/record.rs | 2 +- src/zkp/piaffg.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/presign/record.rs b/src/presign/record.rs index 7da41b10..6cc17997 100644 --- a/src/presign/record.rs +++ b/src/presign/record.rs @@ -81,7 +81,7 @@ impl TryFrom> for PresignRecord { Delta = Delta + p.Delta; } - let g = CurvePoint::GENERATOR; + let g = C::generator(); if g.multiply_by_scalar(&delta) != Delta { error!("Could not create PresignRecord: mismatch between calculated private and public deltas"); return Err(ProtocolError(None)); diff --git a/src/zkp/piaffg.rs b/src/zkp/piaffg.rs index 84bf5e72..18461c48 100644 --- a/src/zkp/piaffg.rs +++ b/src/zkp/piaffg.rs @@ -419,7 +419,7 @@ impl Proof for PiAffgProof { } // Check that the masked group exponentiation is valid. let masked_group_exponentiation_is_valid = { - let lhs = CurvePoint::GENERATOR.multiply_by_bignum(&self.masked_mult_coeff)?; + let lhs = C::GENERATOR.multiply_by_bignum(&self.masked_mult_coeff)?; let rhs = self.random_mult_coeff_exp + input.mult_coeff_exp.multiply_by_bignum(&self.challenge)?; lhs == rhs From dd372402c0e39f4188026a83c003f3af69f92443 Mon Sep 17 00:00:00 2001 From: emmorais Date: Fri, 9 Aug 2024 08:11:46 -0300 Subject: [PATCH 35/36] Fixing errors --- src/curve_point.rs | 28 +++++++- src/keygen/keyshare.rs | 2 +- src/keyrefresh/input.rs | 4 +- src/keyrefresh/keyshare.rs | 4 +- src/keyrefresh/participant.rs | 83 ++++++++++++++---------- src/presign/input.rs | 2 +- src/presign/participant.rs | 56 +++++++++------- src/presign/record.rs | 6 +- src/presign/round_one.rs | 6 +- src/presign/round_three.rs | 10 +-- src/sign/interactive_sign/participant.rs | 2 +- src/utils.rs | 2 +- src/zkp/piaffg.rs | 10 +-- src/zkp/pilog.rs | 2 +- src/zkp/pimod.rs | 1 + src/zkp/pisch.rs | 3 +- 16 files changed, 129 insertions(+), 92 deletions(-) diff --git a/src/curve_point.rs b/src/curve_point.rs index 427d9eac..61895bf6 100644 --- a/src/curve_point.rs +++ b/src/curve_point.rs @@ -79,7 +79,7 @@ impl<'de> CurvePoint { } // Returns x: BigNumber as a k256::Scalar mod k256_order - fn bn_to_scalar(x: &BigNumber) -> Result { + pub(crate) fn bn_to_scalar(x: &BigNumber) -> Result { // Take (mod q) let order = Self::curve_order(); @@ -206,7 +206,7 @@ pub(crate) fn random_bn_in_z_star( } /// Common trait for curves -pub trait CurveTrait: Serialize + Clone + Debug + Eq + PartialEq + Zeroize + Add { +pub trait CurveTrait: Serialize + Clone + Debug + Eq + PartialEq + Zeroize + Add + Sync + Send{ /// Returns the generator of the curve fn generator() -> Self; /// Returns the identity element of the curve @@ -215,9 +215,17 @@ pub trait CurveTrait: Serialize + Clone + Debug + Eq + PartialEq + Zeroize + Add /// return the order of the curve fn curve_order() -> BigNumber; + fn x_affine(&self) -> FieldBytes; + fn multiply_by_bignum(&self, point: &BigNumber) -> Result where Self: Sized; + fn multiply_by_scalar(&self, point: &Scalar) -> Self; + fn bn_to_scalar(x: &BigNumber) -> Result; + + fn to_bytes(self) -> Vec; + + fn try_from_bytes(bytes: &[u8]) -> Result; } /// Implement the CurveTrait for the CurvePoint @@ -237,13 +245,29 @@ impl CurveTrait for CurvePoint { BigNumber::from_slice(order_bytes) } + fn x_affine(&self) -> FieldBytes { + self.x_affine() + } + fn multiply_by_bignum(&self, point: &BigNumber) -> Result { self.multiply_by_bignum(point) } + + fn multiply_by_scalar(&self, point: &Scalar) -> Self { + self.multiply_by_scalar(point) + } fn bn_to_scalar(x: &BigNumber) -> Result { CurvePoint::bn_to_scalar(x) } + + fn to_bytes(self) -> Vec { + self.to_bytes() + } + + fn try_from_bytes(bytes: &[u8]) -> Result { + CurvePoint::try_from_bytes(bytes) + } } #[cfg(test)] diff --git a/src/keygen/keyshare.rs b/src/keygen/keyshare.rs index 0ca34c5d..d5705889 100644 --- a/src/keygen/keyshare.rs +++ b/src/keygen/keyshare.rs @@ -187,7 +187,7 @@ impl AsRef for KeySharePublic { #[cfg(test)] mod tests { use crate::{ - curve_point::{testing::init_testing, CurvePoint}, keygen::{keyshare::KEYSHARE_TAG, KeySharePrivate} + curve_point::{CurveTrait, testing::init_testing, CurvePoint}, keygen::{keyshare::KEYSHARE_TAG, KeySharePrivate} }; #[test] diff --git a/src/keyrefresh/input.rs b/src/keyrefresh/input.rs index 26c534ba..abe25337 100644 --- a/src/keyrefresh/input.rs +++ b/src/keyrefresh/input.rs @@ -128,7 +128,7 @@ mod test { let config = ParticipantConfig::random(5, rng); let pids = config.all_participants(); assert_eq!(pids.last().unwrap(), &config.id()); - let keygen_output = keygen::Output::simulate(&pids, rng); + let keygen_output: Output = keygen::Output::simulate(&pids, rng); let auxinfo_output = auxinfo::Output::simulate(&pids, rng); // Same length works @@ -136,7 +136,7 @@ mod test { assert!(result.is_ok()); // If keygen is too short, it fails. - let short_keygen = keygen::Output::simulate(&pids[1..], rng); + let short_keygen: Output = keygen::Output::simulate(&pids[1..], rng); let result = Input::new(auxinfo_output, short_keygen); assert!(result.is_err()); assert_eq!( diff --git a/src/keyrefresh/keyshare.rs b/src/keyrefresh/keyshare.rs index 860830ca..56632e7f 100644 --- a/src/keyrefresh/keyshare.rs +++ b/src/keyrefresh/keyshare.rs @@ -223,7 +223,7 @@ mod tests { let rng = &mut rng; // Encryption round-trip. - let share = KeyUpdatePrivate::random(rng); + let share: KeyUpdatePrivate = KeyUpdatePrivate::random(rng); let encrypted = KeyUpdateEncrypted::encrypt(&share, &pk, rng).expect("encryption failed"); let decrypted = encrypted.decrypt(&dk).expect("decryption failed"); @@ -241,7 +241,7 @@ mod tests { let encrypted = KeyUpdateEncrypted::encrypt(&share, &pk, rng).expect("encryption failed"); // Decryption reports an error. - let decrypt_result = encrypted.decrypt(&dk); + let decrypt_result = encrypted.decrypt::(&dk); assert!(decrypt_result.is_err()); } } diff --git a/src/keyrefresh/participant.rs b/src/keyrefresh/participant.rs index 062fb167..9a70cbaa 100644 --- a/src/keyrefresh/participant.rs +++ b/src/keyrefresh/participant.rs @@ -24,6 +24,8 @@ use tracing::{error, info, instrument, warn}; use super::{input::Input, Output}; mod storage { + use k256::elliptic_curve::Curve; + use super::*; use crate::local_storage::TypeTag; @@ -38,17 +40,23 @@ mod storage { impl TypeTag for Decommit { type Value = KeyrefreshDecommit; } - pub(super) struct VecSchnorrPrecom; - impl TypeTag for VecSchnorrPrecom { - type Value = Vec>; + pub(super) struct VecSchnorrPrecom { + /// Marker for the curve type. + curve: std::marker::PhantomData, + } + impl TypeTag for VecSchnorrPrecom { + type Value = Vec>; } pub(super) struct GlobalRid; impl TypeTag for GlobalRid { type Value = [u8; 32]; } - pub(super) struct PrivateUpdatesForOthers; - impl TypeTag for PrivateUpdatesForOthers { - type Value = Vec>; + pub(super) struct PrivateUpdatesForOthers { + /// Marker for the curve type. + curve: std::marker::PhantomData, + } + impl TypeTag for PrivateUpdatesForOthers { + type Value = Vec>; } pub(super) struct ValidPublicUpdates { /// Marker for the curve type. @@ -57,9 +65,12 @@ mod storage { impl TypeTag for ValidPublicUpdates { type Value = Vec>; } - pub(super) struct ValidPrivateUpdate; - impl TypeTag for ValidPrivateUpdate { - type Value = super::KeyUpdatePrivate; + pub(super) struct ValidPrivateUpdate { + /// Marker for the curve type. + curve: std::marker::PhantomData, + } + impl TypeTag for ValidPrivateUpdate { + type Value = super::KeyUpdatePrivate; } } @@ -305,7 +316,7 @@ impl KeyrefreshParticipant { // This corresponds to `A_ij` in the paper. let sch_precoms = (0..update_publics.len()) - .map(|_| PiSchProof::::precommit(rng)) + .map(|_| PiSchProof::::precommit(rng)) .collect::>>()?; let decom = KeyrefreshDecommit::new( @@ -321,21 +332,21 @@ impl KeyrefreshParticipant { // Store the beginning of our proofs so we can continue the proofs later. self.local_storage - .store::(self.id(), sch_precoms); + .store::>(self.id(), sch_precoms); // Mark our own public updates as verified. self.local_storage - .store::>(self.id(), decom.update_publics.clone()); + .store::>(self.id(), decom.update_publics.clone()); // Store the private update from ourselves to ourselves. - self.local_storage.store::( + self.local_storage.store::>( self.id(), update_privates[update_privates.len() - 1].clone(), ); // Store the private updates from us to others so we can share them later. self.local_storage - .store::(self.id(), update_privates); + .store::>(self.id(), update_privates); // Mark our own commitment as ready. This corresponds to `V_i` in the paper. let com = decom.commit()?; @@ -344,7 +355,7 @@ impl KeyrefreshParticipant { // Store our committed values so we can open the commitment later. self.local_storage - .store::>(self.id(), decom); + .store::>(self.id(), decom); let messages = self.broadcast( rng, @@ -436,14 +447,14 @@ impl KeyrefreshParticipant { // `PublicKeyshare` and `Decommit`). This check forces that behavior. // Without it we'll get a `InternalInvariantFailed` error when trying to // retrieve `Decommit` below. - if !self.local_storage.contains::>(self.id()) { + if !self.local_storage.contains::>(self.id()) { let more_messages = run_only_once!(self.gen_round_one_msgs(rng, sid))?; messages.extend_from_slice(&more_messages); } let decom = self .local_storage - .retrieve::>(self.id())?; + .retrieve::>(self.id())?; let more_messages = self.message_for_other_participants( MessageType::Keyrefresh(KeyrefreshMessageType::R2Decommit), decom, @@ -462,7 +473,7 @@ impl KeyrefreshParticipant { rng: &mut R, message: &Message, ) -> Result::Output>> { - self.check_for_duplicate_msg::>(message.from())?; + self.check_for_duplicate_msg::>(message.from())?; info!("Handling round two keyrefresh message."); // We must receive all commitments in round 1 before we start processing @@ -482,12 +493,12 @@ impl KeyrefreshParticipant { .retrieve::(message.from())?; let decom = KeyrefreshDecommit::from_message(message, com, &self.all_participants())?; self.local_storage - .store_once::>(message.from(), decom)?; + .store_once::>(message.from(), decom)?; // Check if we've received all the decommits let r2_done = self .local_storage - .contains_for_all_ids::>(&self.all_participants()); + .contains_for_all_ids::>(&self.all_participants()); if r2_done { // Generate messages for round 3... @@ -532,7 +543,7 @@ impl KeyrefreshParticipant { // Construct `global rid` out of each participant's `rid`s. let my_rid = self .local_storage - .retrieve::>(self.id())? + .retrieve::>(self.id())? .rid; let rids: Vec<[u8; 32]> = self .other_ids() @@ -540,7 +551,7 @@ impl KeyrefreshParticipant { .map(|&other_participant_id| { let decom = self .local_storage - .retrieve::>(other_participant_id)?; + .retrieve::>(other_participant_id)?; Ok(decom.rid) }) .collect::>>()?; @@ -556,20 +567,20 @@ impl KeyrefreshParticipant { let decom = self .local_storage - .retrieve::>(self.id())?; + .retrieve::>(self.id())?; let transcript = schnorr_proof_transcript(self.sid(), &global_rid, self.id())?; // Generate proofs for each update. let precoms = self .local_storage - .retrieve::(self.id())?; + .retrieve::>(self.id())?; let private_updates = self .local_storage - .retrieve::(self.id())?; + .retrieve::>(self.id())?; - let mut proofs: Vec> = vec![]; + let mut proofs: Vec> = vec![]; for i in 0..precoms.len() { let pk = &decom.update_publics[i]; let input = CommonInput::new(pk); @@ -638,7 +649,7 @@ impl KeyrefreshParticipant { &mut self, message: &Message, ) -> Result::Output>> { - self.check_for_duplicate_msg::>(message.from())?; + self.check_for_duplicate_msg::>(message.from())?; if !self.can_handle_round_three_msg() { info!("Not yet ready to handle round three keyrefresh broadcast message."); @@ -651,10 +662,10 @@ impl KeyrefreshParticipant { .local_storage .retrieve::(self.id())?; - let proofs = PiSchProof::::from_message_multi(message)?; + let proofs = PiSchProof::::from_message_multi(message)?; let decom = self .local_storage - .retrieve::>(message.from())?; + .retrieve::>(message.from())?; // Check that there is one proof per participant. if proofs.len() != self.all_participants().len() { @@ -678,7 +689,7 @@ impl KeyrefreshParticipant { // Only if the proof verifies do we store the participant's updates. self.local_storage - .store_once::>( + .store_once::>( message.from(), decom.update_publics.clone(), )?; @@ -695,7 +706,7 @@ impl KeyrefreshParticipant { &mut self, message: &Message, ) -> Result::Output>> { - self.check_for_duplicate_msg::(message.from())?; + self.check_for_duplicate_msg::>(message.from())?; if !self.can_handle_round_three_msg() { info!("Not yet ready to handle round three keyrefresh private message."); @@ -720,7 +731,7 @@ impl KeyrefreshParticipant { let implied_public = update_private.public_point()?; let decom = self .local_storage - .retrieve::>(message.from())?; + .retrieve::>(message.from())?; let expected_public = decom .update_publics .iter() @@ -733,7 +744,7 @@ impl KeyrefreshParticipant { } self.local_storage - .store::(message.from(), update_private); + .store::>(message.from(), update_private); self.maybe_finish() } @@ -742,12 +753,12 @@ impl KeyrefreshParticipant { // Have we validated and stored the public updates from everybody to everybody? let got_all_public_updates = self .local_storage - .contains_for_all_ids::>(&self.all_participants()); + .contains_for_all_ids::>(&self.all_participants()); // Have we got the private updates from everybody to us? let got_all_private_updates = self .local_storage - .contains_for_all_ids::(&self.all_participants()); + .contains_for_all_ids::>(&self.all_participants()); // If so, we completed the protocol! Return the outputs. if got_all_public_updates && got_all_private_updates { @@ -784,7 +795,7 @@ impl KeyrefreshParticipant { .iter() .map(|pid| { self.local_storage - .remove::(*pid) + .remove::>(*pid) }) .collect::>>()?; let my_private_update = Self::aggregate_private_updates(&from_all_to_me_private); diff --git a/src/presign/input.rs b/src/presign/input.rs index a87f0da2..850108ef 100644 --- a/src/presign/input.rs +++ b/src/presign/input.rs @@ -173,7 +173,7 @@ mod test { assert!(result.is_ok()); // If keygen is too short, it fails. - let short_keygen = keygen::Output::simulate(&pids[1..], rng); + let short_keygen: Output = keygen::Output::simulate(&pids[1..], rng); let result = Input::new(auxinfo_output, short_keygen); assert!(result.is_err()); assert_eq!( diff --git a/src/presign/participant.rs b/src/presign/participant.rs index 3fc41720..2e2d7b9d 100644 --- a/src/presign/participant.rs +++ b/src/presign/participant.rs @@ -28,7 +28,7 @@ use tracing::{error, info, instrument}; // Local storage data types. mod storage { - use crate::{curve_point::CurvePoint, local_storage::TypeTag}; + use crate::{curve_point::{CurvePoint, CurveTrait}, local_storage::TypeTag}; pub(super) struct RoundOnePrivate; impl TypeTag for RoundOnePrivate { @@ -46,17 +46,23 @@ mod storage { impl TypeTag for RoundTwoPrivate { type Value = crate::presign::round_two::Private; } - pub(super) struct RoundTwoPublic; - impl TypeTag for RoundTwoPublic { - type Value = crate::presign::round_two::Public; + pub(super) struct RoundTwoPublic { + pub(crate) curve: std::marker::PhantomData, } - pub(super) struct RoundThreePrivate; - impl TypeTag for RoundThreePrivate { - type Value = crate::presign::round_three::Private; + impl TypeTag for RoundTwoPublic { + type Value = crate::presign::round_two::Public; } - pub(super) struct RoundThreePublic; - impl TypeTag for RoundThreePublic { - type Value = crate::presign::round_three::Public; + pub(super) struct RoundThreePrivate { + pub(crate) curve: std::marker::PhantomData, + } + impl TypeTag for RoundThreePrivate { + type Value = crate::presign::round_three::Private; + } + pub(super) struct RoundThreePublic { + pub(crate) curve: std::marker::PhantomData, + } + impl TypeTag for RoundThreePublic { + type Value = crate::presign::round_three::Public; } } @@ -654,7 +660,7 @@ impl PresignParticipant { .contains_for_all_ids::(&self.other_participant_ids); let all_publics_received = self .local_storage - .contains_for_all_ids::(&self.other_participant_ids); + .contains_for_all_ids::>(&self.other_participant_ids); if all_privates_received && all_publics_received { info!("Presign: Round two complete. Generating round three messages."); // Generate messages for round three... @@ -699,7 +705,7 @@ impl PresignParticipant { .retrieve::(pid)?; let r2_public = self .local_storage - .retrieve::(pid)?; + .retrieve::>(pid)?; let _ = hashmap.insert( pid, round_three::Input { @@ -722,7 +728,7 @@ impl PresignParticipant { )?; self.local_storage - .store::(self.id, r3_private); + .store::>(self.id, r3_private); let messages = r3_publics_map .into_iter() @@ -753,7 +759,7 @@ impl PresignParticipant { // private round three value exists in storage. if !self .local_storage - .contains::(self.id) + .contains::>(self.id) { self.stash_message(message)?; return Ok(ProcessOutcome::Incomplete); @@ -766,7 +772,7 @@ impl PresignParticipant { // presign record. if self .local_storage - .contains_for_all_ids::(&self.other_participant_ids) + .contains_for_all_ids::>(&self.other_participant_ids) { let record = self.do_presign_finish()?; self.status = Status::TerminatedSuccessfully; @@ -779,7 +785,7 @@ impl PresignParticipant { /// Finish the presign protocol. #[cfg_attr(feature = "flame_it", flame("presign"))] #[instrument(skip_all, err(Debug))] - fn do_presign_finish(&mut self) -> Result> { + fn do_presign_finish(&mut self) -> Result> { info!("Doing presign finish. Creating presign record."); // Collect the other participants' round three public values from storage. let r3_pubs = self @@ -788,14 +794,14 @@ impl PresignParticipant { .map(|pid| { Ok(self .local_storage - .retrieve::(*pid)? + .retrieve::>(*pid)? .clone()) }) .collect::>>()?; let r3_private = self .local_storage - .retrieve::(self.id)?; + .retrieve::>(self.id)?; // Check consistency across all Gamma values for (i, r3_pub) in r3_pubs.iter().enumerate() { @@ -810,7 +816,7 @@ impl PresignParticipant { // Note: This `try_into` call does the check and computation specified // in Step 2 of Output in the paper's protocol specification (Figure 7). - let presign_record: PresignRecord = RecordPair { + let presign_record: PresignRecord = RecordPair { private: r3_private.clone(), publics: r3_pubs, } @@ -821,7 +827,7 @@ impl PresignParticipant { #[cfg_attr(feature = "flame_it", flame("presign"))] fn validate_and_store_round_two_public(&mut self, message: &Message) -> Result<()> { - self.check_for_duplicate_msg::(message.from())?; + self.check_for_duplicate_msg::>(message.from())?; let input = self.input(); @@ -846,14 +852,14 @@ impl PresignParticipant { )?; self.local_storage - .store_once::(message.from(), round_two_public)?; + .store_once::>(message.from(), round_two_public)?; Ok(()) } #[cfg_attr(feature = "flame_it", flame("presign"))] fn validate_and_store_round_three_public(&mut self, message: &Message) -> Result<()> { - self.check_for_duplicate_msg::(message.from())?; + self.check_for_duplicate_msg::>(message.from())?; let input = self.input(); let receiver_auxinfo_public = input.find_auxinfo_public(message.to())?; @@ -870,7 +876,7 @@ impl PresignParticipant { )?; self.local_storage - .store_once::(message.from(), public)?; + .store_once::>(message.from(), public)?; Ok(()) } } @@ -1101,9 +1107,9 @@ impl PresignKeyShareAndInfo { rng: &mut R, context: &ParticipantPresignContext, sender_r1_priv: &round_one::Private, - other_participant_inputs: &HashMap>, + other_participant_inputs: &HashMap>, ) -> Result<( - round_three::Private, + round_three::Private, HashMap>, )> { let order = C::curve_order(); diff --git a/src/presign/record.rs b/src/presign/record.rs index 6cc17997..52d6e987 100644 --- a/src/presign/record.rs +++ b/src/presign/record.rs @@ -19,7 +19,7 @@ use tracing::error; use zeroize::{Zeroize, ZeroizeOnDrop}; pub(crate) struct RecordPair { - pub(crate) private: RoundThreePrivate, + pub(crate) private: RoundThreePrivate, pub(crate) publics: Vec>, } @@ -183,7 +183,7 @@ impl PresignRecord { // whether parsing succeeded; and // 2. We can log the error message once at the end, rather than duplicating it // across all the parsing code - let mut parse = || -> Result { + let mut parse = || -> Result> { // Make sure the RECORD_TAG is correct. let actual_tag = parser.take_bytes(RECORD_TAG.len())?; if actual_tag != RECORD_TAG { @@ -193,7 +193,7 @@ impl PresignRecord { // Parse the curve point let point_len = parser.take_len()?; let point_bytes = parser.take_bytes(point_len)?; - let point = CurvePoint::try_from_bytes(point_bytes)?; + let point = C::try_from_bytes(point_bytes)?; // Parse the random share `k` let random_share_len = parser.take_len()?; diff --git a/src/presign/round_one.rs b/src/presign/round_one.rs index be1bf333..828514fe 100644 --- a/src/presign/round_one.rs +++ b/src/presign/round_one.rs @@ -8,7 +8,7 @@ use super::participant::ParticipantPresignContext; use crate::{ - curve_point::CurvePoint, errors::{InternalError, Result}, messages::{Message, MessageType, PresignMessageType}, paillier::{Ciphertext, EncryptionKey, Nonce}, ring_pedersen::VerifiedRingPedersen, zkp::{ + curve_point::{CurvePoint, CurveTrait}, errors::{InternalError, Result}, messages::{Message, MessageType, PresignMessageType}, paillier::{Ciphertext, EncryptionKey, Nonce}, ring_pedersen::VerifiedRingPedersen, zkp::{ pienc::{PiEncInput, PiEncProof}, Proof, } @@ -75,9 +75,9 @@ impl Public { /// /// Note: The [`VerifiedRingPedersen`] value must be that of the _caller_ /// (i.e., the verifier). - pub(crate) fn verify( + pub(crate) fn verify( self, - context: &ParticipantPresignContext, + context: &ParticipantPresignContext, verifier_setup_params: &VerifiedRingPedersen, prover_pk: &EncryptionKey, prover_public_broadcast: &PublicBroadcast, diff --git a/src/presign/round_three.rs b/src/presign/round_three.rs index bbc9b45c..697472ab 100644 --- a/src/presign/round_three.rs +++ b/src/presign/round_three.rs @@ -25,18 +25,18 @@ use tracing::error; use zeroize::ZeroizeOnDrop; #[derive(Clone, ZeroizeOnDrop)] -pub(crate) struct Private { +pub(crate) struct Private { pub k: BigNumber, pub chi: Scalar, #[zeroize(skip)] - pub Gamma: CurvePoint, + pub Gamma: C, #[zeroize(skip)] pub delta: Scalar, #[zeroize(skip)] - pub Delta: CurvePoint, + pub Delta: C, } -impl Debug for Private { +impl Debug for Private { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { // Note: delta, Gamma, and Delta are all sent over the network to other // parties so I assume they are not actually private data. @@ -60,7 +60,7 @@ impl Debug for Private { pub(crate) struct Public { pub delta: Scalar, pub Delta: C, - pub psi_double_prime: PiLogProof, + pub psi_double_prime: PiLogProof, /// Gamma value included for convenience pub Gamma: C, } diff --git a/src/sign/interactive_sign/participant.rs b/src/sign/interactive_sign/participant.rs index f73d1caf..3e0d2aad 100644 --- a/src/sign/interactive_sign/participant.rs +++ b/src/sign/interactive_sign/participant.rs @@ -120,7 +120,7 @@ impl SigningMaterial { } } - fn as_mut_signer(&mut self) -> Result<&mut SignParticipant> { + fn as_mut_signer(&mut self) -> Result<&mut SignParticipant> { match self { SigningMaterial::Signer { ref mut signer } => Ok(signer), _ => { diff --git a/src/utils.rs b/src/utils.rs index 4d5eb043..fc139552 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -6,7 +6,7 @@ // License, Version 2.0 found in the LICENSE-APACHE file in the root directory // of this source tree. -use crate::curve_point::CurvePoint; +use crate::curve_point::{CurveTrait, CurvePoint}; use crate::errors::{CallerError, InternalError, Result}; use libpaillier::unknown_order::BigNumber; use merlin::Transcript; diff --git a/src/zkp/piaffg.rs b/src/zkp/piaffg.rs index 18461c48..cc71477c 100644 --- a/src/zkp/piaffg.rs +++ b/src/zkp/piaffg.rs @@ -49,7 +49,6 @@ use rand::{CryptoRng, RngCore}; use serde::{de::DeserializeOwned, Deserialize, Serialize}; use std::fmt::Debug; use tracing::error; -use crate::curve_point::CurvePoint; /// Zero-knowledge proof of knowledge of a Paillier affine operation with a /// group commitment where the encrypted and committed values are in a given @@ -193,7 +192,7 @@ impl<'a> PiAffgSecret<'a> { } impl Proof for PiAffgProof { - type CommonInput<'a> = PiAffgInput<'a, C>; + type CommonInput<'a> = PiAffgInput<'a, C> where C: 'a; type ProverSecret<'b> = PiAffgSecret<'b>; #[cfg_attr(feature = "flame_it", flame("PiAffgProof"))] @@ -419,7 +418,7 @@ impl Proof for PiAffgProof { } // Check that the masked group exponentiation is valid. let masked_group_exponentiation_is_valid = { - let lhs = C::GENERATOR.multiply_by_bignum(&self.masked_mult_coeff)?; + let lhs = C::generator().multiply_by_bignum(&self.masked_mult_coeff)?; let rhs = self.random_mult_coeff_exp + input.mult_coeff_exp.multiply_by_bignum(&self.challenge)?; lhs == rhs @@ -543,10 +542,7 @@ impl PiAffgProof { mod tests { use super::*; use crate::{ - paillier::DecryptionKey, - curve_point::testing::init_testing, - utils::{random_plusminus, random_plusminus_by_size_with_minimum}, - zkp::BadContext, + curve_point::{testing::init_testing, CurvePoint}, paillier::DecryptionKey, utils::{random_plusminus, random_plusminus_by_size_with_minimum}, zkp::BadContext }; use rand::{rngs::StdRng, Rng, SeedableRng}; diff --git a/src/zkp/pilog.rs b/src/zkp/pilog.rs index 27836a4c..b95d6b44 100644 --- a/src/zkp/pilog.rs +++ b/src/zkp/pilog.rs @@ -158,7 +158,7 @@ fn generate_challenge( } impl Proof for PiLogProof { - type CommonInput<'a> = CommonInput<'a, C>; + type CommonInput<'a> = CommonInput<'a, C> where C: 'a; type ProverSecret<'a> = ProverSecret<'a>; #[cfg_attr(feature = "flame_it", flame("PiLogProof"))] fn prove<'a, R: RngCore + CryptoRng>( diff --git a/src/zkp/pimod.rs b/src/zkp/pimod.rs index 2d7b7ab2..80c00ff6 100644 --- a/src/zkp/pimod.rs +++ b/src/zkp/pimod.rs @@ -475,6 +475,7 @@ fn y_prime_combinations( #[cfg(test)] mod tests { use rand::{rngs::StdRng, Rng}; + use crate::curve_point::CurveTrait; use super::*; use crate::{ diff --git a/src/zkp/pisch.rs b/src/zkp/pisch.rs index 9c04a199..e5a26ec0 100644 --- a/src/zkp/pisch.rs +++ b/src/zkp/pisch.rs @@ -109,7 +109,7 @@ impl<'a> ProverSecret<'a> { impl Proof for PiSchProof { - type CommonInput<'a> = CommonInput<'a, C>; + type CommonInput<'a> = CommonInput<'a, C> where C: 'a; type ProverSecret<'a> = ProverSecret<'a>; #[cfg_attr(feature = "flame_it", flame("PiSchProof"))] fn prove( @@ -197,7 +197,6 @@ impl PiSchProof { commitment, challenge, response, - curve: std::marker::PhantomData, }; Ok(proof) } From 4a62bc8f4a66143d405c0bd1c10a98a0da77a307 Mon Sep 17 00:00:00 2001 From: emmorais Date: Fri, 9 Aug 2024 08:32:52 -0300 Subject: [PATCH 36/36] Warnings --- src/keyrefresh/participant.rs | 4 +--- src/presign/participant.rs | 4 ++-- src/presign/record.rs | 2 +- src/presign/round_one.rs | 2 +- src/presign/round_three.rs | 2 +- 5 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/keyrefresh/participant.rs b/src/keyrefresh/participant.rs index 9a70cbaa..c63d9a33 100644 --- a/src/keyrefresh/participant.rs +++ b/src/keyrefresh/participant.rs @@ -9,7 +9,7 @@ // of this source tree. use crate::{ - broadcast::participant::{BroadcastOutput, BroadcastParticipant, BroadcastTag}, curve_point::{CurvePoint, CurveTrait}, errors::{CallerError, InternalError, Result}, keyrefresh::{ + broadcast::participant::{BroadcastOutput, BroadcastParticipant, BroadcastTag}, curve_point::CurveTrait, errors::{CallerError, InternalError, Result}, keyrefresh::{ keyrefresh_commit::{KeyrefreshCommit, KeyrefreshDecommit}, keyshare::{KeyUpdateEncrypted, KeyUpdatePrivate, KeyUpdatePublic}, }, local_storage::LocalStorage, messages::{KeyrefreshMessageType, Message, MessageType}, participant::{ @@ -24,8 +24,6 @@ use tracing::{error, info, instrument, warn}; use super::{input::Input, Output}; mod storage { - use k256::elliptic_curve::Curve; - use super::*; use crate::local_storage::TypeTag; diff --git a/src/presign/participant.rs b/src/presign/participant.rs index 2e2d7b9d..4b353fa1 100644 --- a/src/presign/participant.rs +++ b/src/presign/participant.rs @@ -9,7 +9,7 @@ // of this source tree. use crate::{ - auxinfo::{AuxInfoPrivate, AuxInfoPublic}, broadcast::participant::{BroadcastOutput, BroadcastParticipant, BroadcastTag}, curve_point::{CurvePoint, CurveTrait}, errors::{CallerError, InternalError, Result}, keygen::{KeySharePrivate, KeySharePublic}, local_storage::LocalStorage, messages::{Message, MessageType, PresignMessageType}, parameters::ELL_PRIME, participant::{Broadcast, InnerProtocolParticipant, ProcessOutcome, ProtocolParticipant}, presign::{ + auxinfo::{AuxInfoPrivate, AuxInfoPublic}, broadcast::participant::{BroadcastOutput, BroadcastParticipant, BroadcastTag}, curve_point::CurveTrait, errors::{CallerError, InternalError, Result}, keygen::{KeySharePrivate, KeySharePublic}, local_storage::LocalStorage, messages::{Message, MessageType, PresignMessageType}, parameters::ELL_PRIME, participant::{Broadcast, InnerProtocolParticipant, ProcessOutcome, ProtocolParticipant}, presign::{ input::Input, record::{PresignRecord, RecordPair}, round_one, round_three, round_two, @@ -28,7 +28,7 @@ use tracing::{error, info, instrument}; // Local storage data types. mod storage { - use crate::{curve_point::{CurvePoint, CurveTrait}, local_storage::TypeTag}; + use crate::{curve_point::CurveTrait, local_storage::TypeTag}; pub(super) struct RoundOnePrivate; impl TypeTag for RoundOnePrivate { diff --git a/src/presign/record.rs b/src/presign/record.rs index 52d6e987..4ee27471 100644 --- a/src/presign/record.rs +++ b/src/presign/record.rs @@ -7,7 +7,7 @@ // of this source tree. use crate::{ - curve_point::{CurvePoint, CurveTrait}, errors::{ + curve_point::CurveTrait, errors::{ CallerError, InternalError::{InternalInvariantFailed, ProtocolError}, Result, diff --git a/src/presign/round_one.rs b/src/presign/round_one.rs index 828514fe..db854c6b 100644 --- a/src/presign/round_one.rs +++ b/src/presign/round_one.rs @@ -8,7 +8,7 @@ use super::participant::ParticipantPresignContext; use crate::{ - curve_point::{CurvePoint, CurveTrait}, errors::{InternalError, Result}, messages::{Message, MessageType, PresignMessageType}, paillier::{Ciphertext, EncryptionKey, Nonce}, ring_pedersen::VerifiedRingPedersen, zkp::{ + curve_point::CurveTrait, errors::{InternalError, Result}, messages::{Message, MessageType, PresignMessageType}, paillier::{Ciphertext, EncryptionKey, Nonce}, ring_pedersen::VerifiedRingPedersen, zkp::{ pienc::{PiEncInput, PiEncProof}, Proof, } diff --git a/src/presign/round_three.rs b/src/presign/round_three.rs index 697472ab..b638ee20 100644 --- a/src/presign/round_three.rs +++ b/src/presign/round_three.rs @@ -7,7 +7,7 @@ // of this source tree. use crate::{ - auxinfo::AuxInfoPublic, curve_point::{CurvePoint, CurveTrait}, errors::{InternalError, Result}, messages::{Message, MessageType, PresignMessageType}, presign::{ + auxinfo::AuxInfoPublic, curve_point::CurveTrait, errors::{InternalError, Result}, messages::{Message, MessageType, PresignMessageType}, presign::{ participant::ParticipantPresignContext, round_one::PublicBroadcast as RoundOnePublicBroadcast, round_two::{Private as RoundTwoPrivate, Public as RoundTwoPublic},