Skip to content

Commit

Permalink
ed25519-dalek: make ExpandedSecretKey fields private
Browse files Browse the repository at this point in the history
Motivation can be found in this comment:

dalek-cryptography/ed25519-dalek#293 (review)

Replaces public fields with private fields + accessor methods.

Also adds an `ExpandedSecretKey::from_scalar_and_prefix` constructor
which makes it possible to construct `ExpandedSecretKey` using a
`Scalar` again, which is useful for protocols that derive the scalar
such as Ed25519-BIP32.

Additionally defines a `HashPrefix` type alias to make it semantically
clear which `[u8; 32]` is involved in type signatures.
  • Loading branch information
tarcieri committed Jul 2, 2023
1 parent 76e1934 commit 58f2855
Showing 1 changed file with 32 additions and 2 deletions.
34 changes: 32 additions & 2 deletions ed25519-dalek/src/hazmat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ use zeroize::{Zeroize, ZeroizeOnDrop};
use crate::{Signature, VerifyingKey};
use curve25519_dalek::digest::{generic_array::typenum::U64, Digest};

/// Domain separator used when hashing the message to generate the pseudorandom `r` value.
pub type HashPrefix = [u8; 32];

/// Contains the secret scalar and domain separator used for generating signatures.
///
/// This is used internally for signing.
Expand All @@ -40,14 +43,15 @@ pub struct ExpandedSecretKey {
// modulo l.
pub(crate) scalar_bytes: [u8; 32],
/// The secret scalar used for signing
pub scalar: Scalar,
pub(crate) scalar: Scalar,
/// The domain separator used when hashing the message to generate the pseudorandom `r` value
pub hash_prefix: [u8; 32],
pub(crate) hash_prefix: HashPrefix,
}

#[cfg(feature = "zeroize")]
impl Drop for ExpandedSecretKey {
fn drop(&mut self) {
self.scalar_bytes.zeroize();
self.scalar.zeroize();
self.hash_prefix.zeroize()
}
Expand All @@ -59,6 +63,16 @@ impl ZeroizeOnDrop for ExpandedSecretKey {}
// Some conversion methods for `ExpandedSecretKey`. The signing methods are defined in
// `signing.rs`, since we need them even when `not(feature = "hazmat")`
impl ExpandedSecretKey {
/// Secret scalar used for signing.
pub fn scalar(&self) -> &Scalar {
&self.scalar
}

/// Domain separator used when hashing the message to generate the pseudorandom `r` value.
pub fn hash_prefix(&self) -> &HashPrefix {
&self.hash_prefix
}

/// Convert this `ExpandedSecretKey` into an array of 64 bytes.
pub fn to_bytes(&self) -> [u8; 64] {
let mut bytes: [u8; 64] = [0u8; 64];
Expand Down Expand Up @@ -106,6 +120,22 @@ impl ExpandedSecretKey {
.into()
})
}

/// Construct an `ExpandedSecretKey` from a scalar and hash prefix.
pub fn from_scalar_and_prefix(scalar: Scalar, hash_prefix: HashPrefix) -> Self {
let scalar_bytes = scalar.to_bytes();
Self {
scalar_bytes,
scalar,
hash_prefix,
}
}
}

impl From<(Scalar, HashPrefix)> for ExpandedSecretKey {
fn from(parts: (Scalar, HashPrefix)) -> ExpandedSecretKey {
ExpandedSecretKey::from_scalar_and_prefix(parts.0, parts.1)
}
}

impl TryFrom<&[u8]> for ExpandedSecretKey {
Expand Down

0 comments on commit 58f2855

Please sign in to comment.