diff --git a/CHANGELOG.md b/CHANGELOG.md index 51842ef..3043d96 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- Add `Zeroize` trait implementation for `SecretKey` [#12] + +### Removed + +- Remove `Copy` trait from `SecretKey` [#12] +- Remove `From` for `PublicKey`, use `From<&SecretKey>` instead [#12] + ## [0.2.2] - 2024-03-11 ### Added @@ -32,6 +41,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add initial commit, this package continues the development of [dusk-schnorr](https://github.com/dusk-network/schnorr/) at version `0.18.0` under the new name: jubjub-schnorr +[#12]: https://github.com/dusk-network/jubjub-schnorr/issues/12 [#9]: https://github.com/dusk-network/jubjub-schnorr/issues/9 [#3]: https://github.com/dusk-network/jubjub-schnorr/issues/3 [#2]: https://github.com/dusk-network/jubjub-schnorr/issues/2 diff --git a/Cargo.toml b/Cargo.toml index 97c0f3f..f103f89 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,10 +20,11 @@ dusk-bytes = "0.1" dusk-poseidon = { version ="0.33", default-features = false } dusk-plonk = { version = "0.19", default-features = false } dusk-bls12_381 = { version = "0.13", default-features = false } -dusk-jubjub = { version = "0.14", default-features = false } +dusk-jubjub = { version = "0.14", default-features = false, features = ["zeroize"] } +ff = { version = "0.13", default-features = false } +zeroize = { version = "1", default-features = false, features = ["derive"] } rkyv = { version = "0.7", optional = true, default-features = false } bytecheck = { version = "0.6", optional = true, default-features = false } -ff = { version = "0.13", default-features = false } [dev-dependencies] rkyv = { version = "0.7", default-features = false, features = ["size_32"] } diff --git a/src/keys/public.rs b/src/keys/public.rs index 65f4a8b..163d9e2 100644 --- a/src/keys/public.rs +++ b/src/keys/public.rs @@ -272,13 +272,6 @@ impl From<&SecretKey> for PublicKeyDouble { } } -#[cfg(feature = "double")] -impl From for PublicKeyDouble { - fn from(sk: SecretKey) -> Self { - (&sk).into() - } -} - #[cfg(feature = "double")] impl Serializable<64> for PublicKeyDouble { type Error = Error; diff --git a/src/keys/secret.rs b/src/keys/secret.rs index 97e2c45..413dd71 100644 --- a/src/keys/secret.rs +++ b/src/keys/secret.rs @@ -16,6 +16,7 @@ use dusk_bytes::{Error, Serializable}; use dusk_jubjub::{JubJubScalar, GENERATOR_EXTENDED}; use ff::Field; use rand_core::{CryptoRng, RngCore}; +use zeroize::Zeroize; use crate::{PublicKey, Signature}; @@ -37,6 +38,12 @@ use rkyv::{Archive, Deserialize, Serialize}; /// Structure representing a [`SecretKey`], represented as a private scalar /// in the JubJub scalar field. /// +/// ## Safety +/// +/// To ensure that no secret information lingers in memory after the variable +/// goes out of scope, we advice calling `zeroize` before the variable goes out +/// of scope. +/// /// ## Examples /// /// Generate a random `SecretKey`: @@ -44,12 +51,17 @@ use rkyv::{Archive, Deserialize, Serialize}; /// use jubjub_schnorr::SecretKey; /// use rand::rngs::StdRng; /// use rand::SeedableRng; +/// use zeroize::Zeroize; /// /// let mut rng = StdRng::seed_from_u64(12345); -/// let sk = SecretKey::random(&mut rng); +/// let mut sk = SecretKey::random(&mut rng); +/// +/// // do something with the sk +/// +/// sk.zeroize(); /// ``` #[allow(non_snake_case)] -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)] +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Zeroize)] #[cfg_attr( feature = "rkyv-impl", derive(Archive, Serialize, Deserialize), diff --git a/tests/keys.rs b/tests/keys.rs index 81f1f50..2b9da8d 100644 --- a/tests/keys.rs +++ b/tests/keys.rs @@ -59,6 +59,16 @@ fn partial_eq_pk() { assert_ne!(PublicKey::from(left), PublicKey::from(wrong)) } +#[test] +fn test_zeroize() { + use zeroize::Zeroize; + + let mut sk = SecretKey::from(JubJubScalar::from(42u64)); + sk.zeroize(); + + assert_eq!(sk, SecretKey::from(JubJubScalar::default())); +} + #[test] #[cfg(feature = "double")] fn partial_eq_pk_double() { diff --git a/tests/schnorr_double.rs b/tests/schnorr_double.rs index b804274..d69fa6a 100644 --- a/tests/schnorr_double.rs +++ b/tests/schnorr_double.rs @@ -17,7 +17,7 @@ fn sign_verify() { let sk = SecretKey::random(&mut rng); let message = BlsScalar::random(&mut rng); - let pk_double: PublicKeyDouble = sk.into(); + let pk_double = PublicKeyDouble::from(&sk); let sig = sk.sign_double(&mut rng, message); @@ -35,7 +35,7 @@ fn test_wrong_keys() { // Derive random public key let wrong_sk = SecretKey::random(&mut rng); - let pk_double: PublicKeyDouble = wrong_sk.into(); + let pk_double = PublicKeyDouble::from(&wrong_sk); assert!(!pk_double.verify(&sig, message)); }