diff --git a/umbral-pre/src/capsule.rs b/umbral-pre/src/capsule.rs index bd7740e8..0cead214 100644 --- a/umbral-pre/src/capsule.rs +++ b/umbral-pre/src/capsule.rs @@ -158,17 +158,18 @@ impl Capsule { ) -> (Capsule, SecretBox) { let g = CurvePoint::generator(); - let priv_r = NonZeroCurveScalar::random(rng); - let pub_r = &g * &priv_r; + let priv_r = SecretBox::new(NonZeroCurveScalar::random(rng)); + let pub_r = &g * priv_r.as_secret(); - let priv_u = NonZeroCurveScalar::random(rng); - let pub_u = &g * &priv_u; + let priv_u = SecretBox::new(NonZeroCurveScalar::random(rng)); + let pub_u = &g * priv_u.as_secret(); let h = hash_capsule_points(&pub_r, &pub_u); - let s = &priv_u + &(&priv_r * &h); + let s = priv_u.as_secret() + &(priv_r.as_secret() * &h); - let shared_key = SecretBox::new(&delegating_pk.to_point() * &(&priv_r + &priv_u)); + let shared_key = + SecretBox::new(&delegating_pk.to_point() * &(priv_r.as_secret() + priv_u.as_secret())); let capsule = Self::new(pub_r, pub_u, s); diff --git a/umbral-pre/src/capsule_frag.rs b/umbral-pre/src/capsule_frag.rs index 7e4f1170..10bf6005 100644 --- a/umbral-pre/src/capsule_frag.rs +++ b/umbral-pre/src/capsule_frag.rs @@ -13,6 +13,7 @@ use crate::curve::{CurvePoint, CurveScalar, NonZeroCurveScalar}; use crate::hashing_ds::{hash_to_cfrag_verification, kfrag_signature_message}; use crate::key_frag::{KeyFrag, KeyFragID}; use crate::keys::{PublicKey, Signature}; +use crate::secret_box::SecretBox; use crate::traits::{ fmt_public, ConstructionError, DeserializableFromArray, DeserializationError, HasTypeName, RepresentableAsArray, SerializableToArray, @@ -84,7 +85,7 @@ impl CapsuleFragProof { let params = capsule.params; let rk = kfrag.key; - let t = NonZeroCurveScalar::random(rng); + let t = SecretBox::new(NonZeroCurveScalar::random(rng)); // Here are the formulaic constituents shared with `CapsuleFrag::verify()`. @@ -97,15 +98,15 @@ impl CapsuleFragProof { let u = params.u; let u1 = kfrag.proof.commitment; - let e2 = &e * &t; - let v2 = &v * &t; - let u2 = &u * &t; + let e2 = &e * t.as_secret(); + let v2 = &v * t.as_secret(); + let u2 = &u * t.as_secret(); let h = hash_to_cfrag_verification(&[e, *e1, e2, v, *v1, v2, u, u1, u2]); //////// - let z3 = &(&rk * &h) + &t; + let z3 = &(&rk * &h) + t.as_secret(); Self { point_e2: e2, diff --git a/umbral-pre/src/key_frag.rs b/umbral-pre/src/key_frag.rs index dcfa2b82..3a62d13e 100644 --- a/umbral-pre/src/key_frag.rs +++ b/umbral-pre/src/key_frag.rs @@ -14,6 +14,7 @@ use crate::curve::{CurvePoint, CurveScalar, NonZeroCurveScalar}; use crate::hashing_ds::{hash_to_polynomial_arg, hash_to_shared_secret, kfrag_signature_message}; use crate::keys::{PublicKey, SecretKey, Signature, Signer}; use crate::params::Parameters; +use crate::secret_box::SecretBox; use crate::traits::{ fmt_public, ConstructionError, DeserializableFromArray, DeserializationError, HasTypeName, RepresentableAsArray, SerializableToArray, @@ -460,10 +461,10 @@ impl KeyFragBase { // The precursor point is used as an ephemeral public key in a DH key exchange, // and the resulting shared secret 'dh_point' is used to derive other secret values - let private_precursor = NonZeroCurveScalar::random(rng); - let precursor = &g * &private_precursor; + let private_precursor = SecretBox::new(NonZeroCurveScalar::random(rng)); + let precursor = &g * private_precursor.as_secret(); - let dh_point = &receiving_pk_point * &private_precursor; + let dh_point = &receiving_pk_point * private_precursor.as_secret(); // Secret value 'd' allows to make Umbral non-interactive let d = hash_to_shared_secret(&precursor, &receiving_pk_point, &dh_point); @@ -474,6 +475,7 @@ impl KeyFragBase { let mut coefficients = Vec::::with_capacity(threshold); coefficients.push(coefficient0); for _i in 1..threshold { + // Assuming these are not secret, otherwise they should be put in SecretBox. coefficients.push(NonZeroCurveScalar::random(rng)); } diff --git a/umbral-pre/src/keys.rs b/umbral-pre/src/keys.rs index 142b75d3..0e320822 100644 --- a/umbral-pre/src/keys.rs +++ b/umbral-pre/src/keys.rs @@ -1,4 +1,3 @@ -use alloc::boxed::Box; use alloc::vec::Vec; use core::cmp::Ordering; use core::fmt; @@ -20,7 +19,7 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer}; use crate::curve::{CurvePoint, CurveScalar, CurveType, NonZeroCurveScalar}; use crate::dem::kdf; use crate::hashing::{BackendDigest, Hash, ScalarDigest}; -use crate::secret_box::{CanBeZeroizedOnDrop, SecretBox}; +use crate::secret_box::SecretBox; use crate::traits::{ fmt_public, fmt_secret, ConstructionError, DeserializableFromArray, HasTypeName, RepresentableAsArray, SerializableToArray, SerializableToSecretArray, SizeMismatchError, @@ -95,19 +94,16 @@ impl fmt::Display for Signature { } } -impl CanBeZeroizedOnDrop for BackendSecretKey { - fn ensure_zeroized_on_drop(&mut self) { - // BackendSecretKey is zeroized on drop, nothing to do - } -} - +// TODO (#89): derive `ZeroizeOnDrop` for `SecretKey` when it's available. +// For now we know that `BackendSecretKey` is zeroized on drop (as of elliptic-curve=0.11), +// but cannot check that at compile-time. /// A secret key. #[derive(Clone)] -pub struct SecretKey(SecretBox>); +pub struct SecretKey(BackendSecretKey); impl SecretKey { fn new(sk: BackendSecretKey) -> Self { - Self(SecretBox::new(sk)) + Self(sk) } /// Creates a secret key using the given RNG. @@ -124,20 +120,17 @@ impl SecretKey { /// Returns a public key corresponding to this secret key. pub fn public_key(&self) -> PublicKey { - PublicKey(self.0.as_secret().public_key()) + PublicKey(self.0.public_key()) } fn from_nonzero_scalar(scalar: SecretBox) -> Self { - // TODO: SecretBox it - let backend_sk = - BackendSecretKey::::from(scalar.as_secret().as_backend_scalar()); - - Self::new(backend_sk) + let backend_scalar_ref = scalar.as_secret().as_backend_scalar(); + Self::new(BackendSecretKey::::from(backend_scalar_ref)) } /// Returns a reference to the underlying scalar of the secret key. pub(crate) fn to_secret_scalar(&self) -> SecretBox { - let backend_scalar = SecretBox::new(self.0.as_secret().to_nonzero_scalar()); + let backend_scalar = SecretBox::new(self.0.to_nonzero_scalar()); SecretBox::new(NonZeroCurveScalar::from_backend_scalar( *backend_scalar.as_secret(), )) @@ -150,7 +143,7 @@ impl RepresentableAsArray for SecretKey { impl SerializableToSecretArray for SecretKey { fn to_secret_array(&self) -> SecretBox> { - SecretBox::new(self.0.as_secret().to_be_bytes()) + SecretBox::new(self.0.to_be_bytes()) } } @@ -193,10 +186,9 @@ impl Signer { pub fn sign_with_rng(&self, rng: &mut (impl CryptoRng + RngCore), message: &[u8]) -> Signature { let digest = digest_for_signing(message); let secret_key = self.0.clone(); - // We could use SecretBox here, but SigningKey does not implement Clone. - // Box is good enough, seeing as how `signing_key` does not leave this method. - let signing_key = Box::new(SigningKey::::from(secret_key.0.as_secret())); - Signature(signing_key.as_ref().sign_digest_with_rng(rng, digest)) + // `k256::SigningKey` is zeroized on `Drop` as of `k256=0.10`. + let signing_key = SigningKey::::from(secret_key.0); + Signature(signing_key.sign_digest_with_rng(rng, digest)) } /// Signs the given message using the default RNG.