diff --git a/curve25519-dalek/CHANGELOG.md b/curve25519-dalek/CHANGELOG.md index 438b10318..9d940ac8e 100644 --- a/curve25519-dalek/CHANGELOG.md +++ b/curve25519-dalek/CHANGELOG.md @@ -5,6 +5,12 @@ major series. ## 5.x series +## 5.0.0-pre.2 + +* Add optional integration with [`zerocopy`][zerocopy], controlled by the `zerocopy` feature. + +[zerocopy]: https://docs.rs/zerocopy/latest/zerocopy/ + ## 5.0.0-pre.1 * Rename `Scalar::batch_invert` -> `Scalar::invert_batch` for consistency. Also make it no-alloc. diff --git a/curve25519-dalek/Cargo.toml b/curve25519-dalek/Cargo.toml index 9e626976d..8c8d5eefb 100644 --- a/curve25519-dalek/Cargo.toml +++ b/curve25519-dalek/Cargo.toml @@ -34,6 +34,7 @@ features = [ "digest", "legacy_compatibility", "group-bits", + "zerocopy", ] [dev-dependencies] @@ -68,6 +69,9 @@ serde = { version = "1.0", default-features = false, optional = true, features = "derive", ] } zeroize = { version = "1", default-features = false, optional = true } +zerocopy = { version = "0.8", default-features = false, optional = true, features = [ + "derive" +] } [target.'cfg(target_arch = "x86_64")'.dependencies] cpufeatures = "0.2.17" @@ -77,12 +81,13 @@ fiat-crypto = { version = "0.3.0", default-features = false } [features] default = ["alloc", "precomputed-tables", "zeroize"] -alloc = ["zeroize?/alloc"] +alloc = ["zerocopy?/alloc", "zeroize?/alloc"] precomputed-tables = [] legacy_compatibility = [] group = ["dep:group", "rand_core"] group-bits = ["group", "ff/bits"] digest = ["dep:digest"] +zerocopy = ["dep:zerocopy"] [target.'cfg(all(not(curve25519_dalek_backend = "fiat"), not(curve25519_dalek_backend = "serial"), target_arch = "x86_64"))'.dependencies] curve25519-dalek-derive = "0.1" diff --git a/curve25519-dalek/README.md b/curve25519-dalek/README.md index 935944573..b42e0c295 100644 --- a/curve25519-dalek/README.md +++ b/curve25519-dalek/README.md @@ -57,6 +57,7 @@ curve25519-dalek = ">= 5.0, < 5.2" | `legacy_compatibility`| | Enables `Scalar::from_bits`, which allows the user to build unreduced scalars whose arithmetic is broken. Do not use this unless you know what you're doing. | | `group` | | Enables external `group` and `ff` crate traits. | | `group-bits` | | Enables `group` and impls `ff::PrimeFieldBits` for `Scalar`. | +| `zerocopy` | | Derives [`zerocopy`][zerocopy] traits on `MontgomeryPoint`. | To disable the default features when using `curve25519-dalek` as a dependency, add `default-features = false` to the dependency in your `Cargo.toml`. To @@ -313,4 +314,5 @@ contributions. [semver]: https://semver.org/spec/v2.0.0.html [rngcorestd]: https://github.com/rust-random/rand/tree/7aa25d577e2df84a5156f824077bb7f6bdf28d97/rand_core#crate-features [zeroize-trait]: https://docs.rs/zeroize/latest/zeroize/trait.Zeroize.html +[zerocopy]: https://docs.rs/zerocopy/latest/zerocopy/ [SIMD backend]: #simd-backend diff --git a/curve25519-dalek/src/montgomery.rs b/curve25519-dalek/src/montgomery.rs index 46a6b1272..b6ecf7615 100644 --- a/curve25519-dalek/src/montgomery.rs +++ b/curve25519-dalek/src/montgomery.rs @@ -88,6 +88,15 @@ const FE_C2: FieldElement = FieldElement::from_limbs([ /// Curve25519 or its twist. #[derive(Copy, Clone, Debug, Default)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr( + feature = "zerocopy", + derive( + zerocopy::FromBytes, + zerocopy::IntoBytes, + zerocopy::Immutable, + zerocopy::KnownLayout + ) +)] pub struct MontgomeryPoint(pub [u8; 32]); /// Equality of `MontgomeryPoint`s is defined mod p. diff --git a/x25519-dalek/CHANGELOG.md b/x25519-dalek/CHANGELOG.md index abb79a240..e696583d3 100644 --- a/x25519-dalek/CHANGELOG.md +++ b/x25519-dalek/CHANGELOG.md @@ -4,6 +4,12 @@ Entries are listed in reverse chronological order. # 3.x Series +## 3.0.0-pre.1 + +* Add optional integration with [`zerocopy`][zerocopy], controlled by the `zerocopy` feature. + +[zerocopy]: https://docs.rs/zerocopy/latest/zerocopy/ + ## 3.0.0-pre.0 * Update edition to 2024 diff --git a/x25519-dalek/Cargo.toml b/x25519-dalek/Cargo.toml index e74ad0800..6b48311fe 100644 --- a/x25519-dalek/Cargo.toml +++ b/x25519-dalek/Cargo.toml @@ -39,7 +39,7 @@ rustdoc-args = [ "--cfg", "docsrs", ] -features = ["os_rng", "reusable_secrets", "serde", "static_secrets"] +features = ["os_rng", "reusable_secrets", "serde", "static_secrets", "zeroize", "zerocopy"] [dependencies] curve25519-dalek = { version = "=5.0.0-pre.1", default-features = false } @@ -48,6 +48,9 @@ serde = { version = "1", default-features = false, optional = true, features = [ "derive", ] } zeroize = { version = "1", default-features = false, optional = true } +zerocopy = { version = "0.8", default-features = false, optional = true, features = [ + "derive" +] } [dev-dependencies] bincode = "1" @@ -63,7 +66,8 @@ default = ["alloc", "precomputed-tables", "zeroize"] os_rng = ["rand_core/os_rng"] zeroize = ["dep:zeroize", "curve25519-dalek/zeroize"] serde = ["dep:serde", "curve25519-dalek/serde"] -alloc = ["curve25519-dalek/alloc", "serde?/alloc", "zeroize?/alloc"] +alloc = ["curve25519-dalek/alloc", "serde?/alloc", "zerocopy?/alloc", "zeroize?/alloc"] precomputed-tables = ["curve25519-dalek/precomputed-tables"] reusable_secrets = [] static_secrets = [] +zerocopy = ["dep:zerocopy", "curve25519-dalek/zerocopy"] diff --git a/x25519-dalek/README.md b/x25519-dalek/README.md index 392f99b5d..e53d9bd95 100644 --- a/x25519-dalek/README.md +++ b/x25519-dalek/README.md @@ -120,6 +120,17 @@ Performance is a secondary goal behind correctness, safety, and clarity, but we Further instructions and details regarding backends can be found in the [curve25519-dalek docs](https://github.com/dalek-cryptography/curve25519-dalek#backends). +# Feature flags + +| Feature | Default? | Description | +|:---------------------|:--------:|:---------------------------------------------------------------------------| +| `zeroize` | ✓ | Enables the [`zeroize`][zeroize-trait] trait on key types, and implements `ZeroizeOnDrop` for secrets. | +| `reusable_secrets` | | Enables `ReusableSecret`, a Diffie-Hellman secret key that can be used more than once, but is not serializable. | +| `static_secrets` | | Enables `StaticSecret`, a Diffie-Hellman secret key that can be used more than once, and is serializable. | +| `os_rng` | | Enables `EphemeralSecret::random`, `ReusableSecret::random` and `StaticSecret::random` helpers that implicitly use the OS RNG. `random_from_rng` with an explicitly provided RNG is available without this feature. | +| `serde` | | Enables `serde` serialization/deserialization for `PublicKey` and `StaticSecret`. | +| `zerocopy` | | Enables [`zerocopy`][zerocopy] serialization/deserialization for `PublicKey` and `StaticSecret`. | + # Note This code matches the [RFC7748][rfc7748] test vectors. @@ -140,3 +151,5 @@ copyright © Amy Wibowo ([@sailorhg](https://twitter.com/sailorhg)) [fiat]: https://github.com/mit-plv/fiat-crypto [crypto_box]: https://github.com/RustCrypto/nacl-compat/tree/master/crypto_box +[zeroize-trait]: https://docs.rs/zeroize/latest/zeroize/trait.Zeroize.html +[zerocopy]: https://docs.rs/zerocopy/latest/zerocopy/ diff --git a/x25519-dalek/src/x25519.rs b/x25519-dalek/src/x25519.rs index 2d155f0d0..f86869286 100644 --- a/x25519-dalek/src/x25519.rs +++ b/x25519-dalek/src/x25519.rs @@ -30,6 +30,15 @@ use zeroize::{Zeroize, ZeroizeOnDrop}; /// (in this crate) does *not* automatically happen, but either must be derived /// for Drop or explicitly called. #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr( + feature = "zerocopy", + derive( + zerocopy::FromBytes, + zerocopy::IntoBytes, + zerocopy::Immutable, + zerocopy::KnownLayout + ) +)] #[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)] pub struct PublicKey(pub(crate) MontgomeryPoint); @@ -198,6 +207,15 @@ impl ZeroizeOnDrop for ReusableSecret {} /// implications for many protocols. #[cfg(feature = "static_secrets")] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr( + feature = "zerocopy", + derive( + zerocopy::FromBytes, + zerocopy::IntoBytes, + zerocopy::Immutable, + zerocopy::KnownLayout + ) +)] #[derive(Clone)] pub struct StaticSecret([u8; 32]);