From 1f093cfbc638eac4ffe8b66855b48df7e1251011 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Thu, 15 Aug 2024 15:32:32 -0400 Subject: [PATCH] Big-endian secq256k1 scalars Also restores the prior, safer, Encryption::register function. --- crypto/dkg/src/encryption.rs | 28 +++++++++++++++++++++------- crypto/dkg/src/pedpop.rs | 11 ++++------- crypto/evrf/secq256k1/README.md | 3 +-- crypto/evrf/secq256k1/src/backend.rs | 10 ++++++---- 4 files changed, 32 insertions(+), 20 deletions(-) diff --git a/crypto/dkg/src/encryption.rs b/crypto/dkg/src/encryption.rs index c53269db0..1ad721f66 100644 --- a/crypto/dkg/src/encryption.rs +++ b/crypto/dkg/src/encryption.rs @@ -48,8 +48,8 @@ pub(crate) use sealed::*; /// Wraps a message with a key to use for encryption in the future. #[derive(Clone, PartialEq, Eq, Debug, Zeroize)] pub struct EncryptionKeyMessage { - pub(crate) msg: M, - pub(crate) enc_key: C::G, + msg: M, + enc_key: C::G, } // Doesn't impl ReadWrite so that doesn't need to be imported @@ -348,12 +348,17 @@ impl Decryption { pub(crate) fn new(context: [u8; 32]) -> Self { Self { context, enc_keys: HashMap::new() } } - pub(crate) fn register(&mut self, participant: Participant, key: C::G) { + pub(crate) fn register( + &mut self, + participant: Participant, + msg: EncryptionKeyMessage, + ) -> M { assert!( !self.enc_keys.contains_key(&participant), "Re-registering encryption key for a participant" ); - self.enc_keys.insert(participant, key); + self.enc_keys.insert(participant, msg.enc_key); + msg.msg } // Given a message, and the intended decryptor, and a proof for its key, decrypt the message. @@ -425,7 +430,12 @@ impl Zeroize for Encryption { } impl Encryption { - pub(crate) fn new(context: [u8; 32], i: Participant, enc_key: Zeroizing) -> Self { + pub(crate) fn new( + context: [u8; 32], + i: Participant, + rng: &mut R, + ) -> Self { + let enc_key = Zeroizing::new(C::random_nonzero_F(rng)); Self { context, i, @@ -439,8 +449,12 @@ impl Encryption { EncryptionKeyMessage { msg, enc_key: self.enc_pub_key } } - pub(crate) fn register(&mut self, participant: Participant, key: C::G) { - self.decryption.register(participant, key) + pub(crate) fn register( + &mut self, + participant: Participant, + msg: EncryptionKeyMessage, + ) -> M { + self.decryption.register(participant, msg) } pub(crate) fn encrypt( diff --git a/crypto/dkg/src/pedpop.rs b/crypto/dkg/src/pedpop.rs index 37af59d2b..adfc6958f 100644 --- a/crypto/dkg/src/pedpop.rs +++ b/crypto/dkg/src/pedpop.rs @@ -133,8 +133,7 @@ impl KeyGenMachine { ); // Additionally create an encryption mechanism to protect the secret shares - let encryption = - Encryption::new(self.context, self.params.i, Zeroizing::new(C::random_nonzero_F(rng))); + let encryption = Encryption::new(self.context, self.params.i, rng); // Step 4: Broadcast let msg = @@ -178,7 +177,7 @@ fn polynomial( // The encryption system also explicitly uses Zeroizing so it can ensure anything being // encrypted is within Zeroizing. Accordingly, internally having Zeroizing would be redundant. #[derive(Clone, PartialEq, Eq)] -pub struct SecretShare(pub(crate) F::Repr); +pub struct SecretShare(F::Repr); impl AsRef<[u8]> for SecretShare { fn as_ref(&self) -> &[u8] { self.0.as_ref() @@ -262,8 +261,7 @@ impl SecretShareMachine { let mut commitments = HashMap::new(); for l in (1 ..= self.params.n()).map(Participant) { let Some(msg) = commitment_msgs.remove(&l) else { continue }; - self.encryption.register(l, msg.enc_key); - let mut msg = msg.msg; + let mut msg = self.encryption.register(l, msg); if msg.commitments.len() != self.params.t().into() { Err(FrostError::InvalidCommitments(l))?; @@ -610,8 +608,7 @@ impl AdditionalBlameMachine { for i in 1 ..= n { let i = Participant::new(i).unwrap(); let Some(msg) = commitment_msgs.remove(&i) else { Err(DkgError::MissingParticipant(i))? }; - encryption.register(i, msg.enc_key); - commitments.insert(i, msg.msg.commitments); + commitments.insert(i, encryption.register(i, msg).commitments); } Ok(AdditionalBlameMachine(BlameMachine { commitments, encryption, result: None })) } diff --git a/crypto/evrf/secq256k1/README.md b/crypto/evrf/secq256k1/README.md index c37a89411..b20ee31fc 100644 --- a/crypto/evrf/secq256k1/README.md +++ b/crypto/evrf/secq256k1/README.md @@ -2,5 +2,4 @@ An implementation of the curve secp256k1 cycles with. -Scalars are encoded as little-endian and field elements are encoded as -big-endian. +Scalars and field elements are encoded in their big-endian formats. diff --git a/crypto/evrf/secq256k1/src/backend.rs b/crypto/evrf/secq256k1/src/backend.rs index 304fa0bc5..6f8653c8a 100644 --- a/crypto/evrf/secq256k1/src/backend.rs +++ b/crypto/evrf/secq256k1/src/backend.rs @@ -183,7 +183,7 @@ macro_rules! field { fn random(mut rng: impl RngCore) -> Self { let mut bytes = [0; 64]; rng.fill_bytes(&mut bytes); - $FieldName(Residue::new(&reduce(U512::from_le_slice(bytes.as_ref())))) + $FieldName(Residue::new(&reduce(U512::from_be_slice(bytes.as_ref())))) } fn square(&self) -> Self { @@ -230,12 +230,12 @@ macro_rules! field { const DELTA: Self = $FieldName(Residue::new(&U256::from_be_hex($DELTA))); fn from_repr(bytes: Self::Repr) -> CtOption { - let res = U256::from_le_slice(&bytes); + let res = U256::from_be_slice(&bytes); CtOption::new($FieldName(Residue::new(&res)), res.ct_lt(&$MODULUS)) } fn to_repr(&self) -> Self::Repr { let mut repr = [0; 32]; - repr.copy_from_slice(&self.0.retrieve().to_le_bytes()); + repr.copy_from_slice(&self.0.retrieve().to_be_bytes()); repr } @@ -248,7 +248,9 @@ macro_rules! field { type ReprBits = [u8; 32]; fn to_le_bits(&self) -> FieldBits { - self.to_repr().into() + let mut repr = [0; 32]; + repr.copy_from_slice(&self.0.retrieve().to_le_bytes()); + repr.into() } fn char_le_bits() -> FieldBits {