add bound to ConstantTimeEq in Scalar
This commit is contained in:
parent
1c6f0b1694
commit
2de0f3c5df
|
@ -23,6 +23,7 @@ digest = "0.10"
|
||||||
hex = { version = "0.4.3", features = ["serde"] }
|
hex = { version = "0.4.3", features = ["serde"] }
|
||||||
rand_core = "0.6"
|
rand_core = "0.6"
|
||||||
serde = { version = "1", optional = true, features = ["derive"] }
|
serde = { version = "1", optional = true, features = ["derive"] }
|
||||||
|
subtle = "2.4.1"
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
zeroize = { version = "1.5.4", default-features = false, features = ["derive"] }
|
zeroize = { version = "1.5.4", default-features = false, features = ["derive"] }
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@ mod verifying_key;
|
||||||
pub use error::Error;
|
pub use error::Error;
|
||||||
pub use signature::Signature;
|
pub use signature::Signature;
|
||||||
pub use signing_key::SigningKey;
|
pub use signing_key::SigningKey;
|
||||||
|
pub use subtle::ConstantTimeEq;
|
||||||
pub use verifying_key::VerifyingKey;
|
pub use verifying_key::VerifyingKey;
|
||||||
|
|
||||||
/// A prime order finite field GF(q) over which all scalar values for our prime order group can be
|
/// A prime order finite field GF(q) over which all scalar values for our prime order group can be
|
||||||
|
@ -41,6 +42,7 @@ pub trait Field: Copy + Clone {
|
||||||
type Scalar: Add<Output = Self::Scalar>
|
type Scalar: Add<Output = Self::Scalar>
|
||||||
+ Copy
|
+ Copy
|
||||||
+ Clone
|
+ Clone
|
||||||
|
+ ConstantTimeEq
|
||||||
+ Eq
|
+ Eq
|
||||||
+ Mul<Output = Self::Scalar>
|
+ Mul<Output = Self::Scalar>
|
||||||
+ PartialEq
|
+ PartialEq
|
||||||
|
@ -277,13 +279,12 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates a random nonzero scalar.
|
/// Generates a random nonzero scalar.
|
||||||
///
|
|
||||||
/// It assumes that the Scalar Eq/PartialEq implementation is constant-time.
|
|
||||||
pub(crate) fn random_nonzero<C: Ciphersuite, R: RngCore + CryptoRng>(rng: &mut R) -> Scalar<C> {
|
pub(crate) fn random_nonzero<C: Ciphersuite, R: RngCore + CryptoRng>(rng: &mut R) -> Scalar<C> {
|
||||||
|
let zero = <<C::Group as Group>::Field>::zero();
|
||||||
loop {
|
loop {
|
||||||
let scalar = <<C::Group as Group>::Field>::random(rng);
|
let scalar = <<C::Group as Group>::Field>::random(rng);
|
||||||
|
|
||||||
if scalar != <<C::Group as Group>::Field>::zero() {
|
if scalar.ct_eq(&zero).into() {
|
||||||
return scalar;
|
return scalar;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ use sha3::{
|
||||||
Shake256,
|
Shake256,
|
||||||
};
|
};
|
||||||
|
|
||||||
use frost_core::{frost, Ciphersuite, Field, Group};
|
use frost_core::{frost, Ciphersuite, ConstantTimeEq, Field, Group};
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
@ -37,7 +37,7 @@ impl Field for Ed448ScalarField {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn invert(scalar: &Self::Scalar) -> Result<Self::Scalar, Error> {
|
fn invert(scalar: &Self::Scalar) -> Result<Self::Scalar, Error> {
|
||||||
if *scalar == <Self as Field>::zero() {
|
if scalar.ct_eq(&<Self as Field>::zero()).into() {
|
||||||
Err(Error::InvalidZeroScalar)
|
Err(Error::InvalidZeroScalar)
|
||||||
} else {
|
} else {
|
||||||
Ok(scalar.invert())
|
Ok(scalar.invert())
|
||||||
|
|
|
@ -14,7 +14,7 @@ use p256::{
|
||||||
use rand_core::{CryptoRng, RngCore};
|
use rand_core::{CryptoRng, RngCore};
|
||||||
use sha2::{digest::Update, Digest, Sha256};
|
use sha2::{digest::Update, Digest, Sha256};
|
||||||
|
|
||||||
use frost_core::{frost, Ciphersuite, Field, Group};
|
use frost_core::{frost, Ciphersuite, ConstantTimeEq, Field, Group};
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
@ -39,9 +39,7 @@ impl Field for P256ScalarField {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn invert(scalar: &Self::Scalar) -> Result<Self::Scalar, Error> {
|
fn invert(scalar: &Self::Scalar) -> Result<Self::Scalar, Error> {
|
||||||
// [`p256::Scalar`]'s Eq/PartialEq does a constant-time comparison using
|
if scalar.ct_eq(&<Self as Field>::zero()).into() {
|
||||||
// `ConstantTimeEq`
|
|
||||||
if *scalar == <Self as Field>::zero() {
|
|
||||||
Err(Error::InvalidZeroScalar)
|
Err(Error::InvalidZeroScalar)
|
||||||
} else {
|
} else {
|
||||||
Ok(scalar.invert().unwrap())
|
Ok(scalar.invert().unwrap())
|
||||||
|
|
|
@ -11,7 +11,7 @@ use curve25519_dalek::{
|
||||||
use rand_core::{CryptoRng, RngCore};
|
use rand_core::{CryptoRng, RngCore};
|
||||||
use sha2::{digest::Update, Digest, Sha512};
|
use sha2::{digest::Update, Digest, Sha512};
|
||||||
|
|
||||||
use frost_core::{frost, Ciphersuite, Field, Group};
|
use frost_core::{frost, Ciphersuite, ConstantTimeEq, Field, Group};
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
@ -36,9 +36,7 @@ impl Field for RistrettoScalarField {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn invert(scalar: &Self::Scalar) -> Result<Self::Scalar, Error> {
|
fn invert(scalar: &Self::Scalar) -> Result<Self::Scalar, Error> {
|
||||||
// [`curve25519_dalek::scalar::Scalar`]'s Eq/PartialEq does a constant-time comparison using
|
if scalar.ct_eq(&<Self as Field>::zero()).into() {
|
||||||
// `ConstantTimeEq`
|
|
||||||
if *scalar == <Self as Field>::zero() {
|
|
||||||
Err(Error::InvalidZeroScalar)
|
Err(Error::InvalidZeroScalar)
|
||||||
} else {
|
} else {
|
||||||
Ok(scalar.invert())
|
Ok(scalar.invert())
|
||||||
|
|
|
@ -16,7 +16,7 @@ use k256::{
|
||||||
use rand_core::{CryptoRng, RngCore};
|
use rand_core::{CryptoRng, RngCore};
|
||||||
use sha2::{digest::Update, Digest, Sha256};
|
use sha2::{digest::Update, Digest, Sha256};
|
||||||
|
|
||||||
use frost_core::{frost, Ciphersuite, Field, Group};
|
use frost_core::{frost, Ciphersuite, ConstantTimeEq, Field, Group};
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
@ -41,8 +41,7 @@ impl Field for Secp256K1ScalarField {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn invert(scalar: &Self::Scalar) -> Result<Self::Scalar, Error> {
|
fn invert(scalar: &Self::Scalar) -> Result<Self::Scalar, Error> {
|
||||||
// [`Scalar`]'s Eq/PartialEq does a constant-time comparison
|
if scalar.ct_eq(&<Self as Field>::zero()).into() {
|
||||||
if *scalar == <Self as Field>::zero() {
|
|
||||||
Err(Error::InvalidZeroScalar)
|
Err(Error::InvalidZeroScalar)
|
||||||
} else {
|
} else {
|
||||||
Ok(scalar.invert().unwrap())
|
Ok(scalar.invert().unwrap())
|
||||||
|
|
Loading…
Reference in New Issue