Skip to content

Commit

Permalink
crypto_box: use curve25519-dalek; MSRV 1.60
Browse files Browse the repository at this point in the history
Upgrades to the latest `curve25519-dalek` v4.0.0-rc.1 release.

The `x25519-dalek` crate is a wrapper whose functionality isn't really
used, and we can use the `Scalar` and `MontgomeryPoint` types directly.
  • Loading branch information
tarcieri committed Feb 8, 2023
1 parent 1c4f8c2 commit be2800d
Show file tree
Hide file tree
Showing 16 changed files with 100 additions and 59 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/crypto_box.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
strategy:
matrix:
rust:
- 1.56.0 # MSRV
- 1.60.0 # MSRV
- stable
target:
- thumbv7em-none-eabi
Expand All @@ -36,15 +36,15 @@ jobs:
toolchain: ${{ matrix.rust }}
target: ${{ matrix.target }}
override: true
- run: cargo build --target ${{ matrix.target }} --release --no-default-features --features u32_backend
- run: cargo build --target ${{ matrix.target }} --release --no-default-features --features u32_backend,heapless
- run: cargo build --target ${{ matrix.target }} --release --no-default-features
- run: cargo build --target ${{ matrix.target }} --release --no-default-features --features heapless

test:
runs-on: ubuntu-latest
strategy:
matrix:
rust:
- 1.56.0 # MSRV
- 1.60.0 # MSRV
- stable
steps:
- uses: actions/checkout@v3
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/crypto_kx.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
strategy:
matrix:
rust:
- 1.56.0 # MSRV
- 1.60.0 # MSRV
- stable
target:
- thumbv7em-none-eabi
Expand All @@ -42,7 +42,7 @@ jobs:
strategy:
matrix:
rust:
- 1.56.0 # MSRV
- 1.60.0 # MSRV
- stable
steps:
- uses: actions/checkout@v3
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/crypto_secretbox.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
strategy:
matrix:
rust:
- 1.56.0 # MSRV
- 1.60.0 # MSRV
- stable
target:
- thumbv7em-none-eabi
Expand All @@ -44,7 +44,7 @@ jobs:
strategy:
matrix:
rust:
- 1.56.0 # MSRV
- 1.60.0 # MSRV
- stable
steps:
- uses: actions/checkout@v3
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/crypto_secretstream.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
strategy:
matrix:
rust:
- 1.56.0 # MSRV
- 1.60.0 # MSRV
- stable
target:
- thumbv7em-none-eabi
Expand All @@ -42,7 +42,7 @@ jobs:
strategy:
matrix:
rust:
- 1.56.0 # MSRV
- 1.60.0 # MSRV
- stable
steps:
- uses: actions/checkout@v3
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/workspace.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
- uses: actions/checkout@v3
- uses: actions-rs/toolchain@v1
with:
toolchain: 1.56.0
toolchain: 1.60.0
components: clippy
override: true
profile: minimal
Expand Down
52 changes: 47 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 4 additions & 6 deletions crypto_box/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "crypto_box"
version = "0.8.2"
version = "0.9.0-pre"
description = """
Pure Rust implementation of NaCl's crypto_box public-key authenticated
encryption primitive which combines the X25519 Elliptic Curve Diffie-Hellman
Expand All @@ -15,15 +15,15 @@ repository = "https://github.com/RustCrypto/nacl-compat/tree/master/crypto_box"
categories = ["cryptography", "no-std"]
keywords = ["nacl", "libsodium", "public-key", "x25519", "xsalsa20poly1305"]
edition = "2021"
rust-version = "1.56"
rust-version = "1.60"

[dependencies]
aead = { version = "0.5.1", default-features = false }
chacha20 = "0.9"
chacha20poly1305 = { version = "0.10.1", default-features = false, features = ["rand_core"] }
crypto_secretbox = { version = "0", default-features = false, path = "../crypto_secretbox" }
curve25519-dalek = { version = "4.0.0-rc.1", default-features = false, features = ["zeroize"] }
salsa20 = "0.10"
x25519-dalek = { version = "1", default-features = false }
zeroize = { version = "1", default-features = false }

# optional dependencies
Expand All @@ -36,16 +36,14 @@ rand = "0.8"
rmp-serde = "1"

[features]
default = ["alloc", "getrandom", "u64_backend"]
default = ["alloc", "getrandom"]
std = ["aead/std"]
serde = ["serdect"]
alloc = ["aead/alloc"]
getrandom = ["aead/getrandom", "rand_core"]
heapless = ["aead/heapless"]
rand_core = ["aead/rand_core"]
seal = ["alloc", "blake2"]
u32_backend = ["x25519-dalek/u32_backend"]
u64_backend = ["x25519-dalek/u64_backend"]

[package.metadata.docs.rs]
features = ["serde", "seal"]
Expand Down
2 changes: 1 addition & 1 deletion crypto_box/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ dual licensed as above, without any additional terms or conditions.
[docs-image]: https://docs.rs/crypto_box/badge.svg
[docs-link]: https://docs.rs/crypto_box/
[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg
[rustc-image]: https://img.shields.io/badge/rustc-1.56+-blue.svg
[rustc-image]: https://img.shields.io/badge/rustc-1.60+-blue.svg
[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg
[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260038-AEADs
[build-image]: https://github.com/RustCrypto/nacl-compat/actions/workflows/crypto_box.yml/badge.svg
Expand Down
55 changes: 28 additions & 27 deletions crypto_box/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,9 +176,9 @@ use chacha20::hchacha;
use chacha20poly1305::XChaCha20Poly1305;
use core::fmt::{self, Debug};
use crypto_secretbox::XSalsa20Poly1305;
use curve25519_dalek::{MontgomeryPoint, Scalar};
use rand_core::{CryptoRng, RngCore};
use salsa20::hsalsa;
use x25519_dalek::{x25519, X25519_BASEPOINT_BYTES};
use zeroize::{Zeroize, Zeroizing};

#[cfg(feature = "seal")]
Expand Down Expand Up @@ -206,7 +206,7 @@ pub const SEALBYTES: usize = KEY_SIZE + TAG_SIZE;

/// A `crypto_box` secret key.
#[derive(Clone)]
pub struct SecretKey([u8; KEY_SIZE]);
pub struct SecretKey(Scalar);

impl SecretKey {
/// Generate a random [`SecretKey`].
Expand All @@ -216,35 +216,34 @@ impl SecretKey {
{
let mut bytes = [0u8; KEY_SIZE];
csprng.fill_bytes(&mut bytes);
SecretKey(bytes)
bytes.into()
}

/// Get the [`PublicKey`] which corresponds to this [`SecretKey`]
pub fn public_key(&self) -> PublicKey {
PublicKey(x25519(self.0, X25519_BASEPOINT_BYTES))
PublicKey(MontgomeryPoint::mul_base(&self.0).to_bytes())
}

#[deprecated(note = "use `as_bytes` instead")]
#[allow(missing_docs)]
/// Serialize [`SecretKey`] to bytes.
///
/// # ⚠️Warning
///
/// The serialized bytes are secret key material. Please treat them with
/// the care they deserve!
pub fn to_bytes(&self) -> [u8; KEY_SIZE] {
self.0
}

/// Get a slice of the [`SecretKey`] bytes
pub fn as_bytes(&self) -> &[u8; KEY_SIZE] {
&self.0
self.0.to_bytes()
}
}

impl From<[u8; KEY_SIZE]> for SecretKey {
fn from(bytes: [u8; KEY_SIZE]) -> SecretKey {
SecretKey(bytes)
SecretKey(Scalar::from_bits_clamped(bytes))
}
}

impl Debug for SecretKey {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("SecretKey(...)")
f.debug_struct("SecretKey").finish_non_exhaustive()
}
}

Expand All @@ -261,20 +260,22 @@ impl Drop for SecretKey {
pub struct PublicKey([u8; KEY_SIZE]);

impl PublicKey {
/// Get a slice of the [`PublicKey`] bytes
pub fn as_bytes(&self) -> &[u8; KEY_SIZE] {
&self.0
}

/// Create a public key from a slice. The bytes of the slice will be copied.
///
/// This function will fail and return `None` if the length of the byte
/// slice isn't exactly [`KEY_SIZE`].
pub fn from_slice(slice: &[u8]) -> Option<Self> {
match slice.try_into() {
Ok(array) => Some(Self(array)),
Err(_) => None,
}
slice.try_into().map(PublicKey).ok()
}

/// Borrow the public key as bytes.
pub fn as_bytes(&self) -> &[u8; KEY_SIZE] {
&self.0
}

/// Serialize this public key as bytes.
pub fn to_bytes(&self) -> [u8; KEY_SIZE] {
self.0
}
}

Expand Down Expand Up @@ -388,11 +389,11 @@ impl SalsaBox {
/// Create a new [`SalsaBox`], performing X25519 Diffie-Hellman to derive
/// a shared secret from the provided public and secret keys.
pub fn new(public_key: &PublicKey, secret_key: &SecretKey) -> Self {
let shared_secret = Zeroizing::new(x25519(secret_key.0, public_key.0));
let shared_secret = Zeroizing::new(secret_key.0 * MontgomeryPoint(public_key.0));

// Use HSalsa20 to create a uniformly random key from the shared secret
let mut key = hsalsa::<U10>(
GenericArray::from_slice(&*shared_secret),
GenericArray::from_slice(&shared_secret.0),
&GenericArray::default(),
);

Expand Down Expand Up @@ -422,11 +423,11 @@ impl ChaChaBox {
/// Create a new [`ChaChaBox`], performing X25519 Diffie-Hellman to derive
/// a shared secret from the provided public and secret keys.
pub fn new(public_key: &PublicKey, secret_key: &SecretKey) -> Self {
let shared_secret = Zeroizing::new(x25519(secret_key.0, public_key.0));
let shared_secret = Zeroizing::new(secret_key.0 * MontgomeryPoint(public_key.0));

// Use HChaCha20 to create a uniformly random key from the shared secret
let mut key = hchacha::<U10>(
GenericArray::from_slice(&*shared_secret),
GenericArray::from_slice(&shared_secret.0),
&GenericArray::default(),
);

Expand Down
Loading

0 comments on commit be2800d

Please sign in to comment.