From 0154ebbfaf4069b5a49e34894b014838463ea7ee Mon Sep 17 00:00:00 2001 From: Chris Beck Date: Wed, 10 Feb 2021 12:14:32 -0700 Subject: [PATCH 1/2] implement Zeroize trait on Ristretto curve point types This is helpful for hardening some of our cryptographic implementations that use Ristretto curve points --- Cargo.toml | 2 +- src/edwards.rs | 6 ++++-- src/ristretto.rs | 6 ++++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3426071..b20f0ad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,7 +48,7 @@ serde = { version = "1.0", default-features = false, optional = true, features = # The original packed_simd package was orphaned, see # https://github.com/rust-lang/packed_simd/issues/303#issuecomment-701361161 packed_simd = { version = "0.3.4", package = "packed_simd_2", features = ["into_bits"], optional = true } -zeroize = { version = "1", default-features = false } +zeroize = { version = "1", default-features = false, features = ["zeroize_derive"] } [features] nightly = ["subtle/nightly"] diff --git a/src/edwards.rs b/src/edwards.rs index 1524dbd..19ce866 100644 --- a/src/edwards.rs +++ b/src/edwards.rs @@ -105,6 +105,8 @@ use subtle::ConditionallyNegatable; use subtle::ConditionallySelectable; use subtle::ConstantTimeEq; +use zeroize::Zeroize; + use constants; use field::FieldElement; @@ -150,7 +152,7 @@ use backend::vector::scalar_mul; /// /// The first 255 bits of a `CompressedEdwardsY` represent the /// \\(y\\)-coordinate. The high bit of the 32nd byte gives the sign of \\(x\\). -#[derive(Copy, Clone, Eq, PartialEq, Hash)] +#[derive(Copy, Clone, Eq, PartialEq, Hash, Zeroize)] pub struct CompressedEdwardsY(pub [u8; 32]); impl ConstantTimeEq for CompressedEdwardsY { @@ -307,7 +309,7 @@ impl<'de> Deserialize<'de> for CompressedEdwardsY { // ------------------------------------------------------------------------ /// An `EdwardsPoint` represents a point on the Edwards form of Curve25519. -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Zeroize)] #[allow(missing_docs)] pub struct EdwardsPoint { pub(crate) X: FieldElement, diff --git a/src/ristretto.rs b/src/ristretto.rs index 93d310f..55f5ffd 100644 --- a/src/ristretto.rs +++ b/src/ristretto.rs @@ -177,6 +177,8 @@ use subtle::ConditionallySelectable; use subtle::ConditionallyNegatable; use subtle::ConstantTimeEq; +use zeroize::Zeroize; + use edwards::EdwardsBasepointTable; use edwards::EdwardsPoint; @@ -208,7 +210,7 @@ use backend::vector::scalar_mul; /// /// The Ristretto encoding is canonical, so two points are equal if and /// only if their encodings are equal. -#[derive(Copy, Clone, Eq, PartialEq, Hash)] +#[derive(Copy, Clone, Eq, PartialEq, Hash, Zeroize)] pub struct CompressedRistretto(pub [u8; 32]); impl ConstantTimeEq for CompressedRistretto { @@ -434,7 +436,7 @@ impl<'de> Deserialize<'de> for CompressedRistretto { /// operations on `RistrettoPoint`s are exactly as fast as operations on /// `EdwardsPoint`s. /// -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Zeroize)] pub struct RistrettoPoint(pub(crate) EdwardsPoint); impl RistrettoPoint { From 4a1fc3c66ee48044f134f66f93632a53cde7a596 Mon Sep 17 00:00:00 2001 From: Isis Lovecruft Date: Thu, 25 Mar 2021 01:45:54 +0000 Subject: [PATCH 2/2] Implement Zeroize for points as the identity element. --- Cargo.toml | 2 +- src/edwards.rs | 26 ++++++++++++++++++++++++-- src/ristretto.rs | 11 +++-------- 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b20f0ad..3426071 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,7 +48,7 @@ serde = { version = "1.0", default-features = false, optional = true, features = # The original packed_simd package was orphaned, see # https://github.com/rust-lang/packed_simd/issues/303#issuecomment-701361161 packed_simd = { version = "0.3.4", package = "packed_simd_2", features = ["into_bits"], optional = true } -zeroize = { version = "1", default-features = false, features = ["zeroize_derive"] } +zeroize = { version = "1", default-features = false } [features] nightly = ["subtle/nightly"] diff --git a/src/edwards.rs b/src/edwards.rs index 19ce866..0db8727 100644 --- a/src/edwards.rs +++ b/src/edwards.rs @@ -152,7 +152,7 @@ use backend::vector::scalar_mul; /// /// The first 255 bits of a `CompressedEdwardsY` represent the /// \\(y\\)-coordinate. The high bit of the 32nd byte gives the sign of \\(x\\). -#[derive(Copy, Clone, Eq, PartialEq, Hash, Zeroize)] +#[derive(Copy, Clone, Eq, PartialEq, Hash)] pub struct CompressedEdwardsY(pub [u8; 32]); impl ConstantTimeEq for CompressedEdwardsY { @@ -309,7 +309,7 @@ impl<'de> Deserialize<'de> for CompressedEdwardsY { // ------------------------------------------------------------------------ /// An `EdwardsPoint` represents a point on the Edwards form of Curve25519. -#[derive(Copy, Clone, Zeroize)] +#[derive(Copy, Clone)] #[allow(missing_docs)] pub struct EdwardsPoint { pub(crate) X: FieldElement, @@ -369,6 +369,28 @@ impl Default for EdwardsPoint { } } +// ------------------------------------------------------------------------ +// Zeroize implementations for wiping points from memory +// ------------------------------------------------------------------------ + +impl Zeroize for CompressedEdwardsY { + /// Reset this `CompressedEdwardsY` to the compressed form of the identity element. + fn zeroize(&mut self) { + self.0.zeroize(); + self.0[0] = 1; + } +} + +impl Zeroize for EdwardsPoint { + /// Reset this `CompressedEdwardsPoint` to the identity element. + fn zeroize(&mut self) { + self.X.zeroize(); + self.Y = FieldElement::one(); + self.Z = FieldElement::one(); + self.T.zeroize(); + } +} + // ------------------------------------------------------------------------ // Validity checks (for debugging, not CT) // ------------------------------------------------------------------------ diff --git a/src/ristretto.rs b/src/ristretto.rs index 5ef9551..8eb79f5 100644 --- a/src/ristretto.rs +++ b/src/ristretto.rs @@ -202,8 +202,6 @@ use backend::serial::scalar_mul; ))] use backend::vector::scalar_mul; -use zeroize::Zeroize; - // ------------------------------------------------------------------------ // Compressed points // ------------------------------------------------------------------------ @@ -212,7 +210,7 @@ use zeroize::Zeroize; /// /// The Ristretto encoding is canonical, so two points are equal if and /// only if their encodings are equal. -#[derive(Copy, Clone, Eq, PartialEq, Hash, Zeroize)] +#[derive(Copy, Clone, Eq, PartialEq, Hash)] pub struct CompressedRistretto(pub [u8; 32]); impl ConstantTimeEq for CompressedRistretto { @@ -438,7 +436,7 @@ impl<'de> Deserialize<'de> for CompressedRistretto { /// operations on `RistrettoPoint`s are exactly as fast as operations on /// `EdwardsPoint`s. /// -#[derive(Copy, Clone, Zeroize)] +#[derive(Copy, Clone)] pub struct RistrettoPoint(pub(crate) EdwardsPoint); impl RistrettoPoint { @@ -1094,10 +1092,7 @@ impl Zeroize for CompressedRistretto { impl Zeroize for RistrettoPoint { fn zeroize(&mut self) { - self.0.X.zeroize(); - self.0.Y.zeroize(); - self.0.Z.zeroize(); - self.0.T.zeroize(); + self.0.zeroize(); } }