Skip to content

Commit

Permalink
Make static_secrets optional (#122)
Browse files Browse the repository at this point in the history
* Make `static_secrets` optional

* Added more feature combinations to CI
  • Loading branch information
pinkforest committed Mar 31, 2023
1 parent 02a5ce2 commit 8415833
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 6 deletions.
6 changes: 5 additions & 1 deletion .github/workflows/rust.yml
Expand Up @@ -13,7 +13,7 @@ env:

jobs:
test:
name: Test all features
name: Test with multiple feature combinations
runs-on: ubuntu-latest
strategy:
matrix:
Expand All @@ -29,6 +29,10 @@ jobs:
with:
target: ${{ matrix.target }}
- run: ${{ matrix.deps }}
- run: cargo test --target ${{ matrix.target }} --no-default-features
- run: cargo test --target ${{ matrix.target }} --no-default-features --features reusable_secrets
- run: cargo test --target ${{ matrix.target }} --no-default-features --features static_secrets
- run: cargo test --target ${{ matrix.target }}
- run: cargo test --target ${{ matrix.target }} --all-features

build-simd:
Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Expand Up @@ -60,3 +60,4 @@ serde = ["dep:serde", "curve25519-dalek/serde"]
alloc = ["curve25519-dalek/alloc", "serde?/alloc", "zeroize?/alloc"]
precomputed-tables = ["curve25519-dalek/precomputed-tables"]
reusable_secrets = []
static_secrets = []
15 changes: 10 additions & 5 deletions src/x25519.rs
Expand Up @@ -24,8 +24,7 @@ use rand_core::RngCore;
#[cfg(feature = "zeroize")]
use zeroize::Zeroize;

/// A Diffie-Hellman public key, corresponding to an [`EphemeralSecret`] or
/// [`StaticSecret`] key.
/// A Diffie-Hellman public key
///
/// We implement `Zeroize` so that downstream consumers may derive it for `Drop`
/// should they wish to erase public keys from memory. Note that this erasure
Expand Down Expand Up @@ -68,7 +67,7 @@ impl AsRef<[u8]> for PublicKey {
/// A short-lived Diffie-Hellman secret key that can only be used to compute a single
/// [`SharedSecret`].
///
/// This type is identical to the [`StaticSecret`] type, except that the
/// This type is identical to the `StaticSecret` type, except that the
/// [`EphemeralSecret::diffie_hellman`] method consumes and then wipes the secret key, and there
/// are no serialization methods defined. This means that [`EphemeralSecret`]s can only be
/// generated from fresh randomness where the compiler statically checks that the resulting
Expand Down Expand Up @@ -125,7 +124,7 @@ impl<'a> From<&'a EphemeralSecret> for PublicKey {
///
/// Similarly to [`EphemeralSecret`], this type does _not_ have serialisation
/// methods, in order to discourage long-term usage of secret key material. (For
/// long-term secret keys, see [`StaticSecret`].)
/// long-term secret keys, see `StaticSecret`.)
///
/// # Warning
///
Expand Down Expand Up @@ -195,6 +194,7 @@ impl<'a> From<&'a ReusableSecret> for PublicKey {
/// [`EphemeralSecret`] at all times, as that type enforces at compile-time that
/// secret keys are never reused, which can have very serious security
/// implications for many protocols.
#[cfg(feature = "static_secrets")]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "zeroize", derive(Zeroize))]
#[cfg_attr(feature = "zeroize", zeroize(drop))]
Expand All @@ -203,6 +203,7 @@ pub struct StaticSecret(
#[cfg_attr(feature = "serde", serde(with = "AllowUnreducedScalarBytes"))] pub(crate) Scalar,
);

#[cfg(feature = "static_secrets")]
impl StaticSecret {
/// Perform a Diffie-Hellman key agreement between `self` and
/// `their_public` key to produce a `SharedSecret`.
Expand Down Expand Up @@ -247,20 +248,23 @@ impl StaticSecret {
}
}

#[cfg(feature = "static_secrets")]
impl From<[u8; 32]> for StaticSecret {
/// Load a secret key from a byte array.
fn from(bytes: [u8; 32]) -> StaticSecret {
StaticSecret(Scalar::from_bits_clamped(bytes))
}
}

#[cfg(feature = "static_secrets")]
impl<'a> From<&'a StaticSecret> for PublicKey {
/// Given an x25519 [`StaticSecret`] key, compute its corresponding [`PublicKey`].
fn from(secret: &'a StaticSecret) -> PublicKey {
PublicKey(EdwardsPoint::mul_base(&secret.0).to_montgomery())
}
}

#[cfg(feature = "static_secrets")]
impl AsRef<[u8]> for StaticSecret {
/// View this key as a byte array.
#[inline]
Expand Down Expand Up @@ -343,7 +347,8 @@ impl AsRef<[u8]> for SharedSecret {
/// cannot use the better, safer, and faster ephemeral DH API.
///
/// # Example
/// ```rust
#[cfg_attr(feature = "static_secrets", doc = "```")]
#[cfg_attr(not(feature = "static_secrets"), doc = "```ignore")]
/// use rand_core::OsRng;
/// use rand_core::RngCore;
///
Expand Down
2 changes: 2 additions & 0 deletions tests/x25519_tests.rs
Expand Up @@ -202,6 +202,7 @@ mod rand_core {
}

#[test]
#[cfg(feature = "static_secrets")]
fn static_from_rng() {
#[allow(deprecated)]
StaticSecret::new(OsRng);
Expand All @@ -226,6 +227,7 @@ mod getrandom {
}

#[test]
#[cfg(feature = "static_secrets")]
fn static_random() {
StaticSecret::random();
}
Expand Down

0 comments on commit 8415833

Please sign in to comment.