diff --git a/crypto/dleq/src/cross_group/mod.rs b/crypto/dleq/src/cross_group/mod.rs index 498d5f9f..012d1138 100644 --- a/crypto/dleq/src/cross_group/mod.rs +++ b/crypto/dleq/src/cross_group/mod.rs @@ -8,7 +8,7 @@ use group::{ff::{Field, PrimeField, PrimeFieldBits}, prime::PrimeGroup}; use crate::{Generators, challenge}; pub mod scalar; -use scalar::scalar_normalize; +use scalar::{scalar_normalize, scalar_convert}; pub(crate) mod schnorr; use schnorr::SchnorrPoK; @@ -32,7 +32,7 @@ pub(crate) fn read_point(r: &mut R) -> std::io::Result { commitments: (G0, G1), - e: (G0::Scalar, G1::Scalar), + e: G0::Scalar, s: [(G0::Scalar, G1::Scalar); 2] } @@ -41,8 +41,7 @@ impl Bit { pub fn serialize(&self, w: &mut W) -> std::io::Result<()> { w.write_all(self.commitments.0.to_bytes().as_ref())?; w.write_all(self.commitments.1.to_bytes().as_ref())?; - w.write_all(self.e.0.to_repr().as_ref())?; - w.write_all(self.e.1.to_repr().as_ref())?; + w.write_all(self.e.to_repr().as_ref())?; for i in 0 .. 2 { w.write_all(self.s[i].0.to_repr().as_ref())?; w.write_all(self.s[i].1.to_repr().as_ref())?; @@ -55,7 +54,7 @@ impl Bit { Ok( Bit { commitments: (read_point(r)?, read_point(r)?), - e: (read_scalar(r)?, read_scalar(r)?), + e: read_scalar(r)?, s: [ (read_scalar(r)?, read_scalar(r)?), (read_scalar(r)?, read_scalar(r)?) @@ -71,6 +70,8 @@ pub enum DLEqError { InvalidProofOfKnowledge, #[error("invalid proof length")] InvalidProofLength, + #[error("invalid challenge")] + InvalidChallenge, #[error("invalid proof")] InvalidProof } @@ -117,7 +118,7 @@ impl DLEqProof fn nonces(mut transcript: T, nonces: (G0, G1)) -> (G0::Scalar, G1::Scalar) { transcript.append_message(b"nonce_0", nonces.0.to_bytes().as_ref()); transcript.append_message(b"nonce_1", nonces.1.to_bytes().as_ref()); - (challenge(&mut transcript, b"challenge_G"), challenge(&mut transcript, b"challenge_H")) + scalar_normalize(challenge(&mut transcript)) } #[allow(non_snake_case)] @@ -134,7 +135,6 @@ impl DLEqProof ) } - // TODO: Use multiexp here after https://github.com/serai-dex/serai/issues/17 fn reconstruct_key( commitments: impl Iterator ) -> G where G::Scalar: PrimeFieldBits { @@ -240,9 +240,9 @@ impl DLEqProof bits.push( if *bit { - Bit { commitments, e: e_0, s: [s_1, s_0] } + Bit { commitments, e: e_0.0, s: [s_1, s_0] } } else { - Bit { commitments, e: e_1, s: [s_0, s_1] } + Bit { commitments, e: e_1.0, s: [s_0, s_1] } } ); @@ -282,7 +282,8 @@ impl DLEqProof for (i, bit) in self.bits.iter().enumerate() { Self::transcript_bit(transcript, i, bit.commitments); - if bit.e != Self::R_nonces( + let bit_e = (bit.e, scalar_convert(bit.e).ok_or(DLEqError::InvalidChallenge)?); + if bit_e != Self::R_nonces( transcript.clone(), generators, bit.s[0], @@ -295,7 +296,7 @@ impl DLEqProof generators, bit.s[1], bit.commitments, - bit.e + bit_e ) ) { return Err(DLEqError::InvalidProof); diff --git a/crypto/dleq/src/cross_group/schnorr.rs b/crypto/dleq/src/cross_group/schnorr.rs index cbb7cfc8..cbd60aa6 100644 --- a/crypto/dleq/src/cross_group/schnorr.rs +++ b/crypto/dleq/src/cross_group/schnorr.rs @@ -28,7 +28,7 @@ impl SchnorrPoK { transcript.append_message(b"generator", generator.to_bytes().as_ref()); transcript.append_message(b"nonce", R.to_bytes().as_ref()); transcript.append_message(b"public_key", A.to_bytes().as_ref()); - challenge(transcript, b"challenge") + challenge(transcript) } pub(crate) fn prove( diff --git a/crypto/dleq/src/lib.rs b/crypto/dleq/src/lib.rs index cc15775e..f960cdfe 100644 --- a/crypto/dleq/src/lib.rs +++ b/crypto/dleq/src/lib.rs @@ -33,10 +33,7 @@ impl Generators { } } -pub(crate) fn challenge( - transcript: &mut T, - label: &'static [u8] -) -> F { +pub(crate) fn challenge(transcript: &mut T) -> F { assert!(F::NUM_BITS <= 384); // From here, there are three ways to get a scalar under the ff/group API @@ -44,7 +41,7 @@ pub(crate) fn challenge( // 2: Grabbing a UInt library to perform reduction by the modulus, then determining endianess // and loading it in // 3: Iterating over each byte and manually doubling/adding. This is simplest - let challenge_bytes = transcript.challenge(label); + let challenge_bytes = transcript.challenge(b"challenge"); assert!(challenge_bytes.as_ref().len() == 64); let mut challenge = F::zero(); @@ -94,7 +91,7 @@ impl DLEqProof { transcript.append_message(b"nonce_alternate", nonces.1.to_bytes().as_ref()); transcript.append_message(b"point_primary", points.0.to_bytes().as_ref()); transcript.append_message(b"point_alternate", points.1.to_bytes().as_ref()); - challenge(transcript, b"challenge") + challenge(transcript) } pub fn prove(