mirror of
https://github.com/saymrwulf/betrusted-curve25519-dalek-source.git
synced 2026-09-04 20:24:07 +00:00
Add getrandom (#118)
* Add getrandom to bring convenience random init functions * Fix doc name * Rename new to random_from_rng * Deprecate new() in favor of random_from_rng() * Simplify constructors documentation Co-authored-by: Ciprian Dorin Craciun <ciprian@volution.ro>
This commit is contained in:
parent
6aabb9bf08
commit
02a5ce20ca
6 changed files with 117 additions and 23 deletions
|
|
@ -54,6 +54,7 @@ harness = false
|
|||
|
||||
[features]
|
||||
default = ["alloc", "precomputed-tables", "zeroize"]
|
||||
getrandom = ["rand_core/getrandom"]
|
||||
zeroize = ["dep:zeroize", "curve25519-dalek/zeroize"]
|
||||
serde = ["dep:serde", "curve25519-dalek/serde"]
|
||||
alloc = ["curve25519-dalek/alloc", "serde?/alloc", "zeroize?/alloc"]
|
||||
|
|
|
|||
|
|
@ -28,23 +28,21 @@ up on modern public key cryptography and have learned a nifty trick called
|
|||
kittens will be able to secretly organise to find their mittens, and then spend
|
||||
the rest of the afternoon nomming some yummy pie!
|
||||
|
||||
First, Alice uses `EphemeralSecret::new()` and then
|
||||
First, Alice uses `EphemeralSecret::random()` and then
|
||||
`PublicKey::from()` to produce her secret and public keys:
|
||||
|
||||
```rust
|
||||
use rand_core::OsRng;
|
||||
use x25519_dalek::{EphemeralSecret, PublicKey};
|
||||
|
||||
let alice_secret = EphemeralSecret::new(OsRng);
|
||||
let alice_secret = EphemeralSecret::random();
|
||||
let alice_public = PublicKey::from(&alice_secret);
|
||||
```
|
||||
|
||||
Bob does the same:
|
||||
|
||||
```rust
|
||||
# use rand_core::OsRng;
|
||||
# use x25519_dalek::{EphemeralSecret, PublicKey};
|
||||
let bob_secret = EphemeralSecret::new(OsRng);
|
||||
let bob_secret = EphemeralSecret::random();
|
||||
let bob_public = PublicKey::from(&bob_secret);
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -19,12 +19,12 @@ use x25519_dalek::EphemeralSecret;
|
|||
use x25519_dalek::PublicKey;
|
||||
|
||||
fn bench_diffie_hellman(c: &mut Criterion) {
|
||||
let bob_secret = EphemeralSecret::new(OsRng);
|
||||
let bob_secret = EphemeralSecret::random_from_rng(OsRng);
|
||||
let bob_public = PublicKey::from(&bob_secret);
|
||||
|
||||
c.bench_function("diffie_hellman", move |b| {
|
||||
b.iter_with_setup(
|
||||
|| EphemeralSecret::new(OsRng),
|
||||
|| EphemeralSecret::random_from_rng(OsRng),
|
||||
|alice_secret| alice_secret.diffie_hellman(&bob_public),
|
||||
)
|
||||
});
|
||||
|
|
|
|||
18
src/lib.rs
18
src/lib.rs
|
|
@ -50,14 +50,14 @@
|
|||
//! kittens will be able to secretly organise to find their mittens, and then spend
|
||||
//! the rest of the afternoon nomming some yummy pie!
|
||||
//!
|
||||
//! First, Alice uses `EphemeralSecret::new()` and then
|
||||
//! First, Alice uses `EphemeralSecret::random_from_rng` and then
|
||||
//! `PublicKey::from()` to produce her secret and public keys:
|
||||
//!
|
||||
//! ```rust
|
||||
//! use rand_core::OsRng;
|
||||
//! use x25519_dalek::{EphemeralSecret, PublicKey};
|
||||
//!
|
||||
//! let alice_secret = EphemeralSecret::new(OsRng);
|
||||
//! let alice_secret = EphemeralSecret::random_from_rng(OsRng);
|
||||
//! let alice_public = PublicKey::from(&alice_secret);
|
||||
//! ```
|
||||
//!
|
||||
|
|
@ -66,7 +66,7 @@
|
|||
//! ```rust
|
||||
//! # use rand_core::OsRng;
|
||||
//! # use x25519_dalek::{EphemeralSecret, PublicKey};
|
||||
//! let bob_secret = EphemeralSecret::new(OsRng);
|
||||
//! let bob_secret = EphemeralSecret::random_from_rng(OsRng);
|
||||
//! let bob_public = PublicKey::from(&bob_secret);
|
||||
//! ```
|
||||
//!
|
||||
|
|
@ -77,9 +77,9 @@
|
|||
//! ```rust
|
||||
//! # use rand_core::OsRng;
|
||||
//! # use x25519_dalek::{EphemeralSecret, PublicKey};
|
||||
//! # let alice_secret = EphemeralSecret::new(OsRng);
|
||||
//! # let alice_secret = EphemeralSecret::random_from_rng(OsRng);
|
||||
//! # let alice_public = PublicKey::from(&alice_secret);
|
||||
//! # let bob_secret = EphemeralSecret::new(OsRng);
|
||||
//! # let bob_secret = EphemeralSecret::random_from_rng(OsRng);
|
||||
//! # let bob_public = PublicKey::from(&bob_secret);
|
||||
//! let alice_shared_secret = alice_secret.diffie_hellman(&bob_public);
|
||||
//! ```
|
||||
|
|
@ -89,9 +89,9 @@
|
|||
//! ```rust
|
||||
//! # use rand_core::OsRng;
|
||||
//! # use x25519_dalek::{EphemeralSecret, PublicKey};
|
||||
//! # let alice_secret = EphemeralSecret::new(OsRng);
|
||||
//! # let alice_secret = EphemeralSecret::random_from_rng(OsRng);
|
||||
//! # let alice_public = PublicKey::from(&alice_secret);
|
||||
//! # let bob_secret = EphemeralSecret::new(OsRng);
|
||||
//! # let bob_secret = EphemeralSecret::random_from_rng(OsRng);
|
||||
//! # let bob_public = PublicKey::from(&bob_secret);
|
||||
//! let bob_shared_secret = bob_secret.diffie_hellman(&alice_public);
|
||||
//! ```
|
||||
|
|
@ -101,9 +101,9 @@
|
|||
//! ```rust
|
||||
//! # use rand_core::OsRng;
|
||||
//! # use x25519_dalek::{EphemeralSecret, PublicKey};
|
||||
//! # let alice_secret = EphemeralSecret::new(OsRng);
|
||||
//! # let alice_secret = EphemeralSecret::random_from_rng(OsRng);
|
||||
//! # let alice_public = PublicKey::from(&alice_secret);
|
||||
//! # let bob_secret = EphemeralSecret::new(OsRng);
|
||||
//! # let bob_secret = EphemeralSecret::random_from_rng(OsRng);
|
||||
//! # let bob_public = PublicKey::from(&bob_secret);
|
||||
//! # let alice_shared_secret = alice_secret.diffie_hellman(&bob_public);
|
||||
//! # let bob_shared_secret = bob_secret.diffie_hellman(&alice_public);
|
||||
|
|
|
|||
|
|
@ -71,8 +71,8 @@ impl AsRef<[u8]> for PublicKey {
|
|||
/// 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 by [`EphemeralSecret::new`] and the compiler statically checks
|
||||
/// that the resulting secret is used at most once.
|
||||
/// generated from fresh randomness where the compiler statically checks that the resulting
|
||||
/// secret is used at most once.
|
||||
#[cfg_attr(feature = "zeroize", derive(Zeroize))]
|
||||
#[cfg_attr(feature = "zeroize", zeroize(drop))]
|
||||
pub struct EphemeralSecret(pub(crate) Scalar);
|
||||
|
|
@ -84,14 +84,29 @@ impl EphemeralSecret {
|
|||
SharedSecret(self.0 * their_public.0)
|
||||
}
|
||||
|
||||
/// Generate an x25519 [`EphemeralSecret`] key.
|
||||
/// Generate a new [`EphemeralSecret`] with the supplied RNG.
|
||||
#[deprecated(
|
||||
since = "2.0.0",
|
||||
note = "Renamed to `random_from_rng`. This will be removed in 2.1.0"
|
||||
)]
|
||||
pub fn new<T: RngCore + CryptoRng>(mut csprng: T) -> Self {
|
||||
Self::random_from_rng(&mut csprng)
|
||||
}
|
||||
|
||||
/// Generate a new [`EphemeralSecret`] with the supplied RNG.
|
||||
pub fn random_from_rng<T: RngCore + CryptoRng>(mut csprng: T) -> Self {
|
||||
let mut bytes = [0u8; 32];
|
||||
|
||||
csprng.fill_bytes(&mut bytes);
|
||||
|
||||
EphemeralSecret(Scalar::from_bits_clamped(bytes))
|
||||
}
|
||||
|
||||
/// Generate a new [`EphemeralSecret`].
|
||||
#[cfg(feature = "getrandom")]
|
||||
pub fn random() -> Self {
|
||||
Self::random_from_rng(&mut rand_core::OsRng)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a EphemeralSecret> for PublicKey {
|
||||
|
|
@ -133,14 +148,29 @@ impl ReusableSecret {
|
|||
SharedSecret(self.0 * their_public.0)
|
||||
}
|
||||
|
||||
/// Generate a non-serializeable x25519 [`ReusableSecret`] key.
|
||||
/// Generate a new [`ReusableSecret`] with the supplied RNG.
|
||||
#[deprecated(
|
||||
since = "2.0.0",
|
||||
note = "Renamed to `random_from_rng`. This will be removed in 2.1.0."
|
||||
)]
|
||||
pub fn new<T: RngCore + CryptoRng>(mut csprng: T) -> Self {
|
||||
Self::random_from_rng(&mut csprng)
|
||||
}
|
||||
|
||||
/// Generate a new [`ReusableSecret`] with the supplied RNG.
|
||||
pub fn random_from_rng<T: RngCore + CryptoRng>(mut csprng: T) -> Self {
|
||||
let mut bytes = [0u8; 32];
|
||||
|
||||
csprng.fill_bytes(&mut bytes);
|
||||
|
||||
ReusableSecret(Scalar::from_bits_clamped(bytes))
|
||||
}
|
||||
|
||||
/// Generate a new [`ReusableSecret`].
|
||||
#[cfg(feature = "getrandom")]
|
||||
pub fn random() -> Self {
|
||||
Self::random_from_rng(&mut rand_core::OsRng)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "reusable_secrets")]
|
||||
|
|
@ -180,8 +210,17 @@ impl StaticSecret {
|
|||
SharedSecret(self.0 * their_public.0)
|
||||
}
|
||||
|
||||
/// Generate an x25519 key.
|
||||
/// Generate a new [`StaticSecret`] with the supplied RNG.
|
||||
#[deprecated(
|
||||
since = "2.0.0",
|
||||
note = "Renamed to `random_from_rng`. This will be removed in 2.1.0"
|
||||
)]
|
||||
pub fn new<T: RngCore + CryptoRng>(mut csprng: T) -> Self {
|
||||
Self::random_from_rng(&mut csprng)
|
||||
}
|
||||
|
||||
/// Generate a new [`StaticSecret`] with the supplied RNG.
|
||||
pub fn random_from_rng<T: RngCore + CryptoRng>(mut csprng: T) -> Self {
|
||||
let mut bytes = [0u8; 32];
|
||||
|
||||
csprng.fill_bytes(&mut bytes);
|
||||
|
|
@ -189,6 +228,12 @@ impl StaticSecret {
|
|||
StaticSecret(Scalar::from_bits_clamped(bytes))
|
||||
}
|
||||
|
||||
/// Generate a new [`StaticSecret`].
|
||||
#[cfg(feature = "getrandom")]
|
||||
pub fn random() -> Self {
|
||||
Self::random_from_rng(&mut rand_core::OsRng)
|
||||
}
|
||||
|
||||
/// Extract this key's bytes for serialization.
|
||||
#[inline]
|
||||
pub fn to_bytes(&self) -> [u8; 32] {
|
||||
|
|
@ -307,11 +352,11 @@ impl AsRef<[u8]> for SharedSecret {
|
|||
/// use x25519_dalek::PublicKey;
|
||||
///
|
||||
/// // Generate Alice's key pair.
|
||||
/// let alice_secret = StaticSecret::new(&mut OsRng);
|
||||
/// let alice_secret = StaticSecret::random_from_rng(&mut OsRng);
|
||||
/// let alice_public = PublicKey::from(&alice_secret);
|
||||
///
|
||||
/// // Generate Bob's key pair.
|
||||
/// let bob_secret = StaticSecret::new(&mut OsRng);
|
||||
/// let bob_secret = StaticSecret::random_from_rng(&mut OsRng);
|
||||
/// let bob_public = PublicKey::from(&bob_secret);
|
||||
///
|
||||
/// // Alice and Bob should now exchange their public keys.
|
||||
|
|
|
|||
|
|
@ -180,3 +180,53 @@ fn rfc7748_ladder_test2() {
|
|||
]
|
||||
);
|
||||
}
|
||||
|
||||
mod rand_core {
|
||||
|
||||
use super::*;
|
||||
use ::rand_core::OsRng;
|
||||
|
||||
#[test]
|
||||
fn ephemeral_from_rng() {
|
||||
#[allow(deprecated)]
|
||||
EphemeralSecret::new(OsRng);
|
||||
EphemeralSecret::random_from_rng(OsRng);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "reusable_secrets")]
|
||||
fn reusable_from_rng() {
|
||||
#[allow(deprecated)]
|
||||
ReusableSecret::new(OsRng);
|
||||
ReusableSecret::random_from_rng(OsRng);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn static_from_rng() {
|
||||
#[allow(deprecated)]
|
||||
StaticSecret::new(OsRng);
|
||||
StaticSecret::random_from_rng(OsRng);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "getrandom")]
|
||||
mod getrandom {
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn ephemeral_random() {
|
||||
EphemeralSecret::random();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "reusable_secrets")]
|
||||
fn reusable_random() {
|
||||
ReusableSecret::random();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn static_random() {
|
||||
StaticSecret::random();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue