From 7fcf935865f1098401b572719f3c48e78cbd4e2a Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 3 Oct 2019 14:49:33 -0700 Subject: [PATCH 0001/1461] universal-hash: OutputSize -> BlockSize (#57) --- universal-hash/src/lib.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/universal-hash/src/lib.rs b/universal-hash/src/lib.rs index 5f1c60645..26f7d913c 100644 --- a/universal-hash/src/lib.rs +++ b/universal-hash/src/lib.rs @@ -31,14 +31,14 @@ use subtle::{Choice, ConstantTimeEq}; pub trait UniversalHash: Clone { /// Size of the key for the universal hash function type KeySize: ArrayLength; - /// Size of the output from the universal hash function - type OutputSize: ArrayLength; + /// Size of the inputs to and outputs from the universal hash function + type BlockSize: ArrayLength; /// Instantiate a universal hash function with the given key fn new(key: &GenericArray) -> Self; /// Input a block into the universal hash function - fn update_block(&mut self, block: &GenericArray); + fn update_block(&mut self, block: &GenericArray); /// Input data into the universal hash function. If the length of the /// data is not a multiple of the block size, the remaining data is @@ -47,7 +47,7 @@ pub trait UniversalHash: Clone { /// This approach is frequently used by AEAD modes which use /// Message Authentication Codes (MACs) based on universal hashing. fn update_padded(&mut self, data: &[u8]) { - let mut chunks = data.chunks_exact(Self::OutputSize::to_usize()); + let mut chunks = data.chunks_exact(Self::BlockSize::to_usize()); for chunk in &mut chunks { self.update_block(GenericArray::from_slice(chunk)); @@ -66,11 +66,11 @@ pub trait UniversalHash: Clone { fn reset(&mut self); /// Obtain the [`Output`] of a `UniversalHash` function and consume it. - fn result(self) -> Output; + fn result(self) -> Output; /// Obtain the [`Output`] of a `UniversalHash` computation and reset it back /// to its initial state. - fn result_reset(&mut self) -> Output { + fn result_reset(&mut self) -> Output { let res = self.clone().result(); self.reset(); res @@ -79,7 +79,7 @@ pub trait UniversalHash: Clone { /// Verify the `UniversalHash` of the processed input matches a given [`Output`]. /// This is useful when constructing Message Authentication Codes (MACs) /// from universal hash functions. - fn verify(self, other: &GenericArray) -> Result<(), Error> { + fn verify(self, other: &GenericArray) -> Result<(), Error> { if self.result() == other.into() { Ok(()) } else { From 5b012e4b0637d7bbe21b30a816df5db033ba1179 Mon Sep 17 00:00:00 2001 From: newpavlov Date: Fri, 4 Oct 2019 00:51:14 +0300 Subject: [PATCH 0002/1461] universal-hash v0.3.0 --- universal-hash/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/universal-hash/Cargo.toml b/universal-hash/Cargo.toml index a2c4818f2..35b072e23 100644 --- a/universal-hash/Cargo.toml +++ b/universal-hash/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "universal-hash" -version = "0.2.0" +version = "0.3.0" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" description = "Trait for universal hash functions" From 8e522f8a12dffbb6a01f6f64da7b5a353968862c Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 17 Nov 2019 14:43:56 -0800 Subject: [PATCH 0003/1461] Add detached in-place encrypt/decrypt API; make alloc optional (#58) This commit adds `encrypt_in_place_detached()` and `decrypt_in_place_detached()` methods to `Aead` and `AeadMut`, along with default implementations of `encrypt()` and `decrypt()` which assume a postfix authentication tag. Presently all of the AEAD implementations in `RustCrypto/AEADs` use this pattern. This PR exposes the detached interface as a public API: https://github.com/RustCrypto/AEADs/pull/21 Note that this need not be the only in-place API (hence the long name with `_detached` on the end. I plan on doing a follow-up PR for adding an in-place API which does not depend on `alloc` but also handles ciphertext message assembly/parsing, which would be more useful for end users. That said, this API isn't just useful for AEAD implementers: there are genuine use cases for a detached API from an end user perspective, e.g encrypted filesystems. With the addition of this API, we can also make `alloc` an optional (but enabled-by-default) feature, allowing use of AEADs on truly `#![no_std]` targets. --- aead/Cargo.toml | 4 ++ aead/src/lib.rs | 132 ++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 131 insertions(+), 5 deletions(-) diff --git a/aead/Cargo.toml b/aead/Cargo.toml index beea5f4a2..95c278147 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -12,3 +12,7 @@ categories = ["cryptography", "no-std"] [dependencies] generic-array = { version = "0.12", default-features = false } + +[features] +default = ["alloc"] +alloc = [] diff --git a/aead/src/lib.rs b/aead/src/lib.rs index 4bc0fe43b..9c16bc529 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -14,13 +14,50 @@ #![no_std] +#[cfg(feature = "alloc")] extern crate alloc; pub use generic_array; +#[cfg(feature = "alloc")] use alloc::vec::Vec; use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; +// Define the default implementation for both `Aead::encrypt()` and +// `AeadMut::encrypt()`. Uses a macro to gloss over `&self` vs `&mut self`. +#[cfg(feature = "alloc")] +macro_rules! encrypt_to_postfix_tagged_vec { + ($aead:expr, $nonce:expr, $payload:expr) => {{ + let payload = $payload.into(); + let mut buffer = Vec::with_capacity(payload.msg.len() + Self::TagSize::to_usize()); + buffer.extend_from_slice(payload.msg); + + let tag = $aead.encrypt_in_place_detached($nonce, payload.aad, &mut buffer)?; + buffer.extend_from_slice(tag.as_slice()); + Ok(buffer) + }}; +} + +// Define the default implementation for both `Aead::decrypt()` and +// `AeadMut::decrypt()`. Uses a macro to gloss over `&self` vs `&mut self`. +#[cfg(feature = "alloc")] +macro_rules! decrypt_postfix_tagged_ciphertext_to_vec { + ($aead:expr, $nonce:expr, $payload:expr) => {{ + let payload = $payload.into(); + + if payload.msg.len() < Self::TagSize::to_usize() { + return Err(Error); + } + + let tag_start = payload.msg.len() - Self::TagSize::to_usize(); + let mut buffer = Vec::from(&payload.msg[..tag_start]); + let tag = GenericArray::from_slice(&payload.msg[tag_start..]); + $aead.decrypt_in_place_detached($nonce, payload.aad, &mut buffer, tag)?; + + Ok(buffer) + }}; +} + #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] pub struct Error; @@ -36,7 +73,7 @@ pub trait NewAead { /// Authenticated Encryption with Associated Data (AEAD) algorithm. /// /// This trait is intended for use with stateless AEAD algorithms. The -/// `AeadMut` trait provides a stateful interface. +/// [`AeadMut`] trait provides a stateful interface. pub trait Aead { /// The length of a nonce. type NonceSize: ArrayLength; @@ -64,11 +101,27 @@ pub trait Aead { /// let plaintext = b"Top secret message, handle with care"; /// let ciphertext = cipher.encrypt(nonce, plaintext); /// ``` + /// + /// The default implementation assumes a postfix tag (ala AES-GCM, + /// AES-GCM-SIV, ChaCha20Poly1305). [`Aead`] implementations which do not + /// use a postfix tag will need to override this to correctly assemble the + /// ciphertext message. + #[cfg(feature = "alloc")] fn encrypt<'msg, 'aad>( &self, nonce: &GenericArray, plaintext: impl Into>, - ) -> Result, Error>; + ) -> Result, Error> { + encrypt_to_postfix_tagged_vec!(self, nonce, plaintext) + } + + /// Encrypt the data in-place, returning the authentication tag + fn encrypt_in_place_detached( + &self, + nonce: &GenericArray, + associated_data: &[u8], + buffer: &mut [u8], + ) -> Result, Error>; /// Decrypt the given ciphertext slice, and return the resulting plaintext /// as a vector of bytes. @@ -82,11 +135,30 @@ pub trait Aead { /// let ciphertext = b"..."; /// let plaintext = cipher.decrypt(nonce, ciphertext)?; /// ``` + /// + /// The default implementation assumes a postfix tag (ala AES-GCM, + /// AES-GCM-SIV, ChaCha20Poly1305). [`Aead`] implementations which do not + /// use a postfix tag will need to override this to correctly parse the + /// ciphertext message. + #[cfg(feature = "alloc")] fn decrypt<'msg, 'aad>( &self, nonce: &GenericArray, ciphertext: impl Into>, - ) -> Result, Error>; + ) -> Result, Error> { + decrypt_postfix_tagged_ciphertext_to_vec!(self, nonce, ciphertext) + } + + /// Decrypt the data in-place, returning an error in the event the provided + /// authentication tag does not match the given ciphertext (i.e. ciphertext + /// is modified/unauthentic) + fn decrypt_in_place_detached( + &self, + nonce: &GenericArray, + associated_data: &[u8], + buffer: &mut [u8], + tag: &GenericArray, + ) -> Result<(), Error>; } /// Stateful Authenticated Encryption with Associated Data algorithm. @@ -104,22 +176,47 @@ pub trait AeadMut { /// /// See notes on [`Aead::encrypt()`] about allowable message payloads and /// Associated Additional Data (AAD). + #[cfg(feature = "alloc")] fn encrypt<'msg, 'aad>( &mut self, nonce: &GenericArray, plaintext: impl Into>, - ) -> Result, Error>; + ) -> Result, Error> { + encrypt_to_postfix_tagged_vec!(self, nonce, plaintext) + } + + /// Encrypt the data in-place, returning the authentication tag + fn encrypt_in_place_detached( + &mut self, + nonce: &GenericArray, + associated_data: &[u8], + buffer: &mut [u8], + ) -> Result, Error>; /// Decrypt the given ciphertext slice, and return the resulting plaintext /// as a vector of bytes. /// /// See notes on [`Aead::encrypt()`] and [`Aead::decrypt()`] about allowable /// message payloads and Associated Additional Data (AAD). + #[cfg(feature = "alloc")] fn decrypt<'msg, 'aad>( &mut self, nonce: &GenericArray, ciphertext: impl Into>, - ) -> Result, Error>; + ) -> Result, Error> { + decrypt_postfix_tagged_ciphertext_to_vec!(self, nonce, ciphertext) + } + + /// Decrypt the data in-place, returning an error in the event the provided + /// authentication tag does not match the given ciphertext (i.e. ciphertext + /// is modified/unauthentic) + fn decrypt_in_place_detached( + &mut self, + nonce: &GenericArray, + associated_data: &[u8], + buffer: &mut [u8], + tag: &GenericArray, + ) -> Result<(), Error>; } /// A blanket implementation of the Stateful AEAD interface for Stateless @@ -131,6 +228,7 @@ impl AeadMut for Algo { /// Encrypt the given plaintext slice, and return the resulting ciphertext /// as a vector of bytes. + #[cfg(feature = "alloc")] fn encrypt<'msg, 'aad>( &mut self, nonce: &GenericArray, @@ -139,8 +237,19 @@ impl AeadMut for Algo { ::encrypt(self, nonce, plaintext) } + /// Encrypt the data in-place, returning the authentication tag + fn encrypt_in_place_detached( + &mut self, + nonce: &GenericArray, + associated_data: &[u8], + buffer: &mut [u8], + ) -> Result, Error> { + ::encrypt_in_place_detached(self, nonce, associated_data, buffer) + } + /// Decrypt the given ciphertext slice, and return the resulting plaintext /// as a vector of bytes. + #[cfg(feature = "alloc")] fn decrypt<'msg, 'aad>( &mut self, nonce: &GenericArray, @@ -148,6 +257,19 @@ impl AeadMut for Algo { ) -> Result, Error> { ::decrypt(self, nonce, ciphertext) } + + /// Decrypt the data in-place, returning an error in the event the provided + /// authentication tag does not match the given ciphertext (i.e. ciphertext + /// is modified/unauthentic) + fn decrypt_in_place_detached( + &mut self, + nonce: &GenericArray, + associated_data: &[u8], + buffer: &mut [u8], + tag: &GenericArray, + ) -> Result<(), Error> { + ::decrypt_in_place_detached(self, nonce, associated_data, buffer, tag) + } } /// AEAD payloads are a combination of a message (plaintext or ciphertext) From 5222a4725e97654ba8279f7c249185c8b781e496 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 17 Nov 2019 15:35:16 -0800 Subject: [PATCH 0004/1461] aead: Add in-place API based on `Buffer` trait (#59) Defines a `Buffer` trait for `Vec`-like types which impl `AsRef<[u8]>`, `AsMut<[u8]>`, `extend_from_slice()`, and `truncate()`, and optionally impls it for `Vec` (when the `alloc` feature is enabled), along with the option to use `heapless::Vec` (when the `heapless` feature is enabled), providing a true `#![no_std]`-friendly option. Uses `impl Buffer` as the argument for `encrypt_in_place` and `decrypt_in_place`, with default implementations that assume a postfix authentication tag. This allows these methods to handle ciphertext assembly and parsing, after which they can invoke the `_detached` APIs. --- aead/Cargo.toml | 6 +- aead/src/lib.rs | 209 +++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 178 insertions(+), 37 deletions(-) diff --git a/aead/Cargo.toml b/aead/Cargo.toml index 95c278147..3916e9064 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -7,12 +7,16 @@ license = "MIT OR Apache-2.0" description = "Traits for Authenticated Encryption with Associated Data (AEAD) algorithms" documentation = "https://docs.rs/aead" repository = "https://github.com/RustCrypto/traits" -keywords = ["digest", "crypto", "encryption"] +keywords = ["crypto", "encryption"] categories = ["cryptography", "no-std"] [dependencies] generic-array = { version = "0.12", default-features = false } +heapless = { version = "0.5", optional = true } [features] default = ["alloc"] alloc = [] + +[package.metadata.docs.rs] +all-features = true diff --git a/aead/src/lib.rs b/aead/src/lib.rs index 9c16bc529..e2be03519 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -18,49 +18,35 @@ extern crate alloc; pub use generic_array; +#[cfg(feature = "heapless")] +pub use heapless; #[cfg(feature = "alloc")] use alloc::vec::Vec; use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; -// Define the default implementation for both `Aead::encrypt()` and -// `AeadMut::encrypt()`. Uses a macro to gloss over `&self` vs `&mut self`. -#[cfg(feature = "alloc")] -macro_rules! encrypt_to_postfix_tagged_vec { - ($aead:expr, $nonce:expr, $payload:expr) => {{ - let payload = $payload.into(); - let mut buffer = Vec::with_capacity(payload.msg.len() + Self::TagSize::to_usize()); - buffer.extend_from_slice(payload.msg); - - let tag = $aead.encrypt_in_place_detached($nonce, payload.aad, &mut buffer)?; - buffer.extend_from_slice(tag.as_slice()); - Ok(buffer) - }}; -} - -// Define the default implementation for both `Aead::decrypt()` and -// `AeadMut::decrypt()`. Uses a macro to gloss over `&self` vs `&mut self`. -#[cfg(feature = "alloc")] -macro_rules! decrypt_postfix_tagged_ciphertext_to_vec { - ($aead:expr, $nonce:expr, $payload:expr) => {{ - let payload = $payload.into(); +#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct Error; - if payload.msg.len() < Self::TagSize::to_usize() { +/// Implement the `decrypt_in_place` method on `Aead` and `AeadMut`. +/// Uses a macro to gloss over `&self` vs `&mut self`. +/// +/// Assumes a postfix authentication tag. AEAD ciphers which do not use a +/// postfix authentication tag will need to define their own implementation. +macro_rules! impl_decrypt_in_place { + ($aead:expr, $nonce:expr, $aad:expr, $buffer:expr) => {{ + if $buffer.len() < Self::TagSize::to_usize() { return Err(Error); } - let tag_start = payload.msg.len() - Self::TagSize::to_usize(); - let mut buffer = Vec::from(&payload.msg[..tag_start]); - let tag = GenericArray::from_slice(&payload.msg[tag_start..]); - $aead.decrypt_in_place_detached($nonce, payload.aad, &mut buffer, tag)?; - - Ok(buffer) + let tag_pos = $buffer.len() - Self::TagSize::to_usize(); + let (msg, tag) = $buffer.as_mut().split_at_mut(tag_pos); + $aead.decrypt_in_place_detached($nonce, $aad, msg, GenericArray::from_slice(tag))?; + $buffer.truncate(tag_pos); + Ok(()) }}; } -#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] -pub struct Error; - /// Instantiate either a stateless [`Aead`] or stateful [`AeadMut`] algorithm. pub trait NewAead { /// The size of the key array required by this algorithm. @@ -112,7 +98,31 @@ pub trait Aead { nonce: &GenericArray, plaintext: impl Into>, ) -> Result, Error> { - encrypt_to_postfix_tagged_vec!(self, nonce, plaintext) + let payload = plaintext.into(); + let mut buffer = Vec::with_capacity(payload.msg.len() + Self::TagSize::to_usize()); + buffer.extend_from_slice(payload.msg); + self.encrypt_in_place(nonce, payload.aad, &mut buffer)?; + Ok(buffer) + } + + /// Encrypt the given buffer containing a plaintext message in-place. + /// + /// The buffer must have sufficient capacity to store the ciphertext + /// message, which will always be larger than the original plaintext. + /// The exact size needed is cipher-dependent, but generally includes + /// the size of an authentication tag. + /// + /// Returns an error if the buffer has insufficient capacity to store the + /// resulting ciphertext message. + fn encrypt_in_place( + &self, + nonce: &GenericArray, + associated_data: &[u8], + buffer: &mut impl Buffer, + ) -> Result<(), Error> { + let tag = self.encrypt_in_place_detached(nonce, associated_data, buffer.as_mut())?; + buffer.extend_from_slice(tag.as_slice())?; + Ok(()) } /// Encrypt the data in-place, returning the authentication tag @@ -146,10 +156,27 @@ pub trait Aead { nonce: &GenericArray, ciphertext: impl Into>, ) -> Result, Error> { - decrypt_postfix_tagged_ciphertext_to_vec!(self, nonce, ciphertext) + let payload = ciphertext.into(); + let mut buffer = Vec::from(payload.msg); + self.decrypt_in_place(nonce, payload.aad, &mut buffer)?; + Ok(buffer) } - /// Decrypt the data in-place, returning an error in the event the provided + /// Decrypt the message in-place, returning an error in the event the + /// provided authentication tag does not match the given ciphertext. + /// + /// The buffer will be truncated to the length of the original plaintext + /// message upon success. + fn decrypt_in_place( + &self, + nonce: &GenericArray, + associated_data: &[u8], + buffer: &mut impl Buffer, + ) -> Result<(), Error> { + impl_decrypt_in_place!(self, nonce, associated_data, buffer) + } + + /// Decrypt the message in-place, returning an error in the event the provided /// authentication tag does not match the given ciphertext (i.e. ciphertext /// is modified/unauthentic) fn decrypt_in_place_detached( @@ -182,7 +209,31 @@ pub trait AeadMut { nonce: &GenericArray, plaintext: impl Into>, ) -> Result, Error> { - encrypt_to_postfix_tagged_vec!(self, nonce, plaintext) + let payload = plaintext.into(); + let mut buffer = Vec::with_capacity(payload.msg.len() + Self::TagSize::to_usize()); + buffer.extend_from_slice(payload.msg); + self.encrypt_in_place(nonce, payload.aad, &mut buffer)?; + Ok(buffer) + } + + /// Encrypt the given buffer containing a plaintext message in-place. + /// + /// The buffer must have sufficient capacity to store the ciphertext + /// message, which will always be larger than the original plaintext. + /// The exact size needed is cipher-dependent, but generally includes + /// the size of an authentication tag. + /// + /// Returns an error if the buffer has insufficient capacity to store the + /// resulting ciphertext message. + fn encrypt_in_place( + &mut self, + nonce: &GenericArray, + associated_data: &[u8], + buffer: &mut impl Buffer, + ) -> Result<(), Error> { + let tag = self.encrypt_in_place_detached(nonce, associated_data, buffer.as_mut())?; + buffer.extend_from_slice(tag.as_slice())?; + Ok(()) } /// Encrypt the data in-place, returning the authentication tag @@ -204,7 +255,24 @@ pub trait AeadMut { nonce: &GenericArray, ciphertext: impl Into>, ) -> Result, Error> { - decrypt_postfix_tagged_ciphertext_to_vec!(self, nonce, ciphertext) + let payload = ciphertext.into(); + let mut buffer = Vec::from(payload.msg); + self.decrypt_in_place(nonce, payload.aad, &mut buffer)?; + Ok(buffer) + } + + /// Decrypt the message in-place, returning an error in the event the + /// provided authentication tag does not match the given ciphertext. + /// + /// The buffer will be truncated to the length of the original plaintext + /// message upon success. + fn decrypt_in_place( + &mut self, + nonce: &GenericArray, + associated_data: &[u8], + buffer: &mut impl Buffer, + ) -> Result<(), Error> { + impl_decrypt_in_place!(self, nonce, associated_data, buffer) } /// Decrypt the data in-place, returning an error in the event the provided @@ -237,6 +305,16 @@ impl AeadMut for Algo { ::encrypt(self, nonce, plaintext) } + /// Encrypt the given buffer containing a plaintext message in-place. + fn encrypt_in_place( + &mut self, + nonce: &GenericArray, + associated_data: &[u8], + buffer: &mut impl Buffer, + ) -> Result<(), Error> { + ::encrypt_in_place(self, nonce, associated_data, buffer) + } + /// Encrypt the data in-place, returning the authentication tag fn encrypt_in_place_detached( &mut self, @@ -258,6 +336,17 @@ impl AeadMut for Algo { ::decrypt(self, nonce, ciphertext) } + /// Decrypt the message in-place, returning an error in the event the + /// provided authentication tag does not match the given ciphertext. + fn decrypt_in_place( + &mut self, + nonce: &GenericArray, + associated_data: &[u8], + buffer: &mut impl Buffer, + ) -> Result<(), Error> { + ::decrypt_in_place(self, nonce, associated_data, buffer) + } + /// Decrypt the data in-place, returning an error in the event the provided /// authentication tag does not match the given ciphertext (i.e. ciphertext /// is modified/unauthentic) @@ -294,3 +383,51 @@ impl<'msg, 'aad> From<&'msg [u8]> for Payload<'msg, 'aad> { Self { msg, aad: b"" } } } + +/// In-place encryption/decryption byte buffers. +/// +/// This trait defines the set of methods needed to support in-place operations +/// on a `Vec`-like data type. +pub trait Buffer: AsRef<[u8]> + AsMut<[u8]> { + /// Get the length of the buffer + fn len(&self) -> usize { + self.as_ref().len() + } + + /// Is the buffer empty? + fn is_empty(&self) -> bool { + self.as_ref().is_empty() + } + + /// Extend this buffer from the given slice + fn extend_from_slice(&mut self, other: &[u8]) -> Result<(), Error>; + + /// Truncate this buffer to the given size + fn truncate(&mut self, len: usize); +} + +#[cfg(feature = "alloc")] +impl Buffer for Vec { + fn extend_from_slice(&mut self, other: &[u8]) -> Result<(), Error> { + Vec::extend_from_slice(self, other); + Ok(()) + } + + fn truncate(&mut self, len: usize) { + Vec::truncate(self, len); + } +} + +#[cfg(feature = "heapless")] +impl Buffer for heapless::Vec +where + N: heapless::ArrayLength, +{ + fn extend_from_slice(&mut self, other: &[u8]) -> Result<(), Error> { + heapless::Vec::extend_from_slice(self, other).map_err(|_| Error) + } + + fn truncate(&mut self, len: usize) { + heapless::Vec::truncate(self, len); + } +} From 5cc7fbf9ae0f8ca18ccb086f8b0d324e3bb47732 Mon Sep 17 00:00:00 2001 From: newpavlov Date: Mon, 18 Nov 2019 02:37:00 +0300 Subject: [PATCH 0005/1461] temp disable no-std CI --- .travis.yml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index f459947b0..3d40e5ea7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,13 +23,14 @@ matrix: - env: TARGET=powerpc64-unknown-linux-gnu rust: stable # tests if crates truly can be built without std - - env: TARGET=thumbv7em-none-eabi - rust: nightly - script: xargo build --all --exclude aead --no-default-features --verbose --target $TARGET - install: - - cargo install xargo || true - - rustup target install armv7-unknown-linux-gnueabihf - - rustup component add rust-src + # temporary disable, since aead enables `alloc` by default + #- env: TARGET=thumbv7em-none-eabi + # rust: nightly + # script: xargo build --all --exclude aead --no-default-features --verbose --target $TARGET + # install: + # - cargo install xargo || true + # - rustup target install armv7-unknown-linux-gnueabihf + # - rustup component add rust-src install: - cargo install cross || true From 2003e14ef9bee82f88315f0b780d1e1d3351af14 Mon Sep 17 00:00:00 2001 From: newpavlov Date: Mon, 18 Nov 2019 02:43:20 +0300 Subject: [PATCH 0006/1461] aead v0.1.2 --- aead/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aead/Cargo.toml b/aead/Cargo.toml index 3916e9064..534ad0685 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aead" -version = "0.1.1" +version = "0.1.2" authors = ["RustCrypto Developers"] edition = "2018" license = "MIT OR Apache-2.0" From dbe69c197b3cd1e7492b1e4d5207ab7bc2aad5c1 Mon Sep 17 00:00:00 2001 From: newpavlov Date: Mon, 18 Nov 2019 02:45:13 +0300 Subject: [PATCH 0007/1461] re-enable no-std CI --- .travis.yml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3d40e5ea7..c52469769 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,14 +23,13 @@ matrix: - env: TARGET=powerpc64-unknown-linux-gnu rust: stable # tests if crates truly can be built without std - # temporary disable, since aead enables `alloc` by default - #- env: TARGET=thumbv7em-none-eabi - # rust: nightly - # script: xargo build --all --exclude aead --no-default-features --verbose --target $TARGET - # install: - # - cargo install xargo || true - # - rustup target install armv7-unknown-linux-gnueabihf - # - rustup component add rust-src + - env: TARGET=thumbv7em-none-eabi + rust: nightly + script: xargo build --all --exclude aead --verbose --target $TARGET + install: + - cargo install xargo || true + - rustup target install armv7-unknown-linux-gnueabihf + - rustup component add rust-src install: - cargo install cross || true From 4569d256f02ac0ecefa393baf225fb4a6df35875 Mon Sep 17 00:00:00 2001 From: newpavlov Date: Mon, 18 Nov 2019 07:15:58 +0300 Subject: [PATCH 0008/1461] aead v0.2.0 --- aead/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aead/Cargo.toml b/aead/Cargo.toml index 534ad0685..74c8b8abd 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aead" -version = "0.1.2" +version = "0.2.0" authors = ["RustCrypto Developers"] edition = "2018" license = "MIT OR Apache-2.0" From e020ecfd83c5d1f5d19b674d071b858ea1369088 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 30 Nov 2019 13:31:24 -0800 Subject: [PATCH 0009/1461] aead: Add optional `std` feature ...with `std::error::Error` impl for `aead::Error`. This is the least-common-bound for `std` users using a type erasure strategy for error handling, so it's helpful for error types to impl this trait when users want that. --- aead/Cargo.toml | 1 + aead/src/lib.rs | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/aead/Cargo.toml b/aead/Cargo.toml index 74c8b8abd..4007e3feb 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -17,6 +17,7 @@ heapless = { version = "0.5", optional = true } [features] default = ["alloc"] alloc = [] +std = ["alloc"] [package.metadata.docs.rs] all-features = true diff --git a/aead/src/lib.rs b/aead/src/lib.rs index e2be03519..61f29c01e 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -17,17 +17,30 @@ #[cfg(feature = "alloc")] extern crate alloc; +#[cfg(feature = "std")] +extern crate std; + pub use generic_array; #[cfg(feature = "heapless")] pub use heapless; #[cfg(feature = "alloc")] use alloc::vec::Vec; +use core::fmt; use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] pub struct Error; +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("aead::Error") + } +} + +#[cfg(feature = "std")] +impl std::error::Error for Error {} + /// Implement the `decrypt_in_place` method on `Aead` and `AeadMut`. /// Uses a macro to gloss over `&self` vs `&mut self`. /// From fc0f2bc6307b9881a46c3c3feb9888af66ef30df Mon Sep 17 00:00:00 2001 From: Emmanuel Gil Peyrot Date: Wed, 26 Feb 2020 11:18:04 +0100 Subject: [PATCH 0010/1461] Bump MSRV from 1.21 to 1.31 This is the first Rust version which stabilised editions, used by aead and universal-hash. --- .travis.yml | 4 ++-- README.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index c52469769..d3984dcec 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ sudo: required matrix: include: - - rust: 1.21.0 + - rust: 1.31.0 script: cargo test --verbose --all --exclude aead --exclude universal-hash --release - rust: 1.36.0 script: cargo test --verbose --package aead --package universal-hash --release @@ -13,7 +13,7 @@ matrix: - rust: nightly script: cargo test --verbose --all --release # tests if crates can be built with std feature - - rust: 1.21.0 + - rust: 1.31.0 script: ./build_std.sh - env: TARGET=i686-unknown-linux-gnu diff --git a/README.md b/README.md index 5d7291f6e..24ff0f669 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Collection of traits which describe functionality of cryptographic primitives. | [`stream-cipher`](https://en.wikipedia.org/wiki/Stream_cipher) | [![crates.io](https://img.shields.io/crates/v/stream-cipher.svg)](https://crates.io/crates/stream-cipher) | [![Documentation](https://docs.rs/stream-cipher/badge.svg)](https://docs.rs/stream-cipher) | ### Minimum Rust version -All crates in this repository support Rust 1.21 or higher. In future minimally +All crates in this repository support Rust 1.31 or higher. In future minimally supported version of Rust can be changed, but it will be done with the minor version bump. From 1a8bda7764e1e7253a9b9fc483d3cdbcc830e423 Mon Sep 17 00:00:00 2001 From: linkmauve Date: Wed, 26 Feb 2020 00:59:44 +0100 Subject: [PATCH 0011/1461] Remove deprecated std::error::Error::description() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It’s been deprecated since Rust 1.41, and we already have a Display implementation anyway. --- crypto-mac/src/errors.rs | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/crypto-mac/src/errors.rs b/crypto-mac/src/errors.rs index 8472a9637..2414d7d78 100644 --- a/crypto-mac/src/errors.rs +++ b/crypto-mac/src/errors.rs @@ -23,15 +23,7 @@ impl fmt::Display for InvalidKeyLength { } #[cfg(feature = "std")] -impl error::Error for MacError { - fn description(&self) -> &str { - "failed MAC verification" - } -} +impl error::Error for MacError {} #[cfg(feature = "std")] -impl error::Error for InvalidKeyLength { - fn description(&self) -> &str { - "invalid key length" - } -} +impl error::Error for InvalidKeyLength {} From 46d1da1af4a82ff637cda6ac83b788e1b5b698da Mon Sep 17 00:00:00 2001 From: "Chris West (Faux)" Date: Sat, 18 Jan 2020 11:57:16 +0000 Subject: [PATCH 0012/1461] chore: no-change generic-array 0.12 -> 0.13 --- aead/Cargo.toml | 2 +- block-cipher-trait/Cargo.toml | 2 +- crypto-mac/Cargo.toml | 2 +- digest/Cargo.toml | 4 ++-- stream-cipher/Cargo.toml | 2 +- universal-hash/Cargo.toml | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/aead/Cargo.toml b/aead/Cargo.toml index 74c8b8abd..082335c01 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -11,7 +11,7 @@ keywords = ["crypto", "encryption"] categories = ["cryptography", "no-std"] [dependencies] -generic-array = { version = "0.12", default-features = false } +generic-array = { version = "0.13", default-features = false } heapless = { version = "0.5", optional = true } [features] diff --git a/block-cipher-trait/Cargo.toml b/block-cipher-trait/Cargo.toml index 267798e1d..70e9e7785 100644 --- a/block-cipher-trait/Cargo.toml +++ b/block-cipher-trait/Cargo.toml @@ -10,7 +10,7 @@ keywords = ["crypto", "block-cipher", "trait"] categories = ["cryptography", "no-std"] [dependencies] -generic-array = "0.12" +generic-array = "0.13" blobby = { version = "0.1", optional = true } [features] diff --git a/crypto-mac/Cargo.toml b/crypto-mac/Cargo.toml index 51af928cd..2c521201a 100644 --- a/crypto-mac/Cargo.toml +++ b/crypto-mac/Cargo.toml @@ -10,7 +10,7 @@ keywords = ["crypto", "mac"] categories = ["cryptography", "no-std"] [dependencies] -generic-array = "0.12" +generic-array = "0.13" subtle = { version = "2", default-features = false } blobby = { version = "0.1", optional = true } diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 5825ca0ab..faeeff901 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -10,7 +10,7 @@ keywords = ["digest", "crypto", "hash"] categories = ["cryptography", "no-std"] [dependencies] -generic-array = "0.12" +generic-array = "0.13" blobby = { version = "0.1", optional = true } [features] @@ -21,4 +21,4 @@ dev = ["blobby"] travis-ci = { repository = "RustCrypto/traits" } [package.metadata.docs.rs] -features = ["std"] \ No newline at end of file +features = ["std"] diff --git a/stream-cipher/Cargo.toml b/stream-cipher/Cargo.toml index 7e0d1196f..159a1806b 100644 --- a/stream-cipher/Cargo.toml +++ b/stream-cipher/Cargo.toml @@ -10,7 +10,7 @@ keywords = ["crypto", "stream-cipher", "trait"] categories = ["cryptography", "no-std"] [dependencies] -generic-array = "0.12" +generic-array = "0.13" blobby = { version = "0.1", optional = true } [features] diff --git a/universal-hash/Cargo.toml b/universal-hash/Cargo.toml index 35b072e23..0f412af61 100644 --- a/universal-hash/Cargo.toml +++ b/universal-hash/Cargo.toml @@ -11,7 +11,7 @@ categories = ["cryptography", "no-std"] edition = "2018" [dependencies] -generic-array = "0.12" +generic-array = "0.13" subtle = { version = "2", default-features = false } [features] From 74565ca194ccea1373667c77284873e888426ea8 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 7 Mar 2020 18:20:05 -0800 Subject: [PATCH 0013/1461] signature: import from RustCrypto/signatures (c82b51e) Imports the code for the `signature` crate previously located at: https://github.com/RustCrypto/signatures/tree/c82b51eabf72b45a2ffb3964cb032d235c12627e/signature-crate Latest release is `v1.0.0-pre.1` --- signature/CHANGES.md | 47 +++++++++++ signature/Cargo.toml | 35 +++++++++ signature/README.md | 64 +++++++++++++++ signature/signature_derive/Cargo.toml | 21 +++++ signature/signature_derive/README.md | 27 +++++++ signature/signature_derive/src/lib.rs | 107 ++++++++++++++++++++++++++ signature/src/error.rs | 63 +++++++++++++++ signature/src/lib.rs | 50 ++++++++++++ signature/src/signature.rs | 31 ++++++++ signature/src/signer.rs | 44 +++++++++++ signature/src/verifier.rs | 35 +++++++++ signature/tests/signature_derive.rs | 76 ++++++++++++++++++ 12 files changed, 600 insertions(+) create mode 100644 signature/CHANGES.md create mode 100644 signature/Cargo.toml create mode 100644 signature/README.md create mode 100644 signature/signature_derive/Cargo.toml create mode 100644 signature/signature_derive/README.md create mode 100644 signature/signature_derive/src/lib.rs create mode 100644 signature/src/error.rs create mode 100644 signature/src/lib.rs create mode 100644 signature/src/signature.rs create mode 100644 signature/src/signer.rs create mode 100644 signature/src/verifier.rs create mode 100644 signature/tests/signature_derive.rs diff --git a/signature/CHANGES.md b/signature/CHANGES.md new file mode 100644 index 000000000..1059f4e1a --- /dev/null +++ b/signature/CHANGES.md @@ -0,0 +1,47 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## 1.0.0-pre.1 (2019-10-27) +### Changed +- Use `Error::source` instead of `::cause` ([#37]) + +### Removed +- Remove `alloc` feature; MSRV 1.34+ ([#38]) + +[#38]: https://github.com/RustCrypto/signatures/pull/38 +[#37]: https://github.com/RustCrypto/signatures/pull/37 + +## 1.0.0-pre.0 (2019-10-11) +### Changed +- Revert removal of `DigestSignature` ([#33]) +- 1.0 stabilization proposal ([#32]) + +[#33]: https://github.com/RustCrypto/signatures/pull/33 +[#32]: https://github.com/RustCrypto/signatures/pull/32 + +## 0.3.0 (2019-10-10) +### Changed +- Simplify alloc gating; MSRV 1.36+ ([#28]) +- Replace `DigestSignature` trait with `#[digest(...)]` attribute ([#27]) +- signature_derive: Upgrade to 1.x proc macro crates ([#26]) + +[#28]: https://github.com/RustCrypto/signatures/pull/28 +[#27]: https://github.com/RustCrypto/signatures/pull/27 +[#26]: https://github.com/RustCrypto/signatures/pull/27 + +## 0.2.0 (2019-06-06) +### Added +- `signature_derive`: Custom derive support for `Signer`/`Verifier` ([#18]) + +### Changed +- Have `DigestSigner`/`DigestVerifier` take `Digest` instance ([#17]) + +[#18]: https://github.com/RustCrypto/signatures/pull/18 +[#17]: https://github.com/RustCrypto/signatures/pull/17 + +## 0.1.0 (2019-05-25) + +- Initial release diff --git a/signature/Cargo.toml b/signature/Cargo.toml new file mode 100644 index 000000000..cc7f8ce4d --- /dev/null +++ b/signature/Cargo.toml @@ -0,0 +1,35 @@ +[package] +name = "signature" +description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" +version = "1.0.0-pre.1" # Also update html_root_url in lib.rs when bumping this +authors = ["RustCrypto Developers"] +license = "Apache-2.0 OR MIT" +documentation = "https://docs.rs/signature" +repository = "https://github.com/RustCrypto/signatures/tree/master/signature-crate" +readme = "README.md" +edition = "2018" +keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"] +categories = ["cryptography", "no-std"] + +[dependencies.digest] +version = "0.8" +optional = true +default-features = false + +[dependencies.signature_derive] +version = "1.0.0-pre.0" +optional = true +path = "signature_derive" + +[dev-dependencies] +hex-literal = "0.2" +sha2 = { version = "0.8", default-features = false } + +[features] +default = ["std"] +derive-preview = ["digest-preview", "signature_derive"] +digest-preview = ["digest"] +std = [] + +[package.metadata.docs.rs] +all-features = true diff --git a/signature/README.md b/signature/README.md new file mode 100644 index 000000000..b42f68767 --- /dev/null +++ b/signature/README.md @@ -0,0 +1,64 @@ +# `signature` crate + +[![crate][crate-image]][crate-link] +[![Docs][docs-image]][docs-link] +![Apache2/MIT licensed][license-image] +![Rust Version][rustc-image] +[![Build Status][build-image]][build-link] + +This crate contains traits which provide generic, object-safe APIs for +generating and verifying [digital signatures][1]. + +It's presently useful in conjunction with the [`ed25519`][2] crate. +Support is also planned for the [`ecdsa`][3] and [`rsa`][4] crates. + +[Documentation][docs-link] + +## Minimum Supported Rust Version + +All crates in this repository support Rust **1.37** or higher. + +Minimum supported Rust version can be changed in the future, but it will be +done with a minor version bump. + +## SemVer Policy + +- All on-by-default features of this library are covered by SemVer +- MSRV is considered exempt from SemVer as noted above +- The off-by-default features `derive-preview` and `digest-preview` are + unstable "preview" features which are also considered exempt from SemVer. + Breaking changes to these features will, like MSRV, be done with a minor + version bump. + +## License + +All crates licensed under either of + + * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) + * [MIT license](http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall be +dual licensed as above, without any additional terms or conditions. + +[//]: # (badges) + +[crate-image]: https://img.shields.io/crates/v/signature.svg +[crate-link]: https://crates.io/crates/signature +[docs-image]: https://docs.rs/signature/badge.svg +[docs-link]: https://docs.rs/signature/ +[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.34+-blue.svg +[build-image]: https://travis-ci.org/RustCrypto/signatures.svg?branch=master +[build-link]: https://travis-ci.org/RustCrypto/signatures + +[//]: # (general links) + +[1]: https://en.wikipedia.org/wiki/Digital_signature +[2]: https://github.com/RustCrypto/signatures/tree/master/ed25519 +[3]: https://github.com/RustCrypto/signatures/tree/master/ecdsa +[4]: https://github.com/RustCrypto/RSA diff --git a/signature/signature_derive/Cargo.toml b/signature/signature_derive/Cargo.toml new file mode 100644 index 000000000..5b006b1f4 --- /dev/null +++ b/signature/signature_derive/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "signature_derive" +version = "1.0.0-pre.0" +authors = ["RustCrypto Developers"] +license = "Apache-2.0 OR MIT" +description = "Custom derive support for the 'signature' crate" +documentation = "https://docs.rs/signature" +repository = "https://github.com/RustCrypto/signatures/tree/master/signature-crate/" +readme = "README.md" +edition = "2018" +keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"] +categories = ["cryptography", "no-std"] + +[lib] +proc-macro = true + +[dependencies] +proc-macro2 = "1" +quote = "1" +syn = "1" +synstructure = "0.12" diff --git a/signature/signature_derive/README.md b/signature/signature_derive/README.md new file mode 100644 index 000000000..6f0350147 --- /dev/null +++ b/signature/signature_derive/README.md @@ -0,0 +1,27 @@ +# `signature` crate custom derive support + +[![Build Status](https://travis-ci.org/RustCrypto/signatures.svg?branch=master)](https://travis-ci.org/RustCrypto/signatures) + +This crate provides proc macros used by the `signature` crate. + +It's not intended to be used directly. See the signature crate's documentation +for additional details: + +[Documentation][docs] + +## License + +All crates licensed under either of + + * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) + * [MIT license](http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall be +dual licensed as above, without any additional terms or conditions. + +[Documentation]: https://docs.rs/signature/ diff --git a/signature/signature_derive/src/lib.rs b/signature/signature_derive/src/lib.rs new file mode 100644 index 000000000..aa0953f99 --- /dev/null +++ b/signature/signature_derive/src/lib.rs @@ -0,0 +1,107 @@ +//! Custom derive support for the `signature` crate. +//! +//! This crate can be used to derive `Signer` and `Verifier` impls for +//! types that impl `DigestSigner` or `DigestVerifier` respectively. + +#![crate_type = "proc-macro"] +#![recursion_limit = "128"] +#![deny(warnings, unused_import_braces, unused_qualifications)] +#![forbid(unsafe_code)] + +extern crate proc_macro; + +use proc_macro2::TokenStream; +use quote::quote; +use synstructure::{decl_derive, AddBounds}; + +/// Derive the `Signer` trait for `DigestSigner` types +fn derive_signer(mut s: synstructure::Structure) -> TokenStream { + s.add_bounds(AddBounds::None); + s.gen_impl(quote! { + gen impl signature::Signer for @Self + where + S: signature::DigestSignature, + Self: signature::DigestSigner + { + fn try_sign(&self, msg: &[u8]) -> Result { + self.try_sign_digest(S::Digest::new().chain(msg)) + } + } + }) +} +decl_derive!([Signer] => derive_signer); + +/// Derive the `Verifier` trait for `DigestVerifier` types +fn derive_verifier(mut s: synstructure::Structure) -> TokenStream { + s.add_bounds(AddBounds::None); + s.gen_impl(quote! { + gen impl signature::Verifier for @Self + where + S: signature::DigestSignature, + Self: signature::DigestVerifier + { + fn verify(&self, msg: &[u8], signature: &S) -> Result<(), signature::Error> { + self.verify_digest(S::Digest::new().chain(msg), signature) + } + } + }) +} +decl_derive!([Verifier] => derive_verifier); + +#[cfg(test)] +mod tests { + use super::*; + use synstructure::test_derive; + + #[test] + fn signer() { + test_derive! { + derive_signer { + struct MySigner { + scalar: Scalar + } + } + expands to { + #[allow(non_upper_case_globals)] + const _DERIVE_signature_Signer_S_FOR_MySigner: () = { + impl signature::Signer for MySigner + where + S: signature::DigestSignature, + Self: signature::DigestSigner + { + fn try_sign(&self, msg: &[u8]) -> Result { + self.try_sign_digest(S::Digest::new().chain(msg)) + } + } + }; + } + no_build // tests in `signature-crate/tests` + } + } + + #[test] + fn verifier() { + test_derive! { + derive_verifier { + struct MyVerifier { + point: UncompressedPoint + } + } + expands to { + #[allow(non_upper_case_globals)] + const _DERIVE_signature_Verifier_S_FOR_MyVerifier: () = { + impl signature::Verifier for MyVerifier + where + S: signature::DigestSignature, + Self: signature::DigestVerifier + { + fn verify(&self, msg: &[u8], signature: &S) -> Result<(), signature::Error> { + self.verify_digest(S::Digest::new().chain(msg), signature) + } + } + }; + } + no_build // tests in `signature-crate/tests` + } + } +} diff --git a/signature/src/error.rs b/signature/src/error.rs new file mode 100644 index 000000000..c864d979d --- /dev/null +++ b/signature/src/error.rs @@ -0,0 +1,63 @@ +//! Signature error types + +use core::fmt::{self, Display}; + +#[cfg(feature = "std")] +use std::boxed::Box; + +/// Box containing a thread-safe + `'static` error suitable for use as a +/// as an `std::error::Error::source` +#[cfg(feature = "std")] +pub type BoxError = Box; + +/// Signature errors +#[derive(Debug, Default)] +pub struct Error { + /// Source of the error (if applicable). + #[cfg(feature = "std")] + source: Option, +} + +impl Error { + /// Create a new error with no associated source + pub fn new() -> Self { + Self::default() + } + + /// Create a new error with an associated source. + /// + /// **NOTE:** The "source" should NOT be used to propagate cryptographic + /// errors e.g. signature parsing or verification errors. The intended use + /// cases are for propagating errors related to external signers, e.g. + /// communication/authentication errors with HSMs, KMS, etc. + #[cfg(feature = "std")] + pub fn from_source(source: impl Into) -> Self { + Self { + source: Some(source.into()), + } + } +} + +impl Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "signature error")?; + + #[cfg(feature = "std")] + { + if let Some(ref source) = self.source { + write!(f, ": {}", source)?; + } + } + + Ok(()) + } +} + +#[cfg(feature = "std")] +impl std::error::Error for Error { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + self.source + .as_ref() + .map(|source| source.as_ref() as &(dyn std::error::Error + 'static)) + } +} diff --git a/signature/src/lib.rs b/signature/src/lib.rs new file mode 100644 index 000000000..0d69fc94f --- /dev/null +++ b/signature/src/lib.rs @@ -0,0 +1,50 @@ +//! Traits which provide generic, object-safe APIs for generating and verifying +//! digital signatures, which provide message authentication using public-key +//! cryptography. +//! +//! ## Minimum Supported Rust Version +//! +//! Rust **1.34** or higher. +//! +//! Minimum supported Rust version can be changed in the future, but it will be +//! done with a minor version bump. +//! +//! ## SemVer Policy +//! +//! - All on-by-default features of this library are covered by SemVer +//! - MSRV is considered exempt from SemVer as noted above +//! - The off-by-default features `derive-preview` and `digest-preview` are +//! unstable "preview" features which are also considered exempt from SemVer. +//! Breaking changes to these features will, like MSRV, be done with a minor +//! version bump. + +#![no_std] +#![forbid(unsafe_code)] +#![warn(missing_docs, rust_2018_idioms, unused_qualifications)] +#![doc( + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png", + html_root_url = "https://docs.rs/signature/1.0.0-pre.1" +)] + +#[cfg(feature = "std")] +#[macro_use] +extern crate std; + +#[cfg(feature = "derive-preview")] +#[allow(unused_imports)] +#[macro_use] +extern crate signature_derive; + +#[cfg(feature = "derive-preview")] +#[doc(hidden)] +pub use signature_derive::{Signer, Verifier}; + +#[cfg(feature = "digest-preview")] +pub use digest; + +mod error; +mod signature; +mod signer; +mod verifier; + +pub use crate::{error::*, signature::*, signer::*, verifier::*}; diff --git a/signature/src/signature.rs b/signature/src/signature.rs new file mode 100644 index 000000000..2f2455b7f --- /dev/null +++ b/signature/src/signature.rs @@ -0,0 +1,31 @@ +//! Signature traits + +use crate::error::Error; +use core::fmt::Debug; + +/// Trait impl'd by concrete types that represent digital signatures +pub trait Signature: AsRef<[u8]> + Debug + Sized { + /// Parse a signature from its byte representation + fn from_bytes(bytes: impl AsRef<[u8]>) -> Result; + + /// Borrow this signature as serialized bytes + fn as_slice(&self) -> &[u8] { + self.as_ref() + } +} + +/// Marker trait for `Signature` types computable as `S(H(m))` +/// +/// - `S`: signature algorithm +/// - `H`: hash (a.k.a. digest) function +/// - `m`: message +/// +/// For signature types that implement this trait, when the `derive-preview` +/// Cargo feature is enabled a custom derive for `Signer` is available for any +/// types that impl `DigestSigner`, and likewise for deriving `Verifier` for +/// types which impl `DigestVerifier`. +#[cfg(feature = "digest")] +pub trait DigestSignature: Signature { + /// Preferred `Digest` algorithm to use when computing this signature type. + type Digest: digest::Digest; +} diff --git a/signature/src/signer.rs b/signature/src/signer.rs new file mode 100644 index 000000000..e74d00449 --- /dev/null +++ b/signature/src/signer.rs @@ -0,0 +1,44 @@ +//! Traits for generating digital signatures + +#[cfg(feature = "digest-preview")] +use crate::digest::Digest; +use crate::{error::Error, Signature}; + +/// Sign the provided message bytestring using `Self` (e.g. a cryptographic key +/// or connection to an HSM), returning a digital signature. +pub trait Signer { + /// Sign the given message and return a digital signature + fn sign(&self, msg: &[u8]) -> S { + self.try_sign(msg).expect("signature operation failed") + } + + /// Attempt to sign the given message, returning a digital signature on + /// success, or an error if something went wrong. + /// + /// The main intended use case for signing errors is when communicating + /// with external signers, e.g. cloud KMS, HSMs, or other hardware tokens. + fn try_sign(&self, msg: &[u8]) -> Result; +} + +/// Sign the given prehashed message `Digest` using `Self`. +/// +/// This trait is only available when the `digest-preview` cargo feature is +/// enabled. +#[cfg(feature = "digest-preview")] +pub trait DigestSigner +where + D: Digest, + S: Signature, +{ + /// Sign the given prehashed message `Digest`, returning a signature. + /// + /// Panics in the event of a signing error. + fn sign_digest(&self, digest: D) -> S { + self.try_sign_digest(digest) + .expect("signature operation failed") + } + + /// Attempt to sign the given prehashed message `Digest`, returning a + /// digital signature on success, or an error if something went wrong. + fn try_sign_digest(&self, digest: D) -> Result; +} diff --git a/signature/src/verifier.rs b/signature/src/verifier.rs new file mode 100644 index 000000000..b1884bd19 --- /dev/null +++ b/signature/src/verifier.rs @@ -0,0 +1,35 @@ +//! Trait for verifying digital signatures + +#[cfg(feature = "digest-preview")] +use crate::digest::Digest; +use crate::{error::Error, Signature}; + +/// Verify the provided message bytestring using `Self` (e.g. a public key) +pub trait Verifier { + /// Use `Self` to verify that the provided signature for a given message + /// bytestring is authentic. + /// + /// Returns `Error` if it is inauthentic, or otherwise returns `()`. + fn verify(&self, msg: &[u8], signature: &S) -> Result<(), Error>; +} + +/// Verify the provided signature for the given prehashed message `Digest` +/// is authentic. +/// +/// This trait is only available when the `digest-preview` cargo feature is +/// enabled. +/// +/// It accepts a [`Digest`] instance, as opposed to a raw digest byte array, +/// as the security of signature algorithms built on hash functions often +/// depends critically on the input being a random oracle as opposed to a +/// value an attacker can choose and solve for. This is enforced at the API +/// level by taking a [`Digest`] instance in order to better resist misuse. +#[cfg(feature = "digest-preview")] +pub trait DigestVerifier +where + D: Digest, + S: Signature, +{ + /// Verify the signature against the given `Digest` output. + fn verify_digest(&self, digest: D, signature: &S) -> Result<(), Error>; +} diff --git a/signature/tests/signature_derive.rs b/signature/tests/signature_derive.rs new file mode 100644 index 000000000..931624b2c --- /dev/null +++ b/signature/tests/signature_derive.rs @@ -0,0 +1,76 @@ +/// "Tests" for code generated by `signature_derive` +#[cfg(all(test, feature = "derive-preview"))] +mod tests { + use digest::{generic_array::GenericArray, Digest}; + use hex_literal::hex; + use sha2::Sha256; + use signature::{ + DigestSignature, DigestSigner, DigestVerifier, Error, Signature, Signer, Verifier, + }; + + /// Test vector to compute SHA-256 digest of + const INPUT_STRING: &[u8] = b"abc"; + + /// Expected SHA-256 digest for the input string + const INPUT_STRING_DIGEST: [u8; 32] = + hex!("ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad"); + + /// Dummy signature which just contains a digest output + #[derive(Debug)] + struct DummySignature(GenericArray::OutputSize>); + + impl Signature for DummySignature { + fn from_bytes(bytes: impl AsRef<[u8]>) -> Result { + Ok(DummySignature(GenericArray::clone_from_slice( + bytes.as_ref(), + ))) + } + } + + impl AsRef<[u8]> for DummySignature { + fn as_ref(&self) -> &[u8] { + self.0.as_ref() + } + } + + impl DigestSignature for DummySignature { + type Digest = Sha256; + } + + /// Dummy signer which just returns the message digest as a `DummySignature` + #[derive(Signer, Default)] + struct DummySigner {} + + impl DigestSigner for DummySigner { + fn try_sign_digest(&self, digest: Sha256) -> Result { + DummySignature::from_bytes(digest.result()) + } + } + + /// Dummy verifier which ensures the `DummySignature` digest matches the + /// expected value. + /// + /// Panics (via `assert_eq!`) if the value is not what is expected. + #[derive(Verifier, Default)] + struct DummyVerifier {} + + impl DigestVerifier for DummyVerifier { + fn verify_digest(&self, digest: Sha256, signature: &DummySignature) -> Result<(), Error> { + let actual_digest = digest.result(); + assert_eq!(signature.as_ref(), actual_digest.as_ref()); + Ok(()) + } + } + + #[test] + fn derived_signer_impl() { + let sig: DummySignature = DummySigner::default().sign(INPUT_STRING); + assert_eq!(sig.as_ref(), INPUT_STRING_DIGEST.as_ref()) + } + + #[test] + fn derived_verifier_impl() { + let sig: DummySignature = DummySigner::default().sign(INPUT_STRING); + assert!(DummyVerifier::default().verify(INPUT_STRING, &sig).is_ok()); + } +} From b9c1558047a70466ad9871a978bd48aa1935acb2 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 7 Mar 2020 18:27:04 -0800 Subject: [PATCH 0014/1461] signature: fixups for new crate location Updates CI config and docs to note `signature` crate's new location in this repository. --- .travis.yml | 8 +++--- Cargo.toml | 1 + README.md | 9 ++++--- build_std.sh | 2 +- signature/CHANGES.md | 36 +++++++++++++-------------- signature/Cargo.toml | 2 +- signature/README.md | 8 +++--- signature/signature_derive/Cargo.toml | 2 +- signature/signature_derive/README.md | 6 ++--- 9 files changed, 39 insertions(+), 35 deletions(-) diff --git a/.travis.yml b/.travis.yml index d3984dcec..5a4fcef3d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,9 +5,9 @@ sudo: required matrix: include: - rust: 1.31.0 - script: cargo test --verbose --all --exclude aead --exclude universal-hash --release + script: cargo test --verbose --all --exclude aead --exclude signature --exclude universal-hash --release - rust: 1.36.0 - script: cargo test --verbose --package aead --package universal-hash --release + script: cargo test --verbose --package aead --package signature --package universal-hash --release - rust: stable script: cargo test --verbose --all --release - rust: nightly @@ -25,7 +25,7 @@ matrix: # tests if crates truly can be built without std - env: TARGET=thumbv7em-none-eabi rust: nightly - script: xargo build --all --exclude aead --verbose --target $TARGET + script: xargo build --all --exclude aead --exclude signature --verbose --target $TARGET install: - cargo install xargo || true - rustup target install armv7-unknown-linux-gnueabihf @@ -35,6 +35,6 @@ install: - cargo install cross || true script: - - cross test --verbose --all --release --target $TARGET + - cross test --verbose --all --exclude signature_derive --release --target $TARGET cache: cargo diff --git a/Cargo.toml b/Cargo.toml index 0a206ff3b..421cdb5cd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,7 @@ members = [ "block-cipher-trait", "crypto-mac", "digest", + "signature", "stream-cipher", "universal-hash", ] diff --git a/README.md b/README.md index 24ff0f669..dd1743e25 100644 --- a/README.md +++ b/README.md @@ -4,15 +4,18 @@ Collection of traits which describe functionality of cryptographic primitives. ## Crates | Name | Crates.io | Documentation | | ------- | :---------:| :-------------:| +| [`aead`](hhttps://en.wikipedia.org/wiki/Authenticated_encryption)| [![crates.io](https://img.shields.io/crates/v/aead.svg)](https://crates.io/crates/aead) | [![Documentation](https://docs.rs/aead/badge.svg)](https://docs.rs/aead) | | [`block-cipher-trait`](https://en.wikipedia.org/wiki/Block_cipher)| [![crates.io](https://img.shields.io/crates/v/block-cipher-trait.svg)](https://crates.io/crates/block-cipher-trait) | [![Documentation](https://docs.rs/block-cipher-trait/badge.svg)](https://docs.rs/block-cipher-trait) | | [`crypto-mac`](https://en.wikipedia.org/wiki/Message_authentication_code) | [![crates.io](https://img.shields.io/crates/v/crypto-mac.svg)](https://crates.io/crates/crypto-mac) | [![Documentation](https://docs.rs/crypto-mac/badge.svg)](https://docs.rs/crypto-mac) | | [`digest`](https://en.wikipedia.org/wiki/Cryptographic_hash_function) | [![crates.io](https://img.shields.io/crates/v/digest.svg)](https://crates.io/crates/digest) | [![Documentation](https://docs.rs/digest/badge.svg)](https://docs.rs/digest) | +| [`signature`](https://en.wikipedia.org/wiki/Digital_signature) | [![crates.io](https://img.shields.io/crates/v/signature.svg)](https://crates.io/crates/stream-cipher) | [![Documentation](https://docs.rs/signature/badge.svg)](https://docs.rs/signature) | | [`stream-cipher`](https://en.wikipedia.org/wiki/Stream_cipher) | [![crates.io](https://img.shields.io/crates/v/stream-cipher.svg)](https://crates.io/crates/stream-cipher) | [![Documentation](https://docs.rs/stream-cipher/badge.svg)](https://docs.rs/stream-cipher) | ### Minimum Rust version -All crates in this repository support Rust 1.31 or higher. In future minimally -supported version of Rust can be changed, but it will be done with the minor -version bump. +All crates in this repository support Rust 1.31 or higher unless otherwise noted. + +In future minimally supported version of Rust can be changed, but it will be done +with the minor version bump. ## License diff --git a/build_std.sh b/build_std.sh index 3ec9fdd71..8543eaa02 100755 --- a/build_std.sh +++ b/build_std.sh @@ -7,7 +7,7 @@ TARGET="thumbv7em-none-eabi" cargo clean for DIR in $DIRS; do - if [ $DIR = "target/" -o $DIR = "aead/" -o $DIR = "universal-hash/" ] + if [ $DIR = "target/" -o $DIR = "aead/" -o $DIR = "signature/" -o $DIR = "universal-hash/" ] then continue fi diff --git a/signature/CHANGES.md b/signature/CHANGES.md index 1059f4e1a..c9364756c 100644 --- a/signature/CHANGES.md +++ b/signature/CHANGES.md @@ -6,41 +6,41 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## 1.0.0-pre.1 (2019-10-27) ### Changed -- Use `Error::source` instead of `::cause` ([#37]) +- Use `Error::source` instead of `::cause` ([RustCrypto/signatures#37]) ### Removed -- Remove `alloc` feature; MSRV 1.34+ ([#38]) +- Remove `alloc` feature; MSRV 1.34+ ([RustCrypto/signatures#38]) -[#38]: https://github.com/RustCrypto/signatures/pull/38 -[#37]: https://github.com/RustCrypto/signatures/pull/37 +[RustCrypto/signatures#38]: https://github.com/RustCrypto/signatures/pull/38 +[RustCrypto/signatures#37]: https://github.com/RustCrypto/signatures/pull/37 ## 1.0.0-pre.0 (2019-10-11) ### Changed -- Revert removal of `DigestSignature` ([#33]) -- 1.0 stabilization proposal ([#32]) +- Revert removal of `DigestSignature` ([RustCrypto/signatures#33]) +- 1.0 stabilization proposal ([RustCrypto/signatures#32]) -[#33]: https://github.com/RustCrypto/signatures/pull/33 -[#32]: https://github.com/RustCrypto/signatures/pull/32 +[RustCrypto/signatures#33]: https://github.com/RustCrypto/signatures/pull/33 +[RustCrypto/signatures#32]: https://github.com/RustCrypto/signatures/pull/32 ## 0.3.0 (2019-10-10) ### Changed -- Simplify alloc gating; MSRV 1.36+ ([#28]) -- Replace `DigestSignature` trait with `#[digest(...)]` attribute ([#27]) -- signature_derive: Upgrade to 1.x proc macro crates ([#26]) +- Simplify alloc gating; MSRV 1.36+ ([RustCrypto/signatures#28]) +- Replace `DigestSignature` trait with `#[digest(...)]` attribute ([RustCrypto/signatures#27]) +- signature_derive: Upgrade to 1.x proc macro crates ([RustCrypto/signatures#26]) -[#28]: https://github.com/RustCrypto/signatures/pull/28 -[#27]: https://github.com/RustCrypto/signatures/pull/27 -[#26]: https://github.com/RustCrypto/signatures/pull/27 +[RustCrypto/signatures#28]: https://github.com/RustCrypto/signatures/pull/28 +[RustCrypto/signatures#27]: https://github.com/RustCrypto/signatures/pull/27 +[RustCrypto/signatures#26]: https://github.com/RustCrypto/signatures/pull/27 ## 0.2.0 (2019-06-06) ### Added -- `signature_derive`: Custom derive support for `Signer`/`Verifier` ([#18]) +- `signature_derive`: Custom derive support for `Signer`/`Verifier` ([RustCrypto/signatures#18]) ### Changed -- Have `DigestSigner`/`DigestVerifier` take `Digest` instance ([#17]) +- Have `DigestSigner`/`DigestVerifier` take `Digest` instance ([RustCrypto/signatures#17]) -[#18]: https://github.com/RustCrypto/signatures/pull/18 -[#17]: https://github.com/RustCrypto/signatures/pull/17 +[RustCrypto/signatures#18]: https://github.com/RustCrypto/signatures/pull/18 +[RustCrypto/signatures#17]: https://github.com/RustCrypto/signatures/pull/17 ## 0.1.0 (2019-05-25) diff --git a/signature/Cargo.toml b/signature/Cargo.toml index cc7f8ce4d..e11f8b684 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -5,7 +5,7 @@ version = "1.0.0-pre.1" # Also update html_root_url in lib.rs when bumping authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/signature" -repository = "https://github.com/RustCrypto/signatures/tree/master/signature-crate" +repository = "https://github.com/RustCrypto/traits/tree/master/signature" readme = "README.md" edition = "2018" keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"] diff --git a/signature/README.md b/signature/README.md index b42f68767..20242fa20 100644 --- a/signature/README.md +++ b/signature/README.md @@ -16,7 +16,7 @@ Support is also planned for the [`ecdsa`][3] and [`rsa`][4] crates. ## Minimum Supported Rust Version -All crates in this repository support Rust **1.37** or higher. +All crates in this repository support Rust **1.36** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -52,9 +52,9 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/signature/badge.svg [docs-link]: https://docs.rs/signature/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.34+-blue.svg -[build-image]: https://travis-ci.org/RustCrypto/signatures.svg?branch=master -[build-link]: https://travis-ci.org/RustCrypto/signatures +[rustc-image]: https://img.shields.io/badge/rustc-1.36+-blue.svg +[build-image]: https://travis-ci.org/RustCrypto/traits.svg?branch=master +[build-link]: https://travis-ci.org/RustCrypto/traits [//]: # (general links) diff --git a/signature/signature_derive/Cargo.toml b/signature/signature_derive/Cargo.toml index 5b006b1f4..262f02d19 100644 --- a/signature/signature_derive/Cargo.toml +++ b/signature/signature_derive/Cargo.toml @@ -5,7 +5,7 @@ authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" description = "Custom derive support for the 'signature' crate" documentation = "https://docs.rs/signature" -repository = "https://github.com/RustCrypto/signatures/tree/master/signature-crate/" +repository = "https://github.com/RustCrypto/traits/tree/master/signature/signature_derive" readme = "README.md" edition = "2018" keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"] diff --git a/signature/signature_derive/README.md b/signature/signature_derive/README.md index 6f0350147..6da6d5d67 100644 --- a/signature/signature_derive/README.md +++ b/signature/signature_derive/README.md @@ -1,13 +1,13 @@ # `signature` crate custom derive support -[![Build Status](https://travis-ci.org/RustCrypto/signatures.svg?branch=master)](https://travis-ci.org/RustCrypto/signatures) +[![Build Status](https://travis-ci.org/RustCrypto/traits.svg?branch=master)](https://travis-ci.org/RustCrypto/traits) This crate provides proc macros used by the `signature` crate. -It's not intended to be used directly. See the signature crate's documentation +Not intended to be used directly. See the `signature` crate's documentation for additional details: -[Documentation][docs] +[Documentation] ## License From 64425bd7501110270b288fa5db087b9a3f1ad4be Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 8 Mar 2020 09:39:53 -0700 Subject: [PATCH 0015/1461] signature: design documentation This commit adds high-level descriptions of how the `signature` crate is designed, including alternatives considered, and hopefully details why it is the way it is. These notes also include a rough sketch of potential additional future traits which could better optimize for implementers of signature traits, rather than consumers (with a blanket impl to link the two). --- README.md | 2 +- signature/README.md | 2 +- signature/src/error.rs | 1 + signature/src/lib.rs | 131 +++++++++++++++++++++++++++++++++---- signature/src/signature.rs | 21 ++++-- signature/src/signer.rs | 20 +++++- signature/src/verifier.rs | 24 +++++-- 7 files changed, 174 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index dd1743e25..c85f5a887 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Collection of traits which describe functionality of cryptographic primitives. ## Crates | Name | Crates.io | Documentation | | ------- | :---------:| :-------------:| -| [`aead`](hhttps://en.wikipedia.org/wiki/Authenticated_encryption)| [![crates.io](https://img.shields.io/crates/v/aead.svg)](https://crates.io/crates/aead) | [![Documentation](https://docs.rs/aead/badge.svg)](https://docs.rs/aead) | +| [`aead`](https://en.wikipedia.org/wiki/Authenticated_encryption)| [![crates.io](https://img.shields.io/crates/v/aead.svg)](https://crates.io/crates/aead) | [![Documentation](https://docs.rs/aead/badge.svg)](https://docs.rs/aead) | | [`block-cipher-trait`](https://en.wikipedia.org/wiki/Block_cipher)| [![crates.io](https://img.shields.io/crates/v/block-cipher-trait.svg)](https://crates.io/crates/block-cipher-trait) | [![Documentation](https://docs.rs/block-cipher-trait/badge.svg)](https://docs.rs/block-cipher-trait) | | [`crypto-mac`](https://en.wikipedia.org/wiki/Message_authentication_code) | [![crates.io](https://img.shields.io/crates/v/crypto-mac.svg)](https://crates.io/crates/crypto-mac) | [![Documentation](https://docs.rs/crypto-mac/badge.svg)](https://docs.rs/crypto-mac) | | [`digest`](https://en.wikipedia.org/wiki/Cryptographic_hash_function) | [![crates.io](https://img.shields.io/crates/v/digest.svg)](https://crates.io/crates/digest) | [![Documentation](https://docs.rs/digest/badge.svg)](https://docs.rs/digest) | diff --git a/signature/README.md b/signature/README.md index 20242fa20..d3ee5d6a6 100644 --- a/signature/README.md +++ b/signature/README.md @@ -1,4 +1,4 @@ -# `signature` crate +# RustCrypto: `signature` crate [![crate][crate-image]][crate-link] [![Docs][docs-image]][docs-link] diff --git a/signature/src/error.rs b/signature/src/error.rs index c864d979d..48ff02fc6 100644 --- a/signature/src/error.rs +++ b/signature/src/error.rs @@ -31,6 +31,7 @@ impl Error { /// cases are for propagating errors related to external signers, e.g. /// communication/authentication errors with HSMs, KMS, etc. #[cfg(feature = "std")] + #[cfg_attr(docsrs, doc(cfg(feature = "std")))] pub fn from_source(source: impl Into) -> Self { Self { source: Some(source.into()), diff --git a/signature/src/lib.rs b/signature/src/lib.rs index 0d69fc94f..e7ea1faa8 100644 --- a/signature/src/lib.rs +++ b/signature/src/lib.rs @@ -1,30 +1,137 @@ +//! RustCrypto: `signature` crate. +//! //! Traits which provide generic, object-safe APIs for generating and verifying -//! digital signatures, which provide message authentication using public-key -//! cryptography. +//! digital signatures: message authentication using public-key cryptography. //! //! ## Minimum Supported Rust Version //! -//! Rust **1.34** or higher. +//! Rust **1.36** or higher. //! -//! Minimum supported Rust version can be changed in the future, but it will be -//! done with a minor version bump. +//! Minimum supported Rust version may be changed in the future, but such +//! changes will be accompanied with a minor version bump. //! -//! ## SemVer Policy +//! ## SemVer policy //! //! - All on-by-default features of this library are covered by SemVer //! - MSRV is considered exempt from SemVer as noted above -//! - The off-by-default features `derive-preview` and `digest-preview` are -//! unstable "preview" features which are also considered exempt from SemVer. -//! Breaking changes to these features will, like MSRV, be done with a minor -//! version bump. +//! - Off-by-default features ending in `*-preview` (e.g. `derive-preview`, +//! `digest-preview`) are unstable "preview" features which are also +//! considered exempt from SemVer (typically because they rely on pre-1.0 +//! crates as dependencies). However, breaking changes to these features +//! will, like MSRV, also be accompanied by a minor version bump. +//! +//! # Design +//! +//! This crate provides a common set of traits for signing and verifying +//! digital signatures intended to be implemented by libraries which produce +//! or contain implementations of digital signature algorithms, and used by +//! libraries which want to produce or verify digital signatures while +//! generically supporting any compatible backend. +//! +//! ## Goals +//! +//! The traits provided by this crate were designed with the following goals +//! in mind: +//! +//! - Provide an easy-to-use, misuse resistant API optimized for consumers +//! (as opposed to implementers) of its traits. +//! - Support common type-safe wrappers around "bag-of-bytes" representations +//! which can be directly parsed from or written to the "wire". +//! - Expose a trait/object-safe API where signers/verifiers spanning multiple +//! homogeneous provider implementations can be seamlessly leveraged together +//! in the same logical "keyring" so long as they operate on the same +//! underlying signature type. +//! - Allow one provider type to potentially implement support (including +//! being generic over) several signature types. +//! - Keep signature algorithm customizations / "knobs" out-of-band from the +//! signing/verification APIs, ideally pushing such concerns into the type +//! system so that algorithm mismatches are caught as type errors. +//! - Opaque error type which minimizes information leaked from crxyptographic +//! failures, as "rich" error types in these scenarios are often a source +//! of sidechannel information for attackers (e.g. [BB'06]) +//! +//! [BB'06]: https://en.wikipedia.org/wiki/Daniel_Bleichenbacher +//! +//! # Implementation +//! +//! To accomplish the above goals, the [`Signer`] and [`Verifier`] traits +//! provided by this are generic over a [`Signature`] return value, and use +//! generic parameters rather than associated types. Notably, they use such +//! a parameter for the return value, allowing it to be inferred by the type +//! checker based on the desired signature type. +//! +//! The [`Signature`] trait is bounded on `AsRef<[u8]>`, enforcing that +//! signature types are thin wrappers around a "bag-of-bytes" +//! serialization. Inspiration for this approach comes from the Ed25519 +//! signature system, which was based on the observation that past +//! systems were not prescriptive about how signatures should be represented +//! on-the-wire, and that lead to a proliferation of different wire formats +//! and confusion about which ones should be used. This crate aims to provide +//! similar simplicity by minimizing the number of steps involved to obtain +//! a serializable signature. +//! +//! # Alternatives considered +//! +//! This crate is based on over two years of exploration of how to encapsulate +//! digital signature systems in the most flexible, developer-friendly way. +//! During that time many design alternatives were explored, tradeoffs +//! compared, and ultimately the provided API was selected. +//! +//! The tradeoffs made in this API have all been to improve simplicity, +//! ergonomics, type safety, and flexibility for *consumers* of the traits. +//! At times, this has come at a cost to implementers. Below are some concerns +//! we are cognizant of which were considered in the design of the API: +//! +//! - "Bag-of-bytes" serialization precludes signature providers from using +//! their own internal representation of a signature, which can be helpful +//! for many reasons (e.g. advanced signature system features like batch +//! verification). Alternatively each provider could define its own signature +//! type, using a marker trait to identify the particular signature algorithm, +//! have `From` impls for converting to/from `[u8; N]`, and a marker trait +//! for identifying a specific signature algorithm. +//! - Associated types, rather than generic parameters of traits, could allow +//! more customization of the types used by a particular signature system, +//! e.g. using custom error types. +//! +//! It may still make sense to continue to explore the above tradeoffs, but +//! with a *new* set of traits which are intended to be implementor-friendly, +//! rather than consumer friendly. The existing [`Signer`] and [`Verifier`] +//! traits could have blanket impls for the "provider-friendly" traits. +//! However, as noted above this is a design space easily explored after +//! stabilizing the consumer-oriented traits, and thus we consider these +//! more important. +//! +//! That said, below are some caveats of trying to design such traits, and +//! why we haven't actively pursued them: +//! +//! - Generics in the return position are already used to select which trait +//! impl to use, i.e. for a particular signature algorithm/system. Avoiding +//! a unified, concrete signature type adds another dimension to complexity +//! and compiler errors, and in our experience makes them unsuitable for this +//! sort of API. We believe such an API is the natural one for signature +//! systems, reflecting the natural way they are written absent a trait. +//! - Associated types preclude multiple (or generic) implementations of the +//! same trait. These parameters are common in signature systems, notably +//! ones which support different digest algorithms. +//! - Digital signatures are almost always larger than the present 32-entry +//! trait impl limitation on array types, which complicates trait signatures +//! for these types (particularly things like `From` or `Borrow` bounds). +//! This may be more interesting to explore after const generics. +//! +//! #![no_std] -#![forbid(unsafe_code)] -#![warn(missing_docs, rust_2018_idioms, unused_qualifications)] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png", html_root_url = "https://docs.rs/signature/1.0.0-pre.1" )] +#![forbid(unsafe_code)] +#![warn( + missing_docs, + rust_2018_idioms, + unused_qualifications, + intra_doc_link_resolution_failure +)] #[cfg(feature = "std")] #[macro_use] diff --git a/signature/src/signature.rs b/signature/src/signature.rs index 2f2455b7f..75a5dfd70 100644 --- a/signature/src/signature.rs +++ b/signature/src/signature.rs @@ -3,6 +3,14 @@ use crate::error::Error; use core::fmt::Debug; +/// For intra-doc link resolution +#[cfg(feature = "digest-preview")] +#[allow(unused_imports)] +use crate::{ + signer::{DigestSigner, Signer}, + verifier::{DigestVerifier, Verifier}, +}; + /// Trait impl'd by concrete types that represent digital signatures pub trait Signature: AsRef<[u8]> + Debug + Sized { /// Parse a signature from its byte representation @@ -20,11 +28,16 @@ pub trait Signature: AsRef<[u8]> + Debug + Sized { /// - `H`: hash (a.k.a. digest) function /// - `m`: message /// +/// i.e. a traditional application of the [Fiat-Shamir heuristic]. +/// /// For signature types that implement this trait, when the `derive-preview` -/// Cargo feature is enabled a custom derive for `Signer` is available for any -/// types that impl `DigestSigner`, and likewise for deriving `Verifier` for -/// types which impl `DigestVerifier`. -#[cfg(feature = "digest")] +/// Cargo feature is enabled a custom derive for [`Signer`] is available for any +/// types that impl [`DigestSigner`], and likewise for deriving [`Verifier`] for +/// types which impl [`DigestVerifier`]. +/// +/// [Fiat-Shamir heuristic]: https://en.wikipedia.org/wiki/Fiat%E2%80%93Shamir_heuristic +#[cfg(feature = "digest-preview")] +#[cfg_attr(docsrs, doc(cfg(feature = "digest-preview")))] pub trait DigestSignature: Signature { /// Preferred `Digest` algorithm to use when computing this signature type. type Digest: digest::Digest; diff --git a/signature/src/signer.rs b/signature/src/signer.rs index e74d00449..b0eeff784 100644 --- a/signature/src/signer.rs +++ b/signature/src/signer.rs @@ -22,9 +22,25 @@ pub trait Signer { /// Sign the given prehashed message `Digest` using `Self`. /// -/// This trait is only available when the `digest-preview` cargo feature is -/// enabled. +/// ## Notes +/// +/// This trait is primarily intended for signature algorithms based on the +/// [Fiat-Shamir heuristic], a method for converting an interactive +/// challenge/response-based proof-of-knowledge protocol into an offline +/// digital signature through the use of a random oracle, i.e. a digest +/// function. +/// +/// The security of such protocols critically rests upon the inability of +/// an attacker to solve for the output of the random oracle, as generally +/// otherwise such signature algorithms are a system of linear equations and +/// therefore doing so would allow the attacker to trivially forge signatures. +/// +/// To prevent misuse which would potentially allow this to be possible, this +/// API accepts a [`Digest`] instance, rather than a raw digest value. +/// +/// [Fiat-Shamir heuristic]: https://en.wikipedia.org/wiki/Fiat%E2%80%93Shamir_heuristic #[cfg(feature = "digest-preview")] +#[cfg_attr(docsrs, doc(cfg(feature = "digest-preview")))] pub trait DigestSigner where D: Digest, diff --git a/signature/src/verifier.rs b/signature/src/verifier.rs index b1884bd19..539f42680 100644 --- a/signature/src/verifier.rs +++ b/signature/src/verifier.rs @@ -16,15 +16,25 @@ pub trait Verifier { /// Verify the provided signature for the given prehashed message `Digest` /// is authentic. /// -/// This trait is only available when the `digest-preview` cargo feature is -/// enabled. +/// ## Notes /// -/// It accepts a [`Digest`] instance, as opposed to a raw digest byte array, -/// as the security of signature algorithms built on hash functions often -/// depends critically on the input being a random oracle as opposed to a -/// value an attacker can choose and solve for. This is enforced at the API -/// level by taking a [`Digest`] instance in order to better resist misuse. +/// This trait is primarily intended for signature algorithms based on the +/// [Fiat-Shamir heuristic], a method for converting an interactive +/// challenge/response-based proof-of-knowledge protocol into an offline +/// digital signature through the use of a random oracle, i.e. a digest +/// function. +/// +/// The security of such protocols critically rests upon the inability of +/// an attacker to solve for the output of the random oracle, as generally +/// otherwise such signature algorithms are a system of linear equations and +/// therefore doing so would allow the attacker to trivially forge signatures. +/// +/// To prevent misuse which would potentially allow this to be possible, this +/// API accepts a [`Digest`] instance, rather than a raw digest value. +/// +/// [Fiat-Shamir heuristic]: https://en.wikipedia.org/wiki/Fiat%E2%80%93Shamir_heuristic #[cfg(feature = "digest-preview")] +#[cfg_attr(docsrs, doc(cfg(feature = "digest-preview")))] pub trait DigestVerifier where D: Digest, From 00030f8fa602f3c4e67ab7fe0b8e51eb13dee5ab Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 8 Mar 2020 10:07:50 -0700 Subject: [PATCH 0016/1461] signature: add RandomizedSigner trait Adds a trait which allows passing a `rand_core::CryptoRng` to the signing operation, which is useful for signature algorithms which rely on a source of randomness, e.g. RSASSA-PSS and traditional ECDSA (with a random `k` value) Presently gated under the `rand-preview` feature (since `rand_core` is presently pre-1.0). --- signature/Cargo.toml | 6 ++++++ signature/src/lib.rs | 33 +++++++++++++++++++++++++++++---- signature/src/signer.rs | 28 +++++++++++++++++++++++++++- signature/src/verifier.rs | 3 ++- 4 files changed, 64 insertions(+), 6 deletions(-) diff --git a/signature/Cargo.toml b/signature/Cargo.toml index e11f8b684..8fca88a95 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -16,6 +16,11 @@ version = "0.8" optional = true default-features = false +[dependencies.rand_core] +version = "0.5" +optional = true +default-features = false + [dependencies.signature_derive] version = "1.0.0-pre.0" optional = true @@ -29,6 +34,7 @@ sha2 = { version = "0.8", default-features = false } default = ["std"] derive-preview = ["digest-preview", "signature_derive"] digest-preview = ["digest"] +rand-preview = ["rand_core"] std = [] [package.metadata.docs.rs] diff --git a/signature/src/lib.rs b/signature/src/lib.rs index e7ea1faa8..1ac68ac24 100644 --- a/signature/src/lib.rs +++ b/signature/src/lib.rs @@ -52,7 +52,7 @@ //! //! [BB'06]: https://en.wikipedia.org/wiki/Daniel_Bleichenbacher //! -//! # Implementation +//! ## Implementation //! //! To accomplish the above goals, the [`Signer`] and [`Verifier`] traits //! provided by this are generic over a [`Signature`] return value, and use @@ -70,7 +70,7 @@ //! similar simplicity by minimizing the number of steps involved to obtain //! a serializable signature. //! -//! # Alternatives considered +//! ## Alternatives considered //! //! This crate is based on over two years of exploration of how to encapsulate //! digital signature systems in the most flexible, developer-friendly way. @@ -118,7 +118,30 @@ //! for these types (particularly things like `From` or `Borrow` bounds). //! This may be more interesting to explore after const generics. //! -//! +//! ## Unstable features +//! +//! Despite being post-1.0, this crate includes a number of off-by-default +//! unstable features named `*-preview`, each of which depends on a pre-1.0 +//! crate. These features are as follows: +//! +//! - `derive-preview`: for implementers of signature systems using +//! [`DigestSigner`] and [`DigestVerifier`], the `derive-preview` feature +//! can be used to derive [`Signer`] and [`Verifier`] traits which prehash +//! the input message using the [`DigestSignature::Digest`] function for +//! a given [`Signature`] type. When the `derive-preview` feature is enabled +//! import the proc macros with `use signature::{Signer, Verifier}` and then +//! add a `derive(Signer)` or `derive(Verifier)` attribute to the given +//! digest signer/verifier type. +//! - `digest-preview`: enables the [`DigestSigner`] and [`DigestVerifier`] +//! traits which are based on the `Digest` trait from the `digest` crate. +//! These traits are used for representing signature systems based on the +//! [Fiat-Shamir heuristic] which compute a random challenge value to sign +//! by computing a cryptographically secure digest of the input message. +//! - `rand-preview`: enables the [`RandomizedSigner`] trait for signature +//! systems which rely on a cryptographically secure random number generator +//! for security. +//! +//! [Fiat-Shamir heuristic]: https://en.wikipedia.org/wiki/Fiat%E2%80%93Shamir_heuristic #![no_std] #![doc( @@ -143,12 +166,14 @@ extern crate std; extern crate signature_derive; #[cfg(feature = "derive-preview")] -#[doc(hidden)] pub use signature_derive::{Signer, Verifier}; #[cfg(feature = "digest-preview")] pub use digest; +#[cfg(feature = "rand-preview")] +pub use rand_core; + mod error; mod signature; mod signer; diff --git a/signature/src/signer.rs b/signature/src/signer.rs index b0eeff784..d456d466e 100644 --- a/signature/src/signer.rs +++ b/signature/src/signer.rs @@ -1,8 +1,12 @@ //! Traits for generating digital signatures +use crate::{error::Error, Signature}; + #[cfg(feature = "digest-preview")] use crate::digest::Digest; -use crate::{error::Error, Signature}; + +#[cfg(feature = "rand-preview")] +use crate::rand_core::{CryptoRng, RngCore}; /// Sign the provided message bytestring using `Self` (e.g. a cryptographic key /// or connection to an HSM), returning a digital signature. @@ -58,3 +62,25 @@ where /// digital signature on success, or an error if something went wrong. fn try_sign_digest(&self, digest: D) -> Result; } + +/// Sign the given message using the provided external randomness source. +#[cfg(feature = "rand-preview")] +#[cfg_attr(docsrs, doc(cfg(feature = "rand-preview")))] +pub trait RandomizedSigner +where + R: CryptoRng + RngCore, + S: Signature, +{ + /// Sign the given message and return a digital signature + fn sign_with_rng(&self, rng: &mut R, msg: &[u8]) -> S { + self.try_sign_with_rng(rng, msg) + .expect("signature operation failed") + } + + /// Attempt to sign the given message, returning a digital signature on + /// success, or an error if something went wrong. + /// + /// The main intended use case for signing errors is when communicating + /// with external signers, e.g. cloud KMS, HSMs, or other hardware tokens. + fn try_sign_with_rng(&self, rng: &mut R, msg: &[u8]) -> Result; +} diff --git a/signature/src/verifier.rs b/signature/src/verifier.rs index 539f42680..3236889cf 100644 --- a/signature/src/verifier.rs +++ b/signature/src/verifier.rs @@ -1,8 +1,9 @@ //! Trait for verifying digital signatures +use crate::{error::Error, Signature}; + #[cfg(feature = "digest-preview")] use crate::digest::Digest; -use crate::{error::Error, Signature}; /// Verify the provided message bytestring using `Self` (e.g. a public key) pub trait Verifier { From 3722b76bc85c3abd72882be17d6aec57b50ac89f Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 8 Mar 2020 10:30:38 -0700 Subject: [PATCH 0017/1461] signature: Error cleanups - Don't print `Error::source` in the `Display` impl for `Error` as this information is available as `Error::source`'s `Display` - Adds a `From` impl for creating an `Error` from a `BoxError`. --- signature/src/error.rs | 16 +++++++--------- signature/src/lib.rs | 4 ++-- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/signature/src/error.rs b/signature/src/error.rs index 48ff02fc6..73996cb2d 100644 --- a/signature/src/error.rs +++ b/signature/src/error.rs @@ -41,16 +41,14 @@ impl Error { impl Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "signature error")?; - - #[cfg(feature = "std")] - { - if let Some(ref source) = self.source { - write!(f, ": {}", source)?; - } - } + f.write_str("signature error") + } +} - Ok(()) +#[cfg(feature = "std")] +impl From for Error { + fn from(source: BoxError) -> Error { + Self::from_source(source) } } diff --git a/signature/src/lib.rs b/signature/src/lib.rs index 1ac68ac24..ff4d2874f 100644 --- a/signature/src/lib.rs +++ b/signature/src/lib.rs @@ -131,7 +131,8 @@ //! a given [`Signature`] type. When the `derive-preview` feature is enabled //! import the proc macros with `use signature::{Signer, Verifier}` and then //! add a `derive(Signer)` or `derive(Verifier)` attribute to the given -//! digest signer/verifier type. +//! digest signer/verifier type. Enabling this feature also enables `digest` +//! support (see immediately below). //! - `digest-preview`: enables the [`DigestSigner`] and [`DigestVerifier`] //! traits which are based on the `Digest` trait from the `digest` crate. //! These traits are used for representing signature systems based on the @@ -157,7 +158,6 @@ )] #[cfg(feature = "std")] -#[macro_use] extern crate std; #[cfg(feature = "derive-preview")] From 85d277020b191d23360eeca314dfda8bcd640f94 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 8 Mar 2020 11:09:33 -0700 Subject: [PATCH 0018/1461] signature 1.0.0-pre.2 --- signature/CHANGES.md | 14 ++++++++++++++ signature/Cargo.toml | 2 +- signature/src/lib.rs | 2 +- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/signature/CHANGES.md b/signature/CHANGES.md index c9364756c..6a7a45f54 100644 --- a/signature/CHANGES.md +++ b/signature/CHANGES.md @@ -4,6 +4,20 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 1.0.0-pre.2 (2020-03-08) +### Added +- `RandomizedSigner` trait ([#73]) +- Design documentation ([#72]) + +### Changed +- Error cleanups ([#74]) +- Crate moved to `RustCrypto/traits` ([#71]) + +[#74]: https://github.com/RustCrypto/traits/pull/74 +[#73]: https://github.com/RustCrypto/traits/pull/73 +[#72]: https://github.com/RustCrypto/traits/pull/72 +[#71]: https://github.com/RustCrypto/traits/pull/71 + ## 1.0.0-pre.1 (2019-10-27) ### Changed - Use `Error::source` instead of `::cause` ([RustCrypto/signatures#37]) diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 8fca88a95..5808bcc95 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "1.0.0-pre.1" # Also update html_root_url in lib.rs when bumping this +version = "1.0.0-pre.2" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/signature" diff --git a/signature/src/lib.rs b/signature/src/lib.rs index ff4d2874f..91d21591d 100644 --- a/signature/src/lib.rs +++ b/signature/src/lib.rs @@ -147,7 +147,7 @@ #![no_std] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png", - html_root_url = "https://docs.rs/signature/1.0.0-pre.1" + html_root_url = "https://docs.rs/signature/1.0.0-pre.2" )] #![forbid(unsafe_code)] #![warn( From b1af0c0f8ed54b61dcd762722068881c93017b5d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 8 Mar 2020 11:35:30 -0700 Subject: [PATCH 0019/1461] signature: fix docs.rs rendering Fixes rendering of `doc(cfg(...))` on docs.rs by passing the proper `cfg` attribute in that environment and enabling the `doc_cfg` (nightly-only) feature. --- signature/Cargo.toml | 1 + signature/src/error.rs | 17 ++++++++++++++--- signature/src/lib.rs | 2 ++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 5808bcc95..242609331 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -39,3 +39,4 @@ std = [] [package.metadata.docs.rs] all-features = true +rustdoc-args = ["--cfg", "docsrs"] diff --git a/signature/src/error.rs b/signature/src/error.rs index 73996cb2d..78be99926 100644 --- a/signature/src/error.rs +++ b/signature/src/error.rs @@ -6,11 +6,22 @@ use core::fmt::{self, Display}; use std::boxed::Box; /// Box containing a thread-safe + `'static` error suitable for use as a -/// as an `std::error::Error::source` +/// as a [`std::error::Error::source`] #[cfg(feature = "std")] +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] pub type BoxError = Box; -/// Signature errors +/// Signature errors. +/// +/// This type is deliberately opaque as to avoid sidechannel leakage which +/// could potentially be used recover signing private keys or forge signatures +/// (e.g. [BB'06]). +/// +/// When the `std` feature is enabled, it impls [`std::error::Error`] and +/// supports an optional [`std::error::Error::source`], which can be used by +/// things like remote signers (e.g. HSM, KMS) to report I/O or auth errors. +/// +/// [BB'06]: https://en.wikipedia.org/wiki/Daniel_Bleichenbacher #[derive(Debug, Default)] pub struct Error { /// Source of the error (if applicable). @@ -26,7 +37,7 @@ impl Error { /// Create a new error with an associated source. /// - /// **NOTE:** The "source" should NOT be used to propagate cryptographic + /// **NOTE:** The "source" should **NOT** be used to propagate cryptographic /// errors e.g. signature parsing or verification errors. The intended use /// cases are for propagating errors related to external signers, e.g. /// communication/authentication errors with HSMs, KMS, etc. diff --git a/signature/src/lib.rs b/signature/src/lib.rs index 91d21591d..83d98729c 100644 --- a/signature/src/lib.rs +++ b/signature/src/lib.rs @@ -149,6 +149,7 @@ html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png", html_root_url = "https://docs.rs/signature/1.0.0-pre.2" )] +#![cfg_attr(docsrs, feature(doc_cfg))] #![forbid(unsafe_code)] #![warn( missing_docs, @@ -166,6 +167,7 @@ extern crate std; extern crate signature_derive; #[cfg(feature = "derive-preview")] +#[cfg_attr(docsrs, doc(cfg(feature = "derive-preview")))] pub use signature_derive::{Signer, Verifier}; #[cfg(feature = "digest-preview")] From 6f1bf443cb19fc12a02877ed569aff5daec63047 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 8 Mar 2020 11:47:30 -0700 Subject: [PATCH 0020/1461] signature v1.0.0-pre.3 --- signature/CHANGES.md | 6 ++++++ signature/Cargo.toml | 2 +- signature/src/lib.rs | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/signature/CHANGES.md b/signature/CHANGES.md index 6a7a45f54..0e98529bb 100644 --- a/signature/CHANGES.md +++ b/signature/CHANGES.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 1.0.0-pre.3 (2020-03-08) +### Fixed +- docs.rs rendering ([#76]) + +[#76]: https://github.com/RustCrypto/traits/pull/76 + ## 1.0.0-pre.2 (2020-03-08) ### Added - `RandomizedSigner` trait ([#73]) diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 242609331..c58e4f7b9 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "1.0.0-pre.2" # Also update html_root_url in lib.rs when bumping this +version = "1.0.0-pre.3" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/signature" diff --git a/signature/src/lib.rs b/signature/src/lib.rs index 83d98729c..01a737820 100644 --- a/signature/src/lib.rs +++ b/signature/src/lib.rs @@ -147,7 +147,7 @@ #![no_std] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png", - html_root_url = "https://docs.rs/signature/1.0.0-pre.2" + html_root_url = "https://docs.rs/signature/1.0.0-pre.3" )] #![cfg_attr(docsrs, feature(doc_cfg))] #![forbid(unsafe_code)] From 55ef493c2a885e8af3ed0d9620267b714c091cd6 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 8 Mar 2020 15:02:56 -0700 Subject: [PATCH 0021/1461] signature: improve docs for `signature_derive` Adds a description of each of the derive macros --- README.md | 2 +- signature/signature_derive/src/lib.rs | 38 +++++++++++++++++++++++++-- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c85f5a887..cc1afce17 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Collection of traits which describe functionality of cryptographic primitives. | [`block-cipher-trait`](https://en.wikipedia.org/wiki/Block_cipher)| [![crates.io](https://img.shields.io/crates/v/block-cipher-trait.svg)](https://crates.io/crates/block-cipher-trait) | [![Documentation](https://docs.rs/block-cipher-trait/badge.svg)](https://docs.rs/block-cipher-trait) | | [`crypto-mac`](https://en.wikipedia.org/wiki/Message_authentication_code) | [![crates.io](https://img.shields.io/crates/v/crypto-mac.svg)](https://crates.io/crates/crypto-mac) | [![Documentation](https://docs.rs/crypto-mac/badge.svg)](https://docs.rs/crypto-mac) | | [`digest`](https://en.wikipedia.org/wiki/Cryptographic_hash_function) | [![crates.io](https://img.shields.io/crates/v/digest.svg)](https://crates.io/crates/digest) | [![Documentation](https://docs.rs/digest/badge.svg)](https://docs.rs/digest) | -| [`signature`](https://en.wikipedia.org/wiki/Digital_signature) | [![crates.io](https://img.shields.io/crates/v/signature.svg)](https://crates.io/crates/stream-cipher) | [![Documentation](https://docs.rs/signature/badge.svg)](https://docs.rs/signature) | +| [`signature`](https://en.wikipedia.org/wiki/Digital_signature) | [![crates.io](https://img.shields.io/crates/v/signature.svg)](https://crates.io/crates/signature) | [![Documentation](https://docs.rs/signature/badge.svg)](https://docs.rs/signature) | | [`stream-cipher`](https://en.wikipedia.org/wiki/Stream_cipher) | [![crates.io](https://img.shields.io/crates/v/stream-cipher.svg)](https://crates.io/crates/stream-cipher) | [![Documentation](https://docs.rs/stream-cipher/badge.svg)](https://docs.rs/stream-cipher) | ### Minimum Rust version diff --git a/signature/signature_derive/src/lib.rs b/signature/signature_derive/src/lib.rs index aa0953f99..81a3094a6 100644 --- a/signature/signature_derive/src/lib.rs +++ b/signature/signature_derive/src/lib.rs @@ -29,7 +29,24 @@ fn derive_signer(mut s: synstructure::Structure) -> TokenStream { } }) } -decl_derive!([Signer] => derive_signer); + +decl_derive! { + [Signer] => + /// Derive the [`Signer`] trait for a type which impls [`DigestSigner`]. + /// + /// When implementing the [`DigestSigner`] trait for a signature type which + /// itself impl's the [`DigestSignature`] trait (which marks signature + /// algorithms which are computed using a [`Digest`]), signature providers + /// can automatically derive the [`Signer`] trait when the digest algorithm + /// is [`DigestSignature::Digest`] (i.e. the "standard" digest algorithm + /// for a given signature type) + /// + /// This automates all of the digest computation otherwise needed for a + /// complete signature algorithm implementation. + /// + /// [`Digest`]: https://docs.rs/digest/latest/digest/trait.Digest.html + derive_signer +} /// Derive the `Verifier` trait for `DigestVerifier` types fn derive_verifier(mut s: synstructure::Structure) -> TokenStream { @@ -46,7 +63,24 @@ fn derive_verifier(mut s: synstructure::Structure) -> TokenStream { } }) } -decl_derive!([Verifier] => derive_verifier); + +decl_derive! { + [Verifier] => + /// Derive the [`Verifier`] trait for a type which impls [`DigestVerifier`]. + /// + /// When implementing the [`DigestVerifier`] trait for a signature type which + /// itself impl's the [`DigestSignature`] trait (which marks signature + /// algorithms which are computed using a [`Digest`]), signature providers + /// can automatically derive the [`Verifier`] trait when the digest algorithm + /// is [`DigestSignature::Digest`] (i.e. the "standard" digest algorithm + /// for a given signature type) + /// + /// This automates all of the digest computation otherwise needed for a + /// complete signature algorithm implementation. + /// + /// [`Digest`]: https://docs.rs/digest/latest/digest/trait.Digest.html + derive_verifier +} #[cfg(test)] mod tests { From f9e4196d4e2f2fd2cd0bb0248c85df5e2000458f Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 8 Mar 2020 15:21:42 -0700 Subject: [PATCH 0022/1461] signature: update README.md crate usage notes --- signature/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/signature/README.md b/signature/README.md index d3ee5d6a6..8241de485 100644 --- a/signature/README.md +++ b/signature/README.md @@ -9,8 +9,8 @@ This crate contains traits which provide generic, object-safe APIs for generating and verifying [digital signatures][1]. -It's presently useful in conjunction with the [`ed25519`][2] crate. -Support is also planned for the [`ecdsa`][3] and [`rsa`][4] crates. +Used by the [`ecdsa`][2] and [`ed25519`][3] crates, with forthcoming support +in the [`rsa`][4] crate. [Documentation][docs-link] @@ -59,6 +59,6 @@ dual licensed as above, without any additional terms or conditions. [//]: # (general links) [1]: https://en.wikipedia.org/wiki/Digital_signature -[2]: https://github.com/RustCrypto/signatures/tree/master/ed25519 -[3]: https://github.com/RustCrypto/signatures/tree/master/ecdsa +[2]: https://github.com/RustCrypto/signatures/tree/master/ecdsa +[3]: https://github.com/RustCrypto/signatures/tree/master/ed25519 [4]: https://github.com/RustCrypto/RSA From 741eb2795723c58fddb29b3f96ae1c3e8d24b55e Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 8 Mar 2020 15:34:14 -0700 Subject: [PATCH 0023/1461] signature_derive v1.0.0-pre.1 --- signature/Cargo.toml | 2 +- signature/signature_derive/CHANGES.md | 12 ++++++++++++ signature/signature_derive/Cargo.toml | 2 +- 3 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 signature/signature_derive/CHANGES.md diff --git a/signature/Cargo.toml b/signature/Cargo.toml index c58e4f7b9..5290fc5d2 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -22,7 +22,7 @@ optional = true default-features = false [dependencies.signature_derive] -version = "1.0.0-pre.0" +version = "= 1.0.0-pre.1" optional = true path = "signature_derive" diff --git a/signature/signature_derive/CHANGES.md b/signature/signature_derive/CHANGES.md new file mode 100644 index 000000000..7a868afad --- /dev/null +++ b/signature/signature_derive/CHANGES.md @@ -0,0 +1,12 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## 1.0.0-pre.1 (2020-03-08) +## Added +- Initial Changelog for `signature_derive` +- Rustdoc ([#79]) + +[#79]: https://github.com/RustCrypto/traits/pull/79 diff --git a/signature/signature_derive/Cargo.toml b/signature/signature_derive/Cargo.toml index 262f02d19..c4e408d64 100644 --- a/signature/signature_derive/Cargo.toml +++ b/signature/signature_derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "signature_derive" -version = "1.0.0-pre.0" +version = "1.0.0-pre.1" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" description = "Custom derive support for the 'signature' crate" From 035285efe04b3f3e4403a8a7c010b1b6744bd375 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 8 Mar 2020 16:40:34 -0700 Subject: [PATCH 0024/1461] signature: remove BoxError type alias We can revisit adding this back after 1.0, but it seems possible such a type may eventually be stabilized in `std`. It's better to "wait and see" if that happens and add `BoxError` back in the event there's a desire for more ergonomic boxed errors for `std` users rather than prematurely stabilizing it if it turns out to be unnecessary. --- signature/src/error.rs | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/signature/src/error.rs b/signature/src/error.rs index 78be99926..c45643157 100644 --- a/signature/src/error.rs +++ b/signature/src/error.rs @@ -5,12 +5,6 @@ use core::fmt::{self, Display}; #[cfg(feature = "std")] use std::boxed::Box; -/// Box containing a thread-safe + `'static` error suitable for use as a -/// as a [`std::error::Error::source`] -#[cfg(feature = "std")] -#[cfg_attr(docsrs, doc(cfg(feature = "std")))] -pub type BoxError = Box; - /// Signature errors. /// /// This type is deliberately opaque as to avoid sidechannel leakage which @@ -26,7 +20,7 @@ pub type BoxError = Box; pub struct Error { /// Source of the error (if applicable). #[cfg(feature = "std")] - source: Option, + source: Option>, } impl Error { @@ -43,7 +37,9 @@ impl Error { /// communication/authentication errors with HSMs, KMS, etc. #[cfg(feature = "std")] #[cfg_attr(docsrs, doc(cfg(feature = "std")))] - pub fn from_source(source: impl Into) -> Self { + pub fn from_source( + source: impl Into>, + ) -> Self { Self { source: Some(source.into()), } @@ -57,8 +53,8 @@ impl Display for Error { } #[cfg(feature = "std")] -impl From for Error { - fn from(source: BoxError) -> Error { +impl From> for Error { + fn from(source: Box) -> Error { Self::from_source(source) } } From 14ab639d26b04f044ef649c6a3f8da63370ca35f Mon Sep 17 00:00:00 2001 From: Robin Lambertz Date: Mon, 9 Mar 2020 17:18:04 +0100 Subject: [PATCH 0025/1461] Mark preview feature as unstable in Cargo.toml --- signature/Cargo.toml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 5290fc5d2..dec65f99a 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -32,10 +32,13 @@ sha2 = { version = "0.8", default-features = false } [features] default = ["std"] +std = [] + +# Preview features are unstable and exempt from semver. +# See https://docs.rs/signature/latest/signature/#unstable-features for more information. derive-preview = ["digest-preview", "signature_derive"] digest-preview = ["digest"] rand-preview = ["rand_core"] -std = [] [package.metadata.docs.rs] all-features = true From e011bda184fb46ef66073a701b45e42a9c7d324a Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 10 Mar 2020 11:52:02 -0700 Subject: [PATCH 0026/1461] signature: ensure `Error::new()` is mandatory Prevents usage of `Error {}` in `no_std` contexts. --- signature/src/error.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/signature/src/error.rs b/signature/src/error.rs index c45643157..86d35c46a 100644 --- a/signature/src/error.rs +++ b/signature/src/error.rs @@ -18,6 +18,10 @@ use std::boxed::Box; /// [BB'06]: https://en.wikipedia.org/wiki/Daniel_Bleichenbacher #[derive(Debug, Default)] pub struct Error { + /// Prevent from being instantiated as `Error {}` when the `std` feature + /// is disabled + _private: (), + /// Source of the error (if applicable). #[cfg(feature = "std")] source: Option>, @@ -41,6 +45,7 @@ impl Error { source: impl Into>, ) -> Self { Self { + _private: (), source: Some(source.into()), } } From 65eb2dff635bc17e29868f8f481329fabc9d935e Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 10 Mar 2020 12:03:49 -0700 Subject: [PATCH 0027/1461] signature: have Signature::from_bytes take a byte slice ...rather than `impl AsRef<[u8]>`, which both breaks object safety, and in many cases is less convenient (e.g. when deref coercion would allow types that don't impl AsRef to work) --- signature/src/signature.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/signature/src/signature.rs b/signature/src/signature.rs index 75a5dfd70..d47978e00 100644 --- a/signature/src/signature.rs +++ b/signature/src/signature.rs @@ -14,7 +14,7 @@ use crate::{ /// Trait impl'd by concrete types that represent digital signatures pub trait Signature: AsRef<[u8]> + Debug + Sized { /// Parse a signature from its byte representation - fn from_bytes(bytes: impl AsRef<[u8]>) -> Result; + fn from_bytes(bytes: &[u8]) -> Result; /// Borrow this signature as serialized bytes fn as_slice(&self) -> &[u8] { From 3024084db6d7e5c336bcef6fc8f17ef8d1d04a0f Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 15 Mar 2020 16:35:41 -0700 Subject: [PATCH 0028/1461] signature 1.0.0-pre.4 --- signature/CHANGES.md | 16 ++++++++++++++++ signature/Cargo.toml | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/signature/CHANGES.md b/signature/CHANGES.md index 0e98529bb..f201fb84b 100644 --- a/signature/CHANGES.md +++ b/signature/CHANGES.md @@ -4,6 +4,22 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 1.0.0-pre.4 (2020-03-15) +### Added +- Mark preview features as unstable in `Cargo.toml` ([#82]) + +### Changed +- Have `Signature::from_bytes` take a byte slice ([#84]) +- Ensure `Error::new()` is mandatory ([#83]) + +### Removed +- `BoxError` type alias ([#81]) + +[#84]: https://github.com/RustCrypto/traits/pull/84 +[#83]: https://github.com/RustCrypto/traits/pull/83 +[#82]: https://github.com/RustCrypto/traits/pull/82 +[#81]: https://github.com/RustCrypto/traits/pull/81 + ## 1.0.0-pre.3 (2020-03-08) ### Fixed - docs.rs rendering ([#76]) diff --git a/signature/Cargo.toml b/signature/Cargo.toml index dec65f99a..d5dd96c23 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "1.0.0-pre.3" # Also update html_root_url in lib.rs when bumping this +version = "1.0.0-pre.4" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/signature" From cd7d5bfb3e18ec8304461df065a347780d84c46b Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 16 Mar 2020 06:59:59 -0700 Subject: [PATCH 0029/1461] signature: rename Signature::as_slice -> Signature::as_bytes --- signature/src/signature.rs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/signature/src/signature.rs b/signature/src/signature.rs index d47978e00..9db76614b 100644 --- a/signature/src/signature.rs +++ b/signature/src/signature.rs @@ -11,13 +11,22 @@ use crate::{ verifier::{DigestVerifier, Verifier}, }; -/// Trait impl'd by concrete types that represent digital signatures +/// Trait impl'd by concrete types that represent digital signatures. +/// +/// Signature types *must* (as mandated by the `AsRef<[u8]>` bound) be a thin +/// wrapper around the "bag-of-bytes" serialized form of a signature which can +/// be directly parsed from or written to the "wire". +/// +/// For signature systems which require a more advanced internal representation +/// (e.g. involving decoded scalars or decompressed elliptic curve points) it's +/// recommended that "provider" libraries maintain their own internal signature +/// type and use `From` bounds to provide automatic conversions. pub trait Signature: AsRef<[u8]> + Debug + Sized { /// Parse a signature from its byte representation fn from_bytes(bytes: &[u8]) -> Result; - /// Borrow this signature as serialized bytes - fn as_slice(&self) -> &[u8] { + /// Borrow a byte slice representing the serialized form of this signature + fn as_bytes(&self) -> &[u8] { self.as_ref() } } From e9e24b1d09c544925b60cfe48715cdae3b66ba13 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 16 Mar 2020 07:26:10 -0700 Subject: [PATCH 0030/1461] signature: fix derive tests These apparently aren't running in CI --- signature/src/lib.rs | 5 ----- signature/tests/signature_derive.rs | 4 ++-- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/signature/src/lib.rs b/signature/src/lib.rs index 01a737820..14f3baf4a 100644 --- a/signature/src/lib.rs +++ b/signature/src/lib.rs @@ -161,11 +161,6 @@ #[cfg(feature = "std")] extern crate std; -#[cfg(feature = "derive-preview")] -#[allow(unused_imports)] -#[macro_use] -extern crate signature_derive; - #[cfg(feature = "derive-preview")] #[cfg_attr(docsrs, doc(cfg(feature = "derive-preview")))] pub use signature_derive::{Signer, Verifier}; diff --git a/signature/tests/signature_derive.rs b/signature/tests/signature_derive.rs index 931624b2c..c4b2532eb 100644 --- a/signature/tests/signature_derive.rs +++ b/signature/tests/signature_derive.rs @@ -20,7 +20,7 @@ mod tests { struct DummySignature(GenericArray::OutputSize>); impl Signature for DummySignature { - fn from_bytes(bytes: impl AsRef<[u8]>) -> Result { + fn from_bytes(bytes: &[u8]) -> Result { Ok(DummySignature(GenericArray::clone_from_slice( bytes.as_ref(), ))) @@ -43,7 +43,7 @@ mod tests { impl DigestSigner for DummySigner { fn try_sign_digest(&self, digest: Sha256) -> Result { - DummySignature::from_bytes(digest.result()) + DummySignature::from_bytes(&digest.result()) } } From 291f119fec9e91ff8c8f28831bbb78044d912970 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 16 Mar 2020 07:45:02 -0700 Subject: [PATCH 0031/1461] signature: improve Debug impl on Error In the event errors have a source, this invokes the `Display` impl on the source (required by the bounds of `std::error::Error`) to make it easier to inspect. --- signature/src/error.rs | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/signature/src/error.rs b/signature/src/error.rs index 86d35c46a..9fba1e601 100644 --- a/signature/src/error.rs +++ b/signature/src/error.rs @@ -1,6 +1,6 @@ //! Signature error types -use core::fmt::{self, Display}; +use core::fmt::{self, Debug, Display}; #[cfg(feature = "std")] use std::boxed::Box; @@ -16,7 +16,7 @@ use std::boxed::Box; /// things like remote signers (e.g. HSM, KMS) to report I/O or auth errors. /// /// [BB'06]: https://en.wikipedia.org/wiki/Daniel_Bleichenbacher -#[derive(Debug, Default)] +#[derive(Default)] pub struct Error { /// Prevent from being instantiated as `Error {}` when the `std` feature /// is disabled @@ -51,6 +51,26 @@ impl Error { } } +impl Debug for Error { + #[cfg(not(feature = "std"))] + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("signature::Error {}") + } + + #[cfg(feature = "std")] + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("signature::Error { source: ")?; + + if let Some(source) = &self.source { + write!(f, "Some({})", source)?; + } else { + f.write_str("None")?; + } + + f.write_str(" }") + } +} + impl Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str("signature error") From 44175e14c62a87e8decb1e3ed0055726c2a42025 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 16 Mar 2020 08:05:08 -0700 Subject: [PATCH 0032/1461] signature v1.0.0-pre.5 --- signature/CHANGES.md | 8 ++++++++ signature/Cargo.toml | 2 +- signature/src/lib.rs | 15 +++++++++++---- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/signature/CHANGES.md b/signature/CHANGES.md index f201fb84b..f90447170 100644 --- a/signature/CHANGES.md +++ b/signature/CHANGES.md @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 1.0.0-pre.5 (2020-03-16) +### Changed +- Improve `Debug` impl on `Error` ([#89]) +- Rename `Signature::as_slice` -> `as_bytes` ([#87]) + +[#89]: https://github.com/RustCrypto/traits/pull/89 +[#87]: https://github.com/RustCrypto/traits/pull/87 + ## 1.0.0-pre.4 (2020-03-15) ### Added - Mark preview features as unstable in `Cargo.toml` ([#82]) diff --git a/signature/Cargo.toml b/signature/Cargo.toml index d5dd96c23..34956edb4 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "1.0.0-pre.4" # Also update html_root_url in lib.rs when bumping this +version = "1.0.0-pre.5" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/signature" diff --git a/signature/src/lib.rs b/signature/src/lib.rs index 14f3baf4a..3eb587013 100644 --- a/signature/src/lib.rs +++ b/signature/src/lib.rs @@ -122,7 +122,12 @@ //! //! Despite being post-1.0, this crate includes a number of off-by-default //! unstable features named `*-preview`, each of which depends on a pre-1.0 -//! crate. These features are as follows: +//! crate. +//! +//! These features are considered exempt from SemVer. See the +//! [SemVer policy](#semver-policy) above for more information. +//! +//! The following unstable features are presently supported: //! //! - `derive-preview`: for implementers of signature systems using //! [`DigestSigner`] and [`DigestVerifier`], the `derive-preview` feature @@ -134,7 +139,7 @@ //! digest signer/verifier type. Enabling this feature also enables `digest` //! support (see immediately below). //! - `digest-preview`: enables the [`DigestSigner`] and [`DigestVerifier`] -//! traits which are based on the `Digest` trait from the `digest` crate. +//! traits which are based on the [`Digest`] trait from the [`digest`] crate. //! These traits are used for representing signature systems based on the //! [Fiat-Shamir heuristic] which compute a random challenge value to sign //! by computing a cryptographically secure digest of the input message. @@ -142,14 +147,16 @@ //! systems which rely on a cryptographically secure random number generator //! for security. //! +//! [`Digest`]: https://docs.rs/digest/latest/digest/trait.Digest.html +//! [`digest`]: https://docs.rs/digest/latest/digest/ //! [Fiat-Shamir heuristic]: https://en.wikipedia.org/wiki/Fiat%E2%80%93Shamir_heuristic #![no_std] +#![cfg_attr(docsrs, feature(doc_cfg))] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png", - html_root_url = "https://docs.rs/signature/1.0.0-pre.3" + html_root_url = "https://docs.rs/signature/1.0.0-pre.5" )] -#![cfg_attr(docsrs, feature(doc_cfg))] #![forbid(unsafe_code)] #![warn( missing_docs, From 7f12dc5f2898937c44a125769d377c5d8f688f7d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 16 Mar 2020 08:23:26 -0700 Subject: [PATCH 0033/1461] signature: add more docs for `Signature` trait --- signature/src/signature.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/signature/src/signature.rs b/signature/src/signature.rs index 9db76614b..d03a39a9d 100644 --- a/signature/src/signature.rs +++ b/signature/src/signature.rs @@ -17,6 +17,17 @@ use crate::{ /// wrapper around the "bag-of-bytes" serialized form of a signature which can /// be directly parsed from or written to the "wire". /// +/// Inspiration for this approach comes from the Ed25519 signature system, +/// which adopted it based on the observation that past signature systems +/// were not prescriptive about how signatures should be represented +/// on-the-wire, and that lead to a proliferation of different wire formats and +/// confusion about which ones should be used. +/// +/// The [`Signature`] trait aims to provide similar simplicity by minimizing +/// the number of steps involved to obtain a serializable signature and +/// ideally ensuring there is one signature type for any given signature system +/// shared by all "provider" crates. +/// /// For signature systems which require a more advanced internal representation /// (e.g. involving decoded scalars or decompressed elliptic curve points) it's /// recommended that "provider" libraries maintain their own internal signature From 754bf0e25a9599b2851402e400e874477705de04 Mon Sep 17 00:00:00 2001 From: Chris Beck Date: Sat, 11 Apr 2020 20:39:20 -0700 Subject: [PATCH 0034/1461] Uprev generic array to version 0.14 In 0.14 they added a pretty nice feature, which is that you can now split not just arrays that you hold by value, but you can split references to generic arrays, into a pair of references to generic arrays corresponding to the subslices, where the size calculations are done correctly at compile-time and the buffer size information is all preserved. https://docs.rs/generic-array/0.14.1/src/generic_array/sequence.rs.html#302-320 I have some ECIES code that looks like this, that builds on `aead` trait: ``` fn decrypt_in_place_detached( &self, key: &RistrettoPrivate, footer: &GenericArray, buffer: &mut [u8], ) -> Result<(), Error> { let (footer, version_data): (_, &GenericArray) = footer.split(); ``` Alternate version is like ``` fn decrypt_in_place_detached( &self, key: &RistrettoPrivate, footer: &GenericArray, buffer: &mut [u8], ) -> Result<(), Error> { let (footer, version_data) = Split::::split(footer); ``` I think these are both expected to work generic array 0.14. There are alternatives of course but they are less tidy :) Since I'm getting the generic array pub export from you, I think that to use this, I have to convince you that it's worth it to uprev. LMK what you think! Thanks --- aead/Cargo.toml | 2 +- block-cipher-trait/Cargo.toml | 2 +- digest/Cargo.toml | 2 +- stream-cipher/Cargo.toml | 2 +- universal-hash/Cargo.toml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/aead/Cargo.toml b/aead/Cargo.toml index d18a3efa2..81179f243 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -11,7 +11,7 @@ keywords = ["crypto", "encryption"] categories = ["cryptography", "no-std"] [dependencies] -generic-array = { version = "0.13", default-features = false } +generic-array = { version = "0.14", default-features = false } heapless = { version = "0.5", optional = true } [features] diff --git a/block-cipher-trait/Cargo.toml b/block-cipher-trait/Cargo.toml index 70e9e7785..fe8498872 100644 --- a/block-cipher-trait/Cargo.toml +++ b/block-cipher-trait/Cargo.toml @@ -10,7 +10,7 @@ keywords = ["crypto", "block-cipher", "trait"] categories = ["cryptography", "no-std"] [dependencies] -generic-array = "0.13" +generic-array = "0.14" blobby = { version = "0.1", optional = true } [features] diff --git a/digest/Cargo.toml b/digest/Cargo.toml index faeeff901..e0a2e7ceb 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -10,7 +10,7 @@ keywords = ["digest", "crypto", "hash"] categories = ["cryptography", "no-std"] [dependencies] -generic-array = "0.13" +generic-array = "0.14" blobby = { version = "0.1", optional = true } [features] diff --git a/stream-cipher/Cargo.toml b/stream-cipher/Cargo.toml index 159a1806b..1355e7dc0 100644 --- a/stream-cipher/Cargo.toml +++ b/stream-cipher/Cargo.toml @@ -10,7 +10,7 @@ keywords = ["crypto", "stream-cipher", "trait"] categories = ["cryptography", "no-std"] [dependencies] -generic-array = "0.13" +generic-array = "0.14" blobby = { version = "0.1", optional = true } [features] diff --git a/universal-hash/Cargo.toml b/universal-hash/Cargo.toml index 0f412af61..66da45701 100644 --- a/universal-hash/Cargo.toml +++ b/universal-hash/Cargo.toml @@ -11,7 +11,7 @@ categories = ["cryptography", "no-std"] edition = "2018" [dependencies] -generic-array = "0.13" +generic-array = "0.14" subtle = { version = "2", default-features = false } [features] From 61b30326b734306692c2beb7e552119830c1fa2d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 18 Apr 2020 10:12:43 -0700 Subject: [PATCH 0035/1461] signature: rename DigestSignature => PrehashSignature The previous name poorly described what these signature types are: ones capable of producing a signature of a message which was hashed in advance. The phrase "pre-hash" is a relatively common one and better describes this property. --- signature/signature_derive/src/lib.rs | 16 ++++++++-------- signature/src/lib.rs | 4 ++-- signature/src/signature.rs | 8 +++++--- signature/tests/signature_derive.rs | 4 ++-- 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/signature/signature_derive/src/lib.rs b/signature/signature_derive/src/lib.rs index 81a3094a6..1059318de 100644 --- a/signature/signature_derive/src/lib.rs +++ b/signature/signature_derive/src/lib.rs @@ -20,7 +20,7 @@ fn derive_signer(mut s: synstructure::Structure) -> TokenStream { s.gen_impl(quote! { gen impl signature::Signer for @Self where - S: signature::DigestSignature, + S: signature::PrehashSignature, Self: signature::DigestSigner { fn try_sign(&self, msg: &[u8]) -> Result { @@ -35,10 +35,10 @@ decl_derive! { /// Derive the [`Signer`] trait for a type which impls [`DigestSigner`]. /// /// When implementing the [`DigestSigner`] trait for a signature type which - /// itself impl's the [`DigestSignature`] trait (which marks signature + /// itself impl's the [`PrehashSignature`] trait (which marks signature /// algorithms which are computed using a [`Digest`]), signature providers /// can automatically derive the [`Signer`] trait when the digest algorithm - /// is [`DigestSignature::Digest`] (i.e. the "standard" digest algorithm + /// is [`PrehashSignature::Digest`] (i.e. the "standard" digest algorithm /// for a given signature type) /// /// This automates all of the digest computation otherwise needed for a @@ -54,7 +54,7 @@ fn derive_verifier(mut s: synstructure::Structure) -> TokenStream { s.gen_impl(quote! { gen impl signature::Verifier for @Self where - S: signature::DigestSignature, + S: signature::PrehashSignature, Self: signature::DigestVerifier { fn verify(&self, msg: &[u8], signature: &S) -> Result<(), signature::Error> { @@ -69,10 +69,10 @@ decl_derive! { /// Derive the [`Verifier`] trait for a type which impls [`DigestVerifier`]. /// /// When implementing the [`DigestVerifier`] trait for a signature type which - /// itself impl's the [`DigestSignature`] trait (which marks signature + /// itself impl's the [`PrehashSignature`] trait (which marks signature /// algorithms which are computed using a [`Digest`]), signature providers /// can automatically derive the [`Verifier`] trait when the digest algorithm - /// is [`DigestSignature::Digest`] (i.e. the "standard" digest algorithm + /// is [`PrehashSignature::Digest`] (i.e. the "standard" digest algorithm /// for a given signature type) /// /// This automates all of the digest computation otherwise needed for a @@ -100,7 +100,7 @@ mod tests { const _DERIVE_signature_Signer_S_FOR_MySigner: () = { impl signature::Signer for MySigner where - S: signature::DigestSignature, + S: signature::PrehashSignature, Self: signature::DigestSigner { fn try_sign(&self, msg: &[u8]) -> Result { @@ -126,7 +126,7 @@ mod tests { const _DERIVE_signature_Verifier_S_FOR_MyVerifier: () = { impl signature::Verifier for MyVerifier where - S: signature::DigestSignature, + S: signature::PrehashSignature, Self: signature::DigestVerifier { fn verify(&self, msg: &[u8], signature: &S) -> Result<(), signature::Error> { diff --git a/signature/src/lib.rs b/signature/src/lib.rs index 3eb587013..56b240c1c 100644 --- a/signature/src/lib.rs +++ b/signature/src/lib.rs @@ -46,7 +46,7 @@ //! - Keep signature algorithm customizations / "knobs" out-of-band from the //! signing/verification APIs, ideally pushing such concerns into the type //! system so that algorithm mismatches are caught as type errors. -//! - Opaque error type which minimizes information leaked from crxyptographic +//! - Opaque error type which minimizes information leaked from cryptographic //! failures, as "rich" error types in these scenarios are often a source //! of sidechannel information for attackers (e.g. [BB'06]) //! @@ -132,7 +132,7 @@ //! - `derive-preview`: for implementers of signature systems using //! [`DigestSigner`] and [`DigestVerifier`], the `derive-preview` feature //! can be used to derive [`Signer`] and [`Verifier`] traits which prehash -//! the input message using the [`DigestSignature::Digest`] function for +//! the input message using the [`PrehashSignature::Digest`] algorithm for //! a given [`Signature`] type. When the `derive-preview` feature is enabled //! import the proc macros with `use signature::{Signer, Verifier}` and then //! add a `derive(Signer)` or `derive(Verifier)` attribute to the given diff --git a/signature/src/signature.rs b/signature/src/signature.rs index d03a39a9d..7aab71117 100644 --- a/signature/src/signature.rs +++ b/signature/src/signature.rs @@ -42,13 +42,15 @@ pub trait Signature: AsRef<[u8]> + Debug + Sized { } } -/// Marker trait for `Signature` types computable as `S(H(m))` +/// Marker trait for `Signature` types computable as `S(H(m))`, i.e. ones which +/// prehash a message to be signed as `H(m)`: /// /// - `S`: signature algorithm /// - `H`: hash (a.k.a. digest) function /// - `m`: message /// -/// i.e. a traditional application of the [Fiat-Shamir heuristic]. +/// This approach is relatively common in signature schemes based on the +/// [Fiat-Shamir heuristic]. /// /// For signature types that implement this trait, when the `derive-preview` /// Cargo feature is enabled a custom derive for [`Signer`] is available for any @@ -58,7 +60,7 @@ pub trait Signature: AsRef<[u8]> + Debug + Sized { /// [Fiat-Shamir heuristic]: https://en.wikipedia.org/wiki/Fiat%E2%80%93Shamir_heuristic #[cfg(feature = "digest-preview")] #[cfg_attr(docsrs, doc(cfg(feature = "digest-preview")))] -pub trait DigestSignature: Signature { +pub trait PrehashSignature: Signature { /// Preferred `Digest` algorithm to use when computing this signature type. type Digest: digest::Digest; } diff --git a/signature/tests/signature_derive.rs b/signature/tests/signature_derive.rs index c4b2532eb..d606abc8f 100644 --- a/signature/tests/signature_derive.rs +++ b/signature/tests/signature_derive.rs @@ -5,7 +5,7 @@ mod tests { use hex_literal::hex; use sha2::Sha256; use signature::{ - DigestSignature, DigestSigner, DigestVerifier, Error, Signature, Signer, Verifier, + DigestSigner, DigestVerifier, Error, PrehashSignature, Signature, Signer, Verifier, }; /// Test vector to compute SHA-256 digest of @@ -33,7 +33,7 @@ mod tests { } } - impl DigestSignature for DummySignature { + impl PrehashSignature for DummySignature { type Digest = Sha256; } From 01f587322b068b7e47ee62ed3769ee3a6dda5dc1 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 18 Apr 2020 10:40:23 -0700 Subject: [PATCH 0036/1461] signature v1.0.0 --- signature/CHANGES.md | 9 +++++++++ signature/Cargo.toml | 2 +- signature/src/lib.rs | 8 ++++---- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/signature/CHANGES.md b/signature/CHANGES.md index f90447170..ce6732684 100644 --- a/signature/CHANGES.md +++ b/signature/CHANGES.md @@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 1.0.0 (2020-04-18) + +Initial 1.0 release! 🎉 + +### Changed +- Rename `DigestSignature` => `PrehashSignature` ([#96]) + +[#96]: https://github.com/RustCrypto/traits/pull/96 + ## 1.0.0-pre.5 (2020-03-16) ### Changed - Improve `Debug` impl on `Error` ([#89]) diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 34956edb4..c6ee7fd95 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "1.0.0-pre.5" # Also update html_root_url in lib.rs when bumping this +version = "1.0.0" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/signature" diff --git a/signature/src/lib.rs b/signature/src/lib.rs index 56b240c1c..42b21faf6 100644 --- a/signature/src/lib.rs +++ b/signature/src/lib.rs @@ -1,7 +1,7 @@ //! RustCrypto: `signature` crate. //! //! Traits which provide generic, object-safe APIs for generating and verifying -//! digital signatures: message authentication using public-key cryptography. +//! digital signatures, i.e. message authentication using public-key cryptography. //! //! ## Minimum Supported Rust Version //! @@ -12,8 +12,8 @@ //! //! ## SemVer policy //! -//! - All on-by-default features of this library are covered by SemVer //! - MSRV is considered exempt from SemVer as noted above +//! - All on-by-default features of this library are covered by SemVer //! - Off-by-default features ending in `*-preview` (e.g. `derive-preview`, //! `digest-preview`) are unstable "preview" features which are also //! considered exempt from SemVer (typically because they rely on pre-1.0 @@ -154,8 +154,8 @@ #![no_std] #![cfg_attr(docsrs, feature(doc_cfg))] #![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png", - html_root_url = "https://docs.rs/signature/1.0.0-pre.5" + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/ferris_signer.png", + html_root_url = "https://docs.rs/signature/1.0.0" )] #![forbid(unsafe_code)] #![warn( From a1125eecf69556b1734387dab15ec37389165a8a Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 19 Apr 2020 11:27:11 -0700 Subject: [PATCH 0037/1461] signature_derive v1.0.0-pre.2 --- signature/Cargo.toml | 2 +- signature/signature_derive/CHANGES.md | 8 +++++++- signature/signature_derive/Cargo.toml | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/signature/Cargo.toml b/signature/Cargo.toml index c6ee7fd95..b3f52c717 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -22,7 +22,7 @@ optional = true default-features = false [dependencies.signature_derive] -version = "= 1.0.0-pre.1" +version = "= 1.0.0-pre.2" optional = true path = "signature_derive" diff --git a/signature/signature_derive/CHANGES.md b/signature/signature_derive/CHANGES.md index 7a868afad..eb7886b25 100644 --- a/signature/signature_derive/CHANGES.md +++ b/signature/signature_derive/CHANGES.md @@ -4,8 +4,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 1.0.0-pre.2 (2020-04-19) +### Changed +- Rename `DigestSignature` => `PrehashSignature` ([#96]) + +[#96]: https://github.com/RustCrypto/traits/pull/96 + ## 1.0.0-pre.1 (2020-03-08) -## Added +### Added - Initial Changelog for `signature_derive` - Rustdoc ([#79]) diff --git a/signature/signature_derive/Cargo.toml b/signature/signature_derive/Cargo.toml index c4e408d64..22a689b62 100644 --- a/signature/signature_derive/Cargo.toml +++ b/signature/signature_derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "signature_derive" -version = "1.0.0-pre.1" +version = "1.0.0-pre.2" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" description = "Custom derive support for the 'signature' crate" From a0d7684a0e55af1076e4ac394c50bc5db4f1f519 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 19 Apr 2020 11:51:32 -0700 Subject: [PATCH 0038/1461] signature v1.0.1 --- signature/CHANGES.md | 6 ++++++ signature/Cargo.toml | 2 +- signature/src/lib.rs | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/signature/CHANGES.md b/signature/CHANGES.md index ce6732684..70632f818 100644 --- a/signature/CHANGES.md +++ b/signature/CHANGES.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 1.0.1 (2020-04-19) +### Changed +- Upgrade `signature_derive` to v1.0.0-pre.2 ([#98]) + +[#98]: https://github.com/RustCrypto/traits/pull/98 + ## 1.0.0 (2020-04-18) Initial 1.0 release! 🎉 diff --git a/signature/Cargo.toml b/signature/Cargo.toml index b3f52c717..fdc093a61 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "1.0.0" # Also update html_root_url in lib.rs when bumping this +version = "1.0.1" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/signature" diff --git a/signature/src/lib.rs b/signature/src/lib.rs index 42b21faf6..3c90fa105 100644 --- a/signature/src/lib.rs +++ b/signature/src/lib.rs @@ -155,7 +155,7 @@ #![cfg_attr(docsrs, feature(doc_cfg))] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/ferris_signer.png", - html_root_url = "https://docs.rs/signature/1.0.0" + html_root_url = "https://docs.rs/signature/1.0.1" )] #![forbid(unsafe_code)] #![warn( From 8d7b5274456562224addf3a6a59b1b0f4674dd13 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 20 Apr 2020 10:43:52 -0700 Subject: [PATCH 0039/1461] signature: improve PrehashSignature docs --- signature/src/signature.rs | 12 +++++++----- signature/src/signer.rs | 2 +- signature/src/verifier.rs | 2 +- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/signature/src/signature.rs b/signature/src/signature.rs index 7aab71117..29aa0b845 100644 --- a/signature/src/signature.rs +++ b/signature/src/signature.rs @@ -42,12 +42,14 @@ pub trait Signature: AsRef<[u8]> + Debug + Sized { } } -/// Marker trait for `Signature` types computable as `S(H(m))`, i.e. ones which -/// prehash a message to be signed as `H(m)`: +/// Marker trait for `Signature` types computable as `𝐒(𝐇(𝒎))` +/// i.e. ones which prehash a message to be signed as `𝐇(𝒎)` /// -/// - `S`: signature algorithm -/// - `H`: hash (a.k.a. digest) function -/// - `m`: message +/// Where: +/// +/// - `𝐒`: signature algorithm +/// - `𝐇`: hash (a.k.a. digest) function +/// - `𝒎`: message /// /// This approach is relatively common in signature schemes based on the /// [Fiat-Shamir heuristic]. diff --git a/signature/src/signer.rs b/signature/src/signer.rs index d456d466e..a2fa588b8 100644 --- a/signature/src/signer.rs +++ b/signature/src/signer.rs @@ -24,7 +24,7 @@ pub trait Signer { fn try_sign(&self, msg: &[u8]) -> Result; } -/// Sign the given prehashed message `Digest` using `Self`. +/// Sign the given prehashed message [`Digest`] using `Self`. /// /// ## Notes /// diff --git a/signature/src/verifier.rs b/signature/src/verifier.rs index 3236889cf..45562ee61 100644 --- a/signature/src/verifier.rs +++ b/signature/src/verifier.rs @@ -14,7 +14,7 @@ pub trait Verifier { fn verify(&self, msg: &[u8], signature: &S) -> Result<(), Error>; } -/// Verify the provided signature for the given prehashed message `Digest` +/// Verify the provided signature for the given prehashed message [`Digest`] /// is authentic. /// /// ## Notes From c22ce8aa6a6f9cbb229b72a257fe5a252a3cfede Mon Sep 17 00:00:00 2001 From: Hubert Hirtz Date: Sun, 26 Apr 2020 11:39:10 +0200 Subject: [PATCH 0040/1461] Forbid unsafe code `#![forbid(unsafe_code)]` attributes make rustc abort compilation if there are any unsafe blocks in the crate, and exceptions cannot be made with allow/warn attributes. --- aead/src/lib.rs | 1 + block-cipher-trait/src/lib.rs | 1 + crypto-mac/src/lib.rs | 1 + digest/src/lib.rs | 1 + stream-cipher/src/lib.rs | 1 + universal-hash/src/lib.rs | 1 + 6 files changed, 6 insertions(+) diff --git a/aead/src/lib.rs b/aead/src/lib.rs index 61f29c01e..b0d795949 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -13,6 +13,7 @@ //! [RustCrypto/AEADs]: https://github.com/RustCrypto/AEADs #![no_std] +#![forbid(unsafe_code)] #[cfg(feature = "alloc")] extern crate alloc; diff --git a/block-cipher-trait/src/lib.rs b/block-cipher-trait/src/lib.rs index 497287fd7..168086990 100644 --- a/block-cipher-trait/src/lib.rs +++ b/block-cipher-trait/src/lib.rs @@ -1,6 +1,7 @@ //! This crate defines a set of simple traits used to define functionality of //! block ciphers. #![no_std] +#![forbid(unsafe_code)] #![doc(html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png")] #[cfg(feature = "dev")] pub extern crate blobby; diff --git a/crypto-mac/src/lib.rs b/crypto-mac/src/lib.rs index 70779cf7e..da1d5c452 100644 --- a/crypto-mac/src/lib.rs +++ b/crypto-mac/src/lib.rs @@ -1,5 +1,6 @@ //! This crate provides trait for Message Authentication Code (MAC) algorithms. #![no_std] +#![forbid(unsafe_code)] #![doc(html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png")] pub extern crate generic_array; extern crate subtle; diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 3d2e06757..fc61b0f75 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -13,6 +13,7 @@ //! //! The `Digest` trait is the most commonly used trait. #![no_std] +#![forbid(unsafe_code)] #![doc(html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png")] pub extern crate generic_array; #[cfg(feature = "std")] diff --git a/stream-cipher/src/lib.rs b/stream-cipher/src/lib.rs index e973c39a0..377f04fc0 100644 --- a/stream-cipher/src/lib.rs +++ b/stream-cipher/src/lib.rs @@ -4,6 +4,7 @@ //! See [RustCrypto/stream-ciphers](https://github.com/RustCrypto/stream-ciphers) //! for ciphers implementation. #![no_std] +#![forbid(unsafe_code)] #![doc(html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png")] #[cfg(feature = "dev")] pub extern crate blobby; diff --git a/universal-hash/src/lib.rs b/universal-hash/src/lib.rs index 26f7d913c..b0981f155 100644 --- a/universal-hash/src/lib.rs +++ b/universal-hash/src/lib.rs @@ -14,6 +14,7 @@ //! [Universal Hash Functions]: https://en.wikipedia.org/wiki/Universal_hashing #![no_std] +#![forbid(unsafe_code)] #![doc(html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png")] #![warn(missing_docs, rust_2018_idioms)] From 30e4fb696b318af76e01e43442d1ece36f71ad11 Mon Sep 17 00:00:00 2001 From: Chris Beck Date: Mon, 4 May 2020 22:36:18 -0700 Subject: [PATCH 0041/1461] Update .travis.yml and README.md to have MSRV 1.41, also test 1.43 --- .travis.yml | 6 +++--- README.md | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5a4fcef3d..554aa4ef8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,16 +4,16 @@ sudo: required matrix: include: - - rust: 1.31.0 + - rust: 1.41.0 script: cargo test --verbose --all --exclude aead --exclude signature --exclude universal-hash --release - - rust: 1.36.0 + - rust: 1.43.0 script: cargo test --verbose --package aead --package signature --package universal-hash --release - rust: stable script: cargo test --verbose --all --release - rust: nightly script: cargo test --verbose --all --release # tests if crates can be built with std feature - - rust: 1.31.0 + - rust: 1.41.0 script: ./build_std.sh - env: TARGET=i686-unknown-linux-gnu diff --git a/README.md b/README.md index cc1afce17..0a5bf208a 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Collection of traits which describe functionality of cryptographic primitives. | [`stream-cipher`](https://en.wikipedia.org/wiki/Stream_cipher) | [![crates.io](https://img.shields.io/crates/v/stream-cipher.svg)](https://crates.io/crates/stream-cipher) | [![Documentation](https://docs.rs/stream-cipher/badge.svg)](https://docs.rs/stream-cipher) | ### Minimum Rust version -All crates in this repository support Rust 1.31 or higher unless otherwise noted. +All crates in this repository support Rust 1.41 or higher unless otherwise noted. In future minimally supported version of Rust can be changed, but it will be done with the minor version bump. From 96a76a2f243c32aee9a07a5683af31b8fe3ec18d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 10 May 2020 07:08:27 -0700 Subject: [PATCH 0042/1461] README.md: add `universal-hash` crate to table --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 0a5bf208a..70cbffd63 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ Collection of traits which describe functionality of cryptographic primitives. | [`digest`](https://en.wikipedia.org/wiki/Cryptographic_hash_function) | [![crates.io](https://img.shields.io/crates/v/digest.svg)](https://crates.io/crates/digest) | [![Documentation](https://docs.rs/digest/badge.svg)](https://docs.rs/digest) | | [`signature`](https://en.wikipedia.org/wiki/Digital_signature) | [![crates.io](https://img.shields.io/crates/v/signature.svg)](https://crates.io/crates/signature) | [![Documentation](https://docs.rs/signature/badge.svg)](https://docs.rs/signature) | | [`stream-cipher`](https://en.wikipedia.org/wiki/Stream_cipher) | [![crates.io](https://img.shields.io/crates/v/stream-cipher.svg)](https://crates.io/crates/stream-cipher) | [![Documentation](https://docs.rs/stream-cipher/badge.svg)](https://docs.rs/stream-cipher) | +| [`universal-hash`](https://en.wikipedia.org/wiki/Universal_hashing) | [![crates.io](https://img.shields.io/crates/v/universal-hash.svg)](https://crates.io/crates/universal-hash) | [![Documentation](https://docs.rs/universal-hash/badge.svg)](https://docs.rs/universal-hash) | ### Minimum Rust version All crates in this repository support Rust 1.41 or higher unless otherwise noted. From d953b4c4c846ee8aed4c4412cc49686e7d5958b3 Mon Sep 17 00:00:00 2001 From: Akhil Velagapudi Date: Tue, 29 Oct 2019 22:18:17 -0700 Subject: [PATCH 0043/1461] initial workspace workflow shared by all crates --- .github/workflows/workspace.yml | 45 +++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 .github/workflows/workspace.yml diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml new file mode 100644 index 000000000..cf254e50e --- /dev/null +++ b/.github/workflows/workspace.yml @@ -0,0 +1,45 @@ +name: workspace +on: +- push +- pull_request +jobs: + test: + runs-on: ubuntu-latest + strategy: + matrix: + rust: + - stable + - beta + - nightly + - 1.36.0 # workspace MSRV + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.rust }} + - run: | + cargo check --all-features + cargo test --no-default-features + cargo test + cargo test --all-features + clippy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + components: clippy + - run: cargo clippy --all-features -- -D warnings + no_std: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + target: thumbv7em-none-eabi + - run: cargo build --target thumbv7em-none-eabi From 13aa64b3061eb2201ec69c39cda5bd96ce4cee42 Mon Sep 17 00:00:00 2001 From: Akhil Velagapudi Date: Tue, 29 Oct 2019 22:19:01 -0700 Subject: [PATCH 0044/1461] crate specific workflows for older MSRVs and custom feature sets --- .github/workflows/block-cipher-trait.yml | 27 ++++++++++++++++++++++++ .github/workflows/crypto-mac.yml | 27 ++++++++++++++++++++++++ .github/workflows/digest.yml | 27 ++++++++++++++++++++++++ .github/workflows/stream-cipher.yml | 27 ++++++++++++++++++++++++ 4 files changed, 108 insertions(+) create mode 100644 .github/workflows/block-cipher-trait.yml create mode 100644 .github/workflows/crypto-mac.yml create mode 100644 .github/workflows/digest.yml create mode 100644 .github/workflows/stream-cipher.yml diff --git a/.github/workflows/block-cipher-trait.yml b/.github/workflows/block-cipher-trait.yml new file mode 100644 index 000000000..886c64d50 --- /dev/null +++ b/.github/workflows/block-cipher-trait.yml @@ -0,0 +1,27 @@ +name: block-cipher-trait +on: + push: + paths: + - 'block-cipher-trait/**' +jobs: + test: + runs-on: ubuntu-latest + strategy: + matrix: + rust: + - stable + - beta + - nightly + - 1.21.0 # MSRV + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.rust }} + - run: | + cargo check --all-features + cargo test --features dev + cargo test --features std + cargo test --all-features + working-directory: block-cipher-trait diff --git a/.github/workflows/crypto-mac.yml b/.github/workflows/crypto-mac.yml new file mode 100644 index 000000000..5a0e82b9d --- /dev/null +++ b/.github/workflows/crypto-mac.yml @@ -0,0 +1,27 @@ +name: crypto-mac +on: + push: + paths: + - 'crypto-mac/**' +jobs: + test: + runs-on: ubuntu-latest + strategy: + matrix: + rust: + - stable + - beta + - nightly + - 1.21.0 # MSRV + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.rust }} + - run: | + cargo check --all-features + cargo test --features dev + cargo test --features std + cargo test --all-features + working-directory: crypto-mac diff --git a/.github/workflows/digest.yml b/.github/workflows/digest.yml new file mode 100644 index 000000000..706487c8a --- /dev/null +++ b/.github/workflows/digest.yml @@ -0,0 +1,27 @@ +name: digest +on: + push: + paths: + - 'digest/**' +jobs: + test: + runs-on: ubuntu-latest + strategy: + matrix: + rust: + - stable + - beta + - nightly + - 1.21.0 # MSRV + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.rust }} + - run: | + cargo check --all-features + cargo test --features dev + cargo test --features std + cargo test --all-features + working-directory: digest diff --git a/.github/workflows/stream-cipher.yml b/.github/workflows/stream-cipher.yml new file mode 100644 index 000000000..9e3a22d14 --- /dev/null +++ b/.github/workflows/stream-cipher.yml @@ -0,0 +1,27 @@ +name: stream-cipher +on: + push: + paths: + - 'stream-cipher/**' +jobs: + test: + runs-on: ubuntu-latest + strategy: + matrix: + rust: + - stable + - beta + - nightly + - 1.21.0 # MSRV + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.rust }} + - run: | + cargo check --all-features + cargo test --features dev + cargo test --features std + cargo test --all-features + working-directory: stream-cipher From 7311b1b7c50e084526e03d6905298d11d694d0d0 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 10 May 2020 11:22:33 -0700 Subject: [PATCH 0045/1461] Remove .travis.yml No longer needed after migrating to GitHub Actions --- .travis.yml | 40 ---------------------------------------- 1 file changed, 40 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 554aa4ef8..000000000 --- a/.travis.yml +++ /dev/null @@ -1,40 +0,0 @@ -language: rust -services: docker -sudo: required - -matrix: - include: - - rust: 1.41.0 - script: cargo test --verbose --all --exclude aead --exclude signature --exclude universal-hash --release - - rust: 1.43.0 - script: cargo test --verbose --package aead --package signature --package universal-hash --release - - rust: stable - script: cargo test --verbose --all --release - - rust: nightly - script: cargo test --verbose --all --release - # tests if crates can be built with std feature - - rust: 1.41.0 - script: ./build_std.sh - - - env: TARGET=i686-unknown-linux-gnu - rust: stable - - env: TARGET=powerpc-unknown-linux-gnu - rust: stable - - env: TARGET=powerpc64-unknown-linux-gnu - rust: stable - # tests if crates truly can be built without std - - env: TARGET=thumbv7em-none-eabi - rust: nightly - script: xargo build --all --exclude aead --exclude signature --verbose --target $TARGET - install: - - cargo install xargo || true - - rustup target install armv7-unknown-linux-gnueabihf - - rustup component add rust-src - -install: - - cargo install cross || true - -script: - - cross test --verbose --all --exclude signature_derive --release --target $TARGET - -cache: cargo From 34fade19638f50f9879042855ea92f9232d790aa Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 10 May 2020 11:27:52 -0700 Subject: [PATCH 0046/1461] .github: only build on Rust 1.41 + stable This bumps the MSRV to 1.41 to match the current state of the repo and removes the `beta` and `nightly` builds as these create a much larger combinatorial explosion of builds. --- .github/workflows/block-cipher-trait.yml | 4 +--- .github/workflows/crypto-mac.yml | 4 +--- .github/workflows/digest.yml | 4 +--- .github/workflows/stream-cipher.yml | 4 +--- .github/workflows/workspace.yml | 4 +--- README.md | 1 + 6 files changed, 6 insertions(+), 15 deletions(-) diff --git a/.github/workflows/block-cipher-trait.yml b/.github/workflows/block-cipher-trait.yml index 886c64d50..cbce21c8e 100644 --- a/.github/workflows/block-cipher-trait.yml +++ b/.github/workflows/block-cipher-trait.yml @@ -9,10 +9,8 @@ jobs: strategy: matrix: rust: + - 1.41.0 # MSRV - stable - - beta - - nightly - - 1.21.0 # MSRV steps: - uses: actions/checkout@v1 - uses: actions-rs/toolchain@v1 diff --git a/.github/workflows/crypto-mac.yml b/.github/workflows/crypto-mac.yml index 5a0e82b9d..bcaf1894e 100644 --- a/.github/workflows/crypto-mac.yml +++ b/.github/workflows/crypto-mac.yml @@ -9,10 +9,8 @@ jobs: strategy: matrix: rust: + - 1.41.0 # MSRV - stable - - beta - - nightly - - 1.21.0 # MSRV steps: - uses: actions/checkout@v1 - uses: actions-rs/toolchain@v1 diff --git a/.github/workflows/digest.yml b/.github/workflows/digest.yml index 706487c8a..f09ae10bd 100644 --- a/.github/workflows/digest.yml +++ b/.github/workflows/digest.yml @@ -9,10 +9,8 @@ jobs: strategy: matrix: rust: + - 1.41.0 # MSRV - stable - - beta - - nightly - - 1.21.0 # MSRV steps: - uses: actions/checkout@v1 - uses: actions-rs/toolchain@v1 diff --git a/.github/workflows/stream-cipher.yml b/.github/workflows/stream-cipher.yml index 9e3a22d14..1ae442d7c 100644 --- a/.github/workflows/stream-cipher.yml +++ b/.github/workflows/stream-cipher.yml @@ -9,10 +9,8 @@ jobs: strategy: matrix: rust: + - 1.41.0 # MSRV - stable - - beta - - nightly - - 1.21.0 # MSRV steps: - uses: actions/checkout@v1 - uses: actions-rs/toolchain@v1 diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index cf254e50e..b47128900 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -8,10 +8,8 @@ jobs: strategy: matrix: rust: + - 1.41.0 # MSRV - stable - - beta - - nightly - - 1.36.0 # workspace MSRV steps: - uses: actions/checkout@v1 - uses: actions-rs/toolchain@v1 diff --git a/README.md b/README.md index 70cbffd63..e830d9f64 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ Collection of traits which describe functionality of cryptographic primitives. | [`universal-hash`](https://en.wikipedia.org/wiki/Universal_hashing) | [![crates.io](https://img.shields.io/crates/v/universal-hash.svg)](https://crates.io/crates/universal-hash) | [![Documentation](https://docs.rs/universal-hash/badge.svg)](https://docs.rs/universal-hash) | ### Minimum Rust version + All crates in this repository support Rust 1.41 or higher unless otherwise noted. In future minimally supported version of Rust can be changed, but it will be done From 6992f367ebae0fb31ef11d90b2f78a8d7f8de1a0 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 10 May 2020 11:32:07 -0700 Subject: [PATCH 0047/1461] .github: build pull requests Builds all crates when pull requests are opened as well as pushes to master. --- .github/workflows/block-cipher-trait.yml | 10 +++++++++- .github/workflows/crypto-mac.yml | 10 +++++++++- .github/workflows/digest.yml | 10 +++++++++- .github/workflows/stream-cipher.yml | 10 +++++++++- .github/workflows/workspace.yml | 13 ++++++++++--- 5 files changed, 46 insertions(+), 7 deletions(-) diff --git a/.github/workflows/block-cipher-trait.yml b/.github/workflows/block-cipher-trait.yml index cbce21c8e..a7b28ae08 100644 --- a/.github/workflows/block-cipher-trait.yml +++ b/.github/workflows/block-cipher-trait.yml @@ -1,8 +1,16 @@ name: block-cipher-trait + on: + pull_request: + paths: + - "block-cipher-trait/**" + - "Cargo.*" push: + branches: master paths: - - 'block-cipher-trait/**' + - "block-cipher-trait/**" + - "Cargo.*" + jobs: test: runs-on: ubuntu-latest diff --git a/.github/workflows/crypto-mac.yml b/.github/workflows/crypto-mac.yml index bcaf1894e..6271a1c46 100644 --- a/.github/workflows/crypto-mac.yml +++ b/.github/workflows/crypto-mac.yml @@ -1,8 +1,16 @@ name: crypto-mac + on: + pull_request: + paths: + - "crypto-mac/**" + - "Cargo.*" push: + branches: master paths: - - 'crypto-mac/**' + - "crypto-mac/**" + - "Cargo.*" + jobs: test: runs-on: ubuntu-latest diff --git a/.github/workflows/digest.yml b/.github/workflows/digest.yml index f09ae10bd..400b0211e 100644 --- a/.github/workflows/digest.yml +++ b/.github/workflows/digest.yml @@ -1,8 +1,16 @@ name: digest + on: + pull_request: + paths: + - "digest/**" + - "Cargo.*" push: + branches: master paths: - - 'digest/**' + - "digest/**" + - "Cargo.*" + jobs: test: runs-on: ubuntu-latest diff --git a/.github/workflows/stream-cipher.yml b/.github/workflows/stream-cipher.yml index 1ae442d7c..1ff1141ad 100644 --- a/.github/workflows/stream-cipher.yml +++ b/.github/workflows/stream-cipher.yml @@ -1,8 +1,16 @@ name: stream-cipher + on: + pull_request: + paths: + - "stream-cipher/**" + - "Cargo.*" push: + branches: master paths: - - 'stream-cipher/**' + - "stream-cipher/**" + - "Cargo.*" + jobs: test: runs-on: ubuntu-latest diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index b47128900..a29f0dc94 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -1,7 +1,14 @@ -name: workspace +name: Workspace + on: -- push -- pull_request + pull_request: + paths-ignore: + - README.md + push: + branches: master + paths-ignore: + - README.md + jobs: test: runs-on: ubuntu-latest From 16d802c5367f2282492e57ef68c64a354a20ec11 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 10 May 2020 11:44:34 -0700 Subject: [PATCH 0048/1461] .github: remove no_std build configuration This needs to be split apart by crate since we need to pass `--no-default-features` and that's not available at a workspace level. This can get added back once the initial build is working. --- .github/workflows/workspace.yml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index a29f0dc94..64ac7b59c 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -38,13 +38,3 @@ jobs: toolchain: stable components: clippy - run: cargo clippy --all-features -- -D warnings - no_std: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: stable - target: thumbv7em-none-eabi - - run: cargo build --target thumbv7em-none-eabi From 3c547a73045e950507450203c09e246db3794e03 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 10 May 2020 11:45:42 -0700 Subject: [PATCH 0049/1461] Cargo.lock: check into repository This is useful for gating GitHub Actions' caching --- .gitignore | 4 - Cargo.lock | 301 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 301 insertions(+), 4 deletions(-) create mode 100644 Cargo.lock diff --git a/.gitignore b/.gitignore index a4048e8bb..2f7896d1d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1 @@ target/ -*/target/ -*/*/target/ -Cargo.lock - diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 000000000..42f6afa6b --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,301 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "aead" +version = "0.2.0" +dependencies = [ + "generic-array 0.14.1", + "heapless", +] + +[[package]] +name = "as-slice" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37dfb65bc03b2bc85ee827004f14a6817e04160e3b1a28931986a666a9290e70" +dependencies = [ + "generic-array 0.12.3", + "generic-array 0.13.2", + "stable_deref_trait", +] + +[[package]] +name = "blobby" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe5f8c2940b65859ece4b3b2ba02d2b12c87cab455fd42dee2556a187bb2cf6" +dependencies = [ + "byteorder", +] + +[[package]] +name = "block-buffer" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" +dependencies = [ + "block-padding", + "byte-tools", + "byteorder", + "generic-array 0.12.3", +] + +[[package]] +name = "block-cipher-trait" +version = "0.6.2" +dependencies = [ + "blobby", + "generic-array 0.14.1", +] + +[[package]] +name = "block-padding" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" +dependencies = [ + "byte-tools", +] + +[[package]] +name = "byte-tools" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" + +[[package]] +name = "byteorder" +version = "1.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" + +[[package]] +name = "crypto-mac" +version = "0.8.0" +dependencies = [ + "blobby", + "generic-array 0.13.2", + "subtle", +] + +[[package]] +name = "digest" +version = "0.8.1" +dependencies = [ + "blobby", + "generic-array 0.14.1", +] + +[[package]] +name = "digest" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" +dependencies = [ + "generic-array 0.12.3", +] + +[[package]] +name = "fake-simd" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" + +[[package]] +name = "generic-array" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" +dependencies = [ + "typenum", +] + +[[package]] +name = "generic-array" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ed1e761351b56f54eb9dcd0cfaca9fd0daecf93918e1cfc01c8a3d26ee7adcd" +dependencies = [ + "typenum", +] + +[[package]] +name = "generic-array" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d2664c2cf08049036f31015b04c6ac3671379a1d86f52ed2416893f16022deb" +dependencies = [ + "typenum", +] + +[[package]] +name = "hash32" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4041af86e63ac4298ce40e5cca669066e75b6f1aa3390fe2561ffa5e1d9f4cc" +dependencies = [ + "byteorder", +] + +[[package]] +name = "heapless" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73a8a2391a3bc70b31f60e7a90daa5755a360559c0b6b9c5cfc0fee482362dc0" +dependencies = [ + "as-slice", + "generic-array 0.13.2", + "hash32", + "stable_deref_trait", +] + +[[package]] +name = "hex-literal" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "961de220ec9a91af2e1e5bd80d02109155695e516771762381ef8581317066e0" +dependencies = [ + "hex-literal-impl", + "proc-macro-hack", +] + +[[package]] +name = "hex-literal-impl" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d4c5c844e2fee0bf673d54c2c177f1713b3d2af2ff6e666b49cb7572e6cf42d" +dependencies = [ + "proc-macro-hack", +] + +[[package]] +name = "opaque-debug" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" + +[[package]] +name = "proc-macro-hack" +version = "0.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d659fe7c6d27f25e9d80a1a094c223f5246f6a6596453e09d7229bf42750b63" + +[[package]] +name = "proc-macro2" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8872cf6f48eee44265156c111456a700ab3483686b3f96df4cf5481c89157319" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c1f4b0efa5fc5e8ceb705136bfee52cfdb6a4e3509f770b478cd6ed434232a7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" + +[[package]] +name = "sha2" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27044adfd2e1f077f649f59deb9490d3941d674002f7d062870a60ebe9bd47a0" +dependencies = [ + "block-buffer", + "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "fake-simd", + "opaque-debug", +] + +[[package]] +name = "signature" +version = "1.0.1" +dependencies = [ + "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal", + "rand_core", + "sha2", + "signature_derive", +] + +[[package]] +name = "signature_derive" +version = "1.0.0-pre.2" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "stable_deref_trait" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" + +[[package]] +name = "stream-cipher" +version = "0.3.2" +dependencies = [ + "blobby", + "generic-array 0.14.1", +] + +[[package]] +name = "subtle" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c65d530b10ccaeac294f349038a597e435b18fb456aadd0840a623f83b9e941" + +[[package]] +name = "syn" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8e5aa70697bb26ee62214ae3288465ecec0000f05182f039b477001f08f5ae7" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "synstructure" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "unicode-xid", +] + +[[package]] +name = "typenum" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" + +[[package]] +name = "unicode-xid" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" + +[[package]] +name = "universal-hash" +version = "0.3.0" +dependencies = [ + "generic-array 0.14.1", + "subtle", +] From 94e3729a78c33c3297b29f4909ca6d73b74b6478 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 10 May 2020 11:49:48 -0700 Subject: [PATCH 0050/1461] .github: add workflow for `signature` crate --- .github/workflows/signature.yml | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 .github/workflows/signature.yml diff --git a/.github/workflows/signature.yml b/.github/workflows/signature.yml new file mode 100644 index 000000000..aa033f16e --- /dev/null +++ b/.github/workflows/signature.yml @@ -0,0 +1,33 @@ +name: signature + +on: + pull_request: + paths: + - "signature/**" + - "Cargo.*" + push: + branches: master + paths: + - "signature/**" + - "Cargo.*" + +jobs: + test: + runs-on: ubuntu-latest + strategy: + matrix: + rust: + - 1.41.0 # MSRV + - stable + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.rust }} + - run: | + cargo check --all-features + cargo test --features dev + cargo test --features std + cargo test --all-features + working-directory: signature From 026318b39deb7b1c65ce52d3f409064ecd42d826 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 10 May 2020 11:54:35 -0700 Subject: [PATCH 0051/1461] universal-hash: fix cargo check failures + std::error::Error The `Display` impl on the error type was using the deprecated `description()` method. This was removed. With that removed, the `Display` impl can still exist in a `no_std` environment. Reduces the `std::error::Error` impl to just a marker trait. --- universal-hash/src/lib.rs | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/universal-hash/src/lib.rs b/universal-hash/src/lib.rs index b0981f155..264bdd9ab 100644 --- a/universal-hash/src/lib.rs +++ b/universal-hash/src/lib.rs @@ -156,17 +156,11 @@ impl> Eq for Output {} #[derive(Default, Debug, Copy, Clone, Eq, PartialEq)] pub struct Error; -#[cfg(feature = "std")] -impl std::error::Error for Error { - fn description(&self) -> &'static str { - "UHF output mismatch" +impl core::fmt::Display for Error { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str("UHF output mismatch") } } #[cfg(feature = "std")] -impl std::fmt::Display for Error { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - use std::error::Error; - self.description().fmt(f) - } -} +impl std::error::Error for Error {} From 9e9b814f27bcd0e7ef9e5577d4c3eff920e24518 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 10 May 2020 11:55:46 -0700 Subject: [PATCH 0052/1461] digest: fix `cargo check` warnings Missing the `dyn` keyword on `DynDigest` --- digest/src/dyn_digest.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/digest/src/dyn_digest.rs b/digest/src/dyn_digest.rs index cb144bdee..93dfdd08c 100644 --- a/digest/src/dyn_digest.rs +++ b/digest/src/dyn_digest.rs @@ -25,7 +25,7 @@ pub trait DynDigest { fn output_size(&self) -> usize; /// Clone hasher state into a boxed trait object - fn box_clone(&self) -> Box; + fn box_clone(&self) -> Box; } impl DynDigest for D { @@ -51,12 +51,12 @@ impl DynDigest for D { ::OutputSize::to_usize() } - fn box_clone(&self) -> Box { + fn box_clone(&self) -> Box { Box::new(self.clone()) } } -impl Clone for Box { +impl Clone for Box { fn clone(&self) -> Self { self.box_clone() } From d42712b3b41d4f7cc9893f5f2f49deced474218d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 10 May 2020 12:02:21 -0700 Subject: [PATCH 0053/1461] digest: fix clippy warnings --- .github/workflows/workspace.yml | 2 +- digest/src/dev.rs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index 64ac7b59c..62865cf50 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -37,4 +37,4 @@ jobs: profile: minimal toolchain: stable components: clippy - - run: cargo clippy --all-features -- -D warnings + - run: cargo clippy --all --all-features -- -D warnings diff --git a/digest/src/dev.rs b/digest/src/dev.rs index f4d79e71e..71723a266 100644 --- a/digest/src/dev.rs +++ b/digest/src/dev.rs @@ -57,7 +57,7 @@ mod foo { while left > 0 { let take = (left + 1) / 2; hasher.input(&input[len - left..take + len - left]); - left = left - take; + left -= take; } if hasher.result().as_slice() != output { return Some("message in pieces"); @@ -129,7 +129,7 @@ where while left > 0 { let take = (left + 1) / 2; hasher.input(&input[len - left..take + len - left]); - left = left - take; + left -= take; } { @@ -186,7 +186,7 @@ where while left > 0 { let take = (left + 1) / 2; hasher.input(&input[len - left..take + len - left]); - left = left - take; + left -= take; } hasher.variable_result(|res| buf.copy_from_slice(res)); if buf != output { From e55a798b8ad9df7661ea3704090671df0c647434 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 10 May 2020 12:03:39 -0700 Subject: [PATCH 0054/1461] .github: remove copypasta cargo features from `signature` It doesn't have a `dev` feature --- .github/workflows/signature.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/signature.yml b/.github/workflows/signature.yml index aa033f16e..f835bf94f 100644 --- a/.github/workflows/signature.yml +++ b/.github/workflows/signature.yml @@ -27,7 +27,6 @@ jobs: toolchain: ${{ matrix.rust }} - run: | cargo check --all-features - cargo test --features dev - cargo test --features std - cargo test --all-features + cargo test --no-default-features + cargo test working-directory: signature From 455b8cc4bdbadbedf6aaa39ed998641ec3baa564 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 10 May 2020 12:08:11 -0700 Subject: [PATCH 0055/1461] .github: remove workspace-level tests; add rustfmt Each crate is already tested individually, so we don't need to run tests at the workspace-level as well. However, it is good to know if rustfmt is passing! --- .github/workflows/workspace.yml | 38 ++++++++++++++++----------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index 62865cf50..57a726c7d 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -10,24 +10,6 @@ on: - README.md jobs: - test: - runs-on: ubuntu-latest - strategy: - matrix: - rust: - - 1.41.0 # MSRV - - stable - steps: - - uses: actions/checkout@v1 - - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: ${{ matrix.rust }} - - run: | - cargo check --all-features - cargo test --no-default-features - cargo test - cargo test --all-features clippy: runs-on: ubuntu-latest steps: @@ -35,6 +17,24 @@ jobs: - uses: actions-rs/toolchain@v1 with: profile: minimal - toolchain: stable + toolchain: 1.41.0 components: clippy - run: cargo clippy --all --all-features -- -D warnings + rustfmt: + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v1 + + - name: Install stable toolchain + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + components: rustfmt + + - name: Run cargo fmt + uses: actions-rs/cargo@v1 + with: + command: fmt + args: --all -- --check From ae2268dd50cd2162e9dedba7c9597aebaa24caf3 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 10 May 2020 12:22:14 -0700 Subject: [PATCH 0056/1461] .github: add no_std build jobs These ensure crates build in no_std environments --- .github/workflows/block-cipher-trait.yml | 24 ++++++++++++++++++++++++ .github/workflows/crypto-mac.yml | 24 ++++++++++++++++++++++++ .github/workflows/digest.yml | 24 ++++++++++++++++++++++++ .github/workflows/signature.yml | 24 ++++++++++++++++++++++++ .github/workflows/stream-cipher.yml | 24 ++++++++++++++++++++++++ 5 files changed, 120 insertions(+) diff --git a/.github/workflows/block-cipher-trait.yml b/.github/workflows/block-cipher-trait.yml index a7b28ae08..2ac3834ed 100644 --- a/.github/workflows/block-cipher-trait.yml +++ b/.github/workflows/block-cipher-trait.yml @@ -12,6 +12,30 @@ on: - "Cargo.*" jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + target: + - thumbv7em-none-eabi + - wasm32-unknown-unknown + rust: + - 1.41.0 # MSRV + - stable + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.rust }} + - name: Install toolchain + uses: actions-rs/toolchain@v1 + with: + target: ${{ matrix.target }} + toolchain: ${{ matrix.toolchain }} + override: true + - working-directory: block-cipher-trait + run: cargo build --no-default-features --release --target ${{ matrix.target }} test: runs-on: ubuntu-latest strategy: diff --git a/.github/workflows/crypto-mac.yml b/.github/workflows/crypto-mac.yml index 6271a1c46..ecd0aa9aa 100644 --- a/.github/workflows/crypto-mac.yml +++ b/.github/workflows/crypto-mac.yml @@ -12,6 +12,30 @@ on: - "Cargo.*" jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + target: + - thumbv7em-none-eabi + - wasm32-unknown-unknown + rust: + - 1.41.0 # MSRV + - stable + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.rust }} + - name: Install toolchain + uses: actions-rs/toolchain@v1 + with: + target: ${{ matrix.target }} + toolchain: ${{ matrix.toolchain }} + override: true + - working-directory: crypto-mac + run: cargo build --no-default-features --release --target ${{ matrix.target }} test: runs-on: ubuntu-latest strategy: diff --git a/.github/workflows/digest.yml b/.github/workflows/digest.yml index 400b0211e..b0ffcf892 100644 --- a/.github/workflows/digest.yml +++ b/.github/workflows/digest.yml @@ -12,6 +12,30 @@ on: - "Cargo.*" jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + target: + - thumbv7em-none-eabi + - wasm32-unknown-unknown + rust: + - 1.41.0 # MSRV + - stable + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.rust }} + - name: Install toolchain + uses: actions-rs/toolchain@v1 + with: + target: ${{ matrix.target }} + toolchain: ${{ matrix.toolchain }} + override: true + - working-directory: digest + run: cargo build --no-default-features --release --target ${{ matrix.target }} test: runs-on: ubuntu-latest strategy: diff --git a/.github/workflows/signature.yml b/.github/workflows/signature.yml index f835bf94f..f52551a04 100644 --- a/.github/workflows/signature.yml +++ b/.github/workflows/signature.yml @@ -12,6 +12,30 @@ on: - "Cargo.*" jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + target: + - thumbv7em-none-eabi + - wasm32-unknown-unknown + rust: + - 1.41.0 # MSRV + - stable + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.rust }} + - name: Install toolchain + uses: actions-rs/toolchain@v1 + with: + target: ${{ matrix.target }} + toolchain: ${{ matrix.toolchain }} + override: true + - working-directory: signature + run: cargo build --no-default-features --release --target ${{ matrix.target }} test: runs-on: ubuntu-latest strategy: diff --git a/.github/workflows/stream-cipher.yml b/.github/workflows/stream-cipher.yml index 1ff1141ad..6c39d2b60 100644 --- a/.github/workflows/stream-cipher.yml +++ b/.github/workflows/stream-cipher.yml @@ -12,6 +12,30 @@ on: - "Cargo.*" jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + target: + - thumbv7em-none-eabi + - wasm32-unknown-unknown + rust: + - 1.41.0 # MSRV + - stable + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.rust }} + - name: Install toolchain + uses: actions-rs/toolchain@v1 + with: + target: ${{ matrix.target }} + toolchain: ${{ matrix.toolchain }} + override: true + - working-directory: stream-cipher + run: cargo build --no-default-features --release --target ${{ matrix.target }} test: runs-on: ubuntu-latest strategy: From 616d52b4f2a163b33cc853edbb4280a3ba5b8508 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 10 May 2020 12:49:21 -0700 Subject: [PATCH 0057/1461] .github: add universal-hash configuration This was missed in #103 --- .github/workflows/universal-hash.yml | 56 ++++++++++++++++++++++++++++ universal-hash/LICENSE-MIT | 2 +- 2 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/universal-hash.yml diff --git a/.github/workflows/universal-hash.yml b/.github/workflows/universal-hash.yml new file mode 100644 index 000000000..b33b7832b --- /dev/null +++ b/.github/workflows/universal-hash.yml @@ -0,0 +1,56 @@ +name: universal-hash + +on: + pull_request: + paths: + - "universal-hash/**" + - "Cargo.*" + push: + branches: master + paths: + - "universal-hash/**" + - "Cargo.*" + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + rust: + - 1.41.0 # MSRV + - stable + target: + - thumbv7em-none-eabi + - wasm32-unknown-unknown + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.rust }} + - name: Install toolchain + uses: actions-rs/toolchain@v1 + with: + target: ${{ matrix.target }} + toolchain: ${{ matrix.rust }} + override: true + - working-directory: universal-hash + run: cargo build --no-default-features --release --target ${{ matrix.target }} + test: + runs-on: ubuntu-latest + strategy: + matrix: + rust: + - 1.41.0 # MSRV + - stable + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.rust }} + - run: | + cargo check --all-features + cargo test --no-default-features + cargo test + working-directory: universal-hash diff --git a/universal-hash/LICENSE-MIT b/universal-hash/LICENSE-MIT index 51e285981..468bccc2d 100644 --- a/universal-hash/LICENSE-MIT +++ b/universal-hash/LICENSE-MIT @@ -1,4 +1,4 @@ -Copyright (c) 2019 RustCrypto Developers +Copyright (c) 2019-2020 RustCrypto Developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated From 2e747a564747c811c3c90eeae6be441d632da3fd Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 10 May 2020 12:58:08 -0700 Subject: [PATCH 0058/1461] .github: Fix no_std builds These didn't actually run the first time and are misconfigured. Oops. --- .github/workflows/block-cipher-trait.yml | 8 ++++---- .github/workflows/crypto-mac.yml | 8 ++++---- .github/workflows/digest.yml | 8 ++++---- .github/workflows/signature.yml | 8 ++++---- .github/workflows/stream-cipher.yml | 8 ++++---- Cargo.lock | 1 + 6 files changed, 21 insertions(+), 20 deletions(-) diff --git a/.github/workflows/block-cipher-trait.yml b/.github/workflows/block-cipher-trait.yml index 2ac3834ed..b8d4a00c0 100644 --- a/.github/workflows/block-cipher-trait.yml +++ b/.github/workflows/block-cipher-trait.yml @@ -16,12 +16,12 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - target: - - thumbv7em-none-eabi - - wasm32-unknown-unknown rust: - 1.41.0 # MSRV - stable + target: + - thumbv7em-none-eabi + - wasm32-unknown-unknown steps: - uses: actions/checkout@v1 - uses: actions-rs/toolchain@v1 @@ -32,7 +32,7 @@ jobs: uses: actions-rs/toolchain@v1 with: target: ${{ matrix.target }} - toolchain: ${{ matrix.toolchain }} + toolchain: ${{ matrix.rust }} override: true - working-directory: block-cipher-trait run: cargo build --no-default-features --release --target ${{ matrix.target }} diff --git a/.github/workflows/crypto-mac.yml b/.github/workflows/crypto-mac.yml index ecd0aa9aa..3f9106e70 100644 --- a/.github/workflows/crypto-mac.yml +++ b/.github/workflows/crypto-mac.yml @@ -16,12 +16,12 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - target: - - thumbv7em-none-eabi - - wasm32-unknown-unknown rust: - 1.41.0 # MSRV - stable + target: + - thumbv7em-none-eabi + - wasm32-unknown-unknown steps: - uses: actions/checkout@v1 - uses: actions-rs/toolchain@v1 @@ -32,7 +32,7 @@ jobs: uses: actions-rs/toolchain@v1 with: target: ${{ matrix.target }} - toolchain: ${{ matrix.toolchain }} + toolchain: ${{ matrix.rust }} override: true - working-directory: crypto-mac run: cargo build --no-default-features --release --target ${{ matrix.target }} diff --git a/.github/workflows/digest.yml b/.github/workflows/digest.yml index b0ffcf892..11bd4ea0b 100644 --- a/.github/workflows/digest.yml +++ b/.github/workflows/digest.yml @@ -16,12 +16,12 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - target: - - thumbv7em-none-eabi - - wasm32-unknown-unknown rust: - 1.41.0 # MSRV - stable + target: + - thumbv7em-none-eabi + - wasm32-unknown-unknown steps: - uses: actions/checkout@v1 - uses: actions-rs/toolchain@v1 @@ -32,7 +32,7 @@ jobs: uses: actions-rs/toolchain@v1 with: target: ${{ matrix.target }} - toolchain: ${{ matrix.toolchain }} + toolchain: ${{ matrix.rust }} override: true - working-directory: digest run: cargo build --no-default-features --release --target ${{ matrix.target }} diff --git a/.github/workflows/signature.yml b/.github/workflows/signature.yml index f52551a04..b0d3fd9d7 100644 --- a/.github/workflows/signature.yml +++ b/.github/workflows/signature.yml @@ -16,12 +16,12 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - target: - - thumbv7em-none-eabi - - wasm32-unknown-unknown rust: - 1.41.0 # MSRV - stable + target: + - thumbv7em-none-eabi + - wasm32-unknown-unknown steps: - uses: actions/checkout@v1 - uses: actions-rs/toolchain@v1 @@ -32,7 +32,7 @@ jobs: uses: actions-rs/toolchain@v1 with: target: ${{ matrix.target }} - toolchain: ${{ matrix.toolchain }} + toolchain: ${{ matrix.rust }} override: true - working-directory: signature run: cargo build --no-default-features --release --target ${{ matrix.target }} diff --git a/.github/workflows/stream-cipher.yml b/.github/workflows/stream-cipher.yml index 6c39d2b60..180569687 100644 --- a/.github/workflows/stream-cipher.yml +++ b/.github/workflows/stream-cipher.yml @@ -16,12 +16,12 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - target: - - thumbv7em-none-eabi - - wasm32-unknown-unknown rust: - 1.41.0 # MSRV - stable + target: + - thumbv7em-none-eabi + - wasm32-unknown-unknown steps: - uses: actions/checkout@v1 - uses: actions-rs/toolchain@v1 @@ -32,7 +32,7 @@ jobs: uses: actions-rs/toolchain@v1 with: target: ${{ matrix.target }} - toolchain: ${{ matrix.toolchain }} + toolchain: ${{ matrix.rust }} override: true - working-directory: stream-cipher run: cargo build --no-default-features --release --target ${{ matrix.target }} diff --git a/Cargo.lock b/Cargo.lock index 42f6afa6b..afed2245f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. + [[package]] name = "aead" version = "0.2.0" From 550a4a2f3299a79fd8a7522deeef945f35b50f40 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 10 May 2020 13:04:25 -0700 Subject: [PATCH 0059/1461] .github: simplify no_std build configuration --- .github/workflows/block-cipher-trait.yml | 4 ---- .github/workflows/crypto-mac.yml | 4 ---- .github/workflows/digest.yml | 4 ---- .github/workflows/signature.yml | 4 ---- .github/workflows/stream-cipher.yml | 4 ---- .github/workflows/universal-hash.yml | 4 ---- 6 files changed, 24 deletions(-) diff --git a/.github/workflows/block-cipher-trait.yml b/.github/workflows/block-cipher-trait.yml index b8d4a00c0..e138aa54f 100644 --- a/.github/workflows/block-cipher-trait.yml +++ b/.github/workflows/block-cipher-trait.yml @@ -28,11 +28,7 @@ jobs: with: profile: minimal toolchain: ${{ matrix.rust }} - - name: Install toolchain - uses: actions-rs/toolchain@v1 - with: target: ${{ matrix.target }} - toolchain: ${{ matrix.rust }} override: true - working-directory: block-cipher-trait run: cargo build --no-default-features --release --target ${{ matrix.target }} diff --git a/.github/workflows/crypto-mac.yml b/.github/workflows/crypto-mac.yml index 3f9106e70..21ddcff8e 100644 --- a/.github/workflows/crypto-mac.yml +++ b/.github/workflows/crypto-mac.yml @@ -28,11 +28,7 @@ jobs: with: profile: minimal toolchain: ${{ matrix.rust }} - - name: Install toolchain - uses: actions-rs/toolchain@v1 - with: target: ${{ matrix.target }} - toolchain: ${{ matrix.rust }} override: true - working-directory: crypto-mac run: cargo build --no-default-features --release --target ${{ matrix.target }} diff --git a/.github/workflows/digest.yml b/.github/workflows/digest.yml index 11bd4ea0b..ca5788824 100644 --- a/.github/workflows/digest.yml +++ b/.github/workflows/digest.yml @@ -28,11 +28,7 @@ jobs: with: profile: minimal toolchain: ${{ matrix.rust }} - - name: Install toolchain - uses: actions-rs/toolchain@v1 - with: target: ${{ matrix.target }} - toolchain: ${{ matrix.rust }} override: true - working-directory: digest run: cargo build --no-default-features --release --target ${{ matrix.target }} diff --git a/.github/workflows/signature.yml b/.github/workflows/signature.yml index b0d3fd9d7..dd34339fd 100644 --- a/.github/workflows/signature.yml +++ b/.github/workflows/signature.yml @@ -28,11 +28,7 @@ jobs: with: profile: minimal toolchain: ${{ matrix.rust }} - - name: Install toolchain - uses: actions-rs/toolchain@v1 - with: target: ${{ matrix.target }} - toolchain: ${{ matrix.rust }} override: true - working-directory: signature run: cargo build --no-default-features --release --target ${{ matrix.target }} diff --git a/.github/workflows/stream-cipher.yml b/.github/workflows/stream-cipher.yml index 180569687..ef6dbdc38 100644 --- a/.github/workflows/stream-cipher.yml +++ b/.github/workflows/stream-cipher.yml @@ -28,11 +28,7 @@ jobs: with: profile: minimal toolchain: ${{ matrix.rust }} - - name: Install toolchain - uses: actions-rs/toolchain@v1 - with: target: ${{ matrix.target }} - toolchain: ${{ matrix.rust }} override: true - working-directory: stream-cipher run: cargo build --no-default-features --release --target ${{ matrix.target }} diff --git a/.github/workflows/universal-hash.yml b/.github/workflows/universal-hash.yml index b33b7832b..0846c56ee 100644 --- a/.github/workflows/universal-hash.yml +++ b/.github/workflows/universal-hash.yml @@ -28,11 +28,7 @@ jobs: with: profile: minimal toolchain: ${{ matrix.rust }} - - name: Install toolchain - uses: actions-rs/toolchain@v1 - with: target: ${{ matrix.target }} - toolchain: ${{ matrix.rust }} override: true - working-directory: universal-hash run: cargo build --no-default-features --release --target ${{ matrix.target }} From af2bc0c45eb1d174608851214eededcc09d36b7d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 10 May 2020 13:12:10 -0700 Subject: [PATCH 0060/1461] block-cipher-trait: update to 2018 edition --- block-cipher-trait/Cargo.toml | 3 ++- block-cipher-trait/src/dev.rs | 4 ++++ block-cipher-trait/src/errors.rs | 2 +- block-cipher-trait/src/lib.rs | 18 ++++++++++-------- 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/block-cipher-trait/Cargo.toml b/block-cipher-trait/Cargo.toml index fe8498872..d4fb41e96 100644 --- a/block-cipher-trait/Cargo.toml +++ b/block-cipher-trait/Cargo.toml @@ -1,9 +1,10 @@ [package] name = "block-cipher-trait" +description = "Traits for description of block ciphers" version = "0.6.2" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" -description = "Traits for description of block ciphers" +edition = "2018" documentation = "https://docs.rs/block-cipher-trait" repository = "https://github.com/RustCrypto/traits" keywords = ["crypto", "block-cipher", "trait"] diff --git a/block-cipher-trait/src/dev.rs b/block-cipher-trait/src/dev.rs index 938df6869..d60cf7cc5 100644 --- a/block-cipher-trait/src/dev.rs +++ b/block-cipher-trait/src/dev.rs @@ -1,3 +1,6 @@ +//! Development-related functionality + +/// Define test #[macro_export] macro_rules! new_test { ($name:ident, $test_name:expr, $cipher:ty) => { @@ -102,6 +105,7 @@ macro_rules! new_test { }; } +/// Define benchmark #[macro_export] macro_rules! bench { ($cipher:path, $key_len:expr) => { diff --git a/block-cipher-trait/src/errors.rs b/block-cipher-trait/src/errors.rs index 50b0f33fd..62ba2fbb5 100644 --- a/block-cipher-trait/src/errors.rs +++ b/block-cipher-trait/src/errors.rs @@ -7,7 +7,7 @@ use std::error; pub struct InvalidKeyLength; impl fmt::Display for InvalidKeyLength { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str("invalid key length") } } diff --git a/block-cipher-trait/src/lib.rs b/block-cipher-trait/src/lib.rs index 168086990..6b85de4fb 100644 --- a/block-cipher-trait/src/lib.rs +++ b/block-cipher-trait/src/lib.rs @@ -1,22 +1,24 @@ //! This crate defines a set of simple traits used to define functionality of //! block ciphers. + #![no_std] -#![forbid(unsafe_code)] #![doc(html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png")] -#[cfg(feature = "dev")] -pub extern crate blobby; -pub extern crate generic_array; +#![forbid(unsafe_code)] +#![warn(missing_docs, rust_2018_idioms)] + #[cfg(feature = "std")] extern crate std; -use generic_array::typenum::Unsigned; -use generic_array::{ArrayLength, GenericArray}; - #[cfg(feature = "dev")] pub mod dev; + mod errors; -pub use errors::InvalidKeyLength; +pub use crate::errors::InvalidKeyLength; +pub use generic_array; + +use generic_array::typenum::Unsigned; +use generic_array::{ArrayLength, GenericArray}; type ParBlocks = GenericArray, P>; From 102d094f192c7b9e4ee62c0870171c574afa7439 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 10 May 2020 13:22:59 -0700 Subject: [PATCH 0061/1461] crypto-mac: update to 2018 edition --- Cargo.lock | 1 - crypto-mac/Cargo.toml | 3 ++- crypto-mac/src/dev.rs | 4 ++++ crypto-mac/src/errors.rs | 4 ++-- crypto-mac/src/lib.rs | 23 +++++++++++++---------- 5 files changed, 21 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index afed2245f..42f6afa6b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,5 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. - [[package]] name = "aead" version = "0.2.0" diff --git a/crypto-mac/Cargo.toml b/crypto-mac/Cargo.toml index 2c521201a..3684784c9 100644 --- a/crypto-mac/Cargo.toml +++ b/crypto-mac/Cargo.toml @@ -1,9 +1,10 @@ [package] name = "crypto-mac" +description = "Trait for Message Authentication Code (MAC) algorithms" version = "0.8.0" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" -description = "Trait for Message Authentication Code (MAC) algorithms" +edition = "2018" documentation = "https://docs.rs/crypto-mac" repository = "https://github.com/RustCrypto/traits" keywords = ["crypto", "mac"] diff --git a/crypto-mac/src/dev.rs b/crypto-mac/src/dev.rs index 9eb4b6b75..a4c2cf3ee 100644 --- a/crypto-mac/src/dev.rs +++ b/crypto-mac/src/dev.rs @@ -1,3 +1,6 @@ +//! Development-related functionality + +/// Define test #[macro_export] macro_rules! new_test { ($name:ident, $test_name:expr, $mac:ty) => { @@ -51,6 +54,7 @@ macro_rules! new_test { }; } +/// Define benchmark #[macro_export] macro_rules! bench { ($name:ident, $engine:path, $bs:expr) => { diff --git a/crypto-mac/src/errors.rs b/crypto-mac/src/errors.rs index 2414d7d78..7a9f226c0 100644 --- a/crypto-mac/src/errors.rs +++ b/crypto-mac/src/errors.rs @@ -11,13 +11,13 @@ pub struct MacError; pub struct InvalidKeyLength; impl fmt::Display for MacError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str("failed MAC verification") } } impl fmt::Display for InvalidKeyLength { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str("invalid key length") } } diff --git a/crypto-mac/src/lib.rs b/crypto-mac/src/lib.rs index da1d5c452..a4c2c5acd 100644 --- a/crypto-mac/src/lib.rs +++ b/crypto-mac/src/lib.rs @@ -1,28 +1,31 @@ //! This crate provides trait for Message Authentication Code (MAC) algorithms. + #![no_std] -#![forbid(unsafe_code)] #![doc(html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png")] -pub extern crate generic_array; -extern crate subtle; +#![forbid(unsafe_code)] +#![warn(missing_docs, rust_2018_idioms)] -#[cfg(feature = "dev")] -pub extern crate blobby; #[cfg(feature = "std")] extern crate std; -use generic_array::typenum::Unsigned; -use generic_array::{ArrayLength, GenericArray}; -use subtle::{Choice, ConstantTimeEq}; - #[cfg(feature = "dev")] pub mod dev; + mod errors; -pub use errors::{InvalidKeyLength, MacError}; +pub use crate::errors::{InvalidKeyLength, MacError}; +pub use generic_array; + +use generic_array::typenum::Unsigned; +use generic_array::{ArrayLength, GenericArray}; +use subtle::{Choice, ConstantTimeEq}; /// The `Mac` trait defines methods for a Message Authentication algorithm. pub trait Mac: Clone { + /// Output size of the [`Mac`] type OutputSize: ArrayLength; + + /// Keys size of the [`Mac`] type KeySize: ArrayLength; /// Create new MAC instance from key with fixed size. From 7899e764e1ef215ad86cb751cfc2d5af4f0ced90 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 10 May 2020 14:19:19 -0700 Subject: [PATCH 0062/1461] digest: update to 2018 edition --- digest/Cargo.toml | 3 ++- digest/src/dev.rs | 10 +++++++++- digest/src/digest.rs | 2 ++ digest/src/errors.rs | 2 +- digest/src/lib.rs | 24 ++++++++++++++++-------- 5 files changed, 30 insertions(+), 11 deletions(-) diff --git a/digest/Cargo.toml b/digest/Cargo.toml index e0a2e7ceb..bd1212ff5 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -1,9 +1,10 @@ [package] name = "digest" +description = "Traits for cryptographic hash functions" version = "0.8.1" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" -description = "Traits for cryptographic hash functions" +edition = "2018" documentation = "https://docs.rs/digest" repository = "https://github.com/RustCrypto/traits" keywords = ["digest", "crypto", "hash"] diff --git a/digest/src/dev.rs b/digest/src/dev.rs index 71723a266..58e7c5ebb 100644 --- a/digest/src/dev.rs +++ b/digest/src/dev.rs @@ -1,6 +1,9 @@ +//! Development-related functionality + use super::{ExtendableOutput, Input, Reset, VariableOutput, XofReader}; use core::fmt::Debug; +/// Define test #[macro_export] macro_rules! new_test { ($name:ident, $test_name:expr, $hasher:ty, $test_func:ident) => { @@ -26,11 +29,12 @@ macro_rules! new_test { }; } -// module to separate Digest from other traits +/// Module to separate Digest from other traits mod foo { use super::super::Digest; use core::fmt::Debug; + /// Digest test pub fn digest_test(input: &[u8], output: &[u8]) -> Option<&'static str> where D: Digest + Debug + Clone, @@ -74,6 +78,7 @@ mod foo { None } + /// Compute digest of one million `a` bytes pub fn one_million_a(expected: &[u8]) where D: Digest + Debug + Clone, @@ -90,6 +95,7 @@ mod foo { pub use self::foo::{digest_test, one_million_a}; +/// XOF test pub fn xof_test(input: &[u8], output: &[u8]) -> Option<&'static str> where D: Input + ExtendableOutput + Default + Debug + Reset + Clone, @@ -156,6 +162,7 @@ where None } +/// Variable-output digest test pub fn variable_test(input: &[u8], output: &[u8]) -> Option<&'static str> where D: Input + VariableOutput + Reset + Debug + Clone, @@ -205,6 +212,7 @@ where None } +/// Define benchmark #[macro_export] macro_rules! bench { ($name:ident, $engine:path, $bs:expr) => { diff --git a/digest/src/digest.rs b/digest/src/digest.rs index 944be43fb..4d26a0e61 100644 --- a/digest/src/digest.rs +++ b/digest/src/digest.rs @@ -7,7 +7,9 @@ use generic_array::{ArrayLength, GenericArray}; /// It's a convenience wrapper around `Input`, `FixedOutput`, `Reset`, `Clone`, /// and `Default` traits. It also provides additional convenience methods. pub trait Digest { + /// Output size for `Digest` type OutputSize: ArrayLength; + /// Create new hasher instance fn new() -> Self; diff --git a/digest/src/errors.rs b/digest/src/errors.rs index aa026a21a..41a255048 100644 --- a/digest/src/errors.rs +++ b/digest/src/errors.rs @@ -7,7 +7,7 @@ use std::error; pub struct InvalidOutputSize; impl fmt::Display for InvalidOutputSize { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str("invalid output size") } } diff --git a/digest/src/lib.rs b/digest/src/lib.rs index fc61b0f75..7dfb7dd37 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -12,29 +12,34 @@ //! `Write`. (the latter depends on enabled-by-default `std` crate feature) //! //! The `Digest` trait is the most commonly used trait. + #![no_std] #![forbid(unsafe_code)] #![doc(html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png")] -pub extern crate generic_array; +#![warn(missing_docs, rust_2018_idioms)] + #[cfg(feature = "std")] #[macro_use] extern crate std; -#[cfg(feature = "dev")] -pub extern crate blobby; -use generic_array::{ArrayLength, GenericArray}; -#[cfg(feature = "std")] -use std::vec::Vec; #[cfg(feature = "dev")] pub mod dev; + mod digest; mod dyn_digest; mod errors; -pub use digest::Digest; +pub use crate::digest::Digest; +pub use crate::errors::InvalidOutputSize; +pub use generic_array; + #[cfg(feature = "std")] pub use dyn_digest::DynDigest; -pub use errors::InvalidOutputSize; + +use generic_array::{ArrayLength, GenericArray}; + +#[cfg(feature = "std")] +use std::vec::Vec; /// Trait for processing input data pub trait Input { @@ -59,11 +64,13 @@ pub trait Input { /// /// The main usage of this trait is for implementing HMAC generically. pub trait BlockInput { + /// Block size type BlockSize: ArrayLength; } /// Trait for returning digest result with the fixed size pub trait FixedOutput { + /// Output size for fixed output digest type OutputSize: ArrayLength; /// Retrieve result and consume hasher instance. @@ -106,6 +113,7 @@ pub trait XofReader { /// Trait which describes extendable-output functions (XOF). pub trait ExtendableOutput: core::marker::Sized { + /// Reader type Reader: XofReader; /// Retrieve XOF reader and consume hasher instance. From 14e2f61426009bae1095d2c4da92b6afbb2be6e9 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 10 May 2020 14:29:13 -0700 Subject: [PATCH 0063/1461] stream-cipher: update to 2018 edition --- stream-cipher/Cargo.toml | 3 ++- stream-cipher/src/dev.rs | 2 ++ stream-cipher/src/errors.rs | 4 ++-- stream-cipher/src/lib.rs | 18 ++++++++++-------- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/stream-cipher/Cargo.toml b/stream-cipher/Cargo.toml index 1355e7dc0..eed73432f 100644 --- a/stream-cipher/Cargo.toml +++ b/stream-cipher/Cargo.toml @@ -1,9 +1,10 @@ [package] name = "stream-cipher" +description = "Stream cipher traits" version = "0.3.2" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" -description = "Stream cipher traits" +edition = "2018" documentation = "https://docs.rs/stream-cipher" repository = "https://github.com/RustCrypto/traits" keywords = ["crypto", "stream-cipher", "trait"] diff --git a/stream-cipher/src/dev.rs b/stream-cipher/src/dev.rs index ee66a72d9..02c2715fa 100644 --- a/stream-cipher/src/dev.rs +++ b/stream-cipher/src/dev.rs @@ -1,3 +1,5 @@ +//! Development-related functionality + /// Test core functionality of synchronous stream cipher #[macro_export] macro_rules! new_sync_test { diff --git a/stream-cipher/src/errors.rs b/stream-cipher/src/errors.rs index b44a6d8f9..d0534f03f 100644 --- a/stream-cipher/src/errors.rs +++ b/stream-cipher/src/errors.rs @@ -7,7 +7,7 @@ use std::error; pub struct LoopError; impl fmt::Display for LoopError { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { f.write_str("Loop Error") } } @@ -25,7 +25,7 @@ impl error::Error for LoopError { pub struct InvalidKeyNonceLength; impl fmt::Display for InvalidKeyNonceLength { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { f.write_str("Loop Error") } } diff --git a/stream-cipher/src/lib.rs b/stream-cipher/src/lib.rs index 377f04fc0..cf5b7d79c 100644 --- a/stream-cipher/src/lib.rs +++ b/stream-cipher/src/lib.rs @@ -3,23 +3,25 @@ //! //! See [RustCrypto/stream-ciphers](https://github.com/RustCrypto/stream-ciphers) //! for ciphers implementation. + #![no_std] -#![forbid(unsafe_code)] #![doc(html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png")] -#[cfg(feature = "dev")] -pub extern crate blobby; -pub extern crate generic_array; +#![forbid(unsafe_code)] +#![warn(missing_docs, rust_2018_idioms)] + #[cfg(feature = "std")] extern crate std; -use generic_array::typenum::Unsigned; -use generic_array::{ArrayLength, GenericArray}; - #[cfg(feature = "dev")] pub mod dev; + mod errors; -pub use errors::{InvalidKeyNonceLength, LoopError}; +pub use crate::errors::{InvalidKeyNonceLength, LoopError}; +pub use generic_array; + +use generic_array::typenum::Unsigned; +use generic_array::{ArrayLength, GenericArray}; /// Stream cipher creation trait. /// From b967c90af9c066bd9e29b9d982994798603d731b Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 23 May 2020 08:25:18 -0700 Subject: [PATCH 0064/1461] crypto-mac/digest: rename `input` to `update` As discussed in #43, following "Initialize-Update-Finalize" (IUF) nomenclature, this renames the `input` methods in `crypto-mac` and `digest` to be `update` instead, and also renames the `digest::Input` trait to `digest::Update`. --- crypto-mac/src/lib.rs | 8 ++++---- digest/src/dev.rs | 34 +++++++++++++++++----------------- digest/src/digest.rs | 16 ++++++++-------- digest/src/dyn_digest.rs | 10 +++++----- digest/src/lib.rs | 8 ++++---- 5 files changed, 38 insertions(+), 38 deletions(-) diff --git a/crypto-mac/src/lib.rs b/crypto-mac/src/lib.rs index a4c2c5acd..ba61ebcad 100644 --- a/crypto-mac/src/lib.rs +++ b/crypto-mac/src/lib.rs @@ -28,10 +28,10 @@ pub trait Mac: Clone { /// Keys size of the [`Mac`] type KeySize: ArrayLength; - /// Create new MAC instance from key with fixed size. + /// Initialize new MAC instance from key with fixed size. fn new(key: &GenericArray) -> Self; - /// Create new MAC instance from key with variable size. + /// Initialize new MAC instance from key with variable size. /// /// Default implementation will accept only keys with length equal to /// `KeySize`, but some MACs can accept range of key lengths. @@ -43,8 +43,8 @@ pub trait Mac: Clone { } } - /// Process input data. - fn input(&mut self, data: &[u8]); + /// Update MAC state with the given data. + fn update(&mut self, data: &[u8]); /// Reset `Mac` instance. fn reset(&mut self); diff --git a/digest/src/dev.rs b/digest/src/dev.rs index 58e7c5ebb..5c7c9a59e 100644 --- a/digest/src/dev.rs +++ b/digest/src/dev.rs @@ -1,6 +1,6 @@ //! Development-related functionality -use super::{ExtendableOutput, Input, Reset, VariableOutput, XofReader}; +use super::{ExtendableOutput, Reset, Update, VariableOutput, XofReader}; use core::fmt::Debug; /// Define test @@ -41,7 +41,7 @@ mod foo { { let mut hasher = D::new(); // Test that it works when accepting the message all at once - hasher.input(input); + hasher.update(input); let mut hasher2 = hasher.clone(); if hasher.result().as_slice() != output { return Some("whole message"); @@ -49,7 +49,7 @@ mod foo { // Test if reset works correctly hasher2.reset(); - hasher2.input(input); + hasher2.update(input); if hasher2.result().as_slice() != output { return Some("whole message after reset"); } @@ -60,7 +60,7 @@ mod foo { let mut left = len; while left > 0 { let take = (left + 1) / 2; - hasher.input(&input[len - left..take + len - left]); + hasher.update(&input[len - left..take + len - left]); left -= take; } if hasher.result().as_slice() != output { @@ -70,7 +70,7 @@ mod foo { // Test processing byte-by-byte let mut hasher = D::new(); for chunk in input.chunks(1) { - hasher.input(chunk) + hasher.update(chunk) } if hasher.result().as_slice() != output { return Some("message byte-by-byte"); @@ -85,9 +85,9 @@ mod foo { { let mut sh = D::new(); for _ in 0..50_000 { - sh.input(&[b'a'; 10]); + sh.update(&[b'a'; 10]); } - sh.input(&[b'a'; 500_000][..]); + sh.update(&[b'a'; 500_000][..]); let out = sh.result(); assert_eq!(out[..], expected[..]); } @@ -98,12 +98,12 @@ pub use self::foo::{digest_test, one_million_a}; /// XOF test pub fn xof_test(input: &[u8], output: &[u8]) -> Option<&'static str> where - D: Input + ExtendableOutput + Default + Debug + Reset + Clone, + D: Update + ExtendableOutput + Default + Debug + Reset + Clone, { let mut hasher = D::default(); let mut buf = [0u8; 1024]; // Test that it works when accepting the message all at once - hasher.input(input); + hasher.update(input); let mut hasher2 = hasher.clone(); { @@ -117,7 +117,7 @@ where // Test if hasher resets correctly hasher2.reset(); - hasher2.input(input); + hasher2.update(input); { let out = &mut buf[..output.len()]; @@ -134,7 +134,7 @@ where let mut left = len; while left > 0 { let take = (left + 1) / 2; - hasher.input(&input[len - left..take + len - left]); + hasher.update(&input[len - left..take + len - left]); left -= take; } @@ -148,7 +148,7 @@ where // Test reading from reader byte by byte let mut hasher = D::default(); - hasher.input(input); + hasher.update(input); let mut reader = hasher.xof_result(); let out = &mut buf[..output.len()]; @@ -165,13 +165,13 @@ where /// Variable-output digest test pub fn variable_test(input: &[u8], output: &[u8]) -> Option<&'static str> where - D: Input + VariableOutput + Reset + Debug + Clone, + D: Update + VariableOutput + Reset + Debug + Clone, { let mut hasher = D::new(output.len()).unwrap(); let mut buf = [0u8; 128]; let buf = &mut buf[..output.len()]; // Test that it works when accepting the message all at once - hasher.input(input); + hasher.update(input); let mut hasher2 = hasher.clone(); hasher.variable_result(|res| buf.copy_from_slice(res)); if buf != output { @@ -180,7 +180,7 @@ where // Test if reset works correctly hasher2.reset(); - hasher2.input(input); + hasher2.update(input); hasher2.variable_result(|res| buf.copy_from_slice(res)); if buf != output { return Some("whole message after reset"); @@ -192,7 +192,7 @@ where let mut left = len; while left > 0 { let take = (left + 1) / 2; - hasher.input(&input[len - left..take + len - left]); + hasher.update(&input[len - left..take + len - left]); left -= take; } hasher.variable_result(|res| buf.copy_from_slice(res)); @@ -203,7 +203,7 @@ where // Test processing byte-by-byte let mut hasher = D::new(output.len()).unwrap(); for chunk in input.chunks(1) { - hasher.input(chunk) + hasher.update(chunk) } hasher.variable_result(|res| buf.copy_from_slice(res)); if buf != output { diff --git a/digest/src/digest.rs b/digest/src/digest.rs index 4d26a0e61..d0a95cd84 100644 --- a/digest/src/digest.rs +++ b/digest/src/digest.rs @@ -1,4 +1,4 @@ -use super::{FixedOutput, Input, Reset}; +use super::{FixedOutput, Reset, Update}; use generic_array::typenum::Unsigned; use generic_array::{ArrayLength, GenericArray}; @@ -13,10 +13,10 @@ pub trait Digest { /// Create new hasher instance fn new() -> Self; - /// Digest input data. + /// Digest data, updating the internal state. /// /// This method can be called repeatedly for use with streaming messages. - fn input>(&mut self, data: B); + fn update>(&mut self, data: B); /// Digest input data in a chained manner. fn chain>(self, data: B) -> Self @@ -49,22 +49,22 @@ pub trait Digest { fn digest(data: &[u8]) -> GenericArray; } -impl Digest for D { +impl Digest for D { type OutputSize = ::OutputSize; fn new() -> Self { Self::default() } - fn input>(&mut self, data: B) { - Input::input(self, data); + fn update>(&mut self, data: B) { + Update::update(self, data); } fn chain>(self, data: B) -> Self where Self: Sized, { - Input::chain(self, data) + Update::chain(self, data) } fn result(self) -> GenericArray { @@ -87,7 +87,7 @@ impl Digest for D { fn digest(data: &[u8]) -> GenericArray { let mut hasher = Self::default(); - Input::input(&mut hasher, data); + Update::update(&mut hasher, data); hasher.fixed_result() } } diff --git a/digest/src/dyn_digest.rs b/digest/src/dyn_digest.rs index 93dfdd08c..e9b56f6d0 100644 --- a/digest/src/dyn_digest.rs +++ b/digest/src/dyn_digest.rs @@ -1,7 +1,7 @@ #![cfg(feature = "std")] use std::boxed::Box; -use super::{FixedOutput, Input, Reset}; +use super::{FixedOutput, Reset, Update}; use generic_array::typenum::Unsigned; /// The `DynDigest` trait is a modification of `Digest` trait suitable @@ -10,7 +10,7 @@ pub trait DynDigest { /// Digest input data. /// /// This method can be called repeatedly for use with streaming messages. - fn input(&mut self, data: &[u8]); + fn update(&mut self, data: &[u8]); /// Retrieve result and reset hasher instance fn result_reset(&mut self) -> Box<[u8]>; @@ -28,9 +28,9 @@ pub trait DynDigest { fn box_clone(&self) -> Box; } -impl DynDigest for D { - fn input(&mut self, data: &[u8]) { - Input::input(self, data); +impl DynDigest for D { + fn update(&mut self, data: &[u8]) { + Update::update(self, data); } fn result_reset(&mut self) -> Box<[u8]> { diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 7dfb7dd37..2c61883b2 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -41,20 +41,20 @@ use generic_array::{ArrayLength, GenericArray}; #[cfg(feature = "std")] use std::vec::Vec; -/// Trait for processing input data -pub trait Input { +/// Trait for updating digest state with input data. +pub trait Update { /// Digest input data. /// /// This method can be called repeatedly, e.g. for processing streaming /// messages. - fn input>(&mut self, data: B); + fn update>(&mut self, data: B); /// Digest input data in a chained manner. fn chain>(mut self, data: B) -> Self where Self: Sized, { - self.input(data); + self.update(data); self } } From a211c91051b8547ddcf1e52d6762c5e2d3b9ee61 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 23 May 2020 08:45:55 -0700 Subject: [PATCH 0065/1461] digest: use impl Trait notation for AsRef<[u8]> Replaces generic parameters on methods which take an `AsRef<[u8]>` bound with `impl AsRef<[u8]>`. This syntax is semantically equivalent but eliminates a generic parameter, which (IMO) makes the method signature easier to read, and in general seems to be preferred after the introduction of `impl Trait`. --- digest/src/digest.rs | 8 ++++---- digest/src/lib.rs | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/digest/src/digest.rs b/digest/src/digest.rs index d0a95cd84..7607f9633 100644 --- a/digest/src/digest.rs +++ b/digest/src/digest.rs @@ -16,10 +16,10 @@ pub trait Digest { /// Digest data, updating the internal state. /// /// This method can be called repeatedly for use with streaming messages. - fn update>(&mut self, data: B); + fn update(&mut self, data: impl AsRef<[u8]>); /// Digest input data in a chained manner. - fn chain>(self, data: B) -> Self + fn chain(self, data: impl AsRef<[u8]>) -> Self where Self: Sized; @@ -56,11 +56,11 @@ impl Digest for D { Self::default() } - fn update>(&mut self, data: B) { + fn update(&mut self, data: impl AsRef<[u8]>) { Update::update(self, data); } - fn chain>(self, data: B) -> Self + fn chain(self, data: impl AsRef<[u8]>) -> Self where Self: Sized, { diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 2c61883b2..e0ac18cb0 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -47,10 +47,10 @@ pub trait Update { /// /// This method can be called repeatedly, e.g. for processing streaming /// messages. - fn update>(&mut self, data: B); + fn update(&mut self, data: impl AsRef<[u8]>); /// Digest input data in a chained manner. - fn chain>(mut self, data: B) -> Self + fn chain(mut self, data: impl AsRef<[u8]>) -> Self where Self: Sized, { From 077a07d6acf32bf7444607a879362040860dacb7 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 23 May 2020 08:59:24 -0700 Subject: [PATCH 0066/1461] Remove deprecated `Error::description` methods This method has been "soft-deprecated" since 1.27.0 and officially deprecated as of Rust 1.42.0. --- block-cipher-trait/src/errors.rs | 8 +------- crypto-mac/src/errors.rs | 6 ++---- digest/src/errors.rs | 8 +------- stream-cipher/src/errors.rs | 14 ++------------ 4 files changed, 6 insertions(+), 30 deletions(-) diff --git a/block-cipher-trait/src/errors.rs b/block-cipher-trait/src/errors.rs index 62ba2fbb5..0769aa2bd 100644 --- a/block-cipher-trait/src/errors.rs +++ b/block-cipher-trait/src/errors.rs @@ -1,6 +1,4 @@ use core::fmt; -#[cfg(feature = "std")] -use std::error; /// Error struct which used with `NewVarKey` #[derive(Debug, Copy, Clone, Eq, PartialEq)] @@ -13,8 +11,4 @@ impl fmt::Display for InvalidKeyLength { } #[cfg(feature = "std")] -impl error::Error for InvalidKeyLength { - fn description(&self) -> &str { - "invalid key length" - } -} +impl std::error::Error for InvalidKeyLength {} diff --git a/crypto-mac/src/errors.rs b/crypto-mac/src/errors.rs index 7a9f226c0..7bcb0fd34 100644 --- a/crypto-mac/src/errors.rs +++ b/crypto-mac/src/errors.rs @@ -1,6 +1,4 @@ use core::fmt; -#[cfg(feature = "std")] -use std::error; /// Error type for signaling failed MAC verification #[derive(Default, Debug, Copy, Clone, Eq, PartialEq)] @@ -23,7 +21,7 @@ impl fmt::Display for InvalidKeyLength { } #[cfg(feature = "std")] -impl error::Error for MacError {} +impl std::error::Error for MacError {} #[cfg(feature = "std")] -impl error::Error for InvalidKeyLength {} +impl std::error::Error for InvalidKeyLength {} diff --git a/digest/src/errors.rs b/digest/src/errors.rs index 41a255048..6071e456b 100644 --- a/digest/src/errors.rs +++ b/digest/src/errors.rs @@ -1,6 +1,4 @@ use core::fmt; -#[cfg(feature = "std")] -use std::error; /// The error type for variable hasher initialization #[derive(Clone, Copy, Debug, Default)] @@ -13,8 +11,4 @@ impl fmt::Display for InvalidOutputSize { } #[cfg(feature = "std")] -impl error::Error for InvalidOutputSize { - fn description(&self) -> &str { - "invalid output size" - } -} +impl std::error::Error for InvalidOutputSize {} diff --git a/stream-cipher/src/errors.rs b/stream-cipher/src/errors.rs index d0534f03f..813a4db90 100644 --- a/stream-cipher/src/errors.rs +++ b/stream-cipher/src/errors.rs @@ -1,6 +1,4 @@ use core::fmt; -#[cfg(feature = "std")] -use std::error; /// Error which notifies that stream cipher has reached the end of a keystream. #[derive(Copy, Clone, Debug)] @@ -13,11 +11,7 @@ impl fmt::Display for LoopError { } #[cfg(feature = "std")] -impl error::Error for LoopError { - fn description(&self) -> &str { - "stream cipher loop detected" - } -} +impl std::error::Error for LoopError {} /// Error which notifies that key or/and nonce used in stream cipher /// initialization had an invalid length. @@ -31,8 +25,4 @@ impl fmt::Display for InvalidKeyNonceLength { } #[cfg(feature = "std")] -impl error::Error for InvalidKeyNonceLength { - fn description(&self) -> &str { - "stream cipher loop detected" - } -} +impl std::error::Error for InvalidKeyNonceLength {} From 9ab8d4bafb5aac62a9da685c3814ba73f5c98fd4 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 23 May 2020 09:14:23 -0700 Subject: [PATCH 0067/1461] crypto-mac: rename `MacResult` to `Output` ...and `code` to `into_bytes`. This is consistent with the API in the `universal-hash` trait. --- crypto-mac/src/lib.rs | 46 +++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/crypto-mac/src/lib.rs b/crypto-mac/src/lib.rs index ba61ebcad..a0477d69f 100644 --- a/crypto-mac/src/lib.rs +++ b/crypto-mac/src/lib.rs @@ -20,12 +20,12 @@ use generic_array::typenum::Unsigned; use generic_array::{ArrayLength, GenericArray}; use subtle::{Choice, ConstantTimeEq}; -/// The `Mac` trait defines methods for a Message Authentication algorithm. +/// The [`Mac`] trait defines methods for a Message Authentication algorithm. pub trait Mac: Clone { - /// Output size of the [`Mac`] + /// Output size of the [[`Mac`]] type OutputSize: ArrayLength; - /// Keys size of the [`Mac`] + /// Keys size of the [[`Mac`]] type KeySize: ArrayLength; /// Initialize new MAC instance from key with fixed size. @@ -46,16 +46,16 @@ pub trait Mac: Clone { /// Update MAC state with the given data. fn update(&mut self, data: &[u8]); - /// Reset `Mac` instance. + /// Reset [`Mac`] instance. fn reset(&mut self); - /// Obtain the result of a `Mac` computation as a `MacResult` and consume - /// `Mac` instance. - fn result(self) -> MacResult; + /// Obtain the result of a [`Mac`] computation as a [`Output`] and consume + /// [`Mac`] instance. + fn result(self) -> Output; - /// Obtain the result of a `Mac` computation as a `MacResult` and reset - /// `Mac` instance. - fn result_reset(&mut self) -> MacResult { + /// Obtain the result of a [`Mac`] computation as a [`Output`] and reset + /// [`Mac`] instance. + fn result_reset(&mut self) -> Output { let res = self.clone().result(); self.reset(); res @@ -72,33 +72,33 @@ pub trait Mac: Clone { } } -/// `MacResult` is a thin wrapper around bytes array which provides a safe `Eq` +/// [`Output`] is a thin wrapper around bytes array which provides a safe `Eq` /// implementation that runs in a fixed time. #[derive(Clone)] -pub struct MacResult> { +pub struct Output> { code: GenericArray, } -impl MacResult +impl Output where N: ArrayLength, { - /// Create a new MacResult. - pub fn new(code: GenericArray) -> MacResult { - MacResult { code } + /// Create a new MAC [`Output`]. + pub fn new(code: GenericArray) -> Output { + Output { code } } - /// Get the code value as a bytes array. + /// Get the MAC code/tag value as a byte array. /// /// Be very careful using this method, since incorrect use of the code value /// may permit timing attacks which defeat the security provided by the - /// `Mac` trait. - pub fn code(self) -> GenericArray { + /// [`Mac`] trait. + pub fn into_bytes(self) -> GenericArray { self.code } } -impl ConstantTimeEq for MacResult +impl ConstantTimeEq for Output where N: ArrayLength, { @@ -107,13 +107,13 @@ where } } -impl PartialEq for MacResult +impl PartialEq for Output where N: ArrayLength, { - fn eq(&self, x: &MacResult) -> bool { + fn eq(&self, x: &Output) -> bool { self.ct_eq(x).unwrap_u8() == 1 } } -impl Eq for MacResult where N: ArrayLength {} +impl Eq for Output where N: ArrayLength {} From 04ee60fa844964a744ac449cc6bf278ed238925c Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 23 May 2020 09:20:12 -0700 Subject: [PATCH 0068/1461] digest: add `Output` type alias Adds a `digest::Output` type alias for a `GenericArray`, which is less unwieldy to remember/type. --- digest/src/digest.rs | 15 +++++++++------ digest/src/lib.rs | 10 +++++----- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/digest/src/digest.rs b/digest/src/digest.rs index 7607f9633..220ae3aee 100644 --- a/digest/src/digest.rs +++ b/digest/src/digest.rs @@ -24,13 +24,13 @@ pub trait Digest { Self: Sized; /// Retrieve result and consume hasher instance. - fn result(self) -> GenericArray; + fn result(self) -> Output; /// Retrieve result and reset hasher instance. /// /// This method sometimes can be more efficient compared to hasher /// re-creation. - fn result_reset(&mut self) -> GenericArray; + fn result_reset(&mut self) -> Output; /// Reset hasher instance to its initial state. fn reset(&mut self); @@ -46,7 +46,7 @@ pub trait Digest { /// ```rust,ignore /// println!("{:x}", sha2::Sha256::digest(b"Hello world")); /// ``` - fn digest(data: &[u8]) -> GenericArray; + fn digest(data: &[u8]) -> Output; } impl Digest for D { @@ -67,11 +67,11 @@ impl Digest for D { Update::chain(self, data) } - fn result(self) -> GenericArray { + fn result(self) -> Output { self.fixed_result() } - fn result_reset(&mut self) -> GenericArray { + fn result_reset(&mut self) -> Output { let res = self.clone().fixed_result(); self.reset(); res @@ -85,9 +85,12 @@ impl Digest for D { Self::OutputSize::to_usize() } - fn digest(data: &[u8]) -> GenericArray { + fn digest(data: &[u8]) -> Output { let mut hasher = Self::default(); Update::update(&mut hasher, data); hasher.fixed_result() } } + +/// Output of a [`Digest`] function +pub type Output = GenericArray::OutputSize>; diff --git a/digest/src/lib.rs b/digest/src/lib.rs index e0ac18cb0..83745928a 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -2,16 +2,16 @@ //! functions. //! //! Traits in this repository can be separated into two levels: -//! - Low level traits: `Input`, `BlockInput`, `Reset`, `FixedOutput`, -//! `VariableOutput`, `ExtendableOutput`. These traits atomically describe +//! - Low level traits: [`Update`], [`BlockInput`], [`Reset`], [`FixedOutput`], +//! [`VariableOutput`], [`ExtendableOutput`]. These traits atomically describe //! available functionality of hash function implementations. -//! - Convenience trait: `Digest`, `DynDigest`. They are wrappers around +//! - Convenience trait: [`Digest`], [`DynDigest`]. They are wrappers around //! low level traits for most common hash-function use-cases. //! //! Additionally hash functions implement traits from `std`: `Default`, `Clone`, //! `Write`. (the latter depends on enabled-by-default `std` crate feature) //! -//! The `Digest` trait is the most commonly used trait. +//! The [`Digest`] trait is the most commonly used trait. #![no_std] #![forbid(unsafe_code)] @@ -29,7 +29,7 @@ mod digest; mod dyn_digest; mod errors; -pub use crate::digest::Digest; +pub use crate::digest::{Digest, Output}; pub use crate::errors::InvalidOutputSize; pub use generic_array; From 705a1579281c4cf21c4e3327f1e67388f45ad166 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 23 May 2020 09:31:21 -0700 Subject: [PATCH 0069/1461] digest: docs.rs documentation improvements + doc_cfg Adds a `--cfg docsrs` option enabled in `package.metadata.docs.rs` which toggles on `doc_cfg` support. This can be used for tagging what cargo features must be enabled to use certain API features. --- digest/Cargo.toml | 3 ++- digest/src/dev.rs | 2 ++ digest/src/digest.rs | 4 ++-- digest/src/lib.rs | 17 ++++++++++++----- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/digest/Cargo.toml b/digest/Cargo.toml index bd1212ff5..3c7229f8a 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -22,4 +22,5 @@ dev = ["blobby"] travis-ci = { repository = "RustCrypto/traits" } [package.metadata.docs.rs] -features = ["std"] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] diff --git a/digest/src/dev.rs b/digest/src/dev.rs index 5c7c9a59e..8ef413105 100644 --- a/digest/src/dev.rs +++ b/digest/src/dev.rs @@ -5,6 +5,7 @@ use core::fmt::Debug; /// Define test #[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] macro_rules! new_test { ($name:ident, $test_name:expr, $hasher:ty, $test_func:ident) => { #[test] @@ -214,6 +215,7 @@ where /// Define benchmark #[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] macro_rules! bench { ($name:ident, $engine:path, $bs:expr) => { #[bench] diff --git a/digest/src/digest.rs b/digest/src/digest.rs index 220ae3aee..24e103be6 100644 --- a/digest/src/digest.rs +++ b/digest/src/digest.rs @@ -4,8 +4,8 @@ use generic_array::{ArrayLength, GenericArray}; /// The `Digest` trait specifies an interface common for digest functions. /// -/// It's a convenience wrapper around `Input`, `FixedOutput`, `Reset`, `Clone`, -/// and `Default` traits. It also provides additional convenience methods. +/// It's a convenience wrapper around [`Update`], [`FixedOutput`], [`Reset`], +/// [`Clone`], and [`Default`] traits. It also provides additional convenience methods. pub trait Digest { /// Output size for `Digest` type OutputSize: ArrayLength; diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 83745928a..64e0e83a9 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -14,6 +14,7 @@ //! The [`Digest`] trait is the most commonly used trait. #![no_std] +#![cfg_attr(docsrs, feature(doc_cfg))] #![forbid(unsafe_code)] #![doc(html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png")] #![warn(missing_docs, rust_2018_idioms)] @@ -23,6 +24,7 @@ extern crate std; #[cfg(feature = "dev")] +#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] pub mod dev; mod digest; @@ -34,6 +36,7 @@ pub use crate::errors::InvalidOutputSize; pub use generic_array; #[cfg(feature = "std")] +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] pub use dyn_digest::DynDigest; use generic_array::{ArrayLength, GenericArray}; @@ -97,6 +100,7 @@ pub trait VariableOutput: core::marker::Sized { /// Retrieve result into vector and consume hasher. #[cfg(feature = "std")] + #[cfg_attr(docsrs, doc(cfg(feature = "std")))] fn vec_result(self) -> Vec { let mut buf = Vec::with_capacity(self.output_size()); self.variable_result(|res| buf.extend_from_slice(res)); @@ -121,6 +125,7 @@ pub trait ExtendableOutput: core::marker::Sized { /// Retrieve result into vector of specified length. #[cfg(feature = "std")] + #[cfg_attr(docsrs, doc(cfg(feature = "std")))] fn vec_result(self, n: usize) -> Vec { let mut buf = vec![0u8; n]; self.xof_result().read(&mut buf); @@ -134,18 +139,20 @@ pub trait Reset { fn reset(&mut self); } +#[cfg(feature = "std")] +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] #[macro_export] -/// Implements `std::io::Write` trait for implementer of `Input` +/// Implements `std::io::Write` trait for implementer of [`Update`] macro_rules! impl_write { ($hasher:ident) => { #[cfg(feature = "std")] - impl ::std::io::Write for $hasher { - fn write(&mut self, buf: &[u8]) -> ::std::io::Result { - Input::input(self, buf); + impl std::io::Write for $hasher { + fn write(&mut self, buf: &[u8]) -> std::io::Result { + Update::update(self, buf); Ok(buf.len()) } - fn flush(&mut self) -> ::std::io::Result<()> { + fn flush(&mut self) -> std::io::Result<()> { Ok(()) } } From c44d250c92ae3777358e7b584c01517fb4642c94 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 23 May 2020 09:49:50 -0700 Subject: [PATCH 0070/1461] aead: documentation improvements + doc_cfg Improves the README.md documentation and adds `doc_cfg` support for flagging which API features require `alloc` support. --- aead/Cargo.toml | 1 + aead/README.md | 70 +++++++++++++++++++++++++++++++++++++++++---- aead/src/lib.rs | 13 +++++++-- signature/README.md | 4 +-- 4 files changed, 79 insertions(+), 9 deletions(-) diff --git a/aead/Cargo.toml b/aead/Cargo.toml index 81179f243..d58049d27 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -21,3 +21,4 @@ std = ["alloc"] [package.metadata.docs.rs] all-features = true +rustdoc-args = ["--cfg", "docsrs"] diff --git a/aead/README.md b/aead/README.md index ee6d0e6b5..dd4431354 100644 --- a/aead/README.md +++ b/aead/README.md @@ -1,6 +1,66 @@ -# Authenticated Encryption with Additional Data +# RustCrypto: Authenticated Encryption with Additional Data -This crate provides the rust trait equivilent of the AEAD API defined in -RFC5116. As a result, it should provide nearly drop-in support for any -compliant AEAD scheme, including AES-GCM, AES-CCM, ChaCha20-Poly1305, -AES-CBC-HMAC, etc. +[![crate][crate-image]][crate-link] +[![Docs][docs-image]][docs-link] +![Apache2/MIT licensed][license-image] +![Rust Version][rustc-image] +[![Build Status][build-image]][build-link] + +This crate provides an abstract interface for [AEAD] ciphers, which guarantee +both confidentiality and integrity, even from a powerful attacker who is +able to execute [chosen-ciphertext attacks]. The resulting security property, +[ciphertext indistinguishability], is considered a basic requirement for +modern cryptographic implementations. + +See [RustCrypto/AEADs] for cipher implementations which use this trait. + +[Documentation][docs-link] + +## Minimum Supported Rust Version + +Rust **1.41** or higher. + +Minimum supported Rust version can be changed in the future, but it will be +done with a minor version bump. + +## SemVer Policy + +- All on-by-default features of this library are covered by SemVer +- MSRV is considered exempt from SemVer as noted above +- The off-by-default features `derive-preview` and `digest-preview` are + unstable "preview" features which are also considered exempt from SemVer. + Breaking changes to these features will, like MSRV, be done with a minor + version bump. + +## License + +All crates licensed under either of + + * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) + * [MIT license](http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall be +dual licensed as above, without any additional terms or conditions. + +[//]: # (badges) + +[crate-image]: https://img.shields.io/crates/v/aead.svg +[crate-link]: https://crates.io/crates/aead +[docs-image]: https://docs.rs/aead/badge.svg +[docs-link]: https://docs.rs/aead/ +[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg +[build-image]: https://travis-ci.org/RustCrypto/traits.svg?branch=master +[build-link]: https://travis-ci.org/RustCrypto/traits + +[//]: # (general links) + +[AEAD]: https://en.wikipedia.org/wiki/Authenticated_encryption +[chosen-ciphertext attacks]: https://en.wikipedia.org/wiki/Chosen-ciphertext_attack +[ciphertext indistinguishability]: https://en.wikipedia.org/wiki/Ciphertext_indistinguishability +[RustCrypto/AEADs]: https://github.com/RustCrypto/AEADs diff --git a/aead/src/lib.rs b/aead/src/lib.rs index b0d795949..b6ccdd7d0 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -1,4 +1,4 @@ -//! Authenticated Encryption with Associated Data (AEAD) traits +//! [Authenticated Encryption with Associated Data] (AEAD) traits //! //! This crate provides an abstract interface for AEAD ciphers, which guarantee //! both confidentiality and integrity, even from a powerful attacker who is @@ -8,12 +8,16 @@ //! //! See [RustCrypto/AEADs] for cipher implementations which use this trait. //! +//! [Authenticated Encryption with Associated Data]: https://en.wikipedia.org/wiki/Authenticated_encryption //! [chosen-ciphertext attacks]: https://en.wikipedia.org/wiki/Chosen-ciphertext_attack //! [ciphertext indistinguishability]: https://en.wikipedia.org/wiki/Ciphertext_indistinguishability //! [RustCrypto/AEADs]: https://github.com/RustCrypto/AEADs #![no_std] +#![cfg_attr(docsrs, feature(doc_cfg))] #![forbid(unsafe_code)] +#![doc(html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png")] +#![warn(missing_docs, rust_2018_idioms)] #[cfg(feature = "alloc")] extern crate alloc; @@ -30,11 +34,12 @@ use alloc::vec::Vec; use core::fmt; use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; +/// Error type #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] pub struct Error; impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str("aead::Error") } } @@ -107,6 +112,7 @@ pub trait Aead { /// use a postfix tag will need to override this to correctly assemble the /// ciphertext message. #[cfg(feature = "alloc")] + #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] fn encrypt<'msg, 'aad>( &self, nonce: &GenericArray, @@ -165,6 +171,7 @@ pub trait Aead { /// use a postfix tag will need to override this to correctly parse the /// ciphertext message. #[cfg(feature = "alloc")] + #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] fn decrypt<'msg, 'aad>( &self, nonce: &GenericArray, @@ -218,6 +225,7 @@ pub trait AeadMut { /// See notes on [`Aead::encrypt()`] about allowable message payloads and /// Associated Additional Data (AAD). #[cfg(feature = "alloc")] + #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] fn encrypt<'msg, 'aad>( &mut self, nonce: &GenericArray, @@ -264,6 +272,7 @@ pub trait AeadMut { /// See notes on [`Aead::encrypt()`] and [`Aead::decrypt()`] about allowable /// message payloads and Associated Additional Data (AAD). #[cfg(feature = "alloc")] + #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] fn decrypt<'msg, 'aad>( &mut self, nonce: &GenericArray, diff --git a/signature/README.md b/signature/README.md index 8241de485..fc39609f8 100644 --- a/signature/README.md +++ b/signature/README.md @@ -16,7 +16,7 @@ in the [`rsa`][4] crate. ## Minimum Supported Rust Version -All crates in this repository support Rust **1.36** or higher. +Rust **1.41** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -52,7 +52,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/signature/badge.svg [docs-link]: https://docs.rs/signature/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.36+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg [build-image]: https://travis-ci.org/RustCrypto/traits.svg?branch=master [build-link]: https://travis-ci.org/RustCrypto/traits From 800398d5a56520eafcfb355518ecaf992b1be542 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 23 May 2020 10:03:16 -0700 Subject: [PATCH 0071/1461] aead: render README.md on crates.io Adds a `readme` key to `Cargo.toml` --- aead/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/aead/Cargo.toml b/aead/Cargo.toml index d58049d27..6b4700421 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -4,6 +4,7 @@ version = "0.2.0" authors = ["RustCrypto Developers"] edition = "2018" license = "MIT OR Apache-2.0" +readme = "README.md" description = "Traits for Authenticated Encryption with Associated Data (AEAD) algorithms" documentation = "https://docs.rs/aead" repository = "https://github.com/RustCrypto/traits" From 7bcff7085d7e7a96836a5d6c2b941ca095daff97 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 23 May 2020 11:34:26 -0700 Subject: [PATCH 0072/1461] README.md: add algorithm links and build status to table --- README.md | 46 +++++++++++++++++++++++++++++++++++---------- signature/README.md | 5 +++-- 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index e830d9f64..ca3810af4 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,18 @@ -# RustCrypto traits [![Build Status](https://travis-ci.org/RustCrypto/traits.svg?branch=master)](https://travis-ci.org/RustCrypto/traits) +# RustCrypto: Traits ![Rust Version][rustc-image] + Collection of traits which describe functionality of cryptographic primitives. ## Crates -| Name | Crates.io | Documentation | -| ------- | :---------:| :-------------:| -| [`aead`](https://en.wikipedia.org/wiki/Authenticated_encryption)| [![crates.io](https://img.shields.io/crates/v/aead.svg)](https://crates.io/crates/aead) | [![Documentation](https://docs.rs/aead/badge.svg)](https://docs.rs/aead) | -| [`block-cipher-trait`](https://en.wikipedia.org/wiki/Block_cipher)| [![crates.io](https://img.shields.io/crates/v/block-cipher-trait.svg)](https://crates.io/crates/block-cipher-trait) | [![Documentation](https://docs.rs/block-cipher-trait/badge.svg)](https://docs.rs/block-cipher-trait) | -| [`crypto-mac`](https://en.wikipedia.org/wiki/Message_authentication_code) | [![crates.io](https://img.shields.io/crates/v/crypto-mac.svg)](https://crates.io/crates/crypto-mac) | [![Documentation](https://docs.rs/crypto-mac/badge.svg)](https://docs.rs/crypto-mac) | -| [`digest`](https://en.wikipedia.org/wiki/Cryptographic_hash_function) | [![crates.io](https://img.shields.io/crates/v/digest.svg)](https://crates.io/crates/digest) | [![Documentation](https://docs.rs/digest/badge.svg)](https://docs.rs/digest) | -| [`signature`](https://en.wikipedia.org/wiki/Digital_signature) | [![crates.io](https://img.shields.io/crates/v/signature.svg)](https://crates.io/crates/signature) | [![Documentation](https://docs.rs/signature/badge.svg)](https://docs.rs/signature) | -| [`stream-cipher`](https://en.wikipedia.org/wiki/Stream_cipher) | [![crates.io](https://img.shields.io/crates/v/stream-cipher.svg)](https://crates.io/crates/stream-cipher) | [![Documentation](https://docs.rs/stream-cipher/badge.svg)](https://docs.rs/stream-cipher) | -| [`universal-hash`](https://en.wikipedia.org/wiki/Universal_hashing) | [![crates.io](https://img.shields.io/crates/v/universal-hash.svg)](https://crates.io/crates/universal-hash) | [![Documentation](https://docs.rs/universal-hash/badge.svg)](https://docs.rs/universal-hash) | + +| Name | Algorithm | Crates.io | Documentation | Build | +|--------------------|-------------------------------|-----------|----------------|-------| +| [`aead`] | [Authenticated encryption] | [![crates.io](https://img.shields.io/crates/v/aead.svg)](https://crates.io/crates/aead) | [![Documentation](https://docs.rs/aead/badge.svg)](https://docs.rs/aead) | N/A | +| [`block-cipher-trait`] | [Block cipher] | [![crates.io](https://img.shields.io/crates/v/block-cipher-trait.svg)](https://crates.io/crates/block-cipher-trait) | [![Documentation](https://docs.rs/block-cipher-trait/badge.svg)](https://docs.rs/block-cipher-trait) | ![block-cipher-trait](https://github.com/RustCrypto/traits/workflows/block-cipher-trait/badge.svg?branch=master&event=push) | +| [`crypto-mac`] | [Message authentication code] | [![crates.io](https://img.shields.io/crates/v/crypto-mac.svg)](https://crates.io/crates/crypto-mac) | [![Documentation](https://docs.rs/crypto-mac/badge.svg)](https://docs.rs/crypto-mac) | ![crypto-mac](https://github.com/RustCrypto/traits/workflows/crypto-mac/badge.svg?branch=master&event=push) | +| [`digest`] | [Cryptographic hash function] | [![crates.io](https://img.shields.io/crates/v/digest.svg)](https://crates.io/crates/digest) | [![Documentation](https://docs.rs/digest/badge.svg)](https://docs.rs/digest) | ![digest](https://github.com/RustCrypto/traits/workflows/digest/badge.svg?branch=master&event=push) | +| [`signature`] | [Digital signature] | [![crates.io](https://img.shields.io/crates/v/signature.svg)](https://crates.io/crates/signature) | [![Documentation](https://docs.rs/signature/badge.svg)](https://docs.rs/signature) | ![signature](https://github.com/RustCrypto/traits/workflows/signature/badge.svg?branch=master&event=push) | +| [`stream-cipher`] | [Stream cipher] | [![crates.io](https://img.shields.io/crates/v/stream-cipher.svg)](https://crates.io/crates/stream-cipher) | [![Documentation](https://docs.rs/stream-cipher/badge.svg)](https://docs.rs/stream-cipher) | ![stream-cipher](https://github.com/RustCrypto/traits/workflows/stream-cipher/badge.svg?branch=master&event=push) | +| [`universal-hash`] | [Universal hash function] | [![crates.io](https://img.shields.io/crates/v/universal-hash.svg)](https://crates.io/crates/universal-hash) | [![Documentation](https://docs.rs/universal-hash/badge.svg)](https://docs.rs/universal-hash) | ![universal-hash](https://github.com/RustCrypto/traits/workflows/universal-hash/badge.svg?branch=master&event=push) | ### Minimum Rust version @@ -33,3 +35,27 @@ at your option. Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. + +[//]: # (badges) + +[rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg + +[//]: # (crates) + +[`aead`]: https://github.com/RustCrypto/traits/tree/master/aead +[`block-cipher-trait`]: https://github.com/RustCrypto/traits/tree/master/block-cipher-trait +[`crypto-mac`]: https://github.com/RustCrypto/traits/tree/master/crypto-mac +[`digest`]: https://github.com/RustCrypto/traits/tree/master/digest +[`signature`]: https://github.com/RustCrypto/traits/tree/master/signature +[`stream-cipher`]: https://github.com/RustCrypto/traits/tree/master/stream-cipher +[`universal-hash`]: https://github.com/RustCrypto/traits/tree/master/universal-hash + +[//]: # (algorithms) + +[Authenticated encryption]: https://en.wikipedia.org/wiki/Authenticated_encryption +[Block cipher]: https://en.wikipedia.org/wiki/Block_cipher +[Message authentication code]: https://en.wikipedia.org/wiki/Message_authentication_code +[Cryptographic hash function]: https://en.wikipedia.org/wiki/Cryptographic_hash_function +[Digital signature]: https://en.wikipedia.org/wiki/Digital_signature +[Stream cipher]: https://en.wikipedia.org/wiki/Stream_cipher +[Universal hash function]: https://en.wikipedia.org/wiki/Universal_hashing diff --git a/signature/README.md b/signature/README.md index fc39609f8..0a46de4a4 100644 --- a/signature/README.md +++ b/signature/README.md @@ -53,8 +53,9 @@ dual licensed as above, without any additional terms or conditions. [docs-link]: https://docs.rs/signature/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg [rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg -[build-image]: https://travis-ci.org/RustCrypto/traits.svg?branch=master -[build-link]: https://travis-ci.org/RustCrypto/traits +[build-image]: https://github.com/RustCrypto/traits/workflows/signature/badge.svg?branch=master&event=push +[build-link]: https://github.com/RustCrypto/Atraits/actions + [//]: # (general links) From e76ff38b91f62b5f631dc8b362f523fb52c2da7c Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 23 May 2020 11:52:51 -0700 Subject: [PATCH 0073/1461] aead: GitHub Actions CI configuration + docs --- .github/workflows/aead.yml | 53 ++++++++++++++++++++++++++++++++++++++ README.md | 14 +++++----- aead/README.md | 4 +-- build_std.sh | 21 --------------- signature/README.md | 3 +-- 5 files changed, 63 insertions(+), 32 deletions(-) create mode 100644 .github/workflows/aead.yml delete mode 100755 build_std.sh diff --git a/.github/workflows/aead.yml b/.github/workflows/aead.yml new file mode 100644 index 000000000..1d7cfe3ff --- /dev/null +++ b/.github/workflows/aead.yml @@ -0,0 +1,53 @@ +name: aead + +on: + pull_request: + paths: + - "aead/**" + - "Cargo.*" + push: + branches: master + paths: + - "aead/**" + - "Cargo.*" + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + rust: + - 1.41.0 # MSRV + - stable + target: + - thumbv7em-none-eabi + - wasm32-unknown-unknown + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.rust }} + target: ${{ matrix.target }} + override: true + - working-directory: aead + run: cargo build --no-default-features --release --target ${{ matrix.target }} + test: + runs-on: ubuntu-latest + strategy: + matrix: + rust: + - 1.41.0 # MSRV + - stable + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.rust }} + - run: | + cargo check --all-features + cargo test --no-default-features + cargo test + cargo test --all-features + working-directory: aead diff --git a/README.md b/README.md index ca3810af4..1b45ed3f1 100644 --- a/README.md +++ b/README.md @@ -6,13 +6,13 @@ Collection of traits which describe functionality of cryptographic primitives. | Name | Algorithm | Crates.io | Documentation | Build | |--------------------|-------------------------------|-----------|----------------|-------| -| [`aead`] | [Authenticated encryption] | [![crates.io](https://img.shields.io/crates/v/aead.svg)](https://crates.io/crates/aead) | [![Documentation](https://docs.rs/aead/badge.svg)](https://docs.rs/aead) | N/A | -| [`block-cipher-trait`] | [Block cipher] | [![crates.io](https://img.shields.io/crates/v/block-cipher-trait.svg)](https://crates.io/crates/block-cipher-trait) | [![Documentation](https://docs.rs/block-cipher-trait/badge.svg)](https://docs.rs/block-cipher-trait) | ![block-cipher-trait](https://github.com/RustCrypto/traits/workflows/block-cipher-trait/badge.svg?branch=master&event=push) | -| [`crypto-mac`] | [Message authentication code] | [![crates.io](https://img.shields.io/crates/v/crypto-mac.svg)](https://crates.io/crates/crypto-mac) | [![Documentation](https://docs.rs/crypto-mac/badge.svg)](https://docs.rs/crypto-mac) | ![crypto-mac](https://github.com/RustCrypto/traits/workflows/crypto-mac/badge.svg?branch=master&event=push) | -| [`digest`] | [Cryptographic hash function] | [![crates.io](https://img.shields.io/crates/v/digest.svg)](https://crates.io/crates/digest) | [![Documentation](https://docs.rs/digest/badge.svg)](https://docs.rs/digest) | ![digest](https://github.com/RustCrypto/traits/workflows/digest/badge.svg?branch=master&event=push) | -| [`signature`] | [Digital signature] | [![crates.io](https://img.shields.io/crates/v/signature.svg)](https://crates.io/crates/signature) | [![Documentation](https://docs.rs/signature/badge.svg)](https://docs.rs/signature) | ![signature](https://github.com/RustCrypto/traits/workflows/signature/badge.svg?branch=master&event=push) | -| [`stream-cipher`] | [Stream cipher] | [![crates.io](https://img.shields.io/crates/v/stream-cipher.svg)](https://crates.io/crates/stream-cipher) | [![Documentation](https://docs.rs/stream-cipher/badge.svg)](https://docs.rs/stream-cipher) | ![stream-cipher](https://github.com/RustCrypto/traits/workflows/stream-cipher/badge.svg?branch=master&event=push) | -| [`universal-hash`] | [Universal hash function] | [![crates.io](https://img.shields.io/crates/v/universal-hash.svg)](https://crates.io/crates/universal-hash) | [![Documentation](https://docs.rs/universal-hash/badge.svg)](https://docs.rs/universal-hash) | ![universal-hash](https://github.com/RustCrypto/traits/workflows/universal-hash/badge.svg?branch=master&event=push) | +| [`aead`] | [Authenticated encryption] | [![crates.io](https://img.shields.io/crates/v/aead.svg)](https://crates.io/crates/aead) | [![Documentation](https://docs.rs/aead/badge.svg)](https://docs.rs/aead) | ![build](https://github.com/RustCrypto/traits/workflows/aead/badge.svg?branch=master&event=push) | +| [`block-cipher-trait`] | [Block cipher] | [![crates.io](https://img.shields.io/crates/v/block-cipher-trait.svg)](https://crates.io/crates/block-cipher-trait) | [![Documentation](https://docs.rs/block-cipher-trait/badge.svg)](https://docs.rs/block-cipher-trait) | ![build](https://github.com/RustCrypto/traits/workflows/block-cipher-trait/badge.svg?branch=master&event=push) | +| [`crypto-mac`] | [Message authentication code] | [![crates.io](https://img.shields.io/crates/v/crypto-mac.svg)](https://crates.io/crates/crypto-mac) | [![Documentation](https://docs.rs/crypto-mac/badge.svg)](https://docs.rs/crypto-mac) | ![build](https://github.com/RustCrypto/traits/workflows/crypto-mac/badge.svg?branch=master&event=push) | +| [`digest`] | [Cryptographic hash function] | [![crates.io](https://img.shields.io/crates/v/digest.svg)](https://crates.io/crates/digest) | [![Documentation](https://docs.rs/digest/badge.svg)](https://docs.rs/digest) | ![build](https://github.com/RustCrypto/traits/workflows/digest/badge.svg?branch=master&event=push) | +| [`signature`] | [Digital signature] | [![crates.io](https://img.shields.io/crates/v/signature.svg)](https://crates.io/crates/signature) | [![Documentation](https://docs.rs/signature/badge.svg)](https://docs.rs/signature) | ![build](https://github.com/RustCrypto/traits/workflows/signature/badge.svg?branch=master&event=push) | +| [`stream-cipher`] | [Stream cipher] | [![crates.io](https://img.shields.io/crates/v/stream-cipher.svg)](https://crates.io/crates/stream-cipher) | [![Documentation](https://docs.rs/stream-cipher/badge.svg)](https://docs.rs/stream-cipher) | ![build](https://github.com/RustCrypto/traits/workflows/stream-cipher/badge.svg?branch=master&event=push) | +| [`universal-hash`] | [Universal hash function] | [![crates.io](https://img.shields.io/crates/v/universal-hash.svg)](https://crates.io/crates/universal-hash) | [![Documentation](https://docs.rs/universal-hash/badge.svg)](https://docs.rs/universal-hash) | ![build](https://github.com/RustCrypto/traits/workflows/universal-hash/badge.svg?branch=master&event=push) | ### Minimum Rust version diff --git a/aead/README.md b/aead/README.md index dd4431354..78f65cdb0 100644 --- a/aead/README.md +++ b/aead/README.md @@ -55,8 +55,8 @@ dual licensed as above, without any additional terms or conditions. [docs-link]: https://docs.rs/aead/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg [rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg -[build-image]: https://travis-ci.org/RustCrypto/traits.svg?branch=master -[build-link]: https://travis-ci.org/RustCrypto/traits +[build-image]: https://github.com/RustCrypto/traits/workflows/aead/badge.svg?branch=master&event=push +[build-link]: https://github.com/RustCrypto/traits/actions?query=workflow%3Aaead [//]: # (general links) diff --git a/build_std.sh b/build_std.sh deleted file mode 100755 index 8543eaa02..000000000 --- a/build_std.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh -# Due to the fact that cargo does not enable features when we use -# `cargo build --all --features std` we have to explicitly iterate over -# all crates (see https://github.com/rust-lang/cargo/issues/4753 ) -DIRS=`ls -d */` -TARGET="thumbv7em-none-eabi" -cargo clean - -for DIR in $DIRS; do - if [ $DIR = "target/" -o $DIR = "aead/" -o $DIR = "signature/" -o $DIR = "universal-hash/" ] - then - continue - fi - cd $DIR - echo Building $DIR - cargo build --all-features || { - echo $DIR failed - exit 1 - } - cd .. -done diff --git a/signature/README.md b/signature/README.md index 0a46de4a4..565b395c7 100644 --- a/signature/README.md +++ b/signature/README.md @@ -54,8 +54,7 @@ dual licensed as above, without any additional terms or conditions. [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg [rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg [build-image]: https://github.com/RustCrypto/traits/workflows/signature/badge.svg?branch=master&event=push -[build-link]: https://github.com/RustCrypto/Atraits/actions - +[build-link]: https://github.com/RustCrypto/traits/actions?query=workflow%3Asignature [//]: # (general links) From 371db89daa4220e794225fb8a9f179e98e8ee8a9 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 23 May 2020 12:16:38 -0700 Subject: [PATCH 0074/1461] Re-export `typenum::consts` as `consts` Inspired by the `heapless` crate: https://github.com/RustCrypto/traits/issues/43#issuecomment-633109800 This re-export provides convenient access to the type-level numeric constants provided by `typenum`, which should make using `generic-array` less annoying. --- aead/src/lib.rs | 8 +++++--- block-cipher-trait/src/lib.rs | 2 +- crypto-mac/src/lib.rs | 2 +- digest/src/lib.rs | 2 +- stream-cipher/src/lib.rs | 2 +- universal-hash/src/lib.rs | 3 ++- 6 files changed, 11 insertions(+), 8 deletions(-) diff --git a/aead/src/lib.rs b/aead/src/lib.rs index b6ccdd7d0..cd358a88d 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -25,15 +25,17 @@ extern crate alloc; #[cfg(feature = "std")] extern crate std; -pub use generic_array; +pub use generic_array::{self, typenum::consts}; + #[cfg(feature = "heapless")] pub use heapless; -#[cfg(feature = "alloc")] -use alloc::vec::Vec; use core::fmt; use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; +#[cfg(feature = "alloc")] +use alloc::vec::Vec; + /// Error type #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] pub struct Error; diff --git a/block-cipher-trait/src/lib.rs b/block-cipher-trait/src/lib.rs index 6b85de4fb..11e2a555a 100644 --- a/block-cipher-trait/src/lib.rs +++ b/block-cipher-trait/src/lib.rs @@ -15,7 +15,7 @@ pub mod dev; mod errors; pub use crate::errors::InvalidKeyLength; -pub use generic_array; +pub use generic_array::{self, typenum::consts}; use generic_array::typenum::Unsigned; use generic_array::{ArrayLength, GenericArray}; diff --git a/crypto-mac/src/lib.rs b/crypto-mac/src/lib.rs index a0477d69f..4c04c3ad4 100644 --- a/crypto-mac/src/lib.rs +++ b/crypto-mac/src/lib.rs @@ -14,7 +14,7 @@ pub mod dev; mod errors; pub use crate::errors::{InvalidKeyLength, MacError}; -pub use generic_array; +pub use generic_array::{self, typenum::consts}; use generic_array::typenum::Unsigned; use generic_array::{ArrayLength, GenericArray}; diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 64e0e83a9..ceb5186ec 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -33,7 +33,7 @@ mod errors; pub use crate::digest::{Digest, Output}; pub use crate::errors::InvalidOutputSize; -pub use generic_array; +pub use generic_array::{self, typenum::consts}; #[cfg(feature = "std")] #[cfg_attr(docsrs, doc(cfg(feature = "std")))] diff --git a/stream-cipher/src/lib.rs b/stream-cipher/src/lib.rs index cf5b7d79c..8a2366905 100644 --- a/stream-cipher/src/lib.rs +++ b/stream-cipher/src/lib.rs @@ -18,7 +18,7 @@ pub mod dev; mod errors; pub use crate::errors::{InvalidKeyNonceLength, LoopError}; -pub use generic_array; +pub use generic_array::{self, typenum::consts}; use generic_array::typenum::Unsigned; use generic_array::{ArrayLength, GenericArray}; diff --git a/universal-hash/src/lib.rs b/universal-hash/src/lib.rs index 264bdd9ab..2e6490e72 100644 --- a/universal-hash/src/lib.rs +++ b/universal-hash/src/lib.rs @@ -21,7 +21,7 @@ #[cfg(feature = "std")] extern crate std; -pub use generic_array; +pub use generic_array::{self, typenum::consts}; use generic_array::typenum::Unsigned; use generic_array::{ArrayLength, GenericArray}; @@ -32,6 +32,7 @@ use subtle::{Choice, ConstantTimeEq}; pub trait UniversalHash: Clone { /// Size of the key for the universal hash function type KeySize: ArrayLength; + /// Size of the inputs to and outputs from the universal hash function type BlockSize: ArrayLength; From 11144cc6d5af35b42c7477095420735912462092 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 23 May 2020 12:27:30 -0700 Subject: [PATCH 0075/1461] aead: have NewAead borrow the key In many AEAD implementations we pass the key directly onto `NewBlockCipher`, e.g. in the `aes-gcm` crate: https://github.com/RustCrypto/AEADs/blob/af9926e/aes-gcm/src/lib.rs#L183 This makes an unnecessary copy of the key which therefore necessitates zeroing it out. If we borrow the key at the time the cipher is initialized, we can avoid making this copy. --- aead/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aead/src/lib.rs b/aead/src/lib.rs index cd358a88d..f19290a1f 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -74,7 +74,7 @@ pub trait NewAead { type KeySize: ArrayLength; /// Construct a new stateful instance for the given key. - fn new(key: GenericArray) -> Self; + fn new(key: &GenericArray) -> Self; } /// Authenticated Encryption with Associated Data (AEAD) algorithm. From 1485ac95535d5fb058c3df1cb9ff6236aff425c2 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 23 May 2020 12:40:35 -0700 Subject: [PATCH 0076/1461] aead: type aliases for `Key`, `Nonce`, and `Tag` It's syntactically annoying to have to use `GenericArray` for these types. This commit introduces a set of `GenericArray` type aliases for them instead. Notably, `Key` might benefit from having a proper struct which handles things like zeroization on drop and prevents accidental exposure in debug output, however this PR uses a simple `GenericArray` type alias for now. --- aead/src/lib.rs | 66 ++++++++++++++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 26 deletions(-) diff --git a/aead/src/lib.rs b/aead/src/lib.rs index f19290a1f..e72170ba7 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -62,19 +62,29 @@ macro_rules! impl_decrypt_in_place { let tag_pos = $buffer.len() - Self::TagSize::to_usize(); let (msg, tag) = $buffer.as_mut().split_at_mut(tag_pos); - $aead.decrypt_in_place_detached($nonce, $aad, msg, GenericArray::from_slice(tag))?; + $aead.decrypt_in_place_detached($nonce, $aad, msg, Tag::from_slice(tag))?; $buffer.truncate(tag_pos); Ok(()) }}; } +/// Key for a [`NewAead`] algorithm +// TODO(tarcieri): make this a struct and zeroize on drop? +pub type Key = GenericArray::KeySize>; + +/// Nonce: single-use value for ensuring ciphertexts are unique +pub type Nonce = GenericArray; + +/// Tag: authentication code which ensures ciphertexts are authentic +pub type Tag = GenericArray; + /// Instantiate either a stateless [`Aead`] or stateful [`AeadMut`] algorithm. pub trait NewAead { /// The size of the key array required by this algorithm. type KeySize: ArrayLength; /// Construct a new stateful instance for the given key. - fn new(key: &GenericArray) -> Self; + fn new(key: &Key) -> Self; } /// Authenticated Encryption with Associated Data (AEAD) algorithm. @@ -84,8 +94,10 @@ pub trait NewAead { pub trait Aead { /// The length of a nonce. type NonceSize: ArrayLength; + /// The maximum length of the nonce. type TagSize: ArrayLength; + /// The upper bound amount of additional space required to support a /// ciphertext vs. a plaintext. type CiphertextOverhead: ArrayLength + Unsigned; @@ -117,7 +129,7 @@ pub trait Aead { #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] fn encrypt<'msg, 'aad>( &self, - nonce: &GenericArray, + nonce: &Nonce, plaintext: impl Into>, ) -> Result, Error> { let payload = plaintext.into(); @@ -138,7 +150,7 @@ pub trait Aead { /// resulting ciphertext message. fn encrypt_in_place( &self, - nonce: &GenericArray, + nonce: &Nonce, associated_data: &[u8], buffer: &mut impl Buffer, ) -> Result<(), Error> { @@ -150,10 +162,10 @@ pub trait Aead { /// Encrypt the data in-place, returning the authentication tag fn encrypt_in_place_detached( &self, - nonce: &GenericArray, + nonce: &Nonce, associated_data: &[u8], buffer: &mut [u8], - ) -> Result, Error>; + ) -> Result, Error>; /// Decrypt the given ciphertext slice, and return the resulting plaintext /// as a vector of bytes. @@ -176,7 +188,7 @@ pub trait Aead { #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] fn decrypt<'msg, 'aad>( &self, - nonce: &GenericArray, + nonce: &Nonce, ciphertext: impl Into>, ) -> Result, Error> { let payload = ciphertext.into(); @@ -192,7 +204,7 @@ pub trait Aead { /// message upon success. fn decrypt_in_place( &self, - nonce: &GenericArray, + nonce: &Nonce, associated_data: &[u8], buffer: &mut impl Buffer, ) -> Result<(), Error> { @@ -204,10 +216,10 @@ pub trait Aead { /// is modified/unauthentic) fn decrypt_in_place_detached( &self, - nonce: &GenericArray, + nonce: &Nonce, associated_data: &[u8], buffer: &mut [u8], - tag: &GenericArray, + tag: &Tag, ) -> Result<(), Error>; } @@ -215,8 +227,10 @@ pub trait Aead { pub trait AeadMut { /// The length of a nonce. type NonceSize: ArrayLength; + /// The maximum length of the nonce. type TagSize: ArrayLength; + /// The upper bound amount of additional space required to support a /// ciphertext vs. a plaintext. type CiphertextOverhead: ArrayLength + Unsigned; @@ -230,7 +244,7 @@ pub trait AeadMut { #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] fn encrypt<'msg, 'aad>( &mut self, - nonce: &GenericArray, + nonce: &Nonce, plaintext: impl Into>, ) -> Result, Error> { let payload = plaintext.into(); @@ -251,7 +265,7 @@ pub trait AeadMut { /// resulting ciphertext message. fn encrypt_in_place( &mut self, - nonce: &GenericArray, + nonce: &Nonce, associated_data: &[u8], buffer: &mut impl Buffer, ) -> Result<(), Error> { @@ -263,10 +277,10 @@ pub trait AeadMut { /// Encrypt the data in-place, returning the authentication tag fn encrypt_in_place_detached( &mut self, - nonce: &GenericArray, + nonce: &Nonce, associated_data: &[u8], buffer: &mut [u8], - ) -> Result, Error>; + ) -> Result, Error>; /// Decrypt the given ciphertext slice, and return the resulting plaintext /// as a vector of bytes. @@ -277,7 +291,7 @@ pub trait AeadMut { #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] fn decrypt<'msg, 'aad>( &mut self, - nonce: &GenericArray, + nonce: &Nonce, ciphertext: impl Into>, ) -> Result, Error> { let payload = ciphertext.into(); @@ -293,7 +307,7 @@ pub trait AeadMut { /// message upon success. fn decrypt_in_place( &mut self, - nonce: &GenericArray, + nonce: &Nonce, associated_data: &[u8], buffer: &mut impl Buffer, ) -> Result<(), Error> { @@ -305,10 +319,10 @@ pub trait AeadMut { /// is modified/unauthentic) fn decrypt_in_place_detached( &mut self, - nonce: &GenericArray, + nonce: &Nonce, associated_data: &[u8], buffer: &mut [u8], - tag: &GenericArray, + tag: &Tag, ) -> Result<(), Error>; } @@ -324,7 +338,7 @@ impl AeadMut for Algo { #[cfg(feature = "alloc")] fn encrypt<'msg, 'aad>( &mut self, - nonce: &GenericArray, + nonce: &Nonce, plaintext: impl Into>, ) -> Result, Error> { ::encrypt(self, nonce, plaintext) @@ -333,7 +347,7 @@ impl AeadMut for Algo { /// Encrypt the given buffer containing a plaintext message in-place. fn encrypt_in_place( &mut self, - nonce: &GenericArray, + nonce: &Nonce, associated_data: &[u8], buffer: &mut impl Buffer, ) -> Result<(), Error> { @@ -343,10 +357,10 @@ impl AeadMut for Algo { /// Encrypt the data in-place, returning the authentication tag fn encrypt_in_place_detached( &mut self, - nonce: &GenericArray, + nonce: &Nonce, associated_data: &[u8], buffer: &mut [u8], - ) -> Result, Error> { + ) -> Result, Error> { ::encrypt_in_place_detached(self, nonce, associated_data, buffer) } @@ -355,7 +369,7 @@ impl AeadMut for Algo { #[cfg(feature = "alloc")] fn decrypt<'msg, 'aad>( &mut self, - nonce: &GenericArray, + nonce: &Nonce, ciphertext: impl Into>, ) -> Result, Error> { ::decrypt(self, nonce, ciphertext) @@ -365,7 +379,7 @@ impl AeadMut for Algo { /// provided authentication tag does not match the given ciphertext. fn decrypt_in_place( &mut self, - nonce: &GenericArray, + nonce: &Nonce, associated_data: &[u8], buffer: &mut impl Buffer, ) -> Result<(), Error> { @@ -377,10 +391,10 @@ impl AeadMut for Algo { /// is modified/unauthentic) fn decrypt_in_place_detached( &mut self, - nonce: &GenericArray, + nonce: &Nonce, associated_data: &[u8], buffer: &mut [u8], - tag: &GenericArray, + tag: &Tag, ) -> Result<(), Error> { ::decrypt_in_place_detached(self, nonce, associated_data, buffer, tag) } From 4eaa6260c34772531c8aa375d287809b33c91229 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 23 May 2020 12:45:24 -0700 Subject: [PATCH 0077/1461] .github: add security-audit action Uses the `actions-rs` wrapper for `cargo audit` to ensure there aren't any vulnerable dependencies in `Cargo.lock`. --- .github/workflows/security-audit.yml | 24 ++++++++++++++++++++++++ Cargo.lock | 1 + 2 files changed, 25 insertions(+) create mode 100644 .github/workflows/security-audit.yml diff --git a/.github/workflows/security-audit.yml b/.github/workflows/security-audit.yml new file mode 100644 index 000000000..b003aa2ec --- /dev/null +++ b/.github/workflows/security-audit.yml @@ -0,0 +1,24 @@ +name: Security Audit +on: + pull_request: + paths: Cargo.lock + push: + branches: develop + paths: Cargo.lock + schedule: + - cron: '0 0 * * *' + +jobs: + security_audit: + name: Security Audit + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Cache cargo bin + uses: actions/cache@v1 + with: + path: ~/.cargo/bin + key: ${{ runner.os }}-cargo-audit-v0.12.0 + - uses: actions-rs/audit-check@v1 + with: + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/Cargo.lock b/Cargo.lock index 42f6afa6b..afed2245f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. + [[package]] name = "aead" version = "0.2.0" From 13341b236e6c3edd27faddf7d59012e1ec50fc65 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 23 May 2020 13:06:54 -0700 Subject: [PATCH 0078/1461] Add basic README.md files to all crates ...and configure Cargo.toml(s) to render them on https://crates.io --- aead/README.md | 8 ++--- block-cipher-trait/Cargo.toml | 4 +-- block-cipher-trait/README.md | 49 +++++++++++++++++++++++++++ crypto-mac/Cargo.toml | 4 +-- crypto-mac/README.md | 49 +++++++++++++++++++++++++++ digest/Cargo.toml | 4 +-- digest/README.md | 50 ++++++++++++++++++++++++++++ signature/README.md | 4 +-- signature/signature_derive/README.md | 2 -- stream-cipher/Cargo.toml | 4 +-- stream-cipher/README.md | 49 +++++++++++++++++++++++++++ universal-hash/Cargo.toml | 4 +-- universal-hash/README.md | 49 +++++++++++++++++++++++++++ 13 files changed, 255 insertions(+), 25 deletions(-) create mode 100644 block-cipher-trait/README.md create mode 100644 crypto-mac/README.md create mode 100644 digest/README.md create mode 100644 stream-cipher/README.md create mode 100644 universal-hash/README.md diff --git a/aead/README.md b/aead/README.md index 78f65cdb0..0a95723ce 100644 --- a/aead/README.md +++ b/aead/README.md @@ -1,4 +1,4 @@ -# RustCrypto: Authenticated Encryption with Additional Data +# RustCrypto: Authenticated Encryption with Additional Data Traits [![crate][crate-image]][crate-link] [![Docs][docs-image]][docs-link] @@ -27,14 +27,10 @@ done with a minor version bump. - All on-by-default features of this library are covered by SemVer - MSRV is considered exempt from SemVer as noted above -- The off-by-default features `derive-preview` and `digest-preview` are - unstable "preview" features which are also considered exempt from SemVer. - Breaking changes to these features will, like MSRV, be done with a minor - version bump. ## License -All crates licensed under either of +Licensed under either of: * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) * [MIT license](http://opensource.org/licenses/MIT) diff --git a/block-cipher-trait/Cargo.toml b/block-cipher-trait/Cargo.toml index d4fb41e96..7aff48624 100644 --- a/block-cipher-trait/Cargo.toml +++ b/block-cipher-trait/Cargo.toml @@ -4,6 +4,7 @@ description = "Traits for description of block ciphers" version = "0.6.2" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" +readme = "README.md" edition = "2018" documentation = "https://docs.rs/block-cipher-trait" repository = "https://github.com/RustCrypto/traits" @@ -18,8 +19,5 @@ blobby = { version = "0.1", optional = true } std = [] dev = ["blobby"] -[badges] -travis-ci = { repository = "RustCrypto/traits" } - [package.metadata.docs.rs] features = [ "std" ] diff --git a/block-cipher-trait/README.md b/block-cipher-trait/README.md new file mode 100644 index 000000000..d199536d8 --- /dev/null +++ b/block-cipher-trait/README.md @@ -0,0 +1,49 @@ +# RustCrypto: Block Cipher Traits + +[![crate][crate-image]][crate-link] +[![Docs][docs-image]][docs-link] +![Apache2/MIT licensed][license-image] +![Rust Version][rustc-image] +[![Build Status][build-image]][build-link] + +Traits which define functionality of block ciphers. + +[Documentation][docs-link] + +## Minimum Supported Rust Version + +Rust **1.41** or higher. + +Minimum supported Rust version can be changed in the future, but it will be +done with a minor version bump. + +## SemVer Policy + +- All on-by-default features of this library are covered by SemVer +- MSRV is considered exempt from SemVer as noted above + +## License + +Licensed under either of: + + * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) + * [MIT license](http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall be +dual licensed as above, without any additional terms or conditions. + +[//]: # (badges) + +[crate-image]: https://img.shields.io/crates/v/block-cipher-trait.svg +[crate-link]: https://crates.io/crates/block-cipher-trait +[docs-image]: https://docs.rs/block-cipher-trait/badge.svg +[docs-link]: https://docs.rs/block-cipher-trait/ +[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg +[build-image]: https://github.com/RustCrypto/traits/workflows/block-cipher-trait/badge.svg?branch=master&event=push +[build-link]: https://github.com/RustCrypto/traits/actions?query=workflow%3Ablock-cipher-trait diff --git a/crypto-mac/Cargo.toml b/crypto-mac/Cargo.toml index 3684784c9..06ef469fb 100644 --- a/crypto-mac/Cargo.toml +++ b/crypto-mac/Cargo.toml @@ -4,6 +4,7 @@ description = "Trait for Message Authentication Code (MAC) algorithms" version = "0.8.0" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" +readme = "README.md" edition = "2018" documentation = "https://docs.rs/crypto-mac" repository = "https://github.com/RustCrypto/traits" @@ -19,8 +20,5 @@ blobby = { version = "0.1", optional = true } dev = ["blobby"] std = [] -[badges] -travis-ci = { repository = "RustCrypto/traits" } - [package.metadata.docs.rs] features = [ "std" ] diff --git a/crypto-mac/README.md b/crypto-mac/README.md new file mode 100644 index 000000000..f31ea717e --- /dev/null +++ b/crypto-mac/README.md @@ -0,0 +1,49 @@ +# RustCrypto: Message Authentication Code Traits + +[![crate][crate-image]][crate-link] +[![Docs][docs-image]][docs-link] +![Apache2/MIT licensed][license-image] +![Rust Version][rustc-image] +[![Build Status][build-image]][build-link] + +Traits for Message Authentication Code (MAC) algorithms. + +[Documentation][docs-link] + +## Minimum Supported Rust Version + +Rust **1.41** or higher. + +Minimum supported Rust version can be changed in the future, but it will be +done with a minor version bump. + +## SemVer Policy + +- All on-by-default features of this library are covered by SemVer +- MSRV is considered exempt from SemVer as noted above + +## License + +Licensed under either of: + + * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) + * [MIT license](http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall be +dual licensed as above, without any additional terms or conditions. + +[//]: # (badges) + +[crate-image]: https://img.shields.io/crates/v/crypto-mac.svg +[crate-link]: https://crates.io/crates/crypto-mac +[docs-image]: https://docs.rs/crypto-mac/badge.svg +[docs-link]: https://docs.rs/crypto-mac/ +[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg +[build-image]: https://github.com/RustCrypto/traits/workflows/crypto-mac/badge.svg?branch=master&event=push +[build-link]: https://github.com/RustCrypto/traits/actions?query=workflow%3Acrypto-mac diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 3c7229f8a..9dffdff5a 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -4,6 +4,7 @@ description = "Traits for cryptographic hash functions" version = "0.8.1" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" +readme = "README.md" edition = "2018" documentation = "https://docs.rs/digest" repository = "https://github.com/RustCrypto/traits" @@ -18,9 +19,6 @@ blobby = { version = "0.1", optional = true } std = [] dev = ["blobby"] -[badges] -travis-ci = { repository = "RustCrypto/traits" } - [package.metadata.docs.rs] all-features = true rustdoc-args = ["--cfg", "docsrs"] diff --git a/digest/README.md b/digest/README.md new file mode 100644 index 000000000..a3c891e29 --- /dev/null +++ b/digest/README.md @@ -0,0 +1,50 @@ +# RustCrypto: Digest Algorithm Traits + +[![crate][crate-image]][crate-link] +[![Docs][docs-image]][docs-link] +![Apache2/MIT licensed][license-image] +![Rust Version][rustc-image] +[![Build Status][build-image]][build-link] + +Traits which describe functionality of cryptographic hash functions, a.k.a. +digest algorithms. + +[Documentation][docs-link] + +## Minimum Supported Rust Version + +Rust **1.41** or higher. + +Minimum supported Rust version can be changed in the future, but it will be +done with a minor version bump. + +## SemVer Policy + +- All on-by-default features of this library are covered by SemVer +- MSRV is considered exempt from SemVer as noted above + +## License + +Licensed under either of: + + * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) + * [MIT license](http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall be +dual licensed as above, without any additional terms or conditions. + +[//]: # (badges) + +[crate-image]: https://img.shields.io/crates/v/digest.svg +[crate-link]: https://crates.io/crates/digest +[docs-image]: https://docs.rs/digest/badge.svg +[docs-link]: https://docs.rs/digest/ +[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg +[build-image]: https://github.com/RustCrypto/traits/workflows/digest/badge.svg?branch=master&event=push +[build-link]: https://github.com/RustCrypto/traits/actions?query=workflow%3Adigest diff --git a/signature/README.md b/signature/README.md index 565b395c7..521f8507d 100644 --- a/signature/README.md +++ b/signature/README.md @@ -1,4 +1,4 @@ -# RustCrypto: `signature` crate +# RustCrypto: Digital Signature Algorithms [![crate][crate-image]][crate-link] [![Docs][docs-image]][docs-link] @@ -32,7 +32,7 @@ done with a minor version bump. ## License -All crates licensed under either of +Licensed under either of * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) * [MIT license](http://opensource.org/licenses/MIT) diff --git a/signature/signature_derive/README.md b/signature/signature_derive/README.md index 6da6d5d67..e63f6f85f 100644 --- a/signature/signature_derive/README.md +++ b/signature/signature_derive/README.md @@ -1,7 +1,5 @@ # `signature` crate custom derive support -[![Build Status](https://travis-ci.org/RustCrypto/traits.svg?branch=master)](https://travis-ci.org/RustCrypto/traits) - This crate provides proc macros used by the `signature` crate. Not intended to be used directly. See the `signature` crate's documentation diff --git a/stream-cipher/Cargo.toml b/stream-cipher/Cargo.toml index eed73432f..81061ca39 100644 --- a/stream-cipher/Cargo.toml +++ b/stream-cipher/Cargo.toml @@ -4,6 +4,7 @@ description = "Stream cipher traits" version = "0.3.2" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" +readme = "README.md" edition = "2018" documentation = "https://docs.rs/stream-cipher" repository = "https://github.com/RustCrypto/traits" @@ -18,8 +19,5 @@ blobby = { version = "0.1", optional = true } std = [] dev = ["blobby"] -[badges] -travis-ci = { repository = "RustCrypto/traits" } - [package.metadata.docs.rs] features = [ "std" ] diff --git a/stream-cipher/README.md b/stream-cipher/README.md new file mode 100644 index 000000000..f49b4c23d --- /dev/null +++ b/stream-cipher/README.md @@ -0,0 +1,49 @@ +# RustCrypto: Stream Cipher Traits + +[![crate][crate-image]][crate-link] +[![Docs][docs-image]][docs-link] +![Apache2/MIT licensed][license-image] +![Rust Version][rustc-image] +[![Build Status][build-image]][build-link] + +Traits which define functionality of stream ciphers. + +[Documentation][docs-link] + +## Minimum Supported Rust Version + +Rust **1.41** or higher. + +Minimum supported Rust version can be changed in the future, but it will be +done with a minor version bump. + +## SemVer Policy + +- All on-by-default features of this library are covered by SemVer +- MSRV is considered exempt from SemVer as noted above + +## License + +Licensed under either of: + + * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) + * [MIT license](http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall be +dual licensed as above, without any additional terms or conditions. + +[//]: # (badges) + +[crate-image]: https://img.shields.io/crates/v/stream-cipher.svg +[crate-link]: https://crates.io/crates/stream-cipher +[docs-image]: https://docs.rs/stream-cipher/badge.svg +[docs-link]: https://docs.rs/stream-cipher/ +[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg +[build-image]: https://github.com/RustCrypto/traits/workflows/stream-cipher/badge.svg?branch=master&event=push +[build-link]: https://github.com/RustCrypto/traits/actions?query=workflow%3Astream-cipher diff --git a/universal-hash/Cargo.toml b/universal-hash/Cargo.toml index 66da45701..78d803493 100644 --- a/universal-hash/Cargo.toml +++ b/universal-hash/Cargo.toml @@ -8,6 +8,7 @@ documentation = "https://docs.rs/universal-hash" repository = "https://github.com/RustCrypto/traits" keywords = ["crypto", "mac"] categories = ["cryptography", "no-std"] +readme = "README.md" edition = "2018" [dependencies] @@ -17,8 +18,5 @@ subtle = { version = "2", default-features = false } [features] std = [] -[badges] -travis-ci = { repository = "RustCrypto/traits" } - [package.metadata.docs.rs] all-features = true diff --git a/universal-hash/README.md b/universal-hash/README.md new file mode 100644 index 000000000..ac238bab3 --- /dev/null +++ b/universal-hash/README.md @@ -0,0 +1,49 @@ +# RustCrypto: Universal Hash Function Traits + +[![crate][crate-image]][crate-link] +[![Docs][docs-image]][docs-link] +![Apache2/MIT licensed][license-image] +![Rust Version][rustc-image] +[![Build Status][build-image]][build-link] + +Traits which define functionality of universal hash functions. + +[Documentation][docs-link] + +## Minimum Supported Rust Version + +Rust **1.41** or higher. + +Minimum supported Rust version can be changed in the future, but it will be +done with a minor version bump. + +## SemVer Policy + +- All on-by-default features of this library are covered by SemVer +- MSRV is considered exempt from SemVer as noted above + +## License + +Licensed under either of: + +* [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) +* [MIT license](http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall be +dual licensed as above, without any additional terms or conditions. + +[//]: # (badges) + +[crate-image]: https://img.shields.io/crates/v/universal-hash.svg +[crate-link]: https://crates.io/crates/universal-hash +[docs-image]: https://docs.rs/universal-hash/badge.svg +[docs-link]: https://docs.rs/universal-hash/ +[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg +[build-image]: https://github.com/RustCrypto/traits/workflows/universal-hash/badge.svg?branch=master&event=push +[build-link]: https://github.com/RustCrypto/traits/actions?query=workflow%3Auniversal-hash From af9c536d133eb2dc2386b03952fed5c0f7589c88 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 23 May 2020 13:26:59 -0700 Subject: [PATCH 0079/1461] universal-hash: add `Key` and `Block` type aliases Also makes `Output` generic around the underlying `UniversalHash`, and improves documentation somewhat. --- Cargo.lock | 1 - universal-hash/src/lib.rs | 84 +++++++++++++++++++++------------------ 2 files changed, 46 insertions(+), 39 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index afed2245f..42f6afa6b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,5 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. - [[package]] name = "aead" version = "0.2.0" diff --git a/universal-hash/src/lib.rs b/universal-hash/src/lib.rs index 2e6490e72..d646715be 100644 --- a/universal-hash/src/lib.rs +++ b/universal-hash/src/lib.rs @@ -1,13 +1,15 @@ //! Traits for [Universal Hash Functions]. //! -//! Universal hash functions select from a "universal family" of possible -//! hash functions selected by a key. They are well suited to the purpose -//! of "one time authenticators" for a sequence of bytestring inputs, -//! as their construction has a number of desirable properties such as -//! pairwise independence as well as amenability to efficient implementations, -//! particularly when implemented using SIMD instructions. +//! Universal hash functions provide a "universal family" of possible +//! hash functions where a given member of a family is selected by a key. //! -//! When combined with a cipher, such as in Galois/Counter Mode or the +//! They are well suited to the purpose of "one time authenticators" for a +//! sequence of bytestring inputs, as their construction has a number of +//! desirable properties such as pairwise independence as well as amenability +//! to efficient implementations, particularly when implemented using SIMD +//! instructions. +//! +//! When combined with a cipher, such as in Galois/Counter Mode (GCM) or the //! Salsa20 family AEAD constructions, they can provide the core functionality //! for a Message Authentication Code (MAC). //! @@ -27,6 +29,12 @@ use generic_array::typenum::Unsigned; use generic_array::{ArrayLength, GenericArray}; use subtle::{Choice, ConstantTimeEq}; +/// Keys to a [`UniversalHash`]. +pub type Key = GenericArray::KeySize>; + +/// Blocks are inputs to a [`UniversalHash`]. +pub type Block = GenericArray::BlockSize>; + /// The `UniversalHash` trait defines a generic interface for universal hash /// functions. pub trait UniversalHash: Clone { @@ -37,10 +45,10 @@ pub trait UniversalHash: Clone { type BlockSize: ArrayLength; /// Instantiate a universal hash function with the given key - fn new(key: &GenericArray) -> Self; + fn new(key: &Key) -> Self; /// Input a block into the universal hash function - fn update_block(&mut self, block: &GenericArray); + fn update_block(&mut self, block: &Block); /// Input data into the universal hash function. If the length of the /// data is not a multiple of the block size, the remaining data is @@ -64,24 +72,24 @@ pub trait UniversalHash: Clone { } } - /// Reset `UniversalHash` instance. + /// Reset [`UniversalHash`] instance. fn reset(&mut self); - /// Obtain the [`Output`] of a `UniversalHash` function and consume it. - fn result(self) -> Output; + /// Obtain the [`Output`] of a [`UniversalHash`] function and consume it. + fn result(self) -> Output; - /// Obtain the [`Output`] of a `UniversalHash` computation and reset it back + /// Obtain the [`Output`] of a [`UniversalHash`] computation and reset it back /// to its initial state. - fn result_reset(&mut self) -> Output { + fn result_reset(&mut self) -> Output { let res = self.clone().result(); self.reset(); res } - /// Verify the `UniversalHash` of the processed input matches a given [`Output`]. + /// Verify the [`UniversalHash`] of the processed input matches a given [`Output`]. /// This is useful when constructing Message Authentication Codes (MACs) /// from universal hash functions. - fn verify(self, other: &GenericArray) -> Result<(), Error> { + fn verify(self, other: &Block) -> Result<(), Error> { if self.result() == other.into() { Ok(()) } else { @@ -91,68 +99,68 @@ pub trait UniversalHash: Clone { } /// Outputs of universal hash functions which are a thin wrapper around a -/// byte array. Provides a safe `Eq` implementation that runs in constant time, +/// byte array. Provides a safe [`Eq`] implementation that runs in constant time, /// which is useful for implementing Message Authentication Codes (MACs) based /// on universal hashing. #[derive(Clone)] -pub struct Output> { - bytes: GenericArray, +pub struct Output { + bytes: GenericArray, } -impl Output +impl Output where - N: ArrayLength, + U: UniversalHash, { - /// Create a new `Block`. - pub fn new(bytes: GenericArray) -> Output { + /// Create a new [`Output`] block. + pub fn new(bytes: Block) -> Output { Output { bytes } } - /// Get the inner `GenericArray` this type wraps - pub fn into_bytes(self) -> GenericArray { + /// Get the inner [`GenericArray`] this type wraps + pub fn into_bytes(self) -> Block { self.bytes } } -impl From> for Output +impl From> for Output where - N: ArrayLength, + U: UniversalHash, { - fn from(bytes: GenericArray) -> Self { + fn from(bytes: Block) -> Self { Output { bytes } } } -impl<'a, N> From<&'a GenericArray> for Output +impl<'a, U> From<&'a Block> for Output where - N: ArrayLength, + U: UniversalHash, { - fn from(bytes: &'a GenericArray) -> Self { + fn from(bytes: &'a Block) -> Self { bytes.clone().into() } } -impl ConstantTimeEq for Output +impl ConstantTimeEq for Output where - N: ArrayLength, + U: UniversalHash, { fn ct_eq(&self, other: &Self) -> Choice { self.bytes.ct_eq(&other.bytes) } } -impl PartialEq for Output +impl PartialEq for Output where - N: ArrayLength, + U: UniversalHash, { - fn eq(&self, x: &Output) -> bool { + fn eq(&self, x: &Output) -> bool { self.ct_eq(x).unwrap_u8() == 1 } } -impl> Eq for Output {} +impl Eq for Output {} -/// Error type for when the `Output` of a `UniversalHash` +/// Error type for when the [`Output`] of a [`UniversalHash`] /// is not equal to the expected value. #[derive(Default, Debug, Copy, Clone, Eq, PartialEq)] pub struct Error; From 9a611e8661d3c3e432ee192855aee7ae413c3c9d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 23 May 2020 14:02:35 -0700 Subject: [PATCH 0080/1461] universal-hash: rename `update_block` => `update` Updating (in the IUF sense) the UHF state by a block is the core "update" primitive, so it makes sense to make it first-class. --- universal-hash/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/universal-hash/src/lib.rs b/universal-hash/src/lib.rs index d646715be..cfb382983 100644 --- a/universal-hash/src/lib.rs +++ b/universal-hash/src/lib.rs @@ -48,7 +48,7 @@ pub trait UniversalHash: Clone { fn new(key: &Key) -> Self; /// Input a block into the universal hash function - fn update_block(&mut self, block: &Block); + fn update(&mut self, block: &Block); /// Input data into the universal hash function. If the length of the /// data is not a multiple of the block size, the remaining data is @@ -60,7 +60,7 @@ pub trait UniversalHash: Clone { let mut chunks = data.chunks_exact(Self::BlockSize::to_usize()); for chunk in &mut chunks { - self.update_block(GenericArray::from_slice(chunk)); + self.update(GenericArray::from_slice(chunk)); } let rem = chunks.remainder(); @@ -68,7 +68,7 @@ pub trait UniversalHash: Clone { if !rem.is_empty() { let mut padded_block = GenericArray::default(); padded_block[..rem.len()].copy_from_slice(rem); - self.update_block(&padded_block); + self.update(&padded_block); } } From 68d74ed299090d63fe12153d0ec1ebfe24967582 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 23 May 2020 14:27:42 -0700 Subject: [PATCH 0081/1461] README.md(s): add supplemental links Adds links to the Wikipedia definitions of various algorithms, as well as the RustCrypto repositories where various algorithm-specific implementations of the traits are located. --- block-cipher-trait/README.md | 9 ++++++++- crypto-mac/README.md | 9 ++++++++- digest/README.md | 9 ++++++++- signature/README.md | 5 +++++ stream-cipher/README.md | 9 ++++++++- universal-hash/README.md | 9 ++++++++- 6 files changed, 45 insertions(+), 5 deletions(-) diff --git a/block-cipher-trait/README.md b/block-cipher-trait/README.md index d199536d8..5ab97ef6b 100644 --- a/block-cipher-trait/README.md +++ b/block-cipher-trait/README.md @@ -6,7 +6,9 @@ ![Rust Version][rustc-image] [![Build Status][build-image]][build-link] -Traits which define functionality of block ciphers. +Traits which define functionality of [block ciphers]. + +See [RustCrypto/block-ciphers] for implementations which use this trait. [Documentation][docs-link] @@ -47,3 +49,8 @@ dual licensed as above, without any additional terms or conditions. [rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg [build-image]: https://github.com/RustCrypto/traits/workflows/block-cipher-trait/badge.svg?branch=master&event=push [build-link]: https://github.com/RustCrypto/traits/actions?query=workflow%3Ablock-cipher-trait + +[//]: # (general links) + +[block ciphers]: https://en.wikipedia.org/wiki/Block_cipher +[RustCrypto/block-ciphers]: https://github.com/RustCrypto/block-ciphers diff --git a/crypto-mac/README.md b/crypto-mac/README.md index f31ea717e..35349ef82 100644 --- a/crypto-mac/README.md +++ b/crypto-mac/README.md @@ -6,7 +6,9 @@ ![Rust Version][rustc-image] [![Build Status][build-image]][build-link] -Traits for Message Authentication Code (MAC) algorithms. +Traits for [Message Authentication Code] (MAC) algorithms. + +See [RustCrypto/MACs] for implementations which use this trait. [Documentation][docs-link] @@ -47,3 +49,8 @@ dual licensed as above, without any additional terms or conditions. [rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg [build-image]: https://github.com/RustCrypto/traits/workflows/crypto-mac/badge.svg?branch=master&event=push [build-link]: https://github.com/RustCrypto/traits/actions?query=workflow%3Acrypto-mac + +[//]: # (general links) + +[Message Authentication Code]: https://en.wikipedia.org/wiki/Message_authentication_code +[RustCrypto/MACs]: https://github.com/RustCrypto/MACs diff --git a/digest/README.md b/digest/README.md index a3c891e29..fb0ffa711 100644 --- a/digest/README.md +++ b/digest/README.md @@ -6,9 +6,11 @@ ![Rust Version][rustc-image] [![Build Status][build-image]][build-link] -Traits which describe functionality of cryptographic hash functions, a.k.a. +Traits which describe functionality of [cryptographic hash functions], a.k.a. digest algorithms. +See [RustCrypto/hashes] for implementations which use this trait. + [Documentation][docs-link] ## Minimum Supported Rust Version @@ -48,3 +50,8 @@ dual licensed as above, without any additional terms or conditions. [rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg [build-image]: https://github.com/RustCrypto/traits/workflows/digest/badge.svg?branch=master&event=push [build-link]: https://github.com/RustCrypto/traits/actions?query=workflow%3Adigest + +[//]: # (general links) + +[cryptographic hash functions]: https://en.wikipedia.org/wiki/Cryptographic_hash_function +[RustCrypto/hashes]: https://github.com/RustCrypto/hashes diff --git a/signature/README.md b/signature/README.md index 521f8507d..f4f3e6262 100644 --- a/signature/README.md +++ b/signature/README.md @@ -12,6 +12,10 @@ generating and verifying [digital signatures][1]. Used by the [`ecdsa`][2] and [`ed25519`][3] crates, with forthcoming support in the [`rsa`][4] crate. +See also the [Signatory][5] project for trait wrappers for using these traits +with many popular Rust cryptography crates, including `ed25519-dalek`, *ring*, +`secp256k1-rs`, and `sodiumoxide`. + [Documentation][docs-link] ## Minimum Supported Rust Version @@ -62,3 +66,4 @@ dual licensed as above, without any additional terms or conditions. [2]: https://github.com/RustCrypto/signatures/tree/master/ecdsa [3]: https://github.com/RustCrypto/signatures/tree/master/ed25519 [4]: https://github.com/RustCrypto/RSA +[5]: https://docs.rs/signatory diff --git a/stream-cipher/README.md b/stream-cipher/README.md index f49b4c23d..86a2886a0 100644 --- a/stream-cipher/README.md +++ b/stream-cipher/README.md @@ -6,7 +6,9 @@ ![Rust Version][rustc-image] [![Build Status][build-image]][build-link] -Traits which define functionality of stream ciphers. +Traits which define functionality of [stream ciphers]. + +See [RustCrypto/stream-ciphers] for implementations which use this trait. [Documentation][docs-link] @@ -47,3 +49,8 @@ dual licensed as above, without any additional terms or conditions. [rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg [build-image]: https://github.com/RustCrypto/traits/workflows/stream-cipher/badge.svg?branch=master&event=push [build-link]: https://github.com/RustCrypto/traits/actions?query=workflow%3Astream-cipher + +[//]: # (general links) + +[stream ciphers]: https://en.wikipedia.org/wiki/Stream_cipher +[RustCrypto/stream-ciphers]: https://github.com/RustCrypto/stream-ciphers diff --git a/universal-hash/README.md b/universal-hash/README.md index ac238bab3..3be1e3cf7 100644 --- a/universal-hash/README.md +++ b/universal-hash/README.md @@ -6,7 +6,9 @@ ![Rust Version][rustc-image] [![Build Status][build-image]][build-link] -Traits which define functionality of universal hash functions. +Traits which define functionality of [universal hash functions]. + +See [RustCrypto/universal-hashes] for implementations which use this trait. [Documentation][docs-link] @@ -47,3 +49,8 @@ dual licensed as above, without any additional terms or conditions. [rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg [build-image]: https://github.com/RustCrypto/traits/workflows/universal-hash/badge.svg?branch=master&event=push [build-link]: https://github.com/RustCrypto/traits/actions?query=workflow%3Auniversal-hash + +[//]: # (general links) + +[universal hash functions]: https://en.wikipedia.org/wiki/Universal_hashing +[RustCrypto/universal-hashes]: https://github.com/RustCrypto/universal-hashes From a05adc1d74ac675c583b54a5dbd9060dd5094666 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 23 May 2020 14:39:14 -0700 Subject: [PATCH 0082/1461] digest: add more content to README.md Copypasta from: https://github.com/RustCrypto/hashes --- digest/README.md | 112 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 108 insertions(+), 4 deletions(-) diff --git a/digest/README.md b/digest/README.md index fb0ffa711..e1a0f8d94 100644 --- a/digest/README.md +++ b/digest/README.md @@ -6,10 +6,10 @@ ![Rust Version][rustc-image] [![Build Status][build-image]][build-link] -Traits which describe functionality of [cryptographic hash functions], a.k.a. +Traits which describe functionality of [cryptographic hash functions][0], a.k.a. digest algorithms. -See [RustCrypto/hashes] for implementations which use this trait. +See [RustCrypto/hashes][1] for implementations which use this trait. [Documentation][docs-link] @@ -25,6 +25,105 @@ done with a minor version bump. - All on-by-default features of this library are covered by SemVer - MSRV is considered exempt from SemVer as noted above +## Usage + +Let us demonstrate how to use crates in this repository using BLAKE2b as an +example. + +First add `blake2` crate to your `Cargo.toml`: + +```toml +[dependencies] +blake2 = "0.8" +``` + +`blake2` and other crates re-export `digest` crate and `Digest` trait for +convenience, so you don't have to add `digest` crate as an explicit dependency. + +Now you can write the following code: + +```rust +use blake2::{Blake2b, Digest}; + +let mut hasher = Blake2b::new(); +let data = b"Hello world!"; +hasher.input(data); +// `input` can be called repeatedly and is generic over `AsRef<[u8]>` +hasher.input("String data"); +// Note that calling `result()` consumes hasher +let hash = hasher.result(); +println!("Result: {:x}", hash); +``` + +In this example `hash` has type [`GenericArray`][2], which is a generic +alternative to `[u8; 64]`. + +Alternatively you can use chained approach, which is equivalent to the previous +example: + +```rust +let hash = Blake2b::new() + .chain(b"Hello world!") + .chain("String data") + .result(); + +println!("Result: {:x}", hash); +``` + +If the whole message is available you also can use convinience `digest` method: + +```rust +let hash = Blake2b::digest(b"my message"); +println!("Result: {:x}", hash); +``` + +### Hashing `Read`-able objects + +If you want to hash data from [`Read`][3] trait (e.g. from file) you can rely on +implementation of [`Write`][4] trait (requires enabled-by-default `std` feature): + +```rust +use blake2::{Blake2b, Digest}; +use std::{fs, io}; + +let mut file = fs::File::open(&path)?; +let mut hasher = Blake2b::new(); +let n = io::copy(&mut file, &mut hasher)?; +let hash = hasher.result(); + +println!("Path: {}", path); +println!("Bytes processed: {}", n); +println!("Hash value: {:x}", hash); +``` + +### Generic code + +You can write generic code over `Digest` (or other traits from `digest` crate) +trait which will work over different hash functions: + +```rust +use digest::Digest; + +// Toy example, do not use it in practice! +// Instead use crates from: https://github.com/RustCrypto/password-hashing +fn hash_password(password: &str, salt: &str, output: &mut [u8]) { + let mut hasher = D::new(); + hasher.input(password.as_bytes()); + hasher.input(b"$"); + hasher.input(salt.as_bytes()); + output.copy_from_slice(hasher.result().as_slice()) +} + +use blake2::Blake2b; +use sha2::Sha256; + +hash_password::("my_password", "abcd", &mut buf); +hash_password::("my_password", "abcd", &mut buf); +``` + +If you want to use hash functions with trait objects, use `digest::DynDigest` +trait. + ## License Licensed under either of: @@ -53,5 +152,10 @@ dual licensed as above, without any additional terms or conditions. [//]: # (general links) -[cryptographic hash functions]: https://en.wikipedia.org/wiki/Cryptographic_hash_function -[RustCrypto/hashes]: https://github.com/RustCrypto/hashes +[0]: https://en.wikipedia.org/wiki/Cryptographic_hash_function +[1]: https://github.com/RustCrypto/hashes +[2]: https://docs.rs/generic-array +[3]: https://doc.rust-lang.org/std/io/trait.Read.html +[4]: https://doc.rust-lang.org/std/io/trait.Write.html +[5]: https://en.wikipedia.org/wiki/Hash-based_message_authentication_code +[6]: https://github.com/RustCrypto/MACs From 20f869894689d5089a47d775a0428aeef4f07f64 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 23 May 2020 10:49:08 -0700 Subject: [PATCH 0083/1461] aead: split Aead(Mut) from Aead(Mut)InPlace (fixes #70) Splits the `Aead` and `AeadMut` trait into the following: - `Aead` and `AeadMut`:gated on the `alloc` feature - `AeadInPlace` and `AeadMutInPlace`: object-safe, always available This further has the benefit that implementors who don't want to provide or abstract over the in-place APIs no longer have to. To make the `*InPlace` traits object safe, the one generic parameter they previously used (`impl Buffer`) was switched to `dyn Buffer`. This adds some vtable dispatch overhead for manipulating the buffer, but hopefully it is still cheap compared to the overhead of cryptographic operations on the underlying data. That said, no benchmarks have been performed (yet) on the costs of this change. --- aead/src/lib.rs | 330 ++++++++++++++++++++++++++++-------------------- 1 file changed, 192 insertions(+), 138 deletions(-) diff --git a/aead/src/lib.rs b/aead/src/lib.rs index e72170ba7..279937703 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -36,7 +36,10 @@ use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; #[cfg(feature = "alloc")] use alloc::vec::Vec; -/// Error type +/// Error type. +/// +/// This type is deliberately opaque as to avoid potential side-channel +/// leakage (e.g. padding oracle). #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] pub struct Error; @@ -49,25 +52,6 @@ impl fmt::Display for Error { #[cfg(feature = "std")] impl std::error::Error for Error {} -/// Implement the `decrypt_in_place` method on `Aead` and `AeadMut`. -/// Uses a macro to gloss over `&self` vs `&mut self`. -/// -/// Assumes a postfix authentication tag. AEAD ciphers which do not use a -/// postfix authentication tag will need to define their own implementation. -macro_rules! impl_decrypt_in_place { - ($aead:expr, $nonce:expr, $aad:expr, $buffer:expr) => {{ - if $buffer.len() < Self::TagSize::to_usize() { - return Err(Error); - } - - let tag_pos = $buffer.len() - Self::TagSize::to_usize(); - let (msg, tag) = $buffer.as_mut().split_at_mut(tag_pos); - $aead.decrypt_in_place_detached($nonce, $aad, msg, Tag::from_slice(tag))?; - $buffer.truncate(tag_pos); - Ok(()) - }}; -} - /// Key for a [`NewAead`] algorithm // TODO(tarcieri): make this a struct and zeroize on drop? pub type Key = GenericArray::KeySize>; @@ -91,6 +75,8 @@ pub trait NewAead { /// /// This trait is intended for use with stateless AEAD algorithms. The /// [`AeadMut`] trait provides a stateful interface. +#[cfg(feature = "alloc")] +#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] pub trait Aead { /// The length of a nonce. type NonceSize: ArrayLength; @@ -125,19 +111,105 @@ pub trait Aead { /// AES-GCM-SIV, ChaCha20Poly1305). [`Aead`] implementations which do not /// use a postfix tag will need to override this to correctly assemble the /// ciphertext message. - #[cfg(feature = "alloc")] - #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] fn encrypt<'msg, 'aad>( &self, nonce: &Nonce, plaintext: impl Into>, - ) -> Result, Error> { - let payload = plaintext.into(); - let mut buffer = Vec::with_capacity(payload.msg.len() + Self::TagSize::to_usize()); - buffer.extend_from_slice(payload.msg); - self.encrypt_in_place(nonce, payload.aad, &mut buffer)?; - Ok(buffer) - } + ) -> Result, Error>; + + /// Decrypt the given ciphertext slice, and return the resulting plaintext + /// as a vector of bytes. + /// + /// See notes on [`Aead::encrypt()`] about allowable message payloads and + /// Associated Additional Data (AAD). + /// + /// If you have no AAD, you can call this as follows: + /// + /// ```nobuild + /// let ciphertext = b"..."; + /// let plaintext = cipher.decrypt(nonce, ciphertext)?; + /// ``` + /// + /// The default implementation assumes a postfix tag (ala AES-GCM, + /// AES-GCM-SIV, ChaCha20Poly1305). [`Aead`] implementations which do not + /// use a postfix tag will need to override this to correctly parse the + /// ciphertext message. + fn decrypt<'msg, 'aad>( + &self, + nonce: &Nonce, + ciphertext: impl Into>, + ) -> Result, Error>; +} + +/// Stateful Authenticated Encryption with Associated Data algorithm. +#[cfg(feature = "alloc")] +#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] +pub trait AeadMut { + /// The length of a nonce. + type NonceSize: ArrayLength; + + /// The maximum length of the nonce. + type TagSize: ArrayLength; + + /// The upper bound amount of additional space required to support a + /// ciphertext vs. a plaintext. + type CiphertextOverhead: ArrayLength + Unsigned; + + /// Encrypt the given plaintext slice, and return the resulting ciphertext + /// as a vector of bytes. + /// + /// See notes on [`Aead::encrypt()`] about allowable message payloads and + /// Associated Additional Data (AAD). + fn encrypt<'msg, 'aad>( + &mut self, + nonce: &Nonce, + plaintext: impl Into>, + ) -> Result, Error>; + + /// Decrypt the given ciphertext slice, and return the resulting plaintext + /// as a vector of bytes. + /// + /// See notes on [`Aead::encrypt()`] and [`Aead::decrypt()`] about allowable + /// message payloads and Associated Additional Data (AAD). + fn decrypt<'msg, 'aad>( + &mut self, + nonce: &Nonce, + ciphertext: impl Into>, + ) -> Result, Error>; +} + +/// Implement the `decrypt_in_place` method on [`AeadInPlace`] and +/// [`AeadMutInPlace]`, using a macro to gloss over the `&self` vs `&mut self`. +/// +/// Assumes a postfix authentication tag. AEAD ciphers which do not use a +/// postfix authentication tag will need to define their own implementation. +macro_rules! impl_decrypt_in_place { + ($aead:expr, $nonce:expr, $aad:expr, $buffer:expr) => {{ + if $buffer.len() < Self::TagSize::to_usize() { + return Err(Error); + } + + let tag_pos = $buffer.len() - Self::TagSize::to_usize(); + let (msg, tag) = $buffer.as_mut().split_at_mut(tag_pos); + $aead.decrypt_in_place_detached($nonce, $aad, msg, Tag::from_slice(tag))?; + $buffer.truncate(tag_pos); + Ok(()) + }}; +} + +/// In-place stateless AEAD trait. +/// +/// This trait is both object safe and has no dependencies on `alloc` or `std`. +pub trait AeadInPlace { + /// The length of a nonce. + type NonceSize: ArrayLength; + + /// The maximum length of the nonce. + type TagSize: ArrayLength; + + /// The upper bound amount of additional space required to support a + /// ciphertext vs. a plaintext. + type CiphertextOverhead: ArrayLength + Unsigned; /// Encrypt the given buffer containing a plaintext message in-place. /// @@ -152,7 +224,7 @@ pub trait Aead { &self, nonce: &Nonce, associated_data: &[u8], - buffer: &mut impl Buffer, + buffer: &mut dyn Buffer, ) -> Result<(), Error> { let tag = self.encrypt_in_place_detached(nonce, associated_data, buffer.as_mut())?; buffer.extend_from_slice(tag.as_slice())?; @@ -165,37 +237,7 @@ pub trait Aead { nonce: &Nonce, associated_data: &[u8], buffer: &mut [u8], - ) -> Result, Error>; - - /// Decrypt the given ciphertext slice, and return the resulting plaintext - /// as a vector of bytes. - /// - /// See notes on [`Aead::encrypt()`] about allowable message payloads and - /// Associated Additional Data (AAD). - /// - /// If you have no AAD, you can call this as follows: - /// - /// ```nobuild - /// let ciphertext = b"..."; - /// let plaintext = cipher.decrypt(nonce, ciphertext)?; - /// ``` - /// - /// The default implementation assumes a postfix tag (ala AES-GCM, - /// AES-GCM-SIV, ChaCha20Poly1305). [`Aead`] implementations which do not - /// use a postfix tag will need to override this to correctly parse the - /// ciphertext message. - #[cfg(feature = "alloc")] - #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] - fn decrypt<'msg, 'aad>( - &self, - nonce: &Nonce, - ciphertext: impl Into>, - ) -> Result, Error> { - let payload = ciphertext.into(); - let mut buffer = Vec::from(payload.msg); - self.decrypt_in_place(nonce, payload.aad, &mut buffer)?; - Ok(buffer) - } + ) -> Result, Error>; /// Decrypt the message in-place, returning an error in the event the /// provided authentication tag does not match the given ciphertext. @@ -206,7 +248,7 @@ pub trait Aead { &self, nonce: &Nonce, associated_data: &[u8], - buffer: &mut impl Buffer, + buffer: &mut dyn Buffer, ) -> Result<(), Error> { impl_decrypt_in_place!(self, nonce, associated_data, buffer) } @@ -219,12 +261,14 @@ pub trait Aead { nonce: &Nonce, associated_data: &[u8], buffer: &mut [u8], - tag: &Tag, + tag: &Tag, ) -> Result<(), Error>; } -/// Stateful Authenticated Encryption with Associated Data algorithm. -pub trait AeadMut { +/// In-place stateful AEAD trait. +/// +/// This trait is both object safe and has no dependencies on `alloc` or `std`. +pub trait AeadMutInPlace { /// The length of a nonce. type NonceSize: ArrayLength; @@ -235,25 +279,6 @@ pub trait AeadMut { /// ciphertext vs. a plaintext. type CiphertextOverhead: ArrayLength + Unsigned; - /// Encrypt the given plaintext slice, and return the resulting ciphertext - /// as a vector of bytes. - /// - /// See notes on [`Aead::encrypt()`] about allowable message payloads and - /// Associated Additional Data (AAD). - #[cfg(feature = "alloc")] - #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] - fn encrypt<'msg, 'aad>( - &mut self, - nonce: &Nonce, - plaintext: impl Into>, - ) -> Result, Error> { - let payload = plaintext.into(); - let mut buffer = Vec::with_capacity(payload.msg.len() + Self::TagSize::to_usize()); - buffer.extend_from_slice(payload.msg); - self.encrypt_in_place(nonce, payload.aad, &mut buffer)?; - Ok(buffer) - } - /// Encrypt the given buffer containing a plaintext message in-place. /// /// The buffer must have sufficient capacity to store the ciphertext @@ -280,25 +305,7 @@ pub trait AeadMut { nonce: &Nonce, associated_data: &[u8], buffer: &mut [u8], - ) -> Result, Error>; - - /// Decrypt the given ciphertext slice, and return the resulting plaintext - /// as a vector of bytes. - /// - /// See notes on [`Aead::encrypt()`] and [`Aead::decrypt()`] about allowable - /// message payloads and Associated Additional Data (AAD). - #[cfg(feature = "alloc")] - #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] - fn decrypt<'msg, 'aad>( - &mut self, - nonce: &Nonce, - ciphertext: impl Into>, - ) -> Result, Error> { - let payload = ciphertext.into(); - let mut buffer = Vec::from(payload.msg); - self.decrypt_in_place(nonce, payload.aad, &mut buffer)?; - Ok(buffer) - } + ) -> Result, Error>; /// Decrypt the message in-place, returning an error in the event the /// provided authentication tag does not match the given ciphertext. @@ -322,81 +329,110 @@ pub trait AeadMut { nonce: &Nonce, associated_data: &[u8], buffer: &mut [u8], - tag: &Tag, + tag: &Tag, ) -> Result<(), Error>; } -/// A blanket implementation of the Stateful AEAD interface for Stateless -/// AEAD implementations. -impl AeadMut for Algo { - type NonceSize = Algo::NonceSize; - type TagSize = Algo::TagSize; - type CiphertextOverhead = Algo::CiphertextOverhead; +#[cfg(feature = "alloc")] +impl Aead for Alg { + type NonceSize = Alg::NonceSize; + type TagSize = Alg::TagSize; + type CiphertextOverhead = Alg::CiphertextOverhead; + + fn encrypt<'msg, 'aad>( + &self, + nonce: &Nonce, + plaintext: impl Into>, + ) -> Result, Error> { + let payload = plaintext.into(); + let mut buffer = Vec::with_capacity(payload.msg.len() + Self::TagSize::to_usize()); + buffer.extend_from_slice(payload.msg); + self.encrypt_in_place(nonce, payload.aad, &mut buffer)?; + Ok(buffer) + } + + fn decrypt<'msg, 'aad>( + &self, + nonce: &Nonce, + ciphertext: impl Into>, + ) -> Result, Error> { + let payload = ciphertext.into(); + let mut buffer = Vec::from(payload.msg); + self.decrypt_in_place(nonce, payload.aad, &mut buffer)?; + Ok(buffer) + } +} + +#[cfg(feature = "alloc")] +impl AeadMut for Alg { + type NonceSize = Alg::NonceSize; + type TagSize = Alg::TagSize; + type CiphertextOverhead = Alg::CiphertextOverhead; - /// Encrypt the given plaintext slice, and return the resulting ciphertext - /// as a vector of bytes. - #[cfg(feature = "alloc")] fn encrypt<'msg, 'aad>( &mut self, nonce: &Nonce, plaintext: impl Into>, ) -> Result, Error> { - ::encrypt(self, nonce, plaintext) + let payload = plaintext.into(); + let mut buffer = Vec::with_capacity(payload.msg.len() + Self::TagSize::to_usize()); + buffer.extend_from_slice(payload.msg); + self.encrypt_in_place(nonce, payload.aad, &mut buffer)?; + Ok(buffer) } - /// Encrypt the given buffer containing a plaintext message in-place. + fn decrypt<'msg, 'aad>( + &mut self, + nonce: &Nonce, + ciphertext: impl Into>, + ) -> Result, Error> { + let payload = ciphertext.into(); + let mut buffer = Vec::from(payload.msg); + self.decrypt_in_place(nonce, payload.aad, &mut buffer)?; + Ok(buffer) + } +} + +impl AeadMutInPlace for Alg { + type NonceSize = Alg::NonceSize; + type TagSize = Alg::TagSize; + type CiphertextOverhead = Alg::CiphertextOverhead; + fn encrypt_in_place( &mut self, nonce: &Nonce, associated_data: &[u8], buffer: &mut impl Buffer, ) -> Result<(), Error> { - ::encrypt_in_place(self, nonce, associated_data, buffer) + ::encrypt_in_place(self, nonce, associated_data, buffer) } - /// Encrypt the data in-place, returning the authentication tag fn encrypt_in_place_detached( &mut self, nonce: &Nonce, associated_data: &[u8], buffer: &mut [u8], - ) -> Result, Error> { - ::encrypt_in_place_detached(self, nonce, associated_data, buffer) - } - - /// Decrypt the given ciphertext slice, and return the resulting plaintext - /// as a vector of bytes. - #[cfg(feature = "alloc")] - fn decrypt<'msg, 'aad>( - &mut self, - nonce: &Nonce, - ciphertext: impl Into>, - ) -> Result, Error> { - ::decrypt(self, nonce, ciphertext) + ) -> Result, Error> { + ::encrypt_in_place_detached(self, nonce, associated_data, buffer) } - /// Decrypt the message in-place, returning an error in the event the - /// provided authentication tag does not match the given ciphertext. fn decrypt_in_place( &mut self, nonce: &Nonce, associated_data: &[u8], buffer: &mut impl Buffer, ) -> Result<(), Error> { - ::decrypt_in_place(self, nonce, associated_data, buffer) + ::decrypt_in_place(self, nonce, associated_data, buffer) } - /// Decrypt the data in-place, returning an error in the event the provided - /// authentication tag does not match the given ciphertext (i.e. ciphertext - /// is modified/unauthentic) fn decrypt_in_place_detached( &mut self, nonce: &Nonce, associated_data: &[u8], buffer: &mut [u8], - tag: &Tag, + tag: &Tag, ) -> Result<(), Error> { - ::decrypt_in_place_detached(self, nonce, associated_data, buffer, tag) + ::decrypt_in_place_detached(self, nonce, associated_data, buffer, tag) } } @@ -406,6 +442,8 @@ impl AeadMut for Algo { /// /// If you don't care about AAD, you can pass a `&[u8]` as the payload to /// `encrypt`/`decrypt` and it will automatically be coerced to this type. +#[cfg(feature = "alloc")] +#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] pub struct Payload<'msg, 'aad> { /// Message to be encrypted/decrypted pub msg: &'msg [u8], @@ -417,6 +455,7 @@ pub struct Payload<'msg, 'aad> { pub aad: &'aad [u8], } +#[cfg(feature = "alloc")] impl<'msg, 'aad> From<&'msg [u8]> for Payload<'msg, 'aad> { fn from(msg: &'msg [u8]) -> Self { Self { msg, aad: b"" } @@ -470,3 +509,18 @@ where heapless::Vec::truncate(self, len); } } + +#[cfg(test)] +mod tests { + use super::*; + + /// Ensure that `AeadInPlace` is object-safe + #[allow(dead_code)] + type DynAeadInPlace = + dyn AeadInPlace; + + /// Ensure that `AeadMutInPlace` is object-safe + #[allow(dead_code)] + type DynAeadMutInPlace = + dyn AeadMutInPlace; +} From 93ab1450613a0b39887f95a98a82388ce0a0a90f Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 24 May 2020 08:09:11 -0700 Subject: [PATCH 0084/1461] block-cipher-trait: split out NewBlockCipher trait As requested on #43, this splits out a `NewBlockCipher` trait from the original `BlockCipher` trait. --- block-cipher-trait/src/lib.rs | 42 ++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/block-cipher-trait/src/lib.rs b/block-cipher-trait/src/lib.rs index 11e2a555a..c5399ebc1 100644 --- a/block-cipher-trait/src/lib.rs +++ b/block-cipher-trait/src/lib.rs @@ -20,21 +20,22 @@ pub use generic_array::{self, typenum::consts}; use generic_array::typenum::Unsigned; use generic_array::{ArrayLength, GenericArray}; -type ParBlocks = GenericArray, P>; +/// Key for an algorithm that implements [`NewBlockCipher`]. +pub type Key = GenericArray::KeySize>; -/// The trait which defines in-place encryption and decryption -/// over single block or several blocks in parallel. -pub trait BlockCipher: core::marker::Sized { - /// Key size in bytes with which cipher guaranteed to be initialized +/// Block on which a [`BlockCipher`] operates. +pub type Block = GenericArray::BlockSize>; + +/// Blocks being acted over in parallel. +pub type ParBlocks = GenericArray, ::ParBlocks>; + +/// Instantiate a `BlockCipher` algorithm. +pub trait NewBlockCipher: Sized { + /// Key size in bytes with which cipher guaranteed to be initialized. type KeySize: ArrayLength; - /// Size of the block in bytes - type BlockSize: ArrayLength; - /// Number of blocks which can be processed in parallel by - /// cipher implementation - type ParBlocks: ArrayLength>; /// Create new block cipher instance from key with fixed size. - fn new(key: &GenericArray) -> Self; + fn new(key: &Key) -> Self; /// Create new block cipher instance from key with variable size. /// @@ -47,19 +48,30 @@ pub trait BlockCipher: core::marker::Sized { Ok(Self::new(GenericArray::from_slice(key))) } } +} + +/// The trait which defines in-place encryption and decryption +/// over single block or several blocks in parallel. +pub trait BlockCipher { + /// Size of the block in bytes + type BlockSize: ArrayLength; + + /// Number of blocks which can be processed in parallel by + /// cipher implementation + type ParBlocks: ArrayLength>; /// Encrypt block in-place - fn encrypt_block(&self, block: &mut GenericArray); + fn encrypt_block(&self, block: &mut Block); /// Decrypt block in-place - fn decrypt_block(&self, block: &mut GenericArray); + fn decrypt_block(&self, block: &mut Block); /// Encrypt several blocks in parallel using instruction level parallelism /// if possible. /// /// If `ParBlocks` equals to 1 it's equivalent to `encrypt_block`. #[inline] - fn encrypt_blocks(&self, blocks: &mut ParBlocks) { + fn encrypt_blocks(&self, blocks: &mut ParBlocks) { for block in blocks.iter_mut() { self.encrypt_block(block); } @@ -70,7 +82,7 @@ pub trait BlockCipher: core::marker::Sized { /// /// If `ParBlocks` equals to 1 it's equivalent to `decrypt_block`. #[inline] - fn decrypt_blocks(&self, blocks: &mut ParBlocks) { + fn decrypt_blocks(&self, blocks: &mut ParBlocks) { for block in blocks.iter_mut() { self.decrypt_block(block); } From 83ae496a450cabc866c3dc16cbc7ba84b8da10be Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 24 May 2020 08:27:05 -0700 Subject: [PATCH 0085/1461] mac: split out NewMac trait --- block-cipher-trait/src/lib.rs | 2 +- crypto-mac/src/lib.rs | 49 ++++++++++++++++------------------- 2 files changed, 24 insertions(+), 27 deletions(-) diff --git a/block-cipher-trait/src/lib.rs b/block-cipher-trait/src/lib.rs index c5399ebc1..7c232de04 100644 --- a/block-cipher-trait/src/lib.rs +++ b/block-cipher-trait/src/lib.rs @@ -29,7 +29,7 @@ pub type Block = GenericArray::BlockSize>; /// Blocks being acted over in parallel. pub type ParBlocks = GenericArray, ::ParBlocks>; -/// Instantiate a `BlockCipher` algorithm. +/// Instantiate a [`BlockCipher`] algorithm. pub trait NewBlockCipher: Sized { /// Key size in bytes with which cipher guaranteed to be initialized. type KeySize: ArrayLength; diff --git a/crypto-mac/src/lib.rs b/crypto-mac/src/lib.rs index 4c04c3ad4..fa348fedf 100644 --- a/crypto-mac/src/lib.rs +++ b/crypto-mac/src/lib.rs @@ -20,16 +20,16 @@ use generic_array::typenum::Unsigned; use generic_array::{ArrayLength, GenericArray}; use subtle::{Choice, ConstantTimeEq}; -/// The [`Mac`] trait defines methods for a Message Authentication algorithm. -pub trait Mac: Clone { - /// Output size of the [[`Mac`]] - type OutputSize: ArrayLength; +/// Key for an algorithm that implements [`NewMac`]. +pub type Key = GenericArray::KeySize>; - /// Keys size of the [[`Mac`]] +/// Instantiate a [`Mac`] algorithm. +pub trait NewMac: Sized { + /// Key size in bytes with which cipher guaranteed to be initialized. type KeySize: ArrayLength; /// Initialize new MAC instance from key with fixed size. - fn new(key: &GenericArray) -> Self; + fn new(key: &Key) -> Self; /// Initialize new MAC instance from key with variable size. /// @@ -42,6 +42,12 @@ pub trait Mac: Clone { Ok(Self::new(GenericArray::from_slice(key))) } } +} + +/// The [`Mac`] trait defines methods for a Message Authentication algorithm. +pub trait Mac: Clone { + /// Output size of the [[`Mac`]] + type OutputSize: ArrayLength; /// Update MAC state with the given data. fn update(&mut self, data: &[u8]); @@ -51,11 +57,11 @@ pub trait Mac: Clone { /// Obtain the result of a [`Mac`] computation as a [`Output`] and consume /// [`Mac`] instance. - fn result(self) -> Output; + fn result(self) -> Output; /// Obtain the result of a [`Mac`] computation as a [`Output`] and reset /// [`Mac`] instance. - fn result_reset(&mut self) -> Output { + fn result_reset(&mut self) -> Output { let res = self.clone().result(); self.reset(); res @@ -75,16 +81,13 @@ pub trait Mac: Clone { /// [`Output`] is a thin wrapper around bytes array which provides a safe `Eq` /// implementation that runs in a fixed time. #[derive(Clone)] -pub struct Output> { - code: GenericArray, +pub struct Output { + code: GenericArray, } -impl Output -where - N: ArrayLength, -{ +impl Output { /// Create a new MAC [`Output`]. - pub fn new(code: GenericArray) -> Output { + pub fn new(code: GenericArray) -> Output { Output { code } } @@ -93,27 +96,21 @@ where /// Be very careful using this method, since incorrect use of the code value /// may permit timing attacks which defeat the security provided by the /// [`Mac`] trait. - pub fn into_bytes(self) -> GenericArray { + pub fn into_bytes(self) -> GenericArray { self.code } } -impl ConstantTimeEq for Output -where - N: ArrayLength, -{ +impl ConstantTimeEq for Output { fn ct_eq(&self, other: &Self) -> Choice { self.code.ct_eq(&other.code) } } -impl PartialEq for Output -where - N: ArrayLength, -{ - fn eq(&self, x: &Output) -> bool { +impl PartialEq for Output { + fn eq(&self, x: &Output) -> bool { self.ct_eq(x).unwrap_u8() == 1 } } -impl Eq for Output where N: ArrayLength {} +impl Eq for Output {} From ba58937f14c25a0b1d37584c9aa7d73f17f2bd99 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 24 May 2020 08:40:47 -0700 Subject: [PATCH 0086/1461] crypto-mac: add `impl_write!` macro As discussed on #43, similar to the one in `digest`. --- crypto-mac/src/lib.rs | 18 ++++++++++++++++++ digest/src/lib.rs | 2 -- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/crypto-mac/src/lib.rs b/crypto-mac/src/lib.rs index fa348fedf..7a0d143fd 100644 --- a/crypto-mac/src/lib.rs +++ b/crypto-mac/src/lib.rs @@ -114,3 +114,21 @@ impl PartialEq for Output { } impl Eq for Output {} + +#[macro_export] +/// Implements `std::io::Write` trait for implementer of [`Mac`] +macro_rules! impl_write { + ($mac:ident) => { + #[cfg(feature = "std")] + impl std::io::Write for $mac { + fn write(&mut self, buf: &[u8]) -> std::io::Result { + Mac::update(self, buf); + Ok(buf.len()) + } + + fn flush(&mut self) -> std::io::Result<()> { + Ok(()) + } + } + }; +} diff --git a/digest/src/lib.rs b/digest/src/lib.rs index ceb5186ec..8b322a8d8 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -139,8 +139,6 @@ pub trait Reset { fn reset(&mut self); } -#[cfg(feature = "std")] -#[cfg_attr(docsrs, doc(cfg(feature = "std")))] #[macro_export] /// Implements `std::io::Write` trait for implementer of [`Update`] macro_rules! impl_write { From c21d68cbd7a7d0de8bc64d48725b2838eec9fa84 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 24 May 2020 08:50:30 -0700 Subject: [PATCH 0087/1461] universal-hash: split out NewUniversalHash trait --- universal-hash/src/lib.rs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/universal-hash/src/lib.rs b/universal-hash/src/lib.rs index cfb382983..9976a3d66 100644 --- a/universal-hash/src/lib.rs +++ b/universal-hash/src/lib.rs @@ -30,23 +30,26 @@ use generic_array::{ArrayLength, GenericArray}; use subtle::{Choice, ConstantTimeEq}; /// Keys to a [`UniversalHash`]. -pub type Key = GenericArray::KeySize>; +pub type Key = GenericArray::KeySize>; /// Blocks are inputs to a [`UniversalHash`]. pub type Block = GenericArray::BlockSize>; -/// The `UniversalHash` trait defines a generic interface for universal hash -/// functions. -pub trait UniversalHash: Clone { - /// Size of the key for the universal hash function +/// Instantiate a [`UniversalHash`] algorithm. +pub trait NewUniversalHash: Sized { + /// Size of the key for the universal hash function. type KeySize: ArrayLength; + /// Instantiate a universal hash function with the given key. + fn new(key: &Key) -> Self; +} + +/// The [`UniversalHash`] trait defines a generic interface for universal hash +/// functions. +pub trait UniversalHash: Clone { /// Size of the inputs to and outputs from the universal hash function type BlockSize: ArrayLength; - /// Instantiate a universal hash function with the given key - fn new(key: &Key) -> Self; - /// Input a block into the universal hash function fn update(&mut self, block: &Block); From 253e5c92bc1c3d7453e461f1cf7e1bcef1a2eb41 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 24 May 2020 13:44:58 -0700 Subject: [PATCH 0088/1461] Bump all crates to `-pre` versions This commit does an across-the-board version bump of all traits, since they've all been migrated (vicariously) to `generic-array` v0.14. There's no intention of releasing them yet, and if I do release preleases they'll be as `-pre.0` and so forth. This just makes it clear what's presently on HEAD is very much SemVer incompatible with the current releases. After this, I'll try updating the various repos which consume these traits to use the latest git versions of these crates before cutting a final release. --- Cargo.lock | 28 ++++++++++++++-------------- aead/Cargo.toml | 2 +- block-cipher-trait/Cargo.toml | 2 +- crypto-mac/Cargo.toml | 2 +- digest/Cargo.toml | 2 +- signature/Cargo.toml | 5 +++-- signature/src/lib.rs | 2 +- stream-cipher/Cargo.toml | 2 +- universal-hash/Cargo.toml | 2 +- 9 files changed, 24 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 42f6afa6b..02d6a029c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,7 +2,7 @@ # It is not intended for manual editing. [[package]] name = "aead" -version = "0.2.0" +version = "0.3.0-pre" dependencies = [ "generic-array 0.14.1", "heapless", @@ -42,7 +42,7 @@ dependencies = [ [[package]] name = "block-cipher-trait" -version = "0.6.2" +version = "0.7.0-pre" dependencies = [ "blobby", "generic-array 0.14.1", @@ -71,7 +71,7 @@ checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" [[package]] name = "crypto-mac" -version = "0.8.0" +version = "0.9.0-pre" dependencies = [ "blobby", "generic-array 0.13.2", @@ -81,18 +81,18 @@ dependencies = [ [[package]] name = "digest" version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" dependencies = [ - "blobby", - "generic-array 0.14.1", + "generic-array 0.12.3", ] [[package]] name = "digest" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" +version = "0.9.0-pre" dependencies = [ - "generic-array 0.12.3", + "blobby", + "generic-array 0.14.1", ] [[package]] @@ -211,16 +211,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "27044adfd2e1f077f649f59deb9490d3941d674002f7d062870a60ebe9bd47a0" dependencies = [ "block-buffer", - "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.8.1", "fake-simd", "opaque-debug", ] [[package]] name = "signature" -version = "1.0.1" +version = "1.1.0-pre" dependencies = [ - "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.9.0-pre", "hex-literal", "rand_core", "sha2", @@ -245,7 +245,7 @@ checksum = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" [[package]] name = "stream-cipher" -version = "0.3.2" +version = "0.4.0-pre" dependencies = [ "blobby", "generic-array 0.14.1", @@ -294,7 +294,7 @@ checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" [[package]] name = "universal-hash" -version = "0.3.0" +version = "0.4.0-pre" dependencies = [ "generic-array 0.14.1", "subtle", diff --git a/aead/Cargo.toml b/aead/Cargo.toml index 6b4700421..d433dc74c 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aead" -version = "0.2.0" +version = "0.3.0-pre" authors = ["RustCrypto Developers"] edition = "2018" license = "MIT OR Apache-2.0" diff --git a/block-cipher-trait/Cargo.toml b/block-cipher-trait/Cargo.toml index 7aff48624..41b9df875 100644 --- a/block-cipher-trait/Cargo.toml +++ b/block-cipher-trait/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "block-cipher-trait" description = "Traits for description of block ciphers" -version = "0.6.2" +version = "0.7.0-pre" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/crypto-mac/Cargo.toml b/crypto-mac/Cargo.toml index 06ef469fb..b8353318a 100644 --- a/crypto-mac/Cargo.toml +++ b/crypto-mac/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crypto-mac" description = "Trait for Message Authentication Code (MAC) algorithms" -version = "0.8.0" +version = "0.9.0-pre" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 9dffdff5a..f18cd93c1 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "digest" description = "Traits for cryptographic hash functions" -version = "0.8.1" +version = "0.9.0-pre" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/signature/Cargo.toml b/signature/Cargo.toml index fdc093a61..0f4b835f8 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "1.0.1" # Also update html_root_url in lib.rs when bumping this +version = "1.1.0-pre" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/signature" @@ -12,9 +12,10 @@ keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"] categories = ["cryptography", "no-std"] [dependencies.digest] -version = "0.8" +version = "= 0.9.0-pre" optional = true default-features = false +path = "../digest" [dependencies.rand_core] version = "0.5" diff --git a/signature/src/lib.rs b/signature/src/lib.rs index 3c90fa105..2895b6b44 100644 --- a/signature/src/lib.rs +++ b/signature/src/lib.rs @@ -155,7 +155,7 @@ #![cfg_attr(docsrs, feature(doc_cfg))] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/ferris_signer.png", - html_root_url = "https://docs.rs/signature/1.0.1" + html_root_url = "https://docs.rs/signature/1.1.0-pre" )] #![forbid(unsafe_code)] #![warn( diff --git a/stream-cipher/Cargo.toml b/stream-cipher/Cargo.toml index 81061ca39..f127c9a01 100644 --- a/stream-cipher/Cargo.toml +++ b/stream-cipher/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "stream-cipher" description = "Stream cipher traits" -version = "0.3.2" +version = "0.4.0-pre" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/universal-hash/Cargo.toml b/universal-hash/Cargo.toml index 78d803493..963e01773 100644 --- a/universal-hash/Cargo.toml +++ b/universal-hash/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "universal-hash" -version = "0.3.0" +version = "0.4.0-pre" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" description = "Trait for universal hash functions" From 9df157e2de998b270f7b0b29bca9362db588df96 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 25 May 2020 08:44:43 +0000 Subject: [PATCH 0089/1461] build(deps): bump sha2 from 0.8.1 to 0.8.2 Bumps [sha2](https://github.com/RustCrypto/hashes) from 0.8.1 to 0.8.2. - [Release notes](https://github.com/RustCrypto/hashes/releases) - [Commits](https://github.com/RustCrypto/hashes/compare/sha2-v0.8.1...sha2-v0.8.2) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 02d6a029c..6533240a0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -206,9 +206,9 @@ checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" [[package]] name = "sha2" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27044adfd2e1f077f649f59deb9490d3941d674002f7d062870a60ebe9bd47a0" +checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69" dependencies = [ "block-buffer", "digest 0.8.1", From cab9b3b2f4b534a1c76e1d331e5ded686e7ebc18 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 26 May 2020 12:03:10 -0700 Subject: [PATCH 0090/1461] Rename `block-cipher-trait` => `block-cipher` This is more consistent with the other RustCrypto/traits crates, as well as shorter and more convenient. --- .../{block-cipher-trait.yml => block-cipher.yml} | 10 +++++----- Cargo.lock | 2 +- Cargo.toml | 2 +- README.md | 4 ++-- {block-cipher-trait => block-cipher}/Cargo.toml | 4 ++-- {block-cipher-trait => block-cipher}/LICENSE-APACHE | 0 {block-cipher-trait => block-cipher}/LICENSE-MIT | 0 {block-cipher-trait => block-cipher}/README.md | 12 ++++++------ {block-cipher-trait => block-cipher}/src/dev.rs | 0 {block-cipher-trait => block-cipher}/src/errors.rs | 0 {block-cipher-trait => block-cipher}/src/lib.rs | 0 11 files changed, 17 insertions(+), 17 deletions(-) rename .github/workflows/{block-cipher-trait.yml => block-cipher.yml} (85%) rename {block-cipher-trait => block-cipher}/Cargo.toml (86%) rename {block-cipher-trait => block-cipher}/LICENSE-APACHE (100%) rename {block-cipher-trait => block-cipher}/LICENSE-MIT (100%) rename {block-cipher-trait => block-cipher}/README.md (83%) rename {block-cipher-trait => block-cipher}/src/dev.rs (100%) rename {block-cipher-trait => block-cipher}/src/errors.rs (100%) rename {block-cipher-trait => block-cipher}/src/lib.rs (100%) diff --git a/.github/workflows/block-cipher-trait.yml b/.github/workflows/block-cipher.yml similarity index 85% rename from .github/workflows/block-cipher-trait.yml rename to .github/workflows/block-cipher.yml index e138aa54f..17a6dc352 100644 --- a/.github/workflows/block-cipher-trait.yml +++ b/.github/workflows/block-cipher.yml @@ -1,14 +1,14 @@ -name: block-cipher-trait +name: block-cipher on: pull_request: paths: - - "block-cipher-trait/**" + - "block-cipher/**" - "Cargo.*" push: branches: master paths: - - "block-cipher-trait/**" + - "block-cipher/**" - "Cargo.*" jobs: @@ -30,7 +30,7 @@ jobs: toolchain: ${{ matrix.rust }} target: ${{ matrix.target }} override: true - - working-directory: block-cipher-trait + - working-directory: block-cipher run: cargo build --no-default-features --release --target ${{ matrix.target }} test: runs-on: ubuntu-latest @@ -50,4 +50,4 @@ jobs: cargo test --features dev cargo test --features std cargo test --all-features - working-directory: block-cipher-trait + working-directory: block-cipher diff --git a/Cargo.lock b/Cargo.lock index 6533240a0..b385c1c1f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -41,7 +41,7 @@ dependencies = [ ] [[package]] -name = "block-cipher-trait" +name = "block-cipher" version = "0.7.0-pre" dependencies = [ "blobby", diff --git a/Cargo.toml b/Cargo.toml index 421cdb5cd..888dea812 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [workspace] members = [ "aead", - "block-cipher-trait", + "block-cipher", "crypto-mac", "digest", "signature", diff --git a/README.md b/README.md index 1b45ed3f1..ecfac1fe9 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Collection of traits which describe functionality of cryptographic primitives. | Name | Algorithm | Crates.io | Documentation | Build | |--------------------|-------------------------------|-----------|----------------|-------| | [`aead`] | [Authenticated encryption] | [![crates.io](https://img.shields.io/crates/v/aead.svg)](https://crates.io/crates/aead) | [![Documentation](https://docs.rs/aead/badge.svg)](https://docs.rs/aead) | ![build](https://github.com/RustCrypto/traits/workflows/aead/badge.svg?branch=master&event=push) | -| [`block-cipher-trait`] | [Block cipher] | [![crates.io](https://img.shields.io/crates/v/block-cipher-trait.svg)](https://crates.io/crates/block-cipher-trait) | [![Documentation](https://docs.rs/block-cipher-trait/badge.svg)](https://docs.rs/block-cipher-trait) | ![build](https://github.com/RustCrypto/traits/workflows/block-cipher-trait/badge.svg?branch=master&event=push) | +| [`block-cipher`] | [Block cipher] | [![crates.io](https://img.shields.io/crates/v/block-cipher.svg)](https://crates.io/crates/block-cipher) | [![Documentation](https://docs.rs/block-cipher/badge.svg)](https://docs.rs/block-cipher) | ![build](https://github.com/RustCrypto/traits/workflows/block-cipher/badge.svg?branch=master&event=push) | | [`crypto-mac`] | [Message authentication code] | [![crates.io](https://img.shields.io/crates/v/crypto-mac.svg)](https://crates.io/crates/crypto-mac) | [![Documentation](https://docs.rs/crypto-mac/badge.svg)](https://docs.rs/crypto-mac) | ![build](https://github.com/RustCrypto/traits/workflows/crypto-mac/badge.svg?branch=master&event=push) | | [`digest`] | [Cryptographic hash function] | [![crates.io](https://img.shields.io/crates/v/digest.svg)](https://crates.io/crates/digest) | [![Documentation](https://docs.rs/digest/badge.svg)](https://docs.rs/digest) | ![build](https://github.com/RustCrypto/traits/workflows/digest/badge.svg?branch=master&event=push) | | [`signature`] | [Digital signature] | [![crates.io](https://img.shields.io/crates/v/signature.svg)](https://crates.io/crates/signature) | [![Documentation](https://docs.rs/signature/badge.svg)](https://docs.rs/signature) | ![build](https://github.com/RustCrypto/traits/workflows/signature/badge.svg?branch=master&event=push) | @@ -43,7 +43,7 @@ dual licensed as above, without any additional terms or conditions. [//]: # (crates) [`aead`]: https://github.com/RustCrypto/traits/tree/master/aead -[`block-cipher-trait`]: https://github.com/RustCrypto/traits/tree/master/block-cipher-trait +[`block-cipher`]: https://github.com/RustCrypto/traits/tree/master/block-cipher [`crypto-mac`]: https://github.com/RustCrypto/traits/tree/master/crypto-mac [`digest`]: https://github.com/RustCrypto/traits/tree/master/digest [`signature`]: https://github.com/RustCrypto/traits/tree/master/signature diff --git a/block-cipher-trait/Cargo.toml b/block-cipher/Cargo.toml similarity index 86% rename from block-cipher-trait/Cargo.toml rename to block-cipher/Cargo.toml index 41b9df875..a74a8842b 100644 --- a/block-cipher-trait/Cargo.toml +++ b/block-cipher/Cargo.toml @@ -1,12 +1,12 @@ [package] -name = "block-cipher-trait" +name = "block-cipher" description = "Traits for description of block ciphers" version = "0.7.0-pre" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" edition = "2018" -documentation = "https://docs.rs/block-cipher-trait" +documentation = "https://docs.rs/block-cipher" repository = "https://github.com/RustCrypto/traits" keywords = ["crypto", "block-cipher", "trait"] categories = ["cryptography", "no-std"] diff --git a/block-cipher-trait/LICENSE-APACHE b/block-cipher/LICENSE-APACHE similarity index 100% rename from block-cipher-trait/LICENSE-APACHE rename to block-cipher/LICENSE-APACHE diff --git a/block-cipher-trait/LICENSE-MIT b/block-cipher/LICENSE-MIT similarity index 100% rename from block-cipher-trait/LICENSE-MIT rename to block-cipher/LICENSE-MIT diff --git a/block-cipher-trait/README.md b/block-cipher/README.md similarity index 83% rename from block-cipher-trait/README.md rename to block-cipher/README.md index 5ab97ef6b..553989fa4 100644 --- a/block-cipher-trait/README.md +++ b/block-cipher/README.md @@ -41,14 +41,14 @@ dual licensed as above, without any additional terms or conditions. [//]: # (badges) -[crate-image]: https://img.shields.io/crates/v/block-cipher-trait.svg -[crate-link]: https://crates.io/crates/block-cipher-trait -[docs-image]: https://docs.rs/block-cipher-trait/badge.svg -[docs-link]: https://docs.rs/block-cipher-trait/ +[crate-image]: https://img.shields.io/crates/v/block-cipher.svg +[crate-link]: https://crates.io/crates/block-cipher +[docs-image]: https://docs.rs/block-cipher/badge.svg +[docs-link]: https://docs.rs/block-cipher/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg [rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg -[build-image]: https://github.com/RustCrypto/traits/workflows/block-cipher-trait/badge.svg?branch=master&event=push -[build-link]: https://github.com/RustCrypto/traits/actions?query=workflow%3Ablock-cipher-trait +[build-image]: https://github.com/RustCrypto/traits/workflows/block-cipher/badge.svg?branch=master&event=push +[build-link]: https://github.com/RustCrypto/traits/actions?query=workflow%3Ablock-cipher [//]: # (general links) diff --git a/block-cipher-trait/src/dev.rs b/block-cipher/src/dev.rs similarity index 100% rename from block-cipher-trait/src/dev.rs rename to block-cipher/src/dev.rs diff --git a/block-cipher-trait/src/errors.rs b/block-cipher/src/errors.rs similarity index 100% rename from block-cipher-trait/src/errors.rs rename to block-cipher/src/errors.rs diff --git a/block-cipher-trait/src/lib.rs b/block-cipher/src/lib.rs similarity index 100% rename from block-cipher-trait/src/lib.rs rename to block-cipher/src/lib.rs From 95718c3bdab81effe856d74a04c185f92c6d794e Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 26 May 2020 14:23:43 -0700 Subject: [PATCH 0091/1461] block-cipher: fix test macros These didn't get properly updated when the crate was renamed --- block-cipher/src/dev.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/block-cipher/src/dev.rs b/block-cipher/src/dev.rs index d60cf7cc5..9567c6dbf 100644 --- a/block-cipher/src/dev.rs +++ b/block-cipher/src/dev.rs @@ -6,10 +6,10 @@ macro_rules! new_test { ($name:ident, $test_name:expr, $cipher:ty) => { #[test] fn $name() { - use block_cipher_trait::blobby::Blob3Iterator; - use block_cipher_trait::generic_array::typenum::Unsigned; - use block_cipher_trait::generic_array::GenericArray; - use block_cipher_trait::BlockCipher; + use block_cipher::blobby::Blob3Iterator; + use block_cipher::generic_array::typenum::Unsigned; + use block_cipher::generic_array::GenericArray; + use block_cipher::BlockCipher; fn run_test(key: &[u8], pt: &[u8], ct: &[u8]) -> bool { let state = <$cipher as BlockCipher>::new_varkey(key).unwrap(); @@ -111,7 +111,7 @@ macro_rules! bench { ($cipher:path, $key_len:expr) => { extern crate test; - use block_cipher_trait::BlockCipher; + use block_cipher::BlockCipher; use test::Bencher; #[bench] From 7737dd58a234f460a0b3fd1f44e5e8ad0393e7d8 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 26 May 2020 14:38:50 -0700 Subject: [PATCH 0092/1461] block-cipher: more test macro fixups --- block-cipher/src/dev.rs | 10 +++++----- block-cipher/src/lib.rs | 3 +++ 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/block-cipher/src/dev.rs b/block-cipher/src/dev.rs index 9567c6dbf..ea1390694 100644 --- a/block-cipher/src/dev.rs +++ b/block-cipher/src/dev.rs @@ -9,10 +9,10 @@ macro_rules! new_test { use block_cipher::blobby::Blob3Iterator; use block_cipher::generic_array::typenum::Unsigned; use block_cipher::generic_array::GenericArray; - use block_cipher::BlockCipher; + use block_cipher::{BlockCipher, NewBlockCipher}; fn run_test(key: &[u8], pt: &[u8], ct: &[u8]) -> bool { - let state = <$cipher as BlockCipher>::new_varkey(key).unwrap(); + let state = <$cipher as NewBlockCipher>::new_varkey(key).unwrap(); let mut block = GenericArray::clone_from_slice(pt); state.encrypt_block(&mut block); @@ -34,7 +34,7 @@ macro_rules! new_test { type Block = GenericArray; type ParBlock = GenericArray; - let state = <$cipher as BlockCipher>::new_varkey(key).unwrap(); + let state = <$cipher as NewBlockCipher>::new_varkey(key).unwrap(); let block = Block::clone_from_slice(pt); let mut blocks1 = ParBlock::default(); @@ -100,7 +100,7 @@ macro_rules! new_test { } // test if cipher can be cloned let key = Default::default(); - let _ = <$cipher as BlockCipher>::new(&key).clone(); + let _ = <$cipher as NewBlockCipher>::new(&key).clone(); } }; } @@ -111,7 +111,7 @@ macro_rules! bench { ($cipher:path, $key_len:expr) => { extern crate test; - use block_cipher::BlockCipher; + use block_cipher::{BlockCipher, NewBlockCipher}; use test::Bencher; #[bench] diff --git a/block-cipher/src/lib.rs b/block-cipher/src/lib.rs index 7c232de04..1e606060a 100644 --- a/block-cipher/src/lib.rs +++ b/block-cipher/src/lib.rs @@ -12,6 +12,9 @@ extern crate std; #[cfg(feature = "dev")] pub mod dev; +#[cfg(feature = "dev")] +pub use blobby; + mod errors; pub use crate::errors::InvalidKeyLength; From 214c70067dc12b9d9c1d1d687df11c7ff5f1ff40 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 26 May 2020 15:36:05 -0700 Subject: [PATCH 0093/1461] block-cipher/stream-cipher: more dev fixes Re-exports blobby under the `dev` module in each crate, and updates the macros to use that. --- block-cipher/src/dev.rs | 4 +++- block-cipher/src/lib.rs | 3 --- stream-cipher/src/dev.rs | 8 +++++--- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/block-cipher/src/dev.rs b/block-cipher/src/dev.rs index ea1390694..7389b6434 100644 --- a/block-cipher/src/dev.rs +++ b/block-cipher/src/dev.rs @@ -1,12 +1,14 @@ //! Development-related functionality +pub use blobby; + /// Define test #[macro_export] macro_rules! new_test { ($name:ident, $test_name:expr, $cipher:ty) => { #[test] fn $name() { - use block_cipher::blobby::Blob3Iterator; + use block_cipher::dev::blobby::Blob3Iterator; use block_cipher::generic_array::typenum::Unsigned; use block_cipher::generic_array::GenericArray; use block_cipher::{BlockCipher, NewBlockCipher}; diff --git a/block-cipher/src/lib.rs b/block-cipher/src/lib.rs index 1e606060a..7c232de04 100644 --- a/block-cipher/src/lib.rs +++ b/block-cipher/src/lib.rs @@ -12,9 +12,6 @@ extern crate std; #[cfg(feature = "dev")] pub mod dev; -#[cfg(feature = "dev")] -pub use blobby; - mod errors; pub use crate::errors::InvalidKeyLength; diff --git a/stream-cipher/src/dev.rs b/stream-cipher/src/dev.rs index 02c2715fa..ed78dd1fc 100644 --- a/stream-cipher/src/dev.rs +++ b/stream-cipher/src/dev.rs @@ -1,12 +1,14 @@ //! Development-related functionality +pub use blobby; + /// Test core functionality of synchronous stream cipher #[macro_export] macro_rules! new_sync_test { ($name:ident, $cipher:ty, $test_name:expr) => { #[test] fn $name() { - use stream_cipher::blobby::Blob4Iterator; + use stream_cipher::dev::blobby::Blob4Iterator; use stream_cipher::generic_array::GenericArray; use stream_cipher::{NewStreamCipher, SyncStreamCipher}; @@ -45,7 +47,7 @@ macro_rules! new_seek_test { ($name:ident, $cipher:ty, $test_name:expr) => { #[test] fn $name() { - use stream_cipher::blobby::Blob4Iterator; + use stream_cipher::dev::blobby::Blob4Iterator; use stream_cipher::generic_array::GenericArray; use stream_cipher::{NewStreamCipher, SyncStreamCipher, SyncStreamCipherSeek}; @@ -87,7 +89,7 @@ macro_rules! new_async_test { ($name:ident, $test_name:expr, $cipher:ty) => { #[test] fn $name() { - use stream_cipher::blobby::Blob4Iterator; + use stream_cipher::dev::blobby::Blob4Iterator; use stream_cipher::generic_array::GenericArray; use stream_cipher::{NewStreamCipher, StreamCipher}; From 6298cf103ddc29b5ab0dcaa40a984323df25aa62 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 27 May 2020 13:16:42 -0700 Subject: [PATCH 0094/1461] crypto-mac: bump version to v0.8.0-pre It seems it was previously bumped to v0.8.0: https://github.com/RustCrypto/traits/commit/128e557120632b623f55356a539b1c9c991d6626 ...but never released, so this bumps it back with the intent of releasing a v0.8.0. --- Cargo.lock | 2 +- crypto-mac/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b385c1c1f..970a35f90 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -71,7 +71,7 @@ checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" [[package]] name = "crypto-mac" -version = "0.9.0-pre" +version = "0.8.0-pre" dependencies = [ "blobby", "generic-array 0.13.2", diff --git a/crypto-mac/Cargo.toml b/crypto-mac/Cargo.toml index b8353318a..e67d029e0 100644 --- a/crypto-mac/Cargo.toml +++ b/crypto-mac/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crypto-mac" description = "Trait for Message Authentication Code (MAC) algorithms" -version = "0.9.0-pre" +version = "0.8.0-pre" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" From 5d72d9d37e5aeefe3581b440b4f31257b140dbe6 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 27 May 2020 13:36:25 -0700 Subject: [PATCH 0095/1461] crypto-mac: bump generic-array to v0.14 Matches the other crates --- Cargo.lock | 2 +- crypto-mac/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 970a35f90..fcb2b274a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -74,7 +74,7 @@ name = "crypto-mac" version = "0.8.0-pre" dependencies = [ "blobby", - "generic-array 0.13.2", + "generic-array 0.14.1", "subtle", ] diff --git a/crypto-mac/Cargo.toml b/crypto-mac/Cargo.toml index e67d029e0..1d15fc8a0 100644 --- a/crypto-mac/Cargo.toml +++ b/crypto-mac/Cargo.toml @@ -12,7 +12,7 @@ keywords = ["crypto", "mac"] categories = ["cryptography", "no-std"] [dependencies] -generic-array = "0.13" +generic-array = "0.14" subtle = { version = "2", default-features = false } blobby = { version = "0.1", optional = true } From da999ac6cdd034aa7e5443488e017f6dee286fb4 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 27 May 2020 13:49:53 -0700 Subject: [PATCH 0096/1461] digest: fix dev blobby re-export This was broken in the 2018 edition upgrade. --- digest/src/dev.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/digest/src/dev.rs b/digest/src/dev.rs index 8ef413105..9f42f8f19 100644 --- a/digest/src/dev.rs +++ b/digest/src/dev.rs @@ -1,5 +1,7 @@ //! Development-related functionality +pub use blobby; + use super::{ExtendableOutput, Reset, Update, VariableOutput, XofReader}; use core::fmt::Debug; @@ -10,7 +12,7 @@ macro_rules! new_test { ($name:ident, $test_name:expr, $hasher:ty, $test_func:ident) => { #[test] fn $name() { - use digest::blobby::Blob2Iterator; + use digest::dev::blobby::Blob2Iterator; let data = include_bytes!(concat!("data/", $test_name, ".blb")); for (i, row) in Blob2Iterator::new(data).unwrap().enumerate() { From 09ffa21b0802b315bd48710762051e28dcf486c0 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 27 May 2020 13:54:05 -0700 Subject: [PATCH 0097/1461] crypto-mac: fix dev blobby re-export This was broken in the 2018 edition upgrade. --- crypto-mac/src/dev.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crypto-mac/src/dev.rs b/crypto-mac/src/dev.rs index a4c2cf3ee..c08783fec 100644 --- a/crypto-mac/src/dev.rs +++ b/crypto-mac/src/dev.rs @@ -1,12 +1,14 @@ //! Development-related functionality +pub use blobby; + /// Define test #[macro_export] macro_rules! new_test { ($name:ident, $test_name:expr, $mac:ty) => { #[test] fn $name() { - use crypto_mac::blobby::Blob3Iterator; + use crypto_mac::dev::blobby::Blob3Iterator; use crypto_mac::Mac; fn run_test(key: &[u8], input: &[u8], tag: &[u8]) -> Option<&'static str> { From a4706d21df292590a73e5a0cc43287be697e1e9b Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 27 May 2020 14:01:31 -0700 Subject: [PATCH 0098/1461] crypto-mac: use NewMac in test macros These weren't properly updated before --- crypto-mac/src/dev.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crypto-mac/src/dev.rs b/crypto-mac/src/dev.rs index c08783fec..4e0f27d1e 100644 --- a/crypto-mac/src/dev.rs +++ b/crypto-mac/src/dev.rs @@ -9,10 +9,10 @@ macro_rules! new_test { #[test] fn $name() { use crypto_mac::dev::blobby::Blob3Iterator; - use crypto_mac::Mac; + use crypto_mac::{Mac, NewMac}; fn run_test(key: &[u8], input: &[u8], tag: &[u8]) -> Option<&'static str> { - let mut mac = <$mac as Mac>::new_varkey(key).unwrap(); + let mut mac = <$mac as NewMac>::new_varkey(key).unwrap(); mac.input(input); let result = mac.result_reset(); if &result.code()[..] != tag { @@ -24,7 +24,7 @@ macro_rules! new_test { return Some("after reset"); } - let mut mac = <$mac as Mac>::new_varkey(key).unwrap(); + let mut mac = <$mac as NewMac>::new_varkey(key).unwrap(); // test reading byte by byte for i in 0..input.len() { mac.input(&input[i..i + 1]); @@ -77,7 +77,7 @@ macro_rules! bench { ($engine:path) => { extern crate test; - use crypto_mac::Mac; + use crypto_mac::{Mac, NewMac}; use test::Bencher; bench!(bench1_10, $engine, 10); From b00e554a4fafc5e3d0b59fd8a0691c7854498da0 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 27 May 2020 14:07:39 -0700 Subject: [PATCH 0099/1461] crypto-mac: more dev macro fixes --- crypto-mac/src/dev.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/crypto-mac/src/dev.rs b/crypto-mac/src/dev.rs index 4e0f27d1e..257ce9fc6 100644 --- a/crypto-mac/src/dev.rs +++ b/crypto-mac/src/dev.rs @@ -13,13 +13,13 @@ macro_rules! new_test { fn run_test(key: &[u8], input: &[u8], tag: &[u8]) -> Option<&'static str> { let mut mac = <$mac as NewMac>::new_varkey(key).unwrap(); - mac.input(input); + mac.update(input); let result = mac.result_reset(); - if &result.code()[..] != tag { + if &result.into_bytes()[..] != tag { return Some("whole message"); } // test if reset worked correctly - mac.input(input); + mac.update(input); if mac.verify(&tag).is_err() { return Some("after reset"); } @@ -27,7 +27,7 @@ macro_rules! new_test { let mut mac = <$mac as NewMac>::new_varkey(key).unwrap(); // test reading byte by byte for i in 0..input.len() { - mac.input(&input[i..i + 1]); + mac.update(&input[i..i + 1]); } if let Err(_) = mac.verify(tag) { return Some("message byte-by-byte"); @@ -63,11 +63,11 @@ macro_rules! bench { #[bench] fn $name(b: &mut Bencher) { let key = Default::default(); - let mut m = <$engine>::new(&key); + let mut mac = <$engine>::new(&key); let data = [0; $bs]; b.iter(|| { - m.input(&data); + mac.update(&data); }); b.bytes = $bs; From 8ceead6ec39c40634b3ef5b4b4c3d36519691402 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 27 May 2020 14:38:33 -0700 Subject: [PATCH 0100/1461] digest: fix benchmark dev macro --- digest/src/dev.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/digest/src/dev.rs b/digest/src/dev.rs index 9f42f8f19..ab01b762e 100644 --- a/digest/src/dev.rs +++ b/digest/src/dev.rs @@ -226,7 +226,7 @@ macro_rules! bench { let data = [0; $bs]; b.iter(|| { - d.input(&data[..]); + d.update(&data[..]); }); b.bytes = $bs; From 2164ac04818c9610129a24c4ed9674dca0b55100 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 28 May 2020 11:11:09 -0700 Subject: [PATCH 0101/1461] .github: fix branch for security audit --- .github/workflows/security-audit.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/security-audit.yml b/.github/workflows/security-audit.yml index b003aa2ec..0d82d54ba 100644 --- a/.github/workflows/security-audit.yml +++ b/.github/workflows/security-audit.yml @@ -3,10 +3,10 @@ on: pull_request: paths: Cargo.lock push: - branches: develop + branches: master paths: Cargo.lock schedule: - - cron: '0 0 * * *' + - cron: "0 0 * * *" jobs: security_audit: From 5f73a0c1e044fb7a1d4c8f297ab23f7ac61311f6 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 28 May 2020 13:27:20 -0700 Subject: [PATCH 0102/1461] .github: deny warnings and disable incremental builds --- .github/workflows/aead.yml | 24 ++++++++++++++++++----- .github/workflows/block-cipher.yml | 29 +++++++++++++++++++++++----- .github/workflows/crypto-mac.yml | 29 +++++++++++++++++++++++----- .github/workflows/digest.yml | 29 +++++++++++++++++++++++----- .github/workflows/signature.yml | 24 +++++++++++++++++++---- .github/workflows/stream-cipher.yml | 29 +++++++++++++++++++++++----- .github/workflows/universal-hash.yml | 23 ++++++++++++++++++---- Cargo.lock | 1 + 8 files changed, 155 insertions(+), 33 deletions(-) diff --git a/.github/workflows/aead.yml b/.github/workflows/aead.yml index 1d7cfe3ff..0e0a8829b 100644 --- a/.github/workflows/aead.yml +++ b/.github/workflows/aead.yml @@ -45,9 +45,23 @@ jobs: with: profile: minimal toolchain: ${{ matrix.rust }} - - run: | - cargo check --all-features - cargo test --no-default-features - cargo test - cargo test --all-features + - run: cargo check --all-features + env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" + working-directory: aead + - run: cargo test --no-default-features --release + env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" + working-directory: aead + - run: cargo test --release + env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" + working-directory: aead + - run: cargo test --all-features --release + env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" working-directory: aead diff --git a/.github/workflows/block-cipher.yml b/.github/workflows/block-cipher.yml index 17a6dc352..72ee955e9 100644 --- a/.github/workflows/block-cipher.yml +++ b/.github/workflows/block-cipher.yml @@ -45,9 +45,28 @@ jobs: with: profile: minimal toolchain: ${{ matrix.rust }} - - run: | - cargo check --all-features - cargo test --features dev - cargo test --features std - cargo test --all-features + - run: cargo check --all-features + env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" + working-directory: block-cipher + - run: cargo test --release + env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" + working-directory: block-cipher + - run: cargo test --features dev --release + env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" + working-directory: block-cipher + - run: cargo test --features std --release + env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" + working-directory: block-cipher + - run: cargo test --all-features --release + env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" working-directory: block-cipher diff --git a/.github/workflows/crypto-mac.yml b/.github/workflows/crypto-mac.yml index 21ddcff8e..4ec115b0f 100644 --- a/.github/workflows/crypto-mac.yml +++ b/.github/workflows/crypto-mac.yml @@ -45,9 +45,28 @@ jobs: with: profile: minimal toolchain: ${{ matrix.rust }} - - run: | - cargo check --all-features - cargo test --features dev - cargo test --features std - cargo test --all-features + - run: cargo check --all-features + env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" + working-directory: crypto-mac + - run: cargo test --release + env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" + working-directory: crypto-mac + - run: cargo test --features dev --release + env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" + working-directory: crypto-mac + - run: cargo test --features std --release + env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" + working-directory: crypto-mac + - run: cargo test --all-features --release + env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" working-directory: crypto-mac diff --git a/.github/workflows/digest.yml b/.github/workflows/digest.yml index ca5788824..8f2cc3689 100644 --- a/.github/workflows/digest.yml +++ b/.github/workflows/digest.yml @@ -45,9 +45,28 @@ jobs: with: profile: minimal toolchain: ${{ matrix.rust }} - - run: | - cargo check --all-features - cargo test --features dev - cargo test --features std - cargo test --all-features + - run: cargo check --all-features + env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" + working-directory: digest + - run: cargo test --release + env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" + working-directory: digest + - run: cargo test --features dev --release + env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" + working-directory: digest + - run: cargo test --features std --release + env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" + working-directory: digest + - run: cargo test --all-features --release + env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" working-directory: digest diff --git a/.github/workflows/signature.yml b/.github/workflows/signature.yml index dd34339fd..53e286020 100644 --- a/.github/workflows/signature.yml +++ b/.github/workflows/signature.yml @@ -45,8 +45,24 @@ jobs: with: profile: minimal toolchain: ${{ matrix.rust }} - - run: | - cargo check --all-features - cargo test --no-default-features - cargo test + - run: cargo check --all-features + env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" working-directory: signature + - run: cargo test --no-default-features --release + env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" + working-directory: signature + - run: cargo test --release + env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" + working-directory: signature +# TODO: fix support for the `digest-preview` feature +# - run: cargo test --all-features --release +# env: +# CARGO_INCREMENTAL: 0 +# RUSTFLAGS: "-Dwarnings" +# working-directory: signature diff --git a/.github/workflows/stream-cipher.yml b/.github/workflows/stream-cipher.yml index ef6dbdc38..558dca73d 100644 --- a/.github/workflows/stream-cipher.yml +++ b/.github/workflows/stream-cipher.yml @@ -45,9 +45,28 @@ jobs: with: profile: minimal toolchain: ${{ matrix.rust }} - - run: | - cargo check --all-features - cargo test --features dev - cargo test --features std - cargo test --all-features + - run: cargo check --all-features + env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" + working-directory: stream-cipher + - run: cargo test --release + env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" + working-directory: stream-cipher + - run: cargo test --features dev --release + env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" + working-directory: stream-cipher + - run: cargo test --features std --release + env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" + working-directory: stream-cipher + - run: cargo test --all-features --release + env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" working-directory: stream-cipher diff --git a/.github/workflows/universal-hash.yml b/.github/workflows/universal-hash.yml index 0846c56ee..fb0855525 100644 --- a/.github/workflows/universal-hash.yml +++ b/.github/workflows/universal-hash.yml @@ -45,8 +45,23 @@ jobs: with: profile: minimal toolchain: ${{ matrix.rust }} - - run: | - cargo check --all-features - cargo test --no-default-features - cargo test + - run: cargo check --all-features + env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" + working-directory: universal-hash + - run: cargo test --no-default-features --release + env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" + working-directory: universal-hash + - run: cargo test --release + env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" + working-directory: universal-hash + - run: cargo test --all-features --release + env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" working-directory: universal-hash diff --git a/Cargo.lock b/Cargo.lock index fcb2b274a..989bcdcf9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -299,3 +299,4 @@ dependencies = [ "generic-array 0.14.1", "subtle", ] + From 98516f4fe35fc90e3ea770277f49daac5aa1ea77 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 29 May 2020 17:03:51 -0700 Subject: [PATCH 0103/1461] digest: use 2018 edition module syntax for `bench` macro --- Cargo.lock | 1 - digest/src/dev.rs | 8 ++++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 989bcdcf9..fcb2b274a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -299,4 +299,3 @@ dependencies = [ "generic-array 0.14.1", "subtle", ] - diff --git a/digest/src/dev.rs b/digest/src/dev.rs index ab01b762e..77fc5ed98 100644 --- a/digest/src/dev.rs +++ b/digest/src/dev.rs @@ -239,9 +239,9 @@ macro_rules! bench { use digest::Digest; use test::Bencher; - bench!(bench1_10, $engine, 10); - bench!(bench2_100, $engine, 100); - bench!(bench3_1000, $engine, 1000); - bench!(bench4_10000, $engine, 10000); + $crate::bench!(bench1_10, $engine, 10); + $crate::bench!(bench2_100, $engine, 100); + $crate::bench!(bench3_1000, $engine, 1000); + $crate::bench!(bench4_10000, $engine, 10000); }; } From cdfb5756b1f688515129dda3782486a017bd65e6 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 30 May 2020 09:36:57 -0700 Subject: [PATCH 0104/1461] .github: set env vars at workspace level --- .github/workflows/aead.yml | 16 ++++------------ .github/workflows/block-cipher.yml | 19 ++++--------------- .github/workflows/crypto-mac.yml | 19 ++++--------------- .github/workflows/digest.yml | 19 ++++--------------- .github/workflows/signature.yml | 16 ++++------------ .github/workflows/stream-cipher.yml | 19 ++++--------------- .github/workflows/universal-hash.yml | 16 ++++------------ 7 files changed, 28 insertions(+), 96 deletions(-) diff --git a/.github/workflows/aead.yml b/.github/workflows/aead.yml index 0e0a8829b..7ecd7cdf5 100644 --- a/.github/workflows/aead.yml +++ b/.github/workflows/aead.yml @@ -11,6 +11,10 @@ on: - "aead/**" - "Cargo.*" +env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" + jobs: build: runs-on: ubuntu-latest @@ -46,22 +50,10 @@ jobs: profile: minimal toolchain: ${{ matrix.rust }} - run: cargo check --all-features - env: - CARGO_INCREMENTAL: 0 - RUSTFLAGS: "-Dwarnings" working-directory: aead - run: cargo test --no-default-features --release - env: - CARGO_INCREMENTAL: 0 - RUSTFLAGS: "-Dwarnings" working-directory: aead - run: cargo test --release - env: - CARGO_INCREMENTAL: 0 - RUSTFLAGS: "-Dwarnings" working-directory: aead - run: cargo test --all-features --release - env: - CARGO_INCREMENTAL: 0 - RUSTFLAGS: "-Dwarnings" working-directory: aead diff --git a/.github/workflows/block-cipher.yml b/.github/workflows/block-cipher.yml index 72ee955e9..7b5fb16e3 100644 --- a/.github/workflows/block-cipher.yml +++ b/.github/workflows/block-cipher.yml @@ -11,6 +11,10 @@ on: - "block-cipher/**" - "Cargo.*" +env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" + jobs: build: runs-on: ubuntu-latest @@ -46,27 +50,12 @@ jobs: profile: minimal toolchain: ${{ matrix.rust }} - run: cargo check --all-features - env: - CARGO_INCREMENTAL: 0 - RUSTFLAGS: "-Dwarnings" working-directory: block-cipher - run: cargo test --release - env: - CARGO_INCREMENTAL: 0 - RUSTFLAGS: "-Dwarnings" working-directory: block-cipher - run: cargo test --features dev --release - env: - CARGO_INCREMENTAL: 0 - RUSTFLAGS: "-Dwarnings" working-directory: block-cipher - run: cargo test --features std --release - env: - CARGO_INCREMENTAL: 0 - RUSTFLAGS: "-Dwarnings" working-directory: block-cipher - run: cargo test --all-features --release - env: - CARGO_INCREMENTAL: 0 - RUSTFLAGS: "-Dwarnings" working-directory: block-cipher diff --git a/.github/workflows/crypto-mac.yml b/.github/workflows/crypto-mac.yml index 4ec115b0f..f724f5350 100644 --- a/.github/workflows/crypto-mac.yml +++ b/.github/workflows/crypto-mac.yml @@ -11,6 +11,10 @@ on: - "crypto-mac/**" - "Cargo.*" +env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" + jobs: build: runs-on: ubuntu-latest @@ -46,27 +50,12 @@ jobs: profile: minimal toolchain: ${{ matrix.rust }} - run: cargo check --all-features - env: - CARGO_INCREMENTAL: 0 - RUSTFLAGS: "-Dwarnings" working-directory: crypto-mac - run: cargo test --release - env: - CARGO_INCREMENTAL: 0 - RUSTFLAGS: "-Dwarnings" working-directory: crypto-mac - run: cargo test --features dev --release - env: - CARGO_INCREMENTAL: 0 - RUSTFLAGS: "-Dwarnings" working-directory: crypto-mac - run: cargo test --features std --release - env: - CARGO_INCREMENTAL: 0 - RUSTFLAGS: "-Dwarnings" working-directory: crypto-mac - run: cargo test --all-features --release - env: - CARGO_INCREMENTAL: 0 - RUSTFLAGS: "-Dwarnings" working-directory: crypto-mac diff --git a/.github/workflows/digest.yml b/.github/workflows/digest.yml index 8f2cc3689..1efa6d6ea 100644 --- a/.github/workflows/digest.yml +++ b/.github/workflows/digest.yml @@ -11,6 +11,10 @@ on: - "digest/**" - "Cargo.*" +env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" + jobs: build: runs-on: ubuntu-latest @@ -46,27 +50,12 @@ jobs: profile: minimal toolchain: ${{ matrix.rust }} - run: cargo check --all-features - env: - CARGO_INCREMENTAL: 0 - RUSTFLAGS: "-Dwarnings" working-directory: digest - run: cargo test --release - env: - CARGO_INCREMENTAL: 0 - RUSTFLAGS: "-Dwarnings" working-directory: digest - run: cargo test --features dev --release - env: - CARGO_INCREMENTAL: 0 - RUSTFLAGS: "-Dwarnings" working-directory: digest - run: cargo test --features std --release - env: - CARGO_INCREMENTAL: 0 - RUSTFLAGS: "-Dwarnings" working-directory: digest - run: cargo test --all-features --release - env: - CARGO_INCREMENTAL: 0 - RUSTFLAGS: "-Dwarnings" working-directory: digest diff --git a/.github/workflows/signature.yml b/.github/workflows/signature.yml index 53e286020..0a303542d 100644 --- a/.github/workflows/signature.yml +++ b/.github/workflows/signature.yml @@ -11,6 +11,10 @@ on: - "signature/**" - "Cargo.*" +env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" + jobs: build: runs-on: ubuntu-latest @@ -46,23 +50,11 @@ jobs: profile: minimal toolchain: ${{ matrix.rust }} - run: cargo check --all-features - env: - CARGO_INCREMENTAL: 0 - RUSTFLAGS: "-Dwarnings" working-directory: signature - run: cargo test --no-default-features --release - env: - CARGO_INCREMENTAL: 0 - RUSTFLAGS: "-Dwarnings" working-directory: signature - run: cargo test --release - env: - CARGO_INCREMENTAL: 0 - RUSTFLAGS: "-Dwarnings" working-directory: signature # TODO: fix support for the `digest-preview` feature # - run: cargo test --all-features --release -# env: -# CARGO_INCREMENTAL: 0 -# RUSTFLAGS: "-Dwarnings" # working-directory: signature diff --git a/.github/workflows/stream-cipher.yml b/.github/workflows/stream-cipher.yml index 558dca73d..74df5f384 100644 --- a/.github/workflows/stream-cipher.yml +++ b/.github/workflows/stream-cipher.yml @@ -11,6 +11,10 @@ on: - "stream-cipher/**" - "Cargo.*" +env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" + jobs: build: runs-on: ubuntu-latest @@ -46,27 +50,12 @@ jobs: profile: minimal toolchain: ${{ matrix.rust }} - run: cargo check --all-features - env: - CARGO_INCREMENTAL: 0 - RUSTFLAGS: "-Dwarnings" working-directory: stream-cipher - run: cargo test --release - env: - CARGO_INCREMENTAL: 0 - RUSTFLAGS: "-Dwarnings" working-directory: stream-cipher - run: cargo test --features dev --release - env: - CARGO_INCREMENTAL: 0 - RUSTFLAGS: "-Dwarnings" working-directory: stream-cipher - run: cargo test --features std --release - env: - CARGO_INCREMENTAL: 0 - RUSTFLAGS: "-Dwarnings" working-directory: stream-cipher - run: cargo test --all-features --release - env: - CARGO_INCREMENTAL: 0 - RUSTFLAGS: "-Dwarnings" working-directory: stream-cipher diff --git a/.github/workflows/universal-hash.yml b/.github/workflows/universal-hash.yml index fb0855525..f7cbcda71 100644 --- a/.github/workflows/universal-hash.yml +++ b/.github/workflows/universal-hash.yml @@ -11,6 +11,10 @@ on: - "universal-hash/**" - "Cargo.*" +env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" + jobs: build: runs-on: ubuntu-latest @@ -46,22 +50,10 @@ jobs: profile: minimal toolchain: ${{ matrix.rust }} - run: cargo check --all-features - env: - CARGO_INCREMENTAL: 0 - RUSTFLAGS: "-Dwarnings" working-directory: universal-hash - run: cargo test --no-default-features --release - env: - CARGO_INCREMENTAL: 0 - RUSTFLAGS: "-Dwarnings" working-directory: universal-hash - run: cargo test --release - env: - CARGO_INCREMENTAL: 0 - RUSTFLAGS: "-Dwarnings" working-directory: universal-hash - run: cargo test --all-features --release - env: - CARGO_INCREMENTAL: 0 - RUSTFLAGS: "-Dwarnings" working-directory: universal-hash From 13bb0dbfa15b2aa8a2fde5b2458b2c9e2f7f1249 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 30 May 2020 10:31:08 -0700 Subject: [PATCH 0105/1461] .github: use `defaults` to set `working-directory` This should eliminate redundantly specifying it on a per-job basis. --- .github/workflows/aead.yml | 14 +++++--------- .github/workflows/block-cipher.yml | 15 +++++---------- .github/workflows/crypto-mac.yml | 15 +++++---------- .github/workflows/digest.yml | 15 +++++---------- .github/workflows/signature.yml | 14 +++++--------- .github/workflows/stream-cipher.yml | 15 +++++---------- .github/workflows/universal-hash.yml | 14 +++++--------- Cargo.lock | 1 + 8 files changed, 36 insertions(+), 67 deletions(-) diff --git a/.github/workflows/aead.yml b/.github/workflows/aead.yml index 7ecd7cdf5..ec0978796 100644 --- a/.github/workflows/aead.yml +++ b/.github/workflows/aead.yml @@ -7,9 +7,10 @@ on: - "Cargo.*" push: branches: master - paths: - - "aead/**" - - "Cargo.*" + +defaults: + run: + working-directory: aead env: CARGO_INCREMENTAL: 0 @@ -34,8 +35,7 @@ jobs: toolchain: ${{ matrix.rust }} target: ${{ matrix.target }} override: true - - working-directory: aead - run: cargo build --no-default-features --release --target ${{ matrix.target }} + - run: cargo build --no-default-features --release --target ${{ matrix.target }} test: runs-on: ubuntu-latest strategy: @@ -50,10 +50,6 @@ jobs: profile: minimal toolchain: ${{ matrix.rust }} - run: cargo check --all-features - working-directory: aead - run: cargo test --no-default-features --release - working-directory: aead - run: cargo test --release - working-directory: aead - run: cargo test --all-features --release - working-directory: aead diff --git a/.github/workflows/block-cipher.yml b/.github/workflows/block-cipher.yml index 7b5fb16e3..3f83ecd64 100644 --- a/.github/workflows/block-cipher.yml +++ b/.github/workflows/block-cipher.yml @@ -7,9 +7,10 @@ on: - "Cargo.*" push: branches: master - paths: - - "block-cipher/**" - - "Cargo.*" + +defaults: + run: + working-directory: block-cipher env: CARGO_INCREMENTAL: 0 @@ -34,8 +35,7 @@ jobs: toolchain: ${{ matrix.rust }} target: ${{ matrix.target }} override: true - - working-directory: block-cipher - run: cargo build --no-default-features --release --target ${{ matrix.target }} + - run: cargo build --no-default-features --release --target ${{ matrix.target }} test: runs-on: ubuntu-latest strategy: @@ -50,12 +50,7 @@ jobs: profile: minimal toolchain: ${{ matrix.rust }} - run: cargo check --all-features - working-directory: block-cipher - run: cargo test --release - working-directory: block-cipher - run: cargo test --features dev --release - working-directory: block-cipher - run: cargo test --features std --release - working-directory: block-cipher - run: cargo test --all-features --release - working-directory: block-cipher diff --git a/.github/workflows/crypto-mac.yml b/.github/workflows/crypto-mac.yml index f724f5350..32333fc8b 100644 --- a/.github/workflows/crypto-mac.yml +++ b/.github/workflows/crypto-mac.yml @@ -7,9 +7,10 @@ on: - "Cargo.*" push: branches: master - paths: - - "crypto-mac/**" - - "Cargo.*" + +defaults: + run: + working-directory: crypto-mac env: CARGO_INCREMENTAL: 0 @@ -34,8 +35,7 @@ jobs: toolchain: ${{ matrix.rust }} target: ${{ matrix.target }} override: true - - working-directory: crypto-mac - run: cargo build --no-default-features --release --target ${{ matrix.target }} + - run: cargo build --no-default-features --release --target ${{ matrix.target }} test: runs-on: ubuntu-latest strategy: @@ -50,12 +50,7 @@ jobs: profile: minimal toolchain: ${{ matrix.rust }} - run: cargo check --all-features - working-directory: crypto-mac - run: cargo test --release - working-directory: crypto-mac - run: cargo test --features dev --release - working-directory: crypto-mac - run: cargo test --features std --release - working-directory: crypto-mac - run: cargo test --all-features --release - working-directory: crypto-mac diff --git a/.github/workflows/digest.yml b/.github/workflows/digest.yml index 1efa6d6ea..aadaafc00 100644 --- a/.github/workflows/digest.yml +++ b/.github/workflows/digest.yml @@ -7,9 +7,10 @@ on: - "Cargo.*" push: branches: master - paths: - - "digest/**" - - "Cargo.*" + +defaults: + run: + working-directory: digest env: CARGO_INCREMENTAL: 0 @@ -34,8 +35,7 @@ jobs: toolchain: ${{ matrix.rust }} target: ${{ matrix.target }} override: true - - working-directory: digest - run: cargo build --no-default-features --release --target ${{ matrix.target }} + - run: cargo build --no-default-features --release --target ${{ matrix.target }} test: runs-on: ubuntu-latest strategy: @@ -50,12 +50,7 @@ jobs: profile: minimal toolchain: ${{ matrix.rust }} - run: cargo check --all-features - working-directory: digest - run: cargo test --release - working-directory: digest - run: cargo test --features dev --release - working-directory: digest - run: cargo test --features std --release - working-directory: digest - run: cargo test --all-features --release - working-directory: digest diff --git a/.github/workflows/signature.yml b/.github/workflows/signature.yml index 0a303542d..c1872a47b 100644 --- a/.github/workflows/signature.yml +++ b/.github/workflows/signature.yml @@ -7,9 +7,10 @@ on: - "Cargo.*" push: branches: master - paths: - - "signature/**" - - "Cargo.*" + +defaults: + run: + working-directory: signature env: CARGO_INCREMENTAL: 0 @@ -34,8 +35,7 @@ jobs: toolchain: ${{ matrix.rust }} target: ${{ matrix.target }} override: true - - working-directory: signature - run: cargo build --no-default-features --release --target ${{ matrix.target }} + - run: cargo build --no-default-features --release --target ${{ matrix.target }} test: runs-on: ubuntu-latest strategy: @@ -50,11 +50,7 @@ jobs: profile: minimal toolchain: ${{ matrix.rust }} - run: cargo check --all-features - working-directory: signature - run: cargo test --no-default-features --release - working-directory: signature - run: cargo test --release - working-directory: signature # TODO: fix support for the `digest-preview` feature # - run: cargo test --all-features --release -# working-directory: signature diff --git a/.github/workflows/stream-cipher.yml b/.github/workflows/stream-cipher.yml index 74df5f384..5c101b93a 100644 --- a/.github/workflows/stream-cipher.yml +++ b/.github/workflows/stream-cipher.yml @@ -7,9 +7,10 @@ on: - "Cargo.*" push: branches: master - paths: - - "stream-cipher/**" - - "Cargo.*" + +defaults: + run: + working-directory: stream-cipher env: CARGO_INCREMENTAL: 0 @@ -34,8 +35,7 @@ jobs: toolchain: ${{ matrix.rust }} target: ${{ matrix.target }} override: true - - working-directory: stream-cipher - run: cargo build --no-default-features --release --target ${{ matrix.target }} + - run: cargo build --no-default-features --release --target ${{ matrix.target }} test: runs-on: ubuntu-latest strategy: @@ -50,12 +50,7 @@ jobs: profile: minimal toolchain: ${{ matrix.rust }} - run: cargo check --all-features - working-directory: stream-cipher - run: cargo test --release - working-directory: stream-cipher - run: cargo test --features dev --release - working-directory: stream-cipher - run: cargo test --features std --release - working-directory: stream-cipher - run: cargo test --all-features --release - working-directory: stream-cipher diff --git a/.github/workflows/universal-hash.yml b/.github/workflows/universal-hash.yml index f7cbcda71..118f29b04 100644 --- a/.github/workflows/universal-hash.yml +++ b/.github/workflows/universal-hash.yml @@ -7,9 +7,10 @@ on: - "Cargo.*" push: branches: master - paths: - - "universal-hash/**" - - "Cargo.*" + +defaults: + run: + working-directory: universal-hash env: CARGO_INCREMENTAL: 0 @@ -34,8 +35,7 @@ jobs: toolchain: ${{ matrix.rust }} target: ${{ matrix.target }} override: true - - working-directory: universal-hash - run: cargo build --no-default-features --release --target ${{ matrix.target }} + - run: cargo build --no-default-features --release --target ${{ matrix.target }} test: runs-on: ubuntu-latest strategy: @@ -50,10 +50,6 @@ jobs: profile: minimal toolchain: ${{ matrix.rust }} - run: cargo check --all-features - working-directory: universal-hash - run: cargo test --no-default-features --release - working-directory: universal-hash - run: cargo test --release - working-directory: universal-hash - run: cargo test --all-features --release - working-directory: universal-hash diff --git a/Cargo.lock b/Cargo.lock index fcb2b274a..989bcdcf9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -299,3 +299,4 @@ dependencies = [ "generic-array 0.14.1", "subtle", ] + From d7e7dcf367cf718bef4ddbba58b9a2f65ee5c39f Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 31 May 2020 07:19:53 -0700 Subject: [PATCH 0106/1461] crypto-mac: use 2018 edition module syntax for `bench` macro --- Cargo.lock | 1 - crypto-mac/src/dev.rs | 8 ++++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 989bcdcf9..fcb2b274a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -299,4 +299,3 @@ dependencies = [ "generic-array 0.14.1", "subtle", ] - diff --git a/crypto-mac/src/dev.rs b/crypto-mac/src/dev.rs index 257ce9fc6..d7d42230f 100644 --- a/crypto-mac/src/dev.rs +++ b/crypto-mac/src/dev.rs @@ -80,9 +80,9 @@ macro_rules! bench { use crypto_mac::{Mac, NewMac}; use test::Bencher; - bench!(bench1_10, $engine, 10); - bench!(bench2_100, $engine, 100); - bench!(bench3_1000, $engine, 1000); - bench!(bench3_10000, $engine, 10000); + $crate::bench!(bench1_10, $engine, 10); + $crate::bench!(bench2_100, $engine, 100); + $crate::bench!(bench3_1000, $engine, 1000); + $crate::bench!(bench3_10000, $engine, 10000); }; } From 48f6d59655bdf6af7cfca1478ed521a6b8e89d62 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 31 May 2020 12:19:33 -0700 Subject: [PATCH 0107/1461] aead: fix `Tag` return values They were using `*::NonceSize` instead of `*::TagSize`. --- aead/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/aead/src/lib.rs b/aead/src/lib.rs index 279937703..aaf7c9ffe 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -237,7 +237,7 @@ pub trait AeadInPlace { nonce: &Nonce, associated_data: &[u8], buffer: &mut [u8], - ) -> Result, Error>; + ) -> Result, Error>; /// Decrypt the message in-place, returning an error in the event the /// provided authentication tag does not match the given ciphertext. @@ -305,7 +305,7 @@ pub trait AeadMutInPlace { nonce: &Nonce, associated_data: &[u8], buffer: &mut [u8], - ) -> Result, Error>; + ) -> Result, Error>; /// Decrypt the message in-place, returning an error in the event the /// provided authentication tag does not match the given ciphertext. @@ -412,7 +412,7 @@ impl AeadMutInPlace for Alg { nonce: &Nonce, associated_data: &[u8], buffer: &mut [u8], - ) -> Result, Error> { + ) -> Result, Error> { ::encrypt_in_place_detached(self, nonce, associated_data, buffer) } From 84e56fbd4412385eafc854eca6b7f397dab2ad02 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 31 May 2020 12:29:51 -0700 Subject: [PATCH 0108/1461] aead: fix Tag params --- aead/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/aead/src/lib.rs b/aead/src/lib.rs index aaf7c9ffe..1f33c5bff 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -261,7 +261,7 @@ pub trait AeadInPlace { nonce: &Nonce, associated_data: &[u8], buffer: &mut [u8], - tag: &Tag, + tag: &Tag, ) -> Result<(), Error>; } @@ -329,7 +329,7 @@ pub trait AeadMutInPlace { nonce: &Nonce, associated_data: &[u8], buffer: &mut [u8], - tag: &Tag, + tag: &Tag, ) -> Result<(), Error>; } @@ -430,7 +430,7 @@ impl AeadMutInPlace for Alg { nonce: &Nonce, associated_data: &[u8], buffer: &mut [u8], - tag: &Tag, + tag: &Tag, ) -> Result<(), Error> { ::decrypt_in_place_detached(self, nonce, associated_data, buffer, tag) } From b269ca32f974f9568408d2c116b9e7d8f970907f Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 1 Jun 2020 08:58:43 +0000 Subject: [PATCH 0109/1461] build(deps): bump subtle from 2.2.2 to 2.2.3 Bumps [subtle](https://github.com/dalek-cryptography/subtle) from 2.2.2 to 2.2.3. - [Release notes](https://github.com/dalek-cryptography/subtle/releases) - [Changelog](https://github.com/dalek-cryptography/subtle/blob/master/CHANGELOG.md) - [Commits](https://github.com/dalek-cryptography/subtle/compare/2.2.2...2.2.3) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fcb2b274a..9a1ddc3f7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -253,9 +253,9 @@ dependencies = [ [[package]] name = "subtle" -version = "2.2.2" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c65d530b10ccaeac294f349038a597e435b18fb456aadd0840a623f83b9e941" +checksum = "502d53007c02d7605a05df1c1a73ee436952781653da5d0bf57ad608f66932c1" [[package]] name = "syn" From 8d23fae2a10fb8409cbb60d5d5bd3068f688b2ec Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 2 Jun 2020 06:55:38 -0700 Subject: [PATCH 0110/1461] stream-cipher: use 2018 edition module syntax for `bench` macros Uses `$crate::bench_sync` and `$crate::bench_async` to invoke them. --- stream-cipher/src/dev.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/stream-cipher/src/dev.rs b/stream-cipher/src/dev.rs index ed78dd1fc..56e80ca64 100644 --- a/stream-cipher/src/dev.rs +++ b/stream-cipher/src/dev.rs @@ -177,11 +177,11 @@ macro_rules! bench_sync { vec![77; n] } - bench_sync!(bench1_10, $cipher, 10); - bench_sync!(bench2_100, $cipher, 100); - bench_sync!(bench3_1000, $cipher, 1000); - bench_sync!(bench4_10000, $cipher, 10000); - bench_sync!(bench5_100000, $cipher, 100000); + $crate::bench_sync!(bench1_10, $cipher, 10); + $crate::bench_sync!(bench2_100, $cipher, 100); + $crate::bench_sync!(bench3_1000, $cipher, 1000); + $crate::bench_sync!(bench4_10000, $cipher, 10000); + $crate::bench_sync!(bench5_100000, $cipher, 100000); }; } @@ -229,10 +229,10 @@ macro_rules! bench_async { vec![77; n] } - bench_async!(encrypt_10, decrypt_10, $cipher, 10); - bench_async!(encrypt_100, decrypt_100, $cipher, 100); - bench_async!(encrypt_1000, decrypt_1000, $cipher, 1000); - bench_async!(encrypt_10000, decrypt_10000, $cipher, 10000); - bench_async!(encrypt_100000, decrypt_100000, $cipher, 100000); + $crate::bench_async!(encrypt_10, decrypt_10, $cipher, 10); + $crate::bench_async!(encrypt_100, decrypt_100, $cipher, 100); + $crate::bench_async!(encrypt_1000, decrypt_1000, $cipher, 1000); + $crate::bench_async!(encrypt_10000, decrypt_10000, $cipher, 10000); + $crate::bench_async!(encrypt_100000, decrypt_100000, $cipher, 100000); }; } From 96395832a859728a80098f3e126c99f88040b77b Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 2 Jun 2020 08:53:12 -0700 Subject: [PATCH 0111/1461] Rename `*result*` methods to finalize (ala IUF) As discussed in #43, this adopts `finalize` naming, following the "Initialize-Update-Finalize" (IUF) interface naming scheme pervasive throughout cryptography and cryptographic API design. --- crypto-mac/src/dev.rs | 2 +- crypto-mac/src/lib.rs | 27 ++++++++++++++------------- digest/README.md | 10 +++++----- digest/src/dev.rs | 26 +++++++++++++------------- digest/src/digest.rs | 14 +++++++------- digest/src/dyn_digest.rs | 12 ++++++------ digest/src/lib.rs | 14 +++++++------- signature/tests/signature_derive.rs | 4 ++-- universal-hash/src/lib.rs | 8 ++++---- 9 files changed, 59 insertions(+), 58 deletions(-) diff --git a/crypto-mac/src/dev.rs b/crypto-mac/src/dev.rs index d7d42230f..4cdebe7b5 100644 --- a/crypto-mac/src/dev.rs +++ b/crypto-mac/src/dev.rs @@ -14,7 +14,7 @@ macro_rules! new_test { fn run_test(key: &[u8], input: &[u8], tag: &[u8]) -> Option<&'static str> { let mut mac = <$mac as NewMac>::new_varkey(key).unwrap(); mac.update(input); - let result = mac.result_reset(); + let result = mac.finalize_reset(); if &result.into_bytes()[..] != tag { return Some("whole message"); } diff --git a/crypto-mac/src/lib.rs b/crypto-mac/src/lib.rs index 7a0d143fd..91683a77e 100644 --- a/crypto-mac/src/lib.rs +++ b/crypto-mac/src/lib.rs @@ -57,19 +57,20 @@ pub trait Mac: Clone { /// Obtain the result of a [`Mac`] computation as a [`Output`] and consume /// [`Mac`] instance. - fn result(self) -> Output; + fn finalize(self) -> Output; /// Obtain the result of a [`Mac`] computation as a [`Output`] and reset /// [`Mac`] instance. - fn result_reset(&mut self) -> Output { - let res = self.clone().result(); + fn finalize_reset(&mut self) -> Output { + let res = self.clone().finalize(); self.reset(); res } - /// Check if code is correct for the processed input. - fn verify(self, code: &[u8]) -> Result<(), MacError> { - let choice = self.result().code.ct_eq(code); + /// Check if tag/code value is correct for the processed input. + fn verify(self, tag: &[u8]) -> Result<(), MacError> { + let choice = self.finalize().bytes.ct_eq(tag); + if choice.unwrap_u8() == 1 { Ok(()) } else { @@ -82,28 +83,28 @@ pub trait Mac: Clone { /// implementation that runs in a fixed time. #[derive(Clone)] pub struct Output { - code: GenericArray, + bytes: GenericArray, } impl Output { /// Create a new MAC [`Output`]. - pub fn new(code: GenericArray) -> Output { - Output { code } + pub fn new(bytes: GenericArray) -> Output { + Output { bytes } } - /// Get the MAC code/tag value as a byte array. + /// Get the MAC tag/code value as a byte array. /// - /// Be very careful using this method, since incorrect use of the code value + /// Be very careful using this method, since incorrect use of the tag value /// may permit timing attacks which defeat the security provided by the /// [`Mac`] trait. pub fn into_bytes(self) -> GenericArray { - self.code + self.bytes } } impl ConstantTimeEq for Output { fn ct_eq(&self, other: &Self) -> Choice { - self.code.ct_eq(&other.code) + self.bytes.ct_eq(&other.bytes) } } diff --git a/digest/README.md b/digest/README.md index e1a0f8d94..e68638771 100644 --- a/digest/README.md +++ b/digest/README.md @@ -50,8 +50,8 @@ let data = b"Hello world!"; hasher.input(data); // `input` can be called repeatedly and is generic over `AsRef<[u8]>` hasher.input("String data"); -// Note that calling `result()` consumes hasher -let hash = hasher.result(); +// Note that calling `finalize()` consumes hasher +let hash = hasher.finalize(); println!("Result: {:x}", hash); ``` @@ -65,7 +65,7 @@ example: let hash = Blake2b::new() .chain(b"Hello world!") .chain("String data") - .result(); + .finalize(); println!("Result: {:x}", hash); ``` @@ -89,7 +89,7 @@ use std::{fs, io}; let mut file = fs::File::open(&path)?; let mut hasher = Blake2b::new(); let n = io::copy(&mut file, &mut hasher)?; -let hash = hasher.result(); +let hash = hasher.finalize(); println!("Path: {}", path); println!("Bytes processed: {}", n); @@ -111,7 +111,7 @@ fn hash_password(password: &str, salt: &str, output: &mut [u8]) { hasher.input(password.as_bytes()); hasher.input(b"$"); hasher.input(salt.as_bytes()); - output.copy_from_slice(hasher.result().as_slice()) + output.copy_from_slice(hasher.finalize().as_slice()) } use blake2::Blake2b; diff --git a/digest/src/dev.rs b/digest/src/dev.rs index 77fc5ed98..c205cab43 100644 --- a/digest/src/dev.rs +++ b/digest/src/dev.rs @@ -46,14 +46,14 @@ mod foo { // Test that it works when accepting the message all at once hasher.update(input); let mut hasher2 = hasher.clone(); - if hasher.result().as_slice() != output { + if hasher.finalize().as_slice() != output { return Some("whole message"); } // Test if reset works correctly hasher2.reset(); hasher2.update(input); - if hasher2.result().as_slice() != output { + if hasher2.finalize().as_slice() != output { return Some("whole message after reset"); } @@ -66,7 +66,7 @@ mod foo { hasher.update(&input[len - left..take + len - left]); left -= take; } - if hasher.result().as_slice() != output { + if hasher.finalize().as_slice() != output { return Some("message in pieces"); } @@ -75,7 +75,7 @@ mod foo { for chunk in input.chunks(1) { hasher.update(chunk) } - if hasher.result().as_slice() != output { + if hasher.finalize().as_slice() != output { return Some("message byte-by-byte"); } None @@ -91,7 +91,7 @@ mod foo { sh.update(&[b'a'; 10]); } sh.update(&[b'a'; 500_000][..]); - let out = sh.result(); + let out = sh.finalize(); assert_eq!(out[..], expected[..]); } } @@ -111,7 +111,7 @@ where let mut hasher2 = hasher.clone(); { let out = &mut buf[..output.len()]; - hasher.xof_result().read(out); + hasher.finalize_xof().read(out); if out != output { return Some("whole message"); @@ -124,7 +124,7 @@ where { let out = &mut buf[..output.len()]; - hasher2.xof_result().read(out); + hasher2.finalize_xof().read(out); if out != output { return Some("whole message after reset"); @@ -143,7 +143,7 @@ where { let out = &mut buf[..output.len()]; - hasher.xof_result().read(out); + hasher.finalize_xof().read(out); if out != output { return Some("message in pieces"); } @@ -153,7 +153,7 @@ where let mut hasher = D::default(); hasher.update(input); - let mut reader = hasher.xof_result(); + let mut reader = hasher.finalize_xof(); let out = &mut buf[..output.len()]; for chunk in out.chunks_mut(1) { reader.read(chunk); @@ -176,7 +176,7 @@ where // Test that it works when accepting the message all at once hasher.update(input); let mut hasher2 = hasher.clone(); - hasher.variable_result(|res| buf.copy_from_slice(res)); + hasher.finalize_variable(|res| buf.copy_from_slice(res)); if buf != output { return Some("whole message"); } @@ -184,7 +184,7 @@ where // Test if reset works correctly hasher2.reset(); hasher2.update(input); - hasher2.variable_result(|res| buf.copy_from_slice(res)); + hasher2.finalize_variable(|res| buf.copy_from_slice(res)); if buf != output { return Some("whole message after reset"); } @@ -198,7 +198,7 @@ where hasher.update(&input[len - left..take + len - left]); left -= take; } - hasher.variable_result(|res| buf.copy_from_slice(res)); + hasher.finalize_variable(|res| buf.copy_from_slice(res)); if buf != output { return Some("message in pieces"); } @@ -208,7 +208,7 @@ where for chunk in input.chunks(1) { hasher.update(chunk) } - hasher.variable_result(|res| buf.copy_from_slice(res)); + hasher.finalize_variable(|res| buf.copy_from_slice(res)); if buf != output { return Some("message byte-by-byte"); } diff --git a/digest/src/digest.rs b/digest/src/digest.rs index 24e103be6..ef72951d8 100644 --- a/digest/src/digest.rs +++ b/digest/src/digest.rs @@ -24,13 +24,13 @@ pub trait Digest { Self: Sized; /// Retrieve result and consume hasher instance. - fn result(self) -> Output; + fn finalize(self) -> Output; /// Retrieve result and reset hasher instance. /// /// This method sometimes can be more efficient compared to hasher /// re-creation. - fn result_reset(&mut self) -> Output; + fn finalize_reset(&mut self) -> Output; /// Reset hasher instance to its initial state. fn reset(&mut self); @@ -67,12 +67,12 @@ impl Digest for D { Update::chain(self, data) } - fn result(self) -> Output { - self.fixed_result() + fn finalize(self) -> Output { + self.finalize_fixed() } - fn result_reset(&mut self) -> Output { - let res = self.clone().fixed_result(); + fn finalize_reset(&mut self) -> Output { + let res = self.clone().finalize_fixed(); self.reset(); res } @@ -88,7 +88,7 @@ impl Digest for D { fn digest(data: &[u8]) -> Output { let mut hasher = Self::default(); Update::update(&mut hasher, data); - hasher.fixed_result() + hasher.finalize_fixed() } } diff --git a/digest/src/dyn_digest.rs b/digest/src/dyn_digest.rs index e9b56f6d0..cb039570c 100644 --- a/digest/src/dyn_digest.rs +++ b/digest/src/dyn_digest.rs @@ -13,10 +13,10 @@ pub trait DynDigest { fn update(&mut self, data: &[u8]); /// Retrieve result and reset hasher instance - fn result_reset(&mut self) -> Box<[u8]>; + fn finalize_reset(&mut self) -> Box<[u8]>; /// Retrieve result and consume boxed hasher instance - fn result(self: Box) -> Box<[u8]>; + fn finalize(self: Box) -> Box<[u8]>; /// Reset hasher instance to its initial state. fn reset(&mut self); @@ -33,14 +33,14 @@ impl DynDigest for D { Update::update(self, data); } - fn result_reset(&mut self) -> Box<[u8]> { - let res = self.clone().fixed_result().to_vec().into_boxed_slice(); + fn finalize_reset(&mut self) -> Box<[u8]> { + let res = self.clone().finalize_fixed().to_vec().into_boxed_slice(); Reset::reset(self); res } - fn result(self: Box) -> Box<[u8]> { - self.fixed_result().to_vec().into_boxed_slice() + fn finalize(self: Box) -> Box<[u8]> { + self.finalize_fixed().to_vec().into_boxed_slice() } fn reset(&mut self) { diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 8b322a8d8..5132f0ecd 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -77,7 +77,7 @@ pub trait FixedOutput { type OutputSize: ArrayLength; /// Retrieve result and consume hasher instance. - fn fixed_result(self) -> GenericArray; + fn finalize_fixed(self) -> GenericArray; } /// Trait for returning digest result with the variable size @@ -96,14 +96,14 @@ pub trait VariableOutput: core::marker::Sized { /// /// Closure is guaranteed to be called, length of the buffer passed to it /// will be equal to `output_size`. - fn variable_result(self, f: F); + fn finalize_variable(self, f: F); /// Retrieve result into vector and consume hasher. #[cfg(feature = "std")] #[cfg_attr(docsrs, doc(cfg(feature = "std")))] - fn vec_result(self) -> Vec { + fn finalize_vec(self) -> Vec { let mut buf = Vec::with_capacity(self.output_size()); - self.variable_result(|res| buf.extend_from_slice(res)); + self.finalize_variable(|res| buf.extend_from_slice(res)); buf } } @@ -121,14 +121,14 @@ pub trait ExtendableOutput: core::marker::Sized { type Reader: XofReader; /// Retrieve XOF reader and consume hasher instance. - fn xof_result(self) -> Self::Reader; + fn finalize_xof(self) -> Self::Reader; /// Retrieve result into vector of specified length. #[cfg(feature = "std")] #[cfg_attr(docsrs, doc(cfg(feature = "std")))] - fn vec_result(self, n: usize) -> Vec { + fn finalize_vec(self, n: usize) -> Vec { let mut buf = vec![0u8; n]; - self.xof_result().read(&mut buf); + self.finalize_xof().read(&mut buf); buf } } diff --git a/signature/tests/signature_derive.rs b/signature/tests/signature_derive.rs index d606abc8f..c4944b0b7 100644 --- a/signature/tests/signature_derive.rs +++ b/signature/tests/signature_derive.rs @@ -43,7 +43,7 @@ mod tests { impl DigestSigner for DummySigner { fn try_sign_digest(&self, digest: Sha256) -> Result { - DummySignature::from_bytes(&digest.result()) + DummySignature::from_bytes(&digest.finalize()) } } @@ -56,7 +56,7 @@ mod tests { impl DigestVerifier for DummyVerifier { fn verify_digest(&self, digest: Sha256, signature: &DummySignature) -> Result<(), Error> { - let actual_digest = digest.result(); + let actual_digest = digest.finalize(); assert_eq!(signature.as_ref(), actual_digest.as_ref()); Ok(()) } diff --git a/universal-hash/src/lib.rs b/universal-hash/src/lib.rs index 9976a3d66..a64021274 100644 --- a/universal-hash/src/lib.rs +++ b/universal-hash/src/lib.rs @@ -79,12 +79,12 @@ pub trait UniversalHash: Clone { fn reset(&mut self); /// Obtain the [`Output`] of a [`UniversalHash`] function and consume it. - fn result(self) -> Output; + fn finalize(self) -> Output; /// Obtain the [`Output`] of a [`UniversalHash`] computation and reset it back /// to its initial state. - fn result_reset(&mut self) -> Output { - let res = self.clone().result(); + fn finalize_reset(&mut self) -> Output { + let res = self.clone().finalize(); self.reset(); res } @@ -93,7 +93,7 @@ pub trait UniversalHash: Clone { /// This is useful when constructing Message Authentication Codes (MACs) /// from universal hash functions. fn verify(self, other: &Block) -> Result<(), Error> { - if self.result() == other.into() { + if self.finalize() == other.into() { Ok(()) } else { Err(Error) From fb0ace36efcab5fc1a111b5f267f8324ab2b61b4 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 2 Jun 2020 13:27:07 -0700 Subject: [PATCH 0112/1461] digest: add `alloc` feature Allows `DynDigest` and `*_vec` methods to function in `no_std` + `alloc` environments. --- .github/workflows/digest.yml | 1 + digest/Cargo.toml | 3 ++- digest/src/dyn_digest.rs | 4 ++-- digest/src/lib.rs | 21 ++++++++++++--------- 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/.github/workflows/digest.yml b/.github/workflows/digest.yml index aadaafc00..516d8ad80 100644 --- a/.github/workflows/digest.yml +++ b/.github/workflows/digest.yml @@ -52,5 +52,6 @@ jobs: - run: cargo check --all-features - run: cargo test --release - run: cargo test --features dev --release + - run: cargo test --features alloc --release - run: cargo test --features std --release - run: cargo test --all-features --release diff --git a/digest/Cargo.toml b/digest/Cargo.toml index f18cd93c1..724952df6 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -16,7 +16,8 @@ generic-array = "0.14" blobby = { version = "0.1", optional = true } [features] -std = [] +alloc = [] +std = ["alloc"] dev = ["blobby"] [package.metadata.docs.rs] diff --git a/digest/src/dyn_digest.rs b/digest/src/dyn_digest.rs index cb039570c..c836ab447 100644 --- a/digest/src/dyn_digest.rs +++ b/digest/src/dyn_digest.rs @@ -1,5 +1,5 @@ -#![cfg(feature = "std")] -use std::boxed::Box; +#![cfg(feature = "alloc")] +use alloc::boxed::Box; use super::{FixedOutput, Reset, Update}; use generic_array::typenum::Unsigned; diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 5132f0ecd..5e40d54e8 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -19,8 +19,11 @@ #![doc(html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png")] #![warn(missing_docs, rust_2018_idioms)] -#[cfg(feature = "std")] +#[cfg(feature = "alloc")] #[macro_use] +extern crate alloc; + +#[cfg(feature = "std")] extern crate std; #[cfg(feature = "dev")] @@ -35,14 +38,14 @@ pub use crate::digest::{Digest, Output}; pub use crate::errors::InvalidOutputSize; pub use generic_array::{self, typenum::consts}; -#[cfg(feature = "std")] -#[cfg_attr(docsrs, doc(cfg(feature = "std")))] +#[cfg(feature = "alloc")] +#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] pub use dyn_digest::DynDigest; use generic_array::{ArrayLength, GenericArray}; -#[cfg(feature = "std")] -use std::vec::Vec; +#[cfg(feature = "alloc")] +use alloc::vec::Vec; /// Trait for updating digest state with input data. pub trait Update { @@ -99,8 +102,8 @@ pub trait VariableOutput: core::marker::Sized { fn finalize_variable(self, f: F); /// Retrieve result into vector and consume hasher. - #[cfg(feature = "std")] - #[cfg_attr(docsrs, doc(cfg(feature = "std")))] + #[cfg(feature = "alloc")] + #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] fn finalize_vec(self) -> Vec { let mut buf = Vec::with_capacity(self.output_size()); self.finalize_variable(|res| buf.extend_from_slice(res)); @@ -124,8 +127,8 @@ pub trait ExtendableOutput: core::marker::Sized { fn finalize_xof(self) -> Self::Reader; /// Retrieve result into vector of specified length. - #[cfg(feature = "std")] - #[cfg_attr(docsrs, doc(cfg(feature = "std")))] + #[cfg(feature = "alloc")] + #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] fn finalize_vec(self, n: usize) -> Vec { let mut buf = vec![0u8; n]; self.finalize_xof().read(&mut buf); From 063cd27aa21c0cdf4c7bd67439958160a13223a3 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 2 Jun 2020 20:09:20 -0700 Subject: [PATCH 0113/1461] stream-cipher: add FromBlockCipher trait (fixes #32) (#164) Support for instantiating a stream cipher from a block cipher --- .github/workflows/stream-cipher.yml | 1 + Cargo.lock | 1 + stream-cipher/Cargo.toml | 8 ++++++- stream-cipher/src/dev.rs | 5 ++++ stream-cipher/src/lib.rs | 36 +++++++++++++++++++++++++++++ 5 files changed, 50 insertions(+), 1 deletion(-) diff --git a/.github/workflows/stream-cipher.yml b/.github/workflows/stream-cipher.yml index 5c101b93a..c6d9a535b 100644 --- a/.github/workflows/stream-cipher.yml +++ b/.github/workflows/stream-cipher.yml @@ -51,6 +51,7 @@ jobs: toolchain: ${{ matrix.rust }} - run: cargo check --all-features - run: cargo test --release + - run: cargo test --features block-cipher - run: cargo test --features dev --release - run: cargo test --features std --release - run: cargo test --all-features --release diff --git a/Cargo.lock b/Cargo.lock index 9a1ddc3f7..44f861d94 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -248,6 +248,7 @@ name = "stream-cipher" version = "0.4.0-pre" dependencies = [ "blobby", + "block-cipher", "generic-array 0.14.1", ] diff --git a/stream-cipher/Cargo.toml b/stream-cipher/Cargo.toml index f127c9a01..b45cc1a88 100644 --- a/stream-cipher/Cargo.toml +++ b/stream-cipher/Cargo.toml @@ -15,9 +15,15 @@ categories = ["cryptography", "no-std"] generic-array = "0.14" blobby = { version = "0.1", optional = true } +[dependencies.block-cipher] +version = "= 0.7.0-pre" +optional = true +path = "../block-cipher" + [features] std = [] dev = ["blobby"] [package.metadata.docs.rs] -features = [ "std" ] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] diff --git a/stream-cipher/src/dev.rs b/stream-cipher/src/dev.rs index 56e80ca64..cd5e080e3 100644 --- a/stream-cipher/src/dev.rs +++ b/stream-cipher/src/dev.rs @@ -4,6 +4,7 @@ pub use blobby; /// Test core functionality of synchronous stream cipher #[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] macro_rules! new_sync_test { ($name:ident, $cipher:ty, $test_name:expr) => { #[test] @@ -43,6 +44,7 @@ macro_rules! new_sync_test { /// Test stream synchronous stream cipher seeking capabilities #[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] macro_rules! new_seek_test { ($name:ident, $cipher:ty, $test_name:expr) => { #[test] @@ -85,6 +87,7 @@ macro_rules! new_seek_test { /// Test core functionality of asynchronous stream cipher #[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] macro_rules! new_async_test { ($name:ident, $test_name:expr, $cipher:ty) => { #[test] @@ -149,6 +152,7 @@ macro_rules! new_async_test { /// Create synchronous stream cipher benchmarks #[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] macro_rules! bench_sync { ($name:ident, $cipher:path, $data_len:expr) => { #[bench] @@ -187,6 +191,7 @@ macro_rules! bench_sync { /// Create synchronous stream cipher benchmarks #[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] macro_rules! bench_async { ($enc_name:ident, $dec_name:ident, $cipher:path, $data_len:expr) => { #[bench] diff --git a/stream-cipher/src/lib.rs b/stream-cipher/src/lib.rs index 8a2366905..1a056c832 100644 --- a/stream-cipher/src/lib.rs +++ b/stream-cipher/src/lib.rs @@ -5,6 +5,7 @@ //! for ciphers implementation. #![no_std] +#![cfg_attr(docsrs, feature(doc_cfg))] #![doc(html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png")] #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] @@ -13,6 +14,7 @@ extern crate std; #[cfg(feature = "dev")] +#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] pub mod dev; mod errors; @@ -23,6 +25,9 @@ pub use generic_array::{self, typenum::consts}; use generic_array::typenum::Unsigned; use generic_array::{ArrayLength, GenericArray}; +#[cfg(feature = "block-cipher")] +use block_cipher::{BlockCipher, NewBlockCipher}; + /// Stream cipher creation trait. /// /// It can be used for creation of synchronous and asynchronous ciphers. @@ -112,3 +117,34 @@ impl StreamCipher for C { SyncStreamCipher::apply_keystream(self, data); } } + +/// Trait for initializing a stream cipher from a block cipher +#[cfg(feature = "block-cipher")] +#[cfg_attr(docsrs, doc(cfg(feature = "block-cipher")))] +pub trait FromBlockCipher { + /// Block cipher + type BlockCipher: BlockCipher + NewBlockCipher; + + /// Instantiate a stream cipher from a block cipher + // TODO(tarcieri): add associated type for NonceSize? + fn from_block_cipher( + cipher: Self::BlockCipher, + nonce: &block_cipher::Block, + ) -> Self; +} + +#[cfg(feature = "block-cipher")] +impl NewStreamCipher for C +where + C: FromBlockCipher, +{ + type KeySize = <::BlockCipher as NewBlockCipher>::KeySize; + type NonceSize = <::BlockCipher as BlockCipher>::BlockSize; + + fn new(key: &GenericArray, nonce: &GenericArray) -> C { + C::from_block_cipher( + <::BlockCipher as NewBlockCipher>::new(key), + nonce, + ) + } +} From 9b804d6f70606bc6142e4242e7cb9b20acc596a0 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 3 Jun 2020 11:34:45 -0700 Subject: [PATCH 0114/1461] stream-cipher: re-export `block_cipher` when enabled --- stream-cipher/src/lib.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/stream-cipher/src/lib.rs b/stream-cipher/src/lib.rs index 1a056c832..505c67fb5 100644 --- a/stream-cipher/src/lib.rs +++ b/stream-cipher/src/lib.rs @@ -22,6 +22,9 @@ mod errors; pub use crate::errors::{InvalidKeyNonceLength, LoopError}; pub use generic_array::{self, typenum::consts}; +#[cfg(feature = "block-cipher")] +pub use block_cipher; + use generic_array::typenum::Unsigned; use generic_array::{ArrayLength, GenericArray}; From cebfee50542823f37b1a0bf33f40b27b8537ba28 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 3 Jun 2020 14:50:57 -0700 Subject: [PATCH 0115/1461] block-cipher/crypto-mac: add doc_cfg + comments Configures the `block-cipher` and `crypto-mac` crates to have `doc_cfg` about their cargo features. Adds some additional comments. --- block-cipher/Cargo.toml | 3 ++- block-cipher/src/dev.rs | 2 ++ block-cipher/src/lib.rs | 13 ++++++++++++- crypto-mac/Cargo.toml | 3 ++- crypto-mac/src/dev.rs | 2 ++ crypto-mac/src/lib.rs | 2 ++ 6 files changed, 22 insertions(+), 3 deletions(-) diff --git a/block-cipher/Cargo.toml b/block-cipher/Cargo.toml index a74a8842b..719235d7d 100644 --- a/block-cipher/Cargo.toml +++ b/block-cipher/Cargo.toml @@ -20,4 +20,5 @@ std = [] dev = ["blobby"] [package.metadata.docs.rs] -features = [ "std" ] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] diff --git a/block-cipher/src/dev.rs b/block-cipher/src/dev.rs index 7389b6434..eeaee9ac7 100644 --- a/block-cipher/src/dev.rs +++ b/block-cipher/src/dev.rs @@ -4,6 +4,7 @@ pub use blobby; /// Define test #[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] macro_rules! new_test { ($name:ident, $test_name:expr, $cipher:ty) => { #[test] @@ -109,6 +110,7 @@ macro_rules! new_test { /// Define benchmark #[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] macro_rules! bench { ($cipher:path, $key_len:expr) => { extern crate test; diff --git a/block-cipher/src/lib.rs b/block-cipher/src/lib.rs index 7c232de04..e7ea86e0d 100644 --- a/block-cipher/src/lib.rs +++ b/block-cipher/src/lib.rs @@ -1,7 +1,17 @@ //! This crate defines a set of simple traits used to define functionality of -//! block ciphers. +//! [block ciphers][1]. +//! +//! # About block ciphers +//! +//! Block ciphers are keyed, deterministic permutations of a fixed-sized input +//! "block" providing a reversible transformation to/from an encrypted output. +//! They are one of the fundamental structural components of [symmetric cryptography][2]. +//! +//! [1]: https://en.wikipedia.org/wiki/Block_cipher +//! [2]: https://en.wikipedia.org/wiki/Symmetric-key_algorithm #![no_std] +#![cfg_attr(docsrs, feature(doc_cfg))] #![doc(html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png")] #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] @@ -10,6 +20,7 @@ extern crate std; #[cfg(feature = "dev")] +#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] pub mod dev; mod errors; diff --git a/crypto-mac/Cargo.toml b/crypto-mac/Cargo.toml index 1d15fc8a0..90963b767 100644 --- a/crypto-mac/Cargo.toml +++ b/crypto-mac/Cargo.toml @@ -21,4 +21,5 @@ dev = ["blobby"] std = [] [package.metadata.docs.rs] -features = [ "std" ] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] diff --git a/crypto-mac/src/dev.rs b/crypto-mac/src/dev.rs index 4cdebe7b5..f338cab74 100644 --- a/crypto-mac/src/dev.rs +++ b/crypto-mac/src/dev.rs @@ -4,6 +4,7 @@ pub use blobby; /// Define test #[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] macro_rules! new_test { ($name:ident, $test_name:expr, $mac:ty) => { #[test] @@ -58,6 +59,7 @@ macro_rules! new_test { /// Define benchmark #[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] macro_rules! bench { ($name:ident, $engine:path, $bs:expr) => { #[bench] diff --git a/crypto-mac/src/lib.rs b/crypto-mac/src/lib.rs index 91683a77e..8b4768d6a 100644 --- a/crypto-mac/src/lib.rs +++ b/crypto-mac/src/lib.rs @@ -1,6 +1,7 @@ //! This crate provides trait for Message Authentication Code (MAC) algorithms. #![no_std] +#![cfg_attr(docsrs, feature(doc_cfg))] #![doc(html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png")] #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] @@ -9,6 +10,7 @@ extern crate std; #[cfg(feature = "dev")] +#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] pub mod dev; mod errors; From 4f05218e439617b9905ba79ef5c9055909dda665 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 4 Jun 2020 10:54:14 -0700 Subject: [PATCH 0116/1461] Add CHANGELOG.md templates Includes all versions and release dates --- aead/CHANGELOG.md | 14 +++++++++++ block-cipher/CHANGELOG.md | 33 +++++++++++++++++++++++++ crypto-mac/CHANGELOG.md | 25 ++++++++++++++++--- digest/CHANGELOG.md | 48 +++++++++++++++++++++++++++++++++++++ signature/CHANGELOG.md | 18 ++++++++++++++ stream-cipher/CHANGELOG.md | 22 +++++++++++++++++ universal-hash/CHANGELOG.md | 7 +++++- universal-hash/src/lib.rs | 2 ++ 8 files changed, 165 insertions(+), 4 deletions(-) create mode 100644 aead/CHANGELOG.md create mode 100644 block-cipher/CHANGELOG.md create mode 100644 digest/CHANGELOG.md create mode 100644 signature/CHANGELOG.md create mode 100644 stream-cipher/CHANGELOG.md diff --git a/aead/CHANGELOG.md b/aead/CHANGELOG.md new file mode 100644 index 000000000..e1df7d06b --- /dev/null +++ b/aead/CHANGELOG.md @@ -0,0 +1,14 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## 0.2.0 (2019-11-17) + +## 0.1.2 (2019-11-17) [YANKED] + +## 0.1.1 (2019-08-30) + +## 0.1.0 (2019-08-29) diff --git a/block-cipher/CHANGELOG.md b/block-cipher/CHANGELOG.md new file mode 100644 index 000000000..929b1faf6 --- /dev/null +++ b/block-cipher/CHANGELOG.md @@ -0,0 +1,33 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## 0.6.2 (2018-11-14) + +## 0.6.1 (2018-10-04) + +## 0.6.0 (2018-10-02) + +## 0.5.3 (2018-07-27) + +## 0.5.2 (2018-06-21) + +## 0.5.1 (2018-06-20) + +## 0.5.0 (2017-11-26) + +## 0.4.2 (2017-09-05) + +## 0.4.1 (2017-09-05) + +## 0.4.0 (2017-09-05) + +## 0.3.0 (2016-12-24) + +## 0.2.0 (2016-12-16) + +## 0.1.0 (2016-12-16) + diff --git a/crypto-mac/CHANGELOG.md b/crypto-mac/CHANGELOG.md index 2a44825bc..8aa7b651c 100644 --- a/crypto-mac/CHANGELOG.md +++ b/crypto-mac/CHANGELOG.md @@ -1,9 +1,28 @@ # Changelog + All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [Unreleased] -### Changed -- `subtle` is updated from `v1` to `v2`. +## 0.7.0 (2018-10-01) + +## 0.6.2 (2018-06-21) + +## 0.6.1 (2018-06-20) + +## 0.6.0 (2017-11-26) + +## 0.5.2 (2017-11-20) + +## 0.5.1 (2017-11-15) + +## 0.5.0 (2017-11-14) + +## 0.4.0 (2017-06-12) + +## 0.3.0 (2017-05-14) + +## 0.2.0 (2017-05-14) + +## 0.1.0 (2016-10-14) diff --git a/digest/CHANGELOG.md b/digest/CHANGELOG.md new file mode 100644 index 000000000..c105f80cb --- /dev/null +++ b/digest/CHANGELOG.md @@ -0,0 +1,48 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## 0.8.1 (2019-06-30) + +## 0.8.0 (2018-10-01) + +## 0.7.6 (2018-09-21) + +## 0.7.5 (2018-07-13) + +## 0.7.4 (2018-06-21) + +## 0.7.3 (2018-06-20) + +## 0.7.2 (2017-11-17) + +## 0.7.1 (2017-11-15) + +## 0.7.0 (2017-11-14) + +## 0.6.2 (2017-07-24) + +## 0.6.1 (2017-06-18) + +## 0.6.0 (2017-06-12) + +## 0.5.2 (2017-05-02) + +## 0.5.1 (2017-05-02) + +## 0.5.0 (2017-04-06) + +## 0.4.0 (2016-12-24) + +## 0.3.1 (2016-12-16) + +## 0.3.0 (2016-11-17) + +## 0.2.1 (2016-10-14) + +## 0.2.0 (2016-10-14) + +## 0.1.0 (2016-10-06) diff --git a/signature/CHANGELOG.md b/signature/CHANGELOG.md new file mode 100644 index 000000000..d9fbc2f23 --- /dev/null +++ b/signature/CHANGELOG.md @@ -0,0 +1,18 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## 1.0.1 (2020-04-19) + +- Update `signature_derive` to v1.0.0-pre.2 + +## 1.0.0 (2020-04-18) + +## 0.3.0 (2019-10-10) + +## 0.2.0 (2019-06-07) + +## 0.1.0 (2019-05-25) diff --git a/stream-cipher/CHANGELOG.md b/stream-cipher/CHANGELOG.md new file mode 100644 index 000000000..bbdfbabae --- /dev/null +++ b/stream-cipher/CHANGELOG.md @@ -0,0 +1,22 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## 0.3.2 (2019-08-18) + +## 0.3.1 (2019-08-17) + +## 0.3.0 (2018-11-01) + +## 0.2.2 (2018-10-16) + +## 0.2.1 (2018-10-04) + +## 0.2.0 (2018-10-03) + +## 0.1.1 (2018-08-08) + +## 0.1.0 (2018-07-27) diff --git a/universal-hash/CHANGELOG.md b/universal-hash/CHANGELOG.md index b7876bd4d..e526404b9 100644 --- a/universal-hash/CHANGELOG.md +++ b/universal-hash/CHANGELOG.md @@ -1,9 +1,15 @@ # Changelog + All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.3.0 (2019-10-03) +- Rename `OutputSize` -> `BlockSize` ([#57]) + +[#57]: https://github.com/RustCrypto/traits/pull/57 + ## 0.2.0 (2019-08-31) ### Changed - Split KeySize/OutputSize ([#55]) @@ -11,5 +17,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [#55]: https://github.com/RustCrypto/traits/pull/55 ## 0.1.0 (2019-08-30) - - Initial release diff --git a/universal-hash/src/lib.rs b/universal-hash/src/lib.rs index a64021274..815affc07 100644 --- a/universal-hash/src/lib.rs +++ b/universal-hash/src/lib.rs @@ -1,5 +1,7 @@ //! Traits for [Universal Hash Functions]. //! +//! # About universal hashes +//! //! Universal hash functions provide a "universal family" of possible //! hash functions where a given member of a family is selected by a key. //! From 88c2303fbe7b60c8154629d69a17d243f30e1b1e Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 4 Jun 2020 14:30:24 -0700 Subject: [PATCH 0117/1461] block-cipher v0.7.0 --- Cargo.lock | 2 +- block-cipher/CHANGELOG.md | 12 ++++++++++++ block-cipher/Cargo.toml | 2 +- stream-cipher/Cargo.toml | 2 +- 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 44f861d94..357b70ab0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -42,7 +42,7 @@ dependencies = [ [[package]] name = "block-cipher" -version = "0.7.0-pre" +version = "0.7.0" dependencies = [ "blobby", "generic-array 0.14.1", diff --git a/block-cipher/CHANGELOG.md b/block-cipher/CHANGELOG.md index 929b1faf6..c54a8b9db 100644 --- a/block-cipher/CHANGELOG.md +++ b/block-cipher/CHANGELOG.md @@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.7.0 (2020-06-04) +### Changed +- Crate renamed from `block-cipher-trait` to `block-cipher` ([#139]) +- Split `BlockCipher` initialization into `NewBlockCipher` trait ([#132]) +- Update to Rust 2018 edition ([#107]) +- Bump `generic-array` dependency to v0.14 ([#95]) + +[#139]: https://github.com/RustCrypto/traits/issues/139 +[#132]: https://github.com/RustCrypto/traits/issues/132 +[#107]: https://github.com/RustCrypto/traits/issues/107 +[#95]: https://github.com/RustCrypto/traits/pull/95 + ## 0.6.2 (2018-11-14) ## 0.6.1 (2018-10-04) diff --git a/block-cipher/Cargo.toml b/block-cipher/Cargo.toml index 719235d7d..c4bf980e2 100644 --- a/block-cipher/Cargo.toml +++ b/block-cipher/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "block-cipher" description = "Traits for description of block ciphers" -version = "0.7.0-pre" +version = "0.7.0" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/stream-cipher/Cargo.toml b/stream-cipher/Cargo.toml index b45cc1a88..a4fb19be4 100644 --- a/stream-cipher/Cargo.toml +++ b/stream-cipher/Cargo.toml @@ -16,7 +16,7 @@ generic-array = "0.14" blobby = { version = "0.1", optional = true } [dependencies.block-cipher] -version = "= 0.7.0-pre" +version = "0.7" optional = true path = "../block-cipher" From 50147543e6c401a11f58bfa5587512fde81d5db9 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 4 Jun 2020 15:15:06 -0700 Subject: [PATCH 0118/1461] crypto-mac v0.8.0 --- Cargo.lock | 2 +- block-cipher/CHANGELOG.md | 2 +- crypto-mac/CHANGELOG.md | 20 ++++++++++++++++++++ crypto-mac/Cargo.toml | 2 +- 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 357b70ab0..d36d2b8f4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -71,7 +71,7 @@ checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" [[package]] name = "crypto-mac" -version = "0.8.0-pre" +version = "0.8.0" dependencies = [ "blobby", "generic-array 0.14.1", diff --git a/block-cipher/CHANGELOG.md b/block-cipher/CHANGELOG.md index c54a8b9db..83b2d67d2 100644 --- a/block-cipher/CHANGELOG.md +++ b/block-cipher/CHANGELOG.md @@ -8,7 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## 0.7.0 (2020-06-04) ### Changed - Crate renamed from `block-cipher-trait` to `block-cipher` ([#139]) -- Split `BlockCipher` initialization into `NewBlockCipher` trait ([#132]) +- Split `BlockCipher` initialization into `NewBlockCipher` trait ([#132]) - Update to Rust 2018 edition ([#107]) - Bump `generic-array` dependency to v0.14 ([#95]) diff --git a/crypto-mac/CHANGELOG.md b/crypto-mac/CHANGELOG.md index 8aa7b651c..b0eb5094b 100644 --- a/crypto-mac/CHANGELOG.md +++ b/crypto-mac/CHANGELOG.md @@ -5,6 +5,26 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.8.0 (2020-06-04) +### Added +- `impl_write!` macro ([#134]) + +### Changed +- Bump `generic-array` dependency to v0.14 ([#144]) +- Split `Mac` initialization into `NewMac` trait ([#133]) +- Rename `MacResult` => `Output`, `code` => `into_bytes` ([#114]) +- Rename `Input::input` to `Update::update` ([#111]) +- Update to 2018 edition ([#108]) +- Bump `subtle` dependency from v1.0 to v2.0 ([#33]) + +[#144]: https://github.com/RustCrypto/traits/pull/95 +[#134]: https://github.com/RustCrypto/traits/pull/134 +[#133]: https://github.com/RustCrypto/traits/pull/133 +[#114]: https://github.com/RustCrypto/traits/pull/114 +[#111]: https://github.com/RustCrypto/traits/pull/111 +[#108]: https://github.com/RustCrypto/traits/pull/108 +[#33]: https://github.com/RustCrypto/traits/pull/33 + ## 0.7.0 (2018-10-01) ## 0.6.2 (2018-06-21) diff --git a/crypto-mac/Cargo.toml b/crypto-mac/Cargo.toml index 90963b767..569f192d5 100644 --- a/crypto-mac/Cargo.toml +++ b/crypto-mac/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crypto-mac" description = "Trait for Message Authentication Code (MAC) algorithms" -version = "0.8.0-pre" +version = "0.8.0" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" From 12fbc1023d687bc053f02f83d559bd78051f0db8 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 4 Jun 2020 15:40:33 -0700 Subject: [PATCH 0119/1461] stream-cipher v0.4.0 (#170) --- Cargo.lock | 2 +- stream-cipher/CHANGELOG.md | 12 ++++++++++++ stream-cipher/Cargo.toml | 2 +- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d36d2b8f4..393a4dec2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -245,7 +245,7 @@ checksum = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" [[package]] name = "stream-cipher" -version = "0.4.0-pre" +version = "0.4.0" dependencies = [ "blobby", "block-cipher", diff --git a/stream-cipher/CHANGELOG.md b/stream-cipher/CHANGELOG.md index bbdfbabae..a2462eaa2 100644 --- a/stream-cipher/CHANGELOG.md +++ b/stream-cipher/CHANGELOG.md @@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.4.0 (2020-06-04) +### Added +- `FromBlockCipher` trait ([#164]) + +### Changed +- Update to 2018 edition ([#110]) +- Bump `generic-array` dependency to v0.14 ([#95]) + +[#164]: https://github.com/RustCrypto/traits/issues/164 +[#110]: https://github.com/RustCrypto/traits/issues/110 +[#95]: https://github.com/RustCrypto/traits/pull/95 + ## 0.3.2 (2019-08-18) ## 0.3.1 (2019-08-17) diff --git a/stream-cipher/Cargo.toml b/stream-cipher/Cargo.toml index a4fb19be4..220e51de5 100644 --- a/stream-cipher/Cargo.toml +++ b/stream-cipher/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "stream-cipher" description = "Stream cipher traits" -version = "0.4.0-pre" +version = "0.4.0" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" From 188acca0877d4b316a3e8a3dc1e1e251933b3286 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 4 Jun 2020 15:55:51 -0700 Subject: [PATCH 0120/1461] universal-hash v0.4.0 (#171) --- Cargo.lock | 2 +- universal-hash/CHANGELOG.md | 14 ++++++++++++++ universal-hash/Cargo.toml | 2 +- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 393a4dec2..221607553 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -295,7 +295,7 @@ checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" [[package]] name = "universal-hash" -version = "0.4.0-pre" +version = "0.4.0" dependencies = [ "generic-array 0.14.1", "subtle", diff --git a/universal-hash/CHANGELOG.md b/universal-hash/CHANGELOG.md index e526404b9..1879015a6 100644 --- a/universal-hash/CHANGELOG.md +++ b/universal-hash/CHANGELOG.md @@ -5,6 +5,20 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.4.0 (2020-06-04) +### Added +- `Key` and `Block` type aliases ([#128]) + +### Changed +- Split `UniversalHash` initialization into `NewUniversalHash` trait ([#135]) +- Rename `update_block` => `update` ([#129]) +- Bump `generic-array` dependency to v0.14 ([#95]) + +[#135]: https://github.com/RustCrypto/traits/pull/135 +[#129]: https://github.com/RustCrypto/traits/pull/129 +[#128]: https://github.com/RustCrypto/traits/pull/128 +[#95]: https://github.com/RustCrypto/traits/pull/95 + ## 0.3.0 (2019-10-03) - Rename `OutputSize` -> `BlockSize` ([#57]) diff --git a/universal-hash/Cargo.toml b/universal-hash/Cargo.toml index 963e01773..143e5f8cd 100644 --- a/universal-hash/Cargo.toml +++ b/universal-hash/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "universal-hash" -version = "0.4.0-pre" +version = "0.4.0" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" description = "Trait for universal hash functions" From 6fb688f60e2bb21370ef1d6f549b112f2039c02e Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 4 Jun 2020 16:04:33 -0700 Subject: [PATCH 0121/1461] signature: rename CHANGES.md => CHANGELOG.md (#172) --- signature/CHANGELOG.md | 94 +++++++++++++++- signature/CHANGES.md | 106 ------------------ .../{CHANGES.md => CHANGELOG.md} | 0 3 files changed, 91 insertions(+), 109 deletions(-) delete mode 100644 signature/CHANGES.md rename signature/signature_derive/{CHANGES.md => CHANGELOG.md} (100%) diff --git a/signature/CHANGELOG.md b/signature/CHANGELOG.md index d9fbc2f23..70632f818 100644 --- a/signature/CHANGELOG.md +++ b/signature/CHANGELOG.md @@ -1,18 +1,106 @@ # Changelog - All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## 1.0.1 (2020-04-19) +### Changed +- Upgrade `signature_derive` to v1.0.0-pre.2 ([#98]) -- Update `signature_derive` to v1.0.0-pre.2 +[#98]: https://github.com/RustCrypto/traits/pull/98 ## 1.0.0 (2020-04-18) +Initial 1.0 release! 🎉 + +### Changed +- Rename `DigestSignature` => `PrehashSignature` ([#96]) + +[#96]: https://github.com/RustCrypto/traits/pull/96 + +## 1.0.0-pre.5 (2020-03-16) +### Changed +- Improve `Debug` impl on `Error` ([#89]) +- Rename `Signature::as_slice` -> `as_bytes` ([#87]) + +[#89]: https://github.com/RustCrypto/traits/pull/89 +[#87]: https://github.com/RustCrypto/traits/pull/87 + +## 1.0.0-pre.4 (2020-03-15) +### Added +- Mark preview features as unstable in `Cargo.toml` ([#82]) + +### Changed +- Have `Signature::from_bytes` take a byte slice ([#84]) +- Ensure `Error::new()` is mandatory ([#83]) + +### Removed +- `BoxError` type alias ([#81]) + +[#84]: https://github.com/RustCrypto/traits/pull/84 +[#83]: https://github.com/RustCrypto/traits/pull/83 +[#82]: https://github.com/RustCrypto/traits/pull/82 +[#81]: https://github.com/RustCrypto/traits/pull/81 + +## 1.0.0-pre.3 (2020-03-08) +### Fixed +- docs.rs rendering ([#76]) + +[#76]: https://github.com/RustCrypto/traits/pull/76 + +## 1.0.0-pre.2 (2020-03-08) +### Added +- `RandomizedSigner` trait ([#73]) +- Design documentation ([#72]) + +### Changed +- Error cleanups ([#74]) +- Crate moved to `RustCrypto/traits` ([#71]) + +[#74]: https://github.com/RustCrypto/traits/pull/74 +[#73]: https://github.com/RustCrypto/traits/pull/73 +[#72]: https://github.com/RustCrypto/traits/pull/72 +[#71]: https://github.com/RustCrypto/traits/pull/71 + +## 1.0.0-pre.1 (2019-10-27) +### Changed +- Use `Error::source` instead of `::cause` ([RustCrypto/signatures#37]) + +### Removed +- Remove `alloc` feature; MSRV 1.34+ ([RustCrypto/signatures#38]) + +[RustCrypto/signatures#38]: https://github.com/RustCrypto/signatures/pull/38 +[RustCrypto/signatures#37]: https://github.com/RustCrypto/signatures/pull/37 + +## 1.0.0-pre.0 (2019-10-11) +### Changed +- Revert removal of `DigestSignature` ([RustCrypto/signatures#33]) +- 1.0 stabilization proposal ([RustCrypto/signatures#32]) + +[RustCrypto/signatures#33]: https://github.com/RustCrypto/signatures/pull/33 +[RustCrypto/signatures#32]: https://github.com/RustCrypto/signatures/pull/32 + ## 0.3.0 (2019-10-10) +### Changed +- Simplify alloc gating; MSRV 1.36+ ([RustCrypto/signatures#28]) +- Replace `DigestSignature` trait with `#[digest(...)]` attribute ([RustCrypto/signatures#27]) +- signature_derive: Upgrade to 1.x proc macro crates ([RustCrypto/signatures#26]) + +[RustCrypto/signatures#28]: https://github.com/RustCrypto/signatures/pull/28 +[RustCrypto/signatures#27]: https://github.com/RustCrypto/signatures/pull/27 +[RustCrypto/signatures#26]: https://github.com/RustCrypto/signatures/pull/27 -## 0.2.0 (2019-06-07) +## 0.2.0 (2019-06-06) +### Added +- `signature_derive`: Custom derive support for `Signer`/`Verifier` ([RustCrypto/signatures#18]) + +### Changed +- Have `DigestSigner`/`DigestVerifier` take `Digest` instance ([RustCrypto/signatures#17]) + +[RustCrypto/signatures#18]: https://github.com/RustCrypto/signatures/pull/18 +[RustCrypto/signatures#17]: https://github.com/RustCrypto/signatures/pull/17 ## 0.1.0 (2019-05-25) + +- Initial release diff --git a/signature/CHANGES.md b/signature/CHANGES.md deleted file mode 100644 index 70632f818..000000000 --- a/signature/CHANGES.md +++ /dev/null @@ -1,106 +0,0 @@ -# Changelog -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## 1.0.1 (2020-04-19) -### Changed -- Upgrade `signature_derive` to v1.0.0-pre.2 ([#98]) - -[#98]: https://github.com/RustCrypto/traits/pull/98 - -## 1.0.0 (2020-04-18) - -Initial 1.0 release! 🎉 - -### Changed -- Rename `DigestSignature` => `PrehashSignature` ([#96]) - -[#96]: https://github.com/RustCrypto/traits/pull/96 - -## 1.0.0-pre.5 (2020-03-16) -### Changed -- Improve `Debug` impl on `Error` ([#89]) -- Rename `Signature::as_slice` -> `as_bytes` ([#87]) - -[#89]: https://github.com/RustCrypto/traits/pull/89 -[#87]: https://github.com/RustCrypto/traits/pull/87 - -## 1.0.0-pre.4 (2020-03-15) -### Added -- Mark preview features as unstable in `Cargo.toml` ([#82]) - -### Changed -- Have `Signature::from_bytes` take a byte slice ([#84]) -- Ensure `Error::new()` is mandatory ([#83]) - -### Removed -- `BoxError` type alias ([#81]) - -[#84]: https://github.com/RustCrypto/traits/pull/84 -[#83]: https://github.com/RustCrypto/traits/pull/83 -[#82]: https://github.com/RustCrypto/traits/pull/82 -[#81]: https://github.com/RustCrypto/traits/pull/81 - -## 1.0.0-pre.3 (2020-03-08) -### Fixed -- docs.rs rendering ([#76]) - -[#76]: https://github.com/RustCrypto/traits/pull/76 - -## 1.0.0-pre.2 (2020-03-08) -### Added -- `RandomizedSigner` trait ([#73]) -- Design documentation ([#72]) - -### Changed -- Error cleanups ([#74]) -- Crate moved to `RustCrypto/traits` ([#71]) - -[#74]: https://github.com/RustCrypto/traits/pull/74 -[#73]: https://github.com/RustCrypto/traits/pull/73 -[#72]: https://github.com/RustCrypto/traits/pull/72 -[#71]: https://github.com/RustCrypto/traits/pull/71 - -## 1.0.0-pre.1 (2019-10-27) -### Changed -- Use `Error::source` instead of `::cause` ([RustCrypto/signatures#37]) - -### Removed -- Remove `alloc` feature; MSRV 1.34+ ([RustCrypto/signatures#38]) - -[RustCrypto/signatures#38]: https://github.com/RustCrypto/signatures/pull/38 -[RustCrypto/signatures#37]: https://github.com/RustCrypto/signatures/pull/37 - -## 1.0.0-pre.0 (2019-10-11) -### Changed -- Revert removal of `DigestSignature` ([RustCrypto/signatures#33]) -- 1.0 stabilization proposal ([RustCrypto/signatures#32]) - -[RustCrypto/signatures#33]: https://github.com/RustCrypto/signatures/pull/33 -[RustCrypto/signatures#32]: https://github.com/RustCrypto/signatures/pull/32 - -## 0.3.0 (2019-10-10) -### Changed -- Simplify alloc gating; MSRV 1.36+ ([RustCrypto/signatures#28]) -- Replace `DigestSignature` trait with `#[digest(...)]` attribute ([RustCrypto/signatures#27]) -- signature_derive: Upgrade to 1.x proc macro crates ([RustCrypto/signatures#26]) - -[RustCrypto/signatures#28]: https://github.com/RustCrypto/signatures/pull/28 -[RustCrypto/signatures#27]: https://github.com/RustCrypto/signatures/pull/27 -[RustCrypto/signatures#26]: https://github.com/RustCrypto/signatures/pull/27 - -## 0.2.0 (2019-06-06) -### Added -- `signature_derive`: Custom derive support for `Signer`/`Verifier` ([RustCrypto/signatures#18]) - -### Changed -- Have `DigestSigner`/`DigestVerifier` take `Digest` instance ([RustCrypto/signatures#17]) - -[RustCrypto/signatures#18]: https://github.com/RustCrypto/signatures/pull/18 -[RustCrypto/signatures#17]: https://github.com/RustCrypto/signatures/pull/17 - -## 0.1.0 (2019-05-25) - -- Initial release diff --git a/signature/signature_derive/CHANGES.md b/signature/signature_derive/CHANGELOG.md similarity index 100% rename from signature/signature_derive/CHANGES.md rename to signature/signature_derive/CHANGELOG.md From 5ff18d29828b17bf404c96035f361b265ae495ad Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 4 Jun 2020 16:09:06 -0700 Subject: [PATCH 0122/1461] signature: rename `signature_derive` dir => `derive` (#173) --- signature/Cargo.toml | 2 +- signature/derive/CHANGES.md | 18 ++++++++++++++++++ .../{signature_derive => derive}/Cargo.toml | 2 +- .../{signature_derive => derive}/README.md | 0 .../{signature_derive => derive}/src/lib.rs | 0 5 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 signature/derive/CHANGES.md rename signature/{signature_derive => derive}/Cargo.toml (95%) rename signature/{signature_derive => derive}/README.md (100%) rename signature/{signature_derive => derive}/src/lib.rs (100%) diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 0f4b835f8..74151f677 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -25,7 +25,7 @@ default-features = false [dependencies.signature_derive] version = "= 1.0.0-pre.2" optional = true -path = "signature_derive" +path = "derive" [dev-dependencies] hex-literal = "0.2" diff --git a/signature/derive/CHANGES.md b/signature/derive/CHANGES.md new file mode 100644 index 000000000..eb7886b25 --- /dev/null +++ b/signature/derive/CHANGES.md @@ -0,0 +1,18 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## 1.0.0-pre.2 (2020-04-19) +### Changed +- Rename `DigestSignature` => `PrehashSignature` ([#96]) + +[#96]: https://github.com/RustCrypto/traits/pull/96 + +## 1.0.0-pre.1 (2020-03-08) +### Added +- Initial Changelog for `signature_derive` +- Rustdoc ([#79]) + +[#79]: https://github.com/RustCrypto/traits/pull/79 diff --git a/signature/signature_derive/Cargo.toml b/signature/derive/Cargo.toml similarity index 95% rename from signature/signature_derive/Cargo.toml rename to signature/derive/Cargo.toml index 22a689b62..836e7baa7 100644 --- a/signature/signature_derive/Cargo.toml +++ b/signature/derive/Cargo.toml @@ -5,7 +5,7 @@ authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" description = "Custom derive support for the 'signature' crate" documentation = "https://docs.rs/signature" -repository = "https://github.com/RustCrypto/traits/tree/master/signature/signature_derive" +repository = "https://github.com/RustCrypto/traits/tree/master/signature/derive" readme = "README.md" edition = "2018" keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"] diff --git a/signature/signature_derive/README.md b/signature/derive/README.md similarity index 100% rename from signature/signature_derive/README.md rename to signature/derive/README.md diff --git a/signature/signature_derive/src/lib.rs b/signature/derive/src/lib.rs similarity index 100% rename from signature/signature_derive/src/lib.rs rename to signature/derive/src/lib.rs From 2769ec10b5af69094dbcff70f3bde7106b7b6d87 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 4 Jun 2020 16:09:46 -0700 Subject: [PATCH 0123/1461] =?UTF-8?q?README.md:=20non=E2=80=91breaking=20h?= =?UTF-8?q?yphens?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ecfac1fe9..d9e15b5de 100644 --- a/README.md +++ b/README.md @@ -7,12 +7,12 @@ Collection of traits which describe functionality of cryptographic primitives. | Name | Algorithm | Crates.io | Documentation | Build | |--------------------|-------------------------------|-----------|----------------|-------| | [`aead`] | [Authenticated encryption] | [![crates.io](https://img.shields.io/crates/v/aead.svg)](https://crates.io/crates/aead) | [![Documentation](https://docs.rs/aead/badge.svg)](https://docs.rs/aead) | ![build](https://github.com/RustCrypto/traits/workflows/aead/badge.svg?branch=master&event=push) | -| [`block-cipher`] | [Block cipher] | [![crates.io](https://img.shields.io/crates/v/block-cipher.svg)](https://crates.io/crates/block-cipher) | [![Documentation](https://docs.rs/block-cipher/badge.svg)](https://docs.rs/block-cipher) | ![build](https://github.com/RustCrypto/traits/workflows/block-cipher/badge.svg?branch=master&event=push) | +| [`block‑cipher`] | [Block cipher] | [![crates.io](https://img.shields.io/crates/v/block-cipher.svg)](https://crates.io/crates/block-cipher) | [![Documentation](https://docs.rs/block-cipher/badge.svg)](https://docs.rs/block-cipher) | ![build](https://github.com/RustCrypto/traits/workflows/block-cipher/badge.svg?branch=master&event=push) | | [`crypto-mac`] | [Message authentication code] | [![crates.io](https://img.shields.io/crates/v/crypto-mac.svg)](https://crates.io/crates/crypto-mac) | [![Documentation](https://docs.rs/crypto-mac/badge.svg)](https://docs.rs/crypto-mac) | ![build](https://github.com/RustCrypto/traits/workflows/crypto-mac/badge.svg?branch=master&event=push) | | [`digest`] | [Cryptographic hash function] | [![crates.io](https://img.shields.io/crates/v/digest.svg)](https://crates.io/crates/digest) | [![Documentation](https://docs.rs/digest/badge.svg)](https://docs.rs/digest) | ![build](https://github.com/RustCrypto/traits/workflows/digest/badge.svg?branch=master&event=push) | | [`signature`] | [Digital signature] | [![crates.io](https://img.shields.io/crates/v/signature.svg)](https://crates.io/crates/signature) | [![Documentation](https://docs.rs/signature/badge.svg)](https://docs.rs/signature) | ![build](https://github.com/RustCrypto/traits/workflows/signature/badge.svg?branch=master&event=push) | -| [`stream-cipher`] | [Stream cipher] | [![crates.io](https://img.shields.io/crates/v/stream-cipher.svg)](https://crates.io/crates/stream-cipher) | [![Documentation](https://docs.rs/stream-cipher/badge.svg)](https://docs.rs/stream-cipher) | ![build](https://github.com/RustCrypto/traits/workflows/stream-cipher/badge.svg?branch=master&event=push) | -| [`universal-hash`] | [Universal hash function] | [![crates.io](https://img.shields.io/crates/v/universal-hash.svg)](https://crates.io/crates/universal-hash) | [![Documentation](https://docs.rs/universal-hash/badge.svg)](https://docs.rs/universal-hash) | ![build](https://github.com/RustCrypto/traits/workflows/universal-hash/badge.svg?branch=master&event=push) | +| [`stream‑cipher`] | [Stream cipher] | [![crates.io](https://img.shields.io/crates/v/stream-cipher.svg)](https://crates.io/crates/stream-cipher) | [![Documentation](https://docs.rs/stream-cipher/badge.svg)](https://docs.rs/stream-cipher) | ![build](https://github.com/RustCrypto/traits/workflows/stream-cipher/badge.svg?branch=master&event=push) | +| [`universal‑hash`] | [Universal hash function] | [![crates.io](https://img.shields.io/crates/v/universal-hash.svg)](https://crates.io/crates/universal-hash) | [![Documentation](https://docs.rs/universal-hash/badge.svg)](https://docs.rs/universal-hash) | ![build](https://github.com/RustCrypto/traits/workflows/universal-hash/badge.svg?branch=master&event=push) | ### Minimum Rust version From b7a2165d1bcc8e57ae485d0217d55fd7d154ddf0 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 4 Jun 2020 16:10:55 -0700 Subject: [PATCH 0124/1461] README.md: fix links --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index d9e15b5de..37384d84f 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Collection of traits which describe functionality of cryptographic primitives. |--------------------|-------------------------------|-----------|----------------|-------| | [`aead`] | [Authenticated encryption] | [![crates.io](https://img.shields.io/crates/v/aead.svg)](https://crates.io/crates/aead) | [![Documentation](https://docs.rs/aead/badge.svg)](https://docs.rs/aead) | ![build](https://github.com/RustCrypto/traits/workflows/aead/badge.svg?branch=master&event=push) | | [`block‑cipher`] | [Block cipher] | [![crates.io](https://img.shields.io/crates/v/block-cipher.svg)](https://crates.io/crates/block-cipher) | [![Documentation](https://docs.rs/block-cipher/badge.svg)](https://docs.rs/block-cipher) | ![build](https://github.com/RustCrypto/traits/workflows/block-cipher/badge.svg?branch=master&event=push) | -| [`crypto-mac`] | [Message authentication code] | [![crates.io](https://img.shields.io/crates/v/crypto-mac.svg)](https://crates.io/crates/crypto-mac) | [![Documentation](https://docs.rs/crypto-mac/badge.svg)](https://docs.rs/crypto-mac) | ![build](https://github.com/RustCrypto/traits/workflows/crypto-mac/badge.svg?branch=master&event=push) | +| [`crypto‑mac`] | [Message authentication code] | [![crates.io](https://img.shields.io/crates/v/crypto-mac.svg)](https://crates.io/crates/crypto-mac) | [![Documentation](https://docs.rs/crypto-mac/badge.svg)](https://docs.rs/crypto-mac) | ![build](https://github.com/RustCrypto/traits/workflows/crypto-mac/badge.svg?branch=master&event=push) | | [`digest`] | [Cryptographic hash function] | [![crates.io](https://img.shields.io/crates/v/digest.svg)](https://crates.io/crates/digest) | [![Documentation](https://docs.rs/digest/badge.svg)](https://docs.rs/digest) | ![build](https://github.com/RustCrypto/traits/workflows/digest/badge.svg?branch=master&event=push) | | [`signature`] | [Digital signature] | [![crates.io](https://img.shields.io/crates/v/signature.svg)](https://crates.io/crates/signature) | [![Documentation](https://docs.rs/signature/badge.svg)](https://docs.rs/signature) | ![build](https://github.com/RustCrypto/traits/workflows/signature/badge.svg?branch=master&event=push) | | [`stream‑cipher`] | [Stream cipher] | [![crates.io](https://img.shields.io/crates/v/stream-cipher.svg)](https://crates.io/crates/stream-cipher) | [![Documentation](https://docs.rs/stream-cipher/badge.svg)](https://docs.rs/stream-cipher) | ![build](https://github.com/RustCrypto/traits/workflows/stream-cipher/badge.svg?branch=master&event=push) | @@ -43,12 +43,12 @@ dual licensed as above, without any additional terms or conditions. [//]: # (crates) [`aead`]: https://github.com/RustCrypto/traits/tree/master/aead -[`block-cipher`]: https://github.com/RustCrypto/traits/tree/master/block-cipher -[`crypto-mac`]: https://github.com/RustCrypto/traits/tree/master/crypto-mac +[`block‑cipher`]: https://github.com/RustCrypto/traits/tree/master/block-cipher +[`crypto‑mac`]: https://github.com/RustCrypto/traits/tree/master/crypto-mac [`digest`]: https://github.com/RustCrypto/traits/tree/master/digest [`signature`]: https://github.com/RustCrypto/traits/tree/master/signature -[`stream-cipher`]: https://github.com/RustCrypto/traits/tree/master/stream-cipher -[`universal-hash`]: https://github.com/RustCrypto/traits/tree/master/universal-hash +[`stream‑cipher`]: https://github.com/RustCrypto/traits/tree/master/stream-cipher +[`universal‑hash`]: https://github.com/RustCrypto/traits/tree/master/universal-hash [//]: # (algorithms) From 95ae635c56f28a67292ac7fc77eb55c44d335b51 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 4 Jun 2020 17:18:27 -0700 Subject: [PATCH 0125/1461] aead v0.3.0 (#174) --- Cargo.lock | 2 +- aead/CHANGELOG.md | 16 ++++++++++++++++ aead/Cargo.toml | 2 +- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 221607553..f2c515928 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,7 +2,7 @@ # It is not intended for manual editing. [[package]] name = "aead" -version = "0.3.0-pre" +version = "0.3.0" dependencies = [ "generic-array 0.14.1", "heapless", diff --git a/aead/CHANGELOG.md b/aead/CHANGELOG.md index e1df7d06b..48b1de965 100644 --- a/aead/CHANGELOG.md +++ b/aead/CHANGELOG.md @@ -5,6 +5,22 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.3.0 (2019-06-04) +### Added +- Type aliases for `Key`, `Nonce`, and `Tag` ([#125]) +- Optional `std` feature ([#63]) + +### Changed +- `NewAead` now borrows the key ([#124]) +- Split `Aead`/`AeadMut` into `AeadInPlace`/`AeadMutInPlace` ([#120]) +- Bump `generic-array` dependency to v0.14 ([#95]) + +[#125]: https://github.com/RustCrypto/traits/pull/125 +[#124]: https://github.com/RustCrypto/traits/pull/124 +[#120]: https://github.com/RustCrypto/traits/pull/120 +[#95]: https://github.com/RustCrypto/traits/pull/95 +[#63]: https://github.com/RustCrypto/traits/pull/63 + ## 0.2.0 (2019-11-17) ## 0.1.2 (2019-11-17) [YANKED] diff --git a/aead/Cargo.toml b/aead/Cargo.toml index d433dc74c..d956b7a1e 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aead" -version = "0.3.0-pre" +version = "0.3.0" authors = ["RustCrypto Developers"] edition = "2018" license = "MIT OR Apache-2.0" From bf34b4ccfaf285542de0d9427d3e759c7e888559 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 5 Jun 2020 07:20:29 -0700 Subject: [PATCH 0126/1461] signature/derive: rename CHANGELOG.md (#175) --- .../{signature_derive => derive}/CHANGELOG.md | 0 signature/derive/CHANGES.md | 18 ------------------ 2 files changed, 18 deletions(-) rename signature/{signature_derive => derive}/CHANGELOG.md (100%) delete mode 100644 signature/derive/CHANGES.md diff --git a/signature/signature_derive/CHANGELOG.md b/signature/derive/CHANGELOG.md similarity index 100% rename from signature/signature_derive/CHANGELOG.md rename to signature/derive/CHANGELOG.md diff --git a/signature/derive/CHANGES.md b/signature/derive/CHANGES.md deleted file mode 100644 index eb7886b25..000000000 --- a/signature/derive/CHANGES.md +++ /dev/null @@ -1,18 +0,0 @@ -# Changelog -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## 1.0.0-pre.2 (2020-04-19) -### Changed -- Rename `DigestSignature` => `PrehashSignature` ([#96]) - -[#96]: https://github.com/RustCrypto/traits/pull/96 - -## 1.0.0-pre.1 (2020-03-08) -### Added -- Initial Changelog for `signature_derive` -- Rustdoc ([#79]) - -[#79]: https://github.com/RustCrypto/traits/pull/79 From bdc337c518d84410d95872cab4518b7e9784333c Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 8 Jun 2020 17:07:14 -0700 Subject: [PATCH 0127/1461] digest: add XofReader::read_vec method (#178) ...gated under the `alloc` feature. Allocates a `Vec` to return an individual `XofReader::read` invocation into. Unlike `ExtensibleOutput::finalize_vec`, it doesn't consume the reader and can be called an unlimited number of times. --- digest/src/lib.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 5e40d54e8..79bef801d 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -114,8 +114,19 @@ pub trait VariableOutput: core::marker::Sized { /// Trait for describing readers which are used to extract extendable output /// from XOF (extendable-output function) result. pub trait XofReader { - /// Read output into the `buffer`. Can be called unlimited number of times. + /// Read output into the `buffer`. Can be called an unlimited number of times. fn read(&mut self, buffer: &mut [u8]); + + /// Read output into a vector of the specified size. + /// + /// Can be called an unlimited number of times in combination with `read`. + #[cfg(feature = "alloc")] + #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] + fn read_vec(&mut self, n: usize) -> Vec { + let mut buf = vec![0u8; n]; + self.read(&mut buf); + buf + } } /// Trait which describes extendable-output functions (XOF). From e312a03b01aa3ee67902c7a2dda2a0d886be7c5b Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 8 Jun 2020 21:30:51 -0700 Subject: [PATCH 0128/1461] block-cipher: add BlockCipherMut (#179) Adds a stateful equivalent to `BlockCipher` that permits `&mut self` access to the underlying type. The main use case for this trait is hardware cryptographic accelerators which need to e.g. communitate with a peripheral device via an underlying `&mut` reference. While it's possible to use some underlying logic to use the existing `BlockCipher` trait in such a scenario, the solutions are somewhat ugly. Here is a real-world example: https://github.com/iqlusioninc/usbarmory.rs/blob/develop/firmware/usbarmory/src/dcp/aes128.rs#L198-L236 The idea with `BlockCipherMut` would be to alternatively provide `AeadMut`/`AeadMutInPlace` for AEAD modes with an underlying `BlockCipherMut` (when possible). --- block-cipher/src/lib.rs | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/block-cipher/src/lib.rs b/block-cipher/src/lib.rs index e7ea86e0d..caa9c2973 100644 --- a/block-cipher/src/lib.rs +++ b/block-cipher/src/lib.rs @@ -99,3 +99,32 @@ pub trait BlockCipher { } } } + +/// Stateful block cipher which permits `&mut self` access. +/// +/// The main use case for this trait is hardware encryption engines which +/// require `&mut self` access to an underlying hardware peripheral. +pub trait BlockCipherMut { + /// Size of the block in bytes + type BlockSize: ArrayLength; + + /// Encrypt block in-place + fn encrypt_block(&mut self, block: &mut GenericArray); + + /// Decrypt block in-place + fn decrypt_block(&mut self, block: &mut GenericArray); +} + +impl BlockCipherMut for Alg { + type BlockSize = Alg::BlockSize; + + /// Encrypt block in-place + fn encrypt_block(&mut self, block: &mut GenericArray) { + ::encrypt_block(self, block); + } + + /// Decrypt block in-place + fn decrypt_block(&mut self, block: &mut GenericArray) { + ::decrypt_block(self, block); + } +} From 496aa73930087c427702e82d6915568ef72f4ac2 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 9 Jun 2020 10:30:15 -0700 Subject: [PATCH 0129/1461] digest: add `FixedOutputDirty` trait + `finalize_into*` (#180) Adds a `FixedOutputDirty` trait which writes the digest output to a provided byte array, but does not reset the internal state. This is intended for implementations to use in order to ensure that they are not reset in the event the instance is consumed. Also adds a set of `finalize_into` and `finalize_into_reset` methods to `FixedOutput` whhich also write their input into a provided byte array, and changes the existing `finalize_fixed` (and newly added `finalize_fixed_reset`) methods to have a default implementation which returns a byte array allocated on the stack. Finally, adds a blanket impl of `FixedOutput` for `FixedOutputDirty` + `Reset` types which handles safely invoking the underlying implementation by either consuming the instance (avoiding a reset) or borrowing the hasher, obtaining the output, and resetting. --- digest/src/dyn_digest.rs | 2 +- digest/src/lib.rs | 60 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 59 insertions(+), 3 deletions(-) diff --git a/digest/src/dyn_digest.rs b/digest/src/dyn_digest.rs index c836ab447..4515c290f 100644 --- a/digest/src/dyn_digest.rs +++ b/digest/src/dyn_digest.rs @@ -34,7 +34,7 @@ impl DynDigest for D { } fn finalize_reset(&mut self) -> Box<[u8]> { - let res = self.clone().finalize_fixed().to_vec().into_boxed_slice(); + let res = self.finalize_fixed_reset().to_vec().into_boxed_slice(); Reset::reset(self); res } diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 79bef801d..72a7e00a9 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -79,8 +79,64 @@ pub trait FixedOutput { /// Output size for fixed output digest type OutputSize: ArrayLength; - /// Retrieve result and consume hasher instance. - fn finalize_fixed(self) -> GenericArray; + /// Write result into provided array and consume the hasher instance. + fn finalize_into(self, out: &mut GenericArray); + + /// Write result into provided array and reset the hasher instance. + fn finalize_into_reset(&mut self, out: &mut GenericArray); + + /// Retrieve result and consume the hasher instance. + #[inline] + fn finalize_fixed(self) -> GenericArray + where + Self: Sized, + { + let mut out = Default::default(); + self.finalize_into(&mut out); + out + } + + /// Retrieve result and reset the hasher instance. + #[inline] + fn finalize_fixed_reset(&mut self) -> GenericArray { + let mut out = Default::default(); + self.finalize_into_reset(&mut out); + out + } +} + +/// Trait for fixed-output digest implementations to use to retrieve the +/// hash output. +/// +/// Usage of this trait in user code is discouraged. Instead use the +/// [`FixedOutput::finalize_fixed`] or [`FixedOutput::finalize_fixed_reset`] +/// methods. +/// +/// Types which impl this trait along with [`Reset`] will receive a blanket +/// impl of [`FixedOutput`]. +pub trait FixedOutputDirty { + /// Output size for fixed output digest + type OutputSize: ArrayLength; + + /// Retrieve result into provided buffer and leave hasher in a dirty state. + /// + /// Implementations should panic if this is called twice without resetting. + fn finalize_into_dirty(&mut self, out: &mut GenericArray); +} + +impl FixedOutput for D { + type OutputSize = D::OutputSize; + + #[inline] + fn finalize_into(mut self, out: &mut GenericArray) { + self.finalize_into_dirty(out); + } + + #[inline] + fn finalize_into_reset(&mut self, out: &mut GenericArray) { + self.finalize_into_dirty(out); + self.reset(); + } } /// Trait for returning digest result with the variable size From 294e992c2ca2b89d3c884f506d059b78d28d75bc Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Tue, 9 Jun 2020 20:46:49 +0300 Subject: [PATCH 0130/1461] Use boxed slices instead of vectors (#181) --- digest/src/lib.rs | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 72a7e00a9..21976e663 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -45,7 +45,7 @@ pub use dyn_digest::DynDigest; use generic_array::{ArrayLength, GenericArray}; #[cfg(feature = "alloc")] -use alloc::vec::Vec; +use alloc::boxed::Box; /// Trait for updating digest state with input data. pub trait Update { @@ -157,12 +157,16 @@ pub trait VariableOutput: core::marker::Sized { /// will be equal to `output_size`. fn finalize_variable(self, f: F); - /// Retrieve result into vector and consume hasher. + /// Retrieve result into a boxed slice and consume hasher. + /// + /// `Box<[u8]>` is used instead of `Vec` to save stack space, since + /// they have size of 2 and 3 words respectively. #[cfg(feature = "alloc")] #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] - fn finalize_vec(self) -> Vec { - let mut buf = Vec::with_capacity(self.output_size()); - self.finalize_variable(|res| buf.extend_from_slice(res)); + fn finalize_box(self) -> Box<[u8]> { + let n = self.output_size(); + let mut buf = vec![0u8; n].into_boxed_slice(); + self.finalize_variable(|res| buf.copy_from_slice(res)); buf } } @@ -173,13 +177,16 @@ pub trait XofReader { /// Read output into the `buffer`. Can be called an unlimited number of times. fn read(&mut self, buffer: &mut [u8]); - /// Read output into a vector of the specified size. + /// Read output into a boxed slice of the specified size. /// /// Can be called an unlimited number of times in combination with `read`. + /// + /// `Box<[u8]>` is used instead of `Vec` to save stack space, since + /// they have size of 2 and 3 words respectively. #[cfg(feature = "alloc")] #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] - fn read_vec(&mut self, n: usize) -> Vec { - let mut buf = vec![0u8; n]; + fn read_box(&mut self, n: usize) -> Box<[u8]> { + let mut buf = vec![0u8; n].into_boxed_slice(); self.read(&mut buf); buf } @@ -193,11 +200,14 @@ pub trait ExtendableOutput: core::marker::Sized { /// Retrieve XOF reader and consume hasher instance. fn finalize_xof(self) -> Self::Reader; - /// Retrieve result into vector of specified length. + /// Retrieve result into a boxed slice of the specified size. + /// + /// `Box<[u8]>` is used instead of `Vec` to save stack space, since + /// they have size of 2 and 3 words respectively. #[cfg(feature = "alloc")] #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] - fn finalize_vec(self, n: usize) -> Vec { - let mut buf = vec![0u8; n]; + fn finalize_box(self, n: usize) -> Box<[u8]> { + let mut buf = vec![0u8; n].into_boxed_slice(); self.finalize_xof().read(&mut buf); buf } From b1d81bae158259272e33f00db4ac483b2d79dd89 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Tue, 9 Jun 2020 20:59:21 +0300 Subject: [PATCH 0131/1461] rename finalize_box to finalize_boxed (#182) --- digest/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 21976e663..f52f42b6f 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -163,7 +163,7 @@ pub trait VariableOutput: core::marker::Sized { /// they have size of 2 and 3 words respectively. #[cfg(feature = "alloc")] #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] - fn finalize_box(self) -> Box<[u8]> { + fn finalize_boxed(self) -> Box<[u8]> { let n = self.output_size(); let mut buf = vec![0u8; n].into_boxed_slice(); self.finalize_variable(|res| buf.copy_from_slice(res)); @@ -185,7 +185,7 @@ pub trait XofReader { /// they have size of 2 and 3 words respectively. #[cfg(feature = "alloc")] #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] - fn read_box(&mut self, n: usize) -> Box<[u8]> { + fn read_boxed(&mut self, n: usize) -> Box<[u8]> { let mut buf = vec![0u8; n].into_boxed_slice(); self.read(&mut buf); buf @@ -206,7 +206,7 @@ pub trait ExtendableOutput: core::marker::Sized { /// they have size of 2 and 3 words respectively. #[cfg(feature = "alloc")] #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] - fn finalize_box(self, n: usize) -> Box<[u8]> { + fn finalize_boxed(self, n: usize) -> Box<[u8]> { let mut buf = vec![0u8; n].into_boxed_slice(); self.finalize_xof().read(&mut buf); buf From 35d745984b65aad87551f592872b27c9472fc33d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 9 Jun 2020 11:48:44 -0700 Subject: [PATCH 0132/1461] digest: add `ExtendableOutputDirty` and `VariableOutputDirty` traits (#183) Adds traits which provide an implementation-focused low-level API similar to the `FixedOutputDirty` trait introduced in #180, but for the `ExtendableOutput` and `VariableOutput` traits. Like `FixedOutputDirty`, these traits have blanket impls when the same type also impls the `Reset` trait. Also adds corresponding `*_reset` methods to the respective `finalize*` methods of these traits. --- digest/src/lib.rs | 126 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 122 insertions(+), 4 deletions(-) diff --git a/digest/src/lib.rs b/digest/src/lib.rs index f52f42b6f..bbdc25e75 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -140,7 +140,7 @@ impl FixedOutput for D { } /// Trait for returning digest result with the variable size -pub trait VariableOutput: core::marker::Sized { +pub trait VariableOutput: Sized { /// Create new hasher instance with the given output size. /// /// It will return `Err(InvalidOutputSize)` in case if hasher can not return @@ -155,7 +155,13 @@ pub trait VariableOutput: core::marker::Sized { /// /// Closure is guaranteed to be called, length of the buffer passed to it /// will be equal to `output_size`. - fn finalize_variable(self, f: F); + fn finalize_variable(self, f: impl FnOnce(&[u8])); + + /// Retrieve result via closure and reset the hasher state. + /// + /// Closure is guaranteed to be called, length of the buffer passed to it + /// will be equal to `output_size`. + fn finalize_variable_reset(&mut self, f: impl FnOnce(&[u8])); /// Retrieve result into a boxed slice and consume hasher. /// @@ -169,6 +175,66 @@ pub trait VariableOutput: core::marker::Sized { self.finalize_variable(|res| buf.copy_from_slice(res)); buf } + + /// Retrieve result into a boxed slice and reset hasher state. + /// + /// `Box<[u8]>` is used instead of `Vec` to save stack space, since + /// they have size of 2 and 3 words respectively. + #[cfg(feature = "alloc")] + #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] + fn finalize_boxed_reset(&mut self) -> Box<[u8]> { + let n = self.output_size(); + let mut buf = vec![0u8; n].into_boxed_slice(); + self.finalize_variable_reset(|res| buf.copy_from_slice(res)); + buf + } +} + +/// Trait for variable-sized output digest implementations to use to retrieve +/// the hash output. +/// +/// Usage of this trait in user code is discouraged. Instead use the +/// [`VariableOutput::finalize_variable`] or +/// [`VariableOutput::finalize_variable_reset`] methods. +/// +/// Types which impl this trait along with [`Reset`] will receive a blanket +/// impl of [`VariableOutput`]. +pub trait VariableOutputDirty: Sized { + /// Create new hasher instance with the given output size. + /// + /// It will return `Err(InvalidOutputSize)` in case if hasher can not return + /// specified output size. It will always return an error if output size + /// equals to zero. + fn new(output_size: usize) -> Result; + + /// Get output size of the hasher instance provided to the `new` method + fn output_size(&self) -> usize; + + /// Retrieve result into provided buffer and leave hasher in a dirty state. + /// + /// Implementations should panic if this is called twice without resetting. + fn finalize_variable_dirty(&mut self, f: impl FnOnce(&[u8])); +} + +impl VariableOutput for D { + fn new(output_size: usize) -> Result { + ::new(output_size) + } + + fn output_size(&self) -> usize { + ::output_size(self) + } + + #[inline] + fn finalize_variable(mut self, f: impl FnOnce(&[u8])) { + self.finalize_variable_dirty(f); + } + + #[inline] + fn finalize_variable_reset(&mut self, f: impl FnOnce(&[u8])) { + self.finalize_variable_dirty(f); + self.reset(); + } } /// Trait for describing readers which are used to extract extendable output @@ -193,14 +259,18 @@ pub trait XofReader { } /// Trait which describes extendable-output functions (XOF). -pub trait ExtendableOutput: core::marker::Sized { +pub trait ExtendableOutput: Sized { /// Reader type Reader: XofReader; /// Retrieve XOF reader and consume hasher instance. fn finalize_xof(self) -> Self::Reader; - /// Retrieve result into a boxed slice of the specified size. + /// Retrieve XOF reader and reset hasher instance state. + fn finalize_xof_reset(&mut self) -> Self::Reader; + + /// Retrieve result into a boxed slice of the specified size and consume + /// the hasher. /// /// `Box<[u8]>` is used instead of `Vec` to save stack space, since /// they have size of 2 and 3 words respectively. @@ -211,6 +281,54 @@ pub trait ExtendableOutput: core::marker::Sized { self.finalize_xof().read(&mut buf); buf } + + /// Retrieve result into a boxed slice of the specified size and reset + /// the hasher's state. + /// + /// `Box<[u8]>` is used instead of `Vec` to save stack space, since + /// they have size of 2 and 3 words respectively. + #[cfg(feature = "alloc")] + #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] + fn finalize_boxed_reset(&mut self, n: usize) -> Box<[u8]> { + let mut buf = vec![0u8; n].into_boxed_slice(); + self.finalize_xof_reset().read(&mut buf); + buf + } +} + +/// Trait for extendable-output function (XOF) implementations to use to +/// retrieve the hash output. +/// +/// Usage of this trait in user code is discouraged. Instead use the +/// [`VariableOutput::finalize_variable`] or +/// [`VariableOutput::finalize_variable_reset`] methods. +/// +/// Types which impl this trait along with [`Reset`] will receive a blanket +/// impl of [`VariableOutput`]. +pub trait ExtendableOutputDirty: Sized { + /// Reader + type Reader: XofReader; + + /// Retrieve XOF reader and consume hasher instance. + /// + /// Implementations should panic if this is called twice without resetting. + fn finalize_xof_dirty(&mut self) -> Self::Reader; +} + +impl ExtendableOutput for X { + type Reader = X::Reader; + + #[inline] + fn finalize_xof(mut self) -> Self::Reader { + self.finalize_xof_dirty() + } + + #[inline] + fn finalize_xof_reset(&mut self) -> Self::Reader { + let reader = self.finalize_xof_dirty(); + self.reset(); + reader + } } /// Trait for resetting hash instances From 63816fc6f27dc0ace87a1671fb22ee438d3ffecf Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 9 Jun 2020 11:55:50 -0700 Subject: [PATCH 0133/1461] digest: factor out `fixed`, `variable`, and `xof` modules (#184) Each of these now defines two traits and a blanket impl, so `lib.rs` was getting rather bloated. This commit factors each of them into their own modules. --- digest/src/dyn_digest.rs | 1 + digest/src/fixed.rs | 69 ++++++++++ digest/src/lib.rs | 269 +-------------------------------------- digest/src/variable.rs | 104 +++++++++++++++ digest/src/xof.rs | 100 +++++++++++++++ 5 files changed, 281 insertions(+), 262 deletions(-) create mode 100644 digest/src/fixed.rs create mode 100644 digest/src/variable.rs create mode 100644 digest/src/xof.rs diff --git a/digest/src/dyn_digest.rs b/digest/src/dyn_digest.rs index 4515c290f..156f9bdbf 100644 --- a/digest/src/dyn_digest.rs +++ b/digest/src/dyn_digest.rs @@ -6,6 +6,7 @@ use generic_array::typenum::Unsigned; /// The `DynDigest` trait is a modification of `Digest` trait suitable /// for trait objects. +#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] pub trait DynDigest { /// Digest input data. /// diff --git a/digest/src/fixed.rs b/digest/src/fixed.rs new file mode 100644 index 000000000..4f0e22098 --- /dev/null +++ b/digest/src/fixed.rs @@ -0,0 +1,69 @@ +//! Fixed-size output digest support + +use crate::Reset; +use generic_array::{ArrayLength, GenericArray}; + +/// Trait for returning digest result with the fixed size +pub trait FixedOutput { + /// Output size for fixed output digest + type OutputSize: ArrayLength; + + /// Write result into provided array and consume the hasher instance. + fn finalize_into(self, out: &mut GenericArray); + + /// Write result into provided array and reset the hasher instance. + fn finalize_into_reset(&mut self, out: &mut GenericArray); + + /// Retrieve result and consume the hasher instance. + #[inline] + fn finalize_fixed(self) -> GenericArray + where + Self: Sized, + { + let mut out = Default::default(); + self.finalize_into(&mut out); + out + } + + /// Retrieve result and reset the hasher instance. + #[inline] + fn finalize_fixed_reset(&mut self) -> GenericArray { + let mut out = Default::default(); + self.finalize_into_reset(&mut out); + out + } +} + +/// Trait for fixed-output digest implementations to use to retrieve the +/// hash output. +/// +/// Usage of this trait in user code is discouraged. Instead use the +/// [`FixedOutput::finalize_fixed`] or [`FixedOutput::finalize_fixed_reset`] +/// methods. +/// +/// Types which impl this trait along with [`Reset`] will receive a blanket +/// impl of [`FixedOutput`]. +pub trait FixedOutputDirty { + /// Output size for fixed output digest + type OutputSize: ArrayLength; + + /// Retrieve result into provided buffer and leave hasher in a dirty state. + /// + /// Implementations should panic if this is called twice without resetting. + fn finalize_into_dirty(&mut self, out: &mut GenericArray); +} + +impl FixedOutput for D { + type OutputSize = D::OutputSize; + + #[inline] + fn finalize_into(mut self, out: &mut GenericArray) { + self.finalize_into_dirty(out); + } + + #[inline] + fn finalize_into_reset(&mut self, out: &mut GenericArray) { + self.finalize_into_dirty(out); + self.reset(); + } +} diff --git a/digest/src/lib.rs b/digest/src/lib.rs index bbdc25e75..094598629 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -33,19 +33,21 @@ pub mod dev; mod digest; mod dyn_digest; mod errors; +mod fixed; +mod variable; +mod xof; pub use crate::digest::{Digest, Output}; pub use crate::errors::InvalidOutputSize; +pub use crate::fixed::{FixedOutput, FixedOutputDirty}; +pub use crate::variable::{VariableOutput, VariableOutputDirty}; +pub use crate::xof::{ExtendableOutput, ExtendableOutputDirty, XofReader}; pub use generic_array::{self, typenum::consts}; #[cfg(feature = "alloc")] -#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] pub use dyn_digest::DynDigest; -use generic_array::{ArrayLength, GenericArray}; - -#[cfg(feature = "alloc")] -use alloc::boxed::Box; +use generic_array::ArrayLength; /// Trait for updating digest state with input data. pub trait Update { @@ -74,263 +76,6 @@ pub trait BlockInput { type BlockSize: ArrayLength; } -/// Trait for returning digest result with the fixed size -pub trait FixedOutput { - /// Output size for fixed output digest - type OutputSize: ArrayLength; - - /// Write result into provided array and consume the hasher instance. - fn finalize_into(self, out: &mut GenericArray); - - /// Write result into provided array and reset the hasher instance. - fn finalize_into_reset(&mut self, out: &mut GenericArray); - - /// Retrieve result and consume the hasher instance. - #[inline] - fn finalize_fixed(self) -> GenericArray - where - Self: Sized, - { - let mut out = Default::default(); - self.finalize_into(&mut out); - out - } - - /// Retrieve result and reset the hasher instance. - #[inline] - fn finalize_fixed_reset(&mut self) -> GenericArray { - let mut out = Default::default(); - self.finalize_into_reset(&mut out); - out - } -} - -/// Trait for fixed-output digest implementations to use to retrieve the -/// hash output. -/// -/// Usage of this trait in user code is discouraged. Instead use the -/// [`FixedOutput::finalize_fixed`] or [`FixedOutput::finalize_fixed_reset`] -/// methods. -/// -/// Types which impl this trait along with [`Reset`] will receive a blanket -/// impl of [`FixedOutput`]. -pub trait FixedOutputDirty { - /// Output size for fixed output digest - type OutputSize: ArrayLength; - - /// Retrieve result into provided buffer and leave hasher in a dirty state. - /// - /// Implementations should panic if this is called twice without resetting. - fn finalize_into_dirty(&mut self, out: &mut GenericArray); -} - -impl FixedOutput for D { - type OutputSize = D::OutputSize; - - #[inline] - fn finalize_into(mut self, out: &mut GenericArray) { - self.finalize_into_dirty(out); - } - - #[inline] - fn finalize_into_reset(&mut self, out: &mut GenericArray) { - self.finalize_into_dirty(out); - self.reset(); - } -} - -/// Trait for returning digest result with the variable size -pub trait VariableOutput: Sized { - /// Create new hasher instance with the given output size. - /// - /// It will return `Err(InvalidOutputSize)` in case if hasher can not return - /// specified output size. It will always return an error if output size - /// equals to zero. - fn new(output_size: usize) -> Result; - - /// Get output size of the hasher instance provided to the `new` method - fn output_size(&self) -> usize; - - /// Retrieve result via closure and consume hasher. - /// - /// Closure is guaranteed to be called, length of the buffer passed to it - /// will be equal to `output_size`. - fn finalize_variable(self, f: impl FnOnce(&[u8])); - - /// Retrieve result via closure and reset the hasher state. - /// - /// Closure is guaranteed to be called, length of the buffer passed to it - /// will be equal to `output_size`. - fn finalize_variable_reset(&mut self, f: impl FnOnce(&[u8])); - - /// Retrieve result into a boxed slice and consume hasher. - /// - /// `Box<[u8]>` is used instead of `Vec` to save stack space, since - /// they have size of 2 and 3 words respectively. - #[cfg(feature = "alloc")] - #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] - fn finalize_boxed(self) -> Box<[u8]> { - let n = self.output_size(); - let mut buf = vec![0u8; n].into_boxed_slice(); - self.finalize_variable(|res| buf.copy_from_slice(res)); - buf - } - - /// Retrieve result into a boxed slice and reset hasher state. - /// - /// `Box<[u8]>` is used instead of `Vec` to save stack space, since - /// they have size of 2 and 3 words respectively. - #[cfg(feature = "alloc")] - #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] - fn finalize_boxed_reset(&mut self) -> Box<[u8]> { - let n = self.output_size(); - let mut buf = vec![0u8; n].into_boxed_slice(); - self.finalize_variable_reset(|res| buf.copy_from_slice(res)); - buf - } -} - -/// Trait for variable-sized output digest implementations to use to retrieve -/// the hash output. -/// -/// Usage of this trait in user code is discouraged. Instead use the -/// [`VariableOutput::finalize_variable`] or -/// [`VariableOutput::finalize_variable_reset`] methods. -/// -/// Types which impl this trait along with [`Reset`] will receive a blanket -/// impl of [`VariableOutput`]. -pub trait VariableOutputDirty: Sized { - /// Create new hasher instance with the given output size. - /// - /// It will return `Err(InvalidOutputSize)` in case if hasher can not return - /// specified output size. It will always return an error if output size - /// equals to zero. - fn new(output_size: usize) -> Result; - - /// Get output size of the hasher instance provided to the `new` method - fn output_size(&self) -> usize; - - /// Retrieve result into provided buffer and leave hasher in a dirty state. - /// - /// Implementations should panic if this is called twice without resetting. - fn finalize_variable_dirty(&mut self, f: impl FnOnce(&[u8])); -} - -impl VariableOutput for D { - fn new(output_size: usize) -> Result { - ::new(output_size) - } - - fn output_size(&self) -> usize { - ::output_size(self) - } - - #[inline] - fn finalize_variable(mut self, f: impl FnOnce(&[u8])) { - self.finalize_variable_dirty(f); - } - - #[inline] - fn finalize_variable_reset(&mut self, f: impl FnOnce(&[u8])) { - self.finalize_variable_dirty(f); - self.reset(); - } -} - -/// Trait for describing readers which are used to extract extendable output -/// from XOF (extendable-output function) result. -pub trait XofReader { - /// Read output into the `buffer`. Can be called an unlimited number of times. - fn read(&mut self, buffer: &mut [u8]); - - /// Read output into a boxed slice of the specified size. - /// - /// Can be called an unlimited number of times in combination with `read`. - /// - /// `Box<[u8]>` is used instead of `Vec` to save stack space, since - /// they have size of 2 and 3 words respectively. - #[cfg(feature = "alloc")] - #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] - fn read_boxed(&mut self, n: usize) -> Box<[u8]> { - let mut buf = vec![0u8; n].into_boxed_slice(); - self.read(&mut buf); - buf - } -} - -/// Trait which describes extendable-output functions (XOF). -pub trait ExtendableOutput: Sized { - /// Reader - type Reader: XofReader; - - /// Retrieve XOF reader and consume hasher instance. - fn finalize_xof(self) -> Self::Reader; - - /// Retrieve XOF reader and reset hasher instance state. - fn finalize_xof_reset(&mut self) -> Self::Reader; - - /// Retrieve result into a boxed slice of the specified size and consume - /// the hasher. - /// - /// `Box<[u8]>` is used instead of `Vec` to save stack space, since - /// they have size of 2 and 3 words respectively. - #[cfg(feature = "alloc")] - #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] - fn finalize_boxed(self, n: usize) -> Box<[u8]> { - let mut buf = vec![0u8; n].into_boxed_slice(); - self.finalize_xof().read(&mut buf); - buf - } - - /// Retrieve result into a boxed slice of the specified size and reset - /// the hasher's state. - /// - /// `Box<[u8]>` is used instead of `Vec` to save stack space, since - /// they have size of 2 and 3 words respectively. - #[cfg(feature = "alloc")] - #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] - fn finalize_boxed_reset(&mut self, n: usize) -> Box<[u8]> { - let mut buf = vec![0u8; n].into_boxed_slice(); - self.finalize_xof_reset().read(&mut buf); - buf - } -} - -/// Trait for extendable-output function (XOF) implementations to use to -/// retrieve the hash output. -/// -/// Usage of this trait in user code is discouraged. Instead use the -/// [`VariableOutput::finalize_variable`] or -/// [`VariableOutput::finalize_variable_reset`] methods. -/// -/// Types which impl this trait along with [`Reset`] will receive a blanket -/// impl of [`VariableOutput`]. -pub trait ExtendableOutputDirty: Sized { - /// Reader - type Reader: XofReader; - - /// Retrieve XOF reader and consume hasher instance. - /// - /// Implementations should panic if this is called twice without resetting. - fn finalize_xof_dirty(&mut self) -> Self::Reader; -} - -impl ExtendableOutput for X { - type Reader = X::Reader; - - #[inline] - fn finalize_xof(mut self) -> Self::Reader { - self.finalize_xof_dirty() - } - - #[inline] - fn finalize_xof_reset(&mut self) -> Self::Reader { - let reader = self.finalize_xof_dirty(); - self.reset(); - reader - } -} - /// Trait for resetting hash instances pub trait Reset { /// Reset hasher instance to its initial state and return current state. diff --git a/digest/src/variable.rs b/digest/src/variable.rs new file mode 100644 index 000000000..42f280ae1 --- /dev/null +++ b/digest/src/variable.rs @@ -0,0 +1,104 @@ +//! Variable-sized output digest support + +use crate::{InvalidOutputSize, Reset}; + +#[cfg(feature = "alloc")] +use alloc::boxed::Box; + +/// Trait for returning digest result with the variable size +pub trait VariableOutput: Sized { + /// Create new hasher instance with the given output size. + /// + /// It will return `Err(InvalidOutputSize)` in case if hasher can not return + /// specified output size. It will always return an error if output size + /// equals to zero. + fn new(output_size: usize) -> Result; + + /// Get output size of the hasher instance provided to the `new` method + fn output_size(&self) -> usize; + + /// Retrieve result via closure and consume hasher. + /// + /// Closure is guaranteed to be called, length of the buffer passed to it + /// will be equal to `output_size`. + fn finalize_variable(self, f: impl FnOnce(&[u8])); + + /// Retrieve result via closure and reset the hasher state. + /// + /// Closure is guaranteed to be called, length of the buffer passed to it + /// will be equal to `output_size`. + fn finalize_variable_reset(&mut self, f: impl FnOnce(&[u8])); + + /// Retrieve result into a boxed slice and consume hasher. + /// + /// `Box<[u8]>` is used instead of `Vec` to save stack space, since + /// they have size of 2 and 3 words respectively. + #[cfg(feature = "alloc")] + #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] + fn finalize_boxed(self) -> Box<[u8]> { + let n = self.output_size(); + let mut buf = vec![0u8; n].into_boxed_slice(); + self.finalize_variable(|res| buf.copy_from_slice(res)); + buf + } + + /// Retrieve result into a boxed slice and reset hasher state. + /// + /// `Box<[u8]>` is used instead of `Vec` to save stack space, since + /// they have size of 2 and 3 words respectively. + #[cfg(feature = "alloc")] + #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] + fn finalize_boxed_reset(&mut self) -> Box<[u8]> { + let n = self.output_size(); + let mut buf = vec![0u8; n].into_boxed_slice(); + self.finalize_variable_reset(|res| buf.copy_from_slice(res)); + buf + } +} + +/// Trait for variable-sized output digest implementations to use to retrieve +/// the hash output. +/// +/// Usage of this trait in user code is discouraged. Instead use the +/// [`VariableOutput::finalize_variable`] or +/// [`VariableOutput::finalize_variable_reset`] methods. +/// +/// Types which impl this trait along with [`Reset`] will receive a blanket +/// impl of [`VariableOutput`]. +pub trait VariableOutputDirty: Sized { + /// Create new hasher instance with the given output size. + /// + /// It will return `Err(InvalidOutputSize)` in case if hasher can not return + /// specified output size. It will always return an error if output size + /// equals to zero. + fn new(output_size: usize) -> Result; + + /// Get output size of the hasher instance provided to the `new` method + fn output_size(&self) -> usize; + + /// Retrieve result into provided buffer and leave hasher in a dirty state. + /// + /// Implementations should panic if this is called twice without resetting. + fn finalize_variable_dirty(&mut self, f: impl FnOnce(&[u8])); +} + +impl VariableOutput for D { + fn new(output_size: usize) -> Result { + ::new(output_size) + } + + fn output_size(&self) -> usize { + ::output_size(self) + } + + #[inline] + fn finalize_variable(mut self, f: impl FnOnce(&[u8])) { + self.finalize_variable_dirty(f); + } + + #[inline] + fn finalize_variable_reset(&mut self, f: impl FnOnce(&[u8])) { + self.finalize_variable_dirty(f); + self.reset(); + } +} diff --git a/digest/src/xof.rs b/digest/src/xof.rs new file mode 100644 index 000000000..518477860 --- /dev/null +++ b/digest/src/xof.rs @@ -0,0 +1,100 @@ +//! Extendable-Output Function (XOF) support + +use crate::Reset; + +#[cfg(feature = "alloc")] +use alloc::boxed::Box; + +/// Trait for describing readers which are used to extract extendable output +/// from XOF (extendable-output function) result. +pub trait XofReader { + /// Read output into the `buffer`. Can be called an unlimited number of times. + fn read(&mut self, buffer: &mut [u8]); + + /// Read output into a boxed slice of the specified size. + /// + /// Can be called an unlimited number of times in combination with `read`. + /// + /// `Box<[u8]>` is used instead of `Vec` to save stack space, since + /// they have size of 2 and 3 words respectively. + #[cfg(feature = "alloc")] + #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] + fn read_boxed(&mut self, n: usize) -> Box<[u8]> { + let mut buf = vec![0u8; n].into_boxed_slice(); + self.read(&mut buf); + buf + } +} + +/// Trait which describes extendable-output functions (XOF). +pub trait ExtendableOutput: Sized { + /// Reader + type Reader: XofReader; + + /// Retrieve XOF reader and consume hasher instance. + fn finalize_xof(self) -> Self::Reader; + + /// Retrieve XOF reader and reset hasher instance state. + fn finalize_xof_reset(&mut self) -> Self::Reader; + + /// Retrieve result into a boxed slice of the specified size and consume + /// the hasher. + /// + /// `Box<[u8]>` is used instead of `Vec` to save stack space, since + /// they have size of 2 and 3 words respectively. + #[cfg(feature = "alloc")] + #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] + fn finalize_boxed(self, n: usize) -> Box<[u8]> { + let mut buf = vec![0u8; n].into_boxed_slice(); + self.finalize_xof().read(&mut buf); + buf + } + + /// Retrieve result into a boxed slice of the specified size and reset + /// the hasher's state. + /// + /// `Box<[u8]>` is used instead of `Vec` to save stack space, since + /// they have size of 2 and 3 words respectively. + #[cfg(feature = "alloc")] + #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] + fn finalize_boxed_reset(&mut self, n: usize) -> Box<[u8]> { + let mut buf = vec![0u8; n].into_boxed_slice(); + self.finalize_xof_reset().read(&mut buf); + buf + } +} + +/// Trait for extendable-output function (XOF) implementations to use to +/// retrieve the hash output. +/// +/// Usage of this trait in user code is discouraged. Instead use the +/// [`ExtendableOutput::finalize_xof`] or +/// [`ExtendableOutput::finalize_xof_reset`] methods. +/// +/// Types which impl this trait along with [`Reset`] will receive a blanket +/// impl of [`ExtendableOutput`]. +pub trait ExtendableOutputDirty: Sized { + /// Reader + type Reader: XofReader; + + /// Retrieve XOF reader and consume hasher instance. + /// + /// Implementations should panic if this is called twice without resetting. + fn finalize_xof_dirty(&mut self) -> Self::Reader; +} + +impl ExtendableOutput for X { + type Reader = X::Reader; + + #[inline] + fn finalize_xof(mut self) -> Self::Reader { + self.finalize_xof_dirty() + } + + #[inline] + fn finalize_xof_reset(&mut self) -> Self::Reader { + let reader = self.finalize_xof_dirty(); + self.reset(); + reader + } +} From b6c5fad59c4079b915a1df20c47bf3154b3612b1 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 9 Jun 2020 12:50:45 -0700 Subject: [PATCH 0134/1461] digest: document three levels of organization (#185) * digest: document three levels of organization The new `*Dirty` traits add another level of organization to the crate's design. This commit updates the documentation to reflect that. * minor update Co-authored-by: Artyom Pavlov --- digest/src/fixed.rs | 4 +++- digest/src/lib.rs | 25 +++++++++++++++++-------- digest/src/variable.rs | 4 +++- digest/src/xof.rs | 6 ++++-- 4 files changed, 27 insertions(+), 12 deletions(-) diff --git a/digest/src/fixed.rs b/digest/src/fixed.rs index 4f0e22098..432a6c42c 100644 --- a/digest/src/fixed.rs +++ b/digest/src/fixed.rs @@ -49,7 +49,9 @@ pub trait FixedOutputDirty { /// Retrieve result into provided buffer and leave hasher in a dirty state. /// - /// Implementations should panic if this is called twice without resetting. + /// This method is expected to only be called once unless + /// [`Reset::reset`] is called, after which point it can be + /// called again and reset again (and so on). fn finalize_into_dirty(&mut self, out: &mut GenericArray); } diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 094598629..b049a694d 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -1,15 +1,24 @@ //! This crate provides traits which describe functionality of cryptographic hash //! functions. //! -//! Traits in this repository can be separated into two levels: -//! - Low level traits: [`Update`], [`BlockInput`], [`Reset`], [`FixedOutput`], -//! [`VariableOutput`], [`ExtendableOutput`]. These traits atomically describe -//! available functionality of hash function implementations. -//! - Convenience trait: [`Digest`], [`DynDigest`]. They are wrappers around -//! low level traits for most common hash-function use-cases. +//! Traits in this repository are organized into high-level convenience traits, +//! mid-level traits which expose more fine-grained functionality, and +//! low-level traits intended to only be used by algorithm implementations: //! -//! Additionally hash functions implement traits from `std`: `Default`, `Clone`, -//! `Write`. (the latter depends on enabled-by-default `std` crate feature) +//! - **High-level convenience traits**: [`Digest`], [`DynDigest`]. They are wrappers +//! around lower-level traits for most common hash-function use-cases. +//! - **Mid-level traits**: [`Update`], [`BlockInput`], [`Reset`], [`FixedOutput`], +//! [`VariableOutput`], [`ExtendableOutput`]. These traits atomically describe +//! available functionality of hash function implementations. +//! - **Low-level traits**: [`FixedOutputDirty`], [`VariableOutputDirty`], +//! [`ExtendableOutputDirty`]. These traits are intended to be implemented by +//! low-level algorithm providers only and simplify the amount of work +//! implementers need to do and therefore shouldn't be used in +//! application-level code. +//! +//! Additionally hash functions implement traits from the standard library: +//! `Default`, `Clone`, `Write`. The latter is feature-gated behind `std` feature, +//! which is usually enabled by default by hash implementation crates. //! //! The [`Digest`] trait is the most commonly used trait. diff --git a/digest/src/variable.rs b/digest/src/variable.rs index 42f280ae1..7f444931f 100644 --- a/digest/src/variable.rs +++ b/digest/src/variable.rs @@ -78,7 +78,9 @@ pub trait VariableOutputDirty: Sized { /// Retrieve result into provided buffer and leave hasher in a dirty state. /// - /// Implementations should panic if this is called twice without resetting. + /// This method is expected to only be called once unless + /// [`Reset::reset`] is called, after which point it can be + /// called again and reset again (and so on). fn finalize_variable_dirty(&mut self, f: impl FnOnce(&[u8])); } diff --git a/digest/src/xof.rs b/digest/src/xof.rs index 518477860..0a41833b0 100644 --- a/digest/src/xof.rs +++ b/digest/src/xof.rs @@ -77,9 +77,11 @@ pub trait ExtendableOutputDirty: Sized { /// Reader type Reader: XofReader; - /// Retrieve XOF reader and consume hasher instance. + /// Retrieve XOF reader. /// - /// Implementations should panic if this is called twice without resetting. + /// This method is expected to only be called once unless + /// [`Reset::reset`] is called, after which point it can be + /// called again and reset again (and so on). fn finalize_xof_dirty(&mut self) -> Self::Reader; } From d22dc3e77d424415d60f448a14db5c45efd0f0de Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 9 Jun 2020 18:35:28 -0700 Subject: [PATCH 0135/1461] digest v0.9.0 (#186) --- Cargo.lock | 4 ++-- digest/CHANGELOG.md | 30 ++++++++++++++++++++++++++++++ digest/Cargo.toml | 2 +- signature/Cargo.toml | 2 +- 4 files changed, 34 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f2c515928..2645a235f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -89,7 +89,7 @@ dependencies = [ [[package]] name = "digest" -version = "0.9.0-pre" +version = "0.9.0" dependencies = [ "blobby", "generic-array 0.14.1", @@ -220,7 +220,7 @@ dependencies = [ name = "signature" version = "1.1.0-pre" dependencies = [ - "digest 0.9.0-pre", + "digest 0.9.0", "hex-literal", "rand_core", "sha2", diff --git a/digest/CHANGELOG.md b/digest/CHANGELOG.md index c105f80cb..03f0ad387 100644 --- a/digest/CHANGELOG.md +++ b/digest/CHANGELOG.md @@ -5,6 +5,36 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.9.0 (2020-06-09) +### Added +- `ExtendableOutputDirty` and `VariableOutputDirty` traits ([#183]) +- `FixedOutputDirty` trait + `finalize_into*` ([#180]) +- `XofReader::read_boxed` method ([#178], [#181], [#182]) +- `alloc` feature ([#163]) +- Re-export `typenum::consts` as `consts` ([#123]) +- `Output` type alias ([#115]) + +### Changed +- Rename `*result*` methods to `finalize` ala IUF ([#161]) +- Use `impl AsRef<[u8]>` instead of generic params on methods ([#112]) +- Rename `Input::input` to `Update::update` ala IUF ([#111]) +- Upgrade to Rust 2018 edition ([#109]) +- Bump `generic-array` to v0.14 ([#95]) + +[#183]: https://github.com/RustCrypto/traits/pull/183 +[#181]: https://github.com/RustCrypto/traits/pull/181 +[#182]: https://github.com/RustCrypto/traits/pull/182 +[#180]: https://github.com/RustCrypto/traits/pull/180 +[#178]: https://github.com/RustCrypto/traits/pull/178 +[#163]: https://github.com/RustCrypto/traits/pull/163 +[#161]: https://github.com/RustCrypto/traits/pull/161 +[#123]: https://github.com/RustCrypto/traits/pull/123 +[#115]: https://github.com/RustCrypto/traits/pull/115 +[#111]: https://github.com/RustCrypto/traits/pull/111 +[#112]: https://github.com/RustCrypto/traits/pull/112 +[#109]: https://github.com/RustCrypto/traits/pull/109 +[#95]: https://github.com/RustCrypto/traits/pull/95 + ## 0.8.1 (2019-06-30) ## 0.8.0 (2018-10-01) diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 724952df6..8f5774775 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "digest" description = "Traits for cryptographic hash functions" -version = "0.9.0-pre" +version = "0.9.0" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 74151f677..a0559bf03 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -12,7 +12,7 @@ keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"] categories = ["cryptography", "no-std"] [dependencies.digest] -version = "= 0.9.0-pre" +version = "0.9" optional = true default-features = false path = "../digest" From 82aa8770edfc225e93be0af070b819c3f8305b4c Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 9 Jun 2020 19:50:03 -0700 Subject: [PATCH 0136/1461] signature v1.1.0 (#187) --- .github/workflows/signature.yml | 3 +-- Cargo.lock | 26 +++++++++++++------------- signature/CHANGELOG.md | 6 ++++++ signature/Cargo.toml | 5 ++--- signature/src/lib.rs | 2 +- signature/tests/signature_derive.rs | 2 +- 6 files changed, 24 insertions(+), 20 deletions(-) diff --git a/.github/workflows/signature.yml b/.github/workflows/signature.yml index c1872a47b..b04544b7a 100644 --- a/.github/workflows/signature.yml +++ b/.github/workflows/signature.yml @@ -52,5 +52,4 @@ jobs: - run: cargo check --all-features - run: cargo test --no-default-features --release - run: cargo test --release -# TODO: fix support for the `digest-preview` feature -# - run: cargo test --all-features --release + - run: cargo test --all-features --release diff --git a/Cargo.lock b/Cargo.lock index 2645a235f..68d1ed8d4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -30,14 +30,14 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.7.3" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" +checksum = "dbcf92448676f82bb7a334c58bbce8b0d43580fb5362a9d608b18879d12a3d31" dependencies = [ "block-padding", "byte-tools", "byteorder", - "generic-array 0.12.3", + "generic-array 0.14.1", ] [[package]] @@ -80,18 +80,18 @@ dependencies = [ [[package]] name = "digest" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" +version = "0.9.0" dependencies = [ - "generic-array 0.12.3", + "blobby", + "generic-array 0.14.1", ] [[package]] name = "digest" version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ - "blobby", "generic-array 0.14.1", ] @@ -206,21 +206,21 @@ checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" [[package]] name = "sha2" -version = "0.8.2" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69" +checksum = "72377440080fd008550fe9b441e854e43318db116f90181eef92e9ae9aedab48" dependencies = [ "block-buffer", - "digest 0.8.1", + "digest 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "fake-simd", "opaque-debug", ] [[package]] name = "signature" -version = "1.1.0-pre" +version = "1.1.0" dependencies = [ - "digest 0.9.0", + "digest 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal", "rand_core", "sha2", diff --git a/signature/CHANGELOG.md b/signature/CHANGELOG.md index 70632f818..0bb6c681d 100644 --- a/signature/CHANGELOG.md +++ b/signature/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 1.1.0 (2020-06-09) +### Changed +- Upgrade `digest` to v0.9; MSRV 1.41+ ([#186]) + +[#186]: https://github.com/RustCrypto/traits/pull/186 + ## 1.0.1 (2020-04-19) ### Changed - Upgrade `signature_derive` to v1.0.0-pre.2 ([#98]) diff --git a/signature/Cargo.toml b/signature/Cargo.toml index a0559bf03..f6eefd08e 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "1.1.0-pre" # Also update html_root_url in lib.rs when bumping this +version = "1.1.0" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/signature" @@ -15,7 +15,6 @@ categories = ["cryptography", "no-std"] version = "0.9" optional = true default-features = false -path = "../digest" [dependencies.rand_core] version = "0.5" @@ -29,7 +28,7 @@ path = "derive" [dev-dependencies] hex-literal = "0.2" -sha2 = { version = "0.8", default-features = false } +sha2 = { version = "0.9", default-features = false } [features] default = ["std"] diff --git a/signature/src/lib.rs b/signature/src/lib.rs index 2895b6b44..e3a07f037 100644 --- a/signature/src/lib.rs +++ b/signature/src/lib.rs @@ -155,7 +155,7 @@ #![cfg_attr(docsrs, feature(doc_cfg))] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/ferris_signer.png", - html_root_url = "https://docs.rs/signature/1.1.0-pre" + html_root_url = "https://docs.rs/signature/1.1.0" )] #![forbid(unsafe_code)] #![warn( diff --git a/signature/tests/signature_derive.rs b/signature/tests/signature_derive.rs index c4944b0b7..272718a66 100644 --- a/signature/tests/signature_derive.rs +++ b/signature/tests/signature_derive.rs @@ -57,7 +57,7 @@ mod tests { impl DigestVerifier for DummyVerifier { fn verify_digest(&self, digest: Sha256, signature: &DummySignature) -> Result<(), Error> { let actual_digest = digest.finalize(); - assert_eq!(signature.as_ref(), actual_digest.as_ref()); + assert_eq!(signature.as_ref(), actual_digest.as_slice()); Ok(()) } } From 00fd43d39d94705af6a83409aa943ff2e7acab07 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 10 Jun 2020 15:16:46 -0700 Subject: [PATCH 0137/1461] stream-cipher: add Key and Nonce type aliases (#188) These are useful for removing `GenericArray` boilerplate, particularly in type signatures for arguments. --- stream-cipher/src/lib.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/stream-cipher/src/lib.rs b/stream-cipher/src/lib.rs index 505c67fb5..5755858fe 100644 --- a/stream-cipher/src/lib.rs +++ b/stream-cipher/src/lib.rs @@ -31,20 +31,24 @@ use generic_array::{ArrayLength, GenericArray}; #[cfg(feature = "block-cipher")] use block_cipher::{BlockCipher, NewBlockCipher}; +/// Key for an algorithm that implements [`NewStreamCipher`]. +pub type Key = GenericArray::KeySize>; + +/// Nonce for an algorithm that implements [`NewStreamCipher`]. +pub type Nonce = GenericArray::NonceSize>; + /// Stream cipher creation trait. /// /// It can be used for creation of synchronous and asynchronous ciphers. pub trait NewStreamCipher: Sized { /// Key size in bytes type KeySize: ArrayLength; + /// Nonce size in bytes type NonceSize: ArrayLength; /// Create new stream cipher instance from variable length key and nonce. - fn new( - key: &GenericArray, - nonce: &GenericArray, - ) -> Self; + fn new(key: &Key, nonce: &Nonce) -> Self; /// Create new stream cipher instance from variable length key and nonce. #[inline] @@ -144,7 +148,7 @@ where type KeySize = <::BlockCipher as NewBlockCipher>::KeySize; type NonceSize = <::BlockCipher as BlockCipher>::BlockSize; - fn new(key: &GenericArray, nonce: &GenericArray) -> C { + fn new(key: &Key, nonce: &Nonce) -> C { C::from_block_cipher( <::BlockCipher as NewBlockCipher>::new(key), nonce, From 8565e793fbc3ab97a90b36076b3623de9d7553e6 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 10 Jun 2020 17:53:37 -0700 Subject: [PATCH 0138/1461] block-cipher v0.7.1 (#189) --- Cargo.lock | 2 +- block-cipher/CHANGELOG.md | 6 ++++++ block-cipher/Cargo.toml | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 68d1ed8d4..5485aa5ea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -42,7 +42,7 @@ dependencies = [ [[package]] name = "block-cipher" -version = "0.7.0" +version = "0.7.1" dependencies = [ "blobby", "generic-array 0.14.1", diff --git a/block-cipher/CHANGELOG.md b/block-cipher/CHANGELOG.md index 83b2d67d2..b46c41ccb 100644 --- a/block-cipher/CHANGELOG.md +++ b/block-cipher/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.7.1 (2020-06-10) +### Added +- `BlockCipherMut` trait ([#179]) + +[#179]: https://github.com/RustCrypto/traits/issues/179 + ## 0.7.0 (2020-06-04) ### Changed - Crate renamed from `block-cipher-trait` to `block-cipher` ([#139]) diff --git a/block-cipher/Cargo.toml b/block-cipher/Cargo.toml index c4bf980e2..05671b7b0 100644 --- a/block-cipher/Cargo.toml +++ b/block-cipher/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "block-cipher" description = "Traits for description of block ciphers" -version = "0.7.0" +version = "0.7.1" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" From ef11420e950b847524d549991efb09af2d908931 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 10 Jun 2020 18:02:03 -0700 Subject: [PATCH 0139/1461] stream-cipher v0.4.1 (#190) --- Cargo.lock | 2 +- stream-cipher/CHANGELOG.md | 6 ++++++ stream-cipher/Cargo.toml | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5485aa5ea..b8312dddf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -245,7 +245,7 @@ checksum = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" [[package]] name = "stream-cipher" -version = "0.4.0" +version = "0.4.1" dependencies = [ "blobby", "block-cipher", diff --git a/stream-cipher/CHANGELOG.md b/stream-cipher/CHANGELOG.md index a2462eaa2..23ad81e7e 100644 --- a/stream-cipher/CHANGELOG.md +++ b/stream-cipher/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.4.1 (2020-06-10) +### Added +- `Key` and `Nonce` type aliases ([#188]) + +[#188]: https://github.com/RustCrypto/traits/issues/188 + ## 0.4.0 (2020-06-04) ### Added - `FromBlockCipher` trait ([#164]) diff --git a/stream-cipher/Cargo.toml b/stream-cipher/Cargo.toml index 220e51de5..23c6b3c15 100644 --- a/stream-cipher/Cargo.toml +++ b/stream-cipher/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "stream-cipher" description = "Stream cipher traits" -version = "0.4.0" +version = "0.4.1" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" From 0b404c80b42796170c1c3e6c4649e819764e480c Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 11 Jun 2020 14:55:38 -0700 Subject: [PATCH 0140/1461] aead: add `NewAead::new_varkey` method (#191) Adds a method which accepts a slice for a key, similar to the methods in the `block-cipher` and `stream-cipher` crates. --- aead/src/lib.rs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/aead/src/lib.rs b/aead/src/lib.rs index 1f33c5bff..d5c50d7c0 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -67,8 +67,22 @@ pub trait NewAead { /// The size of the key array required by this algorithm. type KeySize: ArrayLength; - /// Construct a new stateful instance for the given key. + /// Create a new AEAD instance with the given key. fn new(key: &Key) -> Self; + + /// Create new AEAD instance from key with variable size. + /// + /// Default implementation will accept only keys with length equal to `KeySize`. + fn new_varkey(key: &[u8]) -> Result + where + Self: Sized, + { + if key.len() != Self::KeySize::to_usize() { + Err(Error) + } else { + Ok(Self::new(GenericArray::from_slice(key))) + } + } } /// Authenticated Encryption with Associated Data (AEAD) algorithm. From 99a3a0de95a297e4c6736bc93089b643efd5b417 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 12 Jun 2020 08:27:41 +0000 Subject: [PATCH 0141/1461] build(deps): bump generic-array from 0.14.1 to 0.14.2 (#192) --- Cargo.lock | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b8312dddf..caa195279 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,7 +4,7 @@ name = "aead" version = "0.3.0" dependencies = [ - "generic-array 0.14.1", + "generic-array 0.14.2", "heapless", ] @@ -37,7 +37,7 @@ dependencies = [ "block-padding", "byte-tools", "byteorder", - "generic-array 0.14.1", + "generic-array 0.14.2", ] [[package]] @@ -45,7 +45,7 @@ name = "block-cipher" version = "0.7.1" dependencies = [ "blobby", - "generic-array 0.14.1", + "generic-array 0.14.2", ] [[package]] @@ -74,7 +74,7 @@ name = "crypto-mac" version = "0.8.0" dependencies = [ "blobby", - "generic-array 0.14.1", + "generic-array 0.14.2", "subtle", ] @@ -83,7 +83,7 @@ name = "digest" version = "0.9.0" dependencies = [ "blobby", - "generic-array 0.14.1", + "generic-array 0.14.2", ] [[package]] @@ -92,7 +92,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ - "generic-array 0.14.1", + "generic-array 0.14.2", ] [[package]] @@ -121,11 +121,12 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.1" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d2664c2cf08049036f31015b04c6ac3671379a1d86f52ed2416893f16022deb" +checksum = "ac746a5f3bbfdadd6106868134545e684693d54d9d44f6e9588a7d54af0bf980" dependencies = [ "typenum", + "version_check", ] [[package]] @@ -249,7 +250,7 @@ version = "0.4.1" dependencies = [ "blobby", "block-cipher", - "generic-array 0.14.1", + "generic-array 0.14.2", ] [[package]] @@ -297,6 +298,12 @@ checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" name = "universal-hash" version = "0.4.0" dependencies = [ - "generic-array 0.14.1", + "generic-array 0.14.2", "subtle", ] + +[[package]] +name = "version_check" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" From 5514c9dfb75e5f05527a6de2101625295b3acf68 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 12 Jun 2020 11:40:53 -0700 Subject: [PATCH 0142/1461] aead v0.3.1 (#193) --- Cargo.lock | 2 +- aead/CHANGELOG.md | 8 +++++++- aead/Cargo.toml | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index caa195279..1141157c8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,7 +2,7 @@ # It is not intended for manual editing. [[package]] name = "aead" -version = "0.3.0" +version = "0.3.1" dependencies = [ "generic-array 0.14.2", "heapless", diff --git a/aead/CHANGELOG.md b/aead/CHANGELOG.md index 48b1de965..f250b2c3a 100644 --- a/aead/CHANGELOG.md +++ b/aead/CHANGELOG.md @@ -5,7 +5,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 0.3.0 (2019-06-04) +## 0.3.1 (2020-06-12) +### Added +- `NewAead::new_varkey` method ([#191]) + +[#191]: https://github.com/RustCrypto/traits/pull/191 + +## 0.3.0 (2020-06-04) ### Added - Type aliases for `Key`, `Nonce`, and `Tag` ([#125]) - Optional `std` feature ([#63]) diff --git a/aead/Cargo.toml b/aead/Cargo.toml index d956b7a1e..f653f3362 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aead" -version = "0.3.0" +version = "0.3.1" authors = ["RustCrypto Developers"] edition = "2018" license = "MIT OR Apache-2.0" From d26e0f78f671a87d558db613f136ebcd861015be Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 15 Jun 2020 18:32:44 -0700 Subject: [PATCH 0143/1461] build(deps): bump blobby from 0.1.2 to 0.2.0 (#195) Bumps [blobby](https://github.com/RustCrypto/utils) from 0.1.2 to 0.2.0. - [Release notes](https://github.com/RustCrypto/utils/releases) - [Commits](https://github.com/RustCrypto/utils/compare/blobby-v0.1.2...blobby-v0.2.0) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- Cargo.lock | 7 ++----- block-cipher/Cargo.toml | 2 +- crypto-mac/Cargo.toml | 2 +- digest/Cargo.toml | 2 +- stream-cipher/Cargo.toml | 2 +- 5 files changed, 6 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1141157c8..3ecc41a10 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21,12 +21,9 @@ dependencies = [ [[package]] name = "blobby" -version = "0.1.2" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fe5f8c2940b65859ece4b3b2ba02d2b12c87cab455fd42dee2556a187bb2cf6" -dependencies = [ - "byteorder", -] +checksum = "517e75eae2ab6547f6a32ca5eefce861ecb5ec4c57a4c015e82503f71a7c63a9" [[package]] name = "block-buffer" diff --git a/block-cipher/Cargo.toml b/block-cipher/Cargo.toml index 05671b7b0..30027d71d 100644 --- a/block-cipher/Cargo.toml +++ b/block-cipher/Cargo.toml @@ -13,7 +13,7 @@ categories = ["cryptography", "no-std"] [dependencies] generic-array = "0.14" -blobby = { version = "0.1", optional = true } +blobby = { version = "0.2", optional = true } [features] std = [] diff --git a/crypto-mac/Cargo.toml b/crypto-mac/Cargo.toml index 569f192d5..ff5c9313d 100644 --- a/crypto-mac/Cargo.toml +++ b/crypto-mac/Cargo.toml @@ -14,7 +14,7 @@ categories = ["cryptography", "no-std"] [dependencies] generic-array = "0.14" subtle = { version = "2", default-features = false } -blobby = { version = "0.1", optional = true } +blobby = { version = "0.2", optional = true } [features] dev = ["blobby"] diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 8f5774775..5c0652e08 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -13,7 +13,7 @@ categories = ["cryptography", "no-std"] [dependencies] generic-array = "0.14" -blobby = { version = "0.1", optional = true } +blobby = { version = "0.2", optional = true } [features] alloc = [] diff --git a/stream-cipher/Cargo.toml b/stream-cipher/Cargo.toml index 23c6b3c15..691297efa 100644 --- a/stream-cipher/Cargo.toml +++ b/stream-cipher/Cargo.toml @@ -13,7 +13,7 @@ categories = ["cryptography", "no-std"] [dependencies] generic-array = "0.14" -blobby = { version = "0.1", optional = true } +blobby = { version = "0.2", optional = true } [dependencies.block-cipher] version = "0.7" From 05f63588814ebade64d52da33938ff1f341aa5e3 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 15 Jun 2020 18:33:01 -0700 Subject: [PATCH 0144/1461] README.md: use Minimum Supported Rust Version (MSRV) terminology (#196) --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 37384d84f..900cf93e7 100644 --- a/README.md +++ b/README.md @@ -14,9 +14,9 @@ Collection of traits which describe functionality of cryptographic primitives. | [`stream‑cipher`] | [Stream cipher] | [![crates.io](https://img.shields.io/crates/v/stream-cipher.svg)](https://crates.io/crates/stream-cipher) | [![Documentation](https://docs.rs/stream-cipher/badge.svg)](https://docs.rs/stream-cipher) | ![build](https://github.com/RustCrypto/traits/workflows/stream-cipher/badge.svg?branch=master&event=push) | | [`universal‑hash`] | [Universal hash function] | [![crates.io](https://img.shields.io/crates/v/universal-hash.svg)](https://crates.io/crates/universal-hash) | [![Documentation](https://docs.rs/universal-hash/badge.svg)](https://docs.rs/universal-hash) | ![build](https://github.com/RustCrypto/traits/workflows/universal-hash/badge.svg?branch=master&event=push) | -### Minimum Rust version +### Minimum Supported Rust Version -All crates in this repository support Rust 1.41 or higher unless otherwise noted. +All crates in this repository support **Rust 1.41** or higher unless otherwise noted. In future minimally supported version of Rust can be changed, but it will be done with the minor version bump. From 50ca18e6226ac891d8d00f9561849cebcee9f1be Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 21 Jun 2020 08:13:35 -0700 Subject: [PATCH 0145/1461] Add `cryptography` facade crate (#198) Adds a `cryptography` crate which re-exports compatible versions of the other trait crates as a facade. This should simplify cases where it's necessary to combine several cryptographic algorithms, by ensuring you have a single import to get compatible versions. --- .github/workflows/cryptography.yml | 55 ++++++++ Cargo.lock | 13 ++ Cargo.toml | 1 + README.md | 13 +- cryptography/Cargo.toml | 24 ++++ cryptography/LICENSE-APACHE | 202 +++++++++++++++++++++++++++++ cryptography/LICENSE-MIT | 25 ++++ cryptography/README.md | 54 ++++++++ cryptography/src/lib.rs | 60 +++++++++ 9 files changed, 444 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/cryptography.yml create mode 100644 cryptography/Cargo.toml create mode 100644 cryptography/LICENSE-APACHE create mode 100644 cryptography/LICENSE-MIT create mode 100644 cryptography/README.md create mode 100644 cryptography/src/lib.rs diff --git a/.github/workflows/cryptography.yml b/.github/workflows/cryptography.yml new file mode 100644 index 000000000..b45df1f48 --- /dev/null +++ b/.github/workflows/cryptography.yml @@ -0,0 +1,55 @@ +name: cryptography + +on: + pull_request: + paths: + - "cryptography/**" + - "Cargo.*" + push: + branches: master + +defaults: + run: + working-directory: cryptography + +env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + rust: + - 1.41.0 # MSRV + - stable + target: + - thumbv7em-none-eabi + - wasm32-unknown-unknown + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.rust }} + target: ${{ matrix.target }} + override: true + - run: cargo build --no-default-features --release --target ${{ matrix.target }} + test: + runs-on: ubuntu-latest + strategy: + matrix: + rust: + - 1.41.0 # MSRV + - stable + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.rust }} + - run: cargo check --all-features + - run: cargo test --no-default-features --release + - run: cargo test --release + - run: cargo test --all-features --release diff --git a/Cargo.lock b/Cargo.lock index 3ecc41a10..0c1c79fe1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -75,6 +75,19 @@ dependencies = [ "subtle", ] +[[package]] +name = "cryptography" +version = "0.1.0" +dependencies = [ + "aead", + "block-cipher", + "crypto-mac", + "digest 0.9.0", + "signature", + "stream-cipher", + "universal-hash", +] + [[package]] name = "digest" version = "0.9.0" diff --git a/Cargo.toml b/Cargo.toml index 888dea812..4b9fdd831 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,6 +3,7 @@ members = [ "aead", "block-cipher", "crypto-mac", + "cryptography", "digest", "signature", "stream-cipher", diff --git a/README.md b/README.md index 900cf93e7..a5c679232 100644 --- a/README.md +++ b/README.md @@ -4,16 +4,22 @@ Collection of traits which describe functionality of cryptographic primitives. ## Crates -| Name | Algorithm | Crates.io | Documentation | Build | -|--------------------|-------------------------------|-----------|----------------|-------| +| Crate name | Algorithm | Crates.io | Docs | Build Status | +|--------------------|-------------------------------|-----------|-------|--------------| | [`aead`] | [Authenticated encryption] | [![crates.io](https://img.shields.io/crates/v/aead.svg)](https://crates.io/crates/aead) | [![Documentation](https://docs.rs/aead/badge.svg)](https://docs.rs/aead) | ![build](https://github.com/RustCrypto/traits/workflows/aead/badge.svg?branch=master&event=push) | -| [`block‑cipher`] | [Block cipher] | [![crates.io](https://img.shields.io/crates/v/block-cipher.svg)](https://crates.io/crates/block-cipher) | [![Documentation](https://docs.rs/block-cipher/badge.svg)](https://docs.rs/block-cipher) | ![build](https://github.com/RustCrypto/traits/workflows/block-cipher/badge.svg?branch=master&event=push) | +| [`block‑cipher`] | [Block cipher] | [![crates.io](https://img.shields.io/crates/v/block-cipher.svg)](https://crates.io/crates/block-cipher) | [![Documentation](https://docs.rs/block-cipher/badge.svg)](https://docs.rs/block-cipher) | ![build](https://github.com/RustCrypto/traits/workflows/block-cipher/badge.svg?branch=master&event=push) | | [`crypto‑mac`] | [Message authentication code] | [![crates.io](https://img.shields.io/crates/v/crypto-mac.svg)](https://crates.io/crates/crypto-mac) | [![Documentation](https://docs.rs/crypto-mac/badge.svg)](https://docs.rs/crypto-mac) | ![build](https://github.com/RustCrypto/traits/workflows/crypto-mac/badge.svg?branch=master&event=push) | | [`digest`] | [Cryptographic hash function] | [![crates.io](https://img.shields.io/crates/v/digest.svg)](https://crates.io/crates/digest) | [![Documentation](https://docs.rs/digest/badge.svg)](https://docs.rs/digest) | ![build](https://github.com/RustCrypto/traits/workflows/digest/badge.svg?branch=master&event=push) | | [`signature`] | [Digital signature] | [![crates.io](https://img.shields.io/crates/v/signature.svg)](https://crates.io/crates/signature) | [![Documentation](https://docs.rs/signature/badge.svg)](https://docs.rs/signature) | ![build](https://github.com/RustCrypto/traits/workflows/signature/badge.svg?branch=master&event=push) | | [`stream‑cipher`] | [Stream cipher] | [![crates.io](https://img.shields.io/crates/v/stream-cipher.svg)](https://crates.io/crates/stream-cipher) | [![Documentation](https://docs.rs/stream-cipher/badge.svg)](https://docs.rs/stream-cipher) | ![build](https://github.com/RustCrypto/traits/workflows/stream-cipher/badge.svg?branch=master&event=push) | | [`universal‑hash`] | [Universal hash function] | [![crates.io](https://img.shields.io/crates/v/universal-hash.svg)](https://crates.io/crates/universal-hash) | [![Documentation](https://docs.rs/universal-hash/badge.svg)](https://docs.rs/universal-hash) | ![build](https://github.com/RustCrypto/traits/workflows/universal-hash/badge.svg?branch=master&event=push) | +### Additional crates + +| Crate name | Description | Crates.io | Docs | Build Status | +|------------------|-------------|-----------|-------|--------------| +| [`cryptography`] | Facade for trait crates | [![crates.io](https://img.shields.io/crates/v/cryptography.svg)](https://crates.io/crates/cryptography) | [![Documentation](https://docs.rs/cryptography/badge.svg)](https://docs.rs/cryptography) | ![build](https://github.com/RustCrypto/traits/workflows/cryptography/badge.svg?branch=master&event=push) + ### Minimum Supported Rust Version All crates in this repository support **Rust 1.41** or higher unless otherwise noted. @@ -45,6 +51,7 @@ dual licensed as above, without any additional terms or conditions. [`aead`]: https://github.com/RustCrypto/traits/tree/master/aead [`block‑cipher`]: https://github.com/RustCrypto/traits/tree/master/block-cipher [`crypto‑mac`]: https://github.com/RustCrypto/traits/tree/master/crypto-mac +[`cryptography`]: https://github.com/RustCrypto/traits/tree/master/cryptography [`digest`]: https://github.com/RustCrypto/traits/tree/master/digest [`signature`]: https://github.com/RustCrypto/traits/tree/master/signature [`stream‑cipher`]: https://github.com/RustCrypto/traits/tree/master/stream-cipher diff --git a/cryptography/Cargo.toml b/cryptography/Cargo.toml new file mode 100644 index 000000000..c63c70c68 --- /dev/null +++ b/cryptography/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "cryptography" +version = "0.1.0" +authors = ["The RustCrypto Project Developers"] +license = "Apache-2.0 OR MIT" +description = "Facade crate for the RustCrypto project's traits" +documentation = "https://docs.rs/cryptography" +repository = "https://github.com/RustCrypto/traits" +keywords = ["crypto", "encryption", "rustcrypto"] +categories = ["cryptography", "no-std"] +readme = "README.md" +edition = "2018" + +[dependencies] +aead = { version = "0.3", optional = true, path = "../aead" } +block-cipher = { version = "0.7", optional = true, path = "../block-cipher" } +crypto-mac = { version = "0.8", optional = true, path = "../crypto-mac" } +digest = { version = "0.9", optional = true, path = "../digest" } +signature = { version = "1.1.0", optional = true, default-features = false, path = "../signature" } +stream-cipher = { version = "0.4", optional = true, path = "../stream-cipher" } +universal-hash = { version = "0.4", optional = true, path = "../universal-hash" } + +[package.metadata.docs.rs] +all-features = true diff --git a/cryptography/LICENSE-APACHE b/cryptography/LICENSE-APACHE new file mode 100644 index 000000000..7650239c7 --- /dev/null +++ b/cryptography/LICENSE-APACHE @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + diff --git a/cryptography/LICENSE-MIT b/cryptography/LICENSE-MIT new file mode 100644 index 000000000..2726e14a4 --- /dev/null +++ b/cryptography/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2020 The RustCrypto Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/cryptography/README.md b/cryptography/README.md new file mode 100644 index 000000000..668849958 --- /dev/null +++ b/cryptography/README.md @@ -0,0 +1,54 @@ +# RustCrypto: `cryptography` crate + +[![crate][crate-image]][crate-link] +[![Docs][docs-image]][docs-link] +![Apache2/MIT licensed][license-image] +![Rust Version][rustc-image] +[![Build Status][build-image]][build-link] + +Facade crate for [RustCrypto Traits][1], providing a single place to +access compatible versions of all traits from the Rust Crypto project. + +[Documentation][docs-link] + +## Minimum Supported Rust Version + +Rust **1.41** or higher. + +Minimum supported Rust version can be changed in the future, but it will be +done with a minor version bump. + +## SemVer Policy + +- All on-by-default features of this library are covered by SemVer +- MSRV is considered exempt from SemVer as noted above + +## License + +Licensed under either of: + + * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) + * [MIT license](http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall be +dual licensed as above, without any additional terms or conditions. + +[//]: # (badges) + +[crate-image]: https://img.shields.io/crates/v/cryptography.svg +[crate-link]: https://crates.io/crates/cryptography +[docs-image]: https://docs.rs/cryptography/badge.svg +[docs-link]: https://docs.rs/cryptography/ +[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg +[build-image]: https://github.com/RustCrypto/traits/workflows/cryptography/badge.svg?branch=master&event=push +[build-link]: https://github.com/RustCrypto/traits/actions?query=workflow%3Acryptography + +[//]: # (footnotes) + +[1]: https://github.com/RustCrypto/traits diff --git a/cryptography/src/lib.rs b/cryptography/src/lib.rs new file mode 100644 index 000000000..6413e22de --- /dev/null +++ b/cryptography/src/lib.rs @@ -0,0 +1,60 @@ +//! Facade crate for [RustCrypto Traits][1], providing a single place to +//! access compatible versions of all traits from the Rust Crypto project. +//! +//! # About +//! +//! The [RustCrypto Project][2] publishes and maintains independently versioned +//! crates containing traits for many different kinds of cryptographic +//! algorithms. +//! +//! However, these algorithms are often interdependent (e.g. many depend on digest +//! algorithms), which requires figuring out which versions of the trait crates +//! are compatible with each other. +//! +//! This crate will automatically pull in compatible versions of these crates, +//! with each one gated under a cargo feature, providing a single place to both +//! import and upgrade these crates while ensuring they remain compatible. +//! +//! # Traits +//! +//! - [`aead`] - Authenticated Encryption with Associated Data +//! (i.e. high-level symmetric encryption) +//! - [`block_cipher`] - block-based cryptographic permutations +//! (i.e. low-level symmetric encryption) +//! - [`mac`] - message authentication codes (i.e. symmetric message +//! authentication) +//! - [`digest`] - cryptographic hash functions +//! - [`signature`] - digital signatures (i.e. public key-based message +//! authentication) +//! - [`stream_cipher`] - ciphers based on randomly generated keystreams +//! (i.e. low-level symmetric encryption) +//! - [`universal_hash`] - universal hash functions (used to build MACs) +//! +//! [1]: https://github.com/RustCrypto/traits +//! [2]: https://github.com/RustCrypto + +#![no_std] +#![doc(html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png")] +#![forbid(unsafe_code)] +#![warn(rust_2018_idioms)] + +#[cfg(feature = "aead")] +pub use aead; + +#[cfg(feature = "block-cipher")] +pub use block_cipher; + +#[cfg(feature = "crypto-mac")] +pub use crypto_mac as mac; + +#[cfg(feature = "digest")] +pub use digest; + +#[cfg(feature = "signature")] +pub use signature; + +#[cfg(feature = "stream-cipher")] +pub use stream_cipher; + +#[cfg(feature = "universal-hash")] +pub use universal_hash; From d710251685f00da332b9f2aa4502f7c52363c80a Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 21 Jun 2020 08:20:23 -0700 Subject: [PATCH 0146/1461] cryptography v0.1.1 (#199) --- Cargo.lock | 2 +- cryptography/CHANGELOG.md | 9 +++++++++ cryptography/Cargo.toml | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 cryptography/CHANGELOG.md diff --git a/Cargo.lock b/Cargo.lock index 0c1c79fe1..582dd97ff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -77,7 +77,7 @@ dependencies = [ [[package]] name = "cryptography" -version = "0.1.0" +version = "0.1.1" dependencies = [ "aead", "block-cipher", diff --git a/cryptography/CHANGELOG.md b/cryptography/CHANGELOG.md new file mode 100644 index 000000000..4b739eb31 --- /dev/null +++ b/cryptography/CHANGELOG.md @@ -0,0 +1,9 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## 0.1.1 (2020-06-21) +- Initial release diff --git a/cryptography/Cargo.toml b/cryptography/Cargo.toml index c63c70c68..31a5c93fb 100644 --- a/cryptography/Cargo.toml +++ b/cryptography/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cryptography" -version = "0.1.0" +version = "0.1.1" authors = ["The RustCrypto Project Developers"] license = "Apache-2.0 OR MIT" description = "Facade crate for the RustCrypto project's traits" From 094b83655142546fb78f1673aa4d192f87827dc8 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 21 Jun 2020 08:37:39 -0700 Subject: [PATCH 0147/1461] cryptography: add explicit rustdoc links (#200) For whatever reason https://docs.rs did not render the links to the various trait crates (despite `cargo +nightly doc` rendering them fine for me). Even stranger still, there was one exception: it was happy with the `signature` crate (possibly because it's post-1.0?) Regardless, this commit adds direct links for the various crates to https://docs.rs so users can easily find the relevant documentation. --- cryptography/src/lib.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cryptography/src/lib.rs b/cryptography/src/lib.rs index 6413e22de..8747c4d3c 100644 --- a/cryptography/src/lib.rs +++ b/cryptography/src/lib.rs @@ -32,6 +32,14 @@ //! //! [1]: https://github.com/RustCrypto/traits //! [2]: https://github.com/RustCrypto +//! +//! [`aead`]: https://docs.rs/aead +//! [`block_cipher`]: https://docs.rs/block-cipher +//! [`mac`]: https://docs.rs/crypto-mac +//! [`digest`]: https://docs.rs/digest +//! [`signature`]: https://docs.rs/signature +//! [`stream_cipher`]: https://docs.rs/stream-cipher +//! [`universal_hash`]: https://docs.rs/universal-hash #![no_std] #![doc(html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png")] From dd5d063ed6422c6b6ef3f25b22cfe703d9a59254 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 21 Jun 2020 10:23:04 -0700 Subject: [PATCH 0148/1461] cryptography v0.1.2 (#201) --- Cargo.lock | 2 +- cryptography/CHANGELOG.md | 6 ++++++ cryptography/Cargo.toml | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 582dd97ff..4358ba9ac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -77,7 +77,7 @@ dependencies = [ [[package]] name = "cryptography" -version = "0.1.1" +version = "0.1.2" dependencies = [ "aead", "block-cipher", diff --git a/cryptography/CHANGELOG.md b/cryptography/CHANGELOG.md index 4b739eb31..809e33dbd 100644 --- a/cryptography/CHANGELOG.md +++ b/cryptography/CHANGELOG.md @@ -5,5 +5,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.1.2 (2020-06-21) +### Fixed +- Rustdoc link rendering for https://docs.rs ([#200]) + +[#200]: https://github.com/RustCrypto/traits/pull/200 + ## 0.1.1 (2020-06-21) - Initial release diff --git a/cryptography/Cargo.toml b/cryptography/Cargo.toml index 31a5c93fb..21341e9fd 100644 --- a/cryptography/Cargo.toml +++ b/cryptography/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cryptography" -version = "0.1.1" +version = "0.1.2" authors = ["The RustCrypto Project Developers"] license = "Apache-2.0 OR MIT" description = "Facade crate for the RustCrypto project's traits" From 2895b6b357b7ef5875cffcb4b8d8e0c94c5438e1 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 21 Jun 2020 11:07:40 -0700 Subject: [PATCH 0149/1461] cryptography: fix rustdoc by linking directly to https://docs.rs (#202) Unfortunately even after #200 the links to the documentation for the various trait crates is still broken in the exact same way. I suspect this might be some kind of rustdoc/docs.rs bug around re-exports. This commit explicitly links to https://docs.rs for each of the crates rather than using *any* kind of indirection, in hopes that corrects the issue. --- cryptography/src/lib.rs | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/cryptography/src/lib.rs b/cryptography/src/lib.rs index 8747c4d3c..1920e7fb9 100644 --- a/cryptography/src/lib.rs +++ b/cryptography/src/lib.rs @@ -17,29 +17,23 @@ //! //! # Traits //! -//! - [`aead`] - Authenticated Encryption with Associated Data -//! (i.e. high-level symmetric encryption) -//! - [`block_cipher`] - block-based cryptographic permutations -//! (i.e. low-level symmetric encryption) -//! - [`mac`] - message authentication codes (i.e. symmetric message -//! authentication) -//! - [`digest`] - cryptographic hash functions -//! - [`signature`] - digital signatures (i.e. public key-based message -//! authentication) -//! - [`stream_cipher`] - ciphers based on randomly generated keystreams -//! (i.e. low-level symmetric encryption) -//! - [`universal_hash`] - universal hash functions (used to build MACs) +//! - [`aead`](https://docs.rs/aead) - +//! Authenticated Encryption with Associated Data (i.e. high-level symmetric encryption) +//! - [`block_cipher`](https://docs.rs/block-cipher) - +//! block-based cryptographic permutations (i.e. low-level symmetric encryption) +//! - [`mac`](https://docs.rs/crypto-mac) - +//! message authentication codes (i.e. symmetric message authentication) +//! - [`digest`](https://docs.rs/digest) - +//! cryptographic hash functions +//! - [`signature`](https://docs.rs/signature) - +//! digital signatures (i.e. public key-based message authentication) +//! - [`stream_cipher`](https://docs.rs/stream-cipher) - +//! ciphers based on randomly generated keystreams (i.e. low-level symmetric encryption) +//! - [`universal_hash`](https://docs.rs/universal-hash) - +//! universal hash functions (used to build MACs) //! //! [1]: https://github.com/RustCrypto/traits //! [2]: https://github.com/RustCrypto -//! -//! [`aead`]: https://docs.rs/aead -//! [`block_cipher`]: https://docs.rs/block-cipher -//! [`mac`]: https://docs.rs/crypto-mac -//! [`digest`]: https://docs.rs/digest -//! [`signature`]: https://docs.rs/signature -//! [`stream_cipher`]: https://docs.rs/stream-cipher -//! [`universal_hash`]: https://docs.rs/universal-hash #![no_std] #![doc(html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png")] From 930ea11600369f5b8b62fe328f67938446077693 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 21 Jun 2020 13:09:17 -0700 Subject: [PATCH 0150/1461] cryptography v0.1.3 (#203) --- Cargo.lock | 2 +- cryptography/CHANGELOG.md | 12 ++++++++++++ cryptography/Cargo.toml | 2 +- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4358ba9ac..f3fe1cd2d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -77,7 +77,7 @@ dependencies = [ [[package]] name = "cryptography" -version = "0.1.2" +version = "0.1.3" dependencies = [ "aead", "block-cipher", diff --git a/cryptography/CHANGELOG.md b/cryptography/CHANGELOG.md index 809e33dbd..bcadefe62 100644 --- a/cryptography/CHANGELOG.md +++ b/cryptography/CHANGELOG.md @@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.1.3 (2020-06-21) +### Fixed +- Link rendering on https://docs.rs ([#202]) + +[#202]: https://github.com/RustCrypto/traits/pull/202 + +## 0.1.2 (2020-06-21) +### Fixed +- (Attempted) fix link rendering on https://docs.rs ([#200]) + +[#200]: https://github.com/RustCrypto/traits/pull/200 + ## 0.1.2 (2020-06-21) ### Fixed - Rustdoc link rendering for https://docs.rs ([#200]) diff --git a/cryptography/Cargo.toml b/cryptography/Cargo.toml index 21341e9fd..51da10dd0 100644 --- a/cryptography/Cargo.toml +++ b/cryptography/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cryptography" -version = "0.1.2" +version = "0.1.3" authors = ["The RustCrypto Project Developers"] license = "Apache-2.0 OR MIT" description = "Facade crate for the RustCrypto project's traits" From a19963fab98611fe907fa458250a9a7f5a255c1d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 21 Jun 2020 14:01:35 -0700 Subject: [PATCH 0151/1461] cryptography: add `mac` feature; put docs in table (#204) Imports `crypto-mac` as `mac` via a `package` directive in Cargo.toml rather than re-exporting it under another name. Reorganizes the rustdoc into a table which shows both the module name and associated Cargo feature. --- .github/workflows/cryptography.yml | 3 ++- cryptography/Cargo.toml | 5 +--- cryptography/src/lib.rs | 37 +++++++++++++++--------------- 3 files changed, 21 insertions(+), 24 deletions(-) diff --git a/.github/workflows/cryptography.yml b/.github/workflows/cryptography.yml index b45df1f48..d3059d888 100644 --- a/.github/workflows/cryptography.yml +++ b/.github/workflows/cryptography.yml @@ -35,7 +35,8 @@ jobs: toolchain: ${{ matrix.rust }} target: ${{ matrix.target }} override: true - - run: cargo build --no-default-features --release --target ${{ matrix.target }} + - run: cargo build --release --target ${{ matrix.target }} + - run: cargo build --all-features --release --target ${{ matrix.target }} test: runs-on: ubuntu-latest strategy: diff --git a/cryptography/Cargo.toml b/cryptography/Cargo.toml index 51da10dd0..89e92a7eb 100644 --- a/cryptography/Cargo.toml +++ b/cryptography/Cargo.toml @@ -14,11 +14,8 @@ edition = "2018" [dependencies] aead = { version = "0.3", optional = true, path = "../aead" } block-cipher = { version = "0.7", optional = true, path = "../block-cipher" } -crypto-mac = { version = "0.8", optional = true, path = "../crypto-mac" } digest = { version = "0.9", optional = true, path = "../digest" } +mac = { version = "0.8", package = "crypto-mac", optional = true, path = "../crypto-mac" } signature = { version = "1.1.0", optional = true, default-features = false, path = "../signature" } stream-cipher = { version = "0.4", optional = true, path = "../stream-cipher" } universal-hash = { version = "0.4", optional = true, path = "../universal-hash" } - -[package.metadata.docs.rs] -all-features = true diff --git a/cryptography/src/lib.rs b/cryptography/src/lib.rs index 1920e7fb9..0e0fa0231 100644 --- a/cryptography/src/lib.rs +++ b/cryptography/src/lib.rs @@ -15,22 +15,21 @@ //! with each one gated under a cargo feature, providing a single place to both //! import and upgrade these crates while ensuring they remain compatible. //! -//! # Traits -//! -//! - [`aead`](https://docs.rs/aead) - -//! Authenticated Encryption with Associated Data (i.e. high-level symmetric encryption) -//! - [`block_cipher`](https://docs.rs/block-cipher) - -//! block-based cryptographic permutations (i.e. low-level symmetric encryption) -//! - [`mac`](https://docs.rs/crypto-mac) - -//! message authentication codes (i.e. symmetric message authentication) -//! - [`digest`](https://docs.rs/digest) - -//! cryptographic hash functions -//! - [`signature`](https://docs.rs/signature) - -//! digital signatures (i.e. public key-based message authentication) -//! - [`stream_cipher`](https://docs.rs/stream-cipher) - -//! ciphers based on randomly generated keystreams (i.e. low-level symmetric encryption) -//! - [`universal_hash`](https://docs.rs/universal-hash) - -//! universal hash functions (used to build MACs) +//! # Trait re-exports +//! +//! Below are the re-exports of the various RustCrypto crates available through +//! this crate's facade. To access a particular re-export you (or a crate you +//! depend on) must enable the associated Cargo feature named below. +//! +//! | Module name | Cargo feature | Description | +//! |-------------|---------------|-------------| +//! | [`aead`](https://docs.rs/aead) | `aead` | Authenticated Encryption with Associated Data (i.e. high-level symmetric encryption) | +//! | [`block_cipher`](https://docs.rs/block-cipher) | `block-cipher` | Block-based cryptographic permutations (i.e. low-level symmetric encryption) | +//! | [`digest`](https://docs.rs/digest) | `digest` | Cryptographic hash functions | +//! | [`mac`](https://docs.rs/crypto-mac) | `mac` | Message Authentication Codes (i.e. symmetric message authentication) | +//! | [`signature`](https://docs.rs/signature) | `signature` | Digital signatures (i.e. public key-based message authentication) | +//! | [`stream_cipher`](https://docs.rs/stream-cipher) | `stream-cipher` | Ciphers based on randomly generated keystreams (i.e. low-level symmetric encryption) | +//! | [`universal_hash`](https://docs.rs/universal-hash) | `universal-hash` | Universal Hash Functions (used to build MACs) | //! //! [1]: https://github.com/RustCrypto/traits //! [2]: https://github.com/RustCrypto @@ -46,12 +45,12 @@ pub use aead; #[cfg(feature = "block-cipher")] pub use block_cipher; -#[cfg(feature = "crypto-mac")] -pub use crypto_mac as mac; - #[cfg(feature = "digest")] pub use digest; +#[cfg(feature = "mac")] +pub use mac; + #[cfg(feature = "signature")] pub use signature; From 8ded2942c16f49e3d349478a3d78cc81cd8dade6 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 21 Jun 2020 14:41:42 -0700 Subject: [PATCH 0152/1461] cryptography: rustdoc improvements (#205) --- cryptography/Cargo.toml | 3 +++ cryptography/src/lib.rs | 14 +++++++------- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/cryptography/Cargo.toml b/cryptography/Cargo.toml index 89e92a7eb..30d66bde0 100644 --- a/cryptography/Cargo.toml +++ b/cryptography/Cargo.toml @@ -19,3 +19,6 @@ mac = { version = "0.8", package = "crypto-mac", optional = true, path = "../cry signature = { version = "1.1.0", optional = true, default-features = false, path = "../signature" } stream-cipher = { version = "0.4", optional = true, path = "../stream-cipher" } universal-hash = { version = "0.4", optional = true, path = "../universal-hash" } + +[package.metadata.docs.rs] +all-features = true diff --git a/cryptography/src/lib.rs b/cryptography/src/lib.rs index 0e0fa0231..fdb505fbf 100644 --- a/cryptography/src/lib.rs +++ b/cryptography/src/lib.rs @@ -15,21 +15,21 @@ //! with each one gated under a cargo feature, providing a single place to both //! import and upgrade these crates while ensuring they remain compatible. //! -//! # Trait re-exports +//! # Traits //! -//! Below are the re-exports of the various RustCrypto crates available through +//! The following traits are available as re-exports of RustCrypto crates through //! this crate's facade. To access a particular re-export you (or a crate you //! depend on) must enable the associated Cargo feature named below. //! -//! | Module name | Cargo feature | Description | -//! |-------------|---------------|-------------| +//! | Re-export | Cargo feature | Description | +//! |-----------|---------------|-------------| //! | [`aead`](https://docs.rs/aead) | `aead` | Authenticated Encryption with Associated Data (i.e. high-level symmetric encryption) | -//! | [`block_cipher`](https://docs.rs/block-cipher) | `block-cipher` | Block-based cryptographic permutations (i.e. low-level symmetric encryption) | +//! | [`block_cipher`](https://docs.rs/block-cipher) | `block‑cipher` | Block-based cryptographic permutations (i.e. low-level symmetric encryption) | //! | [`digest`](https://docs.rs/digest) | `digest` | Cryptographic hash functions | //! | [`mac`](https://docs.rs/crypto-mac) | `mac` | Message Authentication Codes (i.e. symmetric message authentication) | //! | [`signature`](https://docs.rs/signature) | `signature` | Digital signatures (i.e. public key-based message authentication) | -//! | [`stream_cipher`](https://docs.rs/stream-cipher) | `stream-cipher` | Ciphers based on randomly generated keystreams (i.e. low-level symmetric encryption) | -//! | [`universal_hash`](https://docs.rs/universal-hash) | `universal-hash` | Universal Hash Functions (used to build MACs) | +//! | [`stream_cipher`](https://docs.rs/stream-cipher) | `stream‑cipher` | Ciphers based on randomly generated keystreams (i.e. low-level symmetric encryption) | +//! | [`universal_hash`](https://docs.rs/universal-hash) | `universal‑hash` | Universal Hash Functions (used to build MACs) | //! //! [1]: https://github.com/RustCrypto/traits //! [2]: https://github.com/RustCrypto From 050147818c1a313cf1ec30bdd4dfbdab4a26e574 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 21 Jun 2020 14:53:19 -0700 Subject: [PATCH 0153/1461] cryptography v0.1.4 (#206) --- Cargo.lock | 2 +- cryptography/CHANGELOG.md | 8 ++++++++ cryptography/Cargo.toml | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f3fe1cd2d..0917e679d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -77,7 +77,7 @@ dependencies = [ [[package]] name = "cryptography" -version = "0.1.3" +version = "0.1.4" dependencies = [ "aead", "block-cipher", diff --git a/cryptography/CHANGELOG.md b/cryptography/CHANGELOG.md index bcadefe62..10747fdcc 100644 --- a/cryptography/CHANGELOG.md +++ b/cryptography/CHANGELOG.md @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.1.4 (2020-06-21) +### Added +- rustdoc improvements ([#205]) +- `mac` feature ([#204]) + +[#205]: https://github.com/RustCrypto/traits/pull/205 +[#204]: https://github.com/RustCrypto/traits/pull/204 + ## 0.1.3 (2020-06-21) ### Fixed - Link rendering on https://docs.rs ([#202]) diff --git a/cryptography/Cargo.toml b/cryptography/Cargo.toml index 30d66bde0..b858a5f90 100644 --- a/cryptography/Cargo.toml +++ b/cryptography/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cryptography" -version = "0.1.3" +version = "0.1.4" authors = ["The RustCrypto Project Developers"] license = "Apache-2.0 OR MIT" description = "Facade crate for the RustCrypto project's traits" From 8d00a12f0841d6c4747ae7be666cf1ecfd679d55 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 25 Jun 2020 09:24:45 +0000 Subject: [PATCH 0154/1461] build(deps): bump sha2 from 0.9.0 to 0.9.1 (#207) Bumps [sha2](https://github.com/RustCrypto/hashes) from 0.9.0 to 0.9.1. - [Release notes](https://github.com/RustCrypto/hashes/releases) - [Commits](https://github.com/RustCrypto/hashes/compare/sha2-v0.9.0...sha2-v0.9.1) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- Cargo.lock | 45 +++++++++++++++++---------------------------- 1 file changed, 17 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0917e679d..f823e103a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -27,13 +27,10 @@ checksum = "517e75eae2ab6547f6a32ca5eefce861ecb5ec4c57a4c015e82503f71a7c63a9" [[package]] name = "block-buffer" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbcf92448676f82bb7a334c58bbce8b0d43580fb5362a9d608b18879d12a3d31" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "block-padding", - "byte-tools", - "byteorder", "generic-array 0.14.2", ] @@ -46,25 +43,22 @@ dependencies = [ ] [[package]] -name = "block-padding" -version = "0.1.5" +name = "byteorder" +version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" -dependencies = [ - "byte-tools", -] +checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" [[package]] -name = "byte-tools" -version = "0.3.1" +name = "cfg-if" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" [[package]] -name = "byteorder" -version = "1.3.4" +name = "cpuid-bool" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" +checksum = "6d375c433320f6c5057ae04a04376eef4d04ce2801448cf8863a78da99107be4" [[package]] name = "crypto-mac" @@ -105,12 +99,6 @@ dependencies = [ "generic-array 0.14.2", ] -[[package]] -name = "fake-simd" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" - [[package]] name = "generic-array" version = "0.12.3" @@ -181,9 +169,9 @@ dependencies = [ [[package]] name = "opaque-debug" -version = "0.2.3" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "proc-macro-hack" @@ -217,13 +205,14 @@ checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" [[package]] name = "sha2" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72377440080fd008550fe9b441e854e43318db116f90181eef92e9ae9aedab48" +checksum = "2933378ddfeda7ea26f48c555bdad8bb446bf8a3d17832dc83e380d444cfb8c1" dependencies = [ "block-buffer", + "cfg-if", + "cpuid-bool", "digest 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "fake-simd", "opaque-debug", ] From 79c08436644b94ceb5f5ff3839f0d99de0a3fb5d Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Wed, 1 Jul 2020 23:33:50 +0300 Subject: [PATCH 0155/1461] Add dev module to the aead crate (#194) --- Cargo.lock | 17 ++++++++--- aead/CHANGELOG.md | 6 ++++ aead/Cargo.toml | 4 ++- aead/src/dev.rs | 77 +++++++++++++++++++++++++++++++++++++++++++++++ aead/src/lib.rs | 4 +++ 5 files changed, 102 insertions(+), 6 deletions(-) create mode 100644 aead/src/dev.rs diff --git a/Cargo.lock b/Cargo.lock index f823e103a..432f8cda5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,8 +2,9 @@ # It is not intended for manual editing. [[package]] name = "aead" -version = "0.3.1" +version = "0.3.2" dependencies = [ + "blobby 0.3.0", "generic-array 0.14.2", "heapless", ] @@ -25,6 +26,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "517e75eae2ab6547f6a32ca5eefce861ecb5ec4c57a4c015e82503f71a7c63a9" +[[package]] +name = "blobby" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc52553543ecb104069b0ff9e0fcc5c739ad16202935528a112d974e8f1a4ee8" + [[package]] name = "block-buffer" version = "0.9.0" @@ -38,7 +45,7 @@ dependencies = [ name = "block-cipher" version = "0.7.1" dependencies = [ - "blobby", + "blobby 0.1.2", "generic-array 0.14.2", ] @@ -64,7 +71,7 @@ checksum = "6d375c433320f6c5057ae04a04376eef4d04ce2801448cf8863a78da99107be4" name = "crypto-mac" version = "0.8.0" dependencies = [ - "blobby", + "blobby 0.1.2", "generic-array 0.14.2", "subtle", ] @@ -86,7 +93,7 @@ dependencies = [ name = "digest" version = "0.9.0" dependencies = [ - "blobby", + "blobby 0.1.2", "generic-array 0.14.2", ] @@ -247,7 +254,7 @@ checksum = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" name = "stream-cipher" version = "0.4.1" dependencies = [ - "blobby", + "blobby 0.1.2", "block-cipher", "generic-array 0.14.2", ] diff --git a/aead/CHANGELOG.md b/aead/CHANGELOG.md index f250b2c3a..c10fb269d 100644 --- a/aead/CHANGELOG.md +++ b/aead/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.3.2 (2020-07-01) +### Added +- `dev` module ([#194]) + +[#194]: https://github.com/RustCrypto/traits/pull/194 + ## 0.3.1 (2020-06-12) ### Added - `NewAead::new_varkey` method ([#191]) diff --git a/aead/Cargo.toml b/aead/Cargo.toml index f653f3362..99b6fa646 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aead" -version = "0.3.1" +version = "0.3.2" authors = ["RustCrypto Developers"] edition = "2018" license = "MIT OR Apache-2.0" @@ -14,11 +14,13 @@ categories = ["cryptography", "no-std"] [dependencies] generic-array = { version = "0.14", default-features = false } heapless = { version = "0.5", optional = true } +blobby = { version = "0.3", optional = true } [features] default = ["alloc"] alloc = [] std = ["alloc"] +dev = ["blobby"] [package.metadata.docs.rs] all-features = true diff --git a/aead/src/dev.rs b/aead/src/dev.rs new file mode 100644 index 000000000..cfd531267 --- /dev/null +++ b/aead/src/dev.rs @@ -0,0 +1,77 @@ +//! Development-related functionality +pub use blobby; + +/// Define AEAD test +#[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] +macro_rules! new_test { + ($name:ident, $test_name:expr, $cipher:ty $(,)?) => { + #[test] + fn $name() { + use aead::dev::blobby::Blob6Iterator; + use aead::generic_array::typenum::Unsigned; + use aead::{generic_array::GenericArray, Aead, NewAead, Payload}; + use core::convert::TryInto; + + fn run_test( + key: &[u8], + nonce: &[u8], + aad: &[u8], + pt: &[u8], + ct: &[u8], + pass: bool, + ) -> Result<(), &'static str> { + let key = key.try_into().map_err(|_| "wrong key size")?; + let cipher = <$cipher>::new(key); + let nonce = nonce.try_into().map_err(|_| "wrong nonce size")?; + + if !pass { + let res = cipher.decrypt(nonce, Payload { aad: aad, msg: ct }); + if res.is_ok() { + return Err("decryption must return error"); + } + return Ok(()); + } + + let res = cipher + .encrypt(nonce, Payload { aad: aad, msg: pt }) + .map_err(|_| "encryption failure")?; + if res != ct { + return Err("encrypted data is different from target ciphertext"); + } + let res = cipher + .decrypt(nonce, Payload { aad: aad, msg: ct }) + .map_err(|_| "decryption failure")?; + if res != pt { + return Err("decrypted data is different from target plaintext"); + } + Ok(()) + } + + let data = include_bytes!(concat!("data/", $test_name, ".blb")); + for (i, row) in Blob6Iterator::new(data).unwrap().enumerate() { + let [key, nonce, aad, pt, ct, status] = row.unwrap(); + let pass = match status[0] { + 0 => false, + 1 => true, + _ => panic!("invalid value for pass flag"), + }; + if let Err(reason) = run_test(key, nonce, aad, pt, ct, pass) { + panic!( + "\n\ + Failed test №{}\n\ + reason: \t{:?}\n\ + key:\t{:?}\n\ + nonce:\t{:?}\n\ + aad:\t{:?}\n\ + plaintext:\t{:?}\n\ + ciphertext:\t{:?}\n\ + pass:\t{}\n\ + ", + i, reason, key, nonce, aad, pt, ct, pass, + ); + } + } + } + }; +} diff --git a/aead/src/lib.rs b/aead/src/lib.rs index d5c50d7c0..3f7ea4ca6 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -25,6 +25,10 @@ extern crate alloc; #[cfg(feature = "std")] extern crate std; +#[cfg(feature = "dev")] +#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] +pub mod dev; + pub use generic_array::{self, typenum::consts}; #[cfg(feature = "heapless")] From 8d39a09a7369e4ea5194c41a2537bcb56901d95b Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Fri, 3 Jul 2020 18:55:18 +0300 Subject: [PATCH 0156/1461] Add NonceSize to FromBlockCipher (#209) --- Cargo.lock | 12 ++++++------ cryptography/CHANGELOG.md | 6 ++++++ cryptography/Cargo.toml | 4 ++-- stream-cipher/CHANGELOG.md | 6 ++++++ stream-cipher/Cargo.toml | 3 ++- stream-cipher/src/lib.rs | 19 +++++++++++++++++-- 6 files changed, 39 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 432f8cda5..155efe447 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -45,7 +45,7 @@ dependencies = [ name = "block-cipher" version = "0.7.1" dependencies = [ - "blobby 0.1.2", + "blobby 0.2.0", "generic-array 0.14.2", ] @@ -71,14 +71,14 @@ checksum = "6d375c433320f6c5057ae04a04376eef4d04ce2801448cf8863a78da99107be4" name = "crypto-mac" version = "0.8.0" dependencies = [ - "blobby 0.1.2", + "blobby 0.2.0", "generic-array 0.14.2", "subtle", ] [[package]] name = "cryptography" -version = "0.1.4" +version = "0.2.0" dependencies = [ "aead", "block-cipher", @@ -93,7 +93,7 @@ dependencies = [ name = "digest" version = "0.9.0" dependencies = [ - "blobby 0.1.2", + "blobby 0.2.0", "generic-array 0.14.2", ] @@ -252,9 +252,9 @@ checksum = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" [[package]] name = "stream-cipher" -version = "0.4.1" +version = "0.5.0" dependencies = [ - "blobby 0.1.2", + "blobby 0.2.0", "block-cipher", "generic-array 0.14.2", ] diff --git a/cryptography/CHANGELOG.md b/cryptography/CHANGELOG.md index 10747fdcc..2f0bc6786 100644 --- a/cryptography/CHANGELOG.md +++ b/cryptography/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.2.0 (2020-07-03) +### Changed +- Bump `stream-cipher` to v0.5 ([#209]) + +[#209]: https://github.com/RustCrypto/traits/pull/209 + ## 0.1.4 (2020-06-21) ### Added - rustdoc improvements ([#205]) diff --git a/cryptography/Cargo.toml b/cryptography/Cargo.toml index b858a5f90..580f0ca9a 100644 --- a/cryptography/Cargo.toml +++ b/cryptography/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cryptography" -version = "0.1.4" +version = "0.2.0" authors = ["The RustCrypto Project Developers"] license = "Apache-2.0 OR MIT" description = "Facade crate for the RustCrypto project's traits" @@ -17,7 +17,7 @@ block-cipher = { version = "0.7", optional = true, path = "../block-cipher" } digest = { version = "0.9", optional = true, path = "../digest" } mac = { version = "0.8", package = "crypto-mac", optional = true, path = "../crypto-mac" } signature = { version = "1.1.0", optional = true, default-features = false, path = "../signature" } -stream-cipher = { version = "0.4", optional = true, path = "../stream-cipher" } +stream-cipher = { version = "0.5", optional = true, path = "../stream-cipher" } universal-hash = { version = "0.4", optional = true, path = "../universal-hash" } [package.metadata.docs.rs] diff --git a/stream-cipher/CHANGELOG.md b/stream-cipher/CHANGELOG.md index 23ad81e7e..78b5770e4 100644 --- a/stream-cipher/CHANGELOG.md +++ b/stream-cipher/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.5.0 (2020-07-03) +### Changed +- Add `NonceSize` associated type to the `FromBlockCipher` trait ([#209]) + +[#209]: https://github.com/RustCrypto/traits/pull/209 + ## 0.4.1 (2020-06-10) ### Added - `Key` and `Nonce` type aliases ([#188]) diff --git a/stream-cipher/Cargo.toml b/stream-cipher/Cargo.toml index 691297efa..d336127e1 100644 --- a/stream-cipher/Cargo.toml +++ b/stream-cipher/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "stream-cipher" description = "Stream cipher traits" -version = "0.4.1" +version = "0.5.0" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" @@ -21,6 +21,7 @@ optional = true path = "../block-cipher" [features] +default = ["block-cipher"] std = [] dev = ["blobby"] diff --git a/stream-cipher/src/lib.rs b/stream-cipher/src/lib.rs index 5755858fe..86ed54d05 100644 --- a/stream-cipher/src/lib.rs +++ b/stream-cipher/src/lib.rs @@ -131,12 +131,14 @@ impl StreamCipher for C { pub trait FromBlockCipher { /// Block cipher type BlockCipher: BlockCipher + NewBlockCipher; + /// Nonce size in bytes + type NonceSize: ArrayLength; /// Instantiate a stream cipher from a block cipher // TODO(tarcieri): add associated type for NonceSize? fn from_block_cipher( cipher: Self::BlockCipher, - nonce: &block_cipher::Block, + nonce: &GenericArray, ) -> Self; } @@ -146,7 +148,7 @@ where C: FromBlockCipher, { type KeySize = <::BlockCipher as NewBlockCipher>::KeySize; - type NonceSize = <::BlockCipher as BlockCipher>::BlockSize; + type NonceSize = ::NonceSize; fn new(key: &Key, nonce: &Nonce) -> C { C::from_block_cipher( @@ -154,4 +156,17 @@ where nonce, ) } + + fn new_var(key: &[u8], nonce: &[u8]) -> Result { + if nonce.len() != Self::NonceSize::USIZE { + Err(InvalidKeyNonceLength) + } else { + C::BlockCipher::new_varkey(key) + .map_err(|_| InvalidKeyNonceLength) + .map(|cipher| { + let nonce = GenericArray::from_slice(nonce); + Self::from_block_cipher(cipher, nonce) + }) + } + } } From 54ded886927531793e62b6b49635c7074141f2f8 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Fri, 10 Jul 2020 17:59:49 +0300 Subject: [PATCH 0157/1461] Add blanket trait impls for references (#210) --- Cargo.lock | 8 ++++---- block-cipher/Cargo.toml | 4 ++-- block-cipher/src/dev.rs | 12 +++++------- block-cipher/src/lib.rs | 29 ++++++++++++++++++++++++++-- cryptography/Cargo.toml | 4 ++-- stream-cipher/Cargo.toml | 6 +++--- stream-cipher/src/dev.rs | 41 ++++++++++++++++------------------------ stream-cipher/src/lib.rs | 12 ++++++++++++ 8 files changed, 71 insertions(+), 45 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 155efe447..2e23d426a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -43,9 +43,9 @@ dependencies = [ [[package]] name = "block-cipher" -version = "0.7.1" +version = "0.8.0" dependencies = [ - "blobby 0.2.0", + "blobby 0.3.0", "generic-array 0.14.2", ] @@ -252,9 +252,9 @@ checksum = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" [[package]] name = "stream-cipher" -version = "0.5.0" +version = "0.6.0" dependencies = [ - "blobby 0.2.0", + "blobby 0.3.0", "block-cipher", "generic-array 0.14.2", ] diff --git a/block-cipher/Cargo.toml b/block-cipher/Cargo.toml index 30027d71d..cd3cc79a2 100644 --- a/block-cipher/Cargo.toml +++ b/block-cipher/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "block-cipher" description = "Traits for description of block ciphers" -version = "0.7.1" +version = "0.8.0" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" @@ -13,7 +13,7 @@ categories = ["cryptography", "no-std"] [dependencies] generic-array = "0.14" -blobby = { version = "0.2", optional = true } +blobby = { version = "0.3", optional = true } [features] std = [] diff --git a/block-cipher/src/dev.rs b/block-cipher/src/dev.rs index eeaee9ac7..11c570c1a 100644 --- a/block-cipher/src/dev.rs +++ b/block-cipher/src/dev.rs @@ -73,30 +73,28 @@ macro_rules! new_test { let pb = <$cipher as BlockCipher>::ParBlocks::to_usize(); let data = include_bytes!(concat!("data/", $test_name, ".blb")); for (i, row) in Blob3Iterator::new(data).unwrap().enumerate() { - let key = row[0]; - let plaintext = row[1]; - let ciphertext = row[2]; - if !run_test(key, plaintext, ciphertext) { + let [key, pt, ct] = row.unwrap(); + if !run_test(key, pt, ct) { panic!( "\n\ Failed test №{}\n\ key:\t{:?}\n\ plaintext:\t{:?}\n\ ciphertext:\t{:?}\n", - i, key, plaintext, ciphertext, + i, key, pt, ct, ); } // test parallel blocks encryption/decryption if pb != 1 { - if !run_par_test(key, plaintext) { + if !run_par_test(key, pt) { panic!( "\n\ Failed parallel test №{}\n\ key:\t{:?}\n\ plaintext:\t{:?}\n\ ciphertext:\t{:?}\n", - i, key, plaintext, ciphertext, + i, key, pt, ct, ); } } diff --git a/block-cipher/src/lib.rs b/block-cipher/src/lib.rs index caa9c2973..18aefa627 100644 --- a/block-cipher/src/lib.rs +++ b/block-cipher/src/lib.rs @@ -118,13 +118,38 @@ pub trait BlockCipherMut { impl BlockCipherMut for Alg { type BlockSize = Alg::BlockSize; - /// Encrypt block in-place + #[inline] fn encrypt_block(&mut self, block: &mut GenericArray) { ::encrypt_block(self, block); } - /// Decrypt block in-place + #[inline] fn decrypt_block(&mut self, block: &mut GenericArray) { ::decrypt_block(self, block); } } + +impl BlockCipher for &Alg { + type BlockSize = Alg::BlockSize; + type ParBlocks = Alg::ParBlocks; + + #[inline] + fn encrypt_block(&self, block: &mut Block) { + Alg::encrypt_block(self, block); + } + + #[inline] + fn decrypt_block(&self, block: &mut Block) { + Alg::decrypt_block(self, block); + } + + #[inline] + fn encrypt_blocks(&self, blocks: &mut ParBlocks) { + Alg::encrypt_blocks(self, blocks); + } + + #[inline] + fn decrypt_blocks(&self, blocks: &mut ParBlocks) { + Alg::decrypt_blocks(self, blocks); + } +} diff --git a/cryptography/Cargo.toml b/cryptography/Cargo.toml index 580f0ca9a..403f66880 100644 --- a/cryptography/Cargo.toml +++ b/cryptography/Cargo.toml @@ -13,11 +13,11 @@ edition = "2018" [dependencies] aead = { version = "0.3", optional = true, path = "../aead" } -block-cipher = { version = "0.7", optional = true, path = "../block-cipher" } +block-cipher = { version = "0.8", optional = true, path = "../block-cipher" } digest = { version = "0.9", optional = true, path = "../digest" } mac = { version = "0.8", package = "crypto-mac", optional = true, path = "../crypto-mac" } signature = { version = "1.1.0", optional = true, default-features = false, path = "../signature" } -stream-cipher = { version = "0.5", optional = true, path = "../stream-cipher" } +stream-cipher = { version = "0.6", optional = true, path = "../stream-cipher" } universal-hash = { version = "0.4", optional = true, path = "../universal-hash" } [package.metadata.docs.rs] diff --git a/stream-cipher/Cargo.toml b/stream-cipher/Cargo.toml index d336127e1..fd5e77799 100644 --- a/stream-cipher/Cargo.toml +++ b/stream-cipher/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "stream-cipher" description = "Stream cipher traits" -version = "0.5.0" +version = "0.6.0" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" @@ -13,10 +13,10 @@ categories = ["cryptography", "no-std"] [dependencies] generic-array = "0.14" -blobby = { version = "0.2", optional = true } +blobby = { version = "0.3", optional = true } [dependencies.block-cipher] -version = "0.7" +version = "0.8" optional = true path = "../block-cipher" diff --git a/stream-cipher/src/dev.rs b/stream-cipher/src/dev.rs index cd5e080e3..741cf3005 100644 --- a/stream-cipher/src/dev.rs +++ b/stream-cipher/src/dev.rs @@ -15,25 +15,22 @@ macro_rules! new_sync_test { let data = include_bytes!(concat!("data/", $test_name, ".blb")); for (i, row) in Blob4Iterator::new(data).unwrap().enumerate() { - let key = row[0]; - let iv = row[1]; - let plaintext = row[2]; - let ciphertext = row[3]; + let [key, iv, pt, ct] = row.unwrap(); for chunk_n in 1..256 { let mut mode = <$cipher>::new_var(key, iv).unwrap(); - let mut pt = plaintext.to_vec(); + let mut pt = pt.to_vec(); for chunk in pt.chunks_mut(chunk_n) { mode.apply_keystream(chunk); } - if pt != &ciphertext[..] { + if pt != &ct[..] { panic!( "Failed main test №{}, chunk size: {}\n\ - key:\t{:?}\n\ - iv:\t{:?}\n\ - plaintext:\t{:?}\n\ - ciphertext:\t{:?}\n", - i, chunk_n, key, iv, plaintext, ciphertext, + key:\t{:?}\n\ + iv:\t{:?}\n\ + plaintext:\t{:?}\n\ + ciphertext:\t{:?}\n", + i, chunk_n, key, iv, pt, ct, ); } } @@ -57,26 +54,23 @@ macro_rules! new_seek_test { let data = include_bytes!(concat!("data/", $test_name, ".blb")); for (i, row) in Blob4Iterator::new(data).unwrap().enumerate() { - let key = row[0]; - let iv = row[1]; - let plaintext = row[2]; - let ciphertext = row[3]; + let [key, iv, pt, ct] = row.unwrap(); let mut mode = <$cipher>::new_var(key, iv).unwrap(); - let pl = plaintext.len(); + let pl = pt.len(); let n = if pl > MAX_SEEK { MAX_SEEK } else { pl }; for seek_n in 0..n { - let mut pt = plaintext[seek_n..].to_vec(); + let mut pt = pt[seek_n..].to_vec(); mode.seek(seek_n as u64); mode.apply_keystream(&mut pt); - if pt != &ciphertext[seek_n..] { + if pt != &ct[seek_n..] { panic!( "Failed seek test №{}, seek pos: {}\n\ key:\t{:?}\n\ iv:\t{:?}\n\ plaintext:\t{:?}\n\ ciphertext:\t{:?}\n", - i, seek_n, key, iv, plaintext, ciphertext, + i, seek_n, key, iv, pt, ct, ); } } @@ -130,11 +124,8 @@ macro_rules! new_async_test { let data = include_bytes!(concat!("data/", $test_name, ".blb")); for (i, row) in Blob4Iterator::new(data).unwrap().enumerate() { - let key = row[0]; - let iv = row[1]; - let plaintext = row[2]; - let ciphertext = row[3]; - if let Some(desc) = run_test(key, iv, plaintext, ciphertext) { + let [key, iv, pt, ct] = row.unwrap(); + if let Some(desc) = run_test(key, iv, pt, ct) { panic!( "\n\ Failed test №{}: {}\n\ @@ -142,7 +133,7 @@ macro_rules! new_async_test { iv:\t{:?}\n\ plaintext:\t{:?}\n\ ciphertext:\t{:?}\n", - i, desc, key, iv, plaintext, ciphertext, + i, desc, key, iv, pt, ct, ); } } diff --git a/stream-cipher/src/lib.rs b/stream-cipher/src/lib.rs index 86ed54d05..80184d0d3 100644 --- a/stream-cipher/src/lib.rs +++ b/stream-cipher/src/lib.rs @@ -125,6 +125,18 @@ impl StreamCipher for C { } } +impl SyncStreamCipher for &mut C { + #[inline] + fn apply_keystream(&mut self, data: &mut [u8]) { + C::apply_keystream(self, data); + } + + #[inline] + fn try_apply_keystream(&mut self, data: &mut [u8]) -> Result<(), LoopError> { + C::try_apply_keystream(self, data) + } +} + /// Trait for initializing a stream cipher from a block cipher #[cfg(feature = "block-cipher")] #[cfg_attr(docsrs, doc(cfg(feature = "block-cipher")))] From c34a875c7bb956cc125d1e9fa19d2ed99b0b94bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2?= Date: Fri, 10 Jul 2020 18:05:37 +0300 Subject: [PATCH 0158/1461] update changelogs --- block-cipher/CHANGELOG.md | 7 +++++++ stream-cipher/CHANGELOG.md | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/block-cipher/CHANGELOG.md b/block-cipher/CHANGELOG.md index b46c41ccb..43ea0cedc 100644 --- a/block-cipher/CHANGELOG.md +++ b/block-cipher/CHANGELOG.md @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.8.0 (2020-07-10) +### Changed +- Add blanket implementation for `&mut SyncCtreamCipher` ([#210]) +- Update to `blobby v0.3` ([#210]) + +[#210]: https://github.com/RustCrypto/traits/pull/210 + ## 0.7.1 (2020-06-10) ### Added - `BlockCipherMut` trait ([#179]) diff --git a/stream-cipher/CHANGELOG.md b/stream-cipher/CHANGELOG.md index 78b5770e4..5d947704c 100644 --- a/stream-cipher/CHANGELOG.md +++ b/stream-cipher/CHANGELOG.md @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.6.0 (2020-07-10) +### Changed +- Add blanket implementation for `&mut SyncCtreamCipher` ([#210]) +- Update to `blobby v0.3` ([#210]) + +[#210]: https://github.com/RustCrypto/traits/pull/210 + ## 0.5.0 (2020-07-03) ### Changed - Add `NonceSize` associated type to the `FromBlockCipher` trait ([#209]) From d5f144d32fdcf36bc77388f1ccba115f14ba1987 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sat, 11 Jul 2020 18:07:45 -0700 Subject: [PATCH 0159/1461] Create Dependabot config file (#211) Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- .github/dependabot.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..5cde1657c --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,7 @@ +version: 2 +updates: +- package-ecosystem: cargo + directory: "/" + schedule: + interval: daily + open-pull-requests-limit: 10 From 2188a08770c0f10fe80e9bc1e570987765630bce Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 11 Jul 2020 18:16:18 -0700 Subject: [PATCH 0160/1461] build(deps): bump generic-array from 0.14.2 to 0.14.3 (#212) Bumps [generic-array](https://github.com/fizyk20/generic-array) from 0.14.2 to 0.14.3. - [Release notes](https://github.com/fizyk20/generic-array/releases) - [Changelog](https://github.com/fizyk20/generic-array/blob/master/CHANGELOG.md) - [Commits](https://github.com/fizyk20/generic-array/commits) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2e23d426a..20895ffac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5,7 +5,7 @@ name = "aead" version = "0.3.2" dependencies = [ "blobby 0.3.0", - "generic-array 0.14.2", + "generic-array 0.14.3", "heapless", ] @@ -38,7 +38,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "generic-array 0.14.2", + "generic-array 0.14.3", ] [[package]] @@ -46,7 +46,7 @@ name = "block-cipher" version = "0.8.0" dependencies = [ "blobby 0.3.0", - "generic-array 0.14.2", + "generic-array 0.14.3", ] [[package]] @@ -72,7 +72,7 @@ name = "crypto-mac" version = "0.8.0" dependencies = [ "blobby 0.2.0", - "generic-array 0.14.2", + "generic-array 0.14.3", "subtle", ] @@ -94,7 +94,7 @@ name = "digest" version = "0.9.0" dependencies = [ "blobby 0.2.0", - "generic-array 0.14.2", + "generic-array 0.14.3", ] [[package]] @@ -103,7 +103,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ - "generic-array 0.14.2", + "generic-array 0.14.3", ] [[package]] @@ -126,9 +126,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.2" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac746a5f3bbfdadd6106868134545e684693d54d9d44f6e9588a7d54af0bf980" +checksum = "60fb4bb6bba52f78a471264d9a3b7d026cc0af47b22cd2cffbc0b787ca003e63" dependencies = [ "typenum", "version_check", @@ -256,7 +256,7 @@ version = "0.6.0" dependencies = [ "blobby 0.3.0", "block-cipher", - "generic-array 0.14.2", + "generic-array 0.14.3", ] [[package]] @@ -304,7 +304,7 @@ checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" name = "universal-hash" version = "0.4.0" dependencies = [ - "generic-array 0.14.2", + "generic-array 0.14.3", "subtle", ] From 9fc143a0864129028955256763c450602c008a66 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 13 Jul 2020 06:51:23 -0700 Subject: [PATCH 0161/1461] elliptic-curve: import from RustCrypto/elliptic-curves (359f16d) (#213) Imports the code for the `elliptic-curve` crate previously located at: https://github.com/RustCrypto/elliptic-curves/tree/359f16dc9479bd27ef4d506aaf44b16f5945f718/elliptic-curve-crate Latest release is `v0.4.0` --- .github/workflows/elliptic-curve.yml | 55 +++++ Cargo.lock | 24 +++ Cargo.toml | 1 + README.md | 3 + cryptography/Cargo.toml | 1 + cryptography/src/lib.rs | 4 + elliptic-curve/CHANGELOG.md | 36 ++++ elliptic-curve/Cargo.toml | 46 +++++ elliptic-curve/LICENSE-APACHE | 201 +++++++++++++++++++ elliptic-curve/LICENSE-MIT | 25 +++ elliptic-curve/README.md | 51 +++++ elliptic-curve/src/error.rs | 16 ++ elliptic-curve/src/lib.rs | 41 ++++ elliptic-curve/src/secret_key.rs | 88 ++++++++ elliptic-curve/src/weierstrass.rs | 46 +++++ elliptic-curve/src/weierstrass/curve.rs | 20 ++ elliptic-curve/src/weierstrass/point.rs | 201 +++++++++++++++++++ elliptic-curve/src/weierstrass/public_key.rs | 187 +++++++++++++++++ 18 files changed, 1046 insertions(+) create mode 100644 .github/workflows/elliptic-curve.yml create mode 100644 elliptic-curve/CHANGELOG.md create mode 100644 elliptic-curve/Cargo.toml create mode 100644 elliptic-curve/LICENSE-APACHE create mode 100644 elliptic-curve/LICENSE-MIT create mode 100644 elliptic-curve/README.md create mode 100644 elliptic-curve/src/error.rs create mode 100644 elliptic-curve/src/lib.rs create mode 100644 elliptic-curve/src/secret_key.rs create mode 100644 elliptic-curve/src/weierstrass.rs create mode 100644 elliptic-curve/src/weierstrass/curve.rs create mode 100644 elliptic-curve/src/weierstrass/point.rs create mode 100644 elliptic-curve/src/weierstrass/public_key.rs diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml new file mode 100644 index 000000000..0a251428b --- /dev/null +++ b/.github/workflows/elliptic-curve.yml @@ -0,0 +1,55 @@ +name: elliptic-curve + +on: + pull_request: + paths: + - "elliptic-curve/**" + - "Cargo.*" + push: + branches: master + +defaults: + run: + working-directory: elliptic-curve + +env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + rust: + - 1.41.0 # MSRV + - stable + target: + - thumbv7em-none-eabi + - wasm32-unknown-unknown + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.rust }} + target: ${{ matrix.target }} + override: true + - run: cargo build --no-default-features --release --target ${{ matrix.target }} + test: + runs-on: ubuntu-latest + strategy: + matrix: + rust: + - 1.41.0 # MSRV + - stable + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.rust }} + - run: cargo check --all-features + - run: cargo test --no-default-features + - run: cargo test + - run: cargo test --all-features diff --git a/Cargo.lock b/Cargo.lock index 20895ffac..9d551c775 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -84,6 +84,7 @@ dependencies = [ "block-cipher", "crypto-mac", "digest 0.9.0", + "elliptic-curve", "signature", "stream-cipher", "universal-hash", @@ -106,6 +107,17 @@ dependencies = [ "generic-array 0.14.3", ] +[[package]] +name = "elliptic-curve" +version = "0.4.0" +dependencies = [ + "generic-array 0.14.3", + "hex", + "rand_core", + "subtle", + "zeroize", +] + [[package]] name = "generic-array" version = "0.12.3" @@ -155,6 +167,12 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "hex" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35" + [[package]] name = "hex-literal" version = "0.2.1" @@ -313,3 +331,9 @@ name = "version_check" version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" + +[[package]] +name = "zeroize" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cbac2ed2ba24cc90f5e06485ac8c7c1e5449fe8911aef4d8877218af021a5b8" diff --git a/Cargo.toml b/Cargo.toml index 4b9fdd831..aa9d7d9c4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,7 @@ members = [ "crypto-mac", "cryptography", "digest", + "elliptic-curve", "signature", "stream-cipher", "universal-hash", diff --git a/README.md b/README.md index a5c679232..39e3fce84 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ Collection of traits which describe functionality of cryptographic primitives. | [`block‑cipher`] | [Block cipher] | [![crates.io](https://img.shields.io/crates/v/block-cipher.svg)](https://crates.io/crates/block-cipher) | [![Documentation](https://docs.rs/block-cipher/badge.svg)](https://docs.rs/block-cipher) | ![build](https://github.com/RustCrypto/traits/workflows/block-cipher/badge.svg?branch=master&event=push) | | [`crypto‑mac`] | [Message authentication code] | [![crates.io](https://img.shields.io/crates/v/crypto-mac.svg)](https://crates.io/crates/crypto-mac) | [![Documentation](https://docs.rs/crypto-mac/badge.svg)](https://docs.rs/crypto-mac) | ![build](https://github.com/RustCrypto/traits/workflows/crypto-mac/badge.svg?branch=master&event=push) | | [`digest`] | [Cryptographic hash function] | [![crates.io](https://img.shields.io/crates/v/digest.svg)](https://crates.io/crates/digest) | [![Documentation](https://docs.rs/digest/badge.svg)](https://docs.rs/digest) | ![build](https://github.com/RustCrypto/traits/workflows/digest/badge.svg?branch=master&event=push) | +| [`elliptic-curve`] | [Elliptic curve cryptography] | [![crates.io](https://img.shields.io/crates/v/elliptic-curve.svg)](https://crates.io/crates/elliptic-curve) | [![Documentation](https://docs.rs/elliptic-curve/badge.svg)](https://docs.rs/elliptic-curve) | ![build](https://github.com/RustCrypto/traits/workflows/elliptic-curve/badge.svg?branch=master&event=push) | | [`signature`] | [Digital signature] | [![crates.io](https://img.shields.io/crates/v/signature.svg)](https://crates.io/crates/signature) | [![Documentation](https://docs.rs/signature/badge.svg)](https://docs.rs/signature) | ![build](https://github.com/RustCrypto/traits/workflows/signature/badge.svg?branch=master&event=push) | | [`stream‑cipher`] | [Stream cipher] | [![crates.io](https://img.shields.io/crates/v/stream-cipher.svg)](https://crates.io/crates/stream-cipher) | [![Documentation](https://docs.rs/stream-cipher/badge.svg)](https://docs.rs/stream-cipher) | ![build](https://github.com/RustCrypto/traits/workflows/stream-cipher/badge.svg?branch=master&event=push) | | [`universal‑hash`] | [Universal hash function] | [![crates.io](https://img.shields.io/crates/v/universal-hash.svg)](https://crates.io/crates/universal-hash) | [![Documentation](https://docs.rs/universal-hash/badge.svg)](https://docs.rs/universal-hash) | ![build](https://github.com/RustCrypto/traits/workflows/universal-hash/badge.svg?branch=master&event=push) | @@ -53,6 +54,7 @@ dual licensed as above, without any additional terms or conditions. [`crypto‑mac`]: https://github.com/RustCrypto/traits/tree/master/crypto-mac [`cryptography`]: https://github.com/RustCrypto/traits/tree/master/cryptography [`digest`]: https://github.com/RustCrypto/traits/tree/master/digest +[`elliptic-curve`]: https://github.com/RustCrypto/traits/tree/master/elliptic-curve [`signature`]: https://github.com/RustCrypto/traits/tree/master/signature [`stream‑cipher`]: https://github.com/RustCrypto/traits/tree/master/stream-cipher [`universal‑hash`]: https://github.com/RustCrypto/traits/tree/master/universal-hash @@ -64,5 +66,6 @@ dual licensed as above, without any additional terms or conditions. [Message authentication code]: https://en.wikipedia.org/wiki/Message_authentication_code [Cryptographic hash function]: https://en.wikipedia.org/wiki/Cryptographic_hash_function [Digital signature]: https://en.wikipedia.org/wiki/Digital_signature +[Elliptic curve cryptography]: https://en.wikipedia.org/wiki/Elliptic-curve_cryptography [Stream cipher]: https://en.wikipedia.org/wiki/Stream_cipher [Universal hash function]: https://en.wikipedia.org/wiki/Universal_hashing diff --git a/cryptography/Cargo.toml b/cryptography/Cargo.toml index 403f66880..5edcceec6 100644 --- a/cryptography/Cargo.toml +++ b/cryptography/Cargo.toml @@ -15,6 +15,7 @@ edition = "2018" aead = { version = "0.3", optional = true, path = "../aead" } block-cipher = { version = "0.8", optional = true, path = "../block-cipher" } digest = { version = "0.9", optional = true, path = "../digest" } +elliptic-curve = { version = "0.4", optional = true, path = "../elliptic-curve" } mac = { version = "0.8", package = "crypto-mac", optional = true, path = "../crypto-mac" } signature = { version = "1.1.0", optional = true, default-features = false, path = "../signature" } stream-cipher = { version = "0.6", optional = true, path = "../stream-cipher" } diff --git a/cryptography/src/lib.rs b/cryptography/src/lib.rs index fdb505fbf..9df174413 100644 --- a/cryptography/src/lib.rs +++ b/cryptography/src/lib.rs @@ -26,6 +26,7 @@ //! | [`aead`](https://docs.rs/aead) | `aead` | Authenticated Encryption with Associated Data (i.e. high-level symmetric encryption) | //! | [`block_cipher`](https://docs.rs/block-cipher) | `block‑cipher` | Block-based cryptographic permutations (i.e. low-level symmetric encryption) | //! | [`digest`](https://docs.rs/digest) | `digest` | Cryptographic hash functions | +//! | [`elliptic-curve`](https://docs.rs/elliptic-curve) | `elliptic-curve` | Elliptic curve cryptography | //! | [`mac`](https://docs.rs/crypto-mac) | `mac` | Message Authentication Codes (i.e. symmetric message authentication) | //! | [`signature`](https://docs.rs/signature) | `signature` | Digital signatures (i.e. public key-based message authentication) | //! | [`stream_cipher`](https://docs.rs/stream-cipher) | `stream‑cipher` | Ciphers based on randomly generated keystreams (i.e. low-level symmetric encryption) | @@ -48,6 +49,9 @@ pub use block_cipher; #[cfg(feature = "digest")] pub use digest; +#[cfg(feature = "elliptic-curve")] +pub use elliptic_curve; + #[cfg(feature = "mac")] pub use mac; diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md new file mode 100644 index 000000000..de475f85b --- /dev/null +++ b/elliptic-curve/CHANGELOG.md @@ -0,0 +1,36 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## 0.4.0 (2020-06-04) +### Changed +- Bump `generic-array` dependency from v0.12 to v0.14 ([#38]) + +[#38]: https://github.com/RustCrypto/elliptic-curves/pull/38 + +## 0.3.0 (2020-01-15) +### Added +- `Scalar` struct type ([#5]) + +### Changed +- Repository moved to + +### Removed +- Curve definitions/arithmetic extracted out into per-curve crates ([#5]) + +[#5]: https://github.com/RustCrypto/elliptic-curves/pull/5 + +## 0.2.0 (2019-12-11) +### Added +- `secp256r1` (P-256) point compression and decompression ([RustCrypto/signatures#63], [RustCrypto/signatures#64]) + +### Changed +- Bump MSRV to 1.37 ([RustCrypto/signatures#63]) + +[RustCrypto/signatures#63]: https://github.com/RustCrypto/signatures/pull/63 +[RustCrypto/signatures#64]: https://github.com/RustCrypto/signatures/pull/64 + +## 0.1.0 (2019-12-06) +- Initial release diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml new file mode 100644 index 000000000..54a690344 --- /dev/null +++ b/elliptic-curve/Cargo.toml @@ -0,0 +1,46 @@ +[package] +name = "elliptic-curve" +description = """ +General purpose Elliptic Curve Cryptography (ECC) support, including types +and traits for representing various elliptic curve forms, scalars, points, +and public/secret keys composed thereof. +""" +version = "0.4.0" # Also update html_root_url in lib.rs when bumping this +authors = ["RustCrypto Developers"] +license = "Apache-2.0 OR MIT" +documentation = "https://docs.rs/elliptic-curve" +repository = "https://github.com/RustCrypto/elliptic-curves/tree/master/elliptic-curve-crate" +readme = "README.md" +edition = "2018" +categories = ["cryptography", "no-std"] +keywords = ["crypto", "ecc", "elliptic", "weierstrass"] + +[dependencies.generic-array] +version = "0.14" +default-features = false + +[dependencies.rand_core] +version = "0.5" +optional = true +default-features = false + +[dependencies.subtle] +version = "2.2.2" +default-features = false + +[dependencies.zeroize] +version = "1" +optional = true +default-features = false + +[dev-dependencies] +hex = "0.4" + +[features] +default = [] +weierstrass = [] +std = [] + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] diff --git a/elliptic-curve/LICENSE-APACHE b/elliptic-curve/LICENSE-APACHE new file mode 100644 index 000000000..78173fa2e --- /dev/null +++ b/elliptic-curve/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/elliptic-curve/LICENSE-MIT b/elliptic-curve/LICENSE-MIT new file mode 100644 index 000000000..f39f9ff82 --- /dev/null +++ b/elliptic-curve/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2020 RustCrypto Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/elliptic-curve/README.md b/elliptic-curve/README.md new file mode 100644 index 000000000..5b7e92ba9 --- /dev/null +++ b/elliptic-curve/README.md @@ -0,0 +1,51 @@ +# RustCrypto: Elliptic Curve Traits + +[![crate][crate-image]][crate-link] +[![Docs][docs-image]][docs-link] +![Apache2/MIT licensed][license-image] +![Rust Version][rustc-image] +[![Build Status][build-image]][build-link] + +General purpose Elliptic Curve Cryptography (ECC) support, including types +and traits for representing various elliptic curve forms, scalars, points, +and public/secret keys composed thereof. + +[Documentation][docs-link] + +## Minimum Supported Rust Version + +All crates in this repository support Rust **1.41** or higher. + +Minimum supported Rust version can be changed in the future, but it will be +done with a minor version bump. + +## SemVer Policy + +- All on-by-default features of this library are covered by SemVer +- MSRV is considered exempt from SemVer as noted above + +## License + +All crates licensed under either of + + * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) + * [MIT license](http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall be +dual licensed as above, without any additional terms or conditions. + +[//]: # (badges) + +[crate-image]: https://img.shields.io/crates/v/elliptic-curve.svg +[crate-link]: https://crates.io/crates/elliptic-curve +[docs-image]: https://docs.rs/elliptic-curve/badge.svg +[docs-link]: https://docs.rs/elliptic-curve/ +[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg +[build-image]: https://github.com/RustCrypto/elliptic-curves/workflows/elliptic-curve%20crate/badge.svg?branch=master&event=push +[build-link]: https://github.com/RustCrypto/elliptic-curves/actions?query=workflow%3A%22elliptic-curve+crate%22 diff --git a/elliptic-curve/src/error.rs b/elliptic-curve/src/error.rs new file mode 100644 index 000000000..0a1ab14a8 --- /dev/null +++ b/elliptic-curve/src/error.rs @@ -0,0 +1,16 @@ +//! Error type + +use core::fmt::{self, Display}; + +/// Elliptic curve errors +#[derive(Copy, Clone, Debug)] +pub struct Error; + +impl Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("crypto error") + } +} + +#[cfg(feature = "std")] +impl std::error::Error for Error {} diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs new file mode 100644 index 000000000..35cdb5b0c --- /dev/null +++ b/elliptic-curve/src/lib.rs @@ -0,0 +1,41 @@ +//! General purpose Elliptic Curve Cryptography (ECC) support, including types +//! and traits for representing various elliptic curve forms, scalars, points, +//! and public/secret keys composed thereof. +//! +//! ## Minimum Supported Rust Version +//! +//! Rust **1.41** or higher. +//! +//! Minimum supported Rust version can be changed in the future, but it will be +//! done with a minor version bump. + +#![no_std] +#![cfg_attr(docsrs, feature(doc_cfg))] +#![forbid(unsafe_code)] +#![warn(missing_docs, rust_2018_idioms, unused_qualifications)] +#![doc( + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png", + html_root_url = "https://docs.rs/elliptic-curve/0.4.0" +)] + +#[cfg(feature = "std")] +extern crate std; + +#[cfg(feature = "rand_core")] +pub use rand_core; + +pub mod error; +pub mod secret_key; + +pub use generic_array::{self, typenum::consts}; +pub use subtle; + +// TODO(tarcieri): other curve forms +#[cfg(feature = "weierstrass")] +#[cfg_attr(docsrs, doc(cfg(feature = "weierstrass")))] +pub mod weierstrass; + +pub use self::{error::Error, secret_key::SecretKey}; + +/// Byte array containing a serialized scalar value (i.e. an integer) +pub type ScalarBytes = generic_array::GenericArray; diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs new file mode 100644 index 000000000..dd88fabdc --- /dev/null +++ b/elliptic-curve/src/secret_key.rs @@ -0,0 +1,88 @@ +//! Secret keys for elliptic curves (i.e. private scalars) +//! +//! The [`SecretKey`] type wraps the [`ScalarBytes`] byte array type with +//! a wrapper designed to prevent unintentional exposure of the scalar +//! value (e.g. via `Debug` or other logging). +//! +//! When the `zeroize` feature of this crate is enabled, it also handles +//! zeroing it out of memory securely on drop. + +use crate::{error::Error, ScalarBytes}; +use core::{ + convert::{TryFrom, TryInto}, + fmt, +}; +use generic_array::ArrayLength; + +/// Secret keys. +/// +/// In elliptic curve cryptography, secret keys are concretely privately known +/// scalar values. +/// +/// This type wraps a (serialized) scalar value, helping to prevent accidental +/// exposure and securely erasing the value from memory when dropped +/// (when the `zeroize` feature of this crate is enabled). +pub struct SecretKey +where + ScalarSize: ArrayLength, +{ + /// Private scalar value + scalar: ScalarBytes, +} + +impl SecretKey +where + ScalarSize: ArrayLength, +{ + /// Create a new secret key from a serialized scalar value + pub fn new(bytes: ScalarBytes) -> Self { + Self { scalar: bytes } + } + + /// Deserialize this secret key from a bytestring + pub fn from_bytes(bytes: impl AsRef<[u8]>) -> Result { + bytes.as_ref().try_into() + } + + /// Expose the secret [`ScalarBytes`] value this [`SecretKey`] wraps + pub fn secret_scalar(&self) -> &ScalarBytes { + &self.scalar + } +} + +impl TryFrom<&[u8]> for SecretKey +where + ScalarSize: ArrayLength, +{ + type Error = Error; + + fn try_from(slice: &[u8]) -> Result { + if slice.len() == ScalarSize::to_usize() { + Ok(SecretKey { + scalar: ScalarBytes::clone_from_slice(slice), + }) + } else { + Err(Error) + } + } +} + +impl fmt::Debug for SecretKey +where + ScalarSize: ArrayLength, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "SecretKey{{ ... }}", ScalarSize::to_usize()) + } +} + +#[cfg(feature = "zeroize")] +impl Drop for SecretKey +where + ScalarSize: ArrayLength, +{ + fn drop(&mut self) { + use zeroize::Zeroize; + self.scalar.zeroize(); + } +} diff --git a/elliptic-curve/src/weierstrass.rs b/elliptic-curve/src/weierstrass.rs new file mode 100644 index 000000000..23be63769 --- /dev/null +++ b/elliptic-curve/src/weierstrass.rs @@ -0,0 +1,46 @@ +//! Elliptic curves in short Weierstrass form. + +pub mod curve; +pub mod point; +pub mod public_key; + +pub use curve::Curve; +pub use point::{CompressedPoint, CompressedPointSize, UncompressedPoint, UncompressedPointSize}; +pub use public_key::PublicKey; + +use crate::{consts::U1, ScalarBytes}; +use core::ops::Add; +use generic_array::ArrayLength; +use subtle::{ConditionallySelectable, CtOption}; + +#[cfg(feature = "rand_core")] +use crate::secret_key::SecretKey; + +#[cfg(feature = "rand_core")] +use rand_core::{CryptoRng, RngCore}; + +/// Fixed-base scalar multiplication +pub trait FixedBaseScalarMul: Curve +where + ::Output: Add, + CompressedPoint: From, + UncompressedPoint: From, + CompressedPointSize: ArrayLength, + UncompressedPointSize: ArrayLength, +{ + /// Elliptic curve point type + type Point: ConditionallySelectable; + + /// Multiply the given scalar by the generator point for this elliptic + /// curve. + fn mul_base(scalar: &ScalarBytes) -> CtOption; +} + +/// Generate a secret key for this elliptic curve +#[cfg(feature = "rand_core")] +#[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] +pub trait GenerateSecretKey: Curve { + /// Generate a random [`SecretKey`] for this elliptic curve using the + /// provided [`CryptoRng`] + fn generate_secret_key(rng: &mut (impl CryptoRng + RngCore)) -> SecretKey; +} diff --git a/elliptic-curve/src/weierstrass/curve.rs b/elliptic-curve/src/weierstrass/curve.rs new file mode 100644 index 000000000..c7fdf623a --- /dev/null +++ b/elliptic-curve/src/weierstrass/curve.rs @@ -0,0 +1,20 @@ +//! Elliptic curves in short Weierstrass form + +use core::{fmt::Debug, ops::Add}; +use generic_array::{ + typenum::{Unsigned, U1}, + ArrayLength, +}; + +#[cfg(docsrs)] +use crate::ScalarBytes; + +/// Elliptic curve in short Weierstrass form +pub trait Curve: Clone + Debug + Default + Eq + Ord + Send + Sync { + /// Size of [`ScalarBytes`] for this curve, i.e. a serialized integer + /// modulo p (i.e. the curve's order). + type ScalarSize: ArrayLength + Add + Add + Eq + Ord + Unsigned; +} + +/// Alias for [`SecretKey`] type for a given Weierstrass curve +pub type SecretKey = crate::secret_key::SecretKey<::ScalarSize>; diff --git a/elliptic-curve/src/weierstrass/point.rs b/elliptic-curve/src/weierstrass/point.rs new file mode 100644 index 000000000..eb5d5b765 --- /dev/null +++ b/elliptic-curve/src/weierstrass/point.rs @@ -0,0 +1,201 @@ +//! Compressed and uncompressed Weierstrass elliptic curve points. +//! +//! Serialized according to the `Elliptic-Curve-Point-to-Octet-String` +//! algorithm described in SEC 1: Elliptic Curve Cryptography (Version 2.0) +//! section 2.3.3 (page 10): +//! +//! + +use super::Curve; +use crate::ScalarBytes; +use core::ops::Add; +use generic_array::{ + typenum::{Unsigned, U1}, + ArrayLength, GenericArray, +}; + +/// Size of a compressed elliptic curve point for the given curve when +/// serialized using `Elliptic-Curve-Point-to-Octet-String` encoding +/// (including leading `0x02` or `0x03` tag byte). +pub type CompressedPointSize = >::Output; + +/// Size of an uncompressed elliptic curve point for the given curve when +/// serialized using the `Elliptic-Curve-Point-to-Octet-String` encoding +/// (including leading `0x04` tag byte). +pub type UncompressedPointSize = <::Output as Add>::Output; + +/// Compressed elliptic curve points serialized according to the +/// `Elliptic-Curve-Point-to-Octet-String` algorithm. +/// +/// See section 2.3.3 of SEC 1: Elliptic Curve Cryptography (Version 2.0): +/// +/// +#[derive(Eq, Hash, PartialEq, PartialOrd, Ord)] +pub struct CompressedPoint +where + CompressedPointSize: ArrayLength, +{ + /// Raw serialized bytes of the compressed point + bytes: GenericArray>, +} + +impl CompressedPoint +where + CompressedPointSize: ArrayLength, +{ + /// Compress and serialize an elliptic curve point from its affine coordinates + pub fn from_affine_coords( + x: &ScalarBytes, + y: &ScalarBytes, + ) -> Self { + // Is the y-coordinate odd in the SEC-1 sense: `self mod 2 == 1`? + let is_y_odd = y.as_ref().last().expect("last byte") & 1 == 1; + let mut bytes = GenericArray::default(); + bytes[0] = if is_y_odd { 0x03 } else { 0x02 }; + bytes[1..].copy_from_slice(x); + Self { bytes } + } + + /// Create a new compressed elliptic curve point + pub fn from_bytes(into_bytes: B) -> Option + where + B: Into>>, + { + let bytes = into_bytes.into(); + let tag_byte = bytes.as_ref()[0]; + + if tag_byte == 0x02 || tag_byte == 0x03 { + Some(Self { bytes }) + } else { + None + } + } + + /// Borrow byte slice containing compressed curve point + #[inline] + pub fn as_bytes(&self) -> &[u8] { + &self.bytes + } + + /// Obtain owned array containing compressed curve point + #[inline] + pub fn into_bytes(self) -> GenericArray> { + self.bytes + } +} + +impl AsRef<[u8]> for CompressedPoint +where + CompressedPointSize: ArrayLength, +{ + #[inline] + fn as_ref(&self) -> &[u8] { + self.bytes.as_ref() + } +} + +impl Copy for CompressedPoint +where + CompressedPointSize: ArrayLength, + as ArrayLength>::ArrayType: Copy, +{ +} + +impl Clone for CompressedPoint +where + CompressedPointSize: ArrayLength, +{ + fn clone(&self) -> Self { + Self::from_bytes(self.bytes.clone()).unwrap() + } +} + +/// Uncompressed elliptic curve points serialized according to the +/// `Elliptic-Curve-Point-to-Octet-String` algorithm. +/// +/// See section 2.3.3 of SEC 1: Elliptic Curve Cryptography (Version 2.0): +/// +/// +#[derive(Eq, Hash, PartialEq, PartialOrd, Ord)] +pub struct UncompressedPoint +where + ::Output: Add, + UncompressedPointSize: ArrayLength, +{ + /// Raw serialized bytes of the uncompressed point + bytes: GenericArray>, +} + +impl UncompressedPoint +where + ::Output: Add, + UncompressedPointSize: ArrayLength, +{ + /// Serialize an elliptic curve point from its affine coordinates + pub fn from_affine_coords( + x: &ScalarBytes, + y: &ScalarBytes, + ) -> Self { + let scalar_size = C::ScalarSize::to_usize(); + let mut bytes = GenericArray::default(); + bytes[0] = 0x04; + bytes[1..(scalar_size + 1)].copy_from_slice(x); + bytes[(scalar_size + 1)..].copy_from_slice(y); + Self { bytes } + } + + /// Create a new uncompressed elliptic curve point + pub fn from_bytes(into_bytes: B) -> Option + where + B: Into>>, + { + let bytes = into_bytes.into(); + + if bytes.get(0) == Some(&0x04) { + Some(Self { bytes }) + } else { + None + } + } + + /// Borrow byte slice containing uncompressed curve point + #[inline] + pub fn as_bytes(&self) -> &[u8] { + &self.bytes + } + + /// Convert public key into owned byte array + #[inline] + pub fn into_bytes(self) -> GenericArray> { + self.bytes + } +} + +impl AsRef<[u8]> for UncompressedPoint +where + ::Output: Add, + UncompressedPointSize: ArrayLength, +{ + #[inline] + fn as_ref(&self) -> &[u8] { + self.bytes.as_ref() + } +} + +impl Copy for UncompressedPoint +where + ::Output: Add, + UncompressedPointSize: ArrayLength, + as ArrayLength>::ArrayType: Copy, +{ +} + +impl Clone for UncompressedPoint +where + ::Output: Add, + UncompressedPointSize: ArrayLength, +{ + fn clone(&self) -> Self { + Self::from_bytes(self.bytes.clone()).unwrap() + } +} diff --git a/elliptic-curve/src/weierstrass/public_key.rs b/elliptic-curve/src/weierstrass/public_key.rs new file mode 100644 index 000000000..d882a9580 --- /dev/null +++ b/elliptic-curve/src/weierstrass/public_key.rs @@ -0,0 +1,187 @@ +//! Public keys for Weierstrass curves: wrapper around compressed or +//! uncompressed elliptic curve points. + +use super::{ + point::{CompressedPoint, CompressedPointSize, UncompressedPoint, UncompressedPointSize}, + Curve, FixedBaseScalarMul, +}; +use crate::SecretKey; +use core::fmt::{self, Debug}; +use core::ops::Add; +use generic_array::{ + typenum::{Unsigned, U1}, + ArrayLength, GenericArray, +}; + +/// Size of an untagged point for given elliptic curve. +// TODO(tarcieri): const generics +pub type UntaggedPointSize = ::Output; + +/// Public keys for Weierstrass curves +#[derive(Clone, Eq, PartialEq, PartialOrd, Ord)] +pub enum PublicKey +where + ::Output: Add, + CompressedPointSize: ArrayLength, + UncompressedPointSize: ArrayLength, +{ + /// Compressed Weierstrass elliptic curve point + Compressed(CompressedPoint), + + /// Uncompressed Weierstrass elliptic curve point + Uncompressed(UncompressedPoint), +} + +impl PublicKey +where + ::Output: Add, + CompressedPointSize: ArrayLength, + UncompressedPointSize: ArrayLength, +{ + /// Decode public key from an elliptic curve point + /// (compressed or uncompressed) encoded using the + /// `Elliptic-Curve-Point-to-Octet-String` algorithm described in + /// SEC 1: Elliptic Curve Cryptography (Version 2.0) section + /// 2.3.3 (page 10). + /// + /// + pub fn from_bytes>(bytes: B) -> Option { + let slice = bytes.as_ref(); + let length = slice.len(); + + if length == >::to_usize() { + let array = GenericArray::clone_from_slice(slice); + let point = CompressedPoint::from_bytes(array)?; + Some(PublicKey::Compressed(point)) + } else if length == >::to_usize() { + let array = GenericArray::clone_from_slice(slice); + let point = UncompressedPoint::from_bytes(array)?; + Some(PublicKey::Uncompressed(point)) + } else { + None + } + } + + /// Decode public key from an compressed elliptic curve point + /// encoded using the `Elliptic-Curve-Point-to-Octet-String` algorithm + /// described in SEC 1: Elliptic Curve Cryptography (Version 2.0) section + /// 2.3.3 (page 10). + /// + /// + pub fn from_compressed_point(into_bytes: B) -> Option + where + B: Into>>, + { + CompressedPoint::from_bytes(into_bytes).map(PublicKey::Compressed) + } + + /// Decode public key from a raw uncompressed point serialized + /// as a bytestring, without a `0x04`-byte tag. + /// + /// This will be twice the modulus size, or 1-byte smaller than the + /// `Elliptic-Curve-Point-to-Octet-String` encoding i.e + /// with the leading `0x04` byte in that encoding removed. + pub fn from_untagged_point(bytes: &GenericArray>) -> Self + where + ::Output: ArrayLength, + { + let mut tagged_bytes = GenericArray::default(); + tagged_bytes.as_mut_slice()[0] = 0x04; + tagged_bytes.as_mut_slice()[1..].copy_from_slice(bytes.as_ref()); + + PublicKey::Uncompressed(UncompressedPoint::from_bytes(tagged_bytes).unwrap()) + } + + /// Obtain public key as a byte array reference + #[inline] + pub fn as_bytes(&self) -> &[u8] { + match self { + PublicKey::Compressed(ref point) => point.as_bytes(), + PublicKey::Uncompressed(ref point) => point.as_bytes(), + } + } +} + +impl PublicKey +where + C: FixedBaseScalarMul, + ::Output: Add, + CompressedPoint: From, + UncompressedPoint: From, + CompressedPointSize: ArrayLength, + UncompressedPointSize: ArrayLength, +{ + /// Compute the [`PublicKey`] for the provided [`SecretKey`]. + /// + /// The `compress` flag requests point compression. + pub fn from_secret_key(secret_key: &SecretKey, compress: bool) -> Option { + let ct_option = C::mul_base(secret_key.secret_scalar()); + + if ct_option.is_some().into() { + let affine_point = ct_option.unwrap(); + + if compress { + Some(PublicKey::Compressed(affine_point.into())) + } else { + Some(PublicKey::Uncompressed(affine_point.into())) + } + } else { + None + } + } +} + +impl AsRef<[u8]> for PublicKey +where + ::Output: Add, + CompressedPointSize: ArrayLength, + UncompressedPointSize: ArrayLength, +{ + #[inline] + fn as_ref(&self) -> &[u8] { + self.as_bytes() + } +} + +impl Copy for PublicKey +where + ::Output: Add, + CompressedPointSize: ArrayLength, + UncompressedPointSize: ArrayLength, + as ArrayLength>::ArrayType: Copy, + as ArrayLength>::ArrayType: Copy, +{ +} + +impl Debug for PublicKey +where + ::Output: Add, + CompressedPointSize: ArrayLength, + UncompressedPointSize: ArrayLength, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "PublicKey<{:?}>({:?})", C::default(), self.as_ref()) + } +} + +impl From> for PublicKey +where + ::Output: Add, + CompressedPointSize: ArrayLength, + UncompressedPointSize: ArrayLength, +{ + fn from(point: CompressedPoint) -> Self { + PublicKey::Compressed(point) + } +} + +impl From> for PublicKey +where + ::Output: Add, + CompressedPointSize: ArrayLength, + UncompressedPointSize: ArrayLength, +{ + fn from(point: UncompressedPoint) -> Self { + PublicKey::Uncompressed(point) + } +} From cbe0f2ae5902ef5f0750b48ce526febc05dcb20d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 13 Jul 2020 06:59:50 -0700 Subject: [PATCH 0162/1461] elliptic-curve: remove dev-dependency on `hex` (#214) It's not used in this crate --- Cargo.lock | 7 ------- elliptic-curve/Cargo.toml | 3 --- 2 files changed, 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9d551c775..bed9f72e7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -112,7 +112,6 @@ name = "elliptic-curve" version = "0.4.0" dependencies = [ "generic-array 0.14.3", - "hex", "rand_core", "subtle", "zeroize", @@ -167,12 +166,6 @@ dependencies = [ "stable_deref_trait", ] -[[package]] -name = "hex" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35" - [[package]] name = "hex-literal" version = "0.2.1" diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 54a690344..d16bfb9af 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -33,9 +33,6 @@ version = "1" optional = true default-features = false -[dev-dependencies] -hex = "0.4" - [features] default = [] weierstrass = [] From 3e7b861581185d7350db3315cd1a99b4c6d382e4 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 13 Jul 2020 10:14:59 -0700 Subject: [PATCH 0163/1461] elliptic-curve: bump version to v0.5.0-pre (#215) This commit isn't intended to be a release, but just bumps the version number in Cargo.toml to a `-pre` to distinguish it from the currently released v0.4.0. Several backwards incompatible / semver breaking changes have been introduced since the release. --- Cargo.lock | 2 +- cryptography/Cargo.toml | 2 +- elliptic-curve/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bed9f72e7..b3471b3ec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -109,7 +109,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.4.0" +version = "0.5.0-pre" dependencies = [ "generic-array 0.14.3", "rand_core", diff --git a/cryptography/Cargo.toml b/cryptography/Cargo.toml index 5edcceec6..38b0afe16 100644 --- a/cryptography/Cargo.toml +++ b/cryptography/Cargo.toml @@ -15,7 +15,7 @@ edition = "2018" aead = { version = "0.3", optional = true, path = "../aead" } block-cipher = { version = "0.8", optional = true, path = "../block-cipher" } digest = { version = "0.9", optional = true, path = "../digest" } -elliptic-curve = { version = "0.4", optional = true, path = "../elliptic-curve" } +elliptic-curve = { version = "= 0.5.0-pre", optional = true, path = "../elliptic-curve" } mac = { version = "0.8", package = "crypto-mac", optional = true, path = "../crypto-mac" } signature = { version = "1.1.0", optional = true, default-features = false, path = "../signature" } stream-cipher = { version = "0.6", optional = true, path = "../stream-cipher" } diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index d16bfb9af..ecc7a7274 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -5,7 +5,7 @@ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. """ -version = "0.4.0" # Also update html_root_url in lib.rs when bumping this +version = "0.5.0-pre" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/elliptic-curve" From 2b02a1b4f5a2a3aeb6e5e947db8096ac1f2a8c80 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 25 Jul 2020 11:14:46 -0700 Subject: [PATCH 0164/1461] elliptic-curve: add `Arithmetic` trait (#219) Several potentially useful traits (including the ECDSA ones) need access to these types, so it's helpful to have a single trait that defines them as associated types. Some additional bounds would really be helpful, but we can add those as they come up in practice. --- elliptic-curve/src/weierstrass/curve.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/elliptic-curve/src/weierstrass/curve.rs b/elliptic-curve/src/weierstrass/curve.rs index c7fdf623a..1d0079282 100644 --- a/elliptic-curve/src/weierstrass/curve.rs +++ b/elliptic-curve/src/weierstrass/curve.rs @@ -16,5 +16,14 @@ pub trait Curve: Clone + Debug + Default + Eq + Ord + Send + Sync { type ScalarSize: ArrayLength + Add + Add + Eq + Ord + Unsigned; } +/// Curve arithmetic support +pub trait Arithmetic: Curve { + /// Scalar type for a given curve + type Scalar; + + /// Affine point type for a given curve + type AffinePoint; +} + /// Alias for [`SecretKey`] type for a given Weierstrass curve pub type SecretKey = crate::secret_key::SecretKey<::ScalarSize>; From d009349c109f557b4f223c27969df613808a9931 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 25 Jul 2020 11:48:39 -0700 Subject: [PATCH 0165/1461] elliptic-curve: add `Generate` trait (#220) Trait for randomly generating types using a `rand_core::CryptoRng`. Potentially useful in trait bounds that need to generate e.g. `Scalar` types. --- elliptic-curve/src/lib.rs | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 35cdb5b0c..11c2c17e6 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -21,21 +21,30 @@ #[cfg(feature = "std")] extern crate std; -#[cfg(feature = "rand_core")] -pub use rand_core; - pub mod error; pub mod secret_key; -pub use generic_array::{self, typenum::consts}; -pub use subtle; - // TODO(tarcieri): other curve forms #[cfg(feature = "weierstrass")] #[cfg_attr(docsrs, doc(cfg(feature = "weierstrass")))] pub mod weierstrass; pub use self::{error::Error, secret_key::SecretKey}; +pub use generic_array::{self, typenum::consts}; +pub use subtle; + +#[cfg(feature = "rand_core")] +pub use rand_core; + +#[cfg(feature = "rand_core")] +use rand_core::{CryptoRng, RngCore}; /// Byte array containing a serialized scalar value (i.e. an integer) pub type ScalarBytes = generic_array::GenericArray; + +/// Trait for randomly generating a value +#[cfg(feature = "rand_core")] +pub trait Generate { + /// Generate a random element of this type using the provided [`CryptoRng`] + fn generate(rng: impl CryptoRng + RngCore) -> Self; +} From 51f97b6f0976f70eb31bd3f9839bf7ed15f9b977 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 27 Jul 2020 07:28:10 -0700 Subject: [PATCH 0166/1461] elliptic-curve: add doc_cfg label to Generate (#221) --- elliptic-curve/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 11c2c17e6..f763f5e83 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -44,6 +44,7 @@ pub type ScalarBytes = generic_array::GenericArray; /// Trait for randomly generating a value #[cfg(feature = "rand_core")] +#[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] pub trait Generate { /// Generate a random element of this type using the provided [`CryptoRng`] fn generate(rng: impl CryptoRng + RngCore) -> Self; From 8d67bb6c48fc54bfe76a52eebeb4cee0f8cd579c Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 27 Jul 2020 08:18:33 -0700 Subject: [PATCH 0167/1461] elliptic-curve: simplify GenerateSecretKey signature (#222) Removes the reference requirement on the argument, since the traits are impl'd for reference types --- elliptic-curve/src/weierstrass.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elliptic-curve/src/weierstrass.rs b/elliptic-curve/src/weierstrass.rs index 23be63769..f9a5cfd05 100644 --- a/elliptic-curve/src/weierstrass.rs +++ b/elliptic-curve/src/weierstrass.rs @@ -42,5 +42,5 @@ where pub trait GenerateSecretKey: Curve { /// Generate a random [`SecretKey`] for this elliptic curve using the /// provided [`CryptoRng`] - fn generate_secret_key(rng: &mut (impl CryptoRng + RngCore)) -> SecretKey; + fn generate_secret_key(rng: impl CryptoRng + RngCore) -> SecretKey; } From 3fd8ac7fa787cfbea275306fab011a592206b1b2 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 27 Jul 2020 13:47:50 -0700 Subject: [PATCH 0168/1461] [WIP] elliptic-curve: extract toplevel `Curve` trait (#223) This is a fairly substantial refactoring of the `elliptic-curve` crate which extracts a toplevel `elliptic_curve::Curve` trait and redefines all types to use it. The `elliptic_curve::weierstrass::Curve` trait is maintained, but relegated to a marker trait. That said, it's still used as the marker trait for all traits/types defined in the `elliptic_curve::weierstrass` module. Notably the main thing this facilitates is making `SecretKey` generic around a `C: elliptic_curve::Curve` generic type. The previous impetus was to avoid directly associating types dependent on scalars with specific elliptic curves (rather the curve's order), but this is ultimately unhelpful as it precludes accounting for trait impls on the curve in trait bounds. With the new approach, we can use trait bounds to conditionally define methods on `SecretKey`, e.g. bounding a `SecretKey::generate` impl on curves which impl `Arithmetic where Self::Scalar: Generate`. This would eliminate the need for a special `GenerateSecretKey` trait. One other notable change is the associated type for computing type sizes for a particular curve has been renamed to `ElementSize`, rather than the previous `ScalarSize`. This hopefully captures that this size is for all elements related to a particular curve, i.e. both the base and scalar fields. --- elliptic-curve/src/lib.rs | 36 ++++++++- elliptic-curve/src/secret_key.rs | 50 ++++--------- elliptic-curve/src/weierstrass.rs | 30 ++++---- elliptic-curve/src/weierstrass/curve.rs | 29 ------- elliptic-curve/src/weierstrass/point.rs | 73 +++++++++--------- elliptic-curve/src/weierstrass/public_key.rs | 79 +++++++++++--------- 6 files changed, 148 insertions(+), 149 deletions(-) delete mode 100644 elliptic-curve/src/weierstrass/curve.rs diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index f763f5e83..9918f7613 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -36,16 +36,46 @@ pub use subtle; #[cfg(feature = "rand_core")] pub use rand_core; +use core::{fmt::Debug, ops::Add}; +use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; + #[cfg(feature = "rand_core")] use rand_core::{CryptoRng, RngCore}; -/// Byte array containing a serialized scalar value (i.e. an integer) -pub type ScalarBytes = generic_array::GenericArray; +/// Elliptic curve. +/// +/// This trait is intended to be impl'd by a ZST which represents a concrete +/// elliptic curve. +/// +/// Other traits in this crate which are bounded by [`Curve`] are intended to +/// be impl'd by these ZSTs, facilitating types which are generic over elliptic +/// curves (e.g. [`SecretKey`]). +pub trait Curve: Clone + Debug + Default + Eq + Ord + Send + Sync { + /// Number of bytes required to serialize elements of field elements + /// associated with this curve, e.g. elements of the base/scalar fields. + /// + /// This is used for computing the sizes for types related to this curve. + type ElementSize: ArrayLength + Add + Eq + Ord + Unsigned; +} + +/// Elliptic curve with curve arithmetic support +pub trait Arithmetic: Curve { + /// Scalar type for a given curve + type Scalar; -/// Trait for randomly generating a value + /// Affine point type for a given curve + type AffinePoint; +} + +/// Trait for randomly generating a value. +/// +/// Primarily intended for use with scalar types for a particular curve. #[cfg(feature = "rand_core")] #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] pub trait Generate { /// Generate a random element of this type using the provided [`CryptoRng`] fn generate(rng: impl CryptoRng + RngCore) -> Self; } + +/// Byte array containing a serialized scalar value (i.e. an integer) +pub type ScalarBytes = GenericArray::ElementSize>; diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index dd88fabdc..ef6db527e 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -7,35 +7,26 @@ //! When the `zeroize` feature of this crate is enabled, it also handles //! zeroing it out of memory securely on drop. -use crate::{error::Error, ScalarBytes}; +use crate::{error::Error, Curve, ScalarBytes}; use core::{ convert::{TryFrom, TryInto}, - fmt, + fmt::{self, Debug}, }; -use generic_array::ArrayLength; +use generic_array::{typenum::Unsigned, GenericArray}; -/// Secret keys. +/// Elliptic curve secret keys. /// -/// In elliptic curve cryptography, secret keys are concretely privately known -/// scalar values. -/// -/// This type wraps a (serialized) scalar value, helping to prevent accidental +/// This type wraps a serialized scalar value, helping to prevent accidental /// exposure and securely erasing the value from memory when dropped /// (when the `zeroize` feature of this crate is enabled). -pub struct SecretKey -where - ScalarSize: ArrayLength, -{ +pub struct SecretKey { /// Private scalar value - scalar: ScalarBytes, + scalar: ScalarBytes, } -impl SecretKey -where - ScalarSize: ArrayLength, -{ +impl SecretKey { /// Create a new secret key from a serialized scalar value - pub fn new(bytes: ScalarBytes) -> Self { + pub fn new(bytes: ScalarBytes) -> Self { Self { scalar: bytes } } @@ -45,21 +36,18 @@ where } /// Expose the secret [`ScalarBytes`] value this [`SecretKey`] wraps - pub fn secret_scalar(&self) -> &ScalarBytes { + pub fn secret_scalar(&self) -> &ScalarBytes { &self.scalar } } -impl TryFrom<&[u8]> for SecretKey -where - ScalarSize: ArrayLength, -{ +impl TryFrom<&[u8]> for SecretKey { type Error = Error; fn try_from(slice: &[u8]) -> Result { - if slice.len() == ScalarSize::to_usize() { + if slice.len() == C::ElementSize::to_usize() { Ok(SecretKey { - scalar: ScalarBytes::clone_from_slice(slice), + scalar: GenericArray::clone_from_slice(slice), }) } else { Err(Error) @@ -67,20 +55,14 @@ where } } -impl fmt::Debug for SecretKey -where - ScalarSize: ArrayLength, -{ +impl Debug for SecretKey { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "SecretKey{{ ... }}", ScalarSize::to_usize()) + write!(f, "SecretKey<{:?}>{{ ... }}", C::default()) } } #[cfg(feature = "zeroize")] -impl Drop for SecretKey -where - ScalarSize: ArrayLength, -{ +impl Drop for SecretKey { fn drop(&mut self) { use zeroize::Zeroize; self.scalar.zeroize(); diff --git a/elliptic-curve/src/weierstrass.rs b/elliptic-curve/src/weierstrass.rs index f9a5cfd05..3ac76ab66 100644 --- a/elliptic-curve/src/weierstrass.rs +++ b/elliptic-curve/src/weierstrass.rs @@ -1,12 +1,12 @@ //! Elliptic curves in short Weierstrass form. -pub mod curve; pub mod point; pub mod public_key; -pub use curve::Curve; -pub use point::{CompressedPoint, CompressedPointSize, UncompressedPoint, UncompressedPointSize}; -pub use public_key::PublicKey; +pub use self::{ + point::{CompressedPoint, CompressedPointSize, UncompressedPoint, UncompressedPointSize}, + public_key::PublicKey, +}; use crate::{consts::U1, ScalarBytes}; use core::ops::Add; @@ -19,21 +19,25 @@ use crate::secret_key::SecretKey; #[cfg(feature = "rand_core")] use rand_core::{CryptoRng, RngCore}; +/// Marker trait for elliptic curves in short Weierstrass form +pub trait Curve: super::Curve {} + /// Fixed-base scalar multiplication pub trait FixedBaseScalarMul: Curve where - ::Output: Add, - CompressedPoint: From, - UncompressedPoint: From, - CompressedPointSize: ArrayLength, - UncompressedPointSize: ArrayLength, + Self::ElementSize: Add, + ::Output: Add, + CompressedPoint: From, + UncompressedPoint: From, + CompressedPointSize: ArrayLength, + UncompressedPointSize: ArrayLength, { - /// Elliptic curve point type - type Point: ConditionallySelectable; + /// Affine point type for this elliptic curve + type AffinePoint: ConditionallySelectable; /// Multiply the given scalar by the generator point for this elliptic /// curve. - fn mul_base(scalar: &ScalarBytes) -> CtOption; + fn mul_base(scalar: &ScalarBytes) -> CtOption; } /// Generate a secret key for this elliptic curve @@ -42,5 +46,5 @@ where pub trait GenerateSecretKey: Curve { /// Generate a random [`SecretKey`] for this elliptic curve using the /// provided [`CryptoRng`] - fn generate_secret_key(rng: impl CryptoRng + RngCore) -> SecretKey; + fn generate_secret_key(rng: impl CryptoRng + RngCore) -> SecretKey; } diff --git a/elliptic-curve/src/weierstrass/curve.rs b/elliptic-curve/src/weierstrass/curve.rs deleted file mode 100644 index 1d0079282..000000000 --- a/elliptic-curve/src/weierstrass/curve.rs +++ /dev/null @@ -1,29 +0,0 @@ -//! Elliptic curves in short Weierstrass form - -use core::{fmt::Debug, ops::Add}; -use generic_array::{ - typenum::{Unsigned, U1}, - ArrayLength, -}; - -#[cfg(docsrs)] -use crate::ScalarBytes; - -/// Elliptic curve in short Weierstrass form -pub trait Curve: Clone + Debug + Default + Eq + Ord + Send + Sync { - /// Size of [`ScalarBytes`] for this curve, i.e. a serialized integer - /// modulo p (i.e. the curve's order). - type ScalarSize: ArrayLength + Add + Add + Eq + Ord + Unsigned; -} - -/// Curve arithmetic support -pub trait Arithmetic: Curve { - /// Scalar type for a given curve - type Scalar; - - /// Affine point type for a given curve - type AffinePoint; -} - -/// Alias for [`SecretKey`] type for a given Weierstrass curve -pub type SecretKey = crate::secret_key::SecretKey<::ScalarSize>; diff --git a/elliptic-curve/src/weierstrass/point.rs b/elliptic-curve/src/weierstrass/point.rs index eb5d5b765..735ceb711 100644 --- a/elliptic-curve/src/weierstrass/point.rs +++ b/elliptic-curve/src/weierstrass/point.rs @@ -17,12 +17,13 @@ use generic_array::{ /// Size of a compressed elliptic curve point for the given curve when /// serialized using `Elliptic-Curve-Point-to-Octet-String` encoding /// (including leading `0x02` or `0x03` tag byte). -pub type CompressedPointSize = >::Output; +pub type CompressedPointSize = <::ElementSize as Add>::Output; /// Size of an uncompressed elliptic curve point for the given curve when /// serialized using the `Elliptic-Curve-Point-to-Octet-String` encoding /// (including leading `0x04` tag byte). -pub type UncompressedPointSize = <::Output as Add>::Output; +pub type UncompressedPointSize = + <<::ElementSize as Add>::Output as Add>::Output; /// Compressed elliptic curve points serialized according to the /// `Elliptic-Curve-Point-to-Octet-String` algorithm. @@ -33,21 +34,20 @@ pub type UncompressedPointSize = <::Output as Add #[derive(Eq, Hash, PartialEq, PartialOrd, Ord)] pub struct CompressedPoint where - CompressedPointSize: ArrayLength, + C::ElementSize: Add, + CompressedPointSize: ArrayLength, { /// Raw serialized bytes of the compressed point - bytes: GenericArray>, + bytes: GenericArray>, } impl CompressedPoint where - CompressedPointSize: ArrayLength, + C::ElementSize: Add, + CompressedPointSize: ArrayLength, { /// Compress and serialize an elliptic curve point from its affine coordinates - pub fn from_affine_coords( - x: &ScalarBytes, - y: &ScalarBytes, - ) -> Self { + pub fn from_affine_coords(x: &ScalarBytes, y: &ScalarBytes) -> Self { // Is the y-coordinate odd in the SEC-1 sense: `self mod 2 == 1`? let is_y_odd = y.as_ref().last().expect("last byte") & 1 == 1; let mut bytes = GenericArray::default(); @@ -59,7 +59,7 @@ where /// Create a new compressed elliptic curve point pub fn from_bytes(into_bytes: B) -> Option where - B: Into>>, + B: Into>>, { let bytes = into_bytes.into(); let tag_byte = bytes.as_ref()[0]; @@ -79,14 +79,15 @@ where /// Obtain owned array containing compressed curve point #[inline] - pub fn into_bytes(self) -> GenericArray> { + pub fn into_bytes(self) -> GenericArray> { self.bytes } } impl AsRef<[u8]> for CompressedPoint where - CompressedPointSize: ArrayLength, + C::ElementSize: Add, + CompressedPointSize: ArrayLength, { #[inline] fn as_ref(&self) -> &[u8] { @@ -96,14 +97,16 @@ where impl Copy for CompressedPoint where - CompressedPointSize: ArrayLength, - as ArrayLength>::ArrayType: Copy, + C::ElementSize: Add, + CompressedPointSize: ArrayLength, + as ArrayLength>::ArrayType: Copy, { } impl Clone for CompressedPoint where - CompressedPointSize: ArrayLength, + C::ElementSize: Add, + CompressedPointSize: ArrayLength, { fn clone(&self) -> Self { Self::from_bytes(self.bytes.clone()).unwrap() @@ -119,24 +122,23 @@ where #[derive(Eq, Hash, PartialEq, PartialOrd, Ord)] pub struct UncompressedPoint where - ::Output: Add, - UncompressedPointSize: ArrayLength, + C::ElementSize: Add, + ::Output: Add, + UncompressedPointSize: ArrayLength, { /// Raw serialized bytes of the uncompressed point - bytes: GenericArray>, + bytes: GenericArray>, } impl UncompressedPoint where - ::Output: Add, - UncompressedPointSize: ArrayLength, + C::ElementSize: Add, + ::Output: Add, + UncompressedPointSize: ArrayLength, { /// Serialize an elliptic curve point from its affine coordinates - pub fn from_affine_coords( - x: &ScalarBytes, - y: &ScalarBytes, - ) -> Self { - let scalar_size = C::ScalarSize::to_usize(); + pub fn from_affine_coords(x: &ScalarBytes, y: &ScalarBytes) -> Self { + let scalar_size = C::ElementSize::to_usize(); let mut bytes = GenericArray::default(); bytes[0] = 0x04; bytes[1..(scalar_size + 1)].copy_from_slice(x); @@ -147,7 +149,7 @@ where /// Create a new uncompressed elliptic curve point pub fn from_bytes(into_bytes: B) -> Option where - B: Into>>, + B: Into>>, { let bytes = into_bytes.into(); @@ -166,15 +168,16 @@ where /// Convert public key into owned byte array #[inline] - pub fn into_bytes(self) -> GenericArray> { + pub fn into_bytes(self) -> GenericArray> { self.bytes } } impl AsRef<[u8]> for UncompressedPoint where - ::Output: Add, - UncompressedPointSize: ArrayLength, + C::ElementSize: Add, + ::Output: Add, + UncompressedPointSize: ArrayLength, { #[inline] fn as_ref(&self) -> &[u8] { @@ -184,16 +187,18 @@ where impl Copy for UncompressedPoint where - ::Output: Add, - UncompressedPointSize: ArrayLength, - as ArrayLength>::ArrayType: Copy, + C::ElementSize: Add, + ::Output: Add, + UncompressedPointSize: ArrayLength, + as ArrayLength>::ArrayType: Copy, { } impl Clone for UncompressedPoint where - ::Output: Add, - UncompressedPointSize: ArrayLength, + C::ElementSize: Add, + ::Output: Add, + UncompressedPointSize: ArrayLength, { fn clone(&self) -> Self { Self::from_bytes(self.bytes.clone()).unwrap() diff --git a/elliptic-curve/src/weierstrass/public_key.rs b/elliptic-curve/src/weierstrass/public_key.rs index d882a9580..8036d4a2d 100644 --- a/elliptic-curve/src/weierstrass/public_key.rs +++ b/elliptic-curve/src/weierstrass/public_key.rs @@ -14,16 +14,16 @@ use generic_array::{ }; /// Size of an untagged point for given elliptic curve. -// TODO(tarcieri): const generics -pub type UntaggedPointSize = ::Output; +pub type UntaggedPointSize = <::ElementSize as Add>::Output; /// Public keys for Weierstrass curves #[derive(Clone, Eq, PartialEq, PartialOrd, Ord)] pub enum PublicKey where - ::Output: Add, - CompressedPointSize: ArrayLength, - UncompressedPointSize: ArrayLength, + C::ElementSize: Add, + ::Output: Add, + CompressedPointSize: ArrayLength, + UncompressedPointSize: ArrayLength, { /// Compressed Weierstrass elliptic curve point Compressed(CompressedPoint), @@ -34,9 +34,10 @@ where impl PublicKey where - ::Output: Add, - CompressedPointSize: ArrayLength, - UncompressedPointSize: ArrayLength, + C::ElementSize: Add, + ::Output: Add, + CompressedPointSize: ArrayLength, + UncompressedPointSize: ArrayLength, { /// Decode public key from an elliptic curve point /// (compressed or uncompressed) encoded using the @@ -49,11 +50,11 @@ where let slice = bytes.as_ref(); let length = slice.len(); - if length == >::to_usize() { + if length == >::to_usize() { let array = GenericArray::clone_from_slice(slice); let point = CompressedPoint::from_bytes(array)?; Some(PublicKey::Compressed(point)) - } else if length == >::to_usize() { + } else if length == >::to_usize() { let array = GenericArray::clone_from_slice(slice); let point = UncompressedPoint::from_bytes(array)?; Some(PublicKey::Uncompressed(point)) @@ -70,7 +71,7 @@ where /// pub fn from_compressed_point(into_bytes: B) -> Option where - B: Into>>, + B: Into>>, { CompressedPoint::from_bytes(into_bytes).map(PublicKey::Compressed) } @@ -81,9 +82,9 @@ where /// This will be twice the modulus size, or 1-byte smaller than the /// `Elliptic-Curve-Point-to-Octet-String` encoding i.e /// with the leading `0x04` byte in that encoding removed. - pub fn from_untagged_point(bytes: &GenericArray>) -> Self + pub fn from_untagged_point(bytes: &GenericArray>) -> Self where - ::Output: ArrayLength, + ::Output: ArrayLength, { let mut tagged_bytes = GenericArray::default(); tagged_bytes.as_mut_slice()[0] = 0x04; @@ -105,16 +106,17 @@ where impl PublicKey where C: FixedBaseScalarMul, - ::Output: Add, - CompressedPoint: From, - UncompressedPoint: From, - CompressedPointSize: ArrayLength, - UncompressedPointSize: ArrayLength, + C::ElementSize: Add, + ::Output: Add, + CompressedPoint: From, + UncompressedPoint: From, + CompressedPointSize: ArrayLength, + UncompressedPointSize: ArrayLength, { /// Compute the [`PublicKey`] for the provided [`SecretKey`]. /// /// The `compress` flag requests point compression. - pub fn from_secret_key(secret_key: &SecretKey, compress: bool) -> Option { + pub fn from_secret_key(secret_key: &SecretKey, compress: bool) -> Option { let ct_option = C::mul_base(secret_key.secret_scalar()); if ct_option.is_some().into() { @@ -133,9 +135,10 @@ where impl AsRef<[u8]> for PublicKey where - ::Output: Add, - CompressedPointSize: ArrayLength, - UncompressedPointSize: ArrayLength, + C::ElementSize: Add, + ::Output: Add, + CompressedPointSize: ArrayLength, + UncompressedPointSize: ArrayLength, { #[inline] fn as_ref(&self) -> &[u8] { @@ -145,19 +148,21 @@ where impl Copy for PublicKey where - ::Output: Add, - CompressedPointSize: ArrayLength, - UncompressedPointSize: ArrayLength, - as ArrayLength>::ArrayType: Copy, - as ArrayLength>::ArrayType: Copy, + C::ElementSize: Add, + ::Output: Add, + CompressedPointSize: ArrayLength, + UncompressedPointSize: ArrayLength, + as ArrayLength>::ArrayType: Copy, + as ArrayLength>::ArrayType: Copy, { } impl Debug for PublicKey where - ::Output: Add, - CompressedPointSize: ArrayLength, - UncompressedPointSize: ArrayLength, + C::ElementSize: Add, + ::Output: Add, + CompressedPointSize: ArrayLength, + UncompressedPointSize: ArrayLength, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "PublicKey<{:?}>({:?})", C::default(), self.as_ref()) @@ -166,9 +171,10 @@ where impl From> for PublicKey where - ::Output: Add, - CompressedPointSize: ArrayLength, - UncompressedPointSize: ArrayLength, + C::ElementSize: Add, + ::Output: Add, + CompressedPointSize: ArrayLength, + UncompressedPointSize: ArrayLength, { fn from(point: CompressedPoint) -> Self { PublicKey::Compressed(point) @@ -177,9 +183,10 @@ where impl From> for PublicKey where - ::Output: Add, - CompressedPointSize: ArrayLength, - UncompressedPointSize: ArrayLength, + C::ElementSize: Add, + ::Output: Add, + CompressedPointSize: ArrayLength, + UncompressedPointSize: ArrayLength, { fn from(point: UncompressedPoint) -> Self { PublicKey::Uncompressed(point) From c9a57b57b28ed659e5f7c56406a7ecf0674a4e49 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 27 Jul 2020 16:26:10 -0700 Subject: [PATCH 0169/1461] elliptic-curve: add conditional `SecretKey::generate` method (#224) Replaces the `GenerateSecretKey` trait with a conditionally implemented `SecretKey::generate` method, which leverages the new `Curve`, `Arithmetic`, and `Generate` traits. --- elliptic-curve/src/secret_key.rs | 21 +++++++++++++++++++++ elliptic-curve/src/weierstrass.rs | 9 --------- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index ef6db527e..81c3ffeff 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -14,6 +14,12 @@ use core::{ }; use generic_array::{typenum::Unsigned, GenericArray}; +#[cfg(feature = "rand_core")] +use { + crate::{Arithmetic, Generate}, + rand_core::{CryptoRng, RngCore}, +}; + /// Elliptic curve secret keys. /// /// This type wraps a serialized scalar value, helping to prevent accidental @@ -61,6 +67,21 @@ impl Debug for SecretKey { } } +#[cfg(feature = "rand_core")] +#[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] +impl SecretKey +where + C: Curve + Arithmetic, + C::Scalar: Generate + Into>, +{ + /// Generate a new [`SecretKey`] + pub fn generate(rng: impl CryptoRng + RngCore) -> Self { + Self { + scalar: C::Scalar::generate(rng).into(), + } + } +} + #[cfg(feature = "zeroize")] impl Drop for SecretKey { fn drop(&mut self) { diff --git a/elliptic-curve/src/weierstrass.rs b/elliptic-curve/src/weierstrass.rs index 3ac76ab66..c6fc7b545 100644 --- a/elliptic-curve/src/weierstrass.rs +++ b/elliptic-curve/src/weierstrass.rs @@ -39,12 +39,3 @@ where /// curve. fn mul_base(scalar: &ScalarBytes) -> CtOption; } - -/// Generate a secret key for this elliptic curve -#[cfg(feature = "rand_core")] -#[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] -pub trait GenerateSecretKey: Curve { - /// Generate a random [`SecretKey`] for this elliptic curve using the - /// provided [`CryptoRng`] - fn generate_secret_key(rng: impl CryptoRng + RngCore) -> SecretKey; -} From 7f56eb0dd570bbaf0fc411a061694e0860329e29 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 27 Jul 2020 16:33:52 -0700 Subject: [PATCH 0170/1461] elliptic-curve: fix warnings (#225) Fixes some unused import warnings overlooked in #224 --- elliptic-curve/src/weierstrass.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/elliptic-curve/src/weierstrass.rs b/elliptic-curve/src/weierstrass.rs index c6fc7b545..cc2d15fa7 100644 --- a/elliptic-curve/src/weierstrass.rs +++ b/elliptic-curve/src/weierstrass.rs @@ -13,12 +13,6 @@ use core::ops::Add; use generic_array::ArrayLength; use subtle::{ConditionallySelectable, CtOption}; -#[cfg(feature = "rand_core")] -use crate::secret_key::SecretKey; - -#[cfg(feature = "rand_core")] -use rand_core::{CryptoRng, RngCore}; - /// Marker trait for elliptic curves in short Weierstrass form pub trait Curve: super::Curve {} From 513eb076c77f9272289272bd4abbc017f190af84 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 27 Jul 2020 17:02:55 -0700 Subject: [PATCH 0171/1461] elliptic-curve: impl Generate for SecretKey (#226) This method fits the existing `Generate` trait. This allows bounds to simply specify `where SecretKey: Generate` to write code that needs to handle generic generation of secret keys, as opposed to trying to encode the full bounds for the impl. --- elliptic-curve/src/secret_key.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 81c3ffeff..31de82fd9 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -69,13 +69,13 @@ impl Debug for SecretKey { #[cfg(feature = "rand_core")] #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] -impl SecretKey +impl Generate for SecretKey where C: Curve + Arithmetic, C::Scalar: Generate + Into>, { /// Generate a new [`SecretKey`] - pub fn generate(rng: impl CryptoRng + RngCore) -> Self { + fn generate(rng: impl CryptoRng + RngCore) -> Self { Self { scalar: C::Scalar::generate(rng).into(), } From 23b27c07e84c078edb748d2157cf9328fe9659eb Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 27 Jul 2020 18:35:24 -0700 Subject: [PATCH 0172/1461] elliptic-curve: simplify `FixedBaseScalarMul` trait (#227) Most of the previous bounds are now irrelevant, and it can now also leverage the `Arithmetic` trait for the `AffinePoint` definition. --- elliptic-curve/src/weierstrass.rs | 20 ++++---------------- elliptic-curve/src/weierstrass/public_key.rs | 10 +++++----- 2 files changed, 9 insertions(+), 21 deletions(-) diff --git a/elliptic-curve/src/weierstrass.rs b/elliptic-curve/src/weierstrass.rs index cc2d15fa7..362ea1704 100644 --- a/elliptic-curve/src/weierstrass.rs +++ b/elliptic-curve/src/weierstrass.rs @@ -8,28 +8,16 @@ pub use self::{ public_key::PublicKey, }; -use crate::{consts::U1, ScalarBytes}; -use core::ops::Add; -use generic_array::ArrayLength; -use subtle::{ConditionallySelectable, CtOption}; +use crate::{Arithmetic, ScalarBytes}; +use subtle::CtOption; /// Marker trait for elliptic curves in short Weierstrass form pub trait Curve: super::Curve {} /// Fixed-base scalar multiplication -pub trait FixedBaseScalarMul: Curve -where - Self::ElementSize: Add, - ::Output: Add, - CompressedPoint: From, - UncompressedPoint: From, - CompressedPointSize: ArrayLength, - UncompressedPointSize: ArrayLength, -{ - /// Affine point type for this elliptic curve - type AffinePoint: ConditionallySelectable; - +pub trait FixedBaseScalarMul: Curve + Arithmetic { /// Multiply the given scalar by the generator point for this elliptic /// curve. + // TODO(tarcieri): use `Self::Scalar` for the `scalar` param fn mul_base(scalar: &ScalarBytes) -> CtOption; } diff --git a/elliptic-curve/src/weierstrass/public_key.rs b/elliptic-curve/src/weierstrass/public_key.rs index 8036d4a2d..dde6000d1 100644 --- a/elliptic-curve/src/weierstrass/public_key.rs +++ b/elliptic-curve/src/weierstrass/public_key.rs @@ -5,7 +5,7 @@ use super::{ point::{CompressedPoint, CompressedPointSize, UncompressedPoint, UncompressedPointSize}, Curve, FixedBaseScalarMul, }; -use crate::SecretKey; +use crate::{Error, SecretKey}; use core::fmt::{self, Debug}; use core::ops::Add; use generic_array::{ @@ -116,19 +116,19 @@ where /// Compute the [`PublicKey`] for the provided [`SecretKey`]. /// /// The `compress` flag requests point compression. - pub fn from_secret_key(secret_key: &SecretKey, compress: bool) -> Option { + pub fn from_secret_key(secret_key: &SecretKey, compress: bool) -> Result { let ct_option = C::mul_base(secret_key.secret_scalar()); if ct_option.is_some().into() { let affine_point = ct_option.unwrap(); if compress { - Some(PublicKey::Compressed(affine_point.into())) + Ok(PublicKey::Compressed(affine_point.into())) } else { - Some(PublicKey::Uncompressed(affine_point.into())) + Ok(PublicKey::Uncompressed(affine_point.into())) } } else { - None + Err(Error) } } } From f8a916bbcff07aece243db24f17f663d4077baba Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 28 Jul 2020 09:50:22 -0700 Subject: [PATCH 0173/1461] elliptic-curve: add `Invert` trait (#228) Add a trait for performing scalar/field inversions. The main motivation for this is to allow for things like `BlindedScalar` type which use random blinding for either efficiency reasons (to allow a vartime inversion) and/or as a side-channel defense. --- elliptic-curve/src/lib.rs | 1 + elliptic-curve/src/ops.rs | 12 ++++++++++++ 2 files changed, 13 insertions(+) create mode 100644 elliptic-curve/src/ops.rs diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 9918f7613..141bff378 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -22,6 +22,7 @@ extern crate std; pub mod error; +pub mod ops; pub mod secret_key; // TODO(tarcieri): other curve forms diff --git a/elliptic-curve/src/ops.rs b/elliptic-curve/src/ops.rs new file mode 100644 index 000000000..09f811d7e --- /dev/null +++ b/elliptic-curve/src/ops.rs @@ -0,0 +1,12 @@ +//! Traits for arithmetic operations on elliptic curve field elements + +use subtle::CtOption; + +/// Perform an inversion on a field element (i.e. base field element or scalar) +pub trait Invert { + /// Field element type + type Output; + + /// Invert a field element. + fn invert(&self) -> CtOption; +} From 6616a7c639435b682936ef4e2d338860a4029aa8 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 29 Jul 2020 09:44:18 -0700 Subject: [PATCH 0174/1461] elliptic-curve: add FromPublicKey/FromSecretKey traits (#229) These traits allow converting: - SecretKey => Scalar - PublicKey => AffinePoint ...in a curve-agnostic way. --- elliptic-curve/src/lib.rs | 9 ++++++--- elliptic-curve/src/secret_key.rs | 9 +++++++++ elliptic-curve/src/weierstrass.rs | 2 +- elliptic-curve/src/weierstrass/public_key.rs | 19 +++++++++++++++++++ 4 files changed, 35 insertions(+), 4 deletions(-) diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 141bff378..dbb6292e9 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -30,7 +30,10 @@ pub mod secret_key; #[cfg_attr(docsrs, doc(cfg(feature = "weierstrass")))] pub mod weierstrass; -pub use self::{error::Error, secret_key::SecretKey}; +pub use self::{ + error::Error, + secret_key::{FromSecretKey, SecretKey}, +}; pub use generic_array::{self, typenum::consts}; pub use subtle; @@ -62,13 +65,13 @@ pub trait Curve: Clone + Debug + Default + Eq + Ord + Send + Sync { /// Elliptic curve with curve arithmetic support pub trait Arithmetic: Curve { /// Scalar type for a given curve - type Scalar; + type Scalar: FromSecretKey; /// Affine point type for a given curve type AffinePoint; } -/// Trait for randomly generating a value. +/// Randomly generate a value. /// /// Primarily intended for use with scalar types for a particular curve. #[cfg(feature = "rand_core")] diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 31de82fd9..d431cf2f0 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -13,6 +13,7 @@ use core::{ fmt::{self, Debug}, }; use generic_array::{typenum::Unsigned, GenericArray}; +use subtle::CtOption; #[cfg(feature = "rand_core")] use { @@ -89,3 +90,11 @@ impl Drop for SecretKey { self.scalar.zeroize(); } } + +/// Trait for deserializing a value from a secret key. +/// +/// This is intended for use with the `Scalar` type for a given elliptic curve. +pub trait FromSecretKey: Sized { + /// Deserialize this value from a [`SecretKey`] + fn from_secret_key(secret_key: &SecretKey) -> CtOption; +} diff --git a/elliptic-curve/src/weierstrass.rs b/elliptic-curve/src/weierstrass.rs index 362ea1704..424f28fbb 100644 --- a/elliptic-curve/src/weierstrass.rs +++ b/elliptic-curve/src/weierstrass.rs @@ -5,7 +5,7 @@ pub mod public_key; pub use self::{ point::{CompressedPoint, CompressedPointSize, UncompressedPoint, UncompressedPointSize}, - public_key::PublicKey, + public_key::{FromPublicKey, PublicKey}, }; use crate::{Arithmetic, ScalarBytes}; diff --git a/elliptic-curve/src/weierstrass/public_key.rs b/elliptic-curve/src/weierstrass/public_key.rs index dde6000d1..3aaaa520d 100644 --- a/elliptic-curve/src/weierstrass/public_key.rs +++ b/elliptic-curve/src/weierstrass/public_key.rs @@ -12,6 +12,7 @@ use generic_array::{ typenum::{Unsigned, U1}, ArrayLength, GenericArray, }; +use subtle::CtOption; /// Size of an untagged point for given elliptic curve. pub type UntaggedPointSize = <::ElementSize as Add>::Output; @@ -192,3 +193,21 @@ where PublicKey::Uncompressed(point) } } + +/// Trait for deserializing a value from a public key. +/// +/// This is intended for use with the `AffinePoint` type for a given elliptic curve. +pub trait FromPublicKey: Sized +where + C::ElementSize: Add, + ::Output: Add, + CompressedPointSize: ArrayLength, + UncompressedPointSize: ArrayLength, +{ + /// Deserialize this value from a [`PublicKey`] + /// + /// # Returns + /// + /// `None` if the public key is not on the curve. + fn from_public_key(public_key: &PublicKey) -> CtOption; +} From 129205462a5f04d3e3b6f2e4592b5d7a0d6448f0 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 29 Jul 2020 10:18:05 -0700 Subject: [PATCH 0175/1461] elliptic-curve: replace FixedBaseScalarMul with ops::MulBase (#230) `FixedBaseScalarMul` was a hack around the lack of an associated `Scalar` type on a curve and generic way of converting a `SecretKey` to a `Scalar`. We have both of those things, so this commit replaces it with an `ops::MulBase` trait intended to be impl'd on `Scalar` types. Further, it bounds the `Arithmetic::Scalar` associated type on this, which allows it to be used for generic `SecretKey` -> `PublicKey` conversions. It also means the `Arithmetic` trait now has a(n implicit) way of representing the generator point, making it genuinely useful for generic arithmetic operations. This would also be useful for e.g. a generic implementation of Diffie-Hellman. --- elliptic-curve/src/lib.rs | 13 +++++----- elliptic-curve/src/ops.rs | 9 +++++++ elliptic-curve/src/weierstrass.rs | 11 --------- elliptic-curve/src/weierstrass/public_key.rs | 26 ++++++++++---------- 4 files changed, 29 insertions(+), 30 deletions(-) diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index dbb6292e9..31ee72515 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -30,10 +30,7 @@ pub mod secret_key; #[cfg_attr(docsrs, doc(cfg(feature = "weierstrass")))] pub mod weierstrass; -pub use self::{ - error::Error, - secret_key::{FromSecretKey, SecretKey}, -}; +pub use self::{error::Error, secret_key::SecretKey}; pub use generic_array::{self, typenum::consts}; pub use subtle; @@ -42,6 +39,7 @@ pub use rand_core; use core::{fmt::Debug, ops::Add}; use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; +use subtle::ConditionallySelectable; #[cfg(feature = "rand_core")] use rand_core::{CryptoRng, RngCore}; @@ -65,10 +63,13 @@ pub trait Curve: Clone + Debug + Default + Eq + Ord + Send + Sync { /// Elliptic curve with curve arithmetic support pub trait Arithmetic: Curve { /// Scalar type for a given curve - type Scalar: FromSecretKey; + type Scalar: ConditionallySelectable + + Default + + secret_key::FromSecretKey + + ops::MulBase; /// Affine point type for a given curve - type AffinePoint; + type AffinePoint: ConditionallySelectable; } /// Randomly generate a value. diff --git a/elliptic-curve/src/ops.rs b/elliptic-curve/src/ops.rs index 09f811d7e..4d8f09523 100644 --- a/elliptic-curve/src/ops.rs +++ b/elliptic-curve/src/ops.rs @@ -10,3 +10,12 @@ pub trait Invert { /// Invert a field element. fn invert(&self) -> CtOption; } + +/// Fixed-base scalar multiplication +pub trait MulBase { + /// Affine point type + type Output; + + /// Multiply this value by the generator point for the elliptic curve + fn mul_base(&self) -> CtOption; +} diff --git a/elliptic-curve/src/weierstrass.rs b/elliptic-curve/src/weierstrass.rs index 424f28fbb..d98cc3791 100644 --- a/elliptic-curve/src/weierstrass.rs +++ b/elliptic-curve/src/weierstrass.rs @@ -8,16 +8,5 @@ pub use self::{ public_key::{FromPublicKey, PublicKey}, }; -use crate::{Arithmetic, ScalarBytes}; -use subtle::CtOption; - /// Marker trait for elliptic curves in short Weierstrass form pub trait Curve: super::Curve {} - -/// Fixed-base scalar multiplication -pub trait FixedBaseScalarMul: Curve + Arithmetic { - /// Multiply the given scalar by the generator point for this elliptic - /// curve. - // TODO(tarcieri): use `Self::Scalar` for the `scalar` param - fn mul_base(scalar: &ScalarBytes) -> CtOption; -} diff --git a/elliptic-curve/src/weierstrass/public_key.rs b/elliptic-curve/src/weierstrass/public_key.rs index 3aaaa520d..b369e8f2d 100644 --- a/elliptic-curve/src/weierstrass/public_key.rs +++ b/elliptic-curve/src/weierstrass/public_key.rs @@ -3,9 +3,9 @@ use super::{ point::{CompressedPoint, CompressedPointSize, UncompressedPoint, UncompressedPointSize}, - Curve, FixedBaseScalarMul, + Curve, }; -use crate::{Error, SecretKey}; +use crate::{ops::MulBase, secret_key::FromSecretKey, Arithmetic, Error, SecretKey}; use core::fmt::{self, Debug}; use core::ops::Add; use generic_array::{ @@ -104,9 +104,9 @@ where } } -impl PublicKey +impl PublicKey where - C: FixedBaseScalarMul, + C: Curve + Arithmetic, C::ElementSize: Add, ::Output: Add, CompressedPoint: From, @@ -118,18 +118,18 @@ where /// /// The `compress` flag requests point compression. pub fn from_secret_key(secret_key: &SecretKey, compress: bool) -> Result { - let ct_option = C::mul_base(secret_key.secret_scalar()); + let ct_option = C::Scalar::from_secret_key(&secret_key).and_then(|s| s.mul_base()); + + if ct_option.is_none().into() { + return Err(Error); + } - if ct_option.is_some().into() { - let affine_point = ct_option.unwrap(); + let affine_point = ct_option.unwrap(); - if compress { - Ok(PublicKey::Compressed(affine_point.into())) - } else { - Ok(PublicKey::Uncompressed(affine_point.into())) - } + if compress { + Ok(PublicKey::Compressed(affine_point.into())) } else { - Err(Error) + Ok(PublicKey::Uncompressed(affine_point.into())) } } } From 0aea71b0211a99d6d6367445da3c3910957591c3 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 29 Jul 2020 11:27:22 -0700 Subject: [PATCH 0176/1461] signature: remove RNG generic parameter from RandomizedSigner (#231) ...replacing it with `impl CryptoRng + RngCore` parameter. This is a SemVer breaking change, however per our policy around `*-preview` features, it will receive a minor version bump as these features are not part of the SemVer guarantees of this crate. The rationale for this change is the exact RNG method doesn't matter, especially to the point it needs to be a generic parameter of the trait signature. --- signature/src/signer.rs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/signature/src/signer.rs b/signature/src/signer.rs index a2fa588b8..9ecde4029 100644 --- a/signature/src/signer.rs +++ b/signature/src/signer.rs @@ -66,13 +66,9 @@ where /// Sign the given message using the provided external randomness source. #[cfg(feature = "rand-preview")] #[cfg_attr(docsrs, doc(cfg(feature = "rand-preview")))] -pub trait RandomizedSigner -where - R: CryptoRng + RngCore, - S: Signature, -{ +pub trait RandomizedSigner { /// Sign the given message and return a digital signature - fn sign_with_rng(&self, rng: &mut R, msg: &[u8]) -> S { + fn sign_with_rng(&self, rng: impl CryptoRng + RngCore, msg: &[u8]) -> S { self.try_sign_with_rng(rng, msg) .expect("signature operation failed") } @@ -82,5 +78,5 @@ where /// /// The main intended use case for signing errors is when communicating /// with external signers, e.g. cloud KMS, HSMs, or other hardware tokens. - fn try_sign_with_rng(&self, rng: &mut R, msg: &[u8]) -> Result; + fn try_sign_with_rng(&self, rng: impl CryptoRng + RngCore, msg: &[u8]) -> Result; } From 564534aa98100fe9fe04b79baa42733e23a603ee Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 29 Jul 2020 11:35:38 -0700 Subject: [PATCH 0177/1461] signature v1.2.0 (#232) --- Cargo.lock | 2 +- signature/CHANGELOG.md | 6 ++++++ signature/Cargo.toml | 2 +- signature/src/lib.rs | 4 ++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b3471b3ec..8d84cfbea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -236,7 +236,7 @@ dependencies = [ [[package]] name = "signature" -version = "1.1.0" +version = "1.2.0" dependencies = [ "digest 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal", diff --git a/signature/CHANGELOG.md b/signature/CHANGELOG.md index 0bb6c681d..a2a431787 100644 --- a/signature/CHANGELOG.md +++ b/signature/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 1.2.0 (2020-07-29) +### Removed +- RNG generic parameter `R` from `RandomizedSigner` ([#231]) + +[#231]: https://github.com/RustCrypto/traits/pull/231 + ## 1.1.0 (2020-06-09) ### Changed - Upgrade `digest` to v0.9; MSRV 1.41+ ([#186]) diff --git a/signature/Cargo.toml b/signature/Cargo.toml index f6eefd08e..3f24395a0 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "1.1.0" # Also update html_root_url in lib.rs when bumping this +version = "1.2.0" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/signature" diff --git a/signature/src/lib.rs b/signature/src/lib.rs index e3a07f037..81e6af917 100644 --- a/signature/src/lib.rs +++ b/signature/src/lib.rs @@ -5,7 +5,7 @@ //! //! ## Minimum Supported Rust Version //! -//! Rust **1.36** or higher. +//! Rust **1.41** or higher. //! //! Minimum supported Rust version may be changed in the future, but such //! changes will be accompanied with a minor version bump. @@ -155,7 +155,7 @@ #![cfg_attr(docsrs, feature(doc_cfg))] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/ferris_signer.png", - html_root_url = "https://docs.rs/signature/1.1.0" + html_root_url = "https://docs.rs/signature/1.2.0" )] #![forbid(unsafe_code)] #![warn( From 409550d3130c6747b87ce7ff9aba470e4b42bc66 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 29 Jul 2020 11:43:27 -0700 Subject: [PATCH 0178/1461] elliptic-curve: re-export `zeroize` (#233) Useful for conditionally zeroizing long-lived secret `Scalar` values --- elliptic-curve/src/lib.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 31ee72515..db4020af3 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -37,6 +37,9 @@ pub use subtle; #[cfg(feature = "rand_core")] pub use rand_core; +#[cfg(feature = "zeroize")] +pub use zeroize; + use core::{fmt::Debug, ops::Add}; use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; use subtle::ConditionallySelectable; From cb1fdb7ca135d02f9cadf819e036e95d024248f2 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 29 Jul 2020 12:30:05 -0700 Subject: [PATCH 0179/1461] signature v1.2.1 (#234) --- Cargo.lock | 2 +- signature/CHANGELOG.md | 5 ++++- signature/Cargo.toml | 2 +- signature/src/lib.rs | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8d84cfbea..4b5502ed1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -236,7 +236,7 @@ dependencies = [ [[package]] name = "signature" -version = "1.2.0" +version = "1.2.1" dependencies = [ "digest 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal", diff --git a/signature/CHANGELOG.md b/signature/CHANGELOG.md index a2a431787..77c42df7b 100644 --- a/signature/CHANGELOG.md +++ b/signature/CHANGELOG.md @@ -4,12 +4,15 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 1.2.0 (2020-07-29) +## 1.2.1 (2020-07-29) ### Removed - RNG generic parameter `R` from `RandomizedSigner` ([#231]) [#231]: https://github.com/RustCrypto/traits/pull/231 +## 1.2.0 (2020-07-29) [YANKED] +- Note: this release was published without the intended changes + ## 1.1.0 (2020-06-09) ### Changed - Upgrade `digest` to v0.9; MSRV 1.41+ ([#186]) diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 3f24395a0..7137785e5 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "1.2.0" # Also update html_root_url in lib.rs when bumping this +version = "1.2.1" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/signature" diff --git a/signature/src/lib.rs b/signature/src/lib.rs index 81e6af917..f6fb4c85b 100644 --- a/signature/src/lib.rs +++ b/signature/src/lib.rs @@ -155,7 +155,7 @@ #![cfg_attr(docsrs, feature(doc_cfg))] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/ferris_signer.png", - html_root_url = "https://docs.rs/signature/1.2.0" + html_root_url = "https://docs.rs/signature/1.2.1" )] #![forbid(unsafe_code)] #![warn( From 676f62e2002bd7035b3a6270da298690d7ae0e1e Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 29 Jul 2020 12:46:19 -0700 Subject: [PATCH 0180/1461] signature: add RandomizedDigestSigner (#235) Combination of `DigestSigner` and `RandomizedSigner` which computes a signature over a message digest while incorporating additional entropy. --- signature/src/signer.rs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/signature/src/signer.rs b/signature/src/signer.rs index 9ecde4029..24054e0e1 100644 --- a/signature/src/signer.rs +++ b/signature/src/signer.rs @@ -80,3 +80,30 @@ pub trait RandomizedSigner { /// with external signers, e.g. cloud KMS, HSMs, or other hardware tokens. fn try_sign_with_rng(&self, rng: impl CryptoRng + RngCore, msg: &[u8]) -> Result; } + +/// Combination of [`DigestSigner`] and [`RandomizedSigner`] with support for +/// computing a signature over a digest which requires entropy from an RNG. +#[cfg(all(feature = "digest-preview", feature = "rand-preview"))] +#[cfg_attr(docsrs, doc(cfg(feature = "digest-preview")))] +#[cfg_attr(docsrs, doc(cfg(feature = "rand-preview")))] +pub trait RandomizedDigestSigner +where + D: Digest, + S: Signature, +{ + /// Sign the given prehashed message `Digest`, returning a signature. + /// + /// Panics in the event of a signing error. + fn sign_digest_with_rng(&self, rng: impl CryptoRng + RngCore, digest: D) -> S { + self.try_sign_digest_with_rng(rng, digest) + .expect("signature operation failed") + } + + /// Attempt to sign the given prehashed message `Digest`, returning a + /// digital signature on success, or an error if something went wrong. + fn try_sign_digest_with_rng( + &self, + rng: impl CryptoRng + RngCore, + digest: D, + ) -> Result; +} From 06f105843d8f90d0bb0301762f79b73519acbc3c Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 29 Jul 2020 12:54:18 -0700 Subject: [PATCH 0181/1461] signature v1.2.2 (#236) --- Cargo.lock | 2 +- signature/CHANGELOG.md | 6 ++++++ signature/Cargo.toml | 2 +- signature/src/lib.rs | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4b5502ed1..4d86f3c44 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -236,7 +236,7 @@ dependencies = [ [[package]] name = "signature" -version = "1.2.1" +version = "1.2.2" dependencies = [ "digest 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal", diff --git a/signature/CHANGELOG.md b/signature/CHANGELOG.md index 77c42df7b..9bce8732f 100644 --- a/signature/CHANGELOG.md +++ b/signature/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 1.2.2 (2020-07-29) +### Added +- `RandomizedDigestSigner` ([#235]) + +[#235]: https://github.com/RustCrypto/traits/pull/235 + ## 1.2.1 (2020-07-29) ### Removed - RNG generic parameter `R` from `RandomizedSigner` ([#231]) diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 7137785e5..d365473ee 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "1.2.1" # Also update html_root_url in lib.rs when bumping this +version = "1.2.2" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/signature" diff --git a/signature/src/lib.rs b/signature/src/lib.rs index f6fb4c85b..de3293406 100644 --- a/signature/src/lib.rs +++ b/signature/src/lib.rs @@ -155,7 +155,7 @@ #![cfg_attr(docsrs, feature(doc_cfg))] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/ferris_signer.png", - html_root_url = "https://docs.rs/signature/1.2.1" + html_root_url = "https://docs.rs/signature/1.2.2" )] #![forbid(unsafe_code)] #![warn( From 2eb31349c6bef08f910a84caa8678f8aa12b13c5 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 30 Jul 2020 17:44:31 -0700 Subject: [PATCH 0182/1461] elliptic-curve: change MulBase trait to be impl'd on point types (#239) This makes the MulBase trait a static method for point types, which takes an associated scalar type as an associated parameter. This allows multiple impls on both AffinePoint and ProjectivePoint. --- elliptic-curve/src/lib.rs | 7 ++----- elliptic-curve/src/ops.rs | 14 ++++++++------ elliptic-curve/src/weierstrass/public_key.rs | 3 ++- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index db4020af3..3528d22e0 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -66,13 +66,10 @@ pub trait Curve: Clone + Debug + Default + Eq + Ord + Send + Sync { /// Elliptic curve with curve arithmetic support pub trait Arithmetic: Curve { /// Scalar type for a given curve - type Scalar: ConditionallySelectable - + Default - + secret_key::FromSecretKey - + ops::MulBase; + type Scalar: ConditionallySelectable + Default + secret_key::FromSecretKey; /// Affine point type for a given curve - type AffinePoint: ConditionallySelectable; + type AffinePoint: ConditionallySelectable + ops::MulBase; } /// Randomly generate a value. diff --git a/elliptic-curve/src/ops.rs b/elliptic-curve/src/ops.rs index 4d8f09523..6e763c544 100644 --- a/elliptic-curve/src/ops.rs +++ b/elliptic-curve/src/ops.rs @@ -11,11 +11,13 @@ pub trait Invert { fn invert(&self) -> CtOption; } -/// Fixed-base scalar multiplication -pub trait MulBase { - /// Affine point type - type Output; +/// Fixed-base scalar multiplication. +/// +/// This trait is intended to be implemented on a point type. +pub trait MulBase: Sized { + /// Scalar type + type Scalar; - /// Multiply this value by the generator point for the elliptic curve - fn mul_base(&self) -> CtOption; + /// Multiply scalar by the generator point for the elliptic curve + fn mul_base(scalar: &Self::Scalar) -> CtOption; } diff --git a/elliptic-curve/src/weierstrass/public_key.rs b/elliptic-curve/src/weierstrass/public_key.rs index b369e8f2d..1092912ef 100644 --- a/elliptic-curve/src/weierstrass/public_key.rs +++ b/elliptic-curve/src/weierstrass/public_key.rs @@ -118,7 +118,8 @@ where /// /// The `compress` flag requests point compression. pub fn from_secret_key(secret_key: &SecretKey, compress: bool) -> Result { - let ct_option = C::Scalar::from_secret_key(&secret_key).and_then(|s| s.mul_base()); + let ct_option = + C::Scalar::from_secret_key(&secret_key).and_then(|s| C::AffinePoint::mul_base(&s)); if ct_option.is_none().into() { return Err(Error); From a65edce5d5ee2f5daec882d68fe00f860674f542 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 30 Jul 2020 19:30:35 -0700 Subject: [PATCH 0183/1461] elliptic-curve: basic OID support (#240) Adds a (very simple, const-and-no_std-friendly) `ObjectIdentifier` type and an `Identifier` trait for attaching an OID to a curve. No validation of the nodes is presently performed (and since it's impl'd as a `const fn`, it'd require a MSRV bump to do so). Also requires the OID be specified as an array literal: no parsing is supported for either string or binary-encoded OIDs. Only string serialization is supported for now. A `no_std`-friendly binary serializer will be somewhat tricky. --- elliptic-curve/src/lib.rs | 9 +++++++- elliptic-curve/src/oid.rs | 48 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 elliptic-curve/src/oid.rs diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 3528d22e0..c5cf968db 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -22,6 +22,7 @@ extern crate std; pub mod error; +pub mod oid; pub mod ops; pub mod secret_key; @@ -30,7 +31,7 @@ pub mod secret_key; #[cfg_attr(docsrs, doc(cfg(feature = "weierstrass")))] pub mod weierstrass; -pub use self::{error::Error, secret_key::SecretKey}; +pub use self::{error::Error, oid::ObjectIdentifier, secret_key::SecretKey}; pub use generic_array::{self, typenum::consts}; pub use subtle; @@ -72,6 +73,12 @@ pub trait Arithmetic: Curve { type AffinePoint: ConditionallySelectable + ops::MulBase; } +/// Associate an object identifier (OID) with a curve +pub trait Identifier: Curve { + /// Object Identifier (OID) for this curve + const OID: ObjectIdentifier; +} + /// Randomly generate a value. /// /// Primarily intended for use with scalar types for a particular curve. diff --git a/elliptic-curve/src/oid.rs b/elliptic-curve/src/oid.rs new file mode 100644 index 000000000..b5494176f --- /dev/null +++ b/elliptic-curve/src/oid.rs @@ -0,0 +1,48 @@ +//! Object identifiers (OIDs) + +use core::fmt; + +/// Object identifier (OID) +pub struct ObjectIdentifier(&'static [u32]); + +impl ObjectIdentifier { + /// Create a new OID + pub const fn new(nodes: &'static [u32]) -> Self { + // TODO(tarcieri): validate nodes + Self(nodes) + } +} + +impl AsRef<[u32]> for ObjectIdentifier { + fn as_ref(&self) -> &[u32] { + self.0 + } +} + +impl fmt::Display for ObjectIdentifier { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + for (i, node) in self.0.iter().enumerate() { + write!(f, "{}", node)?; + + if i < self.0.len() - 1 { + write!(f, ".")?; + } + } + + Ok(()) + } +} + +#[cfg(all(test, std))] +mod tests { + use super::ObjectIdentifier; + use std::string::ToString; + + const EXAMPLE_OID: ObjectIdentifier = ObjectIdentifier::new(&[1, 2, 840, 10045, 3, 1, 7]); + + #[test] + fn display_test() { + let oid = EXAMPLE_OID.to_string(); + assert_eq!(oid, "1.2.840.10045.3.1.7"); + } +} From efefde4b5088af69407f80c88ecb4d966b9016f7 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 2 Aug 2020 11:03:05 -0700 Subject: [PATCH 0184/1461] elliptic-curve: NonZeroScalar + Generator (replaces MulBase) (#241) Adds a `NonZeroScalar` type generic over curves along with a `Generator` trait which together with the `Mul` trait from `core` can replace the `MulBase` trait. `NonZeroScalar` is able to use the bounds on `Arithmetic::Scalar` and therefore usable anywhere a `Scalar` otherwise would, but with the guarantee that multiplication by an `AffinePoint` will not result in the point at infinity, for which no `AffinePoint` representation is possible given current trait bounds/implementations. --- elliptic-curve/src/lib.rs | 16 ++++-- elliptic-curve/src/ops.rs | 11 ----- elliptic-curve/src/point.rs | 7 +++ elliptic-curve/src/scalar.rs | 51 ++++++++++++++++++++ elliptic-curve/src/weierstrass/public_key.rs | 17 ++++--- 5 files changed, 81 insertions(+), 21 deletions(-) create mode 100644 elliptic-curve/src/point.rs create mode 100644 elliptic-curve/src/scalar.rs diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index c5cf968db..c829740fd 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -24,6 +24,8 @@ extern crate std; pub mod error; pub mod oid; pub mod ops; +pub mod point; +pub mod scalar; pub mod secret_key; // TODO(tarcieri): other curve forms @@ -41,9 +43,12 @@ pub use rand_core; #[cfg(feature = "zeroize")] pub use zeroize; -use core::{fmt::Debug, ops::Add}; +use core::{ + fmt::Debug, + ops::{Add, Mul}, +}; use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; -use subtle::ConditionallySelectable; +use subtle::{ConditionallySelectable, ConstantTimeEq}; #[cfg(feature = "rand_core")] use rand_core::{CryptoRng, RngCore}; @@ -67,10 +72,13 @@ pub trait Curve: Clone + Debug + Default + Eq + Ord + Send + Sync { /// Elliptic curve with curve arithmetic support pub trait Arithmetic: Curve { /// Scalar type for a given curve - type Scalar: ConditionallySelectable + Default + secret_key::FromSecretKey; + type Scalar: ConditionallySelectable + + ConstantTimeEq + + Default + + secret_key::FromSecretKey; /// Affine point type for a given curve - type AffinePoint: ConditionallySelectable + ops::MulBase; + type AffinePoint: ConditionallySelectable + Mul> + point::Generator; } /// Associate an object identifier (OID) with a curve diff --git a/elliptic-curve/src/ops.rs b/elliptic-curve/src/ops.rs index 6e763c544..09f811d7e 100644 --- a/elliptic-curve/src/ops.rs +++ b/elliptic-curve/src/ops.rs @@ -10,14 +10,3 @@ pub trait Invert { /// Invert a field element. fn invert(&self) -> CtOption; } - -/// Fixed-base scalar multiplication. -/// -/// This trait is intended to be implemented on a point type. -pub trait MulBase: Sized { - /// Scalar type - type Scalar; - - /// Multiply scalar by the generator point for the elliptic curve - fn mul_base(scalar: &Self::Scalar) -> CtOption; -} diff --git a/elliptic-curve/src/point.rs b/elliptic-curve/src/point.rs new file mode 100644 index 000000000..67a810a93 --- /dev/null +++ b/elliptic-curve/src/point.rs @@ -0,0 +1,7 @@ +//! Traits for elliptic curve points + +/// Obtain the generator point. +pub trait Generator { + /// Get the generator point for this elliptic curve + fn generator() -> Self; +} diff --git a/elliptic-curve/src/scalar.rs b/elliptic-curve/src/scalar.rs new file mode 100644 index 000000000..0237e8cf3 --- /dev/null +++ b/elliptic-curve/src/scalar.rs @@ -0,0 +1,51 @@ +//! Scalar types + +use crate::{Arithmetic, Curve}; +use subtle::{ConstantTimeEq, CtOption}; + +#[cfg(feature = "zeroize")] +use zeroize::Zeroize; + +/// Non-zero scalar type. +/// +/// This type ensures that its value is not zero, ala `core::num::NonZero*`. +/// To do this, the generic `S` type must impl both `Default` and +/// `ConstantTimeEq`, with the requirement that `S::default()` returns 0. +/// +/// In the context of ECC, it's useful for ensuring that scalar multiplication +/// cannot result in the point at infinity. +pub struct NonZeroScalar { + scalar: C::Scalar, +} + +impl NonZeroScalar +where + C: Curve + Arithmetic, +{ + /// Create a [`NonZeroScalar`] from a scalar, performing a constant-time + /// check that it's non-zero. + pub fn new(scalar: C::Scalar) -> CtOption { + let is_zero = scalar.ct_eq(&C::Scalar::default()); + CtOption::new(Self { scalar }, !is_zero) + } +} + +impl AsRef for NonZeroScalar +where + C: Curve + Arithmetic, +{ + fn as_ref(&self) -> &C::Scalar { + &self.scalar + } +} + +#[cfg(feature = "zeroize")] +impl Zeroize for NonZeroScalar +where + C: Curve + Arithmetic, + C::Scalar: Zeroize, +{ + fn zeroize(&mut self) { + self.scalar.zeroize(); + } +} diff --git a/elliptic-curve/src/weierstrass/public_key.rs b/elliptic-curve/src/weierstrass/public_key.rs index 1092912ef..796a0b866 100644 --- a/elliptic-curve/src/weierstrass/public_key.rs +++ b/elliptic-curve/src/weierstrass/public_key.rs @@ -5,9 +5,14 @@ use super::{ point::{CompressedPoint, CompressedPointSize, UncompressedPoint, UncompressedPointSize}, Curve, }; -use crate::{ops::MulBase, secret_key::FromSecretKey, Arithmetic, Error, SecretKey}; -use core::fmt::{self, Debug}; -use core::ops::Add; +use crate::{ + point::Generator, scalar::NonZeroScalar, secret_key::FromSecretKey, Arithmetic, Error, + SecretKey, +}; +use core::{ + fmt::{self, Debug}, + ops::{Add, Mul}, +}; use generic_array::{ typenum::{Unsigned, U1}, ArrayLength, GenericArray, @@ -107,6 +112,7 @@ where impl PublicKey where C: Curve + Arithmetic, + C::AffinePoint: Mul, Output = C::AffinePoint>, C::ElementSize: Add, ::Output: Add, CompressedPoint: From, @@ -118,14 +124,13 @@ where /// /// The `compress` flag requests point compression. pub fn from_secret_key(secret_key: &SecretKey, compress: bool) -> Result { - let ct_option = - C::Scalar::from_secret_key(&secret_key).and_then(|s| C::AffinePoint::mul_base(&s)); + let ct_option = C::Scalar::from_secret_key(&secret_key).and_then(NonZeroScalar::new); if ct_option.is_none().into() { return Err(Error); } - let affine_point = ct_option.unwrap(); + let affine_point = C::AffinePoint::generator() * ct_option.unwrap(); if compress { Ok(PublicKey::Compressed(affine_point.into())) From 920522ae53f03483a27b24bc8e924db9e8aff29c Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 3 Aug 2020 15:53:06 -0700 Subject: [PATCH 0185/1461] elliptic-curve: add weierstrass::PublicKey::compress (#243) Generic point compression support for SEC-1 encoded public keys --- elliptic-curve/src/weierstrass/point.rs | 10 ++++++++++ elliptic-curve/src/weierstrass/public_key.rs | 9 +++++++++ 2 files changed, 19 insertions(+) diff --git a/elliptic-curve/src/weierstrass/point.rs b/elliptic-curve/src/weierstrass/point.rs index 735ceb711..e0d6c30a0 100644 --- a/elliptic-curve/src/weierstrass/point.rs +++ b/elliptic-curve/src/weierstrass/point.rs @@ -171,6 +171,16 @@ where pub fn into_bytes(self) -> GenericArray> { self.bytes } + + /// Get the x-coordinate of this curve point + pub(crate) fn x(&self) -> &ScalarBytes { + GenericArray::from_slice(&self.bytes[1..(C::ElementSize::to_usize() + 1)]) + } + + /// Get the y-coordinate of this curve point + pub(crate) fn y(&self) -> &ScalarBytes { + GenericArray::from_slice(&self.bytes[(C::ElementSize::to_usize() + 1)..]) + } } impl AsRef<[u8]> for UncompressedPoint diff --git a/elliptic-curve/src/weierstrass/public_key.rs b/elliptic-curve/src/weierstrass/public_key.rs index 796a0b866..ef01f02b9 100644 --- a/elliptic-curve/src/weierstrass/public_key.rs +++ b/elliptic-curve/src/weierstrass/public_key.rs @@ -99,6 +99,15 @@ where PublicKey::Uncompressed(UncompressedPoint::from_bytes(tagged_bytes).unwrap()) } + /// Compress this [`PublicKey`]. + /// + /// If the key is already compressed, this is a no-op. + pub fn compress(&mut self) { + if let PublicKey::Uncompressed(point) = self { + *self = CompressedPoint::from_affine_coords(point.x(), point.y()).into(); + } + } + /// Obtain public key as a byte array reference #[inline] pub fn as_bytes(&self) -> &[u8] { From 83c41ca3a5e19a5d8d776ac7f74123de8373e2e8 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 3 Aug 2020 20:40:53 -0700 Subject: [PATCH 0186/1461] elliptic-curve: derive Clone on SecretKey (#244) SecretKey is auto-zeroizing. While cloning it isn't ideal, we have a strategy for automatically cleaning up afterward. --- elliptic-curve/src/secret_key.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index d431cf2f0..cb613d884 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -26,6 +26,7 @@ use { /// This type wraps a serialized scalar value, helping to prevent accidental /// exposure and securely erasing the value from memory when dropped /// (when the `zeroize` feature of this crate is enabled). +#[derive(Clone)] pub struct SecretKey { /// Private scalar value scalar: ScalarBytes, From 72f1909a39571b0fe57f2751c1393680f364ee32 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 4 Aug 2020 09:19:34 -0700 Subject: [PATCH 0187/1461] elliptic-curve: use `const-oid` crate (#245) The previous implementation has been extracted into that crate. --- Cargo.lock | 7 ++++++ elliptic-curve/Cargo.toml | 23 +++++-------------- elliptic-curve/src/lib.rs | 10 +++++--- elliptic-curve/src/oid.rs | 48 --------------------------------------- 4 files changed, 20 insertions(+), 68 deletions(-) delete mode 100644 elliptic-curve/src/oid.rs diff --git a/Cargo.lock b/Cargo.lock index 4d86f3c44..3660857f1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -61,6 +61,12 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +[[package]] +name = "const-oid" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2d9162b7289a46e86208d6af2c686ca5bfde445878c41a458a9fac706252d0b" + [[package]] name = "cpuid-bool" version = "0.1.0" @@ -111,6 +117,7 @@ dependencies = [ name = "elliptic-curve" version = "0.5.0-pre" dependencies = [ + "const-oid", "generic-array 0.14.3", "rand_core", "subtle", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index ecc7a7274..c6a4f8f47 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -15,23 +15,12 @@ edition = "2018" categories = ["cryptography", "no-std"] keywords = ["crypto", "ecc", "elliptic", "weierstrass"] -[dependencies.generic-array] -version = "0.14" -default-features = false - -[dependencies.rand_core] -version = "0.5" -optional = true -default-features = false - -[dependencies.subtle] -version = "2.2.2" -default-features = false - -[dependencies.zeroize] -version = "1" -optional = true -default-features = false +[dependencies] +generic-array = { version = "0.14", default-features = false } +oid = { package = "const-oid", version = "0.1", optional = true } +rand_core = { version = "0.5", optional = true, default-features = false } +subtle = { version = "2.2.2", default-features = false } +zeroize = { version = "1", optional = true, default-features = false } [features] default = [] diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index c829740fd..8535f6e9a 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -22,7 +22,6 @@ extern crate std; pub mod error; -pub mod oid; pub mod ops; pub mod point; pub mod scalar; @@ -33,10 +32,13 @@ pub mod secret_key; #[cfg_attr(docsrs, doc(cfg(feature = "weierstrass")))] pub mod weierstrass; -pub use self::{error::Error, oid::ObjectIdentifier, secret_key::SecretKey}; +pub use self::{error::Error, secret_key::SecretKey}; pub use generic_array::{self, typenum::consts}; pub use subtle; +#[cfg(feature = "oid")] +pub use oid; + #[cfg(feature = "rand_core")] pub use rand_core; @@ -82,9 +84,11 @@ pub trait Arithmetic: Curve { } /// Associate an object identifier (OID) with a curve +#[cfg(feature = "oid")] +#[cfg_attr(docsrs, doc(cfg(feature = "oid")))] pub trait Identifier: Curve { /// Object Identifier (OID) for this curve - const OID: ObjectIdentifier; + const OID: oid::ObjectIdentifier; } /// Randomly generate a value. diff --git a/elliptic-curve/src/oid.rs b/elliptic-curve/src/oid.rs deleted file mode 100644 index b5494176f..000000000 --- a/elliptic-curve/src/oid.rs +++ /dev/null @@ -1,48 +0,0 @@ -//! Object identifiers (OIDs) - -use core::fmt; - -/// Object identifier (OID) -pub struct ObjectIdentifier(&'static [u32]); - -impl ObjectIdentifier { - /// Create a new OID - pub const fn new(nodes: &'static [u32]) -> Self { - // TODO(tarcieri): validate nodes - Self(nodes) - } -} - -impl AsRef<[u32]> for ObjectIdentifier { - fn as_ref(&self) -> &[u32] { - self.0 - } -} - -impl fmt::Display for ObjectIdentifier { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - for (i, node) in self.0.iter().enumerate() { - write!(f, "{}", node)?; - - if i < self.0.len() - 1 { - write!(f, ".")?; - } - } - - Ok(()) - } -} - -#[cfg(all(test, std))] -mod tests { - use super::ObjectIdentifier; - use std::string::ToString; - - const EXAMPLE_OID: ObjectIdentifier = ObjectIdentifier::new(&[1, 2, 840, 10045, 3, 1, 7]); - - #[test] - fn display_test() { - let oid = EXAMPLE_OID.to_string(); - assert_eq!(oid, "1.2.840.10045.3.1.7"); - } -} From 1dd4bc5ebc1f7c16e4a76fa6264b796579b4685e Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 4 Aug 2020 12:56:44 -0700 Subject: [PATCH 0188/1461] elliptic-curve: rename `ScalarBytes` => `ElementBytes` (#246) This type alias is being used for things that aren't elements of the scalar field, like serialized affine coordinates. This commit renames it into something more general which applies to these cases. It's also more consistent with the `Curve::ElementSize` associated type name. --- elliptic-curve/src/lib.rs | 2 +- elliptic-curve/src/secret_key.rs | 18 +++++++++--------- elliptic-curve/src/weierstrass/point.rs | 10 +++++----- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 8535f6e9a..f8ce3feb2 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -102,4 +102,4 @@ pub trait Generate { } /// Byte array containing a serialized scalar value (i.e. an integer) -pub type ScalarBytes = GenericArray::ElementSize>; +pub type ElementBytes = GenericArray::ElementSize>; diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index cb613d884..7adbf8d26 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -1,13 +1,13 @@ //! Secret keys for elliptic curves (i.e. private scalars) //! -//! The [`SecretKey`] type wraps the [`ScalarBytes`] byte array type with -//! a wrapper designed to prevent unintentional exposure of the scalar -//! value (e.g. via `Debug` or other logging). +//! The [`SecretKey`] type is a wrapper around a secret scalar value which is +//! designed to prevent unintentional exposure (e.g. via `Debug` or other +//! logging). //! //! When the `zeroize` feature of this crate is enabled, it also handles //! zeroing it out of memory securely on drop. -use crate::{error::Error, Curve, ScalarBytes}; +use crate::{error::Error, Curve, ElementBytes}; use core::{ convert::{TryFrom, TryInto}, fmt::{self, Debug}, @@ -29,12 +29,12 @@ use { #[derive(Clone)] pub struct SecretKey { /// Private scalar value - scalar: ScalarBytes, + scalar: ElementBytes, } impl SecretKey { /// Create a new secret key from a serialized scalar value - pub fn new(bytes: ScalarBytes) -> Self { + pub fn new(bytes: ElementBytes) -> Self { Self { scalar: bytes } } @@ -43,8 +43,8 @@ impl SecretKey { bytes.as_ref().try_into() } - /// Expose the secret [`ScalarBytes`] value this [`SecretKey`] wraps - pub fn secret_scalar(&self) -> &ScalarBytes { + /// Expose the byte serialization of the value this [`SecretKey`] wraps + pub fn as_bytes(&self) -> &ElementBytes { &self.scalar } } @@ -74,7 +74,7 @@ impl Debug for SecretKey { impl Generate for SecretKey where C: Curve + Arithmetic, - C::Scalar: Generate + Into>, + C::Scalar: Generate + Into>, { /// Generate a new [`SecretKey`] fn generate(rng: impl CryptoRng + RngCore) -> Self { diff --git a/elliptic-curve/src/weierstrass/point.rs b/elliptic-curve/src/weierstrass/point.rs index e0d6c30a0..050d266a3 100644 --- a/elliptic-curve/src/weierstrass/point.rs +++ b/elliptic-curve/src/weierstrass/point.rs @@ -7,7 +7,7 @@ //! use super::Curve; -use crate::ScalarBytes; +use crate::ElementBytes; use core::ops::Add; use generic_array::{ typenum::{Unsigned, U1}, @@ -47,7 +47,7 @@ where CompressedPointSize: ArrayLength, { /// Compress and serialize an elliptic curve point from its affine coordinates - pub fn from_affine_coords(x: &ScalarBytes, y: &ScalarBytes) -> Self { + pub fn from_affine_coords(x: &ElementBytes, y: &ElementBytes) -> Self { // Is the y-coordinate odd in the SEC-1 sense: `self mod 2 == 1`? let is_y_odd = y.as_ref().last().expect("last byte") & 1 == 1; let mut bytes = GenericArray::default(); @@ -137,7 +137,7 @@ where UncompressedPointSize: ArrayLength, { /// Serialize an elliptic curve point from its affine coordinates - pub fn from_affine_coords(x: &ScalarBytes, y: &ScalarBytes) -> Self { + pub fn from_affine_coords(x: &ElementBytes, y: &ElementBytes) -> Self { let scalar_size = C::ElementSize::to_usize(); let mut bytes = GenericArray::default(); bytes[0] = 0x04; @@ -173,12 +173,12 @@ where } /// Get the x-coordinate of this curve point - pub(crate) fn x(&self) -> &ScalarBytes { + pub(crate) fn x(&self) -> &ElementBytes { GenericArray::from_slice(&self.bytes[1..(C::ElementSize::to_usize() + 1)]) } /// Get the y-coordinate of this curve point - pub(crate) fn y(&self) -> &ScalarBytes { + pub(crate) fn y(&self) -> &ElementBytes { GenericArray::from_slice(&self.bytes[(C::ElementSize::to_usize() + 1)..]) } } From 4554cdc4fbecd5ef6bdb46fdd7e2012474c596e0 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 4 Aug 2020 13:55:24 -0700 Subject: [PATCH 0189/1461] elliptic-curve: add `encoding` module (#247) Replaces the previous `FromPublicKey` and `FromSecretKey` traits with a more general `FromBytes` and `ToBytes` traits. These match the function signatures presently used in the existing crates, and are useful in cases where e.g. a scalar doesn't necessarily represent a secret (such as in ECDSA). --- elliptic-curve/src/encoding.rs | 23 +++++++++++++++++++ elliptic-curve/src/lib.rs | 3 ++- elliptic-curve/src/secret_key.rs | 9 -------- elliptic-curve/src/weierstrass.rs | 2 +- elliptic-curve/src/weierstrass/public_key.rs | 24 ++------------------ 5 files changed, 28 insertions(+), 33 deletions(-) create mode 100644 elliptic-curve/src/encoding.rs diff --git a/elliptic-curve/src/encoding.rs b/elliptic-curve/src/encoding.rs new file mode 100644 index 000000000..d4f39b44e --- /dev/null +++ b/elliptic-curve/src/encoding.rs @@ -0,0 +1,23 @@ +//! Traits for decoding/encoding elliptic curve elements (i.e. base and scalar +//! field elements) as bytes. + +use generic_array::{ArrayLength, GenericArray}; +use subtle::{ConditionallySelectable, CtOption}; + +/// Try to decode the given bytes into a curve element +pub trait FromBytes: ConditionallySelectable + Sized { + /// Size of the serialized byte array + type Size: ArrayLength; + + /// Try to decode this object from bytes + fn from_bytes(bytes: &GenericArray) -> CtOption; +} + +/// Encode this curve element as bytes +pub trait ToBytes { + /// Size of the serialized byte array + type Size: ArrayLength; + + /// Encode this object to bytes + fn to_bytes(&self) -> GenericArray; +} diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index f8ce3feb2..c7aaca92f 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -21,6 +21,7 @@ #[cfg(feature = "std")] extern crate std; +pub mod encoding; pub mod error; pub mod ops; pub mod point; @@ -77,7 +78,7 @@ pub trait Arithmetic: Curve { type Scalar: ConditionallySelectable + ConstantTimeEq + Default - + secret_key::FromSecretKey; + + encoding::FromBytes; /// Affine point type for a given curve type AffinePoint: ConditionallySelectable + Mul> + point::Generator; diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 7adbf8d26..c792560f4 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -13,7 +13,6 @@ use core::{ fmt::{self, Debug}, }; use generic_array::{typenum::Unsigned, GenericArray}; -use subtle::CtOption; #[cfg(feature = "rand_core")] use { @@ -91,11 +90,3 @@ impl Drop for SecretKey { self.scalar.zeroize(); } } - -/// Trait for deserializing a value from a secret key. -/// -/// This is intended for use with the `Scalar` type for a given elliptic curve. -pub trait FromSecretKey: Sized { - /// Deserialize this value from a [`SecretKey`] - fn from_secret_key(secret_key: &SecretKey) -> CtOption; -} diff --git a/elliptic-curve/src/weierstrass.rs b/elliptic-curve/src/weierstrass.rs index d98cc3791..36d4a01d3 100644 --- a/elliptic-curve/src/weierstrass.rs +++ b/elliptic-curve/src/weierstrass.rs @@ -5,7 +5,7 @@ pub mod public_key; pub use self::{ point::{CompressedPoint, CompressedPointSize, UncompressedPoint, UncompressedPointSize}, - public_key::{FromPublicKey, PublicKey}, + public_key::PublicKey, }; /// Marker trait for elliptic curves in short Weierstrass form diff --git a/elliptic-curve/src/weierstrass/public_key.rs b/elliptic-curve/src/weierstrass/public_key.rs index ef01f02b9..ef2f5147e 100644 --- a/elliptic-curve/src/weierstrass/public_key.rs +++ b/elliptic-curve/src/weierstrass/public_key.rs @@ -6,8 +6,7 @@ use super::{ Curve, }; use crate::{ - point::Generator, scalar::NonZeroScalar, secret_key::FromSecretKey, Arithmetic, Error, - SecretKey, + encoding::FromBytes, point::Generator, scalar::NonZeroScalar, Arithmetic, Error, SecretKey, }; use core::{ fmt::{self, Debug}, @@ -17,7 +16,6 @@ use generic_array::{ typenum::{Unsigned, U1}, ArrayLength, GenericArray, }; -use subtle::CtOption; /// Size of an untagged point for given elliptic curve. pub type UntaggedPointSize = <::ElementSize as Add>::Output; @@ -133,7 +131,7 @@ where /// /// The `compress` flag requests point compression. pub fn from_secret_key(secret_key: &SecretKey, compress: bool) -> Result { - let ct_option = C::Scalar::from_secret_key(&secret_key).and_then(NonZeroScalar::new); + let ct_option = C::Scalar::from_bytes(secret_key.as_bytes()).and_then(NonZeroScalar::new); if ct_option.is_none().into() { return Err(Error); @@ -208,21 +206,3 @@ where PublicKey::Uncompressed(point) } } - -/// Trait for deserializing a value from a public key. -/// -/// This is intended for use with the `AffinePoint` type for a given elliptic curve. -pub trait FromPublicKey: Sized -where - C::ElementSize: Add, - ::Output: Add, - CompressedPointSize: ArrayLength, - UncompressedPointSize: ArrayLength, -{ - /// Deserialize this value from a [`PublicKey`] - /// - /// # Returns - /// - /// `None` if the public key is not on the curve. - fn from_public_key(public_key: &PublicKey) -> CtOption; -} From 1b3dffb7f194176a97730a72d493e5368ac69359 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 4 Aug 2020 14:16:23 -0700 Subject: [PATCH 0190/1461] elliptic-curve: add back FromPublicKey trait (#248) It seems this was a bit too hastily removed in #247. It's worth keeping around for now as it handles the variable sizes of SEC-1 keys. --- elliptic-curve/src/weierstrass/public_key.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/elliptic-curve/src/weierstrass/public_key.rs b/elliptic-curve/src/weierstrass/public_key.rs index ef2f5147e..d06f56858 100644 --- a/elliptic-curve/src/weierstrass/public_key.rs +++ b/elliptic-curve/src/weierstrass/public_key.rs @@ -16,6 +16,7 @@ use generic_array::{ typenum::{Unsigned, U1}, ArrayLength, GenericArray, }; +use subtle::CtOption; /// Size of an untagged point for given elliptic curve. pub type UntaggedPointSize = <::ElementSize as Add>::Output; @@ -206,3 +207,21 @@ where PublicKey::Uncompressed(point) } } + +/// Trait for deserializing a value from a public key. +/// +/// This is intended for use with the `AffinePoint` type for a given elliptic curve. +pub trait FromPublicKey: Sized +where + C::ElementSize: Add, + ::Output: Add, + CompressedPointSize: ArrayLength, + UncompressedPointSize: ArrayLength, +{ + /// Deserialize this value from a [`PublicKey`] + /// + /// # Returns + /// + /// `None` if the public key is not on the curve. + fn from_public_key(public_key: &PublicKey) -> CtOption; +} From 9bab4e821421e384096e86e92278ef20fb8f4621 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 4 Aug 2020 16:46:02 -0700 Subject: [PATCH 0191/1461] elliptic-curve: remove ToBytes trait (#249) We're using Into bounds for this in places right now, which suffice for existing use cases, and makes a bit redundant. --- elliptic-curve/src/encoding.rs | 23 --------------- elliptic-curve/src/lib.rs | 30 +++++++++++++------- elliptic-curve/src/weierstrass/public_key.rs | 4 +-- 3 files changed, 20 insertions(+), 37 deletions(-) delete mode 100644 elliptic-curve/src/encoding.rs diff --git a/elliptic-curve/src/encoding.rs b/elliptic-curve/src/encoding.rs deleted file mode 100644 index d4f39b44e..000000000 --- a/elliptic-curve/src/encoding.rs +++ /dev/null @@ -1,23 +0,0 @@ -//! Traits for decoding/encoding elliptic curve elements (i.e. base and scalar -//! field elements) as bytes. - -use generic_array::{ArrayLength, GenericArray}; -use subtle::{ConditionallySelectable, CtOption}; - -/// Try to decode the given bytes into a curve element -pub trait FromBytes: ConditionallySelectable + Sized { - /// Size of the serialized byte array - type Size: ArrayLength; - - /// Try to decode this object from bytes - fn from_bytes(bytes: &GenericArray) -> CtOption; -} - -/// Encode this curve element as bytes -pub trait ToBytes { - /// Size of the serialized byte array - type Size: ArrayLength; - - /// Encode this object to bytes - fn to_bytes(&self) -> GenericArray; -} diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index c7aaca92f..f01babce6 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -21,7 +21,6 @@ #[cfg(feature = "std")] extern crate std; -pub mod encoding; pub mod error; pub mod ops; pub mod point; @@ -51,11 +50,14 @@ use core::{ ops::{Add, Mul}, }; use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; -use subtle::{ConditionallySelectable, ConstantTimeEq}; +use subtle::{ConditionallySelectable, ConstantTimeEq, CtOption}; #[cfg(feature = "rand_core")] use rand_core::{CryptoRng, RngCore}; +/// Byte array containing a serialized scalar value (i.e. an integer) +pub type ElementBytes = GenericArray::ElementSize>; + /// Elliptic curve. /// /// This trait is intended to be impl'd by a ZST which represents a concrete @@ -78,18 +80,19 @@ pub trait Arithmetic: Curve { type Scalar: ConditionallySelectable + ConstantTimeEq + Default - + encoding::FromBytes; + + FromBytes; /// Affine point type for a given curve type AffinePoint: ConditionallySelectable + Mul> + point::Generator; } -/// Associate an object identifier (OID) with a curve -#[cfg(feature = "oid")] -#[cfg_attr(docsrs, doc(cfg(feature = "oid")))] -pub trait Identifier: Curve { - /// Object Identifier (OID) for this curve - const OID: oid::ObjectIdentifier; +/// Try to decode the given bytes into a curve element +pub trait FromBytes: ConditionallySelectable + Sized { + /// Size of the serialized byte array + type Size: ArrayLength; + + /// Try to decode this object from bytes + fn from_bytes(bytes: &GenericArray) -> CtOption; } /// Randomly generate a value. @@ -102,5 +105,10 @@ pub trait Generate { fn generate(rng: impl CryptoRng + RngCore) -> Self; } -/// Byte array containing a serialized scalar value (i.e. an integer) -pub type ElementBytes = GenericArray::ElementSize>; +/// Associate an object identifier (OID) with a curve +#[cfg(feature = "oid")] +#[cfg_attr(docsrs, doc(cfg(feature = "oid")))] +pub trait Identifier: Curve { + /// Object Identifier (OID) for this curve + const OID: oid::ObjectIdentifier; +} diff --git a/elliptic-curve/src/weierstrass/public_key.rs b/elliptic-curve/src/weierstrass/public_key.rs index d06f56858..82c2d08cc 100644 --- a/elliptic-curve/src/weierstrass/public_key.rs +++ b/elliptic-curve/src/weierstrass/public_key.rs @@ -5,9 +5,7 @@ use super::{ point::{CompressedPoint, CompressedPointSize, UncompressedPoint, UncompressedPointSize}, Curve, }; -use crate::{ - encoding::FromBytes, point::Generator, scalar::NonZeroScalar, Arithmetic, Error, SecretKey, -}; +use crate::{point::Generator, scalar::NonZeroScalar, Arithmetic, Error, FromBytes, SecretKey}; use core::{ fmt::{self, Debug}, ops::{Add, Mul}, From 048fb8f85a9b4cbbb29a2302a9a3fc596526fdcf Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 4 Aug 2020 19:14:05 -0700 Subject: [PATCH 0192/1461] elliptic-curve: add Into bound to Arithmetic::Scalar (#250) Supports generic scalar serialization --- elliptic-curve/src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index f01babce6..9664ee8f3 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -80,7 +80,8 @@ pub trait Arithmetic: Curve { type Scalar: ConditionallySelectable + ConstantTimeEq + Default - + FromBytes; + + FromBytes + + Into>; /// Affine point type for a given curve type AffinePoint: ConditionallySelectable + Mul> + point::Generator; From 5cf63df92be944bfbde8262f4931c45dadc88469 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 6 Aug 2020 12:50:57 -0700 Subject: [PATCH 0193/1461] elliptic-curve: Elliptic Curve Diffie-Hellman support (#251) Adds an `ecdh` module gated under an `ecdh` Cargo feature containing a generic high-level interface for performing ephemeral Elliptic Curve Diffie-Hellman key exchanges. The API is inspired by the one in `x25519-dalek`. --- elliptic-curve/Cargo.toml | 4 +- elliptic-curve/src/ecdh.rs | 197 +++++++++++++++++++ elliptic-curve/src/lib.rs | 12 +- elliptic-curve/src/scalar.rs | 30 ++- elliptic-curve/src/secret_key.rs | 6 +- elliptic-curve/src/weierstrass.rs | 5 +- elliptic-curve/src/weierstrass/point.rs | 68 +++++-- elliptic-curve/src/weierstrass/public_key.rs | 58 +++--- 8 files changed, 332 insertions(+), 48 deletions(-) create mode 100644 elliptic-curve/src/ecdh.rs diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index c6a4f8f47..6f98bd994 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -23,7 +23,9 @@ subtle = { version = "2.2.2", default-features = false } zeroize = { version = "1", optional = true, default-features = false } [features] -default = [] +default = ["rand"] +ecdh = ["rand", "weierstrass", "zeroize"] +rand = ["rand_core"] weierstrass = [] std = [] diff --git a/elliptic-curve/src/ecdh.rs b/elliptic-curve/src/ecdh.rs new file mode 100644 index 000000000..d604ddbbc --- /dev/null +++ b/elliptic-curve/src/ecdh.rs @@ -0,0 +1,197 @@ +//! Elliptic Curve Diffie-Hellman (Ephemeral) Support. +//! +//! This module contains a generic ECDH implementation which is usable with +//! any elliptic curve which implements the [`Arithmetic`] trait (presently +//! the `k256` and `p256` crates) +//! +//! # Usage +//! +//! Have each participant generate an [`EphemeralSecret`] value, compute the +//! [`PublicKey`] for that value, exchange public keys, then each participant +//! uses their [`EphemeralSecret`] and the other participant's [`PublicKey`] +//! to compute a [`SharedSecret`] value. +//! +//! # ⚠️ SECURITY WARNING ⚠️ +//! +//! Ephemeral Diffie-Hellman exchanges are unauthenticated and without a +//! further authentication step are trivially vulnerable to man-in-the-middle +//! attacks! +//! +//! These exchanges should be performed in the context of a protocol which +//! takes further steps to authenticate the peers in a key exchange. + +use crate::{ + consts::U1, + point::Generator, + scalar::NonZeroScalar, + weierstrass::{ + point::{CompressedPoint, CompressedPointSize, UncompressedPoint, UncompressedPointSize}, + public_key::{FromPublicKey, PublicKey}, + Curve, + }, + Arithmetic, ElementBytes, Error, Generate, +}; +use core::ops::{Add, Mul}; +use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; +use rand_core::{CryptoRng, RngCore}; +use zeroize::Zeroize; + +/// Ephemeral Diffie-Hellman Secret. +/// +/// These are ephemeral "secret key" values which are deliberately designed +/// to avoid being persisted. +pub struct EphemeralSecret +where + C: Curve + Arithmetic, + C::Scalar: Generate + Zeroize, +{ + scalar: NonZeroScalar, +} + +impl EphemeralSecret +where + C: Curve + Arithmetic, + C::Scalar: Clone + Generate + Zeroize, + C::AffinePoint: FromPublicKey + Mul, Output = C::AffinePoint> + Zeroize, + C::ElementSize: Add, + ::Output: Add, + CompressedPoint: From, + UncompressedPoint: From, + CompressedPointSize: ArrayLength, + UncompressedPointSize: ArrayLength, +{ + /// Generate a new [`EphemeralSecret`]. + pub fn generate(rng: impl CryptoRng + RngCore) -> Self { + Self { + scalar: NonZeroScalar::generate(rng), + } + } + + /// Get the public key associated with this ephemeral secret. + /// + /// The `compress` flag enables point compression. + pub fn public_key(&self, compress: bool) -> PublicKey { + let affine_point = C::AffinePoint::generator() * self.scalar.clone(); + + if compress { + PublicKey::Compressed(affine_point.into()) + } else { + PublicKey::Uncompressed(affine_point.into()) + } + } + + /// Compute a Diffie-Hellman shared secret from an ephemeral secret and the + /// [`PublicKey`] of the other participant in the exchange. + pub fn diffie_hellman(&self, public_key: &PublicKey) -> Result, Error> { + let affine_point = C::AffinePoint::from_public_key(public_key); + + if affine_point.is_some().into() { + let shared_secret = affine_point.unwrap() * self.scalar.clone(); + Ok(SharedSecret::new(shared_secret.into())) + } else { + Err(Error) + } + } +} + +impl From<&EphemeralSecret> for PublicKey +where + C: Curve + Arithmetic, + C::Scalar: Clone + Generate + Zeroize, + C::AffinePoint: FromPublicKey + Mul, Output = C::AffinePoint> + Zeroize, + C::ElementSize: Add, + ::Output: Add, + CompressedPoint: From, + UncompressedPoint: From, + CompressedPointSize: ArrayLength, + UncompressedPointSize: ArrayLength, +{ + fn from(ephemeral_secret: &EphemeralSecret) -> Self { + ephemeral_secret.public_key(C::COMPRESS_POINTS) + } +} + +impl Zeroize for EphemeralSecret +where + C: Curve + Arithmetic, + C::Scalar: Generate + Zeroize, +{ + fn zeroize(&mut self) { + self.scalar.zeroize() + } +} + +impl Drop for EphemeralSecret +where + C: Curve + Arithmetic, + C::Scalar: Generate + Zeroize, +{ + fn drop(&mut self) { + self.zeroize(); + } +} + +/// Shared secret value computed via ECDH key agreement. +/// +/// This value contains the raw serialized x-coordinate of the elliptic curve +/// point computed from a Diffie-Hellman exchange. +/// +/// # ⚠️ WARNING: NOT UNIFORMLY RANDOM! ⚠️ +/// +/// This value is not uniformly random and should not be used directly +/// as a cryptographic key for anything which requires that property +/// (e.g. symmetric ciphers). +/// +/// Instead, the resulting value should be used as input to a Key Derivation +/// Function (KDF) or cryptographic hash function to produce a symmetric key. +pub struct SharedSecret { + /// Computed secret value + secret_bytes: ElementBytes, +} + +impl SharedSecret +where + C: Curve + Arithmetic, + C::AffinePoint: Zeroize, + C::ElementSize: Add, + ::Output: Add, + UncompressedPointSize: ArrayLength, +{ + /// Create a new shared secret from the given uncompressed curve point + fn new(mut serialized_point: UncompressedPoint) -> Self { + let secret_bytes = GenericArray::clone_from_slice( + &serialized_point.as_ref()[1..(1 + C::ElementSize::to_usize())], + ); + + serialized_point.zeroize(); + Self { secret_bytes } + } + + /// Shared secret value, serialized as bytes. + /// + /// As noted in the comments for this struct, this value is non-uniform and + /// should not be used directly as a symmetric encryption key, but instead + /// as input to a KDF (or failing that, a hash function) used to produce + /// a symmetric key. + pub fn as_bytes(&self) -> &ElementBytes { + &self.secret_bytes + } +} + +impl Zeroize for SharedSecret +where + C: Curve + Arithmetic, +{ + fn zeroize(&mut self) { + self.secret_bytes.zeroize() + } +} + +impl Drop for SharedSecret +where + C: Curve + Arithmetic, +{ + fn drop(&mut self) { + self.zeroize(); + } +} diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 9664ee8f3..618795245 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -27,6 +27,10 @@ pub mod point; pub mod scalar; pub mod secret_key; +#[cfg(feature = "ecdh")] +#[cfg_attr(docsrs, doc(cfg(feature = "ecdh")))] +pub mod ecdh; + // TODO(tarcieri): other curve forms #[cfg(feature = "weierstrass")] #[cfg_attr(docsrs, doc(cfg(feature = "weierstrass")))] @@ -39,7 +43,7 @@ pub use subtle; #[cfg(feature = "oid")] pub use oid; -#[cfg(feature = "rand_core")] +#[cfg(feature = "rand")] pub use rand_core; #[cfg(feature = "zeroize")] @@ -52,7 +56,7 @@ use core::{ use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; use subtle::{ConditionallySelectable, ConstantTimeEq, CtOption}; -#[cfg(feature = "rand_core")] +#[cfg(feature = "rand")] use rand_core::{CryptoRng, RngCore}; /// Byte array containing a serialized scalar value (i.e. an integer) @@ -99,8 +103,8 @@ pub trait FromBytes: ConditionallySelectable + Sized { /// Randomly generate a value. /// /// Primarily intended for use with scalar types for a particular curve. -#[cfg(feature = "rand_core")] -#[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] +#[cfg(feature = "rand")] +#[cfg_attr(docsrs, doc(cfg(feature = "rand")))] pub trait Generate { /// Generate a random element of this type using the provided [`CryptoRng`] fn generate(rng: impl CryptoRng + RngCore) -> Self; diff --git a/elliptic-curve/src/scalar.rs b/elliptic-curve/src/scalar.rs index 0237e8cf3..bf08b301a 100644 --- a/elliptic-curve/src/scalar.rs +++ b/elliptic-curve/src/scalar.rs @@ -1,8 +1,14 @@ //! Scalar types -use crate::{Arithmetic, Curve}; +use crate::{Arithmetic, Curve, FromBytes}; use subtle::{ConstantTimeEq, CtOption}; +#[cfg(feature = "rand")] +use crate::{ + rand_core::{CryptoRng, RngCore}, + Generate, +}; + #[cfg(feature = "zeroize")] use zeroize::Zeroize; @@ -14,6 +20,7 @@ use zeroize::Zeroize; /// /// In the context of ECC, it's useful for ensuring that scalar multiplication /// cannot result in the point at infinity. +#[derive(Clone)] pub struct NonZeroScalar { scalar: C::Scalar, } @@ -25,7 +32,8 @@ where /// Create a [`NonZeroScalar`] from a scalar, performing a constant-time /// check that it's non-zero. pub fn new(scalar: C::Scalar) -> CtOption { - let is_zero = scalar.ct_eq(&C::Scalar::default()); + let zero = C::Scalar::from_bytes(&Default::default()).unwrap(); + let is_zero = scalar.ct_eq(&zero); CtOption::new(Self { scalar }, !is_zero) } } @@ -39,6 +47,24 @@ where } } +#[cfg(feature = "rand")] +impl Generate for NonZeroScalar +where + C: Curve + Arithmetic, + C::Scalar: Generate, +{ + fn generate(mut rng: impl CryptoRng + RngCore) -> Self { + // Use rejection sampling to eliminate zeroes + loop { + let result = Self::new(C::Scalar::generate(&mut rng)); + + if result.is_some().into() { + break result.unwrap(); + } + } + } +} + #[cfg(feature = "zeroize")] impl Zeroize for NonZeroScalar where diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index c792560f4..f6afcfd45 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -14,7 +14,7 @@ use core::{ }; use generic_array::{typenum::Unsigned, GenericArray}; -#[cfg(feature = "rand_core")] +#[cfg(feature = "rand")] use { crate::{Arithmetic, Generate}, rand_core::{CryptoRng, RngCore}, @@ -68,8 +68,8 @@ impl Debug for SecretKey { } } -#[cfg(feature = "rand_core")] -#[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] +#[cfg(feature = "rand")] +#[cfg_attr(docsrs, doc(cfg(feature = "rand")))] impl Generate for SecretKey where C: Curve + Arithmetic, diff --git a/elliptic-curve/src/weierstrass.rs b/elliptic-curve/src/weierstrass.rs index 36d4a01d3..2858176b8 100644 --- a/elliptic-curve/src/weierstrass.rs +++ b/elliptic-curve/src/weierstrass.rs @@ -9,4 +9,7 @@ pub use self::{ }; /// Marker trait for elliptic curves in short Weierstrass form -pub trait Curve: super::Curve {} +pub trait Curve: super::Curve { + /// Should point compression be applied by default? + const COMPRESS_POINTS: bool; +} diff --git a/elliptic-curve/src/weierstrass/point.rs b/elliptic-curve/src/weierstrass/point.rs index 050d266a3..e2b563eb0 100644 --- a/elliptic-curve/src/weierstrass/point.rs +++ b/elliptic-curve/src/weierstrass/point.rs @@ -14,6 +14,9 @@ use generic_array::{ ArrayLength, GenericArray, }; +#[cfg(feature = "zeroize")] +use zeroize::Zeroize; + /// Size of a compressed elliptic curve point for the given curve when /// serialized using `Elliptic-Curve-Point-to-Octet-String` encoding /// (including leading `0x02` or `0x03` tag byte). @@ -32,8 +35,9 @@ pub type UncompressedPointSize = /// /// #[derive(Eq, Hash, PartialEq, PartialOrd, Ord)] -pub struct CompressedPoint +pub struct CompressedPoint where + C: Curve, C::ElementSize: Add, CompressedPointSize: ArrayLength, { @@ -41,8 +45,9 @@ where bytes: GenericArray>, } -impl CompressedPoint +impl CompressedPoint where + C: Curve, C::ElementSize: Add, CompressedPointSize: ArrayLength, { @@ -62,12 +67,10 @@ where B: Into>>, { let bytes = into_bytes.into(); - let tag_byte = bytes.as_ref()[0]; - if tag_byte == 0x02 || tag_byte == 0x03 { - Some(Self { bytes }) - } else { - None + match bytes[0] { + 0x02 | 0x03 => Some(Self { bytes }), + _ => None, } } @@ -84,8 +87,9 @@ where } } -impl AsRef<[u8]> for CompressedPoint +impl AsRef<[u8]> for CompressedPoint where + C: Curve, C::ElementSize: Add, CompressedPointSize: ArrayLength, { @@ -103,13 +107,28 @@ where { } -impl Clone for CompressedPoint +impl Clone for CompressedPoint where + C: Curve, C::ElementSize: Add, CompressedPointSize: ArrayLength, { fn clone(&self) -> Self { - Self::from_bytes(self.bytes.clone()).unwrap() + Self { + bytes: self.bytes.clone(), + } + } +} + +#[cfg(feature = "zeroize")] +impl Zeroize for CompressedPoint +where + C: Curve, + C::ElementSize: Add, + CompressedPointSize: ArrayLength, +{ + fn zeroize(&mut self) { + self.bytes.zeroize() } } @@ -130,8 +149,9 @@ where bytes: GenericArray>, } -impl UncompressedPoint +impl UncompressedPoint where + C: Curve, C::ElementSize: Add, ::Output: Add, UncompressedPointSize: ArrayLength, @@ -183,8 +203,9 @@ where } } -impl AsRef<[u8]> for UncompressedPoint +impl AsRef<[u8]> for UncompressedPoint where + C: Curve, C::ElementSize: Add, ::Output: Add, UncompressedPointSize: ArrayLength, @@ -195,8 +216,9 @@ where } } -impl Copy for UncompressedPoint +impl Copy for UncompressedPoint where + C: Curve, C::ElementSize: Add, ::Output: Add, UncompressedPointSize: ArrayLength, @@ -204,13 +226,29 @@ where { } -impl Clone for UncompressedPoint +impl Clone for UncompressedPoint where + C: Curve, C::ElementSize: Add, ::Output: Add, UncompressedPointSize: ArrayLength, { fn clone(&self) -> Self { - Self::from_bytes(self.bytes.clone()).unwrap() + Self { + bytes: self.bytes.clone(), + } + } +} + +#[cfg(feature = "zeroize")] +impl Zeroize for UncompressedPoint +where + C: Curve, + C::ElementSize: Add, + ::Output: Add, + UncompressedPointSize: ArrayLength, +{ + fn zeroize(&mut self) { + self.bytes.zeroize() } } diff --git a/elliptic-curve/src/weierstrass/public_key.rs b/elliptic-curve/src/weierstrass/public_key.rs index 82c2d08cc..94614e507 100644 --- a/elliptic-curve/src/weierstrass/public_key.rs +++ b/elliptic-curve/src/weierstrass/public_key.rs @@ -7,6 +7,7 @@ use super::{ }; use crate::{point::Generator, scalar::NonZeroScalar, Arithmetic, Error, FromBytes, SecretKey}; use core::{ + convert::TryFrom, fmt::{self, Debug}, ops::{Add, Mul}, }; @@ -21,8 +22,9 @@ pub type UntaggedPointSize = <::ElementSize as Add>::Outpu /// Public keys for Weierstrass curves #[derive(Clone, Eq, PartialEq, PartialOrd, Ord)] -pub enum PublicKey +pub enum PublicKey where + C: Curve, C::ElementSize: Add, ::Output: Add, CompressedPointSize: ArrayLength, @@ -35,8 +37,9 @@ where Uncompressed(UncompressedPoint), } -impl PublicKey +impl PublicKey where + C: Curve, C::ElementSize: Add, ::Output: Add, CompressedPointSize: ArrayLength, @@ -49,7 +52,7 @@ where /// 2.3.3 (page 10). /// /// - pub fn from_bytes>(bytes: B) -> Option { + pub fn from_bytes(bytes: impl AsRef<[u8]>) -> Option { let slice = bytes.as_ref(); let length = slice.len(); @@ -66,19 +69,6 @@ where } } - /// Decode public key from an compressed elliptic curve point - /// encoded using the `Elliptic-Curve-Point-to-Octet-String` algorithm - /// described in SEC 1: Elliptic Curve Cryptography (Version 2.0) section - /// 2.3.3 (page 10). - /// - /// - pub fn from_compressed_point(into_bytes: B) -> Option - where - B: Into>>, - { - CompressedPoint::from_bytes(into_bytes).map(PublicKey::Compressed) - } - /// Decode public key from a raw uncompressed point serialized /// as a bytestring, without a `0x04`-byte tag. /// @@ -146,8 +136,9 @@ where } } -impl AsRef<[u8]> for PublicKey +impl AsRef<[u8]> for PublicKey where + C: Curve, C::ElementSize: Add, ::Output: Add, CompressedPointSize: ArrayLength, @@ -159,8 +150,9 @@ where } } -impl Copy for PublicKey +impl Copy for PublicKey where + C: Curve, C::ElementSize: Add, ::Output: Add, CompressedPointSize: ArrayLength, @@ -170,8 +162,9 @@ where { } -impl Debug for PublicKey +impl Debug for PublicKey where + C: Curve, C::ElementSize: Add, ::Output: Add, CompressedPointSize: ArrayLength, @@ -182,8 +175,27 @@ where } } -impl From> for PublicKey +impl TryFrom<&SecretKey> for PublicKey +where + C: Curve + Arithmetic, + C::AffinePoint: Mul, Output = C::AffinePoint>, + C::ElementSize: Add, + ::Output: Add, + CompressedPoint: From, + UncompressedPoint: From, + CompressedPointSize: ArrayLength, + UncompressedPointSize: ArrayLength, +{ + type Error = Error; + + fn try_from(secret_key: &SecretKey) -> Result { + Self::from_secret_key(secret_key, C::COMPRESS_POINTS) + } +} + +impl From> for PublicKey where + C: Curve, C::ElementSize: Add, ::Output: Add, CompressedPointSize: ArrayLength, @@ -194,8 +206,9 @@ where } } -impl From> for PublicKey +impl From> for PublicKey where + C: Curve, C::ElementSize: Add, ::Output: Add, CompressedPointSize: ArrayLength, @@ -209,8 +222,9 @@ where /// Trait for deserializing a value from a public key. /// /// This is intended for use with the `AffinePoint` type for a given elliptic curve. -pub trait FromPublicKey: Sized +pub trait FromPublicKey: Sized where + C: Curve, C::ElementSize: Add, ::Output: Add, CompressedPointSize: ArrayLength, From 1feee24e183827f34eb628c46336ee4a2e7a8cec Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Aug 2020 05:49:22 +0000 Subject: [PATCH 0194/1461] build(deps): bump generic-array from 0.14.3 to 0.14.4 (#252) Bumps [generic-array](https://github.com/fizyk20/generic-array) from 0.14.3 to 0.14.4. - [Release notes](https://github.com/fizyk20/generic-array/releases) - [Changelog](https://github.com/fizyk20/generic-array/blob/master/CHANGELOG.md) - [Commits](https://github.com/fizyk20/generic-array/commits) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3660857f1..181476f74 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5,7 +5,7 @@ name = "aead" version = "0.3.2" dependencies = [ "blobby 0.3.0", - "generic-array 0.14.3", + "generic-array 0.14.4", "heapless", ] @@ -38,7 +38,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "generic-array 0.14.3", + "generic-array 0.14.4", ] [[package]] @@ -46,7 +46,7 @@ name = "block-cipher" version = "0.8.0" dependencies = [ "blobby 0.3.0", - "generic-array 0.14.3", + "generic-array 0.14.4", ] [[package]] @@ -78,7 +78,7 @@ name = "crypto-mac" version = "0.8.0" dependencies = [ "blobby 0.2.0", - "generic-array 0.14.3", + "generic-array 0.14.4", "subtle", ] @@ -101,7 +101,7 @@ name = "digest" version = "0.9.0" dependencies = [ "blobby 0.2.0", - "generic-array 0.14.3", + "generic-array 0.14.4", ] [[package]] @@ -110,7 +110,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ - "generic-array 0.14.3", + "generic-array 0.14.4", ] [[package]] @@ -118,7 +118,7 @@ name = "elliptic-curve" version = "0.5.0-pre" dependencies = [ "const-oid", - "generic-array 0.14.3", + "generic-array 0.14.4", "rand_core", "subtle", "zeroize", @@ -144,9 +144,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.3" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60fb4bb6bba52f78a471264d9a3b7d026cc0af47b22cd2cffbc0b787ca003e63" +checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" dependencies = [ "typenum", "version_check", @@ -274,7 +274,7 @@ version = "0.6.0" dependencies = [ "blobby 0.3.0", "block-cipher", - "generic-array 0.14.3", + "generic-array 0.14.4", ] [[package]] @@ -322,7 +322,7 @@ checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" name = "universal-hash" version = "0.4.0" dependencies = [ - "generic-array 0.14.3", + "generic-array 0.14.4", "subtle", ] From a0f0c0c286405449d977f336c208abcb715bc5af Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Mon, 10 Aug 2020 20:46:28 +0300 Subject: [PATCH 0195/1461] Use SVG logo (#253) --- aead/src/lib.rs | 5 ++++- block-cipher/src/lib.rs | 5 ++++- crypto-mac/src/lib.rs | 5 ++++- cryptography/src/lib.rs | 5 ++++- digest/src/lib.rs | 5 ++++- elliptic-curve/src/lib.rs | 3 ++- signature/src/lib.rs | 3 ++- stream-cipher/src/lib.rs | 5 ++++- universal-hash/src/lib.rs | 5 ++++- 9 files changed, 32 insertions(+), 9 deletions(-) diff --git a/aead/src/lib.rs b/aead/src/lib.rs index 3f7ea4ca6..dc37133ba 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -16,7 +16,10 @@ #![no_std] #![cfg_attr(docsrs, feature(doc_cfg))] #![forbid(unsafe_code)] -#![doc(html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png")] +#![doc( + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" +)] #![warn(missing_docs, rust_2018_idioms)] #[cfg(feature = "alloc")] diff --git a/block-cipher/src/lib.rs b/block-cipher/src/lib.rs index 18aefa627..69e16696c 100644 --- a/block-cipher/src/lib.rs +++ b/block-cipher/src/lib.rs @@ -12,7 +12,10 @@ #![no_std] #![cfg_attr(docsrs, feature(doc_cfg))] -#![doc(html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png")] +#![doc( + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" +)] #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] diff --git a/crypto-mac/src/lib.rs b/crypto-mac/src/lib.rs index 8b4768d6a..bb685d044 100644 --- a/crypto-mac/src/lib.rs +++ b/crypto-mac/src/lib.rs @@ -2,7 +2,10 @@ #![no_std] #![cfg_attr(docsrs, feature(doc_cfg))] -#![doc(html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png")] +#![doc( + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" +)] #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] diff --git a/cryptography/src/lib.rs b/cryptography/src/lib.rs index 9df174413..e02b506c7 100644 --- a/cryptography/src/lib.rs +++ b/cryptography/src/lib.rs @@ -36,7 +36,10 @@ //! [2]: https://github.com/RustCrypto #![no_std] -#![doc(html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png")] +#![doc( + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" +)] #![forbid(unsafe_code)] #![warn(rust_2018_idioms)] diff --git a/digest/src/lib.rs b/digest/src/lib.rs index b049a694d..9ded58214 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -25,7 +25,10 @@ #![no_std] #![cfg_attr(docsrs, feature(doc_cfg))] #![forbid(unsafe_code)] -#![doc(html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png")] +#![doc( + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" +)] #![warn(missing_docs, rust_2018_idioms)] #[cfg(feature = "alloc")] diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 618795245..3eb9d3009 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -14,7 +14,8 @@ #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms, unused_qualifications)] #![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png", + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", html_root_url = "https://docs.rs/elliptic-curve/0.4.0" )] diff --git a/signature/src/lib.rs b/signature/src/lib.rs index de3293406..6f69f1684 100644 --- a/signature/src/lib.rs +++ b/signature/src/lib.rs @@ -154,7 +154,8 @@ #![no_std] #![cfg_attr(docsrs, feature(doc_cfg))] #![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/ferris_signer.png", + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", html_root_url = "https://docs.rs/signature/1.2.2" )] #![forbid(unsafe_code)] diff --git a/stream-cipher/src/lib.rs b/stream-cipher/src/lib.rs index 80184d0d3..8c2ac3b01 100644 --- a/stream-cipher/src/lib.rs +++ b/stream-cipher/src/lib.rs @@ -6,7 +6,10 @@ #![no_std] #![cfg_attr(docsrs, feature(doc_cfg))] -#![doc(html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png")] +#![doc( + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" +)] #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] diff --git a/universal-hash/src/lib.rs b/universal-hash/src/lib.rs index 815affc07..dc0e6f1cf 100644 --- a/universal-hash/src/lib.rs +++ b/universal-hash/src/lib.rs @@ -19,7 +19,10 @@ #![no_std] #![forbid(unsafe_code)] -#![doc(html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png")] +#![doc( + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" +)] #![warn(missing_docs, rust_2018_idioms)] #[cfg(feature = "std")] From 18346fdf6e68332e8571503eee6f43c97e6eccbd Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Mon, 10 Aug 2020 20:55:34 +0300 Subject: [PATCH 0196/1461] crypto-mac v0.9 (#217) --- .github/workflows/crypto-mac.yml | 1 + Cargo.lock | 54 +++++++++++++++++++------------- crypto-mac/CHANGELOG.md | 13 ++++++++ crypto-mac/Cargo.toml | 5 +-- crypto-mac/src/dev.rs | 4 +-- crypto-mac/src/lib.rs | 49 +++++++++++++++++++---------- cryptography/Cargo.toml | 2 +- 7 files changed, 84 insertions(+), 44 deletions(-) diff --git a/.github/workflows/crypto-mac.yml b/.github/workflows/crypto-mac.yml index 32333fc8b..490dc7cfa 100644 --- a/.github/workflows/crypto-mac.yml +++ b/.github/workflows/crypto-mac.yml @@ -51,6 +51,7 @@ jobs: toolchain: ${{ matrix.rust }} - run: cargo check --all-features - run: cargo test --release + - run: cargo test --features block-cipher --release - run: cargo test --features dev --release - run: cargo test --features std --release - run: cargo test --all-features --release diff --git a/Cargo.lock b/Cargo.lock index 181476f74..d80a03485 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -49,6 +49,15 @@ dependencies = [ "generic-array 0.14.4", ] +[[package]] +name = "block-cipher" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f337a3e6da609650eb74e02bc9fac7b735049f7623ab12f2e4c719316fcc7e80" +dependencies = [ + "generic-array 0.14.4", +] + [[package]] name = "byteorder" version = "1.3.4" @@ -69,15 +78,16 @@ checksum = "a2d9162b7289a46e86208d6af2c686ca5bfde445878c41a458a9fac706252d0b" [[package]] name = "cpuid-bool" -version = "0.1.0" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d375c433320f6c5057ae04a04376eef4d04ce2801448cf8863a78da99107be4" +checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634" [[package]] name = "crypto-mac" -version = "0.8.0" +version = "0.9.0" dependencies = [ - "blobby 0.2.0", + "blobby 0.3.0", + "block-cipher 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "generic-array 0.14.4", "subtle", ] @@ -87,7 +97,7 @@ name = "cryptography" version = "0.2.0" dependencies = [ "aead", - "block-cipher", + "block-cipher 0.8.0", "crypto-mac", "digest 0.9.0", "elliptic-curve", @@ -185,9 +195,9 @@ dependencies = [ [[package]] name = "hex-literal-impl" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d4c5c844e2fee0bf673d54c2c177f1713b3d2af2ff6e666b49cb7572e6cf42d" +checksum = "853f769599eb31de176303197b7ba4973299c38c7a7604a6bc88c3eef05b9b46" dependencies = [ "proc-macro-hack", ] @@ -200,24 +210,24 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "proc-macro-hack" -version = "0.5.15" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d659fe7c6d27f25e9d80a1a094c223f5246f6a6596453e09d7229bf42750b63" +checksum = "99c605b9a0adc77b7211c6b1f722dcb613d68d66859a44f3d485a6da332b0598" [[package]] name = "proc-macro2" -version = "1.0.12" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8872cf6f48eee44265156c111456a700ab3483686b3f96df4cf5481c89157319" +checksum = "04f5f085b5d71e2188cb8271e5da0161ad52c3f227a661a3c135fdf28e258b12" dependencies = [ "unicode-xid", ] [[package]] name = "quote" -version = "1.0.4" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c1f4b0efa5fc5e8ceb705136bfee52cfdb6a4e3509f770b478cd6ed434232a7" +checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" dependencies = [ "proc-macro2", ] @@ -264,16 +274,16 @@ dependencies = [ [[package]] name = "stable_deref_trait" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "stream-cipher" version = "0.6.0" dependencies = [ "blobby 0.3.0", - "block-cipher", + "block-cipher 0.8.0", "generic-array 0.14.4", ] @@ -285,9 +295,9 @@ checksum = "502d53007c02d7605a05df1c1a73ee436952781653da5d0bf57ad608f66932c1" [[package]] name = "syn" -version = "1.0.19" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8e5aa70697bb26ee62214ae3288465ecec0000f05182f039b477001f08f5ae7" +checksum = "e69abc24912995b3038597a7a593be5053eb0fb44f3cc5beec0deb421790c1f4" dependencies = [ "proc-macro2", "quote", @@ -296,9 +306,9 @@ dependencies = [ [[package]] name = "synstructure" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" +checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701" dependencies = [ "proc-macro2", "quote", @@ -314,9 +324,9 @@ checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" [[package]] name = "unicode-xid" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" +checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" [[package]] name = "universal-hash" diff --git a/crypto-mac/CHANGELOG.md b/crypto-mac/CHANGELOG.md index b0eb5094b..867676934 100644 --- a/crypto-mac/CHANGELOG.md +++ b/crypto-mac/CHANGELOG.md @@ -5,6 +5,19 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.9.0 (2020-08-10) +### Added +- `FromBlockCipher` trait and blanket implementation of the `NewMac` trait +for it ([#217]) + +### Changed +- Updated test vectors storage to `blobby v0.3` ([#217]) + +### Removed +- `impl_write!` macro ([#217]) + +[#217]: https://github.com/RustCrypto/traits/pull/217 + ## 0.8.0 (2020-06-04) ### Added - `impl_write!` macro ([#134]) diff --git a/crypto-mac/Cargo.toml b/crypto-mac/Cargo.toml index ff5c9313d..b8350c22e 100644 --- a/crypto-mac/Cargo.toml +++ b/crypto-mac/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crypto-mac" description = "Trait for Message Authentication Code (MAC) algorithms" -version = "0.8.0" +version = "0.9.0" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" @@ -13,8 +13,9 @@ categories = ["cryptography", "no-std"] [dependencies] generic-array = "0.14" +block-cipher = { version = "0.8", optional = true } subtle = { version = "2", default-features = false } -blobby = { version = "0.2", optional = true } +blobby = { version = "0.3", optional = true } [features] dev = ["blobby"] diff --git a/crypto-mac/src/dev.rs b/crypto-mac/src/dev.rs index f338cab74..e2348501e 100644 --- a/crypto-mac/src/dev.rs +++ b/crypto-mac/src/dev.rs @@ -39,9 +39,7 @@ macro_rules! new_test { let data = include_bytes!(concat!("data/", $test_name, ".blb")); for (i, row) in Blob3Iterator::new(data).unwrap().enumerate() { - let key = row[0]; - let input = row[1]; - let tag = row[2]; + let [key, input, tag] = row.unwrap(); if let Some(desc) = run_test(key, input, tag) { panic!( "\n\ diff --git a/crypto-mac/src/lib.rs b/crypto-mac/src/lib.rs index bb685d044..a4b6e8f77 100644 --- a/crypto-mac/src/lib.rs +++ b/crypto-mac/src/lib.rs @@ -12,6 +12,9 @@ #[cfg(feature = "std")] extern crate std; +#[cfg(feature = "block-cipher")] +use block_cipher::{BlockCipher, NewBlockCipher}; + #[cfg(feature = "dev")] #[cfg_attr(docsrs, doc(cfg(feature = "dev")))] pub mod dev; @@ -121,20 +124,34 @@ impl PartialEq for Output { impl Eq for Output {} -#[macro_export] -/// Implements `std::io::Write` trait for implementer of [`Mac`] -macro_rules! impl_write { - ($mac:ident) => { - #[cfg(feature = "std")] - impl std::io::Write for $mac { - fn write(&mut self, buf: &[u8]) -> std::io::Result { - Mac::update(self, buf); - Ok(buf.len()) - } - - fn flush(&mut self) -> std::io::Result<()> { - Ok(()) - } - } - }; +#[cfg(feature = "block-cipher")] +#[cfg_attr(docsrs, doc(cfg(feature = "block-cipher")))] +/// Trait for MAC functions which can be created from block cipher. +pub trait FromBlockCipher { + /// Block cipher type + type Cipher: BlockCipher; + + /// Create new MAC isntance from provided block cipher. + fn from_cipher(cipher: Self::Cipher) -> Self; +} + +#[cfg(feature = "block-cipher")] +#[cfg_attr(docsrs, doc(cfg(feature = "block-cipher")))] +impl NewMac for T +where + T: FromBlockCipher, + T::Cipher: NewBlockCipher, +{ + type KeySize = <::Cipher as NewBlockCipher>::KeySize; + + fn new(key: &Key) -> Self { + let cipher = ::Cipher::new(key); + Self::from_cipher(cipher) + } + + fn new_varkey(key: &[u8]) -> Result { + ::Cipher::new_varkey(key) + .map_err(|_| InvalidKeyLength) + .map(Self::from_cipher) + } } diff --git a/cryptography/Cargo.toml b/cryptography/Cargo.toml index 38b0afe16..a0895e936 100644 --- a/cryptography/Cargo.toml +++ b/cryptography/Cargo.toml @@ -16,7 +16,7 @@ aead = { version = "0.3", optional = true, path = "../aead" } block-cipher = { version = "0.8", optional = true, path = "../block-cipher" } digest = { version = "0.9", optional = true, path = "../digest" } elliptic-curve = { version = "= 0.5.0-pre", optional = true, path = "../elliptic-curve" } -mac = { version = "0.8", package = "crypto-mac", optional = true, path = "../crypto-mac" } +mac = { version = "0.9", package = "crypto-mac", optional = true, path = "../crypto-mac" } signature = { version = "1.1.0", optional = true, default-features = false, path = "../signature" } stream-cipher = { version = "0.6", optional = true, path = "../stream-cipher" } universal-hash = { version = "0.4", optional = true, path = "../universal-hash" } From de0ff0fb8566382bd712f7efcff07fe4f520bace Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 10 Aug 2020 15:39:35 -0700 Subject: [PATCH 0197/1461] elliptic-curve v0.5.0 (#254) --- Cargo.lock | 2 +- cryptography/Cargo.toml | 2 +- elliptic-curve/CHANGELOG.md | 55 +++++++++++++++++++++++++++++-------- elliptic-curve/Cargo.toml | 19 ++++++------- elliptic-curve/src/lib.rs | 2 +- 5 files changed, 55 insertions(+), 25 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d80a03485..70623bf28 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -125,7 +125,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.5.0-pre" +version = "0.5.0" dependencies = [ "const-oid", "generic-array 0.14.4", diff --git a/cryptography/Cargo.toml b/cryptography/Cargo.toml index a0895e936..d26ef8512 100644 --- a/cryptography/Cargo.toml +++ b/cryptography/Cargo.toml @@ -15,7 +15,7 @@ edition = "2018" aead = { version = "0.3", optional = true, path = "../aead" } block-cipher = { version = "0.8", optional = true, path = "../block-cipher" } digest = { version = "0.9", optional = true, path = "../digest" } -elliptic-curve = { version = "= 0.5.0-pre", optional = true, path = "../elliptic-curve" } +elliptic-curve = { version = "= 0.5", optional = true, path = "../elliptic-curve" } mac = { version = "0.9", package = "crypto-mac", optional = true, path = "../crypto-mac" } signature = { version = "1.1.0", optional = true, default-features = false, path = "../signature" } stream-cipher = { version = "0.6", optional = true, path = "../stream-cipher" } diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index de475f85b..6c4c1587a 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,33 +4,64 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 0.4.0 (2020-06-04) +## 0.5.0 (2020-08-10) +### Added +- `Arithmetic` trait ([#219]) +- `Generate` trait ([#220], [#226]) +- Toplevel `Curve` trait ([#223]) +- `Invert` trait ([#228]) +- `FromPublicKey` trait ([#229], [#248]) +- Re-export `zeroize` ([#233]) +- OID support ([#240], [#245]) +- `NonZeroScalar` type ([#241]) +- `Generator` trait ([#241]) +- `weierstrass::PublicKey::compress` method ([#243]) +- Derive `Clone` on `SecretKey` ([#244]) +- Generic Elliptic Curve Diffie-Hellman support ([#251]) + ### Changed -- Bump `generic-array` dependency from v0.12 to v0.14 ([#38]) +- Moved repo to https://github.com/RustCrypto/traits ([#213]) +- Rename `ScalarBytes` to `ElementBytes` ([#246]) +- Rename `CompressedCurvePoint`/`UncompressedCurvePoint` to + `CompressedPoint`/`UncompressedPoint` + +[#213]: https://github.com/RustCrypto/traits/pull/213 +[#219]: https://github.com/RustCrypto/traits/pull/219 +[#220]: https://github.com/RustCrypto/traits/pull/220 +[#223]: https://github.com/RustCrypto/traits/pull/223 +[#226]: https://github.com/RustCrypto/traits/pull/226 +[#228]: https://github.com/RustCrypto/traits/pull/228 +[#229]: https://github.com/RustCrypto/traits/pull/229 +[#233]: https://github.com/RustCrypto/traits/pull/233 +[#240]: https://github.com/RustCrypto/traits/pull/240 +[#241]: https://github.com/RustCrypto/traits/pull/241 +[#243]: https://github.com/RustCrypto/traits/pull/243 +[#244]: https://github.com/RustCrypto/traits/pull/244 +[#245]: https://github.com/RustCrypto/traits/pull/245 +[#246]: https://github.com/RustCrypto/traits/pull/246 +[#248]: https://github.com/RustCrypto/traits/pull/248 +[#251]: https://github.com/RustCrypto/traits/pull/251 -[#38]: https://github.com/RustCrypto/elliptic-curves/pull/38 +## 0.4.0 (2020-06-04) +### Changed +- Bump `generic-array` dependency from v0.12 to v0.14 ## 0.3.0 (2020-01-15) ### Added -- `Scalar` struct type ([#5]) +- `Scalar` struct type ### Changed - Repository moved to ### Removed -- Curve definitions/arithmetic extracted out into per-curve crates ([#5]) - -[#5]: https://github.com/RustCrypto/elliptic-curves/pull/5 +- Curve definitions/arithmetic extracted out into per-curve crates ## 0.2.0 (2019-12-11) ### Added -- `secp256r1` (P-256) point compression and decompression ([RustCrypto/signatures#63], [RustCrypto/signatures#64]) +- `secp256r1` (P-256) point compression and decompression ### Changed -- Bump MSRV to 1.37 ([RustCrypto/signatures#63]) - -[RustCrypto/signatures#63]: https://github.com/RustCrypto/signatures/pull/63 -[RustCrypto/signatures#64]: https://github.com/RustCrypto/signatures/pull/64 +- Bump MSRV to 1.37 ## 0.1.0 (2019-12-06) - Initial release diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 6f98bd994..16ba4e4b5 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -5,21 +5,20 @@ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. """ -version = "0.5.0-pre" # Also update html_root_url in lib.rs when bumping this -authors = ["RustCrypto Developers"] -license = "Apache-2.0 OR MIT" -documentation = "https://docs.rs/elliptic-curve" -repository = "https://github.com/RustCrypto/elliptic-curves/tree/master/elliptic-curve-crate" -readme = "README.md" -edition = "2018" -categories = ["cryptography", "no-std"] -keywords = ["crypto", "ecc", "elliptic", "weierstrass"] +version = "0.5.0" # Also update html_root_url in lib.rs when bumping this +authors = ["RustCrypto Developers"] +license = "Apache-2.0 OR MIT" +repository = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve" +readme = "README.md" +edition = "2018" +categories = ["cryptography", "no-std"] +keywords = ["crypto", "ecc", "elliptic", "weierstrass"] [dependencies] generic-array = { version = "0.14", default-features = false } oid = { package = "const-oid", version = "0.1", optional = true } rand_core = { version = "0.5", optional = true, default-features = false } -subtle = { version = "2.2.2", default-features = false } +subtle = { version = "2.2", default-features = false } zeroize = { version = "1", optional = true, default-features = false } [features] diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 3eb9d3009..1c3c6b227 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -16,7 +16,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.4.0" + html_root_url = "https://docs.rs/elliptic-curve/0.5.0" )] #[cfg(feature = "std")] From aa657a648815493eb0db39b385607a37235c752a Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 10 Aug 2020 15:45:48 -0700 Subject: [PATCH 0198/1461] cryptography v0.3.0 (#255) --- Cargo.lock | 2 +- cryptography/CHANGELOG.md | 10 ++++++++++ cryptography/Cargo.toml | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 70623bf28..1b50861e8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -94,7 +94,7 @@ dependencies = [ [[package]] name = "cryptography" -version = "0.2.0" +version = "0.3.0" dependencies = [ "aead", "block-cipher 0.8.0", diff --git a/cryptography/CHANGELOG.md b/cryptography/CHANGELOG.md index 2f0bc6786..a9eeae187 100644 --- a/cryptography/CHANGELOG.md +++ b/cryptography/CHANGELOG.md @@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.3.0 (2020-08-10) +### Added +- `elliptic-curve` feature ([#213]) + +### Changed +- Bump `crypto-mac` to v0.9 ([#217]) + +[#213]: https://github.com/RustCrypto/traits/pull/213 +[#217]: https://github.com/RustCrypto/traits/pull/217 + ## 0.2.0 (2020-07-03) ### Changed - Bump `stream-cipher` to v0.5 ([#209]) diff --git a/cryptography/Cargo.toml b/cryptography/Cargo.toml index d26ef8512..892ffd38e 100644 --- a/cryptography/Cargo.toml +++ b/cryptography/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cryptography" -version = "0.2.0" +version = "0.3.0" authors = ["The RustCrypto Project Developers"] license = "Apache-2.0 OR MIT" description = "Facade crate for the RustCrypto project's traits" From 545b1269e57dbb110ec69c76386d39abfb86e781 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 10 Aug 2020 16:01:55 -0700 Subject: [PATCH 0199/1461] cryptography: fix rustdoc for `elliptic_curve` re-export (#256) Previously used a hyphen instead of an underscore --- cryptography/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cryptography/src/lib.rs b/cryptography/src/lib.rs index e02b506c7..ad17177f8 100644 --- a/cryptography/src/lib.rs +++ b/cryptography/src/lib.rs @@ -26,7 +26,7 @@ //! | [`aead`](https://docs.rs/aead) | `aead` | Authenticated Encryption with Associated Data (i.e. high-level symmetric encryption) | //! | [`block_cipher`](https://docs.rs/block-cipher) | `block‑cipher` | Block-based cryptographic permutations (i.e. low-level symmetric encryption) | //! | [`digest`](https://docs.rs/digest) | `digest` | Cryptographic hash functions | -//! | [`elliptic-curve`](https://docs.rs/elliptic-curve) | `elliptic-curve` | Elliptic curve cryptography | +//! | [`elliptic_curve`](https://docs.rs/elliptic-curve) | `elliptic-curve` | Elliptic curve cryptography | //! | [`mac`](https://docs.rs/crypto-mac) | `mac` | Message Authentication Codes (i.e. symmetric message authentication) | //! | [`signature`](https://docs.rs/signature) | `signature` | Digital signatures (i.e. public key-based message authentication) | //! | [`stream_cipher`](https://docs.rs/stream-cipher) | `stream‑cipher` | Ciphers based on randomly generated keystreams (i.e. low-level symmetric encryption) | From e6755825667f13b4c8d3f1d06b5385131a091551 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Wed, 12 Aug 2020 03:07:28 +0300 Subject: [PATCH 0200/1461] crypto-mac: re-export block-cipher (#257) --- Cargo.lock | 2 +- crypto-mac/CHANGELOG.md | 6 ++++++ crypto-mac/Cargo.toml | 2 +- crypto-mac/src/lib.rs | 2 ++ 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1b50861e8..268eda7e0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -84,7 +84,7 @@ checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634" [[package]] name = "crypto-mac" -version = "0.9.0" +version = "0.9.1" dependencies = [ "blobby 0.3.0", "block-cipher 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/crypto-mac/CHANGELOG.md b/crypto-mac/CHANGELOG.md index 867676934..0ed42e3dd 100644 --- a/crypto-mac/CHANGELOG.md +++ b/crypto-mac/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.9.1 (2020-08-12) +### Added +- Re-export the `block-cipher` crate ([#257]) + +[#257]: https://github.com/RustCrypto/traits/pull/257 + ## 0.9.0 (2020-08-10) ### Added - `FromBlockCipher` trait and blanket implementation of the `NewMac` trait diff --git a/crypto-mac/Cargo.toml b/crypto-mac/Cargo.toml index b8350c22e..b1013c0ad 100644 --- a/crypto-mac/Cargo.toml +++ b/crypto-mac/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crypto-mac" description = "Trait for Message Authentication Code (MAC) algorithms" -version = "0.9.0" +version = "0.9.1" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/crypto-mac/src/lib.rs b/crypto-mac/src/lib.rs index a4b6e8f77..b4174fbab 100644 --- a/crypto-mac/src/lib.rs +++ b/crypto-mac/src/lib.rs @@ -12,6 +12,8 @@ #[cfg(feature = "std")] extern crate std; +#[cfg(feature = "block-cipher")] +pub use block_cipher; #[cfg(feature = "block-cipher")] use block_cipher::{BlockCipher, NewBlockCipher}; From f3ab35e5e672152e1f21e43c65b8064923b9905a Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 21 Aug 2020 09:55:24 -0700 Subject: [PATCH 0201/1461] elliptic-curve: refactor `PublicKey` into `sec1::EncodedPoint` (#264) elliptic-curve: refactor `PublicKey` into `sec1::EncodedPoint` Moves the type for SEC1 encoded points to `sec1::EncodedPoint`, which both much more precisely describes what it represents, but also moves it out-of-the-way so we can add a better `PublicKey` type (e.g. one which is or wraps an `AffinePoint` in crates which have a curve arithmetic implementation). It also changes `sec1::EncodedPoint` to be backed by a byte slice which is always the size of a SEC1 encoded uncompressed point, eliminating the previous `CompressedPoint` and `UncompressedPoint` types. This type can still contain a SEC1-encoded compressed point, sliced to the proper size via the `as_bytes()` method. This allows for simplified trait bounds as we no longer need to care about `CompressedPointSize` in the bounds. --- Cargo.lock | 1 + elliptic-curve/Cargo.toml | 3 + elliptic-curve/src/ecdh.rs | 64 +-- elliptic-curve/src/lib.rs | 5 +- elliptic-curve/src/sec1.rs | 451 +++++++++++++++++++ elliptic-curve/src/weierstrass.rs | 8 - elliptic-curve/src/weierstrass/point.rs | 254 ----------- elliptic-curve/src/weierstrass/public_key.rs | 239 ---------- 8 files changed, 484 insertions(+), 541 deletions(-) create mode 100644 elliptic-curve/src/sec1.rs delete mode 100644 elliptic-curve/src/weierstrass/point.rs delete mode 100644 elliptic-curve/src/weierstrass/public_key.rs diff --git a/Cargo.lock b/Cargo.lock index 268eda7e0..f2928efb2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -129,6 +129,7 @@ version = "0.5.0" dependencies = [ "const-oid", "generic-array 0.14.4", + "hex-literal", "rand_core", "subtle", "zeroize", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 16ba4e4b5..40f664562 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -21,6 +21,9 @@ rand_core = { version = "0.5", optional = true, default-features = false } subtle = { version = "2.2", default-features = false } zeroize = { version = "1", optional = true, default-features = false } +[dev-dependencies] +hex-literal = "0.2" + [features] default = ["rand"] ecdh = ["rand", "weierstrass", "zeroize"] diff --git a/elliptic-curve/src/ecdh.rs b/elliptic-curve/src/ecdh.rs index d604ddbbc..a7216a2aa 100644 --- a/elliptic-curve/src/ecdh.rs +++ b/elliptic-curve/src/ecdh.rs @@ -7,8 +7,8 @@ //! # Usage //! //! Have each participant generate an [`EphemeralSecret`] value, compute the -//! [`PublicKey`] for that value, exchange public keys, then each participant -//! uses their [`EphemeralSecret`] and the other participant's [`PublicKey`] +//! [`EncodedPoint`] for that value, exchange public keys, then each participant +//! uses their [`EphemeralSecret`] and the other participant's [`EncodedPoint`] //! to compute a [`SharedSecret`] value. //! //! # ⚠️ SECURITY WARNING ⚠️ @@ -22,20 +22,22 @@ use crate::{ consts::U1, + generic_array::ArrayLength, point::Generator, scalar::NonZeroScalar, - weierstrass::{ - point::{CompressedPoint, CompressedPointSize, UncompressedPoint, UncompressedPointSize}, - public_key::{FromPublicKey, PublicKey}, - Curve, - }, + sec1::{self, FromEncodedPoint, UncompressedPointSize, UntaggedPointSize}, + weierstrass::Curve, Arithmetic, ElementBytes, Error, Generate, }; use core::ops::{Add, Mul}; -use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; use rand_core::{CryptoRng, RngCore}; use zeroize::Zeroize; +/// Elliptic Curve Diffie-Hellman public keys. +/// +/// These are SEC1-encoded elliptic curve points. +pub type PublicKey = sec1::EncodedPoint; + /// Ephemeral Diffie-Hellman Secret. /// /// These are ephemeral "secret key" values which are deliberately designed @@ -52,12 +54,9 @@ impl EphemeralSecret where C: Curve + Arithmetic, C::Scalar: Clone + Generate + Zeroize, - C::AffinePoint: FromPublicKey + Mul, Output = C::AffinePoint> + Zeroize, - C::ElementSize: Add, - ::Output: Add, - CompressedPoint: From, - UncompressedPoint: From, - CompressedPointSize: ArrayLength, + C::AffinePoint: FromEncodedPoint + Mul, Output = C::AffinePoint> + Zeroize, + PublicKey: From, + UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { /// Generate a new [`EphemeralSecret`]. @@ -70,20 +69,14 @@ where /// Get the public key associated with this ephemeral secret. /// /// The `compress` flag enables point compression. - pub fn public_key(&self, compress: bool) -> PublicKey { - let affine_point = C::AffinePoint::generator() * self.scalar.clone(); - - if compress { - PublicKey::Compressed(affine_point.into()) - } else { - PublicKey::Uncompressed(affine_point.into()) - } + pub fn public_key(&self) -> PublicKey { + PublicKey::from(C::AffinePoint::generator() * self.scalar.clone()) } /// Compute a Diffie-Hellman shared secret from an ephemeral secret and the - /// [`PublicKey`] of the other participant in the exchange. + /// public key of the other participant in the exchange. pub fn diffie_hellman(&self, public_key: &PublicKey) -> Result, Error> { - let affine_point = C::AffinePoint::from_public_key(public_key); + let affine_point = C::AffinePoint::from_encoded_point(public_key); if affine_point.is_some().into() { let shared_secret = affine_point.unwrap() * self.scalar.clone(); @@ -98,16 +91,13 @@ impl From<&EphemeralSecret> for PublicKey where C: Curve + Arithmetic, C::Scalar: Clone + Generate + Zeroize, - C::AffinePoint: FromPublicKey + Mul, Output = C::AffinePoint> + Zeroize, - C::ElementSize: Add, - ::Output: Add, - CompressedPoint: From, - UncompressedPoint: From, - CompressedPointSize: ArrayLength, + C::AffinePoint: FromEncodedPoint + Mul, Output = C::AffinePoint> + Zeroize, + PublicKey: From, + UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { fn from(ephemeral_secret: &EphemeralSecret) -> Self { - ephemeral_secret.public_key(C::COMPRESS_POINTS) + ephemeral_secret.public_key() } } @@ -153,17 +143,13 @@ impl SharedSecret where C: Curve + Arithmetic, C::AffinePoint: Zeroize, - C::ElementSize: Add, - ::Output: Add, + UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { /// Create a new shared secret from the given uncompressed curve point - fn new(mut serialized_point: UncompressedPoint) -> Self { - let secret_bytes = GenericArray::clone_from_slice( - &serialized_point.as_ref()[1..(1 + C::ElementSize::to_usize())], - ); - - serialized_point.zeroize(); + fn new(mut encoded_point: sec1::EncodedPoint) -> Self { + let secret_bytes = encoded_point.x().clone(); + encoded_point.zeroize(); Self { secret_bytes } } diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 1c3c6b227..6e154cab2 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -32,7 +32,10 @@ pub mod secret_key; #[cfg_attr(docsrs, doc(cfg(feature = "ecdh")))] pub mod ecdh; -// TODO(tarcieri): other curve forms +#[cfg(feature = "weierstrass")] +#[cfg_attr(docsrs, doc(cfg(feature = "weierstrass")))] +pub mod sec1; + #[cfg(feature = "weierstrass")] #[cfg_attr(docsrs, doc(cfg(feature = "weierstrass")))] pub mod weierstrass; diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs new file mode 100644 index 000000000..af54fffef --- /dev/null +++ b/elliptic-curve/src/sec1.rs @@ -0,0 +1,451 @@ +//! SEC1 encoding support. +//! +//! Support for the `Elliptic-Curve-Point-to-Octet-String` encoding described +//! in SEC1: Elliptic Curve Cryptography (Version 2.0) section 2.3.3 (p.10): +//! +//! + +use crate::ElementBytes; +use crate::{weierstrass::Curve, Error}; +use core::{ + fmt::{self, Debug}, + ops::Add, +}; +use generic_array::{ + typenum::{Unsigned, U1}, + ArrayLength, GenericArray, +}; +use subtle::CtOption; + +#[cfg(feature = "zeroize")] +use zeroize::Zeroize; + +/// Size of a compressed point for the given elliptic curve when encoded +/// using the SEC1 `Elliptic-Curve-Point-to-Octet-String` algorithm +/// (including leading `0x02` or `0x03` tag byte). +pub type CompressedPointSize = <::ElementSize as Add>::Output; + +/// Size of an uncompressed point for the given elliptic curve when encoded +/// using the SEC1 `Elliptic-Curve-Point-to-Octet-String` algorithm +/// (including leading `0x04` tag byte). +pub type UncompressedPointSize = as Add>::Output; + +/// Size of an untagged point for given elliptic curve. +pub type UntaggedPointSize = <::ElementSize as Add>::Output; + +/// SEC1 encoded curve point. +/// +/// This type is an enum over the compressed and uncompressed encodings, +/// useful for cases where either encoding can be supported, or conversions +/// between the two forms. +#[derive(Clone, Eq, PartialEq, PartialOrd, Ord)] +pub struct EncodedPoint +where + C: Curve, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + bytes: GenericArray>, +} + +#[allow(clippy::len_without_is_empty)] +impl EncodedPoint +where + C: Curve, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + /// Decode elliptic curve point (compressed or uncompressed) from the + /// `Elliptic-Curve-Point-to-Octet-String` encoding described in + /// SEC 1: Elliptic Curve Cryptography (Version 2.0) section + /// 2.3.3 (page 10). + /// + /// + pub fn from_bytes(input: impl AsRef<[u8]>) -> Result { + let input = input.as_ref(); + + // Validate tag + let tag = input.first().cloned().ok_or(Error).and_then(Tag::from_u8)?; + + // Validate length + let expected_len = tag.message_len(C::ElementSize::to_usize()); + + if input.len() != expected_len { + return Err(Error); + } + + let mut bytes = GenericArray::default(); + bytes[..expected_len].copy_from_slice(input); + Ok(Self { bytes }) + } + + /// Decode elliptic curve point from raw uncompressed coordinates, i.e. + /// encoded as the concatenated `x || y` coordinates with no leading SEC1 + /// tag byte (which would otherwise be `0x04` for an uncompressed point). + pub fn from_untagged_bytes(bytes: &GenericArray>) -> Self { + let (x, y) = bytes.split_at(C::ElementSize::to_usize()); + Self::from_affine_coords(x.into(), y.into(), false) + } + + /// Encode an elliptic curve point from big endian serialized coordinates + /// (with optional point compression) + pub fn from_affine_coords(x: &ElementBytes, y: &ElementBytes, compress: bool) -> Self { + let tag = if compress { + Tag::compress_y(y.as_slice()) + } else { + Tag::Uncompressed + }; + + let mut bytes = GenericArray::default(); + bytes[0] = tag.into(); + + let element_size = C::ElementSize::to_usize(); + bytes[1..(element_size + 1)].copy_from_slice(x); + + if !compress { + bytes[(element_size + 1)..].copy_from_slice(y); + } + + Self { bytes } + } + + /// Is this [`EncodedPoint`] compressed? + pub fn is_compressed(&self) -> bool { + self.tag().is_compressed() + } + + /// Get the length of the encoded point in bytes + pub fn len(&self) -> usize { + self.tag().message_len(C::ElementSize::to_usize()) + } + + /// Get byte slice containing the serialized [`EncodedPoint`]. + #[inline] + pub fn as_bytes(&self) -> &[u8] { + &self.bytes[..self.len()] + } + + /// Compress this [`EncodedPoint`], returning a new [`EncodedPoint`]. + pub fn compress(&self) -> Self { + if self.tag().is_compressed() { + self.clone() + } else { + Self::from_affine_coords(self.x(), self.y().unwrap(), true) + } + } + + /// Decode this [`EncodedPoint`] into the desired type + pub fn decode(&self) -> CtOption + where + T: FromEncodedPoint, + { + T::from_encoded_point(self) + } + + /// Get the x-coordinate for this [`EncodedPoint`] + #[cfg(feature = "ecdh")] + pub(crate) fn x(&self) -> &ElementBytes { + self.coordinates().0 + } + + /// Get the y-coordinate for this [`EncodedPoint`]. + /// + /// Returns `None` if this point is compressed. + fn y(&self) -> Option<&ElementBytes> { + self.coordinates().1 + } + + /// Get the coordinates for this [`EncodedPoint`] as a pair + #[inline] + fn coordinates(&self) -> (&ElementBytes, Option<&ElementBytes>) { + let (x, y) = self.bytes[1..].split_at(C::ElementSize::to_usize()); + + if self.is_compressed() { + (x.into(), None) + } else { + (x.into(), Some(y.into())) + } + } + + /// Get the SEC1 tag for this [`EncodedPoint`] + fn tag(&self) -> Tag { + // Tag is ensured valid by the constructor + Tag::from_u8(self.bytes[0]).expect("invalid tag") + } +} + +impl AsRef<[u8]> for EncodedPoint +where + C: Curve, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + #[inline] + fn as_ref(&self) -> &[u8] { + self.as_bytes() + } +} + +impl Copy for EncodedPoint +where + C: Curve, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, + as ArrayLength>::ArrayType: Copy, +{ +} + +impl Debug for EncodedPoint +where + C: Curve, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "EncodedPoint<{:?}>({:?})", C::default(), &self.bytes) + } +} + +#[cfg(feature = "zeroize")] +impl Zeroize for EncodedPoint +where + C: Curve, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + fn zeroize(&mut self) { + self.bytes.zeroize() + } +} + +/// Trait for deserializing a value from a SEC1 encoded curve point. +/// +/// This is intended for use with the `AffinePoint` type for a given elliptic curve. +pub trait FromEncodedPoint +where + C: Curve, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, + Self: Sized, +{ + /// Deserialize the type this trait is impl'd on from an [`EncodedPoint`]. + /// + /// # Returns + /// + /// `None` if the [`EncodedPoint`] is invalid. + fn from_encoded_point(public_key: &EncodedPoint) -> CtOption; +} + +/// Trait for serializing a value to a SEC1 encoded curve point. +/// +/// This is intended for use with the `AffinePoint` type for a given elliptic curve. +pub trait ToEncodedPoint +where + C: Curve, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + /// Serialize this value as a SEC1 [`EncodedPoint`], optionally applying + /// point compression. + fn to_encoded_point(&self, compress: bool) -> EncodedPoint; +} + +/// Tag byte used by the `Elliptic-Curve-Point-to-Octet-String` encoding. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[repr(u8)] +enum Tag { + /// Compressed point with even y-coordinate + CompressedEvenY = 2, + + /// Compressed point with odd y-coordinate + CompressedOddY = 3, + + /// Uncompressed point + Uncompressed = 4, +} + +impl Tag { + /// Parse a tag value from a byte + pub fn from_u8(byte: u8) -> Result { + match byte { + 2 => Ok(Tag::CompressedEvenY), + 3 => Ok(Tag::CompressedOddY), + 4 => Ok(Tag::Uncompressed), + _ => Err(Error), + } + } + + /// Compress the given y-coordinate, returning a `Tag::Compressed*` value + pub fn compress_y(y: &[u8]) -> Self { + debug_assert!(!y.is_empty()); + + // Is the y-coordinate odd in the SEC1 sense: `self mod 2 == 1`? + if y.as_ref().last().unwrap() & 1 == 1 { + Tag::CompressedOddY + } else { + Tag::CompressedEvenY + } + } + + /// Is this point compressed? + pub fn is_compressed(self) -> bool { + match self { + Tag::CompressedEvenY | Tag::CompressedOddY => true, + Tag::Uncompressed => false, + } + } + + /// Compute the expected total message length for a message prefixed + /// with this tag (including the tag byte), given the field element size + /// (in bytes) for a particular elliptic curve. + pub fn message_len(self, field_element_size: usize) -> usize { + 1 + if self.is_compressed() { + field_element_size + } else { + field_element_size * 2 + } + } +} + +impl From for u8 { + fn from(tag: Tag) -> u8 { + tag as u8 + } +} + +#[cfg(test)] +mod tests { + use super::Tag; + use crate::{weierstrass, Curve}; + use generic_array::{typenum::U32, GenericArray}; + use hex_literal::hex; + + #[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Ord)] + struct ExampleCurve; + + impl Curve for ExampleCurve { + type ElementSize = U32; + } + + impl weierstrass::Curve for ExampleCurve { + const COMPRESS_POINTS: bool = false; + } + + type EncodedPoint = super::EncodedPoint; + + /// Example uncompressed point + const UNCOMPRESSED_BYTES: [u8; 65] = hex!("0411111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222"); + + /// Example compressed point: `UNCOMPRESSED_BYTES` after point compression + const COMPRESSED_BYTES: [u8; 33] = + hex!("021111111111111111111111111111111111111111111111111111111111111111"); + + #[test] + fn decode_compressed_point() { + // Even y-coordinate + let compressed_even_y_bytes = + hex!("020100000000000000000000000000000000000000000000000000000000000000"); + + let compressed_even_y = EncodedPoint::from_bytes(&compressed_even_y_bytes[..]).unwrap(); + + assert!(compressed_even_y.is_compressed()); + assert_eq!(compressed_even_y.tag(), Tag::CompressedEvenY); + assert_eq!( + compressed_even_y.x(), + &hex!("0100000000000000000000000000000000000000000000000000000000000000").into() + ); + assert_eq!(compressed_even_y.y(), None); + assert_eq!(compressed_even_y.len(), 33); + assert_eq!(compressed_even_y.as_bytes(), &compressed_even_y_bytes[..]); + + // Odd y-coordinate + let compressed_odd_y_bytes = + hex!("030200000000000000000000000000000000000000000000000000000000000000"); + + let compressed_odd_y = EncodedPoint::from_bytes(&compressed_odd_y_bytes[..]).unwrap(); + + assert!(compressed_odd_y.is_compressed()); + assert_eq!(compressed_odd_y.tag(), Tag::CompressedOddY); + assert_eq!( + compressed_odd_y.x(), + &hex!("0200000000000000000000000000000000000000000000000000000000000000").into() + ); + assert_eq!(compressed_odd_y.y(), None); + assert_eq!(compressed_odd_y.len(), 33); + assert_eq!(compressed_odd_y.as_bytes(), &compressed_odd_y_bytes[..]); + } + + #[test] + fn decode_uncompressed_point() { + let uncompressed_point = EncodedPoint::from_bytes(&UNCOMPRESSED_BYTES[..]).unwrap(); + + assert!(!uncompressed_point.is_compressed()); + assert_eq!(uncompressed_point.tag(), Tag::Uncompressed); + assert_eq!( + uncompressed_point.x(), + &hex!("1111111111111111111111111111111111111111111111111111111111111111").into() + ); + assert_eq!( + uncompressed_point.y().unwrap(), + &hex!("2222222222222222222222222222222222222222222222222222222222222222").into() + ); + assert_eq!(uncompressed_point.len(), 65); + assert_eq!(uncompressed_point.as_bytes(), &UNCOMPRESSED_BYTES[..]); + } + + #[test] + fn decode_invalid_tag() { + let mut compressed_bytes = COMPRESSED_BYTES.clone(); + let mut uncompressed_bytes = UNCOMPRESSED_BYTES.clone(); + + for bytes in &mut [&mut compressed_bytes[..], &mut uncompressed_bytes[..]] { + for tag in 0..=0xFF { + // valid tags + if tag == 2 || tag == 3 || tag == 4 { + continue; + } + + (*bytes)[0] = tag; + let decode_result = EncodedPoint::from_bytes(&*bytes); + assert!(decode_result.is_err()); + } + } + } + + #[test] + fn decode_truncated_point() { + for bytes in &[&COMPRESSED_BYTES[..], &UNCOMPRESSED_BYTES[..]] { + for len in 0..bytes.len() { + let decode_result = EncodedPoint::from_bytes(&bytes[..len]); + assert!(decode_result.is_err()); + } + } + } + + #[test] + fn from_untagged_point() { + let untagged_bytes = hex!("11111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222"); + let uncompressed_point = + EncodedPoint::from_untagged_bytes(GenericArray::from_slice(&untagged_bytes[..])); + assert_eq!(uncompressed_point.as_bytes(), &UNCOMPRESSED_BYTES[..]); + } + + #[test] + fn from_affine_coords() { + let x = hex!("1111111111111111111111111111111111111111111111111111111111111111"); + let y = hex!("2222222222222222222222222222222222222222222222222222222222222222"); + + let uncompressed_point = EncodedPoint::from_affine_coords(&x.into(), &y.into(), false); + assert_eq!(uncompressed_point.as_bytes(), &UNCOMPRESSED_BYTES[..]); + + let compressed_point = EncodedPoint::from_affine_coords(&x.into(), &y.into(), true); + assert_eq!(compressed_point.as_bytes(), &COMPRESSED_BYTES[..]); + } + + #[test] + fn compress() { + let uncompressed_point = EncodedPoint::from_bytes(&UNCOMPRESSED_BYTES[..]).unwrap(); + let compressed_point = uncompressed_point.compress(); + assert_eq!(compressed_point.as_bytes(), &COMPRESSED_BYTES[..]); + } +} diff --git a/elliptic-curve/src/weierstrass.rs b/elliptic-curve/src/weierstrass.rs index 2858176b8..bb095bae2 100644 --- a/elliptic-curve/src/weierstrass.rs +++ b/elliptic-curve/src/weierstrass.rs @@ -1,13 +1,5 @@ //! Elliptic curves in short Weierstrass form. -pub mod point; -pub mod public_key; - -pub use self::{ - point::{CompressedPoint, CompressedPointSize, UncompressedPoint, UncompressedPointSize}, - public_key::PublicKey, -}; - /// Marker trait for elliptic curves in short Weierstrass form pub trait Curve: super::Curve { /// Should point compression be applied by default? diff --git a/elliptic-curve/src/weierstrass/point.rs b/elliptic-curve/src/weierstrass/point.rs deleted file mode 100644 index e2b563eb0..000000000 --- a/elliptic-curve/src/weierstrass/point.rs +++ /dev/null @@ -1,254 +0,0 @@ -//! Compressed and uncompressed Weierstrass elliptic curve points. -//! -//! Serialized according to the `Elliptic-Curve-Point-to-Octet-String` -//! algorithm described in SEC 1: Elliptic Curve Cryptography (Version 2.0) -//! section 2.3.3 (page 10): -//! -//! - -use super::Curve; -use crate::ElementBytes; -use core::ops::Add; -use generic_array::{ - typenum::{Unsigned, U1}, - ArrayLength, GenericArray, -}; - -#[cfg(feature = "zeroize")] -use zeroize::Zeroize; - -/// Size of a compressed elliptic curve point for the given curve when -/// serialized using `Elliptic-Curve-Point-to-Octet-String` encoding -/// (including leading `0x02` or `0x03` tag byte). -pub type CompressedPointSize = <::ElementSize as Add>::Output; - -/// Size of an uncompressed elliptic curve point for the given curve when -/// serialized using the `Elliptic-Curve-Point-to-Octet-String` encoding -/// (including leading `0x04` tag byte). -pub type UncompressedPointSize = - <<::ElementSize as Add>::Output as Add>::Output; - -/// Compressed elliptic curve points serialized according to the -/// `Elliptic-Curve-Point-to-Octet-String` algorithm. -/// -/// See section 2.3.3 of SEC 1: Elliptic Curve Cryptography (Version 2.0): -/// -/// -#[derive(Eq, Hash, PartialEq, PartialOrd, Ord)] -pub struct CompressedPoint -where - C: Curve, - C::ElementSize: Add, - CompressedPointSize: ArrayLength, -{ - /// Raw serialized bytes of the compressed point - bytes: GenericArray>, -} - -impl CompressedPoint -where - C: Curve, - C::ElementSize: Add, - CompressedPointSize: ArrayLength, -{ - /// Compress and serialize an elliptic curve point from its affine coordinates - pub fn from_affine_coords(x: &ElementBytes, y: &ElementBytes) -> Self { - // Is the y-coordinate odd in the SEC-1 sense: `self mod 2 == 1`? - let is_y_odd = y.as_ref().last().expect("last byte") & 1 == 1; - let mut bytes = GenericArray::default(); - bytes[0] = if is_y_odd { 0x03 } else { 0x02 }; - bytes[1..].copy_from_slice(x); - Self { bytes } - } - - /// Create a new compressed elliptic curve point - pub fn from_bytes(into_bytes: B) -> Option - where - B: Into>>, - { - let bytes = into_bytes.into(); - - match bytes[0] { - 0x02 | 0x03 => Some(Self { bytes }), - _ => None, - } - } - - /// Borrow byte slice containing compressed curve point - #[inline] - pub fn as_bytes(&self) -> &[u8] { - &self.bytes - } - - /// Obtain owned array containing compressed curve point - #[inline] - pub fn into_bytes(self) -> GenericArray> { - self.bytes - } -} - -impl AsRef<[u8]> for CompressedPoint -where - C: Curve, - C::ElementSize: Add, - CompressedPointSize: ArrayLength, -{ - #[inline] - fn as_ref(&self) -> &[u8] { - self.bytes.as_ref() - } -} - -impl Copy for CompressedPoint -where - C::ElementSize: Add, - CompressedPointSize: ArrayLength, - as ArrayLength>::ArrayType: Copy, -{ -} - -impl Clone for CompressedPoint -where - C: Curve, - C::ElementSize: Add, - CompressedPointSize: ArrayLength, -{ - fn clone(&self) -> Self { - Self { - bytes: self.bytes.clone(), - } - } -} - -#[cfg(feature = "zeroize")] -impl Zeroize for CompressedPoint -where - C: Curve, - C::ElementSize: Add, - CompressedPointSize: ArrayLength, -{ - fn zeroize(&mut self) { - self.bytes.zeroize() - } -} - -/// Uncompressed elliptic curve points serialized according to the -/// `Elliptic-Curve-Point-to-Octet-String` algorithm. -/// -/// See section 2.3.3 of SEC 1: Elliptic Curve Cryptography (Version 2.0): -/// -/// -#[derive(Eq, Hash, PartialEq, PartialOrd, Ord)] -pub struct UncompressedPoint -where - C::ElementSize: Add, - ::Output: Add, - UncompressedPointSize: ArrayLength, -{ - /// Raw serialized bytes of the uncompressed point - bytes: GenericArray>, -} - -impl UncompressedPoint -where - C: Curve, - C::ElementSize: Add, - ::Output: Add, - UncompressedPointSize: ArrayLength, -{ - /// Serialize an elliptic curve point from its affine coordinates - pub fn from_affine_coords(x: &ElementBytes, y: &ElementBytes) -> Self { - let scalar_size = C::ElementSize::to_usize(); - let mut bytes = GenericArray::default(); - bytes[0] = 0x04; - bytes[1..(scalar_size + 1)].copy_from_slice(x); - bytes[(scalar_size + 1)..].copy_from_slice(y); - Self { bytes } - } - - /// Create a new uncompressed elliptic curve point - pub fn from_bytes(into_bytes: B) -> Option - where - B: Into>>, - { - let bytes = into_bytes.into(); - - if bytes.get(0) == Some(&0x04) { - Some(Self { bytes }) - } else { - None - } - } - - /// Borrow byte slice containing uncompressed curve point - #[inline] - pub fn as_bytes(&self) -> &[u8] { - &self.bytes - } - - /// Convert public key into owned byte array - #[inline] - pub fn into_bytes(self) -> GenericArray> { - self.bytes - } - - /// Get the x-coordinate of this curve point - pub(crate) fn x(&self) -> &ElementBytes { - GenericArray::from_slice(&self.bytes[1..(C::ElementSize::to_usize() + 1)]) - } - - /// Get the y-coordinate of this curve point - pub(crate) fn y(&self) -> &ElementBytes { - GenericArray::from_slice(&self.bytes[(C::ElementSize::to_usize() + 1)..]) - } -} - -impl AsRef<[u8]> for UncompressedPoint -where - C: Curve, - C::ElementSize: Add, - ::Output: Add, - UncompressedPointSize: ArrayLength, -{ - #[inline] - fn as_ref(&self) -> &[u8] { - self.bytes.as_ref() - } -} - -impl Copy for UncompressedPoint -where - C: Curve, - C::ElementSize: Add, - ::Output: Add, - UncompressedPointSize: ArrayLength, - as ArrayLength>::ArrayType: Copy, -{ -} - -impl Clone for UncompressedPoint -where - C: Curve, - C::ElementSize: Add, - ::Output: Add, - UncompressedPointSize: ArrayLength, -{ - fn clone(&self) -> Self { - Self { - bytes: self.bytes.clone(), - } - } -} - -#[cfg(feature = "zeroize")] -impl Zeroize for UncompressedPoint -where - C: Curve, - C::ElementSize: Add, - ::Output: Add, - UncompressedPointSize: ArrayLength, -{ - fn zeroize(&mut self) { - self.bytes.zeroize() - } -} diff --git a/elliptic-curve/src/weierstrass/public_key.rs b/elliptic-curve/src/weierstrass/public_key.rs deleted file mode 100644 index 94614e507..000000000 --- a/elliptic-curve/src/weierstrass/public_key.rs +++ /dev/null @@ -1,239 +0,0 @@ -//! Public keys for Weierstrass curves: wrapper around compressed or -//! uncompressed elliptic curve points. - -use super::{ - point::{CompressedPoint, CompressedPointSize, UncompressedPoint, UncompressedPointSize}, - Curve, -}; -use crate::{point::Generator, scalar::NonZeroScalar, Arithmetic, Error, FromBytes, SecretKey}; -use core::{ - convert::TryFrom, - fmt::{self, Debug}, - ops::{Add, Mul}, -}; -use generic_array::{ - typenum::{Unsigned, U1}, - ArrayLength, GenericArray, -}; -use subtle::CtOption; - -/// Size of an untagged point for given elliptic curve. -pub type UntaggedPointSize = <::ElementSize as Add>::Output; - -/// Public keys for Weierstrass curves -#[derive(Clone, Eq, PartialEq, PartialOrd, Ord)] -pub enum PublicKey -where - C: Curve, - C::ElementSize: Add, - ::Output: Add, - CompressedPointSize: ArrayLength, - UncompressedPointSize: ArrayLength, -{ - /// Compressed Weierstrass elliptic curve point - Compressed(CompressedPoint), - - /// Uncompressed Weierstrass elliptic curve point - Uncompressed(UncompressedPoint), -} - -impl PublicKey -where - C: Curve, - C::ElementSize: Add, - ::Output: Add, - CompressedPointSize: ArrayLength, - UncompressedPointSize: ArrayLength, -{ - /// Decode public key from an elliptic curve point - /// (compressed or uncompressed) encoded using the - /// `Elliptic-Curve-Point-to-Octet-String` algorithm described in - /// SEC 1: Elliptic Curve Cryptography (Version 2.0) section - /// 2.3.3 (page 10). - /// - /// - pub fn from_bytes(bytes: impl AsRef<[u8]>) -> Option { - let slice = bytes.as_ref(); - let length = slice.len(); - - if length == >::to_usize() { - let array = GenericArray::clone_from_slice(slice); - let point = CompressedPoint::from_bytes(array)?; - Some(PublicKey::Compressed(point)) - } else if length == >::to_usize() { - let array = GenericArray::clone_from_slice(slice); - let point = UncompressedPoint::from_bytes(array)?; - Some(PublicKey::Uncompressed(point)) - } else { - None - } - } - - /// Decode public key from a raw uncompressed point serialized - /// as a bytestring, without a `0x04`-byte tag. - /// - /// This will be twice the modulus size, or 1-byte smaller than the - /// `Elliptic-Curve-Point-to-Octet-String` encoding i.e - /// with the leading `0x04` byte in that encoding removed. - pub fn from_untagged_point(bytes: &GenericArray>) -> Self - where - ::Output: ArrayLength, - { - let mut tagged_bytes = GenericArray::default(); - tagged_bytes.as_mut_slice()[0] = 0x04; - tagged_bytes.as_mut_slice()[1..].copy_from_slice(bytes.as_ref()); - - PublicKey::Uncompressed(UncompressedPoint::from_bytes(tagged_bytes).unwrap()) - } - - /// Compress this [`PublicKey`]. - /// - /// If the key is already compressed, this is a no-op. - pub fn compress(&mut self) { - if let PublicKey::Uncompressed(point) = self { - *self = CompressedPoint::from_affine_coords(point.x(), point.y()).into(); - } - } - - /// Obtain public key as a byte array reference - #[inline] - pub fn as_bytes(&self) -> &[u8] { - match self { - PublicKey::Compressed(ref point) => point.as_bytes(), - PublicKey::Uncompressed(ref point) => point.as_bytes(), - } - } -} - -impl PublicKey -where - C: Curve + Arithmetic, - C::AffinePoint: Mul, Output = C::AffinePoint>, - C::ElementSize: Add, - ::Output: Add, - CompressedPoint: From, - UncompressedPoint: From, - CompressedPointSize: ArrayLength, - UncompressedPointSize: ArrayLength, -{ - /// Compute the [`PublicKey`] for the provided [`SecretKey`]. - /// - /// The `compress` flag requests point compression. - pub fn from_secret_key(secret_key: &SecretKey, compress: bool) -> Result { - let ct_option = C::Scalar::from_bytes(secret_key.as_bytes()).and_then(NonZeroScalar::new); - - if ct_option.is_none().into() { - return Err(Error); - } - - let affine_point = C::AffinePoint::generator() * ct_option.unwrap(); - - if compress { - Ok(PublicKey::Compressed(affine_point.into())) - } else { - Ok(PublicKey::Uncompressed(affine_point.into())) - } - } -} - -impl AsRef<[u8]> for PublicKey -where - C: Curve, - C::ElementSize: Add, - ::Output: Add, - CompressedPointSize: ArrayLength, - UncompressedPointSize: ArrayLength, -{ - #[inline] - fn as_ref(&self) -> &[u8] { - self.as_bytes() - } -} - -impl Copy for PublicKey -where - C: Curve, - C::ElementSize: Add, - ::Output: Add, - CompressedPointSize: ArrayLength, - UncompressedPointSize: ArrayLength, - as ArrayLength>::ArrayType: Copy, - as ArrayLength>::ArrayType: Copy, -{ -} - -impl Debug for PublicKey -where - C: Curve, - C::ElementSize: Add, - ::Output: Add, - CompressedPointSize: ArrayLength, - UncompressedPointSize: ArrayLength, -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "PublicKey<{:?}>({:?})", C::default(), self.as_ref()) - } -} - -impl TryFrom<&SecretKey> for PublicKey -where - C: Curve + Arithmetic, - C::AffinePoint: Mul, Output = C::AffinePoint>, - C::ElementSize: Add, - ::Output: Add, - CompressedPoint: From, - UncompressedPoint: From, - CompressedPointSize: ArrayLength, - UncompressedPointSize: ArrayLength, -{ - type Error = Error; - - fn try_from(secret_key: &SecretKey) -> Result { - Self::from_secret_key(secret_key, C::COMPRESS_POINTS) - } -} - -impl From> for PublicKey -where - C: Curve, - C::ElementSize: Add, - ::Output: Add, - CompressedPointSize: ArrayLength, - UncompressedPointSize: ArrayLength, -{ - fn from(point: CompressedPoint) -> Self { - PublicKey::Compressed(point) - } -} - -impl From> for PublicKey -where - C: Curve, - C::ElementSize: Add, - ::Output: Add, - CompressedPointSize: ArrayLength, - UncompressedPointSize: ArrayLength, -{ - fn from(point: UncompressedPoint) -> Self { - PublicKey::Uncompressed(point) - } -} - -/// Trait for deserializing a value from a public key. -/// -/// This is intended for use with the `AffinePoint` type for a given elliptic curve. -pub trait FromPublicKey: Sized -where - C: Curve, - C::ElementSize: Add, - ::Output: Add, - CompressedPointSize: ArrayLength, - UncompressedPointSize: ArrayLength, -{ - /// Deserialize this value from a [`PublicKey`] - /// - /// # Returns - /// - /// `None` if the public key is not on the curve. - fn from_public_key(public_key: &PublicKey) -> CtOption; -} From 9a05f8e8fc6c5ac9c31f6baed053f74badd40a52 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 21 Aug 2020 16:31:59 -0700 Subject: [PATCH 0202/1461] elliptic-curve: add `alloc` feature + EncodedPoint::to_bytes() (#265) Support serializing an `EncodedPoint` as a heap-allocated byte slice. --- elliptic-curve/Cargo.toml | 3 ++- elliptic-curve/src/ecdh.rs | 4 ++-- elliptic-curve/src/lib.rs | 3 +++ elliptic-curve/src/sec1.rs | 18 +++++++++++++++++- 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 40f664562..8422122eb 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -26,10 +26,11 @@ hex-literal = "0.2" [features] default = ["rand"] +alloc = [] ecdh = ["rand", "weierstrass", "zeroize"] rand = ["rand_core"] weierstrass = [] -std = [] +std = ["alloc"] [package.metadata.docs.rs] all-features = true diff --git a/elliptic-curve/src/ecdh.rs b/elliptic-curve/src/ecdh.rs index a7216a2aa..3f9867215 100644 --- a/elliptic-curve/src/ecdh.rs +++ b/elliptic-curve/src/ecdh.rs @@ -7,8 +7,8 @@ //! # Usage //! //! Have each participant generate an [`EphemeralSecret`] value, compute the -//! [`EncodedPoint`] for that value, exchange public keys, then each participant -//! uses their [`EphemeralSecret`] and the other participant's [`EncodedPoint`] +//! [`PublicKey'] for that value, exchange public keys, then each participant +//! uses their [`EphemeralSecret`] and the other participant's [`PublicKey`] //! to compute a [`SharedSecret`] value. //! //! # ⚠️ SECURITY WARNING ⚠️ diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 6e154cab2..e7c6c79e8 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -19,6 +19,9 @@ html_root_url = "https://docs.rs/elliptic-curve/0.5.0" )] +#[cfg(feature = "alloc")] +extern crate alloc; + #[cfg(feature = "std")] extern crate std; diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index af54fffef..ec596e8fc 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -17,6 +17,9 @@ use generic_array::{ }; use subtle::CtOption; +#[cfg(feature = "alloc")] +use alloc::boxed::Box; + #[cfg(feature = "zeroize")] use zeroize::Zeroize; @@ -120,11 +123,17 @@ where } /// Get byte slice containing the serialized [`EncodedPoint`]. - #[inline] pub fn as_bytes(&self) -> &[u8] { &self.bytes[..self.len()] } + /// Get boxed byte slice containing the serialized [`EncodedPoint`] + #[cfg(feature = "alloc")] + #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] + pub fn to_bytes(&self) -> Box<[u8]> { + self.as_bytes().to_vec().into_boxed_slice() + } + /// Compress this [`EncodedPoint`], returning a new [`EncodedPoint`]. pub fn compress(&self) -> Self { if self.tag().is_compressed() { @@ -448,4 +457,11 @@ mod tests { let compressed_point = uncompressed_point.compress(); assert_eq!(compressed_point.as_bytes(), &COMPRESSED_BYTES[..]); } + + #[cfg(feature = "alloc")] + #[test] + fn to_bytes() { + let uncompressed_point = EncodedPoint::from_bytes(&UNCOMPRESSED_BYTES[..]).unwrap(); + assert_eq!(&*uncompressed_point.to_bytes(), &UNCOMPRESSED_BYTES[..]); + } } From acfc369c77259c70ebc72601cc83684847ae499d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 23 Aug 2020 09:37:42 -0700 Subject: [PATCH 0203/1461] elliptic-curve: add weierstrass::point::Decompress trait (#266) Adds a trait for decompressing Weierstrass points from a big endian encoded affine x-coordinate and a flag indicating whether or not the y-coordinate is odd. --- elliptic-curve/src/weierstrass.rs | 2 ++ elliptic-curve/src/weierstrass/point.rs | 12 ++++++++++++ 2 files changed, 14 insertions(+) create mode 100644 elliptic-curve/src/weierstrass/point.rs diff --git a/elliptic-curve/src/weierstrass.rs b/elliptic-curve/src/weierstrass.rs index bb095bae2..c87a54ed2 100644 --- a/elliptic-curve/src/weierstrass.rs +++ b/elliptic-curve/src/weierstrass.rs @@ -1,5 +1,7 @@ //! Elliptic curves in short Weierstrass form. +pub mod point; + /// Marker trait for elliptic curves in short Weierstrass form pub trait Curve: super::Curve { /// Should point compression be applied by default? diff --git a/elliptic-curve/src/weierstrass/point.rs b/elliptic-curve/src/weierstrass/point.rs new file mode 100644 index 000000000..acb170035 --- /dev/null +++ b/elliptic-curve/src/weierstrass/point.rs @@ -0,0 +1,12 @@ +//! Traits for Weierstrass elliptic curve points + +use super::Curve; +use crate::ElementBytes; +use subtle::CtOption; + +/// Attempt to decompress an elliptic curve point from its x-coordinate and +/// a boolean flag indicating whether or not the y-coordinate is odd. +pub trait Decompress: Sized { + /// Attempt to decompress an elliptic curve point + fn decompress(x: &ElementBytes, y_is_odd: bool) -> CtOption; +} From 61464f528779d2231df69039a4d9a954d4091ad3 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 23 Aug 2020 11:05:56 -0700 Subject: [PATCH 0204/1461] elliptic-curve: don't conditionally define `EncodedPoint::x` (#267) This was causing compile errors when only the `weierstrass` feature was enabled. --- .github/workflows/elliptic-curve.yml | 1 + elliptic-curve/src/sec1.rs | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index 0a251428b..b25ddf1d2 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -51,5 +51,6 @@ jobs: toolchain: ${{ matrix.rust }} - run: cargo check --all-features - run: cargo test --no-default-features + - run: cargo test --no-default-features --features weierstrass - run: cargo test - run: cargo test --all-features diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index ec596e8fc..79afe6a6a 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -152,7 +152,6 @@ where } /// Get the x-coordinate for this [`EncodedPoint`] - #[cfg(feature = "ecdh")] pub(crate) fn x(&self) -> &ElementBytes { self.coordinates().0 } From eb93343b4ef3e3213bb5cfc284a71af8887f396c Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Tue, 25 Aug 2020 06:06:20 +0300 Subject: [PATCH 0205/1461] stream-cipher: SyncStreamCipherSeek rework, improve seek tests (#260) --- Cargo.lock | 2 +- cryptography/Cargo.toml | 2 +- stream-cipher/CHANGELOG.md | 9 ++++ stream-cipher/Cargo.toml | 2 +- stream-cipher/src/dev.rs | 61 ++++++++++++++---------- stream-cipher/src/errors.rs | 24 +++++++++- stream-cipher/src/lib.rs | 92 +++++++++++++++++++++++++++++++++---- 7 files changed, 153 insertions(+), 39 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f2928efb2..822d28a05 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -281,7 +281,7 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "stream-cipher" -version = "0.6.0" +version = "0.7.0" dependencies = [ "blobby 0.3.0", "block-cipher 0.8.0", diff --git a/cryptography/Cargo.toml b/cryptography/Cargo.toml index 892ffd38e..c7374fbf6 100644 --- a/cryptography/Cargo.toml +++ b/cryptography/Cargo.toml @@ -18,7 +18,7 @@ digest = { version = "0.9", optional = true, path = "../digest" } elliptic-curve = { version = "= 0.5", optional = true, path = "../elliptic-curve" } mac = { version = "0.9", package = "crypto-mac", optional = true, path = "../crypto-mac" } signature = { version = "1.1.0", optional = true, default-features = false, path = "../signature" } -stream-cipher = { version = "0.6", optional = true, path = "../stream-cipher" } +stream-cipher = { version = "0.7", optional = true, path = "../stream-cipher" } universal-hash = { version = "0.4", optional = true, path = "../universal-hash" } [package.metadata.docs.rs] diff --git a/stream-cipher/CHANGELOG.md b/stream-cipher/CHANGELOG.md index 5d947704c..39507603e 100644 --- a/stream-cipher/CHANGELOG.md +++ b/stream-cipher/CHANGELOG.md @@ -5,6 +5,15 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.7.0 (2020-08-25) +### Changed +- Rework of the `SyncStreamCipherSeek` trait, make methods generic over +numeric types, add fallable `try_seek` and `try_current_pos` methods ([#260]) +- Rework macro for generating seek tests, re-export `blobby` at top-level, +remove the `dev` module from public API ([#260]) + +[#260]: https://github.com/RustCrypto/traits/pull/260 + ## 0.6.0 (2020-07-10) ### Changed - Add blanket implementation for `&mut SyncCtreamCipher` ([#210]) diff --git a/stream-cipher/Cargo.toml b/stream-cipher/Cargo.toml index fd5e77799..8371fef24 100644 --- a/stream-cipher/Cargo.toml +++ b/stream-cipher/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "stream-cipher" description = "Stream cipher traits" -version = "0.6.0" +version = "0.7.0" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/stream-cipher/src/dev.rs b/stream-cipher/src/dev.rs index 741cf3005..d5b877f0d 100644 --- a/stream-cipher/src/dev.rs +++ b/stream-cipher/src/dev.rs @@ -1,7 +1,5 @@ //! Development-related functionality -pub use blobby; - /// Test core functionality of synchronous stream cipher #[macro_export] #[cfg_attr(docsrs, doc(cfg(feature = "dev")))] @@ -9,7 +7,7 @@ macro_rules! new_sync_test { ($name:ident, $cipher:ty, $test_name:expr) => { #[test] fn $name() { - use stream_cipher::dev::blobby::Blob4Iterator; + use stream_cipher::blobby::Blob4Iterator; use stream_cipher::generic_array::GenericArray; use stream_cipher::{NewStreamCipher, SyncStreamCipher}; @@ -43,37 +41,50 @@ macro_rules! new_sync_test { #[macro_export] #[cfg_attr(docsrs, doc(cfg(feature = "dev")))] macro_rules! new_seek_test { - ($name:ident, $cipher:ty, $test_name:expr) => { + ($name:ident, $cipher:ty) => { #[test] fn $name() { - use stream_cipher::dev::blobby::Blob4Iterator; use stream_cipher::generic_array::GenericArray; use stream_cipher::{NewStreamCipher, SyncStreamCipher, SyncStreamCipherSeek}; + fn get_cipher() -> $cipher { + <$cipher>::new(&Default::default(), &Default::default()) + } + const MAX_SEEK: usize = 512; - let data = include_bytes!(concat!("data/", $test_name, ".blb")); - for (i, row) in Blob4Iterator::new(data).unwrap().enumerate() { - let [key, iv, pt, ct] = row.unwrap(); + let mut ct = [0u8; MAX_SEEK]; + get_cipher().apply_keystream(&mut ct[..]); + + for n in 0..MAX_SEEK { + let mut cipher = get_cipher(); + assert_eq!(cipher.current_pos::(), 0); + cipher.seek(n); + assert_eq!(cipher.current_pos::(), n); + let mut buf = [0u8; MAX_SEEK]; + cipher.apply_keystream(&mut buf[n..]); + assert_eq!(cipher.current_pos::(), MAX_SEEK); + assert_eq!(&buf[n..], &ct[n..]); + } - let mut mode = <$cipher>::new_var(key, iv).unwrap(); - let pl = pt.len(); - let n = if pl > MAX_SEEK { MAX_SEEK } else { pl }; - for seek_n in 0..n { - let mut pt = pt[seek_n..].to_vec(); - mode.seek(seek_n as u64); - mode.apply_keystream(&mut pt); - if pt != &ct[seek_n..] { - panic!( - "Failed seek test №{}, seek pos: {}\n\ - key:\t{:?}\n\ - iv:\t{:?}\n\ - plaintext:\t{:?}\n\ - ciphertext:\t{:?}\n", - i, seek_n, key, iv, pt, ct, - ); + const MAX_CHUNK: usize = 128; + const MAX_LEN: usize = 1024; + + let mut buf = [0u8; MAX_CHUNK]; + let mut cipher = get_cipher(); + assert_eq!(cipher.current_pos::(), 0); + cipher.apply_keystream(&mut []); + assert_eq!(cipher.current_pos::(), 0); + for n in 1..MAX_CHUNK { + assert_eq!(cipher.current_pos::(), 0); + for m in 1.. { + cipher.apply_keystream(&mut buf[..n]); + assert_eq!(cipher.current_pos::(), n * m); + if n * m > MAX_LEN { + break; } } + cipher.seek(0); } } }; @@ -86,7 +97,7 @@ macro_rules! new_async_test { ($name:ident, $test_name:expr, $cipher:ty) => { #[test] fn $name() { - use stream_cipher::dev::blobby::Blob4Iterator; + use stream_cipher::blobby::Blob4Iterator; use stream_cipher::generic_array::GenericArray; use stream_cipher::{NewStreamCipher, StreamCipher}; diff --git a/stream-cipher/src/errors.rs b/stream-cipher/src/errors.rs index 813a4db90..404822f95 100644 --- a/stream-cipher/src/errors.rs +++ b/stream-cipher/src/errors.rs @@ -1,6 +1,6 @@ use core::fmt; -/// Error which notifies that stream cipher has reached the end of a keystream. +/// The error type returned when stream cipher has reached the end of a keystream. #[derive(Copy, Clone, Debug)] pub struct LoopError; @@ -13,7 +13,7 @@ impl fmt::Display for LoopError { #[cfg(feature = "std")] impl std::error::Error for LoopError {} -/// Error which notifies that key or/and nonce used in stream cipher +/// The error type returned when key and/or nonce used in stream cipher /// initialization had an invalid length. #[derive(Copy, Clone, Debug)] pub struct InvalidKeyNonceLength; @@ -26,3 +26,23 @@ impl fmt::Display for InvalidKeyNonceLength { #[cfg(feature = "std")] impl std::error::Error for InvalidKeyNonceLength {} + +/// The error type returned when a cipher position can not be represented +/// by the requested type. +#[derive(Copy, Clone, Debug)] +pub struct OverflowError; + +impl fmt::Display for OverflowError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + f.write_str("Overflow Error") + } +} + +impl From for LoopError { + fn from(_: OverflowError) -> LoopError { + LoopError + } +} + +#[cfg(feature = "std")] +impl std::error::Error for OverflowError {} diff --git a/stream-cipher/src/lib.rs b/stream-cipher/src/lib.rs index 8c2ac3b01..89c90d122 100644 --- a/stream-cipher/src/lib.rs +++ b/stream-cipher/src/lib.rs @@ -17,17 +17,20 @@ extern crate std; #[cfg(feature = "dev")] -#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] -pub mod dev; +mod dev; mod errors; -pub use crate::errors::{InvalidKeyNonceLength, LoopError}; +pub use errors::{InvalidKeyNonceLength, LoopError, OverflowError}; pub use generic_array::{self, typenum::consts}; #[cfg(feature = "block-cipher")] pub use block_cipher; +#[cfg(feature = "dev")] +pub use blobby; + +use core::convert::{TryFrom, TryInto}; use generic_array::typenum::Unsigned; use generic_array::{ArrayLength, GenericArray}; @@ -94,13 +97,38 @@ pub trait SyncStreamCipher { fn try_apply_keystream(&mut self, data: &mut [u8]) -> Result<(), LoopError>; } -/// Synchronous stream cipher seeking trait. +/// Trait for seekable stream ciphers. +/// +/// Methods of this trait are generic over the [`SeekNum`] trait, which is +/// implemented for primitive numeric types, i.e.: `i/u8`, `i/u16`, `i/u32`, +/// `i/u64`, `i/u128`, and `i/usize`. pub trait SyncStreamCipherSeek { - /// Return current position of a keystream in bytes from the beginning. - fn current_pos(&self) -> u64; + /// Try to get current keystream position + /// + /// Returns [`LoopError`] if position can not be represented by type `T` + fn try_current_pos(&self) -> Result; + + /// Try to seek to the given position + /// + /// Returns [`LoopError`] if provided position value is bigger than + /// keystream leangth + fn try_seek(&mut self, pos: T) -> Result<(), LoopError>; - /// Seek keystream to the given `pos` in bytes. - fn seek(&mut self, pos: u64); + /// Get current keystream position + /// + /// # Panics + /// If position can not be represented by type `T` + fn current_pos(&self) -> T { + self.try_current_pos().unwrap() + } + + /// Seek to the given position + /// + /// # Panics + /// If provided position value is bigger than keystream leangth + fn seek(&mut self, pos: T) { + self.try_seek(pos).unwrap() + } } /// Stream cipher core trait which covers both synchronous and asynchronous @@ -150,7 +178,6 @@ pub trait FromBlockCipher { type NonceSize: ArrayLength; /// Instantiate a stream cipher from a block cipher - // TODO(tarcieri): add associated type for NonceSize? fn from_block_cipher( cipher: Self::BlockCipher, nonce: &GenericArray, @@ -185,3 +212,50 @@ where } } } + +/// Trait implemented for numeric types which can be used with the +/// [`SyncStreamCipherSeek`] trait. +/// +/// This trait is implemented for primitive numeric types, i.e. `i/u8`, +/// `i/u16`, `i/u32`, `i/u64`, `i/u128`, and `i/usize`. It is not intended +/// to be implemented in third-party crates. +#[rustfmt::skip] +pub trait SeekNum: + Sized + + TryInto + TryFrom + TryInto + TryFrom + + TryInto + TryFrom + TryInto + TryFrom + + TryInto + TryFrom + TryInto + TryFrom + + TryInto + TryFrom + TryInto + TryFrom + + TryInto + TryFrom + TryInto + TryFrom + + TryInto + TryFrom + TryInto + TryFrom +{ + /// Try to get position for block number `block`, byte position inside + /// block `byte`, and block size `bs`. + fn from_block_byte(block: T, byte: u8, bs: u8) -> Result; + + /// Try to get block number and bytes position for given block size `bs`. + fn to_block_byte(self, bs: u8) -> Result<(T, u8), OverflowError>; +} + +macro_rules! impl_seek_num { + {$($t:ty )*} => { + $( + impl SeekNum for $t { + fn from_block_byte>(block: T, byte: u8, bs: u8) -> Result { + debug_assert!(byte < bs); + let block = block.try_into().map_err(|_| OverflowError)?; + let pos = block.checked_mul(bs as Self).ok_or(OverflowError)? + (byte as Self); + Ok(pos) + } + + fn to_block_byte>(self, bs: u8) -> Result<(T, u8), OverflowError> { + let byte = (self as u8) % bs; + let block = T::try_from(self/(bs as Self)).map_err(|_| OverflowError)?; + Ok((block, byte)) + } + } + )* + }; +} + +impl_seek_num! { u8 i8 u16 i16 u32 i32 u64 i64 u128 i128 isize usize } From 7ce3653b6b73c46cf83f473d1cf4302be369d35c Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Tue, 25 Aug 2020 10:33:39 +0300 Subject: [PATCH 0206/1461] Fix SeekNum::to_block_byte computation (#268) --- Cargo.lock | 2 +- stream-cipher/CHANGELOG.md | 6 ++++++ stream-cipher/Cargo.toml | 2 +- stream-cipher/src/lib.rs | 7 ++++--- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 822d28a05..78ae486f9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -281,7 +281,7 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "stream-cipher" -version = "0.7.0" +version = "0.7.1" dependencies = [ "blobby 0.3.0", "block-cipher 0.8.0", diff --git a/stream-cipher/CHANGELOG.md b/stream-cipher/CHANGELOG.md index 39507603e..c8032dd6d 100644 --- a/stream-cipher/CHANGELOG.md +++ b/stream-cipher/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.7.1 (2020-08-25) +### Fixed +- Computation of `SeekNum::to_block_byte` for numbers which are not a power of 2 ([#268]) + +[#268]: https://github.com/RustCrypto/traits/pull/268 + ## 0.7.0 (2020-08-25) ### Changed - Rework of the `SyncStreamCipherSeek` trait, make methods generic over diff --git a/stream-cipher/Cargo.toml b/stream-cipher/Cargo.toml index 8371fef24..8dedd33c7 100644 --- a/stream-cipher/Cargo.toml +++ b/stream-cipher/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "stream-cipher" description = "Stream cipher traits" -version = "0.7.0" +version = "0.7.1" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/stream-cipher/src/lib.rs b/stream-cipher/src/lib.rs index 89c90d122..e35f0008d 100644 --- a/stream-cipher/src/lib.rs +++ b/stream-cipher/src/lib.rs @@ -249,9 +249,10 @@ macro_rules! impl_seek_num { } fn to_block_byte>(self, bs: u8) -> Result<(T, u8), OverflowError> { - let byte = (self as u8) % bs; - let block = T::try_from(self/(bs as Self)).map_err(|_| OverflowError)?; - Ok((block, byte)) + let bs = bs as Self; + let byte = self % bs; + let block = T::try_from(self/bs).map_err(|_| OverflowError)?; + Ok((block, byte as u8)) } } )* From 9a04033fa9a44c0dd1710af165d8c0add95fc303 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 25 Aug 2020 09:40:30 -0700 Subject: [PATCH 0207/1461] elliptic-curve: make weierstrass::point::Decode constant time (#269) Replaces boolean flag for y-coordinate even/odd with subtle::Choice --- elliptic-curve/src/weierstrass/point.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/elliptic-curve/src/weierstrass/point.rs b/elliptic-curve/src/weierstrass/point.rs index acb170035..67c3833f2 100644 --- a/elliptic-curve/src/weierstrass/point.rs +++ b/elliptic-curve/src/weierstrass/point.rs @@ -2,11 +2,11 @@ use super::Curve; use crate::ElementBytes; -use subtle::CtOption; +use subtle::{Choice, CtOption}; /// Attempt to decompress an elliptic curve point from its x-coordinate and /// a boolean flag indicating whether or not the y-coordinate is odd. pub trait Decompress: Sized { /// Attempt to decompress an elliptic curve point - fn decompress(x: &ElementBytes, y_is_odd: bool) -> CtOption; + fn decompress(x: &ElementBytes, y_is_odd: Choice) -> CtOption; } From ce8887651eed81aa1b6d10d464a7c8f5cdcea0bb Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 25 Aug 2020 09:46:50 -0700 Subject: [PATCH 0208/1461] elliptic-curve: expose SEC1 Tag and coordinates (#270) These are helpful when implementing SEC1 point decoding --- elliptic-curve/src/sec1.rs | 42 +++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index 79afe6a6a..4df0d9d48 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -151,15 +151,21 @@ where T::from_encoded_point(self) } + /// Get the SEC1 tag for this [`EncodedPoint`] + pub fn tag(&self) -> Tag { + // Tag is ensured valid by the constructor + Tag::from_u8(self.bytes[0]).expect("invalid tag") + } + /// Get the x-coordinate for this [`EncodedPoint`] - pub(crate) fn x(&self) -> &ElementBytes { + pub fn x(&self) -> &ElementBytes { self.coordinates().0 } /// Get the y-coordinate for this [`EncodedPoint`]. /// /// Returns `None` if this point is compressed. - fn y(&self) -> Option<&ElementBytes> { + pub fn y(&self) -> Option<&ElementBytes> { self.coordinates().1 } @@ -174,12 +180,6 @@ where (x.into(), Some(y.into())) } } - - /// Get the SEC1 tag for this [`EncodedPoint`] - fn tag(&self) -> Tag { - // Tag is ensured valid by the constructor - Tag::from_u8(self.bytes[0]).expect("invalid tag") - } } impl AsRef<[u8]> for EncodedPoint @@ -261,7 +261,7 @@ where /// Tag byte used by the `Elliptic-Curve-Point-to-Octet-String` encoding. #[derive(Copy, Clone, Debug, Eq, PartialEq)] #[repr(u8)] -enum Tag { +pub enum Tag { /// Compressed point with even y-coordinate CompressedEvenY = 2, @@ -283,18 +283,6 @@ impl Tag { } } - /// Compress the given y-coordinate, returning a `Tag::Compressed*` value - pub fn compress_y(y: &[u8]) -> Self { - debug_assert!(!y.is_empty()); - - // Is the y-coordinate odd in the SEC1 sense: `self mod 2 == 1`? - if y.as_ref().last().unwrap() & 1 == 1 { - Tag::CompressedOddY - } else { - Tag::CompressedEvenY - } - } - /// Is this point compressed? pub fn is_compressed(self) -> bool { match self { @@ -313,6 +301,18 @@ impl Tag { field_element_size * 2 } } + + /// Compress the given y-coordinate, returning a `Tag::Compressed*` value + fn compress_y(y: &[u8]) -> Self { + debug_assert!(!y.is_empty()); + + // Is the y-coordinate odd in the SEC1 sense: `self mod 2 == 1`? + if y.as_ref().last().unwrap() & 1 == 1 { + Tag::CompressedOddY + } else { + Tag::CompressedEvenY + } + } } impl From for u8 { From a0cfce36dad42df4e3ee565eecf8309ffda592f1 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 25 Aug 2020 10:27:24 -0700 Subject: [PATCH 0209/1461] elliptic-curve: add back sec1::EncodedPoint::from_secret_key (#271) I'd eventually like to get rid of this method, replacing it with a proper public key (associated) type which supports a ToEncodedPoint conversion. That said, until we have that, keeping it around for now makes upgrading the existing RustCrypto/elliptic-curve crates easier. --- elliptic-curve/src/sec1.rs | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index 4df0d9d48..48e712817 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -5,11 +5,13 @@ //! //! -use crate::ElementBytes; -use crate::{weierstrass::Curve, Error}; +use crate::{ + point::Generator, scalar::NonZeroScalar, weierstrass::Curve, Arithmetic, ElementBytes, Error, + FromBytes, SecretKey, +}; use core::{ fmt::{self, Debug}, - ops::Add, + ops::{Add, Mul}, }; use generic_array::{ typenum::{Unsigned, U1}, @@ -112,6 +114,33 @@ where Self { bytes } } + /// Compute [`EncodedPoint`] representing the public key for the provided + /// [`SecretKey`]. + /// + /// The `compress` flag requests point compression. + pub fn from_secret_key(secret_key: &SecretKey, compress: bool) -> Result + where + C: Arithmetic, + C::AffinePoint: Mul, Output = C::AffinePoint> + ToEncodedPoint, + { + let ct_option = C::Scalar::from_bytes(secret_key.as_bytes()).and_then(NonZeroScalar::new); + + if ct_option.is_none().into() { + return Err(Error); + } + + let affine_point = C::AffinePoint::generator() * ct_option.unwrap(); + Ok(Self::encode(affine_point, compress)) + } + + /// Encode an [`EncodedPoint`] from the desired type + pub fn encode(encodable: T, compress: bool) -> Self + where + T: ToEncodedPoint, + { + encodable.to_encoded_point(compress) + } + /// Is this [`EncodedPoint`] compressed? pub fn is_compressed(&self) -> bool { self.tag().is_compressed() From b90b6155df7af202686b2e2765b8b77a23f27287 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 26 Aug 2020 11:16:57 -0700 Subject: [PATCH 0210/1461] elliptic-curve: impl FromBytes on NonZeroScalar (#274) Provides a more direct path from serialized bytes to a NonZeroScalar. --- elliptic-curve/src/ecdh.rs | 9 ++++----- elliptic-curve/src/scalar.rs | 27 +++++++++++++++++++++++++-- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/elliptic-curve/src/ecdh.rs b/elliptic-curve/src/ecdh.rs index 3f9867215..75ea4ba85 100644 --- a/elliptic-curve/src/ecdh.rs +++ b/elliptic-curve/src/ecdh.rs @@ -61,16 +61,15 @@ where { /// Generate a new [`EphemeralSecret`]. pub fn generate(rng: impl CryptoRng + RngCore) -> Self { - Self { - scalar: NonZeroScalar::generate(rng), - } + let scalar = NonZeroScalar::generate(rng); + Self { scalar } } /// Get the public key associated with this ephemeral secret. /// /// The `compress` flag enables point compression. pub fn public_key(&self) -> PublicKey { - PublicKey::from(C::AffinePoint::generator() * self.scalar.clone()) + PublicKey::from(C::AffinePoint::generator() * self.scalar) } /// Compute a Diffie-Hellman shared secret from an ephemeral secret and the @@ -79,7 +78,7 @@ where let affine_point = C::AffinePoint::from_encoded_point(public_key); if affine_point.is_some().into() { - let shared_secret = affine_point.unwrap() * self.scalar.clone(); + let shared_secret = affine_point.unwrap() * self.scalar; Ok(SharedSecret::new(shared_secret.into())) } else { Err(Error) diff --git a/elliptic-curve/src/scalar.rs b/elliptic-curve/src/scalar.rs index bf08b301a..f9cb56996 100644 --- a/elliptic-curve/src/scalar.rs +++ b/elliptic-curve/src/scalar.rs @@ -1,7 +1,7 @@ //! Scalar types -use crate::{Arithmetic, Curve, FromBytes}; -use subtle::{ConstantTimeEq, CtOption}; +use crate::{Arithmetic, Curve, ElementBytes, FromBytes}; +use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; #[cfg(feature = "rand")] use crate::{ @@ -47,6 +47,29 @@ where } } +impl ConditionallySelectable for NonZeroScalar +where + C: Curve + Arithmetic, +{ + fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { + let scalar = C::Scalar::conditional_select(&a.scalar, &b.scalar, choice); + Self { scalar } + } +} + +impl Copy for NonZeroScalar where C: Curve + Arithmetic {} + +impl FromBytes for NonZeroScalar +where + C: Curve + Arithmetic, +{ + type Size = C::ElementSize; + + fn from_bytes(bytes: &ElementBytes) -> CtOption { + C::Scalar::from_bytes(bytes).and_then(Self::new) + } +} + #[cfg(feature = "rand")] impl Generate for NonZeroScalar where From a43036613f499df4c50d8cead4ccbc3a01aa2f24 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 26 Aug 2020 11:50:03 -0700 Subject: [PATCH 0211/1461] elliptic-curve: add EncodedPoint::decompress (#275) Generic support for decompressing SEC1-encoded points --- elliptic-curve/src/sec1.rs | 50 +++++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index 48e712817..a1e39fb2b 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -6,8 +6,10 @@ //! use crate::{ - point::Generator, scalar::NonZeroScalar, weierstrass::Curve, Arithmetic, ElementBytes, Error, - FromBytes, SecretKey, + point::Generator, + scalar::NonZeroScalar, + weierstrass::{point::Decompress, Curve}, + Arithmetic, ElementBytes, Error, FromBytes, SecretKey, }; use core::{ fmt::{self, Debug}, @@ -17,7 +19,7 @@ use generic_array::{ typenum::{Unsigned, U1}, ArrayLength, GenericArray, }; -use subtle::CtOption; +use subtle::{Choice, CtOption}; #[cfg(feature = "alloc")] use alloc::boxed::Box; @@ -133,19 +135,6 @@ where Ok(Self::encode(affine_point, compress)) } - /// Encode an [`EncodedPoint`] from the desired type - pub fn encode(encodable: T, compress: bool) -> Self - where - T: ToEncodedPoint, - { - encodable.to_encoded_point(compress) - } - - /// Is this [`EncodedPoint`] compressed? - pub fn is_compressed(&self) -> bool { - self.tag().is_compressed() - } - /// Get the length of the encoded point in bytes pub fn len(&self) -> usize { self.tag().message_len(C::ElementSize::to_usize()) @@ -163,15 +152,42 @@ where self.as_bytes().to_vec().into_boxed_slice() } + /// Is this [`EncodedPoint`] compressed? + pub fn is_compressed(&self) -> bool { + self.tag().is_compressed() + } + /// Compress this [`EncodedPoint`], returning a new [`EncodedPoint`]. pub fn compress(&self) -> Self { - if self.tag().is_compressed() { + if self.is_compressed() { self.clone() } else { Self::from_affine_coords(self.x(), self.y().unwrap(), true) } } + /// Decompress this [`EncodedPoint`], returning a new [`EncodedPoint`]. + pub fn decompress(&self) -> CtOption + where + C: Arithmetic, + C::Scalar: Decompress + ToEncodedPoint, + { + if self.is_compressed() { + C::Scalar::decompress(self.x(), Choice::from(self.tag() as u8 & 1)) + .map(|s| s.to_encoded_point(false)) + } else { + CtOption::new(self.clone(), Choice::from(1)) + } + } + + /// Encode an [`EncodedPoint`] from the desired type + pub fn encode(encodable: T, compress: bool) -> Self + where + T: ToEncodedPoint, + { + encodable.to_encoded_point(compress) + } + /// Decode this [`EncodedPoint`] into the desired type pub fn decode(&self) -> CtOption where From 05d2eaebbb0678616c195bd297e7f43e48049612 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 26 Aug 2020 12:37:08 -0700 Subject: [PATCH 0212/1461] elliptic-curve: add NonZeroScalar::to_bytes (#276) ...and a `From` conversion to `ElementBytes` --- elliptic-curve/src/scalar.rs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/elliptic-curve/src/scalar.rs b/elliptic-curve/src/scalar.rs index f9cb56996..957d7bd74 100644 --- a/elliptic-curve/src/scalar.rs +++ b/elliptic-curve/src/scalar.rs @@ -36,6 +36,11 @@ where let is_zero = scalar.ct_eq(&zero); CtOption::new(Self { scalar }, !is_zero) } + + /// Serialize this [`NonZeroScalar`] as a byte array + pub fn to_bytes(&self) -> ElementBytes { + self.scalar.into() + } } impl AsRef for NonZeroScalar @@ -70,6 +75,15 @@ where } } +impl From> for ElementBytes +where + C: Curve + Arithmetic, +{ + fn from(scalar: NonZeroScalar) -> ElementBytes { + scalar.to_bytes() + } +} + #[cfg(feature = "rand")] impl Generate for NonZeroScalar where @@ -77,7 +91,7 @@ where C::Scalar: Generate, { fn generate(mut rng: impl CryptoRng + RngCore) -> Self { - // Use rejection sampling to eliminate zeroes + // Use rejection sampling to eliminate zero values loop { let result = Self::new(C::Scalar::generate(&mut rng)); From 733146a74ec4d0913d4d624bca31fc8a962d5170 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 26 Aug 2020 12:51:27 -0700 Subject: [PATCH 0213/1461] elliptic-curve: conditionally impl Invert for NonZeroScalar (#277) ...if the underlying scalar type it wraps also impls `Invert` --- elliptic-curve/src/scalar.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/elliptic-curve/src/scalar.rs b/elliptic-curve/src/scalar.rs index 957d7bd74..78946fe02 100644 --- a/elliptic-curve/src/scalar.rs +++ b/elliptic-curve/src/scalar.rs @@ -1,6 +1,6 @@ //! Scalar types -use crate::{Arithmetic, Curve, ElementBytes, FromBytes}; +use crate::{ops::Invert, Arithmetic, Curve, ElementBytes, FromBytes}; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; #[cfg(feature = "rand")] @@ -84,6 +84,19 @@ where } } +impl Invert for NonZeroScalar +where + C: Curve + Arithmetic, + C::Scalar: Invert, +{ + type Output = ::Output; + + /// Perform a scalar inversion + fn invert(&self) -> CtOption { + self.scalar.invert() + } +} + #[cfg(feature = "rand")] impl Generate for NonZeroScalar where From 7cf898c746bcee5ffcc9bd100a341d0d63f1c27b Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 31 Aug 2020 09:43:49 -0700 Subject: [PATCH 0214/1461] elliptic-curve: impl Deref for NonZeroScalar (#278) --- elliptic-curve/src/scalar.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/elliptic-curve/src/scalar.rs b/elliptic-curve/src/scalar.rs index 78946fe02..18bb9f92b 100644 --- a/elliptic-curve/src/scalar.rs +++ b/elliptic-curve/src/scalar.rs @@ -1,6 +1,7 @@ //! Scalar types use crate::{ops::Invert, Arithmetic, Curve, ElementBytes, FromBytes}; +use core::ops::Deref; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; #[cfg(feature = "rand")] @@ -64,6 +65,17 @@ where impl Copy for NonZeroScalar where C: Curve + Arithmetic {} +impl Deref for NonZeroScalar +where + C: Curve + Arithmetic, +{ + type Target = C::Scalar; + + fn deref(&self) -> &C::Scalar { + &self.scalar + } +} + impl FromBytes for NonZeroScalar where C: Curve + Arithmetic, From bc66b11fb22566c3987319024a7eba2dfe37a420 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 31 Aug 2020 11:20:04 -0700 Subject: [PATCH 0215/1461] elliptic-curve: add `digest` feature and FromDigest trait (#279) This is needed in a generic implementation of RFC 6979, but is also potentially useful for things like hash-to-curve. --- Cargo.lock | 1 + elliptic-curve/Cargo.toml | 1 + elliptic-curve/src/lib.rs | 16 ++++++++++++++++ 3 files changed, 18 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 78ae486f9..ec8c6fc08 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -128,6 +128,7 @@ name = "elliptic-curve" version = "0.5.0" dependencies = [ "const-oid", + "digest 0.9.0", "generic-array 0.14.4", "hex-literal", "rand_core", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 8422122eb..866b47d4f 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -15,6 +15,7 @@ categories = ["cryptography", "no-std"] keywords = ["crypto", "ecc", "elliptic", "weierstrass"] [dependencies] +digest = { version = "0.9", optional = true, path = "../digest" } generic-array = { version = "0.14", default-features = false } oid = { package = "const-oid", version = "0.1", optional = true } rand_core = { version = "0.5", optional = true, default-features = false } diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index e7c6c79e8..64814960f 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -47,6 +47,9 @@ pub use self::{error::Error, secret_key::SecretKey}; pub use generic_array::{self, typenum::consts}; pub use subtle; +#[cfg(feature = "digest")] +pub use digest::{self, Digest}; + #[cfg(feature = "oid")] pub use oid; @@ -107,6 +110,19 @@ pub trait FromBytes: ConditionallySelectable + Sized { fn from_bytes(bytes: &GenericArray) -> CtOption; } +/// Instantiate this type from the output of a digest. +/// +/// This can be used for implementing hash-to-scalar (e.g. as in ECDSA) or +/// hash-to-curve algorithms. +#[cfg(feature = "digest")] +#[cfg_attr(docsrs, doc(cfg(feature = "digest")))] +pub trait FromDigest { + /// Instantiate this type from a [`Digest`] instance + fn from_digest(digest: D) -> Self + where + D: Digest; +} + /// Randomly generate a value. /// /// Primarily intended for use with scalar types for a particular curve. From fc56c1b4f649f2126b0f42931d2a7d19cbcdbb0e Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 31 Aug 2020 11:45:54 -0700 Subject: [PATCH 0216/1461] elliptic-curve: remove `digest` crate path directive (#280) This makes it incompatible with `signature` when fetched via git, which does not have such a declaration (and cannot, as it'd break the dev-dependency on `sha2`). --- Cargo.lock | 2 +- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ec8c6fc08..87917de38 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -128,7 +128,7 @@ name = "elliptic-curve" version = "0.5.0" dependencies = [ "const-oid", - "digest 0.9.0", + "digest 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "generic-array 0.14.4", "hex-literal", "rand_core", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 866b47d4f..5fca29ab8 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -15,7 +15,7 @@ categories = ["cryptography", "no-std"] keywords = ["crypto", "ecc", "elliptic", "weierstrass"] [dependencies] -digest = { version = "0.9", optional = true, path = "../digest" } +digest = { version = "0.9", optional = true } generic-array = { version = "0.14", default-features = false } oid = { package = "const-oid", version = "0.1", optional = true } rand_core = { version = "0.5", optional = true, default-features = false } From abff234bfe0ced9254615dc608ece09619a8db38 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 1 Sep 2020 17:51:23 -0700 Subject: [PATCH 0217/1461] elliptic-curve: import arithmetic helper functions (#281) These are helper functions for performing arithmetic on field element "limbs", e.g. implementing carry chains. The particular versions in this file come from the `k256`, which started as a fork of the `p256` crate, and notably provide 32-bit and 64-bit versions of the same functions. These are potentially helpful to have in the `elliptic-curve` crate for several reasons, most notably for testing things which are generic across elliptic curves without having to provide a full curve arithmetic implementation. Also having things in one place is nice, and potentially we can use these to provide a generic baseline implementation of certain types of curve arithmetic for curves that don't provide their own arithmetic. --- elliptic-curve/src/lib.rs | 1 + elliptic-curve/src/util.rs | 55 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 elliptic-curve/src/util.rs diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 64814960f..9a1ee1970 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -30,6 +30,7 @@ pub mod ops; pub mod point; pub mod scalar; pub mod secret_key; +pub mod util; #[cfg(feature = "ecdh")] #[cfg_attr(docsrs, doc(cfg(feature = "ecdh")))] diff --git a/elliptic-curve/src/util.rs b/elliptic-curve/src/util.rs new file mode 100644 index 000000000..15e933c0f --- /dev/null +++ b/elliptic-curve/src/util.rs @@ -0,0 +1,55 @@ +//! Arithmetic helper functions designed for efficient LLVM lowering. +//! +//! These functions are intended for supporting arithmetic on field elements +//! modeled as multiple "limbs" (e.g. carry chains). + +// TODO(tarcieri): enforce 64-bit versions are only available on 64-bit arches +// i.e. add: #[cfg(target_pointer_width = "64")] + +/// Computes `a + b + carry`, returning the result along with the new carry. +/// 32-bit version. +#[inline(always)] +pub const fn adc32(a: u32, b: u32, carry: u32) -> (u32, u32) { + let ret = (a as u64) + (b as u64) + (carry as u64); + (ret as u32, (ret >> 32) as u32) +} + +/// Computes `a + b + carry`, returning the result along with the new carry. +/// 64-bit version. +#[inline(always)] +pub const fn adc64(a: u64, b: u64, carry: u64) -> (u64, u64) { + let ret = (a as u128) + (b as u128) + (carry as u128); + (ret as u64, (ret >> 64) as u64) +} + +/// Computes `a - (b + borrow)`, returning the result along with the new borrow. +/// 32-bit version. +#[inline(always)] +pub const fn sbb32(a: u32, b: u32, borrow: u32) -> (u32, u32) { + let ret = (a as u64).wrapping_sub((b as u64) + ((borrow >> 31) as u64)); + (ret as u32, (ret >> 32) as u32) +} + +/// Computes `a - (b + borrow)`, returning the result along with the new borrow. +/// 64-bit version. +#[inline(always)] +pub const fn sbb64(a: u64, b: u64, borrow: u64) -> (u64, u64) { + let ret = (a as u128).wrapping_sub((b as u128) + ((borrow >> 63) as u128)); + (ret as u64, (ret >> 64) as u64) +} + +/// Computes `a + (b * c) + carry`, returning the result along with the new carry. +/// 32-bit version. +#[inline(always)] +pub const fn mac32(a: u32, b: u32, c: u32, carry: u32) -> (u32, u32) { + let ret = (a as u64) + ((b as u64) * (c as u64)) + (carry as u64); + (ret as u32, (ret >> 32) as u32) +} + +/// Computes `a + (b * c) + carry`, returning the result along with the new carry. +/// 64-bit version. +#[inline(always)] +pub const fn mac64(a: u64, b: u64, c: u64, carry: u64) -> (u64, u64) { + let ret = (a as u128) + ((b as u128) * (c as u128)) + (carry as u128); + (ret as u64, (ret >> 64) as u64) +} From a85525d61e1d882d12a4c00387655dded76fd0c2 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 2 Sep 2020 08:24:19 -0700 Subject: [PATCH 0218/1461] Rename C::ElementSize => FieldSize (#282) This is hopefully a more apt description of this particular size. --- elliptic-curve/src/lib.rs | 15 ++++++++------- elliptic-curve/src/scalar.rs | 2 +- elliptic-curve/src/sec1.rs | 16 ++++++++-------- elliptic-curve/src/secret_key.rs | 2 +- 4 files changed, 18 insertions(+), 17 deletions(-) diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 9a1ee1970..ee518b2bc 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -71,7 +71,7 @@ use subtle::{ConditionallySelectable, ConstantTimeEq, CtOption}; use rand_core::{CryptoRng, RngCore}; /// Byte array containing a serialized scalar value (i.e. an integer) -pub type ElementBytes = GenericArray::ElementSize>; +pub type ElementBytes = GenericArray::FieldSize>; /// Elliptic curve. /// @@ -82,11 +82,12 @@ pub type ElementBytes = GenericArray::ElementSize>; /// be impl'd by these ZSTs, facilitating types which are generic over elliptic /// curves (e.g. [`SecretKey`]). pub trait Curve: Clone + Debug + Default + Eq + Ord + Send + Sync { - /// Number of bytes required to serialize elements of field elements - /// associated with this curve, e.g. elements of the base/scalar fields. + /// Size of this curve's field in *bytes*, i.e. the number of bytes needed + /// to serialize a field element. /// - /// This is used for computing the sizes for types related to this curve. - type ElementSize: ArrayLength + Add + Eq + Ord + Unsigned; + /// This is used for computing the sizes of field element types related to + /// this curve and other types composed from them (e.g. signatures). + type FieldSize: ArrayLength + Add + Eq + Ord + Unsigned; } /// Elliptic curve with curve arithmetic support @@ -95,7 +96,7 @@ pub trait Arithmetic: Curve { type Scalar: ConditionallySelectable + ConstantTimeEq + Default - + FromBytes + + FromBytes + Into>; /// Affine point type for a given curve @@ -121,7 +122,7 @@ pub trait FromDigest { /// Instantiate this type from a [`Digest`] instance fn from_digest(digest: D) -> Self where - D: Digest; + D: Digest; } /// Randomly generate a value. diff --git a/elliptic-curve/src/scalar.rs b/elliptic-curve/src/scalar.rs index 18bb9f92b..fe49556c8 100644 --- a/elliptic-curve/src/scalar.rs +++ b/elliptic-curve/src/scalar.rs @@ -80,7 +80,7 @@ impl FromBytes for NonZeroScalar where C: Curve + Arithmetic, { - type Size = C::ElementSize; + type Size = C::FieldSize; fn from_bytes(bytes: &ElementBytes) -> CtOption { C::Scalar::from_bytes(bytes).and_then(Self::new) diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index a1e39fb2b..d59ab95a3 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -30,7 +30,7 @@ use zeroize::Zeroize; /// Size of a compressed point for the given elliptic curve when encoded /// using the SEC1 `Elliptic-Curve-Point-to-Octet-String` algorithm /// (including leading `0x02` or `0x03` tag byte). -pub type CompressedPointSize = <::ElementSize as Add>::Output; +pub type CompressedPointSize = <::FieldSize as Add>::Output; /// Size of an uncompressed point for the given elliptic curve when encoded /// using the SEC1 `Elliptic-Curve-Point-to-Octet-String` algorithm @@ -38,7 +38,7 @@ pub type CompressedPointSize = <::ElementSize as Add>: pub type UncompressedPointSize = as Add>::Output; /// Size of an untagged point for given elliptic curve. -pub type UntaggedPointSize = <::ElementSize as Add>::Output; +pub type UntaggedPointSize = <::FieldSize as Add>::Output; /// SEC1 encoded curve point. /// @@ -75,7 +75,7 @@ where let tag = input.first().cloned().ok_or(Error).and_then(Tag::from_u8)?; // Validate length - let expected_len = tag.message_len(C::ElementSize::to_usize()); + let expected_len = tag.message_len(C::FieldSize::to_usize()); if input.len() != expected_len { return Err(Error); @@ -90,7 +90,7 @@ where /// encoded as the concatenated `x || y` coordinates with no leading SEC1 /// tag byte (which would otherwise be `0x04` for an uncompressed point). pub fn from_untagged_bytes(bytes: &GenericArray>) -> Self { - let (x, y) = bytes.split_at(C::ElementSize::to_usize()); + let (x, y) = bytes.split_at(C::FieldSize::to_usize()); Self::from_affine_coords(x.into(), y.into(), false) } @@ -106,7 +106,7 @@ where let mut bytes = GenericArray::default(); bytes[0] = tag.into(); - let element_size = C::ElementSize::to_usize(); + let element_size = C::FieldSize::to_usize(); bytes[1..(element_size + 1)].copy_from_slice(x); if !compress { @@ -137,7 +137,7 @@ where /// Get the length of the encoded point in bytes pub fn len(&self) -> usize { - self.tag().message_len(C::ElementSize::to_usize()) + self.tag().message_len(C::FieldSize::to_usize()) } /// Get byte slice containing the serialized [`EncodedPoint`]. @@ -217,7 +217,7 @@ where /// Get the coordinates for this [`EncodedPoint`] as a pair #[inline] fn coordinates(&self) -> (&ElementBytes, Option<&ElementBytes>) { - let (x, y) = self.bytes[1..].split_at(C::ElementSize::to_usize()); + let (x, y) = self.bytes[1..].split_at(C::FieldSize::to_usize()); if self.is_compressed() { (x.into(), None) @@ -377,7 +377,7 @@ mod tests { struct ExampleCurve; impl Curve for ExampleCurve { - type ElementSize = U32; + type FieldSize = U32; } impl weierstrass::Curve for ExampleCurve { diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index f6afcfd45..275f7601c 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -52,7 +52,7 @@ impl TryFrom<&[u8]> for SecretKey { type Error = Error; fn try_from(slice: &[u8]) -> Result { - if slice.len() == C::ElementSize::to_usize() { + if slice.len() == C::FieldSize::to_usize() { Ok(SecretKey { scalar: GenericArray::clone_from_slice(slice), }) From b9f71bd73969649a34d46230900fd3f9ab6b1340 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 2 Sep 2020 09:16:42 -0700 Subject: [PATCH 0219/1461] elliptic-curve: extract point::Compression trait (#283) Move point compression defaults onto their own trait --- elliptic-curve/src/point.rs | 6 ++++++ elliptic-curve/src/sec1.rs | 4 +--- elliptic-curve/src/weierstrass.rs | 5 +---- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/elliptic-curve/src/point.rs b/elliptic-curve/src/point.rs index 67a810a93..5a0ae58ae 100644 --- a/elliptic-curve/src/point.rs +++ b/elliptic-curve/src/point.rs @@ -1,5 +1,11 @@ //! Traits for elliptic curve points +/// Point compression settings +pub trait Compression { + /// Should point compression be applied by default? + const COMPRESS_POINTS: bool; +} + /// Obtain the generator point. pub trait Generator { /// Get the generator point for this elliptic curve diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index d59ab95a3..5445b0872 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -380,9 +380,7 @@ mod tests { type FieldSize = U32; } - impl weierstrass::Curve for ExampleCurve { - const COMPRESS_POINTS: bool = false; - } + impl weierstrass::Curve for ExampleCurve {} type EncodedPoint = super::EncodedPoint; diff --git a/elliptic-curve/src/weierstrass.rs b/elliptic-curve/src/weierstrass.rs index c87a54ed2..ba05927ba 100644 --- a/elliptic-curve/src/weierstrass.rs +++ b/elliptic-curve/src/weierstrass.rs @@ -3,7 +3,4 @@ pub mod point; /// Marker trait for elliptic curves in short Weierstrass form -pub trait Curve: super::Curve { - /// Should point compression be applied by default? - const COMPRESS_POINTS: bool; -} +pub trait Curve: super::Curve {} From 3df75fcbb642248b6509cde13b8753e695b3f19c Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 2 Sep 2020 12:16:24 -0700 Subject: [PATCH 0220/1461] elliptic-curve: ensure C::AffinePoint Mul (#284) Ensures that the output of a scalar multiplication with an affine point is also an affine point. --- elliptic-curve/src/lib.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index ee518b2bc..16c8dff03 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -100,7 +100,9 @@ pub trait Arithmetic: Curve { + Into>; /// Affine point type for a given curve - type AffinePoint: ConditionallySelectable + Mul> + point::Generator; + type AffinePoint: ConditionallySelectable + + Mul, Output = Self::AffinePoint> + + point::Generator; } /// Try to decode the given bytes into a curve element From ab2598b62c35d8e9350937b2f632c54b84cbcb01 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 3 Sep 2020 07:22:48 -0700 Subject: [PATCH 0221/1461] elliptic-curve: add sec1::Coordinates (#286) Provides an enum-based "view" of a parsed SEC1-encoded elliptic curve point, including the compressed and uncompressed representations. --- elliptic-curve/src/sec1.rs | 140 +++++++++++++++++++++++++++---------- 1 file changed, 103 insertions(+), 37 deletions(-) diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index 5445b0872..3c58397cb 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -91,12 +91,16 @@ where /// tag byte (which would otherwise be `0x04` for an uncompressed point). pub fn from_untagged_bytes(bytes: &GenericArray>) -> Self { let (x, y) = bytes.split_at(C::FieldSize::to_usize()); - Self::from_affine_coords(x.into(), y.into(), false) + Self::from_affine_coordinates(x.into(), y.into(), false) } /// Encode an elliptic curve point from big endian serialized coordinates /// (with optional point compression) - pub fn from_affine_coords(x: &ElementBytes, y: &ElementBytes, compress: bool) -> Self { + pub fn from_affine_coordinates( + x: &ElementBytes, + y: &ElementBytes, + compress: bool, + ) -> Self { let tag = if compress { Tag::compress_y(y.as_slice()) } else { @@ -159,10 +163,9 @@ where /// Compress this [`EncodedPoint`], returning a new [`EncodedPoint`]. pub fn compress(&self) -> Self { - if self.is_compressed() { - self.clone() - } else { - Self::from_affine_coords(self.x(), self.y().unwrap(), true) + match self.coordinates() { + Coordinates::Compressed { .. } => self.clone(), + Coordinates::Uncompressed { x, y } => Self::from_affine_coordinates(x, y, true), } } @@ -172,11 +175,12 @@ where C: Arithmetic, C::Scalar: Decompress + ToEncodedPoint, { - if self.is_compressed() { - C::Scalar::decompress(self.x(), Choice::from(self.tag() as u8 & 1)) - .map(|s| s.to_encoded_point(false)) - } else { - CtOption::new(self.clone(), Choice::from(1)) + match self.coordinates() { + Coordinates::Compressed { x, y_is_odd } => { + C::Scalar::decompress(x, Choice::from(y_is_odd as u8)) + .map(|s| s.to_encoded_point(false)) + } + Coordinates::Uncompressed { .. } => CtOption::new(self.clone(), Choice::from(1)), } } @@ -202,27 +206,39 @@ where Tag::from_u8(self.bytes[0]).expect("invalid tag") } + /// Get the [`Coordinates`] for this [`EncodedPoint`]. + #[inline] + pub fn coordinates(&self) -> Coordinates<'_, C> { + let (x, y) = self.bytes[1..].split_at(C::FieldSize::to_usize()); + + if self.is_compressed() { + Coordinates::Compressed { + x: x.into(), + y_is_odd: self.tag() as u8 & 1 == 1, + } + } else { + Coordinates::Uncompressed { + x: x.into(), + y: y.into(), + } + } + } + /// Get the x-coordinate for this [`EncodedPoint`] pub fn x(&self) -> &ElementBytes { - self.coordinates().0 + match self.coordinates() { + Coordinates::Compressed { x, .. } => x, + Coordinates::Uncompressed { x, .. } => x, + } } /// Get the y-coordinate for this [`EncodedPoint`]. /// /// Returns `None` if this point is compressed. pub fn y(&self) -> Option<&ElementBytes> { - self.coordinates().1 - } - - /// Get the coordinates for this [`EncodedPoint`] as a pair - #[inline] - fn coordinates(&self) -> (&ElementBytes, Option<&ElementBytes>) { - let (x, y) = self.bytes[1..].split_at(C::FieldSize::to_usize()); - - if self.is_compressed() { - (x.into(), None) - } else { - (x.into(), Some(y.into())) + match self.coordinates() { + Coordinates::Compressed { .. } => None, + Coordinates::Uncompressed { y, .. } => Some(y), } } } @@ -271,6 +287,29 @@ where } } +/// Enum representing the coordinates of either compressed or uncompressed +/// SEC1-encoded elliptic curve points. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum Coordinates<'a, C: Curve> { + /// Compressed curve point + Compressed { + /// x-coordinate + x: &'a ElementBytes, + + /// Is the y-coordinate odd? + y_is_odd: bool, + }, + + /// Uncompressed curve point + Uncompressed { + /// x-coordinate + x: &'a ElementBytes, + + /// y-coordinate + y: &'a ElementBytes, + }, +} + /// Trait for deserializing a value from a SEC1 encoded curve point. /// /// This is intended for use with the `AffinePoint` type for a given elliptic curve. @@ -307,13 +346,13 @@ where #[derive(Copy, Clone, Debug, Eq, PartialEq)] #[repr(u8)] pub enum Tag { - /// Compressed point with even y-coordinate + /// Compressed point with even y-coordinate (`0x02`) CompressedEvenY = 2, - /// Compressed point with odd y-coordinate + /// Compressed point with odd y-coordinate (`0x03`) CompressedOddY = 3, - /// Uncompressed point + /// Uncompressed point (`0x04`) Uncompressed = 4, } @@ -368,7 +407,7 @@ impl From for u8 { #[cfg(test)] mod tests { - use super::Tag; + use super::{Coordinates, Tag}; use crate::{weierstrass, Curve}; use generic_array::{typenum::U32, GenericArray}; use hex_literal::hex; @@ -401,13 +440,22 @@ mod tests { assert!(compressed_even_y.is_compressed()); assert_eq!(compressed_even_y.tag(), Tag::CompressedEvenY); + assert_eq!(compressed_even_y.len(), 33); + assert_eq!(compressed_even_y.as_bytes(), &compressed_even_y_bytes[..]); + + assert_eq!( + compressed_even_y.coordinates(), + Coordinates::Compressed { + x: &hex!("0100000000000000000000000000000000000000000000000000000000000000").into(), + y_is_odd: false + } + ); + assert_eq!( compressed_even_y.x(), &hex!("0100000000000000000000000000000000000000000000000000000000000000").into() ); assert_eq!(compressed_even_y.y(), None); - assert_eq!(compressed_even_y.len(), 33); - assert_eq!(compressed_even_y.as_bytes(), &compressed_even_y_bytes[..]); // Odd y-coordinate let compressed_odd_y_bytes = @@ -417,13 +465,22 @@ mod tests { assert!(compressed_odd_y.is_compressed()); assert_eq!(compressed_odd_y.tag(), Tag::CompressedOddY); + assert_eq!(compressed_odd_y.len(), 33); + assert_eq!(compressed_odd_y.as_bytes(), &compressed_odd_y_bytes[..]); + + assert_eq!( + compressed_odd_y.coordinates(), + Coordinates::Compressed { + x: &hex!("0200000000000000000000000000000000000000000000000000000000000000").into(), + y_is_odd: true + } + ); + assert_eq!( compressed_odd_y.x(), &hex!("0200000000000000000000000000000000000000000000000000000000000000").into() ); assert_eq!(compressed_odd_y.y(), None); - assert_eq!(compressed_odd_y.len(), 33); - assert_eq!(compressed_odd_y.as_bytes(), &compressed_odd_y_bytes[..]); } #[test] @@ -432,6 +489,17 @@ mod tests { assert!(!uncompressed_point.is_compressed()); assert_eq!(uncompressed_point.tag(), Tag::Uncompressed); + assert_eq!(uncompressed_point.len(), 65); + assert_eq!(uncompressed_point.as_bytes(), &UNCOMPRESSED_BYTES[..]); + + assert_eq!( + uncompressed_point.coordinates(), + Coordinates::Uncompressed { + x: &hex!("1111111111111111111111111111111111111111111111111111111111111111").into(), + y: &hex!("2222222222222222222222222222222222222222222222222222222222222222").into() + } + ); + assert_eq!( uncompressed_point.x(), &hex!("1111111111111111111111111111111111111111111111111111111111111111").into() @@ -440,8 +508,6 @@ mod tests { uncompressed_point.y().unwrap(), &hex!("2222222222222222222222222222222222222222222222222222222222222222").into() ); - assert_eq!(uncompressed_point.len(), 65); - assert_eq!(uncompressed_point.as_bytes(), &UNCOMPRESSED_BYTES[..]); } #[test] @@ -482,14 +548,14 @@ mod tests { } #[test] - fn from_affine_coords() { + fn from_affine_coordinates() { let x = hex!("1111111111111111111111111111111111111111111111111111111111111111"); let y = hex!("2222222222222222222222222222222222222222222222222222222222222222"); - let uncompressed_point = EncodedPoint::from_affine_coords(&x.into(), &y.into(), false); + let uncompressed_point = EncodedPoint::from_affine_coordinates(&x.into(), &y.into(), false); assert_eq!(uncompressed_point.as_bytes(), &UNCOMPRESSED_BYTES[..]); - let compressed_point = EncodedPoint::from_affine_coords(&x.into(), &y.into(), true); + let compressed_point = EncodedPoint::from_affine_coordinates(&x.into(), &y.into(), true); assert_eq!(compressed_point.as_bytes(), &COMPRESSED_BYTES[..]); } From 80abd0a2e92202915d853cf644ec8de50c2c3324 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 4 Sep 2020 07:37:06 -0700 Subject: [PATCH 0222/1461] elliptic-curve: add `ff` and `group` crate dependencies (#287) Adds the `ff` and `group` crates as dependencies, with the goal of replacing some of the existing traits and trait relationships in `elliptic-curve` with ones from `ff`/`group`. This PR also removes the `rand` and `weierstrass` features from the `elliptic-curve` crate, making `rand_core` a hard requirement, since it seems at least `rand_core` will probably be a hard requirement for `group`, and requiring an RNG as a hard dependency makes sense. --- .github/workflows/elliptic-curve.yml | 1 - Cargo.lock | 32 ++++++++++++++++++++--- Cargo.toml | 3 +++ elliptic-curve/Cargo.toml | 10 ++++---- elliptic-curve/src/lib.rs | 38 ++++++++++------------------ elliptic-curve/src/scalar.rs | 11 +++----- elliptic-curve/src/secret_key.rs | 10 ++------ 7 files changed, 56 insertions(+), 49 deletions(-) diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index b25ddf1d2..0a251428b 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -51,6 +51,5 @@ jobs: toolchain: ${{ matrix.rust }} - run: cargo check --all-features - run: cargo test --no-default-features - - run: cargo test --no-default-features --features weierstrass - run: cargo test - run: cargo test --all-features diff --git a/Cargo.lock b/Cargo.lock index 87917de38..24ef4d73a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -129,13 +129,26 @@ version = "0.5.0" dependencies = [ "const-oid", "digest 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ff", "generic-array 0.14.4", + "group", "hex-literal", "rand_core", "subtle", "zeroize", ] +[[package]] +name = "ff" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11efdc125f2647dde5a0f5f88010a5b0f89b700f86052afa1d148c4696047" +dependencies = [ + "byteorder", + "rand_core", + "subtle", +] + [[package]] name = "generic-array" version = "0.12.3" @@ -164,6 +177,17 @@ dependencies = [ "version_check", ] +[[package]] +name = "group" +version = "0.7.0" +source = "git+https://github.com/zkcrypto/group.git#2942324876cdbb5c94140ad39ae83da642c30374" +dependencies = [ + "byteorder", + "ff", + "rand_core", + "subtle", +] + [[package]] name = "hash32" version = "0.1.1" @@ -218,9 +242,9 @@ checksum = "99c605b9a0adc77b7211c6b1f722dcb613d68d66859a44f3d485a6da332b0598" [[package]] name = "proc-macro2" -version = "1.0.19" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04f5f085b5d71e2188cb8271e5da0161ad52c3f227a661a3c135fdf28e258b12" +checksum = "175c513d55719db99da20232b06cda8bab6b83ec2d04e3283edf0213c37c1a29" dependencies = [ "unicode-xid", ] @@ -297,9 +321,9 @@ checksum = "502d53007c02d7605a05df1c1a73ee436952781653da5d0bf57ad608f66932c1" [[package]] name = "syn" -version = "1.0.38" +version = "1.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e69abc24912995b3038597a7a593be5053eb0fb44f3cc5beec0deb421790c1f4" +checksum = "891d8d6567fe7c7f8835a3a98af4208f3846fba258c1bc3c31d6e506239f11f9" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index aa9d7d9c4..7da963005 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,3 +10,6 @@ members = [ "stream-cipher", "universal-hash", ] + +[patch.crates-io] +group = { git = "https://github.com/zkcrypto/group.git" } diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 5fca29ab8..aeaaa62da 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -16,9 +16,11 @@ keywords = ["crypto", "ecc", "elliptic", "weierstrass"] [dependencies] digest = { version = "0.9", optional = true } +ff = { version = "0.7", default-features = false } +group = { version = "0.7", default-features = false } generic-array = { version = "0.14", default-features = false } oid = { package = "const-oid", version = "0.1", optional = true } -rand_core = { version = "0.5", optional = true, default-features = false } +rand_core = { version = "0.5", default-features = false } subtle = { version = "2.2", default-features = false } zeroize = { version = "1", optional = true, default-features = false } @@ -26,11 +28,9 @@ zeroize = { version = "1", optional = true, default-features = false } hex-literal = "0.2" [features] -default = ["rand"] +default = [] alloc = [] -ecdh = ["rand", "weierstrass", "zeroize"] -rand = ["rand_core"] -weierstrass = [] +ecdh = ["zeroize"] std = ["alloc"] [package.metadata.docs.rs] diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 16c8dff03..1f49f1267 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -29,23 +29,20 @@ pub mod error; pub mod ops; pub mod point; pub mod scalar; +pub mod sec1; pub mod secret_key; pub mod util; +pub mod weierstrass; #[cfg(feature = "ecdh")] #[cfg_attr(docsrs, doc(cfg(feature = "ecdh")))] pub mod ecdh; -#[cfg(feature = "weierstrass")] -#[cfg_attr(docsrs, doc(cfg(feature = "weierstrass")))] -pub mod sec1; - -#[cfg(feature = "weierstrass")] -#[cfg_attr(docsrs, doc(cfg(feature = "weierstrass")))] -pub mod weierstrass; - pub use self::{error::Error, secret_key::SecretKey}; +pub use ff; pub use generic_array::{self, typenum::consts}; +pub use group; +pub use rand_core; pub use subtle; #[cfg(feature = "digest")] @@ -54,9 +51,6 @@ pub use digest::{self, Digest}; #[cfg(feature = "oid")] pub use oid; -#[cfg(feature = "rand")] -pub use rand_core; - #[cfg(feature = "zeroize")] pub use zeroize; @@ -65,10 +59,8 @@ use core::{ ops::{Add, Mul}, }; use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; -use subtle::{ConditionallySelectable, ConstantTimeEq, CtOption}; - -#[cfg(feature = "rand")] use rand_core::{CryptoRng, RngCore}; +use subtle::{ConditionallySelectable, ConstantTimeEq, CtOption}; /// Byte array containing a serialized scalar value (i.e. an integer) pub type ElementBytes = GenericArray::FieldSize>; @@ -114,6 +106,14 @@ pub trait FromBytes: ConditionallySelectable + Sized { fn from_bytes(bytes: &GenericArray) -> CtOption; } +/// Randomly generate a value. +/// +/// Primarily intended for use with scalar types for a particular curve. +pub trait Generate { + /// Generate a random element of this type using the provided [`CryptoRng`] + fn generate(rng: impl CryptoRng + RngCore) -> Self; +} + /// Instantiate this type from the output of a digest. /// /// This can be used for implementing hash-to-scalar (e.g. as in ECDSA) or @@ -127,16 +127,6 @@ pub trait FromDigest { D: Digest; } -/// Randomly generate a value. -/// -/// Primarily intended for use with scalar types for a particular curve. -#[cfg(feature = "rand")] -#[cfg_attr(docsrs, doc(cfg(feature = "rand")))] -pub trait Generate { - /// Generate a random element of this type using the provided [`CryptoRng`] - fn generate(rng: impl CryptoRng + RngCore) -> Self; -} - /// Associate an object identifier (OID) with a curve #[cfg(feature = "oid")] #[cfg_attr(docsrs, doc(cfg(feature = "oid")))] diff --git a/elliptic-curve/src/scalar.rs b/elliptic-curve/src/scalar.rs index fe49556c8..535e064eb 100644 --- a/elliptic-curve/src/scalar.rs +++ b/elliptic-curve/src/scalar.rs @@ -1,14 +1,12 @@ //! Scalar types -use crate::{ops::Invert, Arithmetic, Curve, ElementBytes, FromBytes}; -use core::ops::Deref; -use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; - -#[cfg(feature = "rand")] use crate::{ + ops::Invert, rand_core::{CryptoRng, RngCore}, - Generate, + Arithmetic, Curve, ElementBytes, FromBytes, Generate, }; +use core::ops::Deref; +use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; #[cfg(feature = "zeroize")] use zeroize::Zeroize; @@ -109,7 +107,6 @@ where } } -#[cfg(feature = "rand")] impl Generate for NonZeroScalar where C: Curve + Arithmetic, diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 275f7601c..263c0111c 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -8,17 +8,13 @@ //! zeroing it out of memory securely on drop. use crate::{error::Error, Curve, ElementBytes}; +use crate::{Arithmetic, Generate}; use core::{ convert::{TryFrom, TryInto}, fmt::{self, Debug}, }; use generic_array::{typenum::Unsigned, GenericArray}; - -#[cfg(feature = "rand")] -use { - crate::{Arithmetic, Generate}, - rand_core::{CryptoRng, RngCore}, -}; +use rand_core::{CryptoRng, RngCore}; /// Elliptic curve secret keys. /// @@ -68,8 +64,6 @@ impl Debug for SecretKey { } } -#[cfg(feature = "rand")] -#[cfg_attr(docsrs, doc(cfg(feature = "rand")))] impl Generate for SecretKey where C: Curve + Arithmetic, From 88d462bd5c94a1b1dbf3f2f5375fdfc406b35293 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 8 Sep 2020 11:12:33 -0700 Subject: [PATCH 0223/1461] elliptic-curve: bump minimum subtle version to 2.3 (#290) This version has the following extremely useful impls: - `From for Option` - `ConstantTimeEq` for `Choice` There is a bunch of code in `RustCrypto/elliptic-curve` that can be cleaned up/simplified assuming these are available. --- Cargo.lock | 8 ++++---- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 24ef4d73a..fa376a930 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -315,15 +315,15 @@ dependencies = [ [[package]] name = "subtle" -version = "2.2.3" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "502d53007c02d7605a05df1c1a73ee436952781653da5d0bf57ad608f66932c1" +checksum = "343f3f510c2915908f155e94f17220b19ccfacf2a64a2a5d8004f2c3e311e7fd" [[package]] name = "syn" -version = "1.0.39" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891d8d6567fe7c7f8835a3a98af4208f3846fba258c1bc3c31d6e506239f11f9" +checksum = "963f7d3cc59b59b9325165add223142bbf1df27655d07789f109896d353d8350" dependencies = [ "proc-macro2", "quote", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index aeaaa62da..a0bfa761f 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -21,7 +21,7 @@ group = { version = "0.7", default-features = false } generic-array = { version = "0.14", default-features = false } oid = { package = "const-oid", version = "0.1", optional = true } rand_core = { version = "0.5", default-features = false } -subtle = { version = "2.2", default-features = false } +subtle = { version = "2.3", default-features = false } zeroize = { version = "1", optional = true, default-features = false } [dev-dependencies] From c83f980eaa82277e522cb656842b964efaad83c0 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 8 Sep 2020 12:30:46 -0700 Subject: [PATCH 0224/1461] elliptic-curve: add `ff` and `group` bounds on Arithmetic trait (#291) Adds the following: - `Arithmetic::ProjectivePoint` associated type with `group::Curve` and `group::Group` bounds - `Arithmetic::Scalar` is now bounded by `ff::PrimeField` --- elliptic-curve/src/lib.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 1f49f1267..3bcd5b974 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -84,13 +84,17 @@ pub trait Curve: Clone + Debug + Default + Eq + Ord + Send + Sync { /// Elliptic curve with curve arithmetic support pub trait Arithmetic: Curve { - /// Scalar type for a given curve - type Scalar: ConditionallySelectable + /// Scalar type for a given curve. + type Scalar: ff::PrimeField + ConstantTimeEq + Default + FromBytes + Into>; + /// Elliptic curve point in projective coordinates. + type ProjectivePoint: group::Curve + + group::Group; + /// Affine point type for a given curve type AffinePoint: ConditionallySelectable + Mul, Output = Self::AffinePoint> From 16ccdc2c7e4d9a7d5cd92907c40154cffd937b88 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 8 Sep 2020 17:16:02 -0700 Subject: [PATCH 0225/1461] elliptic-curve: bump `ff` and `group` to v0.8 releases; MSRV 1.44 (#292) --- .github/workflows/cryptography.yml | 4 +-- .github/workflows/elliptic-curve.yml | 4 +-- .github/workflows/workspace.yml | 2 +- Cargo.lock | 41 ++++++++++++++++++++++++---- Cargo.toml | 3 -- cryptography/README.md | 4 +-- elliptic-curve/Cargo.toml | 4 +-- elliptic-curve/README.md | 4 +-- elliptic-curve/src/lib.rs | 2 +- 9 files changed, 47 insertions(+), 21 deletions(-) diff --git a/.github/workflows/cryptography.yml b/.github/workflows/cryptography.yml index d3059d888..e3639cc57 100644 --- a/.github/workflows/cryptography.yml +++ b/.github/workflows/cryptography.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.41.0 # MSRV + - 1.44.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -42,7 +42,7 @@ jobs: strategy: matrix: rust: - - 1.41.0 # MSRV + - 1.44.0 # MSRV - stable steps: - uses: actions/checkout@v1 diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index 0a251428b..5e43712e1 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.41.0 # MSRV + - 1.44.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -41,7 +41,7 @@ jobs: strategy: matrix: rust: - - 1.41.0 # MSRV + - 1.44.0 # MSRV - stable steps: - uses: actions/checkout@v1 diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index 57a726c7d..87efa633d 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -17,7 +17,7 @@ jobs: - uses: actions-rs/toolchain@v1 with: profile: minimal - toolchain: 1.41.0 + toolchain: 1.44.0 # Highest MSRV in repo components: clippy - run: cargo clippy --all --all-features -- -D warnings rustfmt: diff --git a/Cargo.lock b/Cargo.lock index fa376a930..747877e70 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,6 +20,17 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "bitvec" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c1f0df4bb4c441080e98d6ea2dc3281fc19bb440e69ce03075e3d705894f1cb" +dependencies = [ + "funty", + "radium", + "wyz", +] + [[package]] name = "blobby" version = "0.2.0" @@ -140,15 +151,21 @@ dependencies = [ [[package]] name = "ff" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01d11efdc125f2647dde5a0f5f88010a5b0f89b700f86052afa1d148c4696047" +checksum = "01646e077d4ebda82b73f1bca002ea1e91561a77df2431a9e79729bcc31950ef" dependencies = [ - "byteorder", + "bitvec", "rand_core", "subtle", ] +[[package]] +name = "funty" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ba62103ce691c2fd80fbae2213dfdda9ce60804973ac6b6e97de818ea7f52c8" + [[package]] name = "generic-array" version = "0.12.3" @@ -179,10 +196,10 @@ dependencies = [ [[package]] name = "group" -version = "0.7.0" -source = "git+https://github.com/zkcrypto/group.git#2942324876cdbb5c94140ad39ae83da642c30374" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc11f9f5fbf1943b48ae7c2bf6846e7d827a512d1be4f23af708f5ca5d01dde1" dependencies = [ - "byteorder", "ff", "rand_core", "subtle", @@ -258,6 +275,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "radium" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "def50a86306165861203e7f84ecffbbdfdea79f0e51039b33de1e952358c47ac" + [[package]] name = "rand_core" version = "0.5.1" @@ -368,6 +391,12 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" +[[package]] +name = "wyz" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" + [[package]] name = "zeroize" version = "1.1.0" diff --git a/Cargo.toml b/Cargo.toml index 7da963005..aa9d7d9c4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,3 @@ members = [ "stream-cipher", "universal-hash", ] - -[patch.crates-io] -group = { git = "https://github.com/zkcrypto/group.git" } diff --git a/cryptography/README.md b/cryptography/README.md index 668849958..82b3a4adf 100644 --- a/cryptography/README.md +++ b/cryptography/README.md @@ -13,7 +13,7 @@ access compatible versions of all traits from the Rust Crypto project. ## Minimum Supported Rust Version -Rust **1.41** or higher. +Rust **1.44** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -45,7 +45,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/cryptography/badge.svg [docs-link]: https://docs.rs/cryptography/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.44+-blue.svg [build-image]: https://github.com/RustCrypto/traits/workflows/cryptography/badge.svg?branch=master&event=push [build-link]: https://github.com/RustCrypto/traits/actions?query=workflow%3Acryptography diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index a0bfa761f..da50dd4b0 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -16,8 +16,8 @@ keywords = ["crypto", "ecc", "elliptic", "weierstrass"] [dependencies] digest = { version = "0.9", optional = true } -ff = { version = "0.7", default-features = false } -group = { version = "0.7", default-features = false } +ff = { version = "0.8", default-features = false } +group = { version = "0.8", default-features = false } generic-array = { version = "0.14", default-features = false } oid = { package = "const-oid", version = "0.1", optional = true } rand_core = { version = "0.5", default-features = false } diff --git a/elliptic-curve/README.md b/elliptic-curve/README.md index 5b7e92ba9..f155859c4 100644 --- a/elliptic-curve/README.md +++ b/elliptic-curve/README.md @@ -14,7 +14,7 @@ and public/secret keys composed thereof. ## Minimum Supported Rust Version -All crates in this repository support Rust **1.41** or higher. +Requires Rust **1.44** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -46,6 +46,6 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/elliptic-curve/badge.svg [docs-link]: https://docs.rs/elliptic-curve/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.44+-blue.svg [build-image]: https://github.com/RustCrypto/elliptic-curves/workflows/elliptic-curve%20crate/badge.svg?branch=master&event=push [build-link]: https://github.com/RustCrypto/elliptic-curves/actions?query=workflow%3A%22elliptic-curve+crate%22 diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 3bcd5b974..2bd5c04c1 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -4,7 +4,7 @@ //! //! ## Minimum Supported Rust Version //! -//! Rust **1.41** or higher. +//! Rust **1.44** or higher. //! //! Minimum supported Rust version can be changed in the future, but it will be //! done with a minor version bump. From 10505b957056995c15ebbc1acaa3a6da97af59c4 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 8 Sep 2020 17:22:13 -0700 Subject: [PATCH 0226/1461] elliptic-curve: reorder Arithmetic associated types --- elliptic-curve/src/lib.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 2bd5c04c1..aa874d451 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -84,21 +84,21 @@ pub trait Curve: Clone + Debug + Default + Eq + Ord + Send + Sync { /// Elliptic curve with curve arithmetic support pub trait Arithmetic: Curve { - /// Scalar type for a given curve. + /// Scalar field element modulo the curve's order. type Scalar: ff::PrimeField + ConstantTimeEq + Default + FromBytes + Into>; - /// Elliptic curve point in projective coordinates. - type ProjectivePoint: group::Curve - + group::Group; - - /// Affine point type for a given curve + /// Elliptic curve point in affine coordinates. type AffinePoint: ConditionallySelectable + Mul, Output = Self::AffinePoint> + point::Generator; + + /// Elliptic curve point in projective coordinates. + type ProjectivePoint: group::Curve + + group::Group; } /// Try to decode the given bytes into a curve element From 0edd4917507811f4f89e07ba282edc11c1b9699b Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 8 Sep 2020 17:25:02 -0700 Subject: [PATCH 0227/1461] elliptic-curve: fix formatting --- elliptic-curve/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index aa874d451..e1849ddd7 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -82,7 +82,7 @@ pub trait Curve: Clone + Debug + Default + Eq + Ord + Send + Sync { type FieldSize: ArrayLength + Add + Eq + Ord + Unsigned; } -/// Elliptic curve with curve arithmetic support +/// Elliptic curve with arithmetic implementation. pub trait Arithmetic: Curve { /// Scalar field element modulo the curve's order. type Scalar: ff::PrimeField @@ -98,7 +98,7 @@ pub trait Arithmetic: Curve { /// Elliptic curve point in projective coordinates. type ProjectivePoint: group::Curve - + group::Group; + + group::Group; } /// Try to decode the given bytes into a curve element From 59e67e05cb30194e1af8aa81a30fd33872d904a6 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 8 Sep 2020 18:51:20 -0700 Subject: [PATCH 0228/1461] elliptic-curve: add `arithmetic` feature (#293) This crate now has a large(r) number of dependencies via the `ff` and `group` crates (notably the recently introduced `bitvec` and its transitive dependencies). This commit adds an `arithmetic` feature and gates related functionality under it, along with the `ff` and `group` crate dependencies. This ensures these dependencies (and their transitive dependencies) can be excluded when the `arithmetic` features of elliptic curve implementations are non-existent or an associated feature disabled. --- .github/workflows/elliptic-curve.yml | 1 + Cargo.lock | 1 + elliptic-curve/Cargo.toml | 10 ++++--- elliptic-curve/src/lib.rs | 39 +++++++++++++++++++++------- elliptic-curve/src/ops.rs | 2 ++ elliptic-curve/src/sec1.rs | 21 +++++++++------ elliptic-curve/src/secret_key.rs | 8 ++++-- 7 files changed, 59 insertions(+), 23 deletions(-) diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index 5e43712e1..65b73fe51 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -36,6 +36,7 @@ jobs: target: ${{ matrix.target }} override: true - run: cargo build --no-default-features --release --target ${{ matrix.target }} + - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features arithmetic test: runs-on: ubuntu-latest strategy: diff --git a/Cargo.lock b/Cargo.lock index 747877e70..0556b4492 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -138,6 +138,7 @@ dependencies = [ name = "elliptic-curve" version = "0.5.0" dependencies = [ + "bitvec", "const-oid", "digest 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "ff", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index da50dd4b0..69cb3301c 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -15,9 +15,10 @@ categories = ["cryptography", "no-std"] keywords = ["crypto", "ecc", "elliptic", "weierstrass"] [dependencies] +bitvec = { version = "0.18", optional = true, default-features = false } digest = { version = "0.9", optional = true } -ff = { version = "0.8", default-features = false } -group = { version = "0.8", default-features = false } +ff = { version = "0.8", optional = true, default-features = false } +group = { version = "0.8", optional = true, default-features = false } generic-array = { version = "0.14", default-features = false } oid = { package = "const-oid", version = "0.1", optional = true } rand_core = { version = "0.5", default-features = false } @@ -28,9 +29,10 @@ zeroize = { version = "1", optional = true, default-features = false } hex-literal = "0.2" [features] -default = [] +default = ["arithmetic"] alloc = [] -ecdh = ["zeroize"] +arithmetic = ["bitvec", "ff", "group"] +ecdh = ["arithmetic", "zeroize"] std = ["alloc"] [package.metadata.docs.rs] diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index e1849ddd7..420e6c934 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -28,23 +28,33 @@ extern crate std; pub mod error; pub mod ops; pub mod point; -pub mod scalar; pub mod sec1; pub mod secret_key; pub mod util; pub mod weierstrass; +#[cfg(feature = "arithmetic")] +#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] +pub mod scalar; + #[cfg(feature = "ecdh")] #[cfg_attr(docsrs, doc(cfg(feature = "ecdh")))] pub mod ecdh; pub use self::{error::Error, secret_key::SecretKey}; -pub use ff; + pub use generic_array::{self, typenum::consts}; -pub use group; pub use rand_core; pub use subtle; +// TODO(tarcieri): source this via ff crate: https://github.com/zkcrypto/ff/pull/40 +#[cfg(feature = "arithmetic")] +pub use bitvec::view::BitView; +#[cfg(feature = "arithmetic")] +pub use ff; +#[cfg(feature = "arithmetic")] +pub use group; + #[cfg(feature = "digest")] pub use digest::{self, Digest}; @@ -54,15 +64,24 @@ pub use oid; #[cfg(feature = "zeroize")] pub use zeroize; -use core::{ - fmt::Debug, - ops::{Add, Mul}, -}; +use core::{fmt::Debug, ops::Add}; use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; use rand_core::{CryptoRng, RngCore}; -use subtle::{ConditionallySelectable, ConstantTimeEq, CtOption}; +use subtle::{ConditionallySelectable, CtOption}; + +#[cfg(feature = "arithmetic")] +use bitvec::{array::BitArray, order::Lsb0}; +#[cfg(feature = "arithmetic")] +use core::ops::Mul; +#[cfg(feature = "arithmetic")] +use subtle::ConstantTimeEq; + +/// Bit representation of a scalar field element of a given curve. +#[cfg(feature = "arithmetic")] +#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] +pub type FieldBits = BitArray::Scalar as ff::PrimeField>::ReprBits>; -/// Byte array containing a serialized scalar value (i.e. an integer) +/// Byte representation of a base/scalar field element of a given curve. pub type ElementBytes = GenericArray::FieldSize>; /// Elliptic curve. @@ -83,6 +102,8 @@ pub trait Curve: Clone + Debug + Default + Eq + Ord + Send + Sync { } /// Elliptic curve with arithmetic implementation. +#[cfg(feature = "arithmetic")] +#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub trait Arithmetic: Curve { /// Scalar field element modulo the curve's order. type Scalar: ff::PrimeField diff --git a/elliptic-curve/src/ops.rs b/elliptic-curve/src/ops.rs index 09f811d7e..f499c01de 100644 --- a/elliptic-curve/src/ops.rs +++ b/elliptic-curve/src/ops.rs @@ -1,5 +1,7 @@ //! Traits for arithmetic operations on elliptic curve field elements +pub use core::ops::{Add, Mul}; + use subtle::CtOption; /// Perform an inversion on a field element (i.e. base field element or scalar) diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index 3c58397cb..24e418e30 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -5,25 +5,26 @@ //! //! -use crate::{ - point::Generator, - scalar::NonZeroScalar, - weierstrass::{point::Decompress, Curve}, - Arithmetic, ElementBytes, Error, FromBytes, SecretKey, -}; +use crate::{weierstrass::Curve, ElementBytes, Error}; use core::{ fmt::{self, Debug}, - ops::{Add, Mul}, + ops::Add, }; use generic_array::{ typenum::{Unsigned, U1}, ArrayLength, GenericArray, }; -use subtle::{Choice, CtOption}; +use subtle::CtOption; #[cfg(feature = "alloc")] use alloc::boxed::Box; +#[cfg(feature = "arithmetic")] +use crate::{ + ops::Mul, point::Generator, scalar::NonZeroScalar, subtle::Choice, + weierstrass::point::Decompress, Arithmetic, FromBytes, SecretKey, +}; + #[cfg(feature = "zeroize")] use zeroize::Zeroize; @@ -124,6 +125,8 @@ where /// [`SecretKey`]. /// /// The `compress` flag requests point compression. + #[cfg(feature = "arithmetic")] + #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub fn from_secret_key(secret_key: &SecretKey, compress: bool) -> Result where C: Arithmetic, @@ -170,6 +173,8 @@ where } /// Decompress this [`EncodedPoint`], returning a new [`EncodedPoint`]. + #[cfg(feature = "arithmetic")] + #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub fn decompress(&self) -> CtOption where C: Arithmetic, diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 263c0111c..76f57ef18 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -8,12 +8,15 @@ //! zeroing it out of memory securely on drop. use crate::{error::Error, Curve, ElementBytes}; -use crate::{Arithmetic, Generate}; use core::{ convert::{TryFrom, TryInto}, fmt::{self, Debug}, }; use generic_array::{typenum::Unsigned, GenericArray}; + +#[cfg(feature = "arithmetic")] +use crate::{scalar::NonZeroScalar, Arithmetic, Generate}; +#[cfg(feature = "arithmetic")] use rand_core::{CryptoRng, RngCore}; /// Elliptic curve secret keys. @@ -64,6 +67,7 @@ impl Debug for SecretKey { } } +#[cfg(feature = "arithmetic")] impl Generate for SecretKey where C: Curve + Arithmetic, @@ -72,7 +76,7 @@ where /// Generate a new [`SecretKey`] fn generate(rng: impl CryptoRng + RngCore) -> Self { Self { - scalar: C::Scalar::generate(rng).into(), + scalar: NonZeroScalar::::generate(rng).into(), } } } From 548e11779ea85d411daa39214afcd7cc6c72c2b8 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 8 Sep 2020 21:15:30 -0700 Subject: [PATCH 0229/1461] elliptic-curve: rename FieldBits to ScalarBits (#294) This is a property of the scalar field specifically and importantly retains properties of the internal representation. --- elliptic-curve/src/lib.rs | 7 ------- elliptic-curve/src/scalar.rs | 4 ++++ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 420e6c934..2de20f477 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -69,18 +69,11 @@ use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; use rand_core::{CryptoRng, RngCore}; use subtle::{ConditionallySelectable, CtOption}; -#[cfg(feature = "arithmetic")] -use bitvec::{array::BitArray, order::Lsb0}; #[cfg(feature = "arithmetic")] use core::ops::Mul; #[cfg(feature = "arithmetic")] use subtle::ConstantTimeEq; -/// Bit representation of a scalar field element of a given curve. -#[cfg(feature = "arithmetic")] -#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] -pub type FieldBits = BitArray::Scalar as ff::PrimeField>::ReprBits>; - /// Byte representation of a base/scalar field element of a given curve. pub type ElementBytes = GenericArray::FieldSize>; diff --git a/elliptic-curve/src/scalar.rs b/elliptic-curve/src/scalar.rs index 535e064eb..ba5411497 100644 --- a/elliptic-curve/src/scalar.rs +++ b/elliptic-curve/src/scalar.rs @@ -5,12 +5,16 @@ use crate::{ rand_core::{CryptoRng, RngCore}, Arithmetic, Curve, ElementBytes, FromBytes, Generate, }; +use bitvec::{array::BitArray, order::Lsb0}; use core::ops::Deref; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; #[cfg(feature = "zeroize")] use zeroize::Zeroize; +/// Bit representation of a scalar field element of a given curve. +pub type ScalarBits = BitArray::Scalar as ff::PrimeField>::ReprBits>; + /// Non-zero scalar type. /// /// This type ensures that its value is not zero, ala `core::num::NonZero*`. From a866a23ab066bc89d000f0931dec9f915d6a8986 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 9 Sep 2020 08:14:51 -0700 Subject: [PATCH 0230/1461] elliptic-curve: remove `Generate` trait (#295) The functionality it previously provided as a trait is now available via methods like `Field::random` and `Group::random`. The other places where it was being used have been converted to inherent methods on concrete types, which is easier to use because there's no need to import a trait. --- elliptic-curve/src/ecdh.rs | 18 ++++++++-------- elliptic-curve/src/lib.rs | 9 -------- elliptic-curve/src/ops.rs | 11 +++++++++- elliptic-curve/src/scalar.rs | 36 ++++++++++++++------------------ elliptic-curve/src/secret_key.rs | 28 ++++++++++++------------- 5 files changed, 48 insertions(+), 54 deletions(-) diff --git a/elliptic-curve/src/ecdh.rs b/elliptic-curve/src/ecdh.rs index 75ea4ba85..64b29328f 100644 --- a/elliptic-curve/src/ecdh.rs +++ b/elliptic-curve/src/ecdh.rs @@ -27,7 +27,7 @@ use crate::{ scalar::NonZeroScalar, sec1::{self, FromEncodedPoint, UncompressedPointSize, UntaggedPointSize}, weierstrass::Curve, - Arithmetic, ElementBytes, Error, Generate, + Arithmetic, ElementBytes, Error, }; use core::ops::{Add, Mul}; use rand_core::{CryptoRng, RngCore}; @@ -45,7 +45,7 @@ pub type PublicKey = sec1::EncodedPoint; pub struct EphemeralSecret where C: Curve + Arithmetic, - C::Scalar: Generate + Zeroize, + C::Scalar: Zeroize, { scalar: NonZeroScalar, } @@ -53,15 +53,15 @@ where impl EphemeralSecret where C: Curve + Arithmetic, - C::Scalar: Clone + Generate + Zeroize, + C::Scalar: Clone + Zeroize, C::AffinePoint: FromEncodedPoint + Mul, Output = C::AffinePoint> + Zeroize, PublicKey: From, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { - /// Generate a new [`EphemeralSecret`]. - pub fn generate(rng: impl CryptoRng + RngCore) -> Self { - let scalar = NonZeroScalar::generate(rng); + /// Generate a cryptographically random [`EphemeralSecret`]. + pub fn random(rng: impl CryptoRng + RngCore) -> Self { + let scalar = NonZeroScalar::random(rng); Self { scalar } } @@ -89,7 +89,7 @@ where impl From<&EphemeralSecret> for PublicKey where C: Curve + Arithmetic, - C::Scalar: Clone + Generate + Zeroize, + C::Scalar: Clone + Zeroize, C::AffinePoint: FromEncodedPoint + Mul, Output = C::AffinePoint> + Zeroize, PublicKey: From, UntaggedPointSize: Add + ArrayLength, @@ -103,7 +103,7 @@ where impl Zeroize for EphemeralSecret where C: Curve + Arithmetic, - C::Scalar: Generate + Zeroize, + C::Scalar: Zeroize, { fn zeroize(&mut self) { self.scalar.zeroize() @@ -113,7 +113,7 @@ where impl Drop for EphemeralSecret where C: Curve + Arithmetic, - C::Scalar: Generate + Zeroize, + C::Scalar: Zeroize, { fn drop(&mut self) { self.zeroize(); diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 2de20f477..576c7d4ad 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -66,7 +66,6 @@ pub use zeroize; use core::{fmt::Debug, ops::Add}; use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; -use rand_core::{CryptoRng, RngCore}; use subtle::{ConditionallySelectable, CtOption}; #[cfg(feature = "arithmetic")] @@ -124,14 +123,6 @@ pub trait FromBytes: ConditionallySelectable + Sized { fn from_bytes(bytes: &GenericArray) -> CtOption; } -/// Randomly generate a value. -/// -/// Primarily intended for use with scalar types for a particular curve. -pub trait Generate { - /// Generate a random element of this type using the provided [`CryptoRng`] - fn generate(rng: impl CryptoRng + RngCore) -> Self; -} - /// Instantiate this type from the output of a digest. /// /// This can be used for implementing hash-to-scalar (e.g. as in ECDSA) or diff --git a/elliptic-curve/src/ops.rs b/elliptic-curve/src/ops.rs index f499c01de..fe6ffe75c 100644 --- a/elliptic-curve/src/ops.rs +++ b/elliptic-curve/src/ops.rs @@ -1,6 +1,6 @@ //! Traits for arithmetic operations on elliptic curve field elements -pub use core::ops::{Add, Mul}; +pub use core::ops::{Add, AddAssign, Mul, Neg, Sub, SubAssign}; use subtle::CtOption; @@ -12,3 +12,12 @@ pub trait Invert { /// Invert a field element. fn invert(&self) -> CtOption; } + +#[cfg(feature = "arithmetic")] +impl Invert for F { + type Output = F; + + fn invert(&self) -> CtOption { + ff::Field::invert(self) + } +} diff --git a/elliptic-curve/src/scalar.rs b/elliptic-curve/src/scalar.rs index ba5411497..924073b25 100644 --- a/elliptic-curve/src/scalar.rs +++ b/elliptic-curve/src/scalar.rs @@ -3,10 +3,11 @@ use crate::{ ops::Invert, rand_core::{CryptoRng, RngCore}, - Arithmetic, Curve, ElementBytes, FromBytes, Generate, + Arithmetic, Curve, ElementBytes, FromBytes, }; use bitvec::{array::BitArray, order::Lsb0}; use core::ops::Deref; +use ff::Field; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; #[cfg(feature = "zeroize")] @@ -32,6 +33,18 @@ impl NonZeroScalar where C: Curve + Arithmetic, { + /// Generate a random `NonZeroScalar` + pub fn random(mut rng: impl CryptoRng + RngCore) -> Self { + // Use rejection sampling to eliminate zero values + loop { + let result = Self::new(C::Scalar::random(&mut rng)); + + if result.is_some().into() { + break result.unwrap(); + } + } + } + /// Create a [`NonZeroScalar`] from a scalar, performing a constant-time /// check that it's non-zero. pub fn new(scalar: C::Scalar) -> CtOption { @@ -103,28 +116,11 @@ where C: Curve + Arithmetic, C::Scalar: Invert, { - type Output = ::Output; + type Output = C::Scalar; /// Perform a scalar inversion fn invert(&self) -> CtOption { - self.scalar.invert() - } -} - -impl Generate for NonZeroScalar -where - C: Curve + Arithmetic, - C::Scalar: Generate, -{ - fn generate(mut rng: impl CryptoRng + RngCore) -> Self { - // Use rejection sampling to eliminate zero values - loop { - let result = Self::new(C::Scalar::generate(&mut rng)); - - if result.is_some().into() { - break result.unwrap(); - } - } + ff::Field::invert(&self.scalar) } } diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 76f57ef18..1bf80d3f6 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -15,7 +15,7 @@ use core::{ use generic_array::{typenum::Unsigned, GenericArray}; #[cfg(feature = "arithmetic")] -use crate::{scalar::NonZeroScalar, Arithmetic, Generate}; +use crate::{scalar::NonZeroScalar, Arithmetic}; #[cfg(feature = "arithmetic")] use rand_core::{CryptoRng, RngCore}; @@ -31,6 +31,18 @@ pub struct SecretKey { } impl SecretKey { + /// Generate a random [`SecretKey`] + #[cfg(feature = "arithmetic")] + #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] + pub fn random(rng: impl CryptoRng + RngCore) -> Self + where + C: Arithmetic, + { + Self { + scalar: NonZeroScalar::::random(rng).into(), + } + } + /// Create a new secret key from a serialized scalar value pub fn new(bytes: ElementBytes) -> Self { Self { scalar: bytes } @@ -67,20 +79,6 @@ impl Debug for SecretKey { } } -#[cfg(feature = "arithmetic")] -impl Generate for SecretKey -where - C: Curve + Arithmetic, - C::Scalar: Generate + Into>, -{ - /// Generate a new [`SecretKey`] - fn generate(rng: impl CryptoRng + RngCore) -> Self { - Self { - scalar: NonZeroScalar::::generate(rng).into(), - } - } -} - #[cfg(feature = "zeroize")] impl Drop for SecretKey { fn drop(&mut self) { From 24ce4e1bda977a7f41af203eb3cbd3fa0e906b93 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 9 Sep 2020 09:29:53 -0700 Subject: [PATCH 0231/1461] elliptic-curve: rename ElementBytes => FieldBytes (#296) Makes it clearer this refers to a field element. --- elliptic-curve/src/ecdh.rs | 6 +++--- elliptic-curve/src/lib.rs | 4 ++-- elliptic-curve/src/scalar.rs | 10 +++++----- elliptic-curve/src/sec1.rs | 18 +++++++----------- elliptic-curve/src/secret_key.rs | 8 ++++---- elliptic-curve/src/weierstrass/point.rs | 4 ++-- 6 files changed, 23 insertions(+), 27 deletions(-) diff --git a/elliptic-curve/src/ecdh.rs b/elliptic-curve/src/ecdh.rs index 64b29328f..b66929263 100644 --- a/elliptic-curve/src/ecdh.rs +++ b/elliptic-curve/src/ecdh.rs @@ -27,7 +27,7 @@ use crate::{ scalar::NonZeroScalar, sec1::{self, FromEncodedPoint, UncompressedPointSize, UntaggedPointSize}, weierstrass::Curve, - Arithmetic, ElementBytes, Error, + Arithmetic, Error, FieldBytes, }; use core::ops::{Add, Mul}; use rand_core::{CryptoRng, RngCore}; @@ -135,7 +135,7 @@ where /// Function (KDF) or cryptographic hash function to produce a symmetric key. pub struct SharedSecret { /// Computed secret value - secret_bytes: ElementBytes, + secret_bytes: FieldBytes, } impl SharedSecret @@ -158,7 +158,7 @@ where /// should not be used directly as a symmetric encryption key, but instead /// as input to a KDF (or failing that, a hash function) used to produce /// a symmetric key. - pub fn as_bytes(&self) -> &ElementBytes { + pub fn as_bytes(&self) -> &FieldBytes { &self.secret_bytes } } diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 576c7d4ad..c1dbd3a0f 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -74,7 +74,7 @@ use core::ops::Mul; use subtle::ConstantTimeEq; /// Byte representation of a base/scalar field element of a given curve. -pub type ElementBytes = GenericArray::FieldSize>; +pub type FieldBytes = GenericArray::FieldSize>; /// Elliptic curve. /// @@ -102,7 +102,7 @@ pub trait Arithmetic: Curve { + ConstantTimeEq + Default + FromBytes - + Into>; + + Into>; /// Elliptic curve point in affine coordinates. type AffinePoint: ConditionallySelectable diff --git a/elliptic-curve/src/scalar.rs b/elliptic-curve/src/scalar.rs index 924073b25..dafae3425 100644 --- a/elliptic-curve/src/scalar.rs +++ b/elliptic-curve/src/scalar.rs @@ -3,7 +3,7 @@ use crate::{ ops::Invert, rand_core::{CryptoRng, RngCore}, - Arithmetic, Curve, ElementBytes, FromBytes, + Arithmetic, Curve, FieldBytes, FromBytes, }; use bitvec::{array::BitArray, order::Lsb0}; use core::ops::Deref; @@ -54,7 +54,7 @@ where } /// Serialize this [`NonZeroScalar`] as a byte array - pub fn to_bytes(&self) -> ElementBytes { + pub fn to_bytes(&self) -> FieldBytes { self.scalar.into() } } @@ -97,16 +97,16 @@ where { type Size = C::FieldSize; - fn from_bytes(bytes: &ElementBytes) -> CtOption { + fn from_bytes(bytes: &FieldBytes) -> CtOption { C::Scalar::from_bytes(bytes).and_then(Self::new) } } -impl From> for ElementBytes +impl From> for FieldBytes where C: Curve + Arithmetic, { - fn from(scalar: NonZeroScalar) -> ElementBytes { + fn from(scalar: NonZeroScalar) -> FieldBytes { scalar.to_bytes() } } diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index 24e418e30..7446dab34 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -5,7 +5,7 @@ //! //! -use crate::{weierstrass::Curve, ElementBytes, Error}; +use crate::{weierstrass::Curve, Error, FieldBytes}; use core::{ fmt::{self, Debug}, ops::Add, @@ -97,11 +97,7 @@ where /// Encode an elliptic curve point from big endian serialized coordinates /// (with optional point compression) - pub fn from_affine_coordinates( - x: &ElementBytes, - y: &ElementBytes, - compress: bool, - ) -> Self { + pub fn from_affine_coordinates(x: &FieldBytes, y: &FieldBytes, compress: bool) -> Self { let tag = if compress { Tag::compress_y(y.as_slice()) } else { @@ -230,7 +226,7 @@ where } /// Get the x-coordinate for this [`EncodedPoint`] - pub fn x(&self) -> &ElementBytes { + pub fn x(&self) -> &FieldBytes { match self.coordinates() { Coordinates::Compressed { x, .. } => x, Coordinates::Uncompressed { x, .. } => x, @@ -240,7 +236,7 @@ where /// Get the y-coordinate for this [`EncodedPoint`]. /// /// Returns `None` if this point is compressed. - pub fn y(&self) -> Option<&ElementBytes> { + pub fn y(&self) -> Option<&FieldBytes> { match self.coordinates() { Coordinates::Compressed { .. } => None, Coordinates::Uncompressed { y, .. } => Some(y), @@ -299,7 +295,7 @@ pub enum Coordinates<'a, C: Curve> { /// Compressed curve point Compressed { /// x-coordinate - x: &'a ElementBytes, + x: &'a FieldBytes, /// Is the y-coordinate odd? y_is_odd: bool, @@ -308,10 +304,10 @@ pub enum Coordinates<'a, C: Curve> { /// Uncompressed curve point Uncompressed { /// x-coordinate - x: &'a ElementBytes, + x: &'a FieldBytes, /// y-coordinate - y: &'a ElementBytes, + y: &'a FieldBytes, }, } diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 1bf80d3f6..ae11996f7 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -7,7 +7,7 @@ //! When the `zeroize` feature of this crate is enabled, it also handles //! zeroing it out of memory securely on drop. -use crate::{error::Error, Curve, ElementBytes}; +use crate::{error::Error, Curve, FieldBytes}; use core::{ convert::{TryFrom, TryInto}, fmt::{self, Debug}, @@ -27,7 +27,7 @@ use rand_core::{CryptoRng, RngCore}; #[derive(Clone)] pub struct SecretKey { /// Private scalar value - scalar: ElementBytes, + scalar: FieldBytes, } impl SecretKey { @@ -44,7 +44,7 @@ impl SecretKey { } /// Create a new secret key from a serialized scalar value - pub fn new(bytes: ElementBytes) -> Self { + pub fn new(bytes: FieldBytes) -> Self { Self { scalar: bytes } } @@ -54,7 +54,7 @@ impl SecretKey { } /// Expose the byte serialization of the value this [`SecretKey`] wraps - pub fn as_bytes(&self) -> &ElementBytes { + pub fn as_bytes(&self) -> &FieldBytes { &self.scalar } } diff --git a/elliptic-curve/src/weierstrass/point.rs b/elliptic-curve/src/weierstrass/point.rs index 67c3833f2..cd52efe07 100644 --- a/elliptic-curve/src/weierstrass/point.rs +++ b/elliptic-curve/src/weierstrass/point.rs @@ -1,12 +1,12 @@ //! Traits for Weierstrass elliptic curve points use super::Curve; -use crate::ElementBytes; +use crate::FieldBytes; use subtle::{Choice, CtOption}; /// Attempt to decompress an elliptic curve point from its x-coordinate and /// a boolean flag indicating whether or not the y-coordinate is odd. pub trait Decompress: Sized { /// Attempt to decompress an elliptic curve point - fn decompress(x: &ElementBytes, y_is_odd: Choice) -> CtOption; + fn decompress(x: &FieldBytes, y_is_odd: Choice) -> CtOption; } From 7dd78e0097bcc9a5adb84acf043f6e11e33ceacc Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 9 Sep 2020 16:59:59 -0700 Subject: [PATCH 0232/1461] elliptic-curve: make SecretKey inner type generic (#297) Makes `SecretKey` a generic wrapper for an inner zeroizable type, with a blanket impl for curves with an arithmetic backend which uses `NonZeroScalar`. --- .github/workflows/elliptic-curve.yml | 2 + elliptic-curve/src/lib.rs | 9 ++- elliptic-curve/src/sec1.rs | 14 ++-- elliptic-curve/src/secret_key.rs | 102 ++++++++++++++++++++------- 4 files changed, 93 insertions(+), 34 deletions(-) diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index 65b73fe51..a7bb03a89 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -37,6 +37,8 @@ jobs: override: true - run: cargo build --no-default-features --release --target ${{ matrix.target }} - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features arithmetic + - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features zeroize + - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features ecdh test: runs-on: ubuntu-latest strategy: diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index c1dbd3a0f..fdbeafff3 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -29,7 +29,6 @@ pub mod error; pub mod ops; pub mod point; pub mod sec1; -pub mod secret_key; pub mod util; pub mod weierstrass; @@ -41,7 +40,11 @@ pub mod scalar; #[cfg_attr(docsrs, doc(cfg(feature = "ecdh")))] pub mod ecdh; -pub use self::{error::Error, secret_key::SecretKey}; +#[cfg(feature = "zeroize")] +#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] +pub mod secret_key; + +pub use self::error::Error; pub use generic_array::{self, typenum::consts}; pub use rand_core; @@ -61,6 +64,8 @@ pub use digest::{self, Digest}; #[cfg(feature = "oid")] pub use oid; +#[cfg(feature = "zeroize")] +pub use secret_key::SecretKey; #[cfg(feature = "zeroize")] pub use zeroize; diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index 7446dab34..9f687fea1 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -20,10 +20,10 @@ use subtle::CtOption; use alloc::boxed::Box; #[cfg(feature = "arithmetic")] -use crate::{ - ops::Mul, point::Generator, scalar::NonZeroScalar, subtle::Choice, - weierstrass::point::Decompress, Arithmetic, FromBytes, SecretKey, -}; +use crate::{subtle::Choice, weierstrass::point::Decompress, Arithmetic}; + +#[cfg(all(feature = "arithmetic", feature = "zeroize"))] +use crate::{ops::Mul, point::Generator, scalar::NonZeroScalar, secret_key::SecretKey, FromBytes}; #[cfg(feature = "zeroize")] use zeroize::Zeroize; @@ -121,14 +121,16 @@ where /// [`SecretKey`]. /// /// The `compress` flag requests point compression. - #[cfg(feature = "arithmetic")] + #[cfg(all(feature = "arithmetic", feature = "zeroize"))] #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] + #[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] pub fn from_secret_key(secret_key: &SecretKey, compress: bool) -> Result where C: Arithmetic, C::AffinePoint: Mul, Output = C::AffinePoint> + ToEncodedPoint, + C::Scalar: Zeroize, { - let ct_option = C::Scalar::from_bytes(secret_key.as_bytes()).and_then(NonZeroScalar::new); + let ct_option = C::Scalar::from_bytes(&secret_key.to_bytes()).and_then(NonZeroScalar::new); if ct_option.is_none().into() { return Err(Error); diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index ae11996f7..ab92d2870 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -12,77 +12,127 @@ use core::{ convert::{TryFrom, TryInto}, fmt::{self, Debug}, }; -use generic_array::{typenum::Unsigned, GenericArray}; +use subtle::CtOption; +use zeroize::Zeroize; #[cfg(feature = "arithmetic")] -use crate::{scalar::NonZeroScalar, Arithmetic}; +use crate::{scalar::NonZeroScalar, Arithmetic, FromBytes}; #[cfg(feature = "arithmetic")] use rand_core::{CryptoRng, RngCore}; +/// Inner value stored by a [`SecretKey`]. +pub trait SecretValue: Curve { + /// Inner secret value + type Secret: Into> + Zeroize; + + /// Parse the secret value from bytes + fn from_secret_bytes(bytes: &FieldBytes) -> CtOption; +} + +#[cfg(feature = "arithmetic")] +impl SecretValue for C +where + C::Scalar: Zeroize, +{ + type Secret = NonZeroScalar; + + fn from_secret_bytes(bytes: &FieldBytes) -> CtOption> { + NonZeroScalar::from_bytes(bytes) + } +} + /// Elliptic curve secret keys. /// /// This type wraps a serialized scalar value, helping to prevent accidental /// exposure and securely erasing the value from memory when dropped /// (when the `zeroize` feature of this crate is enabled). #[derive(Clone)] -pub struct SecretKey { - /// Private scalar value - scalar: FieldBytes, +pub struct SecretKey { + /// Secret value (i.e. secret scalar) + secret_value: C::Secret, } -impl SecretKey { +impl SecretKey +where + C: Curve + SecretValue, + C::Secret: Clone + Zeroize, + FieldBytes: From, +{ /// Generate a random [`SecretKey`] #[cfg(feature = "arithmetic")] #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub fn random(rng: impl CryptoRng + RngCore) -> Self where - C: Arithmetic, + C: Arithmetic + SecretValue>, { Self { - scalar: NonZeroScalar::::random(rng).into(), + secret_value: NonZeroScalar::::random(rng), } } /// Create a new secret key from a serialized scalar value - pub fn new(bytes: FieldBytes) -> Self { - Self { scalar: bytes } + pub fn new(secret_value: C::Secret) -> Self { + Self { secret_value } } /// Deserialize this secret key from a bytestring pub fn from_bytes(bytes: impl AsRef<[u8]>) -> Result { - bytes.as_ref().try_into() + bytes + .as_ref() + .try_into() + .ok() + .and_then(|bytes| C::from_secret_bytes(bytes).into()) + .map(|secret_value| SecretKey { secret_value }) + .ok_or(Error) } /// Expose the byte serialization of the value this [`SecretKey`] wraps - pub fn as_bytes(&self) -> &FieldBytes { - &self.scalar + pub fn to_bytes(&self) -> FieldBytes { + self.secret_value.clone().into() + } + + /// Borrow the inner secret scalar value. + /// + /// # Notice + /// + /// This value is key material. Please treat it accordingly! + #[cfg(feature = "arithmetic")] + #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] + pub fn secret_scalar(&self) -> &NonZeroScalar + where + C: Arithmetic + SecretValue>, + { + &self.secret_value } } -impl TryFrom<&[u8]> for SecretKey { +impl TryFrom<&[u8]> for SecretKey +where + C: Curve + SecretValue, + C::Secret: Clone + Zeroize, + FieldBytes: From, +{ type Error = Error; fn try_from(slice: &[u8]) -> Result { - if slice.len() == C::FieldSize::to_usize() { - Ok(SecretKey { - scalar: GenericArray::clone_from_slice(slice), - }) - } else { - Err(Error) - } + Self::from_bytes(slice) } } -impl Debug for SecretKey { +impl Debug for SecretKey +where + C: Curve + SecretValue, +{ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "SecretKey<{:?}>{{ ... }}", C::default()) } } -#[cfg(feature = "zeroize")] -impl Drop for SecretKey { +impl Drop for SecretKey +where + C: Curve + SecretValue, +{ fn drop(&mut self) { - use zeroize::Zeroize; - self.scalar.zeroize(); + self.secret_value.zeroize(); } } From a9bd70b727bf4cf069fa3dda5661ed5e1b8286fa Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 9 Sep 2020 21:09:43 -0700 Subject: [PATCH 0233/1461] elliptic-curve: rename and simplify FromFieldBytes (#298) --- elliptic-curve/src/lib.rs | 11 ++++------- elliptic-curve/src/scalar.rs | 12 +++++------- elliptic-curve/src/sec1.rs | 18 ++++++++++-------- elliptic-curve/src/secret_key.rs | 4 ++-- 4 files changed, 21 insertions(+), 24 deletions(-) diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index fdbeafff3..89b6a1288 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -106,7 +106,7 @@ pub trait Arithmetic: Curve { type Scalar: ff::PrimeField + ConstantTimeEq + Default - + FromBytes + + FromFieldBytes + Into>; /// Elliptic curve point in affine coordinates. @@ -119,13 +119,10 @@ pub trait Arithmetic: Curve { + group::Group; } -/// Try to decode the given bytes into a curve element -pub trait FromBytes: ConditionallySelectable + Sized { - /// Size of the serialized byte array - type Size: ArrayLength; - +/// Decode the given serialized field element +pub trait FromFieldBytes: ConditionallySelectable + Sized { /// Try to decode this object from bytes - fn from_bytes(bytes: &GenericArray) -> CtOption; + fn from_field_bytes(bytes: &FieldBytes) -> CtOption; } /// Instantiate this type from the output of a digest. diff --git a/elliptic-curve/src/scalar.rs b/elliptic-curve/src/scalar.rs index dafae3425..f5466d40b 100644 --- a/elliptic-curve/src/scalar.rs +++ b/elliptic-curve/src/scalar.rs @@ -3,7 +3,7 @@ use crate::{ ops::Invert, rand_core::{CryptoRng, RngCore}, - Arithmetic, Curve, FieldBytes, FromBytes, + Arithmetic, Curve, FieldBytes, FromFieldBytes, }; use bitvec::{array::BitArray, order::Lsb0}; use core::ops::Deref; @@ -48,7 +48,7 @@ where /// Create a [`NonZeroScalar`] from a scalar, performing a constant-time /// check that it's non-zero. pub fn new(scalar: C::Scalar) -> CtOption { - let zero = C::Scalar::from_bytes(&Default::default()).unwrap(); + let zero = C::Scalar::from_field_bytes(&Default::default()).unwrap(); let is_zero = scalar.ct_eq(&zero); CtOption::new(Self { scalar }, !is_zero) } @@ -91,14 +91,12 @@ where } } -impl FromBytes for NonZeroScalar +impl FromFieldBytes for NonZeroScalar where C: Curve + Arithmetic, { - type Size = C::FieldSize; - - fn from_bytes(bytes: &FieldBytes) -> CtOption { - C::Scalar::from_bytes(bytes).and_then(Self::new) + fn from_field_bytes(bytes: &FieldBytes) -> CtOption { + C::Scalar::from_field_bytes(bytes).and_then(Self::new) } } diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index 9f687fea1..684509cd7 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -23,7 +23,9 @@ use alloc::boxed::Box; use crate::{subtle::Choice, weierstrass::point::Decompress, Arithmetic}; #[cfg(all(feature = "arithmetic", feature = "zeroize"))] -use crate::{ops::Mul, point::Generator, scalar::NonZeroScalar, secret_key::SecretKey, FromBytes}; +use crate::{ + ops::Mul, point::Generator, scalar::NonZeroScalar, secret_key::SecretKey, FromFieldBytes, +}; #[cfg(feature = "zeroize")] use zeroize::Zeroize; @@ -130,14 +132,14 @@ where C::AffinePoint: Mul, Output = C::AffinePoint> + ToEncodedPoint, C::Scalar: Zeroize, { - let ct_option = C::Scalar::from_bytes(&secret_key.to_bytes()).and_then(NonZeroScalar::new); - - if ct_option.is_none().into() { - return Err(Error); + if let Some(scalar) = C::Scalar::from_field_bytes(&secret_key.to_bytes()) + .and_then(NonZeroScalar::new) + .into() + { + Ok(Self::encode(C::AffinePoint::generator() * scalar, compress)) + } else { + Err(Error) } - - let affine_point = C::AffinePoint::generator() * ct_option.unwrap(); - Ok(Self::encode(affine_point, compress)) } /// Get the length of the encoded point in bytes diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index ab92d2870..661f5bbf1 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -16,7 +16,7 @@ use subtle::CtOption; use zeroize::Zeroize; #[cfg(feature = "arithmetic")] -use crate::{scalar::NonZeroScalar, Arithmetic, FromBytes}; +use crate::{scalar::NonZeroScalar, Arithmetic, FromFieldBytes}; #[cfg(feature = "arithmetic")] use rand_core::{CryptoRng, RngCore}; @@ -37,7 +37,7 @@ where type Secret = NonZeroScalar; fn from_secret_bytes(bytes: &FieldBytes) -> CtOption> { - NonZeroScalar::from_bytes(bytes) + NonZeroScalar::from_field_bytes(bytes) } } From 4b41cda21bd6ac70847866f1a72be66ad9a4e35d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 10 Sep 2020 14:57:40 +0000 Subject: [PATCH 0234/1461] build(deps): bump bitvec from 0.18.1 to 0.18.3 (#299) --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0556b4492..bd8042653 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -22,9 +22,9 @@ dependencies = [ [[package]] name = "bitvec" -version = "0.18.1" +version = "0.18.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c1f0df4bb4c441080e98d6ea2dc3281fc19bb440e69ce03075e3d705894f1cb" +checksum = "64143ed23541fe0c6e2235905eaae37ceae1ca69e14dce4afcd6ec9643359d00" dependencies = [ "funty", "radium", From bba389743c8156036ccd4bbb73755d8bb22fb796 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 11 Sep 2020 07:58:57 -0700 Subject: [PATCH 0235/1461] elliptic-curve: refactor ProjectiveArithmetic trait (#300) Renames the `Arithmetic` trait to `ProjectiveArithmetic` and changes it to have only a single associated type: `ProjectivePoint`. Adds `AffinePoint` and `Scalar` type aliases which are able to look up the corresponding associated type chain (along with `ProjectivePoint` for consistency, although this is available as `::ProjectivePoint`). --- elliptic-curve/src/ecdh.rs | 72 ++++++++----- elliptic-curve/src/lib.rs | 53 +++------- elliptic-curve/src/point.rs | 29 ++++-- elliptic-curve/src/scalar.rs | 131 +++++++++++++++--------- elliptic-curve/src/sec1.rs | 37 ++++--- elliptic-curve/src/secret_key.rs | 40 +++++--- elliptic-curve/src/weierstrass/point.rs | 6 ++ 7 files changed, 214 insertions(+), 154 deletions(-) diff --git a/elliptic-curve/src/ecdh.rs b/elliptic-curve/src/ecdh.rs index b66929263..48e4d6aa7 100644 --- a/elliptic-curve/src/ecdh.rs +++ b/elliptic-curve/src/ecdh.rs @@ -1,7 +1,7 @@ //! Elliptic Curve Diffie-Hellman (Ephemeral) Support. //! //! This module contains a generic ECDH implementation which is usable with -//! any elliptic curve which implements the [`Arithmetic`] trait (presently +//! any elliptic curve which implements the [`ProjectiveArithmetic`] trait (presently //! the `k256` and `p256` crates) //! //! # Usage @@ -23,13 +23,14 @@ use crate::{ consts::U1, generic_array::ArrayLength, - point::Generator, scalar::NonZeroScalar, sec1::{self, FromEncodedPoint, UncompressedPointSize, UntaggedPointSize}, weierstrass::Curve, - Arithmetic, Error, FieldBytes, + AffinePoint, Error, FieldBytes, ProjectiveArithmetic, Scalar, }; use core::ops::{Add, Mul}; +use ff::PrimeField; +use group::{Curve as _, Group}; use rand_core::{CryptoRng, RngCore}; use zeroize::Zeroize; @@ -44,38 +45,43 @@ pub type PublicKey = sec1::EncodedPoint; /// to avoid being persisted. pub struct EphemeralSecret where - C: Curve + Arithmetic, - C::Scalar: Zeroize, + C: Curve + ProjectiveArithmetic, + FieldBytes: From> + for<'r> From<&'r Scalar>, + Scalar: PrimeField> + Zeroize, { scalar: NonZeroScalar, } impl EphemeralSecret where - C: Curve + Arithmetic, - C::Scalar: Clone + Zeroize, - C::AffinePoint: FromEncodedPoint + Mul, Output = C::AffinePoint> + Zeroize, - PublicKey: From, + C: Curve + ProjectiveArithmetic, + FieldBytes: From> + for<'r> From<&'r Scalar>, + Scalar: PrimeField> + Clone + Zeroize, + AffinePoint: FromEncodedPoint + Mul, Output = AffinePoint> + Zeroize, + PublicKey: From>, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { /// Generate a cryptographically random [`EphemeralSecret`]. pub fn random(rng: impl CryptoRng + RngCore) -> Self { - let scalar = NonZeroScalar::random(rng); - Self { scalar } + Self { + scalar: NonZeroScalar::random(rng), + } } /// Get the public key associated with this ephemeral secret. /// /// The `compress` flag enables point compression. pub fn public_key(&self) -> PublicKey { - PublicKey::from(C::AffinePoint::generator() * self.scalar) + (C::ProjectivePoint::generator() * &self.scalar) + .to_affine() + .into() } /// Compute a Diffie-Hellman shared secret from an ephemeral secret and the /// public key of the other participant in the exchange. pub fn diffie_hellman(&self, public_key: &PublicKey) -> Result, Error> { - let affine_point = C::AffinePoint::from_encoded_point(public_key); + let affine_point = AffinePoint::::from_encoded_point(public_key); if affine_point.is_some().into() { let shared_secret = affine_point.unwrap() * self.scalar; @@ -88,10 +94,11 @@ where impl From<&EphemeralSecret> for PublicKey where - C: Curve + Arithmetic, - C::Scalar: Clone + Zeroize, - C::AffinePoint: FromEncodedPoint + Mul, Output = C::AffinePoint> + Zeroize, - PublicKey: From, + C: Curve + ProjectiveArithmetic, + FieldBytes: From> + for<'r> From<&'r Scalar>, + Scalar: PrimeField> + Clone + Zeroize, + AffinePoint: FromEncodedPoint + Mul, Output = AffinePoint> + Zeroize, + PublicKey: From>, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -102,8 +109,9 @@ where impl Zeroize for EphemeralSecret where - C: Curve + Arithmetic, - C::Scalar: Zeroize, + C: Curve + ProjectiveArithmetic, + FieldBytes: From> + for<'r> From<&'r Scalar>, + Scalar: PrimeField> + Zeroize, { fn zeroize(&mut self) { self.scalar.zeroize() @@ -112,8 +120,9 @@ where impl Drop for EphemeralSecret where - C: Curve + Arithmetic, - C::Scalar: Zeroize, + C: Curve + ProjectiveArithmetic, + FieldBytes: From> + for<'r> From<&'r Scalar>, + Scalar: PrimeField> + Zeroize, { fn drop(&mut self) { self.zeroize(); @@ -133,15 +142,22 @@ where /// /// Instead, the resulting value should be used as input to a Key Derivation /// Function (KDF) or cryptographic hash function to produce a symmetric key. -pub struct SharedSecret { +pub struct SharedSecret +where + C: Curve + ProjectiveArithmetic, + FieldBytes: From> + for<'r> From<&'r Scalar>, + Scalar: PrimeField>, +{ /// Computed secret value secret_bytes: FieldBytes, } impl SharedSecret where - C: Curve + Arithmetic, - C::AffinePoint: Zeroize, + C: Curve + ProjectiveArithmetic, + FieldBytes: From> + for<'r> From<&'r Scalar>, + Scalar: PrimeField>, + AffinePoint: Zeroize, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -165,7 +181,9 @@ where impl Zeroize for SharedSecret where - C: Curve + Arithmetic, + C: Curve + ProjectiveArithmetic, + FieldBytes: From> + for<'r> From<&'r Scalar>, + Scalar: PrimeField>, { fn zeroize(&mut self) { self.secret_bytes.zeroize() @@ -174,7 +192,9 @@ where impl Drop for SharedSecret where - C: Curve + Arithmetic, + C: Curve + ProjectiveArithmetic, + FieldBytes: From> + for<'r> From<&'r Scalar>, + Scalar: PrimeField>, { fn drop(&mut self) { self.zeroize(); diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 89b6a1288..53c7a72dc 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -27,11 +27,13 @@ extern crate std; pub mod error; pub mod ops; -pub mod point; pub mod sec1; pub mod util; pub mod weierstrass; +#[cfg(feature = "arithmetic")] +#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] +pub mod point; #[cfg(feature = "arithmetic")] #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub mod scalar; @@ -50,13 +52,17 @@ pub use generic_array::{self, typenum::consts}; pub use rand_core; pub use subtle; -// TODO(tarcieri): source this via ff crate: https://github.com/zkcrypto/ff/pull/40 #[cfg(feature = "arithmetic")] -pub use bitvec::view::BitView; +pub use self::{ + point::{AffinePoint, ProjectiveArithmetic, ProjectivePoint}, + scalar::Scalar, +}; +#[cfg(feature = "arithmetic")] +pub use bitvec::view::BitView; // TODO: https://github.com/zkcrypto/ff/pull/40 #[cfg(feature = "arithmetic")] -pub use ff; +pub use ff::{self, Field}; #[cfg(feature = "arithmetic")] -pub use group; +pub use group::{self, Group}; #[cfg(feature = "digest")] pub use digest::{self, Digest}; @@ -71,15 +77,6 @@ pub use zeroize; use core::{fmt::Debug, ops::Add}; use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; -use subtle::{ConditionallySelectable, CtOption}; - -#[cfg(feature = "arithmetic")] -use core::ops::Mul; -#[cfg(feature = "arithmetic")] -use subtle::ConstantTimeEq; - -/// Byte representation of a base/scalar field element of a given curve. -pub type FieldBytes = GenericArray::FieldSize>; /// Elliptic curve. /// @@ -98,32 +95,8 @@ pub trait Curve: Clone + Debug + Default + Eq + Ord + Send + Sync { type FieldSize: ArrayLength + Add + Eq + Ord + Unsigned; } -/// Elliptic curve with arithmetic implementation. -#[cfg(feature = "arithmetic")] -#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] -pub trait Arithmetic: Curve { - /// Scalar field element modulo the curve's order. - type Scalar: ff::PrimeField - + ConstantTimeEq - + Default - + FromFieldBytes - + Into>; - - /// Elliptic curve point in affine coordinates. - type AffinePoint: ConditionallySelectable - + Mul, Output = Self::AffinePoint> - + point::Generator; - - /// Elliptic curve point in projective coordinates. - type ProjectivePoint: group::Curve - + group::Group; -} - -/// Decode the given serialized field element -pub trait FromFieldBytes: ConditionallySelectable + Sized { - /// Try to decode this object from bytes - fn from_field_bytes(bytes: &FieldBytes) -> CtOption; -} +/// Byte representation of a base/scalar field element of a given curve. +pub type FieldBytes = GenericArray::FieldSize>; /// Instantiate this type from the output of a digest. /// diff --git a/elliptic-curve/src/point.rs b/elliptic-curve/src/point.rs index 5a0ae58ae..c0b067508 100644 --- a/elliptic-curve/src/point.rs +++ b/elliptic-curve/src/point.rs @@ -1,13 +1,22 @@ -//! Traits for elliptic curve points +//! Elliptic curve points. -/// Point compression settings -pub trait Compression { - /// Should point compression be applied by default? - const COMPRESS_POINTS: bool; -} +use crate::{Curve, FieldBytes, Scalar}; -/// Obtain the generator point. -pub trait Generator { - /// Get the generator point for this elliptic curve - fn generator() -> Self; +/// Elliptic curve with projective arithmetic implementation. +pub trait ProjectiveArithmetic: Curve +where + FieldBytes: From> + for<'r> From<&'r Scalar>, + Scalar: ff::PrimeField>, +{ + /// Elliptic curve point in projective coordinates. + type ProjectivePoint: group::Curve; } + +/// Affine point type for a given curve with a [`ProjectiveArithmetic`] +/// implementation. +pub type AffinePoint = + <::ProjectivePoint as group::Curve>::AffineRepr; + +/// Projective point type for a given curve with a [`ProjectiveArithmetic`] +/// implementation. +pub type ProjectivePoint = ::ProjectivePoint; diff --git a/elliptic-curve/src/scalar.rs b/elliptic-curve/src/scalar.rs index f5466d40b..a1db5b830 100644 --- a/elliptic-curve/src/scalar.rs +++ b/elliptic-curve/src/scalar.rs @@ -3,18 +3,23 @@ use crate::{ ops::Invert, rand_core::{CryptoRng, RngCore}, - Arithmetic, Curve, FieldBytes, FromFieldBytes, + Curve, Error, FieldBytes, ProjectiveArithmetic, }; use bitvec::{array::BitArray, order::Lsb0}; -use core::ops::Deref; -use ff::Field; -use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; +use core::{convert::TryFrom, ops::Deref}; +use ff::{Field, PrimeField}; +use generic_array::{typenum::Unsigned, GenericArray}; +use group::Group; +use subtle::{Choice, ConditionallySelectable, CtOption}; #[cfg(feature = "zeroize")] use zeroize::Zeroize; +/// Scalar field element for a particular elliptic curve. +pub type Scalar = <::ProjectivePoint as Group>::Scalar; + /// Bit representation of a scalar field element of a given curve. -pub type ScalarBits = BitArray::Scalar as ff::PrimeField>::ReprBits>; +pub type ScalarBits = BitArray as PrimeField>::ReprBits>; /// Non-zero scalar type. /// @@ -25,96 +30,110 @@ pub type ScalarBits = BitArray::Scalar as ff::PrimeF /// In the context of ECC, it's useful for ensuring that scalar multiplication /// cannot result in the point at infinity. #[derive(Clone)] -pub struct NonZeroScalar { - scalar: C::Scalar, +pub struct NonZeroScalar +where + C: Curve + ProjectiveArithmetic, + FieldBytes: From> + for<'r> From<&'r Scalar>, + Scalar: PrimeField>, +{ + scalar: Scalar, } impl NonZeroScalar where - C: Curve + Arithmetic, + C: Curve + ProjectiveArithmetic, + FieldBytes: From> + for<'r> From<&'r Scalar>, + Scalar: PrimeField>, { /// Generate a random `NonZeroScalar` pub fn random(mut rng: impl CryptoRng + RngCore) -> Self { // Use rejection sampling to eliminate zero values loop { - let result = Self::new(C::Scalar::random(&mut rng)); - - if result.is_some().into() { - break result.unwrap(); + if let Some(result) = Self::new(Field::random(&mut rng)) { + break result; } } } - /// Create a [`NonZeroScalar`] from a scalar, performing a constant-time - /// check that it's non-zero. - pub fn new(scalar: C::Scalar) -> CtOption { - let zero = C::Scalar::from_field_bytes(&Default::default()).unwrap(); - let is_zero = scalar.ct_eq(&zero); - CtOption::new(Self { scalar }, !is_zero) + /// Decode a [`NonZeroScalar] from a serialized field element + pub fn from_repr(repr: FieldBytes) -> Option { + Scalar::::from_repr(repr).and_then(Self::new) } - /// Serialize this [`NonZeroScalar`] as a byte array - pub fn to_bytes(&self) -> FieldBytes { - self.scalar.into() + /// Create a [`NonZeroScalar`] from a scalar. + // TODO(tarcieri): make this constant time? + pub fn new(scalar: Scalar) -> Option { + if scalar.is_zero() { + None + } else { + Some(Self { scalar }) + } } } -impl AsRef for NonZeroScalar +impl AsRef> for NonZeroScalar where - C: Curve + Arithmetic, + C: Curve + ProjectiveArithmetic, + FieldBytes: From> + for<'r> From<&'r Scalar>, + Scalar: PrimeField>, { - fn as_ref(&self) -> &C::Scalar { + fn as_ref(&self) -> &Scalar { &self.scalar } } impl ConditionallySelectable for NonZeroScalar where - C: Curve + Arithmetic, + C: Curve + ProjectiveArithmetic, + FieldBytes: From> + for<'r> From<&'r Scalar>, + Scalar: PrimeField>, { fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { - let scalar = C::Scalar::conditional_select(&a.scalar, &b.scalar, choice); - Self { scalar } + Self { + scalar: Scalar::::conditional_select(&a.scalar, &b.scalar, choice), + } } } -impl Copy for NonZeroScalar where C: Curve + Arithmetic {} - -impl Deref for NonZeroScalar +impl Copy for NonZeroScalar where - C: Curve + Arithmetic, + C: Curve + ProjectiveArithmetic, + FieldBytes: From> + for<'r> From<&'r Scalar>, + Scalar: PrimeField>, { - type Target = C::Scalar; - - fn deref(&self) -> &C::Scalar { - &self.scalar - } } -impl FromFieldBytes for NonZeroScalar +impl Deref for NonZeroScalar where - C: Curve + Arithmetic, + C: Curve + ProjectiveArithmetic, + FieldBytes: From> + for<'r> From<&'r Scalar>, + Scalar: PrimeField>, { - fn from_field_bytes(bytes: &FieldBytes) -> CtOption { - C::Scalar::from_field_bytes(bytes).and_then(Self::new) + type Target = Scalar; + + fn deref(&self) -> &Scalar { + &self.scalar } } impl From> for FieldBytes where - C: Curve + Arithmetic, + C: Curve + ProjectiveArithmetic, + FieldBytes: From> + for<'r> From<&'r Scalar>, + Scalar: PrimeField>, { fn from(scalar: NonZeroScalar) -> FieldBytes { - scalar.to_bytes() + scalar.scalar.into() } } impl Invert for NonZeroScalar where - C: Curve + Arithmetic, - C::Scalar: Invert, + C: Curve + ProjectiveArithmetic, + FieldBytes: From> + for<'r> From<&'r Scalar>, + Scalar: PrimeField> + Invert, { - type Output = C::Scalar; + type Output = Scalar; /// Perform a scalar inversion fn invert(&self) -> CtOption { @@ -122,11 +141,29 @@ where } } +impl TryFrom<&[u8]> for NonZeroScalar +where + C: Curve + ProjectiveArithmetic, + FieldBytes: From> + for<'r> From<&'r Scalar>, + Scalar: PrimeField>, +{ + type Error = Error; + + fn try_from(bytes: &[u8]) -> Result { + if bytes.len() == C::FieldSize::to_usize() { + NonZeroScalar::from_repr(GenericArray::clone_from_slice(bytes)).ok_or(Error) + } else { + Err(Error) + } + } +} + #[cfg(feature = "zeroize")] impl Zeroize for NonZeroScalar where - C: Curve + Arithmetic, - C::Scalar: Zeroize, + C: Curve + ProjectiveArithmetic, + FieldBytes: From> + for<'r> From<&'r Scalar>, + Scalar: PrimeField> + Zeroize, { fn zeroize(&mut self) { self.scalar.zeroize(); diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index 684509cd7..af6b8a5e8 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -20,13 +20,19 @@ use subtle::CtOption; use alloc::boxed::Box; #[cfg(feature = "arithmetic")] -use crate::{subtle::Choice, weierstrass::point::Decompress, Arithmetic}; +use crate::{ + ff::PrimeField, subtle::Choice, weierstrass::point::Decompress, ProjectiveArithmetic, Scalar, +}; #[cfg(all(feature = "arithmetic", feature = "zeroize"))] use crate::{ - ops::Mul, point::Generator, scalar::NonZeroScalar, secret_key::SecretKey, FromFieldBytes, + group::{Curve as _, Group}, + AffinePoint, }; +#[cfg(all(feature = "arithmetic", feature = "zeroize"))] +use crate::secret_key::SecretKey; + #[cfg(feature = "zeroize")] use zeroize::Zeroize; @@ -126,20 +132,16 @@ where #[cfg(all(feature = "arithmetic", feature = "zeroize"))] #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] #[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] - pub fn from_secret_key(secret_key: &SecretKey, compress: bool) -> Result + pub fn from_secret_key(secret_key: &SecretKey, compress: bool) -> Self where - C: Arithmetic, - C::AffinePoint: Mul, Output = C::AffinePoint> + ToEncodedPoint, - C::Scalar: Zeroize, + C: Curve + ProjectiveArithmetic, + FieldBytes: From> + for<'r> From<&'r Scalar>, + AffinePoint: ToEncodedPoint, + Scalar: PrimeField> + Zeroize, { - if let Some(scalar) = C::Scalar::from_field_bytes(&secret_key.to_bytes()) - .and_then(NonZeroScalar::new) - .into() - { - Ok(Self::encode(C::AffinePoint::generator() * scalar, compress)) - } else { - Err(Error) - } + (C::ProjectivePoint::generator() * secret_key.secret_scalar()) + .to_affine() + .to_encoded_point(compress) } /// Get the length of the encoded point in bytes @@ -177,12 +179,13 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub fn decompress(&self) -> CtOption where - C: Arithmetic, - C::Scalar: Decompress + ToEncodedPoint, + C: Curve + ProjectiveArithmetic, + FieldBytes: From> + for<'r> From<&'r Scalar>, + Scalar: PrimeField> + Decompress + ToEncodedPoint, { match self.coordinates() { Coordinates::Compressed { x, y_is_odd } => { - C::Scalar::decompress(x, Choice::from(y_is_odd as u8)) + Scalar::::decompress(x, Choice::from(y_is_odd as u8)) .map(|s| s.to_encoded_point(false)) } Coordinates::Uncompressed { .. } => CtOption::new(self.clone(), Choice::from(1)), diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 661f5bbf1..5f18959a4 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -12,11 +12,14 @@ use core::{ convert::{TryFrom, TryInto}, fmt::{self, Debug}, }; -use subtle::CtOption; use zeroize::Zeroize; #[cfg(feature = "arithmetic")] -use crate::{scalar::NonZeroScalar, Arithmetic, FromFieldBytes}; +use crate::{ + ff::PrimeField, + scalar::{NonZeroScalar, Scalar}, + ProjectiveArithmetic, +}; #[cfg(feature = "arithmetic")] use rand_core::{CryptoRng, RngCore}; @@ -26,18 +29,21 @@ pub trait SecretValue: Curve { type Secret: Into> + Zeroize; /// Parse the secret value from bytes - fn from_secret_bytes(bytes: &FieldBytes) -> CtOption; + // TODO(tarcieri): make this constant time? + fn from_secret_bytes(bytes: &FieldBytes) -> Option; } #[cfg(feature = "arithmetic")] -impl SecretValue for C +impl SecretValue for C where - C::Scalar: Zeroize, + C: Curve + ProjectiveArithmetic, + FieldBytes: From> + for<'a> From<&'a Scalar>, + Scalar: PrimeField> + Zeroize, { type Secret = NonZeroScalar; - fn from_secret_bytes(bytes: &FieldBytes) -> CtOption> { - NonZeroScalar::from_field_bytes(bytes) + fn from_secret_bytes(repr: &FieldBytes) -> Option> { + NonZeroScalar::from_repr(repr.clone()) } } @@ -63,7 +69,9 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub fn random(rng: impl CryptoRng + RngCore) -> Self where - C: Arithmetic + SecretValue>, + C: ProjectiveArithmetic + SecretValue>, + FieldBytes: From> + for<'a> From<&'a Scalar>, + Scalar: PrimeField> + Zeroize, { Self { secret_value: NonZeroScalar::::random(rng), @@ -81,7 +89,7 @@ where .as_ref() .try_into() .ok() - .and_then(|bytes| C::from_secret_bytes(bytes).into()) + .and_then(C::from_secret_bytes) .map(|secret_value| SecretKey { secret_value }) .ok_or(Error) } @@ -93,16 +101,20 @@ where /// Borrow the inner secret scalar value. /// - /// # Notice + /// # Warning + /// + /// This value is key material. /// - /// This value is key material. Please treat it accordingly! + /// Please treat it with the care it deserves! #[cfg(feature = "arithmetic")] #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] - pub fn secret_scalar(&self) -> &NonZeroScalar + pub fn secret_scalar(&self) -> &Scalar where - C: Arithmetic + SecretValue>, + C: ProjectiveArithmetic + SecretValue>, + FieldBytes: From> + for<'a> From<&'a Scalar>, + Scalar: PrimeField> + Zeroize, { - &self.secret_value + self.secret_value.as_ref() } } diff --git a/elliptic-curve/src/weierstrass/point.rs b/elliptic-curve/src/weierstrass/point.rs index cd52efe07..e2612ad90 100644 --- a/elliptic-curve/src/weierstrass/point.rs +++ b/elliptic-curve/src/weierstrass/point.rs @@ -4,6 +4,12 @@ use super::Curve; use crate::FieldBytes; use subtle::{Choice, CtOption}; +/// Point compression settings +pub trait Compression { + /// Should point compression be applied by default? + const COMPRESS_POINTS: bool; +} + /// Attempt to decompress an elliptic curve point from its x-coordinate and /// a boolean flag indicating whether or not the y-coordinate is odd. pub trait Decompress: Sized { From 79b714c67de0b375b86083949b739af4f8ec2e4d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 11 Sep 2020 12:48:03 -0700 Subject: [PATCH 0236/1461] elliptic-curve v0.6.0 (#302) --- Cargo.lock | 2 +- cryptography/Cargo.toml | 2 +- elliptic-curve/CHANGELOG.md | 55 +++++++++++++++++++++++++++++++++++++ elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 2 +- 5 files changed, 59 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bd8042653..0c69c57cf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -136,7 +136,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.5.0" +version = "0.6.0" dependencies = [ "bitvec", "const-oid", diff --git a/cryptography/Cargo.toml b/cryptography/Cargo.toml index c7374fbf6..0f4453e08 100644 --- a/cryptography/Cargo.toml +++ b/cryptography/Cargo.toml @@ -15,7 +15,7 @@ edition = "2018" aead = { version = "0.3", optional = true, path = "../aead" } block-cipher = { version = "0.8", optional = true, path = "../block-cipher" } digest = { version = "0.9", optional = true, path = "../digest" } -elliptic-curve = { version = "= 0.5", optional = true, path = "../elliptic-curve" } +elliptic-curve = { version = "0.6", optional = true, path = "../elliptic-curve" } mac = { version = "0.9", package = "crypto-mac", optional = true, path = "../crypto-mac" } signature = { version = "1.1.0", optional = true, default-features = false, path = "../signature" } stream-cipher = { version = "0.7", optional = true, path = "../stream-cipher" } diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index 6c4c1587a..2e1e3349d 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,61 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.6.0 (2020-09-11) +### Added +- `arithmetic` feature ([#293]) +- Generic curve/field arithmetic using the `ff` and `group` crates + ([#287], [#291], [#292]) +- `sec1::Coordinates` ([#286]) +- `weierstrass::point::Compression` trait ([#283], [#300]) +- Arithmetic helper functions ([#281]) +- `digest` feature and `FromDigest` trait ([#279]) +- impl `Deref` for `NonZeroScalar` ([#278]) +- Conditionally impl `Invert` for `NonZeroScalar` ([#277]) +- `NonZeroScalar::to_bytes` ([#276]) +- `EncodedPoint::decompress` ([#275]) +- `sec1::Tag` ([#270]) +- `weierstrass::point::Decompress` trait ([#266]) +- `alloc` feature + `EncodedPoint::to_bytes()` ([#265]) + +### Changed +- Renamed `Arithmetic` trait to `point::ProjectiveArithmetic` ([#300]) +- Replaced `Arithmetic::Scalar` and `Arithmetic::AffinePoint` + with `Scalar` and `AffinePoint` ([#300]) +- Made `SecretKey` inner type generic ([#297]) +- Renamed `ElementBytes` to `FieldBytes` ([#296]) +- MSRV 1.44 ([#292]) +- Minimum `subtle` version now v2.3 ([#290]) +- Renamed `Curve::ElementSize` to `::FieldSize` ([#282]) +- Refactor `PublicKey` into `sec1::EncodedPoint` ([#264]) + +### Removed +- `FromBytes` trait ([#300]) +- `Generate` trait ([#295]) + +[#300]: https://github.com/RustCrypto/traits/pull/300 +[#297]: https://github.com/RustCrypto/traits/pull/297 +[#296]: https://github.com/RustCrypto/traits/pull/296 +[#295]: https://github.com/RustCrypto/traits/pull/295 +[#293]: https://github.com/RustCrypto/traits/pull/293 +[#292]: https://github.com/RustCrypto/traits/pull/292 +[#291]: https://github.com/RustCrypto/traits/pull/291 +[#290]: https://github.com/RustCrypto/traits/pull/290 +[#287]: https://github.com/RustCrypto/traits/pull/293 +[#286]: https://github.com/RustCrypto/traits/pull/286 +[#283]: https://github.com/RustCrypto/traits/pull/283 +[#282]: https://github.com/RustCrypto/traits/pull/282 +[#281]: https://github.com/RustCrypto/traits/pull/281 +[#279]: https://github.com/RustCrypto/traits/pull/279 +[#278]: https://github.com/RustCrypto/traits/pull/278 +[#277]: https://github.com/RustCrypto/traits/pull/277 +[#276]: https://github.com/RustCrypto/traits/pull/276 +[#275]: https://github.com/RustCrypto/traits/pull/275 +[#270]: https://github.com/RustCrypto/traits/pull/270 +[#266]: https://github.com/RustCrypto/traits/pull/266 +[#265]: https://github.com/RustCrypto/traits/pull/265 +[#264]: https://github.com/RustCrypto/traits/pull/264 + ## 0.5.0 (2020-08-10) ### Added - `Arithmetic` trait ([#219]) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 69cb3301c..bc79ee268 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -5,7 +5,7 @@ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. """ -version = "0.5.0" # Also update html_root_url in lib.rs when bumping this +version = "0.6.0" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" repository = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve" diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 53c7a72dc..5d6b8f3b0 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -16,7 +16,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.5.0" + html_root_url = "https://docs.rs/elliptic-curve/0.6.0" )] #[cfg(feature = "alloc")] From b541170e97553891833a4359ea1c27576e0a2b4d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 11 Sep 2020 12:48:26 -0700 Subject: [PATCH 0237/1461] build(deps): bump bitvec from 0.18.3 to 0.19.0 (#301) Bumps [bitvec](https://github.com/myrrlyn/bitvec) from 0.18.3 to 0.19.0. - [Release notes](https://github.com/myrrlyn/bitvec/releases) - [Changelog](https://github.com/myrrlyn/bitvec/blob/develop/CHANGELOG.md) - [Commits](https://github.com/myrrlyn/bitvec/compare/v0.18.3...v0.19.0) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 15 +++++++++++++-- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0c69c57cf..b1ce030b1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -31,6 +31,17 @@ dependencies = [ "wyz", ] +[[package]] +name = "bitvec" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36d8f44cf786f61f341ff3d14c600c47326642326c59d1f65a53f8318885c4b9" +dependencies = [ + "funty", + "radium", + "wyz", +] + [[package]] name = "blobby" version = "0.2.0" @@ -138,7 +149,7 @@ dependencies = [ name = "elliptic-curve" version = "0.6.0" dependencies = [ - "bitvec", + "bitvec 0.19.0", "const-oid", "digest 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "ff", @@ -156,7 +167,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01646e077d4ebda82b73f1bca002ea1e91561a77df2431a9e79729bcc31950ef" dependencies = [ - "bitvec", + "bitvec 0.18.3", "rand_core", "subtle", ] diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index bc79ee268..58bae6b89 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -15,7 +15,7 @@ categories = ["cryptography", "no-std"] keywords = ["crypto", "ecc", "elliptic", "weierstrass"] [dependencies] -bitvec = { version = "0.18", optional = true, default-features = false } +bitvec = { version = "0.19", optional = true, default-features = false } digest = { version = "0.9", optional = true } ff = { version = "0.8", optional = true, default-features = false } group = { version = "0.8", optional = true, default-features = false } From aefa66783a2b96e5d0039adc0e457a20e6462469 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 11 Sep 2020 15:49:25 -0700 Subject: [PATCH 0238/1461] elliptic-curve: minor SecretKey doc fix (#303) --- elliptic-curve/src/secret_key.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 5f18959a4..1265b8abc 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -49,7 +49,7 @@ where /// Elliptic curve secret keys. /// -/// This type wraps a serialized scalar value, helping to prevent accidental +/// This type wraps a secret scalar value, helping to prevent accidental /// exposure and securely erasing the value from memory when dropped /// (when the `zeroize` feature of this crate is enabled). #[derive(Clone)] From 13b4a639290c31c5a154a222fbc6a315b6c7c181 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 16 Sep 2020 08:25:40 +0000 Subject: [PATCH 0239/1461] build(deps): bump zeroize from 1.1.0 to 1.1.1 (#305) --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b1ce030b1..6c88ce7e9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -411,6 +411,6 @@ checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" [[package]] name = "zeroize" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cbac2ed2ba24cc90f5e06485ac8c7c1e5449fe8911aef4d8877218af021a5b8" +checksum = "05f33972566adbd2d3588b0491eb94b98b43695c4ef897903470ede4f3f5a28a" From 1b77dd02368adddcf2fbdbf2672f30e5c1c4dec0 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 21 Sep 2020 07:25:10 -0700 Subject: [PATCH 0240/1461] Revert "build(deps): bump bitvec from 0.18.3 to 0.19.0 (#301)" (#308) This reverts commit b541170e97553891833a4359ea1c27576e0a2b4d. This needs to be upgraded in coordination with the `ff` and `group` crates, so this reverts it back to what the current releases of those crates are presently using. --- Cargo.lock | 15 ++------------- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6c88ce7e9..8c53fe2c1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -31,17 +31,6 @@ dependencies = [ "wyz", ] -[[package]] -name = "bitvec" -version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36d8f44cf786f61f341ff3d14c600c47326642326c59d1f65a53f8318885c4b9" -dependencies = [ - "funty", - "radium", - "wyz", -] - [[package]] name = "blobby" version = "0.2.0" @@ -149,7 +138,7 @@ dependencies = [ name = "elliptic-curve" version = "0.6.0" dependencies = [ - "bitvec 0.19.0", + "bitvec", "const-oid", "digest 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "ff", @@ -167,7 +156,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01646e077d4ebda82b73f1bca002ea1e91561a77df2431a9e79729bcc31950ef" dependencies = [ - "bitvec 0.18.3", + "bitvec", "rand_core", "subtle", ] diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 58bae6b89..bc79ee268 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -15,7 +15,7 @@ categories = ["cryptography", "no-std"] keywords = ["crypto", "ecc", "elliptic", "weierstrass"] [dependencies] -bitvec = { version = "0.19", optional = true, default-features = false } +bitvec = { version = "0.18", optional = true, default-features = false } digest = { version = "0.9", optional = true } ff = { version = "0.8", optional = true, default-features = false } group = { version = "0.8", optional = true, default-features = false } From 797b7d900e457139e01f4a35e5d1ad76eb96e815 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 21 Sep 2020 09:02:30 -0700 Subject: [PATCH 0241/1461] elliptic-curve: fix `sec1::EncodedPoint::decompress` (#309) This method was previously expecting `Decompress` and `ToEncodedPoint` impls on `Scalar`, rather than `AffinePoint`. This updates it to use the correct types. --- elliptic-curve/src/sec1.rs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index af6b8a5e8..db09dc277 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -21,14 +21,14 @@ use alloc::boxed::Box; #[cfg(feature = "arithmetic")] use crate::{ - ff::PrimeField, subtle::Choice, weierstrass::point::Decompress, ProjectiveArithmetic, Scalar, + ff::PrimeField, + subtle::{Choice, ConditionallySelectable}, + weierstrass::point::Decompress, + AffinePoint, ProjectiveArithmetic, Scalar, }; #[cfg(all(feature = "arithmetic", feature = "zeroize"))] -use crate::{ - group::{Curve as _, Group}, - AffinePoint, -}; +use crate::group::{Curve as _, Group}; #[cfg(all(feature = "arithmetic", feature = "zeroize"))] use crate::secret_key::SecretKey; @@ -181,11 +181,12 @@ where where C: Curve + ProjectiveArithmetic, FieldBytes: From> + for<'r> From<&'r Scalar>, - Scalar: PrimeField> + Decompress + ToEncodedPoint, + Scalar: PrimeField>, + AffinePoint: ConditionallySelectable + Default + Decompress + ToEncodedPoint, { match self.coordinates() { Coordinates::Compressed { x, y_is_odd } => { - Scalar::::decompress(x, Choice::from(y_is_odd as u8)) + AffinePoint::::decompress(x, Choice::from(y_is_odd as u8)) .map(|s| s.to_encoded_point(false)) } Coordinates::Uncompressed { .. } => CtOption::new(self.clone(), Choice::from(1)), From b9e43c480d38f11fcc9d51e64db4a7283309ab78 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 21 Sep 2020 11:00:40 -0700 Subject: [PATCH 0242/1461] elliptic-curve v0.6.1 (#310) --- Cargo.lock | 2 +- elliptic-curve/CHANGELOG.md | 8 +++++++- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8c53fe2c1..2536b3e3f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -136,7 +136,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.6.0" +version = "0.6.1" dependencies = [ "bitvec", "const-oid", diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index 2e1e3349d..da3f4c278 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,7 +4,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 0.6.0 (2020-09-11) +## 0.6.1 (2020-09-21) +### Fixed +- `sec1::EncodedPoint::decompress` ([#309]) + +[#309]: https://github.com/RustCrypto/traits/pull/309 + +## 0.6.0 (2020-09-11) [YANKED] ### Added - `arithmetic` feature ([#293]) - Generic curve/field arithmetic using the `ff` and `group` crates diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index bc79ee268..bea2f8d71 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -5,7 +5,7 @@ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. """ -version = "0.6.0" # Also update html_root_url in lib.rs when bumping this +version = "0.6.1" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" repository = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve" diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 5d6b8f3b0..6488bba42 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -16,7 +16,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.6.0" + html_root_url = "https://docs.rs/elliptic-curve/0.6.1" )] #[cfg(feature = "alloc")] From 525246b8f049b904381276cd39ab2622b32a4d69 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 23 Sep 2020 13:26:57 +0300 Subject: [PATCH 0243/1461] build(deps): bump heapless from 0.5.5 to 0.5.6 (#311) --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2536b3e3f..700fb6758 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -217,9 +217,9 @@ dependencies = [ [[package]] name = "heapless" -version = "0.5.5" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73a8a2391a3bc70b31f60e7a90daa5755a360559c0b6b9c5cfc0fee482362dc0" +checksum = "74911a68a1658cfcfb61bc0ccfbd536e3b6e906f8c2f7883ee50157e3e2184f1" dependencies = [ "as-slice", "generic-array 0.13.2", From 871d50cbf02bb6adac6bb611d1797f88153a5031 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 24 Sep 2020 16:51:01 -0700 Subject: [PATCH 0244/1461] elliptic-curve: add `sec1::EncodedPoint::to_untagged_bytes()` (#312) Adds a method for returning a `GenericArray` of the encoded point without a leading tag byte. --- elliptic-curve/src/sec1.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index db09dc277..05cec83d7 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -161,6 +161,25 @@ where self.as_bytes().to_vec().into_boxed_slice() } + /// Serialize point as raw uncompressed coordinates without tag byte, i.e. + /// encoded as the concatenated `x || y` coordinates. + #[cfg(feature = "arithmetic")] + #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] + pub fn to_untagged_bytes(&self) -> Option>> + where + C: Curve + ProjectiveArithmetic, + FieldBytes: From> + for<'r> From<&'r Scalar>, + Scalar: PrimeField>, + AffinePoint: ConditionallySelectable + Default + Decompress + ToEncodedPoint, + { + let decompressed: Option> = self.decompress().into(); + decompressed.map(|point| { + let mut bytes = GenericArray::>::default(); + bytes.copy_from_slice(&point.as_bytes()[1..]); + bytes + }) + } + /// Is this [`EncodedPoint`] compressed? pub fn is_compressed(&self) -> bool { self.tag().is_compressed() From cb2fc0bd92c9fdb495a1595677d5b0d172e13fe7 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 24 Sep 2020 17:02:02 -0700 Subject: [PATCH 0245/1461] elliptic-curve v0.6.2 (#313) --- Cargo.lock | 2 +- elliptic-curve/CHANGELOG.md | 6 ++++++ elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 700fb6758..b1311af47 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -136,7 +136,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.6.1" +version = "0.6.2" dependencies = [ "bitvec", "const-oid", diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index da3f4c278..16a6c7158 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.6.2 (2020-09-24) +### Added +- `sec1::EncodedPoint::to_untagged_bytes()` method ([#312]) + +[#312]: https://github.com/RustCrypto/traits/pull/312 + ## 0.6.1 (2020-09-21) ### Fixed - `sec1::EncodedPoint::decompress` ([#309]) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index bea2f8d71..e34679cfd 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -5,7 +5,7 @@ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. """ -version = "0.6.1" # Also update html_root_url in lib.rs when bumping this +version = "0.6.2" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" repository = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve" diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 6488bba42..65c60444f 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -16,7 +16,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.6.1" + html_root_url = "https://docs.rs/elliptic-curve/0.6.2" )] #[cfg(feature = "alloc")] From 3ef2f364f26827851e33308699b25d45253cc9f3 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 25 Sep 2020 09:13:08 -0700 Subject: [PATCH 0246/1461] cryptography: bump `signature` dependency to 1.2.0 (#314) --- cryptography/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cryptography/Cargo.toml b/cryptography/Cargo.toml index 0f4453e08..dd1b70443 100644 --- a/cryptography/Cargo.toml +++ b/cryptography/Cargo.toml @@ -17,7 +17,7 @@ block-cipher = { version = "0.8", optional = true, path = "../block-cipher" } digest = { version = "0.9", optional = true, path = "../digest" } elliptic-curve = { version = "0.6", optional = true, path = "../elliptic-curve" } mac = { version = "0.9", package = "crypto-mac", optional = true, path = "../crypto-mac" } -signature = { version = "1.1.0", optional = true, default-features = false, path = "../signature" } +signature = { version = "1.2.0", optional = true, default-features = false, path = "../signature" } stream-cipher = { version = "0.7", optional = true, path = "../stream-cipher" } universal-hash = { version = "0.4", optional = true, path = "../universal-hash" } From 3182f68bb08e104502e391f5cf796328895e30ff Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 25 Sep 2020 09:20:21 -0700 Subject: [PATCH 0247/1461] cryptography v0.4 (#315) --- Cargo.lock | 2 +- cryptography/CHANGELOG.md | 10 ++++++++++ cryptography/Cargo.toml | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b1311af47..0924ad286 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -105,7 +105,7 @@ dependencies = [ [[package]] name = "cryptography" -version = "0.3.0" +version = "0.4.0" dependencies = [ "aead", "block-cipher 0.8.0", diff --git a/cryptography/CHANGELOG.md b/cryptography/CHANGELOG.md index a9eeae187..a5d35e541 100644 --- a/cryptography/CHANGELOG.md +++ b/cryptography/CHANGELOG.md @@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.4.0 (2020-09-25) +### Changed +- Bump `signature` dependency to 1.2.0 ([#314]) +- Bump `elliptic-curve` dependency to 0.6 ([#302]) +- Bump `stream-cipher` dependency to 0.7 ([#260]) + +[#314]: https://github.com/RustCrypto/traits/pull/314 +[#302]: https://github.com/RustCrypto/traits/pull/302 +[#260]: https://github.com/RustCrypto/traits/pull/260 + ## 0.3.0 (2020-08-10) ### Added - `elliptic-curve` feature ([#213]) diff --git a/cryptography/Cargo.toml b/cryptography/Cargo.toml index dd1b70443..cdef64845 100644 --- a/cryptography/Cargo.toml +++ b/cryptography/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cryptography" -version = "0.3.0" +version = "0.4.0" authors = ["The RustCrypto Project Developers"] license = "Apache-2.0 OR MIT" description = "Facade crate for the RustCrypto project's traits" From 25f20640404e66ae3bb2687b5090c3c7b54c9fe1 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 29 Sep 2020 19:00:32 -0700 Subject: [PATCH 0248/1461] cryptography: add `std` feature (#317) Adds an off-by-default `std` feature which activates the `std` features of all of the other dependencies. This is a somewhat lousy way of doing this, and I wish that there were a better approach, so much that I posted a Pre-Pre-RFC about it: https://internals.rust-lang.org/t/pre-pre-rfc-weak-cargo-feature-activation/13141 For now though, this is immediately useful to me. --- .github/workflows/cryptography.yml | 5 +++-- cryptography/Cargo.toml | 12 ++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cryptography.yml b/.github/workflows/cryptography.yml index e3639cc57..3d42b3d93 100644 --- a/.github/workflows/cryptography.yml +++ b/.github/workflows/cryptography.yml @@ -35,8 +35,9 @@ jobs: toolchain: ${{ matrix.rust }} target: ${{ matrix.target }} override: true - - run: cargo build --release --target ${{ matrix.target }} - - run: cargo build --all-features --release --target ${{ matrix.target }} + - run: cargo build --no-default-features --release --target ${{ matrix.target }} + - run: cargo build --no-default-features --release --target ${{ matrix.target }} + --features aead,block-cipher,mac,digest,elliptic-curve,signature,stream-cipher,universal-hash test: runs-on: ubuntu-latest strategy: diff --git a/cryptography/Cargo.toml b/cryptography/Cargo.toml index cdef64845..adc1c004a 100644 --- a/cryptography/Cargo.toml +++ b/cryptography/Cargo.toml @@ -21,5 +21,17 @@ signature = { version = "1.2.0", optional = true, default-features = false, path stream-cipher = { version = "0.7", optional = true, path = "../stream-cipher" } universal-hash = { version = "0.4", optional = true, path = "../universal-hash" } +[features] +std = [ + "aead/std", + "block-cipher/std", + "digest/std", + "elliptic-curve/std", + "mac/std", + "signature/std", + "stream-cipher/std", + "universal-hash/std" +] + [package.metadata.docs.rs] all-features = true From dd5e7ec6bb7e6574d5927ace33a178bd54e6bd1d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 29 Sep 2020 19:05:52 -0700 Subject: [PATCH 0249/1461] cryptography v0.4.1 (#318) --- Cargo.lock | 2 +- cryptography/CHANGELOG.md | 6 ++++++ cryptography/Cargo.toml | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0924ad286..c68cc8bea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -105,7 +105,7 @@ dependencies = [ [[package]] name = "cryptography" -version = "0.4.0" +version = "0.4.1" dependencies = [ "aead", "block-cipher 0.8.0", diff --git a/cryptography/CHANGELOG.md b/cryptography/CHANGELOG.md index a5d35e541..51dce1f2c 100644 --- a/cryptography/CHANGELOG.md +++ b/cryptography/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.4.1 (2020-09-29) +### Added +- `std` feature ([#317]) + +[#317]: https://github.com/RustCrypto/traits/pull/317 + ## 0.4.0 (2020-09-25) ### Changed - Bump `signature` dependency to 1.2.0 ([#314]) diff --git a/cryptography/Cargo.toml b/cryptography/Cargo.toml index adc1c004a..75b87d96c 100644 --- a/cryptography/Cargo.toml +++ b/cryptography/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cryptography" -version = "0.4.0" +version = "0.4.1" authors = ["The RustCrypto Project Developers"] license = "Apache-2.0 OR MIT" description = "Facade crate for the RustCrypto project's traits" From ff3b4fa9a06a30429b7898b04319088b428b05ef Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 6 Oct 2020 07:49:56 -0700 Subject: [PATCH 0250/1461] README.md(s): add Zulip badges (#321) --- README.md | 4 +++- aead/README.md | 3 +++ block-cipher/README.md | 3 +++ crypto-mac/README.md | 3 +++ cryptography/README.md | 3 +++ digest/README.md | 3 +++ elliptic-curve/README.md | 3 +++ signature/README.md | 3 +++ stream-cipher/README.md | 3 +++ universal-hash/README.md | 3 +++ 10 files changed, 30 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 39e3fce84..32d65d90a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# RustCrypto: Traits ![Rust Version][rustc-image] +# RustCrypto: Traits ![Rust Version][rustc-image] [![Project Chat][chat-image]][chat-link] Collection of traits which describe functionality of cryptographic primitives. @@ -46,6 +46,8 @@ dual licensed as above, without any additional terms or conditions. [//]: # (badges) [rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg +[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg +[chat-link]: https://rustcrypto.zulipchat.com/ [//]: # (crates) diff --git a/aead/README.md b/aead/README.md index 0a95723ce..8bc2a7a12 100644 --- a/aead/README.md +++ b/aead/README.md @@ -4,6 +4,7 @@ [![Docs][docs-image]][docs-link] ![Apache2/MIT licensed][license-image] ![Rust Version][rustc-image] +[![Project Chat][chat-image]][chat-link] [![Build Status][build-image]][build-link] This crate provides an abstract interface for [AEAD] ciphers, which guarantee @@ -51,6 +52,8 @@ dual licensed as above, without any additional terms or conditions. [docs-link]: https://docs.rs/aead/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg [rustc-image]: https://img.shields.io/badge/rustc-1.41+-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/traits/workflows/aead/badge.svg?branch=master&event=push [build-link]: https://github.com/RustCrypto/traits/actions?query=workflow%3Aaead diff --git a/block-cipher/README.md b/block-cipher/README.md index 553989fa4..c8cffcd7a 100644 --- a/block-cipher/README.md +++ b/block-cipher/README.md @@ -4,6 +4,7 @@ [![Docs][docs-image]][docs-link] ![Apache2/MIT licensed][license-image] ![Rust Version][rustc-image] +[![Project Chat][chat-image]][chat-link] [![Build Status][build-image]][build-link] Traits which define functionality of [block ciphers]. @@ -47,6 +48,8 @@ dual licensed as above, without any additional terms or conditions. [docs-link]: https://docs.rs/block-cipher/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg [rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg +[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg +[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260039-block-ciphers [build-image]: https://github.com/RustCrypto/traits/workflows/block-cipher/badge.svg?branch=master&event=push [build-link]: https://github.com/RustCrypto/traits/actions?query=workflow%3Ablock-cipher diff --git a/crypto-mac/README.md b/crypto-mac/README.md index 35349ef82..889d6c244 100644 --- a/crypto-mac/README.md +++ b/crypto-mac/README.md @@ -4,6 +4,7 @@ [![Docs][docs-image]][docs-link] ![Apache2/MIT licensed][license-image] ![Rust Version][rustc-image] +[![Project Chat][chat-image]][chat-link] [![Build Status][build-image]][build-link] Traits for [Message Authentication Code] (MAC) algorithms. @@ -47,6 +48,8 @@ dual licensed as above, without any additional terms or conditions. [docs-link]: https://docs.rs/crypto-mac/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg [rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg +[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg +[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260044-MACs [build-image]: https://github.com/RustCrypto/traits/workflows/crypto-mac/badge.svg?branch=master&event=push [build-link]: https://github.com/RustCrypto/traits/actions?query=workflow%3Acrypto-mac diff --git a/cryptography/README.md b/cryptography/README.md index 82b3a4adf..76a750403 100644 --- a/cryptography/README.md +++ b/cryptography/README.md @@ -4,6 +4,7 @@ [![Docs][docs-image]][docs-link] ![Apache2/MIT licensed][license-image] ![Rust Version][rustc-image] +[![Project Chat][chat-image]][chat-link] [![Build Status][build-image]][build-link] Facade crate for [RustCrypto Traits][1], providing a single place to @@ -46,6 +47,8 @@ dual licensed as above, without any additional terms or conditions. [docs-link]: https://docs.rs/cryptography/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg [rustc-image]: https://img.shields.io/badge/rustc-1.44+-blue.svg +[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg +[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260050-Traits [build-image]: https://github.com/RustCrypto/traits/workflows/cryptography/badge.svg?branch=master&event=push [build-link]: https://github.com/RustCrypto/traits/actions?query=workflow%3Acryptography diff --git a/digest/README.md b/digest/README.md index e68638771..0a43d4751 100644 --- a/digest/README.md +++ b/digest/README.md @@ -4,6 +4,7 @@ [![Docs][docs-image]][docs-link] ![Apache2/MIT licensed][license-image] ![Rust Version][rustc-image] +[![Project Chat][chat-image]][chat-link] [![Build Status][build-image]][build-link] Traits which describe functionality of [cryptographic hash functions][0], a.k.a. @@ -147,6 +148,8 @@ dual licensed as above, without any additional terms or conditions. [docs-link]: https://docs.rs/digest/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg [rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg +[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg +[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260041-hashes [build-image]: https://github.com/RustCrypto/traits/workflows/digest/badge.svg?branch=master&event=push [build-link]: https://github.com/RustCrypto/traits/actions?query=workflow%3Adigest diff --git a/elliptic-curve/README.md b/elliptic-curve/README.md index f155859c4..69e635c3d 100644 --- a/elliptic-curve/README.md +++ b/elliptic-curve/README.md @@ -4,6 +4,7 @@ [![Docs][docs-image]][docs-link] ![Apache2/MIT licensed][license-image] ![Rust Version][rustc-image] +[![Project Chat][chat-image]][chat-link] [![Build Status][build-image]][build-link] General purpose Elliptic Curve Cryptography (ECC) support, including types @@ -47,5 +48,7 @@ dual licensed as above, without any additional terms or conditions. [docs-link]: https://docs.rs/elliptic-curve/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg [rustc-image]: https://img.shields.io/badge/rustc-1.44+-blue.svg +[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg +[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260040-elliptic-curves [build-image]: https://github.com/RustCrypto/elliptic-curves/workflows/elliptic-curve%20crate/badge.svg?branch=master&event=push [build-link]: https://github.com/RustCrypto/elliptic-curves/actions?query=workflow%3A%22elliptic-curve+crate%22 diff --git a/signature/README.md b/signature/README.md index f4f3e6262..72db8bd3d 100644 --- a/signature/README.md +++ b/signature/README.md @@ -4,6 +4,7 @@ [![Docs][docs-image]][docs-link] ![Apache2/MIT licensed][license-image] ![Rust Version][rustc-image] +[![Project Chat][chat-image]][chat-link] [![Build Status][build-image]][build-link] This crate contains traits which provide generic, object-safe APIs for @@ -57,6 +58,8 @@ dual licensed as above, without any additional terms or conditions. [docs-link]: https://docs.rs/signature/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg [rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg +[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg +[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260048-signatures [build-image]: https://github.com/RustCrypto/traits/workflows/signature/badge.svg?branch=master&event=push [build-link]: https://github.com/RustCrypto/traits/actions?query=workflow%3Asignature diff --git a/stream-cipher/README.md b/stream-cipher/README.md index 86a2886a0..06866ecaa 100644 --- a/stream-cipher/README.md +++ b/stream-cipher/README.md @@ -4,6 +4,7 @@ [![Docs][docs-image]][docs-link] ![Apache2/MIT licensed][license-image] ![Rust Version][rustc-image] +[![Project Chat][chat-image]][chat-link] [![Build Status][build-image]][build-link] Traits which define functionality of [stream ciphers]. @@ -47,6 +48,8 @@ dual licensed as above, without any additional terms or conditions. [docs-link]: https://docs.rs/stream-cipher/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg [rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg +[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg +[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260049-stream-ciphers [build-image]: https://github.com/RustCrypto/traits/workflows/stream-cipher/badge.svg?branch=master&event=push [build-link]: https://github.com/RustCrypto/traits/actions?query=workflow%3Astream-cipher diff --git a/universal-hash/README.md b/universal-hash/README.md index 3be1e3cf7..20fd50a82 100644 --- a/universal-hash/README.md +++ b/universal-hash/README.md @@ -4,6 +4,7 @@ [![Docs][docs-image]][docs-link] ![Apache2/MIT licensed][license-image] ![Rust Version][rustc-image] +[![Project Chat][chat-image]][chat-link] [![Build Status][build-image]][build-link] Traits which define functionality of [universal hash functions]. @@ -47,6 +48,8 @@ dual licensed as above, without any additional terms or conditions. [docs-link]: https://docs.rs/universal-hash/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg [rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg +[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg +[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260051-universal-hashes [build-image]: https://github.com/RustCrypto/traits/workflows/universal-hash/badge.svg?branch=master&event=push [build-link]: https://github.com/RustCrypto/traits/actions?query=workflow%3Auniversal-hash From ab7fe9ab84c57eeb774bb2ababfb8c98b0d2f7ca Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 6 Oct 2020 07:53:34 -0700 Subject: [PATCH 0251/1461] async-signature: initial crate (#320) Adds an `async-signature` crate with `AsyncSigner` and `AsyncDigestSigner` traits, based on the `async-trait` crate. Though we'd discussed not using an `async-trait`-based approach (#304), there are some immediate needs for these traits for `std` users, namely providing a common `async` API to things like Cloud KMS services and NetHSMs. I think we can still pursue nightly-only versions of these traits in the `signature` crate itself (ones which will work in `no_std` environments). In the meantime, these traits are self-contained within their own, relatively small crate to unblock making some initial progress with things like Cloud KMS abstractions. --- .github/workflows/async-signature.yml | 35 ++++++++++ Cargo.lock | 19 ++++++ Cargo.toml | 1 + README.md | 22 ++++--- signature/async/CHANGELOG.md | 5 ++ signature/async/Cargo.toml | 23 +++++++ signature/async/README.md | 40 ++++++++++++ signature/async/src/lib.rs | 93 +++++++++++++++++++++++++++ signature/src/lib.rs | 13 ++-- signature/src/signer.rs | 4 +- signature/src/verifier.rs | 2 +- 11 files changed, 237 insertions(+), 20 deletions(-) create mode 100644 .github/workflows/async-signature.yml create mode 100644 signature/async/CHANGELOG.md create mode 100644 signature/async/Cargo.toml create mode 100644 signature/async/README.md create mode 100644 signature/async/src/lib.rs diff --git a/.github/workflows/async-signature.yml b/.github/workflows/async-signature.yml new file mode 100644 index 000000000..edef51df8 --- /dev/null +++ b/.github/workflows/async-signature.yml @@ -0,0 +1,35 @@ +name: async-signature + +on: + pull_request: + paths: + - "signature/**" + - "Cargo.*" + push: + branches: master + +defaults: + run: + working-directory: signature/async + +env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" + +jobs: + test: + runs-on: ubuntu-latest + strategy: + matrix: + rust: + - 1.41.0 # MSRV + - stable + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.rust }} + - run: cargo check --all-features + - run: cargo test --release + - run: cargo test --all-features --release diff --git a/Cargo.lock b/Cargo.lock index c68cc8bea..4fbed0901 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,6 +20,25 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "async-signature" +version = "0.0.0" +dependencies = [ + "async-trait", + "signature", +] + +[[package]] +name = "async-trait" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b246867b8b3b6ae56035f1eb1ed557c1d8eae97f0d53696138a50fa0e3a3b8c0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "bitvec" version = "0.18.3" diff --git a/Cargo.toml b/Cargo.toml index aa9d7d9c4..b1291ebd4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ members = [ "digest", "elliptic-curve", "signature", + "signature/async", "stream-cipher", "universal-hash", ] diff --git a/README.md b/README.md index 32d65d90a..0287721ef 100644 --- a/README.md +++ b/README.md @@ -4,16 +4,17 @@ Collection of traits which describe functionality of cryptographic primitives. ## Crates -| Crate name | Algorithm | Crates.io | Docs | Build Status | -|--------------------|-------------------------------|-----------|-------|--------------| -| [`aead`] | [Authenticated encryption] | [![crates.io](https://img.shields.io/crates/v/aead.svg)](https://crates.io/crates/aead) | [![Documentation](https://docs.rs/aead/badge.svg)](https://docs.rs/aead) | ![build](https://github.com/RustCrypto/traits/workflows/aead/badge.svg?branch=master&event=push) | -| [`block‑cipher`] | [Block cipher] | [![crates.io](https://img.shields.io/crates/v/block-cipher.svg)](https://crates.io/crates/block-cipher) | [![Documentation](https://docs.rs/block-cipher/badge.svg)](https://docs.rs/block-cipher) | ![build](https://github.com/RustCrypto/traits/workflows/block-cipher/badge.svg?branch=master&event=push) | -| [`crypto‑mac`] | [Message authentication code] | [![crates.io](https://img.shields.io/crates/v/crypto-mac.svg)](https://crates.io/crates/crypto-mac) | [![Documentation](https://docs.rs/crypto-mac/badge.svg)](https://docs.rs/crypto-mac) | ![build](https://github.com/RustCrypto/traits/workflows/crypto-mac/badge.svg?branch=master&event=push) | -| [`digest`] | [Cryptographic hash function] | [![crates.io](https://img.shields.io/crates/v/digest.svg)](https://crates.io/crates/digest) | [![Documentation](https://docs.rs/digest/badge.svg)](https://docs.rs/digest) | ![build](https://github.com/RustCrypto/traits/workflows/digest/badge.svg?branch=master&event=push) | -| [`elliptic-curve`] | [Elliptic curve cryptography] | [![crates.io](https://img.shields.io/crates/v/elliptic-curve.svg)](https://crates.io/crates/elliptic-curve) | [![Documentation](https://docs.rs/elliptic-curve/badge.svg)](https://docs.rs/elliptic-curve) | ![build](https://github.com/RustCrypto/traits/workflows/elliptic-curve/badge.svg?branch=master&event=push) | -| [`signature`] | [Digital signature] | [![crates.io](https://img.shields.io/crates/v/signature.svg)](https://crates.io/crates/signature) | [![Documentation](https://docs.rs/signature/badge.svg)](https://docs.rs/signature) | ![build](https://github.com/RustCrypto/traits/workflows/signature/badge.svg?branch=master&event=push) | -| [`stream‑cipher`] | [Stream cipher] | [![crates.io](https://img.shields.io/crates/v/stream-cipher.svg)](https://crates.io/crates/stream-cipher) | [![Documentation](https://docs.rs/stream-cipher/badge.svg)](https://docs.rs/stream-cipher) | ![build](https://github.com/RustCrypto/traits/workflows/stream-cipher/badge.svg?branch=master&event=push) | -| [`universal‑hash`] | [Universal hash function] | [![crates.io](https://img.shields.io/crates/v/universal-hash.svg)](https://crates.io/crates/universal-hash) | [![Documentation](https://docs.rs/universal-hash/badge.svg)](https://docs.rs/universal-hash) | ![build](https://github.com/RustCrypto/traits/workflows/universal-hash/badge.svg?branch=master&event=push) | +| Crate name | Algorithm | Crates.io | Docs | Build Status | +|---------------------|-------------------------------|-----------|-------|--------------| +| [`aead`] | [Authenticated encryption] | [![crates.io](https://img.shields.io/crates/v/aead.svg)](https://crates.io/crates/aead) | [![Documentation](https://docs.rs/aead/badge.svg)](https://docs.rs/aead) | ![build](https://github.com/RustCrypto/traits/workflows/aead/badge.svg?branch=master&event=push) | +| [`async-signature`] | [Digital signature] | [![crates.io](https://img.shields.io/crates/v/async-signature.svg)](https://crates.io/crates/async-signature) | [![Documentation](https://docs.rs/async-signature/badge.svg)](https://docs.rs/async-signature) | ![build](https://github.com/RustCrypto/traits/workflows/async-signature/badge.svg?branch=master&event=push) | +| [`block‑cipher`] | [Block cipher] | [![crates.io](https://img.shields.io/crates/v/block-cipher.svg)](https://crates.io/crates/block-cipher) | [![Documentation](https://docs.rs/block-cipher/badge.svg)](https://docs.rs/block-cipher) | ![build](https://github.com/RustCrypto/traits/workflows/block-cipher/badge.svg?branch=master&event=push) | +| [`crypto‑mac`] | [Message authentication code] | [![crates.io](https://img.shields.io/crates/v/crypto-mac.svg)](https://crates.io/crates/crypto-mac) | [![Documentation](https://docs.rs/crypto-mac/badge.svg)](https://docs.rs/crypto-mac) | ![build](https://github.com/RustCrypto/traits/workflows/crypto-mac/badge.svg?branch=master&event=push) | +| [`digest`] | [Cryptographic hash function] | [![crates.io](https://img.shields.io/crates/v/digest.svg)](https://crates.io/crates/digest) | [![Documentation](https://docs.rs/digest/badge.svg)](https://docs.rs/digest) | ![build](https://github.com/RustCrypto/traits/workflows/digest/badge.svg?branch=master&event=push) | +| [`elliptic-curve`] | [Elliptic curve cryptography] | [![crates.io](https://img.shields.io/crates/v/elliptic-curve.svg)](https://crates.io/crates/elliptic-curve) | [![Documentation](https://docs.rs/elliptic-curve/badge.svg)](https://docs.rs/elliptic-curve) | ![build](https://github.com/RustCrypto/traits/workflows/elliptic-curve/badge.svg?branch=master&event=push) | +| [`signature`] | [Digital signature] | [![crates.io](https://img.shields.io/crates/v/signature.svg)](https://crates.io/crates/signature) | [![Documentation](https://docs.rs/signature/badge.svg)](https://docs.rs/signature) | ![build](https://github.com/RustCrypto/traits/workflows/signature/badge.svg?branch=master&event=push) | +| [`stream‑cipher`] | [Stream cipher] | [![crates.io](https://img.shields.io/crates/v/stream-cipher.svg)](https://crates.io/crates/stream-cipher) | [![Documentation](https://docs.rs/stream-cipher/badge.svg)](https://docs.rs/stream-cipher) | ![build](https://github.com/RustCrypto/traits/workflows/stream-cipher/badge.svg?branch=master&event=push) | +| [`universal‑hash`] | [Universal hash function] | [![crates.io](https://img.shields.io/crates/v/universal-hash.svg)](https://crates.io/crates/universal-hash) | [![Documentation](https://docs.rs/universal-hash/badge.svg)](https://docs.rs/universal-hash) | ![build](https://github.com/RustCrypto/traits/workflows/universal-hash/badge.svg?branch=master&event=push) | ### Additional crates @@ -52,6 +53,7 @@ dual licensed as above, without any additional terms or conditions. [//]: # (crates) [`aead`]: https://github.com/RustCrypto/traits/tree/master/aead +[`async-signature`]: https://github.com/RustCrypto/traits/tree/master/signature/async [`block‑cipher`]: https://github.com/RustCrypto/traits/tree/master/block-cipher [`crypto‑mac`]: https://github.com/RustCrypto/traits/tree/master/crypto-mac [`cryptography`]: https://github.com/RustCrypto/traits/tree/master/cryptography diff --git a/signature/async/CHANGELOG.md b/signature/async/CHANGELOG.md new file mode 100644 index 000000000..d6637e049 --- /dev/null +++ b/signature/async/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). diff --git a/signature/async/Cargo.toml b/signature/async/Cargo.toml new file mode 100644 index 000000000..3f523e043 --- /dev/null +++ b/signature/async/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "async-signature" +description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" +version = "0.0.0" # Also update html_root_url in lib.rs when bumping this +authors = ["RustCrypto Developers"] +license = "Apache-2.0 OR MIT" +documentation = "https://docs.rs/async-signature" +repository = "https://github.com/RustCrypto/traits/tree/master/signature/async" +readme = "README.md" +edition = "2018" +keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"] +categories = ["cryptography", "no-std"] + +[dependencies] +async-trait = "0.1" +signature = { version = "1.2.0", path = ".." } + +[features] +digest = ["signature/digest-preview"] + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] diff --git a/signature/async/README.md b/signature/async/README.md new file mode 100644 index 000000000..b43b100bc --- /dev/null +++ b/signature/async/README.md @@ -0,0 +1,40 @@ +# RustCrypto: `async-signature` + +[![crate][crate-image]][crate-link] +[![Docs][docs-image]][docs-link] +![Apache2/MIT licensed][license-image] +![Rust Version][rustc-image] +[![Build Status][build-image]][build-link] + +## Minimum Supported Rust Version + +Rust **1.41** or higher. + +Minimum supported Rust version can be changed in the future, but it will be +done with a minor version bump. + +## License + +Licensed under either of + + * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) + * [MIT license](http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall be +dual licensed as above, without any additional terms or conditions. + +[//]: # (badges) + +[crate-image]: https://img.shields.io/crates/v/async-signature.svg +[crate-link]: https://crates.io/crates/async-signature +[docs-image]: https://docs.rs/async-signature/badge.svg +[docs-link]: https://docs.rs/async-signature/ +[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg +[build-image]: https://github.com/RustCrypto/traits/workflows/async-signature/badge.svg?branch=master&event=push +[build-link]: https://github.com/RustCrypto/traits/actions?query=workflow:async-signature diff --git a/signature/async/src/lib.rs b/signature/async/src/lib.rs new file mode 100644 index 000000000..0f73b34e3 --- /dev/null +++ b/signature/async/src/lib.rs @@ -0,0 +1,93 @@ +//! RustCrypto: `async-signature` crate. +//! +//! This is an experimental crate containing `async` versions of select traits +//! from the [`signature`] crate, namely [`AsyncSigner`] and when the `digest` +//! feature is enabled, [`AsyncDigestSigner`]. +//! +//! Traits are implemented using [`async-trait`], which rewrites the traits to +//! use `Box`-ed futures. +//! +//! The longer-term goal is to move these traits into the [`signature`] crate +//! itself, however before doing so we'd like to remove the [`async-trait`] +//! dependency in order to enable use in `no_std` environments. This crate +//! is a stopgap until that happens. +//! +//! For more information, see: +//! +//! +//! [`async-trait`]: https://docs.rs/async-trait + +#![cfg_attr(docsrs, feature(doc_cfg))] +#![doc( + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", + html_root_url = "https://docs.rs/async-signature/0.0.0" +)] +#![forbid(unsafe_code)] +#![warn(missing_docs, rust_2018_idioms, unused_qualifications)] + +pub use signature::{self, Error, Signature}; + +#[cfg(feature = "digest")] +pub use signature::digest::{self, Digest}; + +use async_trait::async_trait; + +/// Asynchronously sign the provided message bytestring using `Self` +/// (e.g. client for a Cloud KMS or HSM), returning a digital signature. +/// +/// This trait is an async equivalent of the [`signature::Signer`] trait. +#[async_trait] +pub trait AsyncSigner +where + Self: Send + Sync, + S: Signature + Send + 'static, +{ + /// Attempt to sign the given message, returning a digital signature on + /// success, or an error if something went wrong. + /// + /// The main intended use case for signing errors is when communicating + /// with external signers, e.g. cloud KMS, HSMs, or other hardware tokens. + async fn sign_async(&self, msg: &[u8]) -> Result; +} + +#[async_trait] +impl AsyncSigner for T +where + S: Signature + Send + 'static, + T: signature::Signer + Send + Sync, +{ + async fn sign_async(&self, msg: &[u8]) -> Result { + self.try_sign(msg) + } +} + +/// Asynchronously sign the given prehashed message [`Digest`] using `Self`. +/// +/// This trait is an async equivalent of the [`signature::DigestSigner`] trait. +#[cfg(feature = "digest")] +#[cfg_attr(docsrs, doc(cfg(feature = "digest")))] +#[async_trait] +pub trait AsyncDigestSigner +where + Self: Send + Sync, + D: Digest + Send + 'static, + S: Signature + 'static, +{ + /// Attempt to sign the given prehashed message [`Digest`], returning a + /// digital signature on success, or an error if something went wrong. + async fn sign_digest_async(&self, digest: D) -> Result; +} + +#[cfg(feature = "digest")] +#[async_trait] +impl AsyncDigestSigner for T +where + D: Digest + Send + 'static, + S: Signature + Send + 'static, + T: signature::DigestSigner + Send + Sync, +{ + async fn sign_digest_async(&self, digest: D) -> Result { + self.try_sign_digest(digest) + } +} diff --git a/signature/src/lib.rs b/signature/src/lib.rs index 6f69f1684..9a1cdab9a 100644 --- a/signature/src/lib.rs +++ b/signature/src/lib.rs @@ -147,8 +147,12 @@ //! systems which rely on a cryptographically secure random number generator //! for security. //! +//! NOTE: the [`async-signature`] crate contains experimental `async` support +//! for [`Signer`] and [`DigestSigner`]. +//! +//! [`async-signature`]: https://docs.rs/async-signature +//! [`digest`]: https://docs.rs/digest/ //! [`Digest`]: https://docs.rs/digest/latest/digest/trait.Digest.html -//! [`digest`]: https://docs.rs/digest/latest/digest/ //! [Fiat-Shamir heuristic]: https://en.wikipedia.org/wiki/Fiat%E2%80%93Shamir_heuristic #![no_std] @@ -159,12 +163,7 @@ html_root_url = "https://docs.rs/signature/1.2.2" )] #![forbid(unsafe_code)] -#![warn( - missing_docs, - rust_2018_idioms, - unused_qualifications, - intra_doc_link_resolution_failure -)] +#![warn(missing_docs, rust_2018_idioms, unused_qualifications)] #[cfg(feature = "std")] extern crate std; diff --git a/signature/src/signer.rs b/signature/src/signer.rs index 24054e0e1..0031b73a7 100644 --- a/signature/src/signer.rs +++ b/signature/src/signer.rs @@ -50,7 +50,7 @@ where D: Digest, S: Signature, { - /// Sign the given prehashed message `Digest`, returning a signature. + /// Sign the given prehashed message [`Digest`], returning a signature. /// /// Panics in the event of a signing error. fn sign_digest(&self, digest: D) -> S { @@ -58,7 +58,7 @@ where .expect("signature operation failed") } - /// Attempt to sign the given prehashed message `Digest`, returning a + /// Attempt to sign the given prehashed message [`Digest`], returning a /// digital signature on success, or an error if something went wrong. fn try_sign_digest(&self, digest: D) -> Result; } diff --git a/signature/src/verifier.rs b/signature/src/verifier.rs index 45562ee61..4d6efbc2b 100644 --- a/signature/src/verifier.rs +++ b/signature/src/verifier.rs @@ -41,6 +41,6 @@ where D: Digest, S: Signature, { - /// Verify the signature against the given `Digest` output. + /// Verify the signature against the given [`Digest`] output. fn verify_digest(&self, digest: D, signature: &S) -> Result<(), Error>; } From 6d9f7278cbf244d15b7566d4e67f2175bf03b7c0 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 6 Oct 2020 08:18:10 -0700 Subject: [PATCH 0252/1461] async-signature: add Zulip badge to README.md (#322) --- signature/async/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/signature/async/README.md b/signature/async/README.md index b43b100bc..1ec573ab3 100644 --- a/signature/async/README.md +++ b/signature/async/README.md @@ -4,6 +4,7 @@ [![Docs][docs-image]][docs-link] ![Apache2/MIT licensed][license-image] ![Rust Version][rustc-image] +[![Project Chat][chat-image]][chat-link] [![Build Status][build-image]][build-link] ## Minimum Supported Rust Version @@ -36,5 +37,7 @@ dual licensed as above, without any additional terms or conditions. [docs-link]: https://docs.rs/async-signature/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg [rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg +[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg +[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260048-signatures [build-image]: https://github.com/RustCrypto/traits/workflows/async-signature/badge.svg?branch=master&event=push [build-link]: https://github.com/RustCrypto/traits/actions?query=workflow:async-signature From 61b0950e603c545fc9becbb54b82793a3c508a2e Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 6 Oct 2020 08:29:19 -0700 Subject: [PATCH 0253/1461] async-signature v0.0.1 (#323) --- Cargo.lock | 2 +- signature/async/CHANGELOG.md | 3 +++ signature/async/Cargo.toml | 2 +- signature/async/src/lib.rs | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4fbed0901..9fadbb795 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -22,7 +22,7 @@ dependencies = [ [[package]] name = "async-signature" -version = "0.0.0" +version = "0.0.1" dependencies = [ "async-trait", "signature", diff --git a/signature/async/CHANGELOG.md b/signature/async/CHANGELOG.md index d6637e049..2815fcdc5 100644 --- a/signature/async/CHANGELOG.md +++ b/signature/async/CHANGELOG.md @@ -3,3 +3,6 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## 0.0.1 (2020-10-06) +- Initial release diff --git a/signature/async/Cargo.toml b/signature/async/Cargo.toml index 3f523e043..dafbc68d6 100644 --- a/signature/async/Cargo.toml +++ b/signature/async/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "async-signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "0.0.0" # Also update html_root_url in lib.rs when bumping this +version = "0.0.1" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/async-signature" diff --git a/signature/async/src/lib.rs b/signature/async/src/lib.rs index 0f73b34e3..89b6a5edc 100644 --- a/signature/async/src/lib.rs +++ b/signature/async/src/lib.rs @@ -21,7 +21,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_root_url = "https://docs.rs/async-signature/0.0.0" + html_root_url = "https://docs.rs/async-signature/0.0.1" )] #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms, unused_qualifications)] From b64d6d25143ab38b25dec384ee455ce8b7b872a7 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 8 Oct 2020 10:37:43 -0700 Subject: [PATCH 0254/1461] elliptic-curve: add SecretBytes newtype (#324) The `SecretValue` trait was supposed to allow curve crates with an `arithmetic` feature to use a `NonZeroScalar` as their secret value, and crates which don't to use `FieldBytes`. Unfortunately `zeroize` has no `generic-array` integration, and therefore `GenericArray` (which is what `FieldBytes` is a type alias for) cannot directly be used as `SecretValue::Secret`. This commit adds a thin `SecretBytes` newtype which wraps `FieldBytes` and impls `Zeroize` so it can be used as `SecretValue::Secret`. --- elliptic-curve/src/secret_key.rs | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 1265b8abc..139d75b8f 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -11,6 +11,7 @@ use crate::{error::Error, Curve, FieldBytes}; use core::{ convert::{TryFrom, TryInto}, fmt::{self, Debug}, + ops::Deref, }; use zeroize::Zeroize; @@ -148,3 +149,34 @@ where self.secret_value.zeroize(); } } + +/// Newtype wrapper for [`FieldBytes`] which impls [`Zeroize`]. +/// +/// This allows it to fulfill the [`Zeroize`] bound on [`SecretValue::Secret`]. +pub struct SecretBytes(FieldBytes); + +impl From> for SecretBytes { + fn from(bytes: FieldBytes) -> SecretBytes { + Self(bytes) + } +} + +impl AsRef<[u8]> for SecretBytes { + fn as_ref(&self) -> &[u8] { + &self.0 + } +} + +impl Deref for SecretBytes { + type Target = FieldBytes; + + fn deref(&self) -> &FieldBytes { + &self.0 + } +} + +impl Zeroize for SecretBytes { + fn zeroize(&mut self) { + self.0.as_mut().zeroize(); + } +} From 83f2e51530d07ff32022a8c774ef40e051f3f299 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 8 Oct 2020 10:56:37 -0700 Subject: [PATCH 0255/1461] elliptic-curve v0.6.3 (#325) --- Cargo.lock | 2 +- elliptic-curve/CHANGELOG.md | 6 ++++++ elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9fadbb795..becde8fcb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -155,7 +155,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.6.2" +version = "0.6.3" dependencies = [ "bitvec", "const-oid", diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index 16a6c7158..0c1247580 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.6.3 (2020-10-08) +### Added +- `SecretBytes` newtype ([#324]) + +[#324]: https://github.com/RustCrypto/traits/pull/324 + ## 0.6.2 (2020-09-24) ### Added - `sec1::EncodedPoint::to_untagged_bytes()` method ([#312]) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index e34679cfd..538aeceb9 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -5,7 +5,7 @@ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. """ -version = "0.6.2" # Also update html_root_url in lib.rs when bumping this +version = "0.6.3" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" repository = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve" diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 65c60444f..cdffc70ba 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -16,7 +16,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.6.2" + html_root_url = "https://docs.rs/elliptic-curve/0.6.3" )] #[cfg(feature = "alloc")] From 36181bc02adda7882233c69c3a139e0629af2b31 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 8 Oct 2020 11:25:12 -0700 Subject: [PATCH 0256/1461] elliptic-curve: impl From for FieldBytes (#326) This is needed to fulfill the trait bounds for `SecretValue` --- elliptic-curve/src/secret_key.rs | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 139d75b8f..137c9ee56 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -26,7 +26,22 @@ use rand_core::{CryptoRng, RngCore}; /// Inner value stored by a [`SecretKey`]. pub trait SecretValue: Curve { - /// Inner secret value + /// Inner secret value. + /// + /// ⚠️ WARNING ⚠️ + /// + /// This type is not intended to be part of the public API and in future + /// versions of this crate we will try to explore ways to hide it. + /// + /// Crates such as `k256` and `p256` conditionally define this type + /// differently depending on what cargo features are enabled. + /// This means any consumers of this crate attempting to use this type + /// may experience breakages if the cargo features are not what are + /// expected. + /// + /// We regret exposing it as part of the public API for now, however if + /// you do reference this type as a downstream consumer of a curve crate, + /// be aware you will experience breakages! type Secret: Into> + Zeroize; /// Parse the secret value from bytes @@ -161,6 +176,12 @@ impl From> for SecretBytes { } } +impl From> for FieldBytes { + fn from(bytes: SecretBytes) -> FieldBytes { + bytes.0 + } +} + impl AsRef<[u8]> for SecretBytes { fn as_ref(&self) -> &[u8] { &self.0 From 00f6fd1b7ca78cc138a0faa8e8cdbb5832719107 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 8 Oct 2020 11:39:53 -0700 Subject: [PATCH 0257/1461] elliptic-curve v0.6.4 (#327) --- Cargo.lock | 2 +- elliptic-curve/CHANGELOG.md | 6 ++++++ elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index becde8fcb..ea1241bc5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -155,7 +155,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.6.3" +version = "0.6.4" dependencies = [ "bitvec", "const-oid", diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index 0c1247580..9e9754252 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.6.4 (2020-10-08) +### Added +- Impl `From>` for `FieldBytes` ([#326]) + +[#326]: https://github.com/RustCrypto/traits/pull/326 + ## 0.6.3 (2020-10-08) ### Added - `SecretBytes` newtype ([#324]) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 538aeceb9..a79d205d1 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -5,7 +5,7 @@ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. """ -version = "0.6.3" # Also update html_root_url in lib.rs when bumping this +version = "0.6.4" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" repository = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve" diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index cdffc70ba..dc702e908 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -16,7 +16,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.6.3" + html_root_url = "https://docs.rs/elliptic-curve/0.6.4" )] #[cfg(feature = "alloc")] From d77bef50155bd084d6e05167eba5dc5743693a77 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 8 Oct 2020 13:51:40 -0700 Subject: [PATCH 0258/1461] elliptic-curve: work around nightly-2020-10-06 breakage (#328) The `elliptic-curve` crate no longer builds on `nightly`. Possible cause: https://github.com/rust-lang/rust/issues/77638 Unfortunately this means rustdoc builds on https://docs.rs fail! This commit works around the issue. --- elliptic-curve/src/ecdh.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/elliptic-curve/src/ecdh.rs b/elliptic-curve/src/ecdh.rs index 48e4d6aa7..5fd3c87d0 100644 --- a/elliptic-curve/src/ecdh.rs +++ b/elliptic-curve/src/ecdh.rs @@ -73,7 +73,8 @@ where /// /// The `compress` flag enables point compression. pub fn public_key(&self) -> PublicKey { - (C::ProjectivePoint::generator() * &self.scalar) + #[allow(clippy::op_ref)] + (C::ProjectivePoint::generator() * &*self.scalar) .to_affine() .into() } From 10f448e73d16462643bf784e0635651308363a68 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 8 Oct 2020 14:07:33 -0700 Subject: [PATCH 0259/1461] elliptic-curve v0.6.5 (#329) --- Cargo.lock | 2 +- elliptic-curve/CHANGELOG.md | 6 ++++++ elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ea1241bc5..e41705a76 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -155,7 +155,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.6.4" +version = "0.6.5" dependencies = [ "bitvec", "const-oid", diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index 9e9754252..b48190ad7 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.6.5 (2020-10-08) +### Fixed +- Work around `nightly-2020-10-06` breakage ([#328]) + +[#328]: https://github.com/RustCrypto/traits/pull/328 + ## 0.6.4 (2020-10-08) ### Added - Impl `From>` for `FieldBytes` ([#326]) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index a79d205d1..12bcad647 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -5,7 +5,7 @@ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. """ -version = "0.6.4" # Also update html_root_url in lib.rs when bumping this +version = "0.6.5" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" repository = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve" diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index dc702e908..ea009f7d4 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -16,7 +16,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.6.4" + html_root_url = "https://docs.rs/elliptic-curve/0.6.5" )] #[cfg(feature = "alloc")] From 88cec74d1a80266fc94743b736d35c3809a1def1 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 8 Oct 2020 14:49:02 -0700 Subject: [PATCH 0260/1461] elliptic-curve: derive `Clone` on `SecretBytes` (#330) --- elliptic-curve/src/secret_key.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 137c9ee56..118f1d89a 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -168,6 +168,7 @@ where /// Newtype wrapper for [`FieldBytes`] which impls [`Zeroize`]. /// /// This allows it to fulfill the [`Zeroize`] bound on [`SecretValue::Secret`]. +#[derive(Clone)] pub struct SecretBytes(FieldBytes); impl From> for SecretBytes { From 1524ac4f1c69becd486ba7e48eeda9141cc4010b Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 8 Oct 2020 14:58:50 -0700 Subject: [PATCH 0261/1461] elliptic-curve v0.6.6 (#331) --- Cargo.lock | 2 +- elliptic-curve/CHANGELOG.md | 6 ++++++ elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e41705a76..04b13aba0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -155,7 +155,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.6.5" +version = "0.6.6" dependencies = [ "bitvec", "const-oid", diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index b48190ad7..4be92102b 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.6.6 (2020-10-08) +### Added +- Derive `Clone` on `SecretBytes` ([#330]) + +[#300]: https://github.com/RustCrypto/traits/pull/300 + ## 0.6.5 (2020-10-08) ### Fixed - Work around `nightly-2020-10-06` breakage ([#328]) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 12bcad647..f3e1430c2 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -5,7 +5,7 @@ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. """ -version = "0.6.5" # Also update html_root_url in lib.rs when bumping this +version = "0.6.6" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" repository = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve" diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index ea009f7d4..4f1e239af 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -16,7 +16,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.6.5" + html_root_url = "https://docs.rs/elliptic-curve/0.6.6" )] #[cfg(feature = "alloc")] From 6c23a077d31a13c88ecfd73e816e18d17dc10478 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 14 Oct 2020 08:17:48 -0700 Subject: [PATCH 0262/1461] stream-cipher: remove NewBlockCipher bound on FromBlockCipher (#333) Note: breaking change. As far as I can tell this was an oversight: `FromBlockCipher` never needs to instantiate a new block cipher (isn't that the point?), making this bound needlessly limiting. The rationale for it in the first place appears to be for the blanket impl of `NewStreamCipher` for `C: FromBlockCipher` which needs it, but we can add the bound to the blanket impl, rather than (needlessly) sticking it on the trait. --- Cargo.lock | 4 ++-- cryptography/Cargo.toml | 4 ++-- stream-cipher/Cargo.toml | 2 +- stream-cipher/src/lib.rs | 3 ++- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 04b13aba0..aa76a1c97 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -124,7 +124,7 @@ dependencies = [ [[package]] name = "cryptography" -version = "0.4.1" +version = "0.5.0-pre" dependencies = [ "aead", "block-cipher 0.8.0", @@ -349,7 +349,7 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "stream-cipher" -version = "0.7.1" +version = "0.8.0-pre" dependencies = [ "blobby 0.3.0", "block-cipher 0.8.0", diff --git a/cryptography/Cargo.toml b/cryptography/Cargo.toml index 75b87d96c..11c0ef8db 100644 --- a/cryptography/Cargo.toml +++ b/cryptography/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cryptography" -version = "0.4.1" +version = "0.5.0-pre" authors = ["The RustCrypto Project Developers"] license = "Apache-2.0 OR MIT" description = "Facade crate for the RustCrypto project's traits" @@ -18,7 +18,7 @@ digest = { version = "0.9", optional = true, path = "../digest" } elliptic-curve = { version = "0.6", optional = true, path = "../elliptic-curve" } mac = { version = "0.9", package = "crypto-mac", optional = true, path = "../crypto-mac" } signature = { version = "1.2.0", optional = true, default-features = false, path = "../signature" } -stream-cipher = { version = "0.7", optional = true, path = "../stream-cipher" } +stream-cipher = { version = "0.8.0-pre", optional = true, path = "../stream-cipher" } universal-hash = { version = "0.4", optional = true, path = "../universal-hash" } [features] diff --git a/stream-cipher/Cargo.toml b/stream-cipher/Cargo.toml index 8dedd33c7..495951f8c 100644 --- a/stream-cipher/Cargo.toml +++ b/stream-cipher/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "stream-cipher" description = "Stream cipher traits" -version = "0.7.1" +version = "0.8.0-pre" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/stream-cipher/src/lib.rs b/stream-cipher/src/lib.rs index e35f0008d..a6bc429d8 100644 --- a/stream-cipher/src/lib.rs +++ b/stream-cipher/src/lib.rs @@ -173,7 +173,7 @@ impl SyncStreamCipher for &mut C { #[cfg_attr(docsrs, doc(cfg(feature = "block-cipher")))] pub trait FromBlockCipher { /// Block cipher - type BlockCipher: BlockCipher + NewBlockCipher; + type BlockCipher: BlockCipher; /// Nonce size in bytes type NonceSize: ArrayLength; @@ -188,6 +188,7 @@ pub trait FromBlockCipher { impl NewStreamCipher for C where C: FromBlockCipher, + C::BlockCipher: NewBlockCipher, { type KeySize = <::BlockCipher as NewBlockCipher>::KeySize; type NonceSize = ::NonceSize; From cdd3492381661b5d3592f98e3e2b936eec09ba00 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 14 Oct 2020 10:39:47 -0700 Subject: [PATCH 0263/1461] stream-cipher: add FromBlockCipherMut trait (#334) Support for initializing a stream cipher from a `BlockCipherMut`. This is a corollary to `FromBlockCipher`, but for cases where `mut` access is needed to the inner block cipher instance (e.g. cryptographic accelerator hardware peripherals). Using chained blanket impls, it's possible to allow a blanket impl of `NewStreamCipher` for types which impl either `FromBlockCipherMut` or `FromBlockCipher`. --- stream-cipher/src/lib.rs | 46 ++++++++++++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/stream-cipher/src/lib.rs b/stream-cipher/src/lib.rs index a6bc429d8..0471d57fc 100644 --- a/stream-cipher/src/lib.rs +++ b/stream-cipher/src/lib.rs @@ -35,7 +35,7 @@ use generic_array::typenum::Unsigned; use generic_array::{ArrayLength, GenericArray}; #[cfg(feature = "block-cipher")] -use block_cipher::{BlockCipher, NewBlockCipher}; +use block_cipher::{BlockCipher, BlockCipherMut, NewBlockCipher}; /// Key for an algorithm that implements [`NewStreamCipher`]. pub type Key = GenericArray::KeySize>; @@ -184,18 +184,50 @@ pub trait FromBlockCipher { ) -> Self; } +/// Trait for initializing a stream cipher from a mutable block cipher #[cfg(feature = "block-cipher")] -impl NewStreamCipher for C +#[cfg_attr(docsrs, doc(cfg(feature = "block-cipher")))] +pub trait FromBlockCipherMut { + /// Block cipher + type BlockCipher: BlockCipherMut; + /// Nonce size in bytes + type NonceSize: ArrayLength; + + /// Instantiate a stream cipher from a block cipher + fn from_block_cipher_mut( + cipher: Self::BlockCipher, + nonce: &GenericArray, + ) -> Self; +} + +#[cfg(feature = "block-cipher")] +impl FromBlockCipherMut for C where C: FromBlockCipher, - C::BlockCipher: NewBlockCipher, { - type KeySize = <::BlockCipher as NewBlockCipher>::KeySize; + type BlockCipher = ::BlockCipher; type NonceSize = ::NonceSize; + fn from_block_cipher_mut( + cipher: Self::BlockCipher, + nonce: &GenericArray, + ) -> C { + C::from_block_cipher(cipher, nonce) + } +} + +#[cfg(feature = "block-cipher")] +impl NewStreamCipher for C +where + C: FromBlockCipherMut, + C::BlockCipher: NewBlockCipher, +{ + type KeySize = <::BlockCipher as NewBlockCipher>::KeySize; + type NonceSize = ::NonceSize; + fn new(key: &Key, nonce: &Nonce) -> C { - C::from_block_cipher( - <::BlockCipher as NewBlockCipher>::new(key), + C::from_block_cipher_mut( + <::BlockCipher as NewBlockCipher>::new(key), nonce, ) } @@ -208,7 +240,7 @@ where .map_err(|_| InvalidKeyNonceLength) .map(|cipher| { let nonce = GenericArray::from_slice(nonce); - Self::from_block_cipher(cipher, nonce) + Self::from_block_cipher_mut(cipher, nonce) }) } } From 6d9f88b4a3748b754863cd041771314478e6d458 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 14 Oct 2020 10:52:42 -0700 Subject: [PATCH 0264/1461] stream-cipher v0.8.0-pre (#335) --- stream-cipher/CHANGELOG.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/stream-cipher/CHANGELOG.md b/stream-cipher/CHANGELOG.md index c8032dd6d..cadf15cb6 100644 --- a/stream-cipher/CHANGELOG.md +++ b/stream-cipher/CHANGELOG.md @@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.8.0-pre (2020-10-14) +### Added +- `FromBlockCipherMut` trait ([#334]) + +### Removed +- `NewBlockCipher` bound on `FromBlockCipher` ([#333]) + +[#334]: https://github.com/RustCrypto/traits/pull/334 +[#333]: https://github.com/RustCrypto/traits/pull/333 + ## 0.7.1 (2020-08-25) ### Fixed - Computation of `SeekNum::to_block_byte` for numbers which are not a power of 2 ([#268]) From 5fcffeb4b1a817a3f3954d0047a205013ac502e4 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 15 Oct 2020 11:37:47 -0700 Subject: [PATCH 0265/1461] Unify `block-cipher` and `stream-cipher` into `cipher` (#337) We are now owners of the `cipher` crate: https://crates.io/crates/cipher This commit unifies the existing `block-cipher` and `stream-cipher` crates into the `cipher` crate, placing their code under the `cipher::block` and `cipher::stream` modules respectively. Ideally this means the crate is a drop-in replacement, and all end users need to do is `s/block_cipher/cipher::block/` and `s/stream_cipher/cipher::stream` to upgrade. --- .../{block-cipher.yml => cipher.yml} | 6 +- .github/workflows/crypto-mac.yml | 2 +- .github/workflows/cryptography.yml | 2 +- .github/workflows/stream-cipher.yml | 57 ----- Cargo.lock | 41 +--- Cargo.toml | 3 +- README.md | 24 +-- block-cipher/CHANGELOG.md | 58 ----- block-cipher/LICENSE-MIT | 25 --- block-cipher/README.md | 59 ----- cipher/CHANGELOG.md | 11 + {block-cipher => cipher}/Cargo.toml | 10 +- {block-cipher => cipher}/LICENSE-APACHE | 0 {stream-cipher => cipher}/LICENSE-MIT | 2 +- {stream-cipher => cipher}/README.md | 23 +- .../src/lib.rs => cipher/src/block.rs | 20 +- {block-cipher/src => cipher/src/block}/dev.rs | 0 .../src => cipher/src/block}/errors.rs | 0 cipher/src/lib.rs | 25 +++ .../src/lib.rs => cipher/src/stream.rs | 28 +-- .../src => cipher/src/stream}/dev.rs | 0 .../src => cipher/src/stream}/errors.rs | 0 crypto-mac/Cargo.toml | 4 +- crypto-mac/src/lib.rs | 16 +- cryptography/Cargo.toml | 8 +- cryptography/src/lib.rs | 10 +- stream-cipher/CHANGELOG.md | 78 ------- stream-cipher/Cargo.toml | 30 --- stream-cipher/LICENSE-APACHE | 201 ------------------ 29 files changed, 104 insertions(+), 639 deletions(-) rename .github/workflows/{block-cipher.yml => cipher.yml} (93%) delete mode 100644 .github/workflows/stream-cipher.yml delete mode 100644 block-cipher/CHANGELOG.md delete mode 100644 block-cipher/LICENSE-MIT delete mode 100644 block-cipher/README.md create mode 100644 cipher/CHANGELOG.md rename {block-cipher => cipher}/Cargo.toml (65%) rename {block-cipher => cipher}/LICENSE-APACHE (100%) rename {stream-cipher => cipher}/LICENSE-MIT (95%) rename {stream-cipher => cipher}/README.md (69%) rename block-cipher/src/lib.rs => cipher/src/block.rs (88%) rename {block-cipher/src => cipher/src/block}/dev.rs (100%) rename {block-cipher/src => cipher/src/block}/errors.rs (100%) create mode 100644 cipher/src/lib.rs rename stream-cipher/src/lib.rs => cipher/src/stream.rs (91%) rename {stream-cipher/src => cipher/src/stream}/dev.rs (100%) rename {stream-cipher/src => cipher/src/stream}/errors.rs (100%) delete mode 100644 stream-cipher/CHANGELOG.md delete mode 100644 stream-cipher/Cargo.toml delete mode 100644 stream-cipher/LICENSE-APACHE diff --git a/.github/workflows/block-cipher.yml b/.github/workflows/cipher.yml similarity index 93% rename from .github/workflows/block-cipher.yml rename to .github/workflows/cipher.yml index 3f83ecd64..aaa7ad29b 100644 --- a/.github/workflows/block-cipher.yml +++ b/.github/workflows/cipher.yml @@ -1,16 +1,16 @@ -name: block-cipher +name: cipher on: pull_request: paths: - - "block-cipher/**" + - "cipher/**" - "Cargo.*" push: branches: master defaults: run: - working-directory: block-cipher + working-directory: cipher env: CARGO_INCREMENTAL: 0 diff --git a/.github/workflows/crypto-mac.yml b/.github/workflows/crypto-mac.yml index 490dc7cfa..5e4ade5dd 100644 --- a/.github/workflows/crypto-mac.yml +++ b/.github/workflows/crypto-mac.yml @@ -51,7 +51,7 @@ jobs: toolchain: ${{ matrix.rust }} - run: cargo check --all-features - run: cargo test --release - - run: cargo test --features block-cipher --release + - run: cargo test --features cipher --release - run: cargo test --features dev --release - run: cargo test --features std --release - run: cargo test --all-features --release diff --git a/.github/workflows/cryptography.yml b/.github/workflows/cryptography.yml index 3d42b3d93..8233c9969 100644 --- a/.github/workflows/cryptography.yml +++ b/.github/workflows/cryptography.yml @@ -37,7 +37,7 @@ jobs: override: true - run: cargo build --no-default-features --release --target ${{ matrix.target }} - run: cargo build --no-default-features --release --target ${{ matrix.target }} - --features aead,block-cipher,mac,digest,elliptic-curve,signature,stream-cipher,universal-hash + --features aead,cipher,mac,digest,elliptic-curve,signature,universal-hash test: runs-on: ubuntu-latest strategy: diff --git a/.github/workflows/stream-cipher.yml b/.github/workflows/stream-cipher.yml deleted file mode 100644 index c6d9a535b..000000000 --- a/.github/workflows/stream-cipher.yml +++ /dev/null @@ -1,57 +0,0 @@ -name: stream-cipher - -on: - pull_request: - paths: - - "stream-cipher/**" - - "Cargo.*" - push: - branches: master - -defaults: - run: - working-directory: stream-cipher - -env: - CARGO_INCREMENTAL: 0 - RUSTFLAGS: "-Dwarnings" - -jobs: - build: - runs-on: ubuntu-latest - strategy: - matrix: - rust: - - 1.41.0 # MSRV - - stable - target: - - thumbv7em-none-eabi - - wasm32-unknown-unknown - steps: - - uses: actions/checkout@v1 - - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: ${{ matrix.rust }} - target: ${{ matrix.target }} - override: true - - run: cargo build --no-default-features --release --target ${{ matrix.target }} - test: - runs-on: ubuntu-latest - strategy: - matrix: - rust: - - 1.41.0 # MSRV - - stable - steps: - - uses: actions/checkout@v1 - - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: ${{ matrix.rust }} - - run: cargo check --all-features - - run: cargo test --release - - run: cargo test --features block-cipher - - run: cargo test --features dev --release - - run: cargo test --features std --release - - run: cargo test --all-features --release diff --git a/Cargo.lock b/Cargo.lock index aa76a1c97..28fa22dca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -71,23 +71,6 @@ dependencies = [ "generic-array 0.14.4", ] -[[package]] -name = "block-cipher" -version = "0.8.0" -dependencies = [ - "blobby 0.3.0", - "generic-array 0.14.4", -] - -[[package]] -name = "block-cipher" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f337a3e6da609650eb74e02bc9fac7b735049f7623ab12f2e4c719316fcc7e80" -dependencies = [ - "generic-array 0.14.4", -] - [[package]] name = "byteorder" version = "1.3.4" @@ -100,6 +83,14 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +[[package]] +name = "cipher" +version = "0.2.0-pre" +dependencies = [ + "blobby 0.3.0", + "generic-array 0.14.4", +] + [[package]] name = "const-oid" version = "0.1.0" @@ -114,10 +105,10 @@ checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634" [[package]] name = "crypto-mac" -version = "0.9.1" +version = "0.10.0-pre" dependencies = [ "blobby 0.3.0", - "block-cipher 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cipher", "generic-array 0.14.4", "subtle", ] @@ -127,12 +118,11 @@ name = "cryptography" version = "0.5.0-pre" dependencies = [ "aead", - "block-cipher 0.8.0", + "cipher", "crypto-mac", "digest 0.9.0", "elliptic-curve", "signature", - "stream-cipher", "universal-hash", ] @@ -347,15 +337,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" -[[package]] -name = "stream-cipher" -version = "0.8.0-pre" -dependencies = [ - "blobby 0.3.0", - "block-cipher 0.8.0", - "generic-array 0.14.4", -] - [[package]] name = "subtle" version = "2.3.0" diff --git a/Cargo.toml b/Cargo.toml index b1291ebd4..c940a69a8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,13 +1,12 @@ [workspace] members = [ "aead", - "block-cipher", + "cipher", "crypto-mac", "cryptography", "digest", "elliptic-curve", "signature", "signature/async", - "stream-cipher", "universal-hash", ] diff --git a/README.md b/README.md index 0287721ef..27511562d 100644 --- a/README.md +++ b/README.md @@ -4,17 +4,16 @@ Collection of traits which describe functionality of cryptographic primitives. ## Crates -| Crate name | Algorithm | Crates.io | Docs | Build Status | -|---------------------|-------------------------------|-----------|-------|--------------| -| [`aead`] | [Authenticated encryption] | [![crates.io](https://img.shields.io/crates/v/aead.svg)](https://crates.io/crates/aead) | [![Documentation](https://docs.rs/aead/badge.svg)](https://docs.rs/aead) | ![build](https://github.com/RustCrypto/traits/workflows/aead/badge.svg?branch=master&event=push) | -| [`async-signature`] | [Digital signature] | [![crates.io](https://img.shields.io/crates/v/async-signature.svg)](https://crates.io/crates/async-signature) | [![Documentation](https://docs.rs/async-signature/badge.svg)](https://docs.rs/async-signature) | ![build](https://github.com/RustCrypto/traits/workflows/async-signature/badge.svg?branch=master&event=push) | -| [`block‑cipher`] | [Block cipher] | [![crates.io](https://img.shields.io/crates/v/block-cipher.svg)](https://crates.io/crates/block-cipher) | [![Documentation](https://docs.rs/block-cipher/badge.svg)](https://docs.rs/block-cipher) | ![build](https://github.com/RustCrypto/traits/workflows/block-cipher/badge.svg?branch=master&event=push) | -| [`crypto‑mac`] | [Message authentication code] | [![crates.io](https://img.shields.io/crates/v/crypto-mac.svg)](https://crates.io/crates/crypto-mac) | [![Documentation](https://docs.rs/crypto-mac/badge.svg)](https://docs.rs/crypto-mac) | ![build](https://github.com/RustCrypto/traits/workflows/crypto-mac/badge.svg?branch=master&event=push) | -| [`digest`] | [Cryptographic hash function] | [![crates.io](https://img.shields.io/crates/v/digest.svg)](https://crates.io/crates/digest) | [![Documentation](https://docs.rs/digest/badge.svg)](https://docs.rs/digest) | ![build](https://github.com/RustCrypto/traits/workflows/digest/badge.svg?branch=master&event=push) | -| [`elliptic-curve`] | [Elliptic curve cryptography] | [![crates.io](https://img.shields.io/crates/v/elliptic-curve.svg)](https://crates.io/crates/elliptic-curve) | [![Documentation](https://docs.rs/elliptic-curve/badge.svg)](https://docs.rs/elliptic-curve) | ![build](https://github.com/RustCrypto/traits/workflows/elliptic-curve/badge.svg?branch=master&event=push) | -| [`signature`] | [Digital signature] | [![crates.io](https://img.shields.io/crates/v/signature.svg)](https://crates.io/crates/signature) | [![Documentation](https://docs.rs/signature/badge.svg)](https://docs.rs/signature) | ![build](https://github.com/RustCrypto/traits/workflows/signature/badge.svg?branch=master&event=push) | -| [`stream‑cipher`] | [Stream cipher] | [![crates.io](https://img.shields.io/crates/v/stream-cipher.svg)](https://crates.io/crates/stream-cipher) | [![Documentation](https://docs.rs/stream-cipher/badge.svg)](https://docs.rs/stream-cipher) | ![build](https://github.com/RustCrypto/traits/workflows/stream-cipher/badge.svg?branch=master&event=push) | -| [`universal‑hash`] | [Universal hash function] | [![crates.io](https://img.shields.io/crates/v/universal-hash.svg)](https://crates.io/crates/universal-hash) | [![Documentation](https://docs.rs/universal-hash/badge.svg)](https://docs.rs/universal-hash) | ![build](https://github.com/RustCrypto/traits/workflows/universal-hash/badge.svg?branch=master&event=push) | +| Crate name | Algorithm | Crates.io | Docs | Build Status | +|---------------------|------------------------------------|-----------|-------|--------------| +| [`aead`] | [Authenticated encryption] | [![crates.io](https://img.shields.io/crates/v/aead.svg)](https://crates.io/crates/aead) | [![Documentation](https://docs.rs/aead/badge.svg)](https://docs.rs/aead) | ![build](https://github.com/RustCrypto/traits/workflows/aead/badge.svg?branch=master&event=push) | +| [`async-signature`] | [Digital signature] | [![crates.io](https://img.shields.io/crates/v/async-signature.svg)](https://crates.io/crates/async-signature) | [![Documentation](https://docs.rs/async-signature/badge.svg)](https://docs.rs/async-signature) | ![build](https://github.com/RustCrypto/traits/workflows/async-signature/badge.svg?branch=master&event=push) | +| [`cipher`] | [Block cipher] and [Stream cipher] | [![crates.io](https://img.shields.io/crates/v/cipher.svg)](https://crates.io/crates/cipher) | [![Documentation](https://docs.rs/cipher/badge.svg)](https://docs.rs/cipher) | ![build](https://github.com/RustCrypto/traits/workflows/cipher/badge.svg?branch=master&event=push) | +| [`crypto‑mac`] | [Message authentication code] | [![crates.io](https://img.shields.io/crates/v/crypto-mac.svg)](https://crates.io/crates/crypto-mac) | [![Documentation](https://docs.rs/crypto-mac/badge.svg)](https://docs.rs/crypto-mac) | ![build](https://github.com/RustCrypto/traits/workflows/crypto-mac/badge.svg?branch=master&event=push) | +| [`digest`] | [Cryptographic hash function] | [![crates.io](https://img.shields.io/crates/v/digest.svg)](https://crates.io/crates/digest) | [![Documentation](https://docs.rs/digest/badge.svg)](https://docs.rs/digest) | ![build](https://github.com/RustCrypto/traits/workflows/digest/badge.svg?branch=master&event=push) | +| [`elliptic-curve`] | [Elliptic curve cryptography] | [![crates.io](https://img.shields.io/crates/v/elliptic-curve.svg)](https://crates.io/crates/elliptic-curve) | [![Documentation](https://docs.rs/elliptic-curve/badge.svg)](https://docs.rs/elliptic-curve) | ![build](https://github.com/RustCrypto/traits/workflows/elliptic-curve/badge.svg?branch=master&event=push) | +| [`signature`] | [Digital signature] | [![crates.io](https://img.shields.io/crates/v/signature.svg)](https://crates.io/crates/signature) | [![Documentation](https://docs.rs/signature/badge.svg)](https://docs.rs/signature) | ![build](https://github.com/RustCrypto/traits/workflows/signature/badge.svg?branch=master&event=push) | +| [`universal‑hash`] | [Universal hash function] | [![crates.io](https://img.shields.io/crates/v/universal-hash.svg)](https://crates.io/crates/universal-hash) | [![Documentation](https://docs.rs/universal-hash/badge.svg)](https://docs.rs/universal-hash) | ![build](https://github.com/RustCrypto/traits/workflows/universal-hash/badge.svg?branch=master&event=push) | ### Additional crates @@ -54,13 +53,12 @@ dual licensed as above, without any additional terms or conditions. [`aead`]: https://github.com/RustCrypto/traits/tree/master/aead [`async-signature`]: https://github.com/RustCrypto/traits/tree/master/signature/async -[`block‑cipher`]: https://github.com/RustCrypto/traits/tree/master/block-cipher +[`cipher`]: https://github.com/RustCrypto/traits/tree/master/cipher [`crypto‑mac`]: https://github.com/RustCrypto/traits/tree/master/crypto-mac [`cryptography`]: https://github.com/RustCrypto/traits/tree/master/cryptography [`digest`]: https://github.com/RustCrypto/traits/tree/master/digest [`elliptic-curve`]: https://github.com/RustCrypto/traits/tree/master/elliptic-curve [`signature`]: https://github.com/RustCrypto/traits/tree/master/signature -[`stream‑cipher`]: https://github.com/RustCrypto/traits/tree/master/stream-cipher [`universal‑hash`]: https://github.com/RustCrypto/traits/tree/master/universal-hash [//]: # (algorithms) diff --git a/block-cipher/CHANGELOG.md b/block-cipher/CHANGELOG.md deleted file mode 100644 index 43ea0cedc..000000000 --- a/block-cipher/CHANGELOG.md +++ /dev/null @@ -1,58 +0,0 @@ -# Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## 0.8.0 (2020-07-10) -### Changed -- Add blanket implementation for `&mut SyncCtreamCipher` ([#210]) -- Update to `blobby v0.3` ([#210]) - -[#210]: https://github.com/RustCrypto/traits/pull/210 - -## 0.7.1 (2020-06-10) -### Added -- `BlockCipherMut` trait ([#179]) - -[#179]: https://github.com/RustCrypto/traits/issues/179 - -## 0.7.0 (2020-06-04) -### Changed -- Crate renamed from `block-cipher-trait` to `block-cipher` ([#139]) -- Split `BlockCipher` initialization into `NewBlockCipher` trait ([#132]) -- Update to Rust 2018 edition ([#107]) -- Bump `generic-array` dependency to v0.14 ([#95]) - -[#139]: https://github.com/RustCrypto/traits/issues/139 -[#132]: https://github.com/RustCrypto/traits/issues/132 -[#107]: https://github.com/RustCrypto/traits/issues/107 -[#95]: https://github.com/RustCrypto/traits/pull/95 - -## 0.6.2 (2018-11-14) - -## 0.6.1 (2018-10-04) - -## 0.6.0 (2018-10-02) - -## 0.5.3 (2018-07-27) - -## 0.5.2 (2018-06-21) - -## 0.5.1 (2018-06-20) - -## 0.5.0 (2017-11-26) - -## 0.4.2 (2017-09-05) - -## 0.4.1 (2017-09-05) - -## 0.4.0 (2017-09-05) - -## 0.3.0 (2016-12-24) - -## 0.2.0 (2016-12-16) - -## 0.1.0 (2016-12-16) - diff --git a/block-cipher/LICENSE-MIT b/block-cipher/LICENSE-MIT deleted file mode 100644 index 78d6d79a4..000000000 --- a/block-cipher/LICENSE-MIT +++ /dev/null @@ -1,25 +0,0 @@ -Copyright (c) 2016 Artyom Pavlov - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without -limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/block-cipher/README.md b/block-cipher/README.md deleted file mode 100644 index c8cffcd7a..000000000 --- a/block-cipher/README.md +++ /dev/null @@ -1,59 +0,0 @@ -# RustCrypto: Block Cipher Traits - -[![crate][crate-image]][crate-link] -[![Docs][docs-image]][docs-link] -![Apache2/MIT licensed][license-image] -![Rust Version][rustc-image] -[![Project Chat][chat-image]][chat-link] -[![Build Status][build-image]][build-link] - -Traits which define functionality of [block ciphers]. - -See [RustCrypto/block-ciphers] for implementations which use this trait. - -[Documentation][docs-link] - -## Minimum Supported Rust Version - -Rust **1.41** or higher. - -Minimum supported Rust version can be changed in the future, but it will be -done with a minor version bump. - -## SemVer Policy - -- All on-by-default features of this library are covered by SemVer -- MSRV is considered exempt from SemVer as noted above - -## License - -Licensed under either of: - - * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) - * [MIT license](http://opensource.org/licenses/MIT) - -at your option. - -### Contribution - -Unless you explicitly state otherwise, any contribution intentionally submitted -for inclusion in the work by you, as defined in the Apache-2.0 license, shall be -dual licensed as above, without any additional terms or conditions. - -[//]: # (badges) - -[crate-image]: https://img.shields.io/crates/v/block-cipher.svg -[crate-link]: https://crates.io/crates/block-cipher -[docs-image]: https://docs.rs/block-cipher/badge.svg -[docs-link]: https://docs.rs/block-cipher/ -[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg -[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg -[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260039-block-ciphers -[build-image]: https://github.com/RustCrypto/traits/workflows/block-cipher/badge.svg?branch=master&event=push -[build-link]: https://github.com/RustCrypto/traits/actions?query=workflow%3Ablock-cipher - -[//]: # (general links) - -[block ciphers]: https://en.wikipedia.org/wiki/Block_cipher -[RustCrypto/block-ciphers]: https://github.com/RustCrypto/block-ciphers diff --git a/cipher/CHANGELOG.md b/cipher/CHANGELOG.md new file mode 100644 index 000000000..ae0bce8fd --- /dev/null +++ b/cipher/CHANGELOG.md @@ -0,0 +1,11 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## 0.1.1 (2015-06-25) + +## 0.1.0 (2015-06-24) +- Initial release diff --git a/block-cipher/Cargo.toml b/cipher/Cargo.toml similarity index 65% rename from block-cipher/Cargo.toml rename to cipher/Cargo.toml index cd3cc79a2..ec715bdda 100644 --- a/block-cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -1,14 +1,14 @@ [package] -name = "block-cipher" -description = "Traits for description of block ciphers" -version = "0.8.0" +name = "cipher" +description = "Traits for describing block ciphers and stream ciphers" +version = "0.2.0-pre" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" edition = "2018" -documentation = "https://docs.rs/block-cipher" +documentation = "https://docs.rs/cipher" repository = "https://github.com/RustCrypto/traits" -keywords = ["crypto", "block-cipher", "trait"] +keywords = ["crypto", "block-cipher", "stream-cipher", "trait"] categories = ["cryptography", "no-std"] [dependencies] diff --git a/block-cipher/LICENSE-APACHE b/cipher/LICENSE-APACHE similarity index 100% rename from block-cipher/LICENSE-APACHE rename to cipher/LICENSE-APACHE diff --git a/stream-cipher/LICENSE-MIT b/cipher/LICENSE-MIT similarity index 95% rename from stream-cipher/LICENSE-MIT rename to cipher/LICENSE-MIT index f5b157a6c..f3a832c3b 100644 --- a/stream-cipher/LICENSE-MIT +++ b/cipher/LICENSE-MIT @@ -1,4 +1,4 @@ -Copyright (c) 2018 Artyom Pavlov +Copyright (c) 2016-2020 RustCrypto Developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated diff --git a/stream-cipher/README.md b/cipher/README.md similarity index 69% rename from stream-cipher/README.md rename to cipher/README.md index 06866ecaa..d88f04339 100644 --- a/stream-cipher/README.md +++ b/cipher/README.md @@ -1,4 +1,4 @@ -# RustCrypto: Stream Cipher Traits +# RustCrypto: Cipher Traits [![crate][crate-image]][crate-link] [![Docs][docs-image]][docs-link] @@ -7,9 +7,10 @@ [![Project Chat][chat-image]][chat-link] [![Build Status][build-image]][build-link] -Traits which define functionality of [stream ciphers]. +Traits which define the functionality of [block ciphers] and [stream ciphers]. -See [RustCrypto/stream-ciphers] for implementations which use this trait. +See [RustCrypto/block-ciphers] and [RustCrypto/stream-ciphers] for algorithm +implementations which use this trait. [Documentation][docs-link] @@ -42,18 +43,20 @@ dual licensed as above, without any additional terms or conditions. [//]: # (badges) -[crate-image]: https://img.shields.io/crates/v/stream-cipher.svg -[crate-link]: https://crates.io/crates/stream-cipher -[docs-image]: https://docs.rs/stream-cipher/badge.svg -[docs-link]: https://docs.rs/stream-cipher/ +[crate-image]: https://img.shields.io/crates/v/cipher.svg +[crate-link]: https://crates.io/crates/cipher +[docs-image]: https://docs.rs/cipher/badge.svg +[docs-link]: https://docs.rs/cipher/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg [rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg -[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260049-stream-ciphers -[build-image]: https://github.com/RustCrypto/traits/workflows/stream-cipher/badge.svg?branch=master&event=push -[build-link]: https://github.com/RustCrypto/traits/actions?query=workflow%3Astream-cipher +[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260050-traits +[build-image]: https://github.com/RustCrypto/traits/workflows/cipher/badge.svg?branch=master&event=push +[build-link]: https://github.com/RustCrypto/traits/actions?query=workflow:cipher [//]: # (general links) +[block ciphers]: https://en.wikipedia.org/wiki/Block_cipher [stream ciphers]: https://en.wikipedia.org/wiki/Stream_cipher +[RustCrypto/block-ciphers]: https://github.com/RustCrypto/block-ciphers [RustCrypto/stream-ciphers]: https://github.com/RustCrypto/stream-ciphers diff --git a/block-cipher/src/lib.rs b/cipher/src/block.rs similarity index 88% rename from block-cipher/src/lib.rs rename to cipher/src/block.rs index 69e16696c..8cf1fb1e4 100644 --- a/block-cipher/src/lib.rs +++ b/cipher/src/block.rs @@ -1,5 +1,4 @@ -//! This crate defines a set of simple traits used to define functionality of -//! [block ciphers][1]. +//! Traits used to define functionality of [block ciphers][1]. //! //! # About block ciphers //! @@ -10,29 +9,16 @@ //! [1]: https://en.wikipedia.org/wiki/Block_cipher //! [2]: https://en.wikipedia.org/wiki/Symmetric-key_algorithm -#![no_std] -#![cfg_attr(docsrs, feature(doc_cfg))] -#![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" -)] -#![forbid(unsafe_code)] -#![warn(missing_docs, rust_2018_idioms)] - -#[cfg(feature = "std")] -extern crate std; - #[cfg(feature = "dev")] #[cfg_attr(docsrs, doc(cfg(feature = "dev")))] pub mod dev; mod errors; -pub use crate::errors::InvalidKeyLength; +pub use errors::InvalidKeyLength; pub use generic_array::{self, typenum::consts}; -use generic_array::typenum::Unsigned; -use generic_array::{ArrayLength, GenericArray}; +use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; /// Key for an algorithm that implements [`NewBlockCipher`]. pub type Key = GenericArray::KeySize>; diff --git a/block-cipher/src/dev.rs b/cipher/src/block/dev.rs similarity index 100% rename from block-cipher/src/dev.rs rename to cipher/src/block/dev.rs diff --git a/block-cipher/src/errors.rs b/cipher/src/block/errors.rs similarity index 100% rename from block-cipher/src/errors.rs rename to cipher/src/block/errors.rs diff --git a/cipher/src/lib.rs b/cipher/src/lib.rs new file mode 100644 index 000000000..771ac533e --- /dev/null +++ b/cipher/src/lib.rs @@ -0,0 +1,25 @@ +//! This crate defines a set of simple traits used to define functionality of +//! [block ciphers][1] and [stream ciphers][2]. +//! +//! [1]: https://en.wikipedia.org/wiki/Block_cipher +//! [2]: https://en.wikipedia.org/wiki/Stream_cipher + +#![no_std] +#![cfg_attr(docsrs, feature(doc_cfg))] +#![doc( + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" +)] +#![forbid(unsafe_code)] +#![warn(missing_docs, rust_2018_idioms)] + +#[cfg(feature = "std")] +extern crate std; + +pub mod block; +pub mod stream; + +pub use crate::{ + block::{BlockCipher, BlockCipherMut, NewBlockCipher}, + stream::{NewStreamCipher, StreamCipher, SyncStreamCipher, SyncStreamCipherSeek}, +}; diff --git a/stream-cipher/src/lib.rs b/cipher/src/stream.rs similarity index 91% rename from stream-cipher/src/lib.rs rename to cipher/src/stream.rs index 0471d57fc..aba220b53 100644 --- a/stream-cipher/src/lib.rs +++ b/cipher/src/stream.rs @@ -1,21 +1,8 @@ -//! This crate defines a set of traits which define functionality of -//! stream ciphers. +//! Traits which define functionality of stream ciphers. //! //! See [RustCrypto/stream-ciphers](https://github.com/RustCrypto/stream-ciphers) //! for ciphers implementation. -#![no_std] -#![cfg_attr(docsrs, feature(doc_cfg))] -#![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" -)] -#![forbid(unsafe_code)] -#![warn(missing_docs, rust_2018_idioms)] - -#[cfg(feature = "std")] -extern crate std; - #[cfg(feature = "dev")] mod dev; @@ -24,19 +11,14 @@ mod errors; pub use errors::{InvalidKeyNonceLength, LoopError, OverflowError}; pub use generic_array::{self, typenum::consts}; -#[cfg(feature = "block-cipher")] -pub use block_cipher; - #[cfg(feature = "dev")] pub use blobby; +use crate::block::{BlockCipher, BlockCipherMut, NewBlockCipher}; use core::convert::{TryFrom, TryInto}; use generic_array::typenum::Unsigned; use generic_array::{ArrayLength, GenericArray}; -#[cfg(feature = "block-cipher")] -use block_cipher::{BlockCipher, BlockCipherMut, NewBlockCipher}; - /// Key for an algorithm that implements [`NewStreamCipher`]. pub type Key = GenericArray::KeySize>; @@ -169,8 +151,6 @@ impl SyncStreamCipher for &mut C { } /// Trait for initializing a stream cipher from a block cipher -#[cfg(feature = "block-cipher")] -#[cfg_attr(docsrs, doc(cfg(feature = "block-cipher")))] pub trait FromBlockCipher { /// Block cipher type BlockCipher: BlockCipher; @@ -185,8 +165,6 @@ pub trait FromBlockCipher { } /// Trait for initializing a stream cipher from a mutable block cipher -#[cfg(feature = "block-cipher")] -#[cfg_attr(docsrs, doc(cfg(feature = "block-cipher")))] pub trait FromBlockCipherMut { /// Block cipher type BlockCipher: BlockCipherMut; @@ -200,7 +178,6 @@ pub trait FromBlockCipherMut { ) -> Self; } -#[cfg(feature = "block-cipher")] impl FromBlockCipherMut for C where C: FromBlockCipher, @@ -216,7 +193,6 @@ where } } -#[cfg(feature = "block-cipher")] impl NewStreamCipher for C where C: FromBlockCipherMut, diff --git a/stream-cipher/src/dev.rs b/cipher/src/stream/dev.rs similarity index 100% rename from stream-cipher/src/dev.rs rename to cipher/src/stream/dev.rs diff --git a/stream-cipher/src/errors.rs b/cipher/src/stream/errors.rs similarity index 100% rename from stream-cipher/src/errors.rs rename to cipher/src/stream/errors.rs diff --git a/crypto-mac/Cargo.toml b/crypto-mac/Cargo.toml index b1013c0ad..956a4c4d0 100644 --- a/crypto-mac/Cargo.toml +++ b/crypto-mac/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crypto-mac" description = "Trait for Message Authentication Code (MAC) algorithms" -version = "0.9.1" +version = "0.10.0-pre" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" @@ -13,7 +13,7 @@ categories = ["cryptography", "no-std"] [dependencies] generic-array = "0.14" -block-cipher = { version = "0.8", optional = true } +cipher = { version = "=0.2.0-pre", optional = true, path = "../cipher" } subtle = { version = "2", default-features = false } blobby = { version = "0.3", optional = true } diff --git a/crypto-mac/src/lib.rs b/crypto-mac/src/lib.rs index b4174fbab..51e26bc09 100644 --- a/crypto-mac/src/lib.rs +++ b/crypto-mac/src/lib.rs @@ -12,10 +12,10 @@ #[cfg(feature = "std")] extern crate std; -#[cfg(feature = "block-cipher")] -pub use block_cipher; -#[cfg(feature = "block-cipher")] -use block_cipher::{BlockCipher, NewBlockCipher}; +#[cfg(feature = "cipher")] +pub use cipher; +#[cfg(feature = "cipher")] +use cipher::{BlockCipher, NewBlockCipher}; #[cfg(feature = "dev")] #[cfg_attr(docsrs, doc(cfg(feature = "dev")))] @@ -126,8 +126,8 @@ impl PartialEq for Output { impl Eq for Output {} -#[cfg(feature = "block-cipher")] -#[cfg_attr(docsrs, doc(cfg(feature = "block-cipher")))] +#[cfg(feature = "cipher")] +#[cfg_attr(docsrs, doc(cfg(feature = "cipher")))] /// Trait for MAC functions which can be created from block cipher. pub trait FromBlockCipher { /// Block cipher type @@ -137,8 +137,8 @@ pub trait FromBlockCipher { fn from_cipher(cipher: Self::Cipher) -> Self; } -#[cfg(feature = "block-cipher")] -#[cfg_attr(docsrs, doc(cfg(feature = "block-cipher")))] +#[cfg(feature = "cipher")] +#[cfg_attr(docsrs, doc(cfg(feature = "cipher")))] impl NewMac for T where T: FromBlockCipher, diff --git a/cryptography/Cargo.toml b/cryptography/Cargo.toml index 11c0ef8db..3db9bfc98 100644 --- a/cryptography/Cargo.toml +++ b/cryptography/Cargo.toml @@ -13,23 +13,21 @@ edition = "2018" [dependencies] aead = { version = "0.3", optional = true, path = "../aead" } -block-cipher = { version = "0.8", optional = true, path = "../block-cipher" } +cipher = { version = "=0.2.0-pre", optional = true, path = "../cipher" } digest = { version = "0.9", optional = true, path = "../digest" } elliptic-curve = { version = "0.6", optional = true, path = "../elliptic-curve" } -mac = { version = "0.9", package = "crypto-mac", optional = true, path = "../crypto-mac" } +mac = { version = "=0.10.0-pre", package = "crypto-mac", optional = true, path = "../crypto-mac" } signature = { version = "1.2.0", optional = true, default-features = false, path = "../signature" } -stream-cipher = { version = "0.8.0-pre", optional = true, path = "../stream-cipher" } universal-hash = { version = "0.4", optional = true, path = "../universal-hash" } [features] std = [ "aead/std", - "block-cipher/std", + "cipher/std", "digest/std", "elliptic-curve/std", "mac/std", "signature/std", - "stream-cipher/std", "universal-hash/std" ] diff --git a/cryptography/src/lib.rs b/cryptography/src/lib.rs index ad17177f8..9c14669a7 100644 --- a/cryptography/src/lib.rs +++ b/cryptography/src/lib.rs @@ -24,12 +24,11 @@ //! | Re-export | Cargo feature | Description | //! |-----------|---------------|-------------| //! | [`aead`](https://docs.rs/aead) | `aead` | Authenticated Encryption with Associated Data (i.e. high-level symmetric encryption) | -//! | [`block_cipher`](https://docs.rs/block-cipher) | `block‑cipher` | Block-based cryptographic permutations (i.e. low-level symmetric encryption) | +//! | [`cipher`](https://docs.rs/cipher) | `cipher` | Block and stream ciphers (i.e. low-level symmetric encryption) | //! | [`digest`](https://docs.rs/digest) | `digest` | Cryptographic hash functions | //! | [`elliptic_curve`](https://docs.rs/elliptic-curve) | `elliptic-curve` | Elliptic curve cryptography | //! | [`mac`](https://docs.rs/crypto-mac) | `mac` | Message Authentication Codes (i.e. symmetric message authentication) | //! | [`signature`](https://docs.rs/signature) | `signature` | Digital signatures (i.e. public key-based message authentication) | -//! | [`stream_cipher`](https://docs.rs/stream-cipher) | `stream‑cipher` | Ciphers based on randomly generated keystreams (i.e. low-level symmetric encryption) | //! | [`universal_hash`](https://docs.rs/universal-hash) | `universal‑hash` | Universal Hash Functions (used to build MACs) | //! //! [1]: https://github.com/RustCrypto/traits @@ -46,8 +45,8 @@ #[cfg(feature = "aead")] pub use aead; -#[cfg(feature = "block-cipher")] -pub use block_cipher; +#[cfg(feature = "cipher")] +pub use cipher; #[cfg(feature = "digest")] pub use digest; @@ -61,8 +60,5 @@ pub use mac; #[cfg(feature = "signature")] pub use signature; -#[cfg(feature = "stream-cipher")] -pub use stream_cipher; - #[cfg(feature = "universal-hash")] pub use universal_hash; diff --git a/stream-cipher/CHANGELOG.md b/stream-cipher/CHANGELOG.md deleted file mode 100644 index cadf15cb6..000000000 --- a/stream-cipher/CHANGELOG.md +++ /dev/null @@ -1,78 +0,0 @@ -# Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## 0.8.0-pre (2020-10-14) -### Added -- `FromBlockCipherMut` trait ([#334]) - -### Removed -- `NewBlockCipher` bound on `FromBlockCipher` ([#333]) - -[#334]: https://github.com/RustCrypto/traits/pull/334 -[#333]: https://github.com/RustCrypto/traits/pull/333 - -## 0.7.1 (2020-08-25) -### Fixed -- Computation of `SeekNum::to_block_byte` for numbers which are not a power of 2 ([#268]) - -[#268]: https://github.com/RustCrypto/traits/pull/268 - -## 0.7.0 (2020-08-25) -### Changed -- Rework of the `SyncStreamCipherSeek` trait, make methods generic over -numeric types, add fallable `try_seek` and `try_current_pos` methods ([#260]) -- Rework macro for generating seek tests, re-export `blobby` at top-level, -remove the `dev` module from public API ([#260]) - -[#260]: https://github.com/RustCrypto/traits/pull/260 - -## 0.6.0 (2020-07-10) -### Changed -- Add blanket implementation for `&mut SyncCtreamCipher` ([#210]) -- Update to `blobby v0.3` ([#210]) - -[#210]: https://github.com/RustCrypto/traits/pull/210 - -## 0.5.0 (2020-07-03) -### Changed -- Add `NonceSize` associated type to the `FromBlockCipher` trait ([#209]) - -[#209]: https://github.com/RustCrypto/traits/pull/209 - -## 0.4.1 (2020-06-10) -### Added -- `Key` and `Nonce` type aliases ([#188]) - -[#188]: https://github.com/RustCrypto/traits/issues/188 - -## 0.4.0 (2020-06-04) -### Added -- `FromBlockCipher` trait ([#164]) - -### Changed -- Update to 2018 edition ([#110]) -- Bump `generic-array` dependency to v0.14 ([#95]) - -[#164]: https://github.com/RustCrypto/traits/issues/164 -[#110]: https://github.com/RustCrypto/traits/issues/110 -[#95]: https://github.com/RustCrypto/traits/pull/95 - -## 0.3.2 (2019-08-18) - -## 0.3.1 (2019-08-17) - -## 0.3.0 (2018-11-01) - -## 0.2.2 (2018-10-16) - -## 0.2.1 (2018-10-04) - -## 0.2.0 (2018-10-03) - -## 0.1.1 (2018-08-08) - -## 0.1.0 (2018-07-27) diff --git a/stream-cipher/Cargo.toml b/stream-cipher/Cargo.toml deleted file mode 100644 index 495951f8c..000000000 --- a/stream-cipher/Cargo.toml +++ /dev/null @@ -1,30 +0,0 @@ -[package] -name = "stream-cipher" -description = "Stream cipher traits" -version = "0.8.0-pre" -authors = ["RustCrypto Developers"] -license = "MIT OR Apache-2.0" -readme = "README.md" -edition = "2018" -documentation = "https://docs.rs/stream-cipher" -repository = "https://github.com/RustCrypto/traits" -keywords = ["crypto", "stream-cipher", "trait"] -categories = ["cryptography", "no-std"] - -[dependencies] -generic-array = "0.14" -blobby = { version = "0.3", optional = true } - -[dependencies.block-cipher] -version = "0.8" -optional = true -path = "../block-cipher" - -[features] -default = ["block-cipher"] -std = [] -dev = ["blobby"] - -[package.metadata.docs.rs] -all-features = true -rustdoc-args = ["--cfg", "docsrs"] diff --git a/stream-cipher/LICENSE-APACHE b/stream-cipher/LICENSE-APACHE deleted file mode 100644 index 78173fa2e..000000000 --- a/stream-cipher/LICENSE-APACHE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - -Copyright [yyyy] [name of copyright owner] - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. From 9a55abca257698a0ad3668dce8e1aa40139e5771 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 15 Oct 2020 12:07:46 -0700 Subject: [PATCH 0266/1461] cipher v0.2.0 (#338) --- Cargo.lock | 2 +- cipher/CHANGELOG.md | 6 ++++++ cipher/Cargo.toml | 2 +- crypto-mac/Cargo.toml | 2 +- cryptography/Cargo.toml | 2 +- 5 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 28fa22dca..11f26684f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -85,7 +85,7 @@ checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" [[package]] name = "cipher" -version = "0.2.0-pre" +version = "0.2.0" dependencies = [ "blobby 0.3.0", "generic-array 0.14.4", diff --git a/cipher/CHANGELOG.md b/cipher/CHANGELOG.md index ae0bce8fd..cfc238736 100644 --- a/cipher/CHANGELOG.md +++ b/cipher/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.2.0 (2020-10-15) +### Changed +- Unify `block-cipher` and `stream-cipher` into `cipher` ([#337]) + +[#337]: https://github.com/RustCrypto/traits/pull/337 + ## 0.1.1 (2015-06-25) ## 0.1.0 (2015-06-24) diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index ec715bdda..88e4d7b9c 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "cipher" description = "Traits for describing block ciphers and stream ciphers" -version = "0.2.0-pre" +version = "0.2.0" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/crypto-mac/Cargo.toml b/crypto-mac/Cargo.toml index 956a4c4d0..86ff4a885 100644 --- a/crypto-mac/Cargo.toml +++ b/crypto-mac/Cargo.toml @@ -13,7 +13,7 @@ categories = ["cryptography", "no-std"] [dependencies] generic-array = "0.14" -cipher = { version = "=0.2.0-pre", optional = true, path = "../cipher" } +cipher = { version = "0.2", optional = true, path = "../cipher" } subtle = { version = "2", default-features = false } blobby = { version = "0.3", optional = true } diff --git a/cryptography/Cargo.toml b/cryptography/Cargo.toml index 3db9bfc98..a9115bcae 100644 --- a/cryptography/Cargo.toml +++ b/cryptography/Cargo.toml @@ -13,7 +13,7 @@ edition = "2018" [dependencies] aead = { version = "0.3", optional = true, path = "../aead" } -cipher = { version = "=0.2.0-pre", optional = true, path = "../cipher" } +cipher = { version = "0.2", optional = true, path = "../cipher" } digest = { version = "0.9", optional = true, path = "../digest" } elliptic-curve = { version = "0.6", optional = true, path = "../elliptic-curve" } mac = { version = "=0.10.0-pre", package = "crypto-mac", optional = true, path = "../crypto-mac" } From ca0ea3064459418a7a8f9945a5eda178982ad260 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 15 Oct 2020 13:01:18 -0700 Subject: [PATCH 0267/1461] crypto-mac v0.10.0 (#339) --- Cargo.lock | 2 +- crypto-mac/CHANGELOG.md | 7 +++++++ crypto-mac/Cargo.toml | 2 +- cryptography/Cargo.toml | 2 +- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 11f26684f..3ba153791 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -105,7 +105,7 @@ checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634" [[package]] name = "crypto-mac" -version = "0.10.0-pre" +version = "0.10.0" dependencies = [ "blobby 0.3.0", "cipher", diff --git a/crypto-mac/CHANGELOG.md b/crypto-mac/CHANGELOG.md index 0ed42e3dd..9d4f0b24c 100644 --- a/crypto-mac/CHANGELOG.md +++ b/crypto-mac/CHANGELOG.md @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.10.0 (2020-10-15) +### Changed +- Replace `block-cipher` crate with new `cipher` crate ([#337], [#338]) + +[#338]: https://github.com/RustCrypto/traits/pull/338 +[#337]: https://github.com/RustCrypto/traits/pull/337 + ## 0.9.1 (2020-08-12) ### Added - Re-export the `block-cipher` crate ([#257]) diff --git a/crypto-mac/Cargo.toml b/crypto-mac/Cargo.toml index 86ff4a885..c2a7121d8 100644 --- a/crypto-mac/Cargo.toml +++ b/crypto-mac/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crypto-mac" description = "Trait for Message Authentication Code (MAC) algorithms" -version = "0.10.0-pre" +version = "0.10.0" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/cryptography/Cargo.toml b/cryptography/Cargo.toml index a9115bcae..557dd8661 100644 --- a/cryptography/Cargo.toml +++ b/cryptography/Cargo.toml @@ -16,7 +16,7 @@ aead = { version = "0.3", optional = true, path = "../aead" } cipher = { version = "0.2", optional = true, path = "../cipher" } digest = { version = "0.9", optional = true, path = "../digest" } elliptic-curve = { version = "0.6", optional = true, path = "../elliptic-curve" } -mac = { version = "=0.10.0-pre", package = "crypto-mac", optional = true, path = "../crypto-mac" } +mac = { version = "0.10", package = "crypto-mac", optional = true, path = "../crypto-mac" } signature = { version = "1.2.0", optional = true, default-features = false, path = "../signature" } universal-hash = { version = "0.4", optional = true, path = "../universal-hash" } From 45aba1d9b2453684bf1eddd644ba8bbcba42c7a1 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 15 Oct 2020 13:12:09 -0700 Subject: [PATCH 0268/1461] cryptography v0.5.0 (#340) --- cryptography/CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/cryptography/CHANGELOG.md b/cryptography/CHANGELOG.md index 51dce1f2c..e4b0f40c3 100644 --- a/cryptography/CHANGELOG.md +++ b/cryptography/CHANGELOG.md @@ -5,6 +5,15 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.5.0 (2020-10-15) +### Changed +- Bump `crypto-mac` to v0.10 ([#339]) +- Unify `block-cipher`/`stream-cipher` into `cipher` ([#337], [#338]) + +[#339]: https://github.com/RustCrypto/traits/pull/339 +[#338]: https://github.com/RustCrypto/traits/pull/338 +[#337]: https://github.com/RustCrypto/traits/pull/337 + ## 0.4.1 (2020-09-29) ### Added - `std` feature ([#317]) From f3d7fe613313e8d8caa00c9d9db11fc0e75f3ce8 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 15 Oct 2020 13:22:33 -0700 Subject: [PATCH 0269/1461] README.md: reformat crate table (#341) --- README.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 27511562d..9d54331f7 100644 --- a/README.md +++ b/README.md @@ -4,16 +4,16 @@ Collection of traits which describe functionality of cryptographic primitives. ## Crates -| Crate name | Algorithm | Crates.io | Docs | Build Status | -|---------------------|------------------------------------|-----------|-------|--------------| -| [`aead`] | [Authenticated encryption] | [![crates.io](https://img.shields.io/crates/v/aead.svg)](https://crates.io/crates/aead) | [![Documentation](https://docs.rs/aead/badge.svg)](https://docs.rs/aead) | ![build](https://github.com/RustCrypto/traits/workflows/aead/badge.svg?branch=master&event=push) | -| [`async-signature`] | [Digital signature] | [![crates.io](https://img.shields.io/crates/v/async-signature.svg)](https://crates.io/crates/async-signature) | [![Documentation](https://docs.rs/async-signature/badge.svg)](https://docs.rs/async-signature) | ![build](https://github.com/RustCrypto/traits/workflows/async-signature/badge.svg?branch=master&event=push) | -| [`cipher`] | [Block cipher] and [Stream cipher] | [![crates.io](https://img.shields.io/crates/v/cipher.svg)](https://crates.io/crates/cipher) | [![Documentation](https://docs.rs/cipher/badge.svg)](https://docs.rs/cipher) | ![build](https://github.com/RustCrypto/traits/workflows/cipher/badge.svg?branch=master&event=push) | -| [`crypto‑mac`] | [Message authentication code] | [![crates.io](https://img.shields.io/crates/v/crypto-mac.svg)](https://crates.io/crates/crypto-mac) | [![Documentation](https://docs.rs/crypto-mac/badge.svg)](https://docs.rs/crypto-mac) | ![build](https://github.com/RustCrypto/traits/workflows/crypto-mac/badge.svg?branch=master&event=push) | -| [`digest`] | [Cryptographic hash function] | [![crates.io](https://img.shields.io/crates/v/digest.svg)](https://crates.io/crates/digest) | [![Documentation](https://docs.rs/digest/badge.svg)](https://docs.rs/digest) | ![build](https://github.com/RustCrypto/traits/workflows/digest/badge.svg?branch=master&event=push) | -| [`elliptic-curve`] | [Elliptic curve cryptography] | [![crates.io](https://img.shields.io/crates/v/elliptic-curve.svg)](https://crates.io/crates/elliptic-curve) | [![Documentation](https://docs.rs/elliptic-curve/badge.svg)](https://docs.rs/elliptic-curve) | ![build](https://github.com/RustCrypto/traits/workflows/elliptic-curve/badge.svg?branch=master&event=push) | -| [`signature`] | [Digital signature] | [![crates.io](https://img.shields.io/crates/v/signature.svg)](https://crates.io/crates/signature) | [![Documentation](https://docs.rs/signature/badge.svg)](https://docs.rs/signature) | ![build](https://github.com/RustCrypto/traits/workflows/signature/badge.svg?branch=master&event=push) | -| [`universal‑hash`] | [Universal hash function] | [![crates.io](https://img.shields.io/crates/v/universal-hash.svg)](https://crates.io/crates/universal-hash) | [![Documentation](https://docs.rs/universal-hash/badge.svg)](https://docs.rs/universal-hash) | ![build](https://github.com/RustCrypto/traits/workflows/universal-hash/badge.svg?branch=master&event=push) | +| Crate name | Algorithm | Crates.io | Docs | Build Status | +|---------------------|-------------------------------|-----------|-------|--------------| +| [`aead`] | [Authenticated encryption] | [![crates.io](https://img.shields.io/crates/v/aead.svg)](https://crates.io/crates/aead) | [![Documentation](https://docs.rs/aead/badge.svg)](https://docs.rs/aead) | ![build](https://github.com/RustCrypto/traits/workflows/aead/badge.svg?branch=master&event=push) | +| [`async-signature`] | [Digital signature] | [![crates.io](https://img.shields.io/crates/v/async-signature.svg)](https://crates.io/crates/async-signature) | [![Documentation](https://docs.rs/async-signature/badge.svg)](https://docs.rs/async-signature) | ![build](https://github.com/RustCrypto/traits/workflows/async-signature/badge.svg?branch=master&event=push) | +| [`cipher`] | [Block] and [stream cipher] | [![crates.io](https://img.shields.io/crates/v/cipher.svg)](https://crates.io/crates/cipher) | [![Documentation](https://docs.rs/cipher/badge.svg)](https://docs.rs/cipher) | ![build](https://github.com/RustCrypto/traits/workflows/cipher/badge.svg?branch=master&event=push) | +| [`crypto‑mac`] | [Message authentication code] | [![crates.io](https://img.shields.io/crates/v/crypto-mac.svg)](https://crates.io/crates/crypto-mac) | [![Documentation](https://docs.rs/crypto-mac/badge.svg)](https://docs.rs/crypto-mac) | ![build](https://github.com/RustCrypto/traits/workflows/crypto-mac/badge.svg?branch=master&event=push) | +| [`digest`] | [Cryptographic hash function] | [![crates.io](https://img.shields.io/crates/v/digest.svg)](https://crates.io/crates/digest) | [![Documentation](https://docs.rs/digest/badge.svg)](https://docs.rs/digest) | ![build](https://github.com/RustCrypto/traits/workflows/digest/badge.svg?branch=master&event=push) | +| [`elliptic-curve`] | [Elliptic curve cryptography] | [![crates.io](https://img.shields.io/crates/v/elliptic-curve.svg)](https://crates.io/crates/elliptic-curve) | [![Documentation](https://docs.rs/elliptic-curve/badge.svg)](https://docs.rs/elliptic-curve) | ![build](https://github.com/RustCrypto/traits/workflows/elliptic-curve/badge.svg?branch=master&event=push) | +| [`signature`] | [Digital signature] | [![crates.io](https://img.shields.io/crates/v/signature.svg)](https://crates.io/crates/signature) | [![Documentation](https://docs.rs/signature/badge.svg)](https://docs.rs/signature) | ![build](https://github.com/RustCrypto/traits/workflows/signature/badge.svg?branch=master&event=push) | +| [`universal‑hash`] | [Universal hash function] | [![crates.io](https://img.shields.io/crates/v/universal-hash.svg)](https://crates.io/crates/universal-hash) | [![Documentation](https://docs.rs/universal-hash/badge.svg)](https://docs.rs/universal-hash) | ![build](https://github.com/RustCrypto/traits/workflows/universal-hash/badge.svg?branch=master&event=push) | ### Additional crates @@ -64,7 +64,7 @@ dual licensed as above, without any additional terms or conditions. [//]: # (algorithms) [Authenticated encryption]: https://en.wikipedia.org/wiki/Authenticated_encryption -[Block cipher]: https://en.wikipedia.org/wiki/Block_cipher +[Block]: https://en.wikipedia.org/wiki/Block_cipher [Message authentication code]: https://en.wikipedia.org/wiki/Message_authentication_code [Cryptographic hash function]: https://en.wikipedia.org/wiki/Cryptographic_hash_function [Digital signature]: https://en.wikipedia.org/wiki/Digital_signature From 676c267579cc32adbdd120ab86f28b640e98bba2 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 15 Oct 2020 13:24:54 -0700 Subject: [PATCH 0270/1461] cryptography: fix version --- Cargo.lock | 2 +- cryptography/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3ba153791..0d1000fb9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -115,7 +115,7 @@ dependencies = [ [[package]] name = "cryptography" -version = "0.5.0-pre" +version = "0.5.0" dependencies = [ "aead", "cipher", diff --git a/cryptography/Cargo.toml b/cryptography/Cargo.toml index 557dd8661..9f9fba591 100644 --- a/cryptography/Cargo.toml +++ b/cryptography/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cryptography" -version = "0.5.0-pre" +version = "0.5.0" authors = ["The RustCrypto Project Developers"] license = "Apache-2.0 OR MIT" description = "Facade crate for the RustCrypto project's traits" From 7410ecdbb6126014357e0b87a40daaf3d7bf2828 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 16 Oct 2020 05:55:14 -0700 Subject: [PATCH 0271/1461] cipher: re-export `generic_array` from toplevel (#343) ...along with `typenum::consts` Failure to do this was an oversight: it doesn't really make sense to re-export these twice from both the `block` and `stream` modules. That said, `cipher` v0.2 is already shipped, and it does ease a sed-based migration to keep these re-exports for now. This commit adds a third re-export from the toplevel, and comments to remove the re-exports from the `block` and `stream` crates. This should happen before `cipher` v0.3 is released. --- cipher/src/block.rs | 2 ++ cipher/src/lib.rs | 1 + cipher/src/stream.rs | 2 ++ 3 files changed, 5 insertions(+) diff --git a/cipher/src/block.rs b/cipher/src/block.rs index 8cf1fb1e4..7289561fd 100644 --- a/cipher/src/block.rs +++ b/cipher/src/block.rs @@ -16,6 +16,8 @@ pub mod dev; mod errors; pub use errors::InvalidKeyLength; + +// TODO(tarcieri): remove these re-exports in favor of the toplevel one pub use generic_array::{self, typenum::consts}; use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; diff --git a/cipher/src/lib.rs b/cipher/src/lib.rs index 771ac533e..036707e71 100644 --- a/cipher/src/lib.rs +++ b/cipher/src/lib.rs @@ -23,3 +23,4 @@ pub use crate::{ block::{BlockCipher, BlockCipherMut, NewBlockCipher}, stream::{NewStreamCipher, StreamCipher, SyncStreamCipher, SyncStreamCipherSeek}, }; +pub use generic_array::{self, typenum::consts}; diff --git a/cipher/src/stream.rs b/cipher/src/stream.rs index aba220b53..ebc022c5c 100644 --- a/cipher/src/stream.rs +++ b/cipher/src/stream.rs @@ -9,6 +9,8 @@ mod dev; mod errors; pub use errors::{InvalidKeyNonceLength, LoopError, OverflowError}; + +// TODO(tarcieri): remove these re-exports in favor of the toplevel one pub use generic_array::{self, typenum::consts}; #[cfg(feature = "dev")] From 742e555bad4198fd30b987d6a85f160e0c85bceb Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 16 Oct 2020 06:23:56 -0700 Subject: [PATCH 0272/1461] cipher: fix dev macro imports (#345) They were previously referring to the old `block_cipher` and `stream_cipher` names. --- cipher/src/block/dev.rs | 8 +++----- cipher/src/stream/dev.rs | 22 ++++++++++------------ 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/cipher/src/block/dev.rs b/cipher/src/block/dev.rs index 11c570c1a..4ab57d706 100644 --- a/cipher/src/block/dev.rs +++ b/cipher/src/block/dev.rs @@ -9,10 +9,8 @@ macro_rules! new_test { ($name:ident, $test_name:expr, $cipher:ty) => { #[test] fn $name() { - use block_cipher::dev::blobby::Blob3Iterator; - use block_cipher::generic_array::typenum::Unsigned; - use block_cipher::generic_array::GenericArray; - use block_cipher::{BlockCipher, NewBlockCipher}; + use cipher::block::{dev::blobby::Blob3Iterator, BlockCipher, NewBlockCipher}; + use cipher::generic_array::{typenum::Unsigned, GenericArray}; fn run_test(key: &[u8], pt: &[u8], ct: &[u8]) -> bool { let state = <$cipher as NewBlockCipher>::new_varkey(key).unwrap(); @@ -113,7 +111,7 @@ macro_rules! bench { ($cipher:path, $key_len:expr) => { extern crate test; - use block_cipher::{BlockCipher, NewBlockCipher}; + use cipher::block::{BlockCipher, NewBlockCipher}; use test::Bencher; #[bench] diff --git a/cipher/src/stream/dev.rs b/cipher/src/stream/dev.rs index d5b877f0d..b538e57c1 100644 --- a/cipher/src/stream/dev.rs +++ b/cipher/src/stream/dev.rs @@ -7,9 +7,8 @@ macro_rules! new_sync_test { ($name:ident, $cipher:ty, $test_name:expr) => { #[test] fn $name() { - use stream_cipher::blobby::Blob4Iterator; - use stream_cipher::generic_array::GenericArray; - use stream_cipher::{NewStreamCipher, SyncStreamCipher}; + use cipher::generic_array::GenericArray; + use cipher::stream::{blobby::Blob4Iterator, NewStreamCipher, SyncStreamCipher}; let data = include_bytes!(concat!("data/", $test_name, ".blb")); for (i, row) in Blob4Iterator::new(data).unwrap().enumerate() { @@ -44,8 +43,8 @@ macro_rules! new_seek_test { ($name:ident, $cipher:ty) => { #[test] fn $name() { - use stream_cipher::generic_array::GenericArray; - use stream_cipher::{NewStreamCipher, SyncStreamCipher, SyncStreamCipherSeek}; + use cipher::generic_array::GenericArray; + use cipher::stream::{NewStreamCipher, SyncStreamCipher, SyncStreamCipherSeek}; fn get_cipher() -> $cipher { <$cipher>::new(&Default::default(), &Default::default()) @@ -97,9 +96,8 @@ macro_rules! new_async_test { ($name:ident, $test_name:expr, $cipher:ty) => { #[test] fn $name() { - use stream_cipher::blobby::Blob4Iterator; - use stream_cipher::generic_array::GenericArray; - use stream_cipher::{NewStreamCipher, StreamCipher}; + use cipher::generic_array::GenericArray; + use cipher::stream::{blobby::Blob4Iterator, NewStreamCipher, StreamCipher}; fn run_test( key: &[u8], @@ -174,8 +172,8 @@ macro_rules! bench_sync { ($cipher:path) => { extern crate test; - use stream_cipher::generic_array::GenericArray; - use stream_cipher::{NewStreamCipher, SyncStreamCipher}; + use cipher::generic_array::GenericArray; + use cipher::stream::{NewStreamCipher, SyncStreamCipher}; use test::Bencher; #[inline(never)] @@ -227,8 +225,8 @@ macro_rules! bench_async { ($cipher:path) => { extern crate test; - use stream_cipher::generic_array::GenericArray; - use stream_cipher::{NewStreamCipher, StreamCipher}; + use cipher::generic_array::GenericArray; + use cipher::stream::{NewStreamCipher, StreamCipher}; use test::Bencher; #[inline(never)] From bc8752aa0ec612e9a8978b0cfd6a0b0547415fa4 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 16 Oct 2020 06:34:24 -0700 Subject: [PATCH 0273/1461] cipher v0.2.1 (#346) --- Cargo.lock | 2 +- cipher/CHANGELOG.md | 12 +++++++++++- cipher/Cargo.toml | 2 +- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0d1000fb9..f4830b126 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -85,7 +85,7 @@ checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" [[package]] name = "cipher" -version = "0.2.0" +version = "0.2.1" dependencies = [ "blobby 0.3.0", "generic-array 0.14.4", diff --git a/cipher/CHANGELOG.md b/cipher/CHANGELOG.md index cfc238736..940b3b262 100644 --- a/cipher/CHANGELOG.md +++ b/cipher/CHANGELOG.md @@ -5,7 +5,17 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 0.2.0 (2020-10-15) +## 0.2.1 (2020-10-16) +### Added +- Re-export `generic_array` from toplevel ([#343]) + +### Fixed +- `dev` macro imports ([#345]) + +[#343]: https://github.com/RustCrypto/traits/pull/343 +[#345]: https://github.com/RustCrypto/traits/pull/345 + +## 0.2.0 (2020-10-15) [YANKED] ### Changed - Unify `block-cipher` and `stream-cipher` into `cipher` ([#337]) diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index 88e4d7b9c..2fb59ef53 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "cipher" description = "Traits for describing block ciphers and stream ciphers" -version = "0.2.0" +version = "0.2.1" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" From 79254b085415f6c13c3f40d34ba78c1a9f15f283 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 30 Oct 2020 08:30:18 -0700 Subject: [PATCH 0274/1461] cipher: revamp macro names (#350) The old macro names come from the `block-cipher` and `stream-cipher` crates, where the crate names disambiguated them. However, in the same crate, and re-exported from the toplevel as macros are, it's now unclear whether a macro is for a block cipher or a stream cipher. This commit adds `block_cipher*` and `stream_cipher` to the start of each macro name to disambiguate them. It also maintains the existing macros as wrappers for the new names, but with a `#[deprecated]` attribute added. --- cipher/README.md | 2 +- cipher/src/block/dev.rs | 30 +++++++++++++++++--- cipher/src/lib.rs | 2 +- cipher/src/stream/dev.rs | 61 ++++++++++++++++++++++++++++++++++++---- 4 files changed, 83 insertions(+), 12 deletions(-) diff --git a/cipher/README.md b/cipher/README.md index d88f04339..b2c33abd7 100644 --- a/cipher/README.md +++ b/cipher/README.md @@ -10,7 +10,7 @@ Traits which define the functionality of [block ciphers] and [stream ciphers]. See [RustCrypto/block-ciphers] and [RustCrypto/stream-ciphers] for algorithm -implementations which use this trait. +implementations which use these traits. [Documentation][docs-link] diff --git a/cipher/src/block/dev.rs b/cipher/src/block/dev.rs index 4ab57d706..d59c58967 100644 --- a/cipher/src/block/dev.rs +++ b/cipher/src/block/dev.rs @@ -2,10 +2,10 @@ pub use blobby; -/// Define test +/// Define block cipher test #[macro_export] #[cfg_attr(docsrs, doc(cfg(feature = "dev")))] -macro_rules! new_test { +macro_rules! block_cipher_test { ($name:ident, $test_name:expr, $cipher:ty) => { #[test] fn $name() { @@ -104,10 +104,10 @@ macro_rules! new_test { }; } -/// Define benchmark +/// Define block cipher benchmark #[macro_export] #[cfg_attr(docsrs, doc(cfg(feature = "dev")))] -macro_rules! bench { +macro_rules! block_cipher_bench { ($cipher:path, $key_len:expr) => { extern crate test; @@ -139,3 +139,25 @@ macro_rules! bench { } }; } + +// +// Below are deprecated legacy macro wrappers. They should be removed in v0.3. +// + +/// Define tests +#[macro_export] +#[deprecated(since = "0.2.2", note = "use `block_cipher_test!` instead")] +macro_rules! new_test { + ($name:ident, $test_name:expr, $cipher:ty) => { + block_cipher_test!($name, $test_name, $cipher) + }; +} + +/// Define benchmark +#[macro_export] +#[deprecated(since = "0.2.2", note = "use `block_cipher_bench!` instead")] +macro_rules! bench { + ($cipher:path, $key_len:expr) => { + block_cipher_bench!($cipher, $key_len) + }; +} diff --git a/cipher/src/lib.rs b/cipher/src/lib.rs index 036707e71..9440c5783 100644 --- a/cipher/src/lib.rs +++ b/cipher/src/lib.rs @@ -1,4 +1,4 @@ -//! This crate defines a set of simple traits used to define functionality of +//! This crate defines a set of traits which describe the functionality of //! [block ciphers][1] and [stream ciphers][2]. //! //! [1]: https://en.wikipedia.org/wiki/Block_cipher diff --git a/cipher/src/stream/dev.rs b/cipher/src/stream/dev.rs index b538e57c1..2f0194598 100644 --- a/cipher/src/stream/dev.rs +++ b/cipher/src/stream/dev.rs @@ -3,7 +3,7 @@ /// Test core functionality of synchronous stream cipher #[macro_export] #[cfg_attr(docsrs, doc(cfg(feature = "dev")))] -macro_rules! new_sync_test { +macro_rules! stream_cipher_sync_test { ($name:ident, $cipher:ty, $test_name:expr) => { #[test] fn $name() { @@ -39,7 +39,7 @@ macro_rules! new_sync_test { /// Test stream synchronous stream cipher seeking capabilities #[macro_export] #[cfg_attr(docsrs, doc(cfg(feature = "dev")))] -macro_rules! new_seek_test { +macro_rules! stream_cipher_seek_test { ($name:ident, $cipher:ty) => { #[test] fn $name() { @@ -92,7 +92,7 @@ macro_rules! new_seek_test { /// Test core functionality of asynchronous stream cipher #[macro_export] #[cfg_attr(docsrs, doc(cfg(feature = "dev")))] -macro_rules! new_async_test { +macro_rules! stream_cipher_async_test { ($name:ident, $test_name:expr, $cipher:ty) => { #[test] fn $name() { @@ -153,7 +153,7 @@ macro_rules! new_async_test { /// Create synchronous stream cipher benchmarks #[macro_export] #[cfg_attr(docsrs, doc(cfg(feature = "dev")))] -macro_rules! bench_sync { +macro_rules! stream_cipher_sync_bench { ($name:ident, $cipher:path, $data_len:expr) => { #[bench] pub fn $name(bh: &mut Bencher) { @@ -189,10 +189,10 @@ macro_rules! bench_sync { }; } -/// Create synchronous stream cipher benchmarks +/// Create asynchronous stream cipher benchmarks #[macro_export] #[cfg_attr(docsrs, doc(cfg(feature = "dev")))] -macro_rules! bench_async { +macro_rules! stream_cipher_async_bench { ($enc_name:ident, $dec_name:ident, $cipher:path, $data_len:expr) => { #[bench] pub fn $enc_name(bh: &mut Bencher) { @@ -241,3 +241,52 @@ macro_rules! bench_async { $crate::bench_async!(encrypt_100000, decrypt_100000, $cipher, 100000); }; } + +// +// Below are deprecated legacy macro wrappers. They should be removed in v0.3. +// + +/// Test core functionality of synchronous stream cipher +#[macro_export] +#[deprecated(since = "0.2.2", note = "use `stream_cipher_sync_test!` instead")] +macro_rules! new_sync_test { + ($name:ident, $cipher:ty, $test_name:expr) => { + stream_cipher_sync_test!($name, $cipher, $test_name) + }; +} + +/// Test stream synchronous stream cipher seeking capabilities +#[macro_export] +#[deprecated(since = "0.2.2", note = "use `stream_cipher_seek_test!` instead")] +macro_rules! new_seek_test { + ($name:ident, $cipher:ty) => { + stream_cipher_seek_test!($name, $cipher) + }; +} + +/// Test core functionality of asynchronous stream cipher +#[macro_export] +#[deprecated(since = "0.2.2", note = "use `stream_cipher_async_test!` instead")] +macro_rules! new_async_test { + ($name:ident, $test_name:expr, $cipher:ty) => { + stream_cipher_async_test!($name, $test_name, $cipher) + }; +} + +/// Create synchronous stream cipher benchmarks +#[macro_export] +#[deprecated(since = "0.2.2", note = "use `stream_cipher_sync_bench!` instead")] +macro_rules! bench_sync { + ($name:ident, $cipher:path, $data_len:expr) => { + stream_cipher_sync_bench!($name, $cipher, $data_len) + }; +} + +/// Create asynchronous stream cipher benchmarks +#[macro_export] +#[deprecated(since = "0.2.2", note = "use `stream_cipher_async_bench!` instead")] +macro_rules! bench_async { + ($enc_name:ident, $dec_name:ident, $cipher:path, $data_len:expr) => { + stream_cipher_async_bench!($enc_name, $dec_name, $cipher, $data_len) + }; +} From a2c62c52bb8e0606a8dcc1746c91cd23a3f4ff65 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 1 Nov 2020 07:47:10 -0800 Subject: [PATCH 0275/1461] cipher: add BlockCipher::{encrypt_slice, decrypt_slice} (#351) Partially addresses #332. Adds methods which work over an arbitrarily sized slice of blocks to encrypt/decrypt. Provides a default implementation, but can be potentially further optimized by individual implementations. --- cipher/src/block.rs | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/cipher/src/block.rs b/cipher/src/block.rs index 7289561fd..551e9d14a 100644 --- a/cipher/src/block.rs +++ b/cipher/src/block.rs @@ -20,6 +20,7 @@ pub use errors::InvalidKeyLength; // TODO(tarcieri): remove these re-exports in favor of the toplevel one pub use generic_array::{self, typenum::consts}; +use core::convert::TryInto; use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; /// Key for an algorithm that implements [`NewBlockCipher`]. @@ -79,6 +80,26 @@ pub trait BlockCipher { } } + /// Encrypt a slice of blocks, leveraging parallelism when available. + #[inline] + fn encrypt_slice(&self, mut blocks: &mut [Block]) { + let pb = Self::ParBlocks::to_usize(); + + if pb > 1 { + let mut iter = blocks.chunks_exact_mut(pb); + + for chunk in &mut iter { + self.encrypt_blocks(chunk.try_into().unwrap()) + } + + blocks = iter.into_remainder(); + } + + for block in blocks { + self.encrypt_block(block); + } + } + /// Decrypt several blocks in parallel using instruction level parallelism /// if possible. /// @@ -89,6 +110,26 @@ pub trait BlockCipher { self.decrypt_block(block); } } + + /// Decrypt a slice of blocks, leveraging parallelism when available. + #[inline] + fn decrypt_slice(&self, mut blocks: &mut [Block]) { + let pb = Self::ParBlocks::to_usize(); + + if pb > 1 { + let mut iter = blocks.chunks_exact_mut(pb); + + for chunk in &mut iter { + self.decrypt_blocks(chunk.try_into().unwrap()) + } + + blocks = iter.into_remainder(); + } + + for block in blocks { + self.decrypt_block(block); + } + } } /// Stateful block cipher which permits `&mut self` access. From 64172c031434d283a7359ce12c4e7bcc74fcba71 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 1 Nov 2020 12:59:01 -0800 Subject: [PATCH 0276/1461] cipher v0.2.2 (#355) --- Cargo.lock | 2 +- cipher/CHANGELOG.md | 10 ++++++++++ cipher/Cargo.toml | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f4830b126..0ab9aa61c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -85,7 +85,7 @@ checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" [[package]] name = "cipher" -version = "0.2.1" +version = "0.2.2" dependencies = [ "blobby 0.3.0", "generic-array 0.14.4", diff --git a/cipher/CHANGELOG.md b/cipher/CHANGELOG.md index 940b3b262..ac409dba7 100644 --- a/cipher/CHANGELOG.md +++ b/cipher/CHANGELOG.md @@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.2.2 (2020-11-01) +### Added +- `BlockCipher::{encrypt_slice, decrypt_slice}` methods ([#351]) + +### Changed +- Revamp macro names ([#350]) + +[#351]: https://github.com/RustCrypto/traits/pull/351 +[#350]: https://github.com/RustCrypto/traits/pull/350 + ## 0.2.1 (2020-10-16) ### Added - Re-export `generic_array` from toplevel ([#343]) diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index 2fb59ef53..d0d0a6053 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "cipher" description = "Traits for describing block ciphers and stream ciphers" -version = "0.2.1" +version = "0.2.2" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" From c697a3d67e33b195e2e6e01ea8fb99056b962a56 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 1 Nov 2020 13:32:04 -0800 Subject: [PATCH 0277/1461] cipher: fix legacy macro wrappers (#356) They weren't using `$crate::*`, and therefore the resulting code doesn't compile. --- cipher/src/block/dev.rs | 4 ++-- cipher/src/stream/dev.rs | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cipher/src/block/dev.rs b/cipher/src/block/dev.rs index d59c58967..08ed8640a 100644 --- a/cipher/src/block/dev.rs +++ b/cipher/src/block/dev.rs @@ -149,7 +149,7 @@ macro_rules! block_cipher_bench { #[deprecated(since = "0.2.2", note = "use `block_cipher_test!` instead")] macro_rules! new_test { ($name:ident, $test_name:expr, $cipher:ty) => { - block_cipher_test!($name, $test_name, $cipher) + $crate::block_cipher_test!($name, $test_name, $cipher) }; } @@ -158,6 +158,6 @@ macro_rules! new_test { #[deprecated(since = "0.2.2", note = "use `block_cipher_bench!` instead")] macro_rules! bench { ($cipher:path, $key_len:expr) => { - block_cipher_bench!($cipher, $key_len) + $crate::block_cipher_bench!($cipher, $key_len) }; } diff --git a/cipher/src/stream/dev.rs b/cipher/src/stream/dev.rs index 2f0194598..273e1e642 100644 --- a/cipher/src/stream/dev.rs +++ b/cipher/src/stream/dev.rs @@ -251,7 +251,7 @@ macro_rules! stream_cipher_async_bench { #[deprecated(since = "0.2.2", note = "use `stream_cipher_sync_test!` instead")] macro_rules! new_sync_test { ($name:ident, $cipher:ty, $test_name:expr) => { - stream_cipher_sync_test!($name, $cipher, $test_name) + $crate::stream_cipher_sync_test!($name, $cipher, $test_name) }; } @@ -260,7 +260,7 @@ macro_rules! new_sync_test { #[deprecated(since = "0.2.2", note = "use `stream_cipher_seek_test!` instead")] macro_rules! new_seek_test { ($name:ident, $cipher:ty) => { - stream_cipher_seek_test!($name, $cipher) + $crate::stream_cipher_seek_test!($name, $cipher) }; } @@ -269,7 +269,7 @@ macro_rules! new_seek_test { #[deprecated(since = "0.2.2", note = "use `stream_cipher_async_test!` instead")] macro_rules! new_async_test { ($name:ident, $test_name:expr, $cipher:ty) => { - stream_cipher_async_test!($name, $test_name, $cipher) + $crate::stream_cipher_async_test!($name, $test_name, $cipher) }; } @@ -278,7 +278,7 @@ macro_rules! new_async_test { #[deprecated(since = "0.2.2", note = "use `stream_cipher_sync_bench!` instead")] macro_rules! bench_sync { ($name:ident, $cipher:path, $data_len:expr) => { - stream_cipher_sync_bench!($name, $cipher, $data_len) + $crate::stream_cipher_sync_bench!($name, $cipher, $data_len) }; } @@ -287,6 +287,6 @@ macro_rules! bench_sync { #[deprecated(since = "0.2.2", note = "use `stream_cipher_async_bench!` instead")] macro_rules! bench_async { ($enc_name:ident, $dec_name:ident, $cipher:path, $data_len:expr) => { - stream_cipher_async_bench!($enc_name, $dec_name, $cipher, $data_len) + $crate::stream_cipher_async_bench!($enc_name, $dec_name, $cipher, $data_len) }; } From 77bb320f81c85f99fc2deac4c63226d6a5b47aeb Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 1 Nov 2020 13:41:18 -0800 Subject: [PATCH 0278/1461] cipher v0.2.3 (#357) --- Cargo.lock | 2 +- cipher/CHANGELOG.md | 6 ++++++ cipher/Cargo.toml | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0ab9aa61c..083b33804 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -85,7 +85,7 @@ checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" [[package]] name = "cipher" -version = "0.2.2" +version = "0.2.3" dependencies = [ "blobby 0.3.0", "generic-array 0.14.4", diff --git a/cipher/CHANGELOG.md b/cipher/CHANGELOG.md index ac409dba7..55b537cde 100644 --- a/cipher/CHANGELOG.md +++ b/cipher/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.2.3 (2020-11-01) +### Fixed +- Legacy macro wrappers ([#356]) + +[#356]: https://github.com/RustCrypto/traits/pull/356 + ## 0.2.2 (2020-11-01) ### Added - `BlockCipher::{encrypt_slice, decrypt_slice}` methods ([#351]) diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index d0d0a6053..ccf4b8bb2 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "cipher" description = "Traits for describing block ciphers and stream ciphers" -version = "0.2.2" +version = "0.2.3" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" From e7c5b472a4f81171500597b0d93522643e2d87eb Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 1 Nov 2020 13:49:49 -0800 Subject: [PATCH 0279/1461] cipher: fix macro expansion error (#358) --- cipher/src/block/dev.rs | 4 ++-- cipher/src/stream/dev.rs | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cipher/src/block/dev.rs b/cipher/src/block/dev.rs index 08ed8640a..b518965a0 100644 --- a/cipher/src/block/dev.rs +++ b/cipher/src/block/dev.rs @@ -149,7 +149,7 @@ macro_rules! block_cipher_bench { #[deprecated(since = "0.2.2", note = "use `block_cipher_test!` instead")] macro_rules! new_test { ($name:ident, $test_name:expr, $cipher:ty) => { - $crate::block_cipher_test!($name, $test_name, $cipher) + $crate::block_cipher_test!($name, $test_name, $cipher); }; } @@ -158,6 +158,6 @@ macro_rules! new_test { #[deprecated(since = "0.2.2", note = "use `block_cipher_bench!` instead")] macro_rules! bench { ($cipher:path, $key_len:expr) => { - $crate::block_cipher_bench!($cipher, $key_len) + $crate::block_cipher_bench!($cipher, $key_len); }; } diff --git a/cipher/src/stream/dev.rs b/cipher/src/stream/dev.rs index 273e1e642..63c6e764d 100644 --- a/cipher/src/stream/dev.rs +++ b/cipher/src/stream/dev.rs @@ -251,7 +251,7 @@ macro_rules! stream_cipher_async_bench { #[deprecated(since = "0.2.2", note = "use `stream_cipher_sync_test!` instead")] macro_rules! new_sync_test { ($name:ident, $cipher:ty, $test_name:expr) => { - $crate::stream_cipher_sync_test!($name, $cipher, $test_name) + $crate::stream_cipher_sync_test!($name, $cipher, $test_name); }; } @@ -260,7 +260,7 @@ macro_rules! new_sync_test { #[deprecated(since = "0.2.2", note = "use `stream_cipher_seek_test!` instead")] macro_rules! new_seek_test { ($name:ident, $cipher:ty) => { - $crate::stream_cipher_seek_test!($name, $cipher) + $crate::stream_cipher_seek_test!($name, $cipher); }; } @@ -269,7 +269,7 @@ macro_rules! new_seek_test { #[deprecated(since = "0.2.2", note = "use `stream_cipher_async_test!` instead")] macro_rules! new_async_test { ($name:ident, $test_name:expr, $cipher:ty) => { - $crate::stream_cipher_async_test!($name, $test_name, $cipher) + $crate::stream_cipher_async_test!($name, $test_name, $cipher); }; } @@ -278,7 +278,7 @@ macro_rules! new_async_test { #[deprecated(since = "0.2.2", note = "use `stream_cipher_sync_bench!` instead")] macro_rules! bench_sync { ($name:ident, $cipher:path, $data_len:expr) => { - $crate::stream_cipher_sync_bench!($name, $cipher, $data_len) + $crate::stream_cipher_sync_bench!($name, $cipher, $data_len); }; } @@ -287,6 +287,6 @@ macro_rules! bench_sync { #[deprecated(since = "0.2.2", note = "use `stream_cipher_async_bench!` instead")] macro_rules! bench_async { ($enc_name:ident, $dec_name:ident, $cipher:path, $data_len:expr) => { - $crate::stream_cipher_async_bench!($enc_name, $dec_name, $cipher, $data_len) + $crate::stream_cipher_async_bench!($enc_name, $dec_name, $cipher, $data_len); }; } From 8c04b9b734300025bb36ce0eea6f499f49b34620 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 1 Nov 2020 14:06:38 -0800 Subject: [PATCH 0280/1461] cipher v0.2.4 (#359) --- Cargo.lock | 2 +- cipher/CHANGELOG.md | 10 ++++++++-- cipher/Cargo.toml | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 083b33804..a7270cc6b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -85,7 +85,7 @@ checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" [[package]] name = "cipher" -version = "0.2.3" +version = "0.2.4" dependencies = [ "blobby 0.3.0", "generic-array 0.14.4", diff --git a/cipher/CHANGELOG.md b/cipher/CHANGELOG.md index 55b537cde..89c4e0fa8 100644 --- a/cipher/CHANGELOG.md +++ b/cipher/CHANGELOG.md @@ -5,13 +5,19 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 0.2.3 (2020-11-01) +## 0.2.4 (2020-11-01) +### Fixed +- Macro expansion error ([#358]) + +[#358]: https://github.com/RustCrypto/traits/pull/358 + +## 0.2.3 (2020-11-01) [YANKED] ### Fixed - Legacy macro wrappers ([#356]) [#356]: https://github.com/RustCrypto/traits/pull/356 -## 0.2.2 (2020-11-01) +## 0.2.2 (2020-11-01) [YANKED] ### Added - `BlockCipher::{encrypt_slice, decrypt_slice}` methods ([#351]) diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index ccf4b8bb2..88f6d63bd 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "cipher" description = "Traits for describing block ciphers and stream ciphers" -version = "0.2.3" +version = "0.2.4" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" From 6c4b6f95da65ef431fcc57858607705fbfd2a09b Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 1 Nov 2020 14:16:18 -0800 Subject: [PATCH 0281/1461] cipher: fix nested macro usage (#360) The new macro names were still invoking the old deprecated ones --- cipher/src/stream/dev.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/cipher/src/stream/dev.rs b/cipher/src/stream/dev.rs index 63c6e764d..5e7f3be08 100644 --- a/cipher/src/stream/dev.rs +++ b/cipher/src/stream/dev.rs @@ -181,11 +181,11 @@ macro_rules! stream_cipher_sync_bench { vec![77; n] } - $crate::bench_sync!(bench1_10, $cipher, 10); - $crate::bench_sync!(bench2_100, $cipher, 100); - $crate::bench_sync!(bench3_1000, $cipher, 1000); - $crate::bench_sync!(bench4_10000, $cipher, 10000); - $crate::bench_sync!(bench5_100000, $cipher, 100000); + $crate::stream_cipher_sync_bench!(bench1_10, $cipher, 10); + $crate::stream_cipher_sync_bench!(bench2_100, $cipher, 100); + $crate::stream_cipher_sync_bench!(bench3_1000, $cipher, 1000); + $crate::stream_cipher_sync_bench!(bench4_10000, $cipher, 10000); + $crate::stream_cipher_sync_bench!(bench5_100000, $cipher, 100000); }; } @@ -234,11 +234,11 @@ macro_rules! stream_cipher_async_bench { vec![77; n] } - $crate::bench_async!(encrypt_10, decrypt_10, $cipher, 10); - $crate::bench_async!(encrypt_100, decrypt_100, $cipher, 100); - $crate::bench_async!(encrypt_1000, decrypt_1000, $cipher, 1000); - $crate::bench_async!(encrypt_10000, decrypt_10000, $cipher, 10000); - $crate::bench_async!(encrypt_100000, decrypt_100000, $cipher, 100000); + $crate::stream_cipher_async_bench!(encrypt_10, decrypt_10, $cipher, 10); + $crate::stream_cipher_async_bench!(encrypt_100, decrypt_100, $cipher, 100); + $crate::stream_cipher_async_bench!(encrypt_1000, decrypt_1000, $cipher, 1000); + $crate::stream_cipher_async_bench!(encrypt_10000, decrypt_10000, $cipher, 10000); + $crate::stream_cipher_async_bench!(encrypt_100000, decrypt_100000, $cipher, 100000); }; } From b524ca61cbc61cfd155426c3828c036e60624580 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 1 Nov 2020 14:20:17 -0800 Subject: [PATCH 0282/1461] cipher v0.2.5 (#361) --- Cargo.lock | 2 +- cipher/CHANGELOG.md | 6 ++++++ cipher/Cargo.toml | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a7270cc6b..3fc8af006 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -85,7 +85,7 @@ checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" [[package]] name = "cipher" -version = "0.2.4" +version = "0.2.5" dependencies = [ "blobby 0.3.0", "generic-array 0.14.4", diff --git a/cipher/CHANGELOG.md b/cipher/CHANGELOG.md index 89c4e0fa8..e7743e965 100644 --- a/cipher/CHANGELOG.md +++ b/cipher/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.2.5 (2020-11-01) +### Fixed +- Nested macros used old deprecated names ([#360]) + +[#360]: https://github.com/RustCrypto/traits/pull/360 + ## 0.2.4 (2020-11-01) ### Fixed - Macro expansion error ([#358]) diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index 88f6d63bd..6a1fde75a 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "cipher" description = "Traits for describing block ciphers and stream ciphers" -version = "0.2.4" +version = "0.2.5" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" From 80b1962854f02ffc4b9e0ebc81361fd30876284e Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 1 Nov 2020 14:34:09 -0800 Subject: [PATCH 0283/1461] README.md: use non-breaking hyphens (#362) --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 9d54331f7..759473736 100644 --- a/README.md +++ b/README.md @@ -7,11 +7,11 @@ Collection of traits which describe functionality of cryptographic primitives. | Crate name | Algorithm | Crates.io | Docs | Build Status | |---------------------|-------------------------------|-----------|-------|--------------| | [`aead`] | [Authenticated encryption] | [![crates.io](https://img.shields.io/crates/v/aead.svg)](https://crates.io/crates/aead) | [![Documentation](https://docs.rs/aead/badge.svg)](https://docs.rs/aead) | ![build](https://github.com/RustCrypto/traits/workflows/aead/badge.svg?branch=master&event=push) | -| [`async-signature`] | [Digital signature] | [![crates.io](https://img.shields.io/crates/v/async-signature.svg)](https://crates.io/crates/async-signature) | [![Documentation](https://docs.rs/async-signature/badge.svg)](https://docs.rs/async-signature) | ![build](https://github.com/RustCrypto/traits/workflows/async-signature/badge.svg?branch=master&event=push) | +| [`async‑signature`] | [Digital signature] | [![crates.io](https://img.shields.io/crates/v/async-signature.svg)](https://crates.io/crates/async-signature) | [![Documentation](https://docs.rs/async-signature/badge.svg)](https://docs.rs/async-signature) | ![build](https://github.com/RustCrypto/traits/workflows/async-signature/badge.svg?branch=master&event=push) | | [`cipher`] | [Block] and [stream cipher] | [![crates.io](https://img.shields.io/crates/v/cipher.svg)](https://crates.io/crates/cipher) | [![Documentation](https://docs.rs/cipher/badge.svg)](https://docs.rs/cipher) | ![build](https://github.com/RustCrypto/traits/workflows/cipher/badge.svg?branch=master&event=push) | | [`crypto‑mac`] | [Message authentication code] | [![crates.io](https://img.shields.io/crates/v/crypto-mac.svg)](https://crates.io/crates/crypto-mac) | [![Documentation](https://docs.rs/crypto-mac/badge.svg)](https://docs.rs/crypto-mac) | ![build](https://github.com/RustCrypto/traits/workflows/crypto-mac/badge.svg?branch=master&event=push) | | [`digest`] | [Cryptographic hash function] | [![crates.io](https://img.shields.io/crates/v/digest.svg)](https://crates.io/crates/digest) | [![Documentation](https://docs.rs/digest/badge.svg)](https://docs.rs/digest) | ![build](https://github.com/RustCrypto/traits/workflows/digest/badge.svg?branch=master&event=push) | -| [`elliptic-curve`] | [Elliptic curve cryptography] | [![crates.io](https://img.shields.io/crates/v/elliptic-curve.svg)](https://crates.io/crates/elliptic-curve) | [![Documentation](https://docs.rs/elliptic-curve/badge.svg)](https://docs.rs/elliptic-curve) | ![build](https://github.com/RustCrypto/traits/workflows/elliptic-curve/badge.svg?branch=master&event=push) | +| [`elliptic‑curve`] | [Elliptic curve cryptography] | [![crates.io](https://img.shields.io/crates/v/elliptic-curve.svg)](https://crates.io/crates/elliptic-curve) | [![Documentation](https://docs.rs/elliptic-curve/badge.svg)](https://docs.rs/elliptic-curve) | ![build](https://github.com/RustCrypto/traits/workflows/elliptic-curve/badge.svg?branch=master&event=push) | | [`signature`] | [Digital signature] | [![crates.io](https://img.shields.io/crates/v/signature.svg)](https://crates.io/crates/signature) | [![Documentation](https://docs.rs/signature/badge.svg)](https://docs.rs/signature) | ![build](https://github.com/RustCrypto/traits/workflows/signature/badge.svg?branch=master&event=push) | | [`universal‑hash`] | [Universal hash function] | [![crates.io](https://img.shields.io/crates/v/universal-hash.svg)](https://crates.io/crates/universal-hash) | [![Documentation](https://docs.rs/universal-hash/badge.svg)](https://docs.rs/universal-hash) | ![build](https://github.com/RustCrypto/traits/workflows/universal-hash/badge.svg?branch=master&event=push) | @@ -52,12 +52,12 @@ dual licensed as above, without any additional terms or conditions. [//]: # (crates) [`aead`]: https://github.com/RustCrypto/traits/tree/master/aead -[`async-signature`]: https://github.com/RustCrypto/traits/tree/master/signature/async +[`async‑signature`]: https://github.com/RustCrypto/traits/tree/master/signature/async [`cipher`]: https://github.com/RustCrypto/traits/tree/master/cipher [`crypto‑mac`]: https://github.com/RustCrypto/traits/tree/master/crypto-mac [`cryptography`]: https://github.com/RustCrypto/traits/tree/master/cryptography [`digest`]: https://github.com/RustCrypto/traits/tree/master/digest -[`elliptic-curve`]: https://github.com/RustCrypto/traits/tree/master/elliptic-curve +[`elliptic‑curve`]: https://github.com/RustCrypto/traits/tree/master/elliptic-curve [`signature`]: https://github.com/RustCrypto/traits/tree/master/signature [`universal‑hash`]: https://github.com/RustCrypto/traits/tree/master/universal-hash From 5f1b3985b914e3d41b649555cfc089668e655985 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 3 Nov 2020 10:39:06 -0800 Subject: [PATCH 0284/1461] elliptic-curve: fix `ecdh` rustdoc (#364) It was using the wrong quote (normal apostrophe instead of backtick). --- elliptic-curve/src/ecdh.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elliptic-curve/src/ecdh.rs b/elliptic-curve/src/ecdh.rs index 5fd3c87d0..fbac64567 100644 --- a/elliptic-curve/src/ecdh.rs +++ b/elliptic-curve/src/ecdh.rs @@ -7,7 +7,7 @@ //! # Usage //! //! Have each participant generate an [`EphemeralSecret`] value, compute the -//! [`PublicKey'] for that value, exchange public keys, then each participant +//! [`PublicKey`] for that value, exchange public keys, then each participant //! uses their [`EphemeralSecret`] and the other participant's [`PublicKey`] //! to compute a [`SharedSecret`] value. //! From 91450f41a6283b9facf317cb609723eb22a8dc48 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 3 Nov 2020 11:19:04 -0800 Subject: [PATCH 0285/1461] Bump `const-oid` to v0.2; MSRV 1.46+ (#365) As MSRV bump is considered a breaking change; this also bumps the Cargo.toml version to v0.7.0-pre. This version of `const-oid` uses the new `const fn` features to provide some basic OID validation. While this alone may be a silly reason to bump MSRV to 1.46+, many of the elliptic curve crates could also benefit from using `const fn` in a similar manner, so bumping MSRV is generally useful. --- .github/workflows/elliptic-curve.yml | 6 +++--- Cargo.lock | 6 +++--- cryptography/Cargo.toml | 2 +- elliptic-curve/Cargo.toml | 4 ++-- elliptic-curve/README.md | 4 ++-- elliptic-curve/src/lib.rs | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index a7bb03a89..3da08cdd0 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.44.0 # MSRV + - 1.46.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -37,14 +37,14 @@ jobs: override: true - run: cargo build --no-default-features --release --target ${{ matrix.target }} - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features arithmetic - - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features zeroize - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features ecdh + - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features zeroize test: runs-on: ubuntu-latest strategy: matrix: rust: - - 1.44.0 # MSRV + - 1.46.0 # MSRV - stable steps: - uses: actions/checkout@v1 diff --git a/Cargo.lock b/Cargo.lock index 3fc8af006..857df726c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -93,9 +93,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2d9162b7289a46e86208d6af2c686ca5bfde445878c41a458a9fac706252d0b" +checksum = "6fc33f77ab0b4232f30cb9049a156775c5ad814b030e929d234d14cd6d7ec17f" [[package]] name = "cpuid-bool" @@ -145,7 +145,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.6.6" +version = "0.7.0-pre" dependencies = [ "bitvec", "const-oid", diff --git a/cryptography/Cargo.toml b/cryptography/Cargo.toml index 9f9fba591..83fd5e8ad 100644 --- a/cryptography/Cargo.toml +++ b/cryptography/Cargo.toml @@ -15,7 +15,7 @@ edition = "2018" aead = { version = "0.3", optional = true, path = "../aead" } cipher = { version = "0.2", optional = true, path = "../cipher" } digest = { version = "0.9", optional = true, path = "../digest" } -elliptic-curve = { version = "0.6", optional = true, path = "../elliptic-curve" } +elliptic-curve = { version = "=0.7.0-pre", optional = true, path = "../elliptic-curve" } mac = { version = "0.10", package = "crypto-mac", optional = true, path = "../crypto-mac" } signature = { version = "1.2.0", optional = true, default-features = false, path = "../signature" } universal-hash = { version = "0.4", optional = true, path = "../universal-hash" } diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index f3e1430c2..54b51d99f 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -5,7 +5,7 @@ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. """ -version = "0.6.6" # Also update html_root_url in lib.rs when bumping this +version = "0.7.0-pre" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" repository = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve" @@ -20,7 +20,7 @@ digest = { version = "0.9", optional = true } ff = { version = "0.8", optional = true, default-features = false } group = { version = "0.8", optional = true, default-features = false } generic-array = { version = "0.14", default-features = false } -oid = { package = "const-oid", version = "0.1", optional = true } +oid = { package = "const-oid", version = "0.2", optional = true } rand_core = { version = "0.5", default-features = false } subtle = { version = "2.3", default-features = false } zeroize = { version = "1", optional = true, default-features = false } diff --git a/elliptic-curve/README.md b/elliptic-curve/README.md index 69e635c3d..247109ab3 100644 --- a/elliptic-curve/README.md +++ b/elliptic-curve/README.md @@ -15,7 +15,7 @@ and public/secret keys composed thereof. ## Minimum Supported Rust Version -Requires Rust **1.44** or higher. +Requires Rust **1.46** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -47,7 +47,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/elliptic-curve/badge.svg [docs-link]: https://docs.rs/elliptic-curve/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.44+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.46+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260040-elliptic-curves [build-image]: https://github.com/RustCrypto/elliptic-curves/workflows/elliptic-curve%20crate/badge.svg?branch=master&event=push diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 4f1e239af..040eb3175 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -4,7 +4,7 @@ //! //! ## Minimum Supported Rust Version //! -//! Rust **1.44** or higher. +//! Rust **1.46** or higher. //! //! Minimum supported Rust version can be changed in the future, but it will be //! done with a minor version bump. From f1123a7165c1af258c15a0d5b63533dc6bb24d40 Mon Sep 17 00:00:00 2001 From: Michael Rosenberg Date: Tue, 3 Nov 2020 14:19:56 -0500 Subject: [PATCH 0286/1461] Made PublicKey a newtype that does point validation upon deserialization (#363) --- elliptic-curve/src/ecdh.rs | 114 ++++++++++++++++++++++++++++++------- 1 file changed, 93 insertions(+), 21 deletions(-) diff --git a/elliptic-curve/src/ecdh.rs b/elliptic-curve/src/ecdh.rs index fbac64567..0247a863e 100644 --- a/elliptic-curve/src/ecdh.rs +++ b/elliptic-curve/src/ecdh.rs @@ -24,11 +24,16 @@ use crate::{ consts::U1, generic_array::ArrayLength, scalar::NonZeroScalar, - sec1::{self, FromEncodedPoint, UncompressedPointSize, UntaggedPointSize}, + sec1::{ + EncodedPoint, FromEncodedPoint, ToEncodedPoint, UncompressedPointSize, UntaggedPointSize, + }, weierstrass::Curve, AffinePoint, Error, FieldBytes, ProjectiveArithmetic, Scalar, }; -use core::ops::{Add, Mul}; +use core::{ + fmt::Debug, + ops::{Add, Mul}, +}; use ff::PrimeField; use group::{Curve as _, Group}; use rand_core::{CryptoRng, RngCore}; @@ -36,8 +41,66 @@ use zeroize::Zeroize; /// Elliptic Curve Diffie-Hellman public keys. /// -/// These are SEC1-encoded elliptic curve points. -pub type PublicKey = sec1::EncodedPoint; +/// These are [`AffinePoint`]s. That is, they are non-identity curve points. +#[derive(Clone, Debug)] +pub struct PublicKey +where + C: Curve + ProjectiveArithmetic, + FieldBytes: From> + for<'r> From<&'r Scalar>, + Scalar: PrimeField>, + AffinePoint: Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + point: AffinePoint, +} + +impl PublicKey +where + C: Curve + ProjectiveArithmetic, + FieldBytes: From> + for<'r> From<&'r Scalar>, + Scalar: PrimeField>, + AffinePoint: Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + /// Initialize [`PublicKey`] from a SEC1-encoded public key + pub fn new(bytes: &[u8]) -> Result { + EncodedPoint::from_bytes(bytes) + .map_err(|_| Error) + .and_then(|point| Self::from_encoded_point(&point)) + } + + /// Initialize [`PublicKey`] from an [`EncodedPoint`] + pub fn from_encoded_point(encoded_point: &EncodedPoint) -> Result { + let affine_point = AffinePoint::::from_encoded_point(encoded_point); + + // No need to return a CtOption when the input is assumed to be public + if affine_point.is_some().into() { + Ok(Self { + point: affine_point.unwrap(), + }) + } else { + Err(Error) + } + } +} + +impl ToEncodedPoint for PublicKey +where + C: Curve + ProjectiveArithmetic, + FieldBytes: From> + for<'r> From<&'r Scalar>, + Scalar: PrimeField>, + AffinePoint: Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + /// Serialize this [`PublicKey`] as a SEC1 [`EncodedPoint`], optionally applying + /// point compression + fn to_encoded_point(&self, compress: bool) -> EncodedPoint { + self.point.to_encoded_point(compress) + } +} /// Ephemeral Diffie-Hellman Secret. /// @@ -57,8 +120,14 @@ where C: Curve + ProjectiveArithmetic, FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField> + Clone + Zeroize, - AffinePoint: FromEncodedPoint + Mul, Output = AffinePoint> + Zeroize, - PublicKey: From>, + AffinePoint: Clone + + Debug + + Default + + Into> + + FromEncodedPoint + + ToEncodedPoint + + Mul, Output = AffinePoint> + + Zeroize, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -74,22 +143,19 @@ where /// The `compress` flag enables point compression. pub fn public_key(&self) -> PublicKey { #[allow(clippy::op_ref)] - (C::ProjectivePoint::generator() * &*self.scalar) - .to_affine() - .into() + let pubkey_point = (C::ProjectivePoint::generator() * &*self.scalar).to_affine(); + + PublicKey { + point: pubkey_point, + } } /// Compute a Diffie-Hellman shared secret from an ephemeral secret and the /// public key of the other participant in the exchange. - pub fn diffie_hellman(&self, public_key: &PublicKey) -> Result, Error> { - let affine_point = AffinePoint::::from_encoded_point(public_key); - - if affine_point.is_some().into() { - let shared_secret = affine_point.unwrap() * self.scalar; - Ok(SharedSecret::new(shared_secret.into())) - } else { - Err(Error) - } + pub fn diffie_hellman(&self, public_key: &PublicKey) -> SharedSecret { + let shared_secret = public_key.point.clone() * self.scalar; + // SharedSecret::new expects an uncompressed point + SharedSecret::new(shared_secret.to_encoded_point(false)) } } @@ -98,8 +164,14 @@ where C: Curve + ProjectiveArithmetic, FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField> + Clone + Zeroize, - AffinePoint: FromEncodedPoint + Mul, Output = AffinePoint> + Zeroize, - PublicKey: From>, + AffinePoint: Clone + + Debug + + Default + + Into> + + FromEncodedPoint + + ToEncodedPoint + + Mul, Output = AffinePoint> + + Zeroize, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -163,7 +235,7 @@ where UncompressedPointSize: ArrayLength, { /// Create a new shared secret from the given uncompressed curve point - fn new(mut encoded_point: sec1::EncodedPoint) -> Self { + fn new(mut encoded_point: EncodedPoint) -> Self { let secret_bytes = encoded_point.x().clone(); encoded_point.zeroize(); Self { secret_bytes } From 78f260ee1d844083094172b0d50c9609ac4002a4 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 3 Nov 2020 13:35:42 -0800 Subject: [PATCH 0287/1461] elliptic-curve: extract toplevel PublicKey; add functionality (#366) This PR refactors the `ecdh::PublicKey` type introduced in #363 into a toplevel `public_key::PublicKey` type which is generally useful anywhere a public key is required. It additionally adds a number of additional impls including `AsRef`, `Deref`, and various `From`/`TryFrom` conversions. It also promotes the `from_encoded_point` method into a proper impl of the `FromEncodedPoint` trait, leveraging a `TryFrom` impl instead as a more convenient API. --- elliptic-curve/src/ecdh.rs | 88 ++------------ elliptic-curve/src/lib.rs | 4 + elliptic-curve/src/public_key.rs | 200 +++++++++++++++++++++++++++++++ elliptic-curve/src/secret_key.rs | 29 ++++- 4 files changed, 238 insertions(+), 83 deletions(-) create mode 100644 elliptic-curve/src/public_key.rs diff --git a/elliptic-curve/src/ecdh.rs b/elliptic-curve/src/ecdh.rs index 0247a863e..bf83d991c 100644 --- a/elliptic-curve/src/ecdh.rs +++ b/elliptic-curve/src/ecdh.rs @@ -22,86 +22,21 @@ use crate::{ consts::U1, - generic_array::ArrayLength, + public_key::PublicKey, scalar::NonZeroScalar, sec1::{ EncodedPoint, FromEncodedPoint, ToEncodedPoint, UncompressedPointSize, UntaggedPointSize, }, weierstrass::Curve, - AffinePoint, Error, FieldBytes, ProjectiveArithmetic, Scalar, -}; -use core::{ - fmt::Debug, - ops::{Add, Mul}, + AffinePoint, FieldBytes, ProjectiveArithmetic, ProjectivePoint, Scalar, }; +use core::{fmt::Debug, ops::Add}; use ff::PrimeField; +use generic_array::ArrayLength; use group::{Curve as _, Group}; use rand_core::{CryptoRng, RngCore}; use zeroize::Zeroize; -/// Elliptic Curve Diffie-Hellman public keys. -/// -/// These are [`AffinePoint`]s. That is, they are non-identity curve points. -#[derive(Clone, Debug)] -pub struct PublicKey -where - C: Curve + ProjectiveArithmetic, - FieldBytes: From> + for<'r> From<&'r Scalar>, - Scalar: PrimeField>, - AffinePoint: Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, -{ - point: AffinePoint, -} - -impl PublicKey -where - C: Curve + ProjectiveArithmetic, - FieldBytes: From> + for<'r> From<&'r Scalar>, - Scalar: PrimeField>, - AffinePoint: Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, -{ - /// Initialize [`PublicKey`] from a SEC1-encoded public key - pub fn new(bytes: &[u8]) -> Result { - EncodedPoint::from_bytes(bytes) - .map_err(|_| Error) - .and_then(|point| Self::from_encoded_point(&point)) - } - - /// Initialize [`PublicKey`] from an [`EncodedPoint`] - pub fn from_encoded_point(encoded_point: &EncodedPoint) -> Result { - let affine_point = AffinePoint::::from_encoded_point(encoded_point); - - // No need to return a CtOption when the input is assumed to be public - if affine_point.is_some().into() { - Ok(Self { - point: affine_point.unwrap(), - }) - } else { - Err(Error) - } - } -} - -impl ToEncodedPoint for PublicKey -where - C: Curve + ProjectiveArithmetic, - FieldBytes: From> + for<'r> From<&'r Scalar>, - Scalar: PrimeField>, - AffinePoint: Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, -{ - /// Serialize this [`PublicKey`] as a SEC1 [`EncodedPoint`], optionally applying - /// point compression - fn to_encoded_point(&self, compress: bool) -> EncodedPoint { - self.point.to_encoded_point(compress) - } -} - /// Ephemeral Diffie-Hellman Secret. /// /// These are ephemeral "secret key" values which are deliberately designed @@ -126,8 +61,8 @@ where + Into> + FromEncodedPoint + ToEncodedPoint - + Mul, Output = AffinePoint> + Zeroize, + ProjectivePoint: From>, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -142,20 +77,15 @@ where /// /// The `compress` flag enables point compression. pub fn public_key(&self) -> PublicKey { - #[allow(clippy::op_ref)] - let pubkey_point = (C::ProjectivePoint::generator() * &*self.scalar).to_affine(); - - PublicKey { - point: pubkey_point, - } + PublicKey::from_affine((C::ProjectivePoint::generator() * self.scalar.as_ref()).to_affine()) } /// Compute a Diffie-Hellman shared secret from an ephemeral secret and the /// public key of the other participant in the exchange. pub fn diffie_hellman(&self, public_key: &PublicKey) -> SharedSecret { - let shared_secret = public_key.point.clone() * self.scalar; + let shared_secret = public_key.to_projective() * &self.scalar; // SharedSecret::new expects an uncompressed point - SharedSecret::new(shared_secret.to_encoded_point(false)) + SharedSecret::new(shared_secret.to_affine().to_encoded_point(false)) } } @@ -170,8 +100,8 @@ where + Into> + FromEncodedPoint + ToEncodedPoint - + Mul, Output = AffinePoint> + Zeroize, + ProjectivePoint: From>, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 040eb3175..7617d044c 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -36,6 +36,9 @@ pub mod weierstrass; pub mod point; #[cfg(feature = "arithmetic")] #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] +pub mod public_key; +#[cfg(feature = "arithmetic")] +#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub mod scalar; #[cfg(feature = "ecdh")] @@ -55,6 +58,7 @@ pub use subtle; #[cfg(feature = "arithmetic")] pub use self::{ point::{AffinePoint, ProjectiveArithmetic, ProjectivePoint}, + public_key::PublicKey, scalar::Scalar, }; #[cfg(feature = "arithmetic")] diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs new file mode 100644 index 000000000..28b6a6b2c --- /dev/null +++ b/elliptic-curve/src/public_key.rs @@ -0,0 +1,200 @@ +//! Elliptic curve public keys. + +use crate::{ + consts::U1, + sec1::{ + EncodedPoint, FromEncodedPoint, ToEncodedPoint, UncompressedPointSize, UntaggedPointSize, + }, + weierstrass::{point, Curve}, + AffinePoint, Error, FieldBytes, ProjectiveArithmetic, ProjectivePoint, Scalar, +}; +use core::{ + convert::TryFrom, + fmt::Debug, + ops::{Add, Deref}, +}; +use ff::PrimeField; +use generic_array::ArrayLength; +use subtle::CtOption; + +/// Elliptic curve public keys. +/// +/// These are a thin wrapper around [`AffinePoint`] which simplifies +/// encoding/decoding. +#[derive(Clone, Debug)] +pub struct PublicKey +where + C: Curve + ProjectiveArithmetic, + FieldBytes: From> + for<'r> From<&'r Scalar>, + Scalar: PrimeField>, + AffinePoint: Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, + ProjectivePoint: From>, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + point: AffinePoint, +} + +impl PublicKey +where + C: Curve + ProjectiveArithmetic, + FieldBytes: From> + for<'r> From<&'r Scalar>, + Scalar: PrimeField>, + AffinePoint: Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, + ProjectivePoint: From>, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + /// Initialize [`PublicKey`] from a SEC1-encoded public key + pub fn new(bytes: &[u8]) -> Result { + EncodedPoint::from_bytes(bytes) + .map_err(|_| Error) + .and_then(|point| Self::try_from(&point)) + } + + /// Convert an [`AffinePoint`] into a [`PublicKey`] + pub fn from_affine(point: AffinePoint) -> Self { + Self { point } + } + + /// Convert this [`PublicKey`] to a [`ProjectivePoint`] for the given curve + pub fn to_projective(&self) -> ProjectivePoint { + self.point.clone().into() + } +} + +impl AsRef> for PublicKey +where + C: Curve + ProjectiveArithmetic, + FieldBytes: From> + for<'r> From<&'r Scalar>, + Scalar: PrimeField>, + AffinePoint: Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, + ProjectivePoint: From>, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + fn as_ref(&self) -> &AffinePoint { + &self.point + } +} + +impl Deref for PublicKey +where + C: Curve + ProjectiveArithmetic, + FieldBytes: From> + for<'r> From<&'r Scalar>, + Scalar: PrimeField>, + AffinePoint: Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, + ProjectivePoint: From>, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + type Target = AffinePoint; + + fn deref(&self) -> &AffinePoint { + &self.point + } +} + +impl TryFrom<&EncodedPoint> for PublicKey +where + C: Curve + ProjectiveArithmetic, + FieldBytes: From> + for<'r> From<&'r Scalar>, + Scalar: PrimeField>, + AffinePoint: Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, + ProjectivePoint: From>, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + type Error = Error; + + fn try_from(encoded_point: &EncodedPoint) -> Result { + let public_key = Self::from_encoded_point(encoded_point); + + // No need to return a CtOption when the input is assumed to be public + if public_key.is_some().into() { + Ok(public_key.unwrap()) + } else { + Err(Error) + } + } +} + +impl From> for EncodedPoint +where + C: Curve + ProjectiveArithmetic + point::Compression, + FieldBytes: From> + for<'r> From<&'r Scalar>, + Scalar: PrimeField>, + AffinePoint: Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, + ProjectivePoint: From>, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + fn from(public_key: PublicKey) -> EncodedPoint { + EncodedPoint::::from(&public_key) + } +} + +impl From<&PublicKey> for EncodedPoint +where + C: Curve + ProjectiveArithmetic + point::Compression, + FieldBytes: From> + for<'r> From<&'r Scalar>, + Scalar: PrimeField>, + AffinePoint: Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, + ProjectivePoint: From>, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + fn from(public_key: &PublicKey) -> EncodedPoint { + public_key.to_encoded_point(C::COMPRESS_POINTS) + } +} + +impl FromEncodedPoint for PublicKey +where + C: Curve + ProjectiveArithmetic, + FieldBytes: From> + for<'r> From<&'r Scalar>, + Scalar: PrimeField>, + AffinePoint: Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, + ProjectivePoint: From>, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + /// Initialize [`PublicKey`] from an [`EncodedPoint`] + fn from_encoded_point(encoded_point: &EncodedPoint) -> CtOption { + let affine_point = AffinePoint::::from_encoded_point(encoded_point); + + // Note: not constant time, but these are public keys + if affine_point.is_some().into() { + CtOption::new( + Self { + point: affine_point.unwrap(), + }, + 1.into(), + ) + } else { + CtOption::new( + Self { + point: Default::default(), + }, + 0.into(), + ) + } + } +} + +impl ToEncodedPoint for PublicKey +where + C: Curve + ProjectiveArithmetic, + FieldBytes: From> + for<'r> From<&'r Scalar>, + Scalar: PrimeField>, + AffinePoint: Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, + ProjectivePoint: From>, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + /// Serialize this [`PublicKey`] as a SEC1 [`EncodedPoint`], optionally applying + /// point compression + fn to_encoded_point(&self, compress: bool) -> EncodedPoint { + self.point.to_encoded_point(compress) + } +} diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 118f1d89a..6c340e2d4 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -17,12 +17,17 @@ use zeroize::Zeroize; #[cfg(feature = "arithmetic")] use crate::{ + consts::U1, ff::PrimeField, + generic_array::ArrayLength, + group::{Curve as _, Group}, + ops::Add, + public_key::PublicKey, + rand_core::{CryptoRng, RngCore}, scalar::{NonZeroScalar, Scalar}, - ProjectiveArithmetic, + sec1::{FromEncodedPoint, ToEncodedPoint, UncompressedPointSize, UntaggedPointSize}, + weierstrass, AffinePoint, ProjectiveArithmetic, ProjectivePoint, }; -#[cfg(feature = "arithmetic")] -use rand_core::{CryptoRng, RngCore}; /// Inner value stored by a [`SecretKey`]. pub trait SecretValue: Curve { @@ -115,7 +120,7 @@ where self.secret_value.clone().into() } - /// Borrow the inner secret scalar value. + /// Borrow the inner secret [`Scalar`] value. /// /// # Warning /// @@ -132,6 +137,22 @@ where { self.secret_value.as_ref() } + + /// Get the [`PublicKey`] which corresponds to this secret key + #[cfg(feature = "arithmetic")] + #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] + pub fn public_key(&self) -> PublicKey + where + C: weierstrass::Curve + ProjectiveArithmetic + SecretValue>, + FieldBytes: From> + for<'a> From<&'a Scalar>, + Scalar: PrimeField> + Zeroize, + AffinePoint: Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, + ProjectivePoint: From>, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, + { + PublicKey::from_affine((C::ProjectivePoint::generator() * self.secret_scalar()).to_affine()) + } } impl TryFrom<&[u8]> for SecretKey From 6baa6a221a2ff30f9054f8b176283906eea531f1 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 3 Nov 2020 13:54:25 -0800 Subject: [PATCH 0288/1461] elliptic-curve: remove `subtle` usage on sec1::EncodedPoint (#367) From a practical perspective, `sec1::EncodedPoint` is always used with public values. The previous use of `CtOption` was almost exclusively for error handling, and in every case immediately wrapped in an `Option` or `Result` to avoid end users dealing with public keys from having to deal with `subtle`. Removing the usage of `subtle` in these cases dramatically simplifies the code and required trait bounds. --- elliptic-curve/src/public_key.rs | 52 ++++++++++++++------------------ elliptic-curve/src/sec1.rs | 15 +++++---- 2 files changed, 29 insertions(+), 38 deletions(-) diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index 28b6a6b2c..82a1a87a4 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -9,13 +9,12 @@ use crate::{ AffinePoint, Error, FieldBytes, ProjectiveArithmetic, ProjectivePoint, Scalar, }; use core::{ - convert::TryFrom, + convert::{TryFrom, TryInto}, fmt::Debug, ops::{Add, Deref}, }; use ff::PrimeField; use generic_array::ArrayLength; -use subtle::CtOption; /// Elliptic curve public keys. /// @@ -49,7 +48,7 @@ where pub fn new(bytes: &[u8]) -> Result { EncodedPoint::from_bytes(bytes) .map_err(|_| Error) - .and_then(|point| Self::try_from(&point)) + .and_then(TryInto::try_into) } /// Convert an [`AffinePoint`] into a [`PublicKey`] @@ -95,6 +94,23 @@ where } } +impl TryFrom> for PublicKey +where + C: Curve + ProjectiveArithmetic, + FieldBytes: From> + for<'r> From<&'r Scalar>, + Scalar: PrimeField>, + AffinePoint: Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, + ProjectivePoint: From>, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + type Error = Error; + + fn try_from(encoded_point: EncodedPoint) -> Result { + encoded_point.decode() + } +} + impl TryFrom<&EncodedPoint> for PublicKey where C: Curve + ProjectiveArithmetic, @@ -108,14 +124,7 @@ where type Error = Error; fn try_from(encoded_point: &EncodedPoint) -> Result { - let public_key = Self::from_encoded_point(encoded_point); - - // No need to return a CtOption when the input is assumed to be public - if public_key.is_some().into() { - Ok(public_key.unwrap()) - } else { - Err(Error) - } + encoded_point.decode() } } @@ -160,25 +169,8 @@ where UncompressedPointSize: ArrayLength, { /// Initialize [`PublicKey`] from an [`EncodedPoint`] - fn from_encoded_point(encoded_point: &EncodedPoint) -> CtOption { - let affine_point = AffinePoint::::from_encoded_point(encoded_point); - - // Note: not constant time, but these are public keys - if affine_point.is_some().into() { - CtOption::new( - Self { - point: affine_point.unwrap(), - }, - 1.into(), - ) - } else { - CtOption::new( - Self { - point: Default::default(), - }, - 0.into(), - ) - } + fn from_encoded_point(encoded_point: &EncodedPoint) -> Option { + AffinePoint::::from_encoded_point(encoded_point).map(|point| Self { point }) } } diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index 05cec83d7..b6925b93f 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -14,7 +14,6 @@ use generic_array::{ typenum::{Unsigned, U1}, ArrayLength, GenericArray, }; -use subtle::CtOption; #[cfg(feature = "alloc")] use alloc::boxed::Box; @@ -172,8 +171,7 @@ where Scalar: PrimeField>, AffinePoint: ConditionallySelectable + Default + Decompress + ToEncodedPoint, { - let decompressed: Option> = self.decompress().into(); - decompressed.map(|point| { + self.decompress().map(|point| { let mut bytes = GenericArray::>::default(); bytes.copy_from_slice(&point.as_bytes()[1..]); bytes @@ -196,7 +194,7 @@ where /// Decompress this [`EncodedPoint`], returning a new [`EncodedPoint`]. #[cfg(feature = "arithmetic")] #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] - pub fn decompress(&self) -> CtOption + pub fn decompress(&self) -> Option where C: Curve + ProjectiveArithmetic, FieldBytes: From> + for<'r> From<&'r Scalar>, @@ -207,8 +205,9 @@ where Coordinates::Compressed { x, y_is_odd } => { AffinePoint::::decompress(x, Choice::from(y_is_odd as u8)) .map(|s| s.to_encoded_point(false)) + .into() } - Coordinates::Uncompressed { .. } => CtOption::new(self.clone(), Choice::from(1)), + Coordinates::Uncompressed { .. } => Some(self.clone()), } } @@ -221,11 +220,11 @@ where } /// Decode this [`EncodedPoint`] into the desired type - pub fn decode(&self) -> CtOption + pub fn decode(&self) -> Result where T: FromEncodedPoint, { - T::from_encoded_point(self) + T::from_encoded_point(self).ok_or_else(|| Error) } /// Get the SEC1 tag for this [`EncodedPoint`] @@ -353,7 +352,7 @@ where /// # Returns /// /// `None` if the [`EncodedPoint`] is invalid. - fn from_encoded_point(public_key: &EncodedPoint) -> CtOption; + fn from_encoded_point(public_key: &EncodedPoint) -> Option; } /// Trait for serializing a value to a SEC1 encoded curve point. From c32065643e207ac4d0bbec8da4847afd02322cb8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Nov 2020 06:17:41 +0000 Subject: [PATCH 0289/1461] build(deps): bump sha2 from 0.9.1 to 0.9.2 (#368) --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 857df726c..971c58759 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -79,9 +79,9 @@ checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" [[package]] name = "cfg-if" -version = "0.1.10" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cipher" @@ -299,9 +299,9 @@ checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" [[package]] name = "sha2" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2933378ddfeda7ea26f48c555bdad8bb446bf8a3d17832dc83e380d444cfb8c1" +checksum = "6e7aab86fe2149bad8c507606bdb3f4ef5e7b2380eb92350f56122cca72a42a8" dependencies = [ "block-buffer", "cfg-if", From cae5988aa3814b6798a04ff61f81ef55099894ce Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 11 Nov 2020 11:31:03 -0800 Subject: [PATCH 0290/1461] Rename `cryptography` to `crypto` (#369) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We are now the owners of the `crypto` crate! 🎉 My suggested use for it is a shorter name for `cryptography`. I don't think there's a non-confusing way to use both `crypto` and `cryptography` otherwise, so IMO this is the best way to use it. --- .../{cryptography.yml => crypto.yml} | 6 ++--- Cargo.lock | 24 +++++++++---------- Cargo.toml | 2 +- README.md | 8 +++---- {cryptography => crypto}/CHANGELOG.md | 0 {cryptography => crypto}/Cargo.toml | 4 ++-- {cryptography => crypto}/LICENSE-APACHE | 0 {cryptography => crypto}/LICENSE-MIT | 0 {cryptography => crypto}/README.md | 0 {cryptography => crypto}/src/lib.rs | 0 10 files changed, 22 insertions(+), 22 deletions(-) rename .github/workflows/{cryptography.yml => crypto.yml} (94%) rename {cryptography => crypto}/CHANGELOG.md (100%) rename {cryptography => crypto}/Cargo.toml (96%) rename {cryptography => crypto}/LICENSE-APACHE (100%) rename {cryptography => crypto}/LICENSE-MIT (100%) rename {cryptography => crypto}/README.md (100%) rename {cryptography => crypto}/src/lib.rs (100%) diff --git a/.github/workflows/cryptography.yml b/.github/workflows/crypto.yml similarity index 94% rename from .github/workflows/cryptography.yml rename to .github/workflows/crypto.yml index 8233c9969..c8aea08ed 100644 --- a/.github/workflows/cryptography.yml +++ b/.github/workflows/crypto.yml @@ -1,16 +1,16 @@ -name: cryptography +name: crypto on: pull_request: paths: - - "cryptography/**" + - "crypto/**" - "Cargo.*" push: branches: master defaults: run: - working-directory: cryptography + working-directory: crypto env: CARGO_INCREMENTAL: 0 diff --git a/Cargo.lock b/Cargo.lock index 971c58759..814a2f74f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -104,18 +104,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634" [[package]] -name = "crypto-mac" -version = "0.10.0" -dependencies = [ - "blobby 0.3.0", - "cipher", - "generic-array 0.14.4", - "subtle", -] - -[[package]] -name = "cryptography" -version = "0.5.0" +name = "crypto" +version = "0.2.0-pre" dependencies = [ "aead", "cipher", @@ -126,6 +116,16 @@ dependencies = [ "universal-hash", ] +[[package]] +name = "crypto-mac" +version = "0.10.0" +dependencies = [ + "blobby 0.3.0", + "cipher", + "generic-array 0.14.4", + "subtle", +] + [[package]] name = "digest" version = "0.9.0" diff --git a/Cargo.toml b/Cargo.toml index c940a69a8..943b0d7a1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ members = [ "aead", "cipher", "crypto-mac", - "cryptography", + "crypto", "digest", "elliptic-curve", "signature", diff --git a/README.md b/README.md index 759473736..5dd0f5f44 100644 --- a/README.md +++ b/README.md @@ -17,9 +17,9 @@ Collection of traits which describe functionality of cryptographic primitives. ### Additional crates -| Crate name | Description | Crates.io | Docs | Build Status | -|------------------|-------------|-----------|-------|--------------| -| [`cryptography`] | Facade for trait crates | [![crates.io](https://img.shields.io/crates/v/cryptography.svg)](https://crates.io/crates/cryptography) | [![Documentation](https://docs.rs/cryptography/badge.svg)](https://docs.rs/cryptography) | ![build](https://github.com/RustCrypto/traits/workflows/cryptography/badge.svg?branch=master&event=push) +| Crate name | Description | Crates.io | Docs | Build Status | +|------------|-------------------------|-----------|-------|--------------| +| [`crypto`] | Facade for trait crates | [![crates.io](https://img.shields.io/crates/v/crypto.svg)](https://crates.io/crates/crypto) | [![Documentation](https://docs.rs/crypto/badge.svg)](https://docs.rs/crypto) | ![build](https://github.com/RustCrypto/traits/workflows/crypto/badge.svg?branch=master&event=push) ### Minimum Supported Rust Version @@ -55,7 +55,7 @@ dual licensed as above, without any additional terms or conditions. [`async‑signature`]: https://github.com/RustCrypto/traits/tree/master/signature/async [`cipher`]: https://github.com/RustCrypto/traits/tree/master/cipher [`crypto‑mac`]: https://github.com/RustCrypto/traits/tree/master/crypto-mac -[`cryptography`]: https://github.com/RustCrypto/traits/tree/master/cryptography +[`crypto`]: https://github.com/RustCrypto/traits/tree/master/crypto [`digest`]: https://github.com/RustCrypto/traits/tree/master/digest [`elliptic‑curve`]: https://github.com/RustCrypto/traits/tree/master/elliptic-curve [`signature`]: https://github.com/RustCrypto/traits/tree/master/signature diff --git a/cryptography/CHANGELOG.md b/crypto/CHANGELOG.md similarity index 100% rename from cryptography/CHANGELOG.md rename to crypto/CHANGELOG.md diff --git a/cryptography/Cargo.toml b/crypto/Cargo.toml similarity index 96% rename from cryptography/Cargo.toml rename to crypto/Cargo.toml index 83fd5e8ad..a33603937 100644 --- a/cryptography/Cargo.toml +++ b/crypto/Cargo.toml @@ -1,6 +1,6 @@ [package] -name = "cryptography" -version = "0.5.0" +name = "crypto" +version = "0.2.0-pre" authors = ["The RustCrypto Project Developers"] license = "Apache-2.0 OR MIT" description = "Facade crate for the RustCrypto project's traits" diff --git a/cryptography/LICENSE-APACHE b/crypto/LICENSE-APACHE similarity index 100% rename from cryptography/LICENSE-APACHE rename to crypto/LICENSE-APACHE diff --git a/cryptography/LICENSE-MIT b/crypto/LICENSE-MIT similarity index 100% rename from cryptography/LICENSE-MIT rename to crypto/LICENSE-MIT diff --git a/cryptography/README.md b/crypto/README.md similarity index 100% rename from cryptography/README.md rename to crypto/README.md diff --git a/cryptography/src/lib.rs b/crypto/src/lib.rs similarity index 100% rename from cryptography/src/lib.rs rename to crypto/src/lib.rs From 3ef33ed2a51c7a2c344901c4983f2fdd0426dd36 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Nov 2020 05:23:45 -0800 Subject: [PATCH 0291/1461] build(deps): bump async-trait from 0.1.41 to 0.1.42 (#370) Bumps [async-trait](https://github.com/dtolnay/async-trait) from 0.1.41 to 0.1.42. - [Release notes](https://github.com/dtolnay/async-trait/releases) - [Commits](https://github.com/dtolnay/async-trait/compare/0.1.41...0.1.42) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 814a2f74f..76778c83b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -30,9 +30,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.41" +version = "0.1.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b246867b8b3b6ae56035f1eb1ed557c1d8eae97f0d53696138a50fa0e3a3b8c0" +checksum = "8d3a45e77e34375a7923b1e8febb049bb011f064714a8e17a1a616fef01da13d" dependencies = [ "proc-macro2", "quote", From 590f5451a342b24c78379c731a0766a377ea4728 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 24 Nov 2020 06:28:04 -0800 Subject: [PATCH 0292/1461] cipher: add encrypt/decrypt-only block cipher traits (#352) Splits `BlockCipher` into `BlockEncrypt` and `BlockDecrypt` traits which can be used in cases where e.g. only the encryption portion of a block cipher is used, as in CTR mode. --- Cargo.lock | 4 +-- cipher/Cargo.toml | 2 +- cipher/src/block.rs | 83 +++++++++++++++++-------------------------- cipher/src/lib.rs | 4 ++- cipher/src/stream.rs | 43 ++++------------------ crypto-mac/Cargo.toml | 4 +-- crypto/Cargo.toml | 4 +-- 7 files changed, 49 insertions(+), 95 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 76778c83b..dd3e6aa61 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -85,7 +85,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cipher" -version = "0.2.5" +version = "0.3.0-pre" dependencies = [ "blobby 0.3.0", "generic-array 0.14.4", @@ -118,7 +118,7 @@ dependencies = [ [[package]] name = "crypto-mac" -version = "0.10.0" +version = "0.11.0-pre" dependencies = [ "blobby 0.3.0", "cipher", diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index 6a1fde75a..9c37e7aa6 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "cipher" description = "Traits for describing block ciphers and stream ciphers" -version = "0.2.5" +version = "0.3.0-pre" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/cipher/src/block.rs b/cipher/src/block.rs index 551e9d14a..212642488 100644 --- a/cipher/src/block.rs +++ b/cipher/src/block.rs @@ -53,8 +53,7 @@ pub trait NewBlockCipher: Sized { } } -/// The trait which defines in-place encryption and decryption -/// over single block or several blocks in parallel. +/// Trait which marks a type as being a block cipher. pub trait BlockCipher { /// Size of the block in bytes type BlockSize: ArrayLength; @@ -62,19 +61,19 @@ pub trait BlockCipher { /// Number of blocks which can be processed in parallel by /// cipher implementation type ParBlocks: ArrayLength>; +} +/// Encrypt-only functionality for block ciphers +pub trait BlockEncrypt: BlockCipher { /// Encrypt block in-place fn encrypt_block(&self, block: &mut Block); - /// Decrypt block in-place - fn decrypt_block(&self, block: &mut Block); - /// Encrypt several blocks in parallel using instruction level parallelism /// if possible. /// /// If `ParBlocks` equals to 1 it's equivalent to `encrypt_block`. #[inline] - fn encrypt_blocks(&self, blocks: &mut ParBlocks) { + fn encrypt_par_blocks(&self, blocks: &mut ParBlocks) { for block in blocks.iter_mut() { self.encrypt_block(block); } @@ -82,14 +81,14 @@ pub trait BlockCipher { /// Encrypt a slice of blocks, leveraging parallelism when available. #[inline] - fn encrypt_slice(&self, mut blocks: &mut [Block]) { + fn encrypt_blocks(&self, mut blocks: &mut [Block]) { let pb = Self::ParBlocks::to_usize(); if pb > 1 { let mut iter = blocks.chunks_exact_mut(pb); for chunk in &mut iter { - self.encrypt_blocks(chunk.try_into().unwrap()) + self.encrypt_par_blocks(chunk.try_into().unwrap()) } blocks = iter.into_remainder(); @@ -99,13 +98,19 @@ pub trait BlockCipher { self.encrypt_block(block); } } +} + +/// Decrypt-only functionality for block ciphers +pub trait BlockDecrypt: BlockCipher { + /// Decrypt block in-place + fn decrypt_block(&self, block: &mut Block); /// Decrypt several blocks in parallel using instruction level parallelism /// if possible. /// /// If `ParBlocks` equals to 1 it's equivalent to `decrypt_block`. #[inline] - fn decrypt_blocks(&self, blocks: &mut ParBlocks) { + fn decrypt_par_blocks(&self, blocks: &mut ParBlocks) { for block in blocks.iter_mut() { self.decrypt_block(block); } @@ -113,14 +118,14 @@ pub trait BlockCipher { /// Decrypt a slice of blocks, leveraging parallelism when available. #[inline] - fn decrypt_slice(&self, mut blocks: &mut [Block]) { + fn decrypt_blocks(&self, mut blocks: &mut [Block]) { let pb = Self::ParBlocks::to_usize(); if pb > 1 { let mut iter = blocks.chunks_exact_mut(pb); for chunk in &mut iter { - self.decrypt_blocks(chunk.try_into().unwrap()) + self.decrypt_par_blocks(chunk.try_into().unwrap()) } blocks = iter.into_remainder(); @@ -132,56 +137,32 @@ pub trait BlockCipher { } } -/// Stateful block cipher which permits `&mut self` access. +/// Encrypt-only functionality for block ciphers with mutable access to `self`. /// /// The main use case for this trait is hardware encryption engines which /// require `&mut self` access to an underlying hardware peripheral. -pub trait BlockCipherMut { - /// Size of the block in bytes - type BlockSize: ArrayLength; - +pub trait BlockEncryptMut: BlockCipher { /// Encrypt block in-place - fn encrypt_block(&mut self, block: &mut GenericArray); + fn encrypt_block_mut(&mut self, block: &mut Block); +} +/// Decrypt-only functionality for block ciphers with mutable access to `self`. +/// +/// The main use case for this trait is hardware encryption engines which +/// require `&mut self` access to an underlying hardware peripheral. +pub trait BlockDecryptMut: BlockCipher { /// Decrypt block in-place - fn decrypt_block(&mut self, block: &mut GenericArray); + fn decrypt_block_mut(&mut self, block: &mut Block); } -impl BlockCipherMut for Alg { - type BlockSize = Alg::BlockSize; - - #[inline] - fn encrypt_block(&mut self, block: &mut GenericArray) { - ::encrypt_block(self, block); - } - - #[inline] - fn decrypt_block(&mut self, block: &mut GenericArray) { - ::decrypt_block(self, block); +impl BlockEncryptMut for Alg { + fn encrypt_block_mut(&mut self, block: &mut Block) { + self.encrypt_block(block); } } -impl BlockCipher for &Alg { - type BlockSize = Alg::BlockSize; - type ParBlocks = Alg::ParBlocks; - - #[inline] - fn encrypt_block(&self, block: &mut Block) { - Alg::encrypt_block(self, block); - } - - #[inline] - fn decrypt_block(&self, block: &mut Block) { - Alg::decrypt_block(self, block); - } - - #[inline] - fn encrypt_blocks(&self, blocks: &mut ParBlocks) { - Alg::encrypt_blocks(self, blocks); - } - - #[inline] - fn decrypt_blocks(&self, blocks: &mut ParBlocks) { - Alg::decrypt_blocks(self, blocks); +impl BlockDecryptMut for Alg { + fn decrypt_block_mut(&mut self, block: &mut Block) { + self.decrypt_block(block); } } diff --git a/cipher/src/lib.rs b/cipher/src/lib.rs index 9440c5783..d2cb92938 100644 --- a/cipher/src/lib.rs +++ b/cipher/src/lib.rs @@ -20,7 +20,9 @@ pub mod block; pub mod stream; pub use crate::{ - block::{BlockCipher, BlockCipherMut, NewBlockCipher}, + block::{ + BlockCipher, BlockDecrypt, BlockDecryptMut, BlockEncrypt, BlockEncryptMut, NewBlockCipher, + }, stream::{NewStreamCipher, StreamCipher, SyncStreamCipher, SyncStreamCipherSeek}, }; pub use generic_array::{self, typenum::consts}; diff --git a/cipher/src/stream.rs b/cipher/src/stream.rs index ebc022c5c..ccf29fca2 100644 --- a/cipher/src/stream.rs +++ b/cipher/src/stream.rs @@ -16,7 +16,7 @@ pub use generic_array::{self, typenum::consts}; #[cfg(feature = "dev")] pub use blobby; -use crate::block::{BlockCipher, BlockCipherMut, NewBlockCipher}; +use crate::block::{BlockCipher, NewBlockCipher}; use core::convert::{TryFrom, TryInto}; use generic_array::typenum::Unsigned; use generic_array::{ArrayLength, GenericArray}; @@ -166,46 +166,17 @@ pub trait FromBlockCipher { ) -> Self; } -/// Trait for initializing a stream cipher from a mutable block cipher -pub trait FromBlockCipherMut { - /// Block cipher - type BlockCipher: BlockCipherMut; - /// Nonce size in bytes - type NonceSize: ArrayLength; - - /// Instantiate a stream cipher from a block cipher - fn from_block_cipher_mut( - cipher: Self::BlockCipher, - nonce: &GenericArray, - ) -> Self; -} - -impl FromBlockCipherMut for C -where - C: FromBlockCipher, -{ - type BlockCipher = ::BlockCipher; - type NonceSize = ::NonceSize; - - fn from_block_cipher_mut( - cipher: Self::BlockCipher, - nonce: &GenericArray, - ) -> C { - C::from_block_cipher(cipher, nonce) - } -} - impl NewStreamCipher for C where - C: FromBlockCipherMut, + C: FromBlockCipher, C::BlockCipher: NewBlockCipher, { - type KeySize = <::BlockCipher as NewBlockCipher>::KeySize; - type NonceSize = ::NonceSize; + type KeySize = <::BlockCipher as NewBlockCipher>::KeySize; + type NonceSize = ::NonceSize; fn new(key: &Key, nonce: &Nonce) -> C { - C::from_block_cipher_mut( - <::BlockCipher as NewBlockCipher>::new(key), + C::from_block_cipher( + <::BlockCipher as NewBlockCipher>::new(key), nonce, ) } @@ -218,7 +189,7 @@ where .map_err(|_| InvalidKeyNonceLength) .map(|cipher| { let nonce = GenericArray::from_slice(nonce); - Self::from_block_cipher_mut(cipher, nonce) + Self::from_block_cipher(cipher, nonce) }) } } diff --git a/crypto-mac/Cargo.toml b/crypto-mac/Cargo.toml index c2a7121d8..7be37f044 100644 --- a/crypto-mac/Cargo.toml +++ b/crypto-mac/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crypto-mac" description = "Trait for Message Authentication Code (MAC) algorithms" -version = "0.10.0" +version = "0.11.0-pre" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" @@ -13,7 +13,7 @@ categories = ["cryptography", "no-std"] [dependencies] generic-array = "0.14" -cipher = { version = "0.2", optional = true, path = "../cipher" } +cipher = { version = "=0.3.0-pre", optional = true, path = "../cipher" } subtle = { version = "2", default-features = false } blobby = { version = "0.3", optional = true } diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index a33603937..b11faf574 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -13,10 +13,10 @@ edition = "2018" [dependencies] aead = { version = "0.3", optional = true, path = "../aead" } -cipher = { version = "0.2", optional = true, path = "../cipher" } +cipher = { version = "=0.3.0-pre", optional = true, path = "../cipher" } digest = { version = "0.9", optional = true, path = "../digest" } elliptic-curve = { version = "=0.7.0-pre", optional = true, path = "../elliptic-curve" } -mac = { version = "0.10", package = "crypto-mac", optional = true, path = "../crypto-mac" } +mac = { version = "=0.11.0-pre", package = "crypto-mac", optional = true, path = "../crypto-mac" } signature = { version = "1.2.0", optional = true, default-features = false, path = "../signature" } universal-hash = { version = "0.4", optional = true, path = "../universal-hash" } From d1c59a4cd0a4354213dc91635cf674c8018bd403 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 24 Nov 2020 06:34:21 -0800 Subject: [PATCH 0293/1461] cipher: delete legacy macros / re-exports (#371) These were previously retained to avoid breaking backwards compatibility. --- cipher/src/block.rs | 3 --- cipher/src/block/dev.rs | 22 ------------------ cipher/src/stream.rs | 3 --- cipher/src/stream/dev.rs | 49 ---------------------------------------- 4 files changed, 77 deletions(-) diff --git a/cipher/src/block.rs b/cipher/src/block.rs index 212642488..b0814f9a1 100644 --- a/cipher/src/block.rs +++ b/cipher/src/block.rs @@ -17,9 +17,6 @@ mod errors; pub use errors::InvalidKeyLength; -// TODO(tarcieri): remove these re-exports in favor of the toplevel one -pub use generic_array::{self, typenum::consts}; - use core::convert::TryInto; use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; diff --git a/cipher/src/block/dev.rs b/cipher/src/block/dev.rs index b518965a0..62c884a81 100644 --- a/cipher/src/block/dev.rs +++ b/cipher/src/block/dev.rs @@ -139,25 +139,3 @@ macro_rules! block_cipher_bench { } }; } - -// -// Below are deprecated legacy macro wrappers. They should be removed in v0.3. -// - -/// Define tests -#[macro_export] -#[deprecated(since = "0.2.2", note = "use `block_cipher_test!` instead")] -macro_rules! new_test { - ($name:ident, $test_name:expr, $cipher:ty) => { - $crate::block_cipher_test!($name, $test_name, $cipher); - }; -} - -/// Define benchmark -#[macro_export] -#[deprecated(since = "0.2.2", note = "use `block_cipher_bench!` instead")] -macro_rules! bench { - ($cipher:path, $key_len:expr) => { - $crate::block_cipher_bench!($cipher, $key_len); - }; -} diff --git a/cipher/src/stream.rs b/cipher/src/stream.rs index ccf29fca2..a1da32f74 100644 --- a/cipher/src/stream.rs +++ b/cipher/src/stream.rs @@ -10,9 +10,6 @@ mod errors; pub use errors::{InvalidKeyNonceLength, LoopError, OverflowError}; -// TODO(tarcieri): remove these re-exports in favor of the toplevel one -pub use generic_array::{self, typenum::consts}; - #[cfg(feature = "dev")] pub use blobby; diff --git a/cipher/src/stream/dev.rs b/cipher/src/stream/dev.rs index 5e7f3be08..92e5c9331 100644 --- a/cipher/src/stream/dev.rs +++ b/cipher/src/stream/dev.rs @@ -241,52 +241,3 @@ macro_rules! stream_cipher_async_bench { $crate::stream_cipher_async_bench!(encrypt_100000, decrypt_100000, $cipher, 100000); }; } - -// -// Below are deprecated legacy macro wrappers. They should be removed in v0.3. -// - -/// Test core functionality of synchronous stream cipher -#[macro_export] -#[deprecated(since = "0.2.2", note = "use `stream_cipher_sync_test!` instead")] -macro_rules! new_sync_test { - ($name:ident, $cipher:ty, $test_name:expr) => { - $crate::stream_cipher_sync_test!($name, $cipher, $test_name); - }; -} - -/// Test stream synchronous stream cipher seeking capabilities -#[macro_export] -#[deprecated(since = "0.2.2", note = "use `stream_cipher_seek_test!` instead")] -macro_rules! new_seek_test { - ($name:ident, $cipher:ty) => { - $crate::stream_cipher_seek_test!($name, $cipher); - }; -} - -/// Test core functionality of asynchronous stream cipher -#[macro_export] -#[deprecated(since = "0.2.2", note = "use `stream_cipher_async_test!` instead")] -macro_rules! new_async_test { - ($name:ident, $test_name:expr, $cipher:ty) => { - $crate::stream_cipher_async_test!($name, $test_name, $cipher); - }; -} - -/// Create synchronous stream cipher benchmarks -#[macro_export] -#[deprecated(since = "0.2.2", note = "use `stream_cipher_sync_bench!` instead")] -macro_rules! bench_sync { - ($name:ident, $cipher:path, $data_len:expr) => { - $crate::stream_cipher_sync_bench!($name, $cipher, $data_len); - }; -} - -/// Create asynchronous stream cipher benchmarks -#[macro_export] -#[deprecated(since = "0.2.2", note = "use `stream_cipher_async_bench!` instead")] -macro_rules! bench_async { - ($enc_name:ident, $dec_name:ident, $cipher:path, $data_len:expr) => { - $crate::stream_cipher_async_bench!($enc_name, $dec_name, $cipher, $data_len); - }; -} From 894409b94dec80a529be02f5683c16b29117cd83 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 24 Nov 2020 07:40:16 -0800 Subject: [PATCH 0294/1461] cipher: fix `cipher::block` test macros (#372) Have them import the new `BlockEncrypt` and `BlockDecrypt` traits. --- cipher/src/block/dev.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cipher/src/block/dev.rs b/cipher/src/block/dev.rs index 62c884a81..8c4f2fda9 100644 --- a/cipher/src/block/dev.rs +++ b/cipher/src/block/dev.rs @@ -9,7 +9,9 @@ macro_rules! block_cipher_test { ($name:ident, $test_name:expr, $cipher:ty) => { #[test] fn $name() { - use cipher::block::{dev::blobby::Blob3Iterator, BlockCipher, NewBlockCipher}; + use cipher::block::{ + dev::blobby::Blob3Iterator, BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher, + }; use cipher::generic_array::{typenum::Unsigned, GenericArray}; fn run_test(key: &[u8], pt: &[u8], ct: &[u8]) -> bool { @@ -111,7 +113,7 @@ macro_rules! block_cipher_bench { ($cipher:path, $key_len:expr) => { extern crate test; - use cipher::block::{BlockCipher, NewBlockCipher}; + use cipher::block::{BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher}; use test::Bencher; #[bench] From c85bc2d9543c30c14dc56c7db4efb88add88405e Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 27 Nov 2020 19:48:43 -0800 Subject: [PATCH 0295/1461] cipher: consolidate error types (#373) Consolidates the `block` and `stream` error types into a single toplevel `errors` module, consolidating `InvalidKeyLength` and `InvalidKeyNonceLength` into a single `InvalidLength` type. --- cipher/src/block.rs | 9 +++------ cipher/src/block/errors.rs | 14 -------------- cipher/src/{stream => }/errors.rs | 8 +++++--- cipher/src/lib.rs | 1 + cipher/src/stream.rs | 19 +++++++++---------- 5 files changed, 18 insertions(+), 33 deletions(-) delete mode 100644 cipher/src/block/errors.rs rename cipher/src/{stream => }/errors.rs (89%) diff --git a/cipher/src/block.rs b/cipher/src/block.rs index b0814f9a1..16205ba86 100644 --- a/cipher/src/block.rs +++ b/cipher/src/block.rs @@ -13,10 +13,7 @@ #[cfg_attr(docsrs, doc(cfg(feature = "dev")))] pub mod dev; -mod errors; - -pub use errors::InvalidKeyLength; - +use crate::errors::InvalidLength; use core::convert::TryInto; use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; @@ -41,9 +38,9 @@ pub trait NewBlockCipher: Sized { /// /// Default implementation will accept only keys with length equal to /// `KeySize`, but some ciphers can accept range of key lengths. - fn new_varkey(key: &[u8]) -> Result { + fn new_varkey(key: &[u8]) -> Result { if key.len() != Self::KeySize::to_usize() { - Err(InvalidKeyLength) + Err(InvalidLength) } else { Ok(Self::new(GenericArray::from_slice(key))) } diff --git a/cipher/src/block/errors.rs b/cipher/src/block/errors.rs deleted file mode 100644 index 0769aa2bd..000000000 --- a/cipher/src/block/errors.rs +++ /dev/null @@ -1,14 +0,0 @@ -use core::fmt; - -/// Error struct which used with `NewVarKey` -#[derive(Debug, Copy, Clone, Eq, PartialEq)] -pub struct InvalidKeyLength; - -impl fmt::Display for InvalidKeyLength { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str("invalid key length") - } -} - -#[cfg(feature = "std")] -impl std::error::Error for InvalidKeyLength {} diff --git a/cipher/src/stream/errors.rs b/cipher/src/errors.rs similarity index 89% rename from cipher/src/stream/errors.rs rename to cipher/src/errors.rs index 404822f95..089a7a077 100644 --- a/cipher/src/stream/errors.rs +++ b/cipher/src/errors.rs @@ -1,3 +1,5 @@ +//! Error types + use core::fmt; /// The error type returned when stream cipher has reached the end of a keystream. @@ -16,16 +18,16 @@ impl std::error::Error for LoopError {} /// The error type returned when key and/or nonce used in stream cipher /// initialization had an invalid length. #[derive(Copy, Clone, Debug)] -pub struct InvalidKeyNonceLength; +pub struct InvalidLength; -impl fmt::Display for InvalidKeyNonceLength { +impl fmt::Display for InvalidLength { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { f.write_str("Loop Error") } } #[cfg(feature = "std")] -impl std::error::Error for InvalidKeyNonceLength {} +impl std::error::Error for InvalidLength {} /// The error type returned when a cipher position can not be represented /// by the requested type. diff --git a/cipher/src/lib.rs b/cipher/src/lib.rs index d2cb92938..5a9dcd182 100644 --- a/cipher/src/lib.rs +++ b/cipher/src/lib.rs @@ -17,6 +17,7 @@ extern crate std; pub mod block; +pub mod errors; pub mod stream; pub use crate::{ diff --git a/cipher/src/stream.rs b/cipher/src/stream.rs index a1da32f74..f5daf01e3 100644 --- a/cipher/src/stream.rs +++ b/cipher/src/stream.rs @@ -6,14 +6,13 @@ #[cfg(feature = "dev")] mod dev; -mod errors; - -pub use errors::{InvalidKeyNonceLength, LoopError, OverflowError}; - #[cfg(feature = "dev")] pub use blobby; -use crate::block::{BlockCipher, NewBlockCipher}; +use crate::{ + block::{BlockCipher, NewBlockCipher}, + errors::{InvalidLength, LoopError, OverflowError}, +}; use core::convert::{TryFrom, TryInto}; use generic_array::typenum::Unsigned; use generic_array::{ArrayLength, GenericArray}; @@ -39,11 +38,11 @@ pub trait NewStreamCipher: Sized { /// Create new stream cipher instance from variable length key and nonce. #[inline] - fn new_var(key: &[u8], nonce: &[u8]) -> Result { + fn new_var(key: &[u8], nonce: &[u8]) -> Result { let kl = Self::KeySize::to_usize(); let nl = Self::NonceSize::to_usize(); if key.len() != kl || nonce.len() != nl { - Err(InvalidKeyNonceLength) + Err(InvalidLength) } else { let key = GenericArray::from_slice(key); let nonce = GenericArray::from_slice(nonce); @@ -178,12 +177,12 @@ where ) } - fn new_var(key: &[u8], nonce: &[u8]) -> Result { + fn new_var(key: &[u8], nonce: &[u8]) -> Result { if nonce.len() != Self::NonceSize::USIZE { - Err(InvalidKeyNonceLength) + Err(InvalidLength) } else { C::BlockCipher::new_varkey(key) - .map_err(|_| InvalidKeyNonceLength) + .map_err(|_| InvalidLength) .map(|cipher| { let nonce = GenericArray::from_slice(nonce); Self::from_block_cipher(cipher, nonce) From ef18c99722c93a68e7386e2efc9c32c4ed41bed4 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 2 Dec 2020 15:55:04 -0800 Subject: [PATCH 0296/1461] elliptic-curve: remove Deref impl from PublicKey; add ::as_affine() (#374) Types with `Deref` impls shouldn't have inherent methods, however `PublicKey` has several. This makes `PublicKey` more than a "smart pointer" type which `Deref` is intended to be used with: it handles encoding and conversions in a way that can be shared across curves. It already provided an `AsRef` impl for obtaining the `AffinePoint`, however this PR also adds a new inherent `as_affine` method as well. --- elliptic-curve/src/public_key.rs | 28 +++++++++------------------- elliptic-curve/src/sec1.rs | 2 +- 2 files changed, 10 insertions(+), 20 deletions(-) diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index 82a1a87a4..8ba8841e2 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -11,7 +11,7 @@ use crate::{ use core::{ convert::{TryFrom, TryInto}, fmt::Debug, - ops::{Add, Deref}, + ops::Add, }; use ff::PrimeField; use generic_array::ArrayLength; @@ -56,6 +56,13 @@ where Self { point } } + /// Borrow the inner [`AffinePoint`] from this [`PublicKey`]. + /// + /// In ECC, public keys are elliptic curve points. + pub fn as_affine(&self) -> &AffinePoint { + &self.point + } + /// Convert this [`PublicKey`] to a [`ProjectivePoint`] for the given curve pub fn to_projective(&self) -> ProjectivePoint { self.point.clone().into() @@ -73,24 +80,7 @@ where UncompressedPointSize: ArrayLength, { fn as_ref(&self) -> &AffinePoint { - &self.point - } -} - -impl Deref for PublicKey -where - C: Curve + ProjectiveArithmetic, - FieldBytes: From> + for<'r> From<&'r Scalar>, - Scalar: PrimeField>, - AffinePoint: Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, - ProjectivePoint: From>, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, -{ - type Target = AffinePoint; - - fn deref(&self) -> &AffinePoint { - &self.point + self.as_affine() } } diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index b6925b93f..577d46eb2 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -224,7 +224,7 @@ where where T: FromEncodedPoint, { - T::from_encoded_point(self).ok_or_else(|| Error) + T::from_encoded_point(self).ok_or(Error) } /// Get the SEC1 tag for this [`EncodedPoint`] From ff1371791a77b8163bcf37fcfcaf6ceb595b133c Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 2 Dec 2020 16:30:49 -0800 Subject: [PATCH 0297/1461] elliptic-curve: add SecretKey::secret_value method (#375) Method for exposing the inner (generic) secret value for a SecretKey --- elliptic-curve/src/secret_key.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 6c340e2d4..e05e4d22c 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -120,6 +120,17 @@ where self.secret_value.clone().into() } + /// Borrow the inner generic secret value. + /// + /// # Warning + /// + /// This value is key material. + /// + /// Please treat it with the care it deserves! + pub fn secret_value(&self) -> &C::Secret { + &self.secret_value + } + /// Borrow the inner secret [`Scalar`] value. /// /// # Warning From 77eb39745ac3520f10c8a78e5e69762a06626910 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 2 Dec 2020 16:57:12 -0800 Subject: [PATCH 0298/1461] elliptic-curve: rename PublicKey::from_sec1_bytes (#376) This has better symmetry with SecretKey::from_bytes, and also leaves room to add additional public key encodings (e.g. SubjectPublicKeyInfo) --- elliptic-curve/src/public_key.rs | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index 8ba8841e2..74ad8bc5b 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -44,18 +44,23 @@ where UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { - /// Initialize [`PublicKey`] from a SEC1-encoded public key - pub fn new(bytes: &[u8]) -> Result { - EncodedPoint::from_bytes(bytes) - .map_err(|_| Error) - .and_then(TryInto::try_into) - } - /// Convert an [`AffinePoint`] into a [`PublicKey`] pub fn from_affine(point: AffinePoint) -> Self { Self { point } } + /// Decode [`PublicKey`] (compressed or uncompressed) from the + /// `Elliptic-Curve-Point-to-Octet-String` encoding described in + /// SEC 1: Elliptic Curve Cryptography (Version 2.0) section + /// 2.3.3 (page 10). + /// + /// + pub fn from_sec1_bytes(bytes: &[u8]) -> Result { + EncodedPoint::from_bytes(bytes) + .map_err(|_| Error) + .and_then(TryInto::try_into) + } + /// Borrow the inner [`AffinePoint`] from this [`PublicKey`]. /// /// In ECC, public keys are elliptic curve points. From 71f6f53f0ac67ac6ba9dfb46aff7eb20df28bafe Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 2 Dec 2020 17:20:31 -0800 Subject: [PATCH 0299/1461] elliptic-curve: impl `Copy`, `Eq`, and `PartialEq` for `PublicKey` (#377) --- elliptic-curve/src/public_key.rs | 41 ++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index 74ad8bc5b..609ed6571 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -185,3 +185,44 @@ where self.point.to_encoded_point(compress) } } + +impl Copy for PublicKey +where + C: Curve + ProjectiveArithmetic, + FieldBytes: From> + for<'r> From<&'r Scalar>, + Scalar: PrimeField>, + AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, + ProjectivePoint: From>, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ +} + +impl Eq for PublicKey +where + C: Curve + ProjectiveArithmetic, + FieldBytes: From> + for<'r> From<&'r Scalar>, + Scalar: PrimeField>, + AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, + ProjectivePoint: From>, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ +} + +impl PartialEq for PublicKey +where + C: Curve + ProjectiveArithmetic, + FieldBytes: From> + for<'r> From<&'r Scalar>, + Scalar: PrimeField>, + AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, + ProjectivePoint: From>, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + fn eq(&self, other: &Self) -> bool { + // TODO(tarcieri): more efficient implementation? + // This is implemented this way to reduce bounds for `AffinePoint` + self.to_encoded_point(false) == other.to_encoded_point(false) + } +} From ea5106e0cd0f47a5ee11af0d7313f1f1dc0a5a9f Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 2 Dec 2020 18:06:04 -0800 Subject: [PATCH 0300/1461] elliptic-curve: simplify PublicKey trait bounds (#378) Decouples PublicKey from SEC1 encoding-related concerns, which allows the trait bounds for anything which interacts with PublicKeys to be dramatically simplified. --- elliptic-curve/src/ecdh.rs | 20 ++---------- elliptic-curve/src/public_key.rs | 53 ++++++++++++-------------------- elliptic-curve/src/secret_key.rs | 11 ++----- 3 files changed, 25 insertions(+), 59 deletions(-) diff --git a/elliptic-curve/src/ecdh.rs b/elliptic-curve/src/ecdh.rs index bf83d991c..252d9cd5e 100644 --- a/elliptic-curve/src/ecdh.rs +++ b/elliptic-curve/src/ecdh.rs @@ -24,9 +24,7 @@ use crate::{ consts::U1, public_key::PublicKey, scalar::NonZeroScalar, - sec1::{ - EncodedPoint, FromEncodedPoint, ToEncodedPoint, UncompressedPointSize, UntaggedPointSize, - }, + sec1::{EncodedPoint, ToEncodedPoint, UncompressedPointSize, UntaggedPointSize}, weierstrass::Curve, AffinePoint, FieldBytes, ProjectiveArithmetic, ProjectivePoint, Scalar, }; @@ -55,13 +53,7 @@ where C: Curve + ProjectiveArithmetic, FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField> + Clone + Zeroize, - AffinePoint: Clone - + Debug - + Default - + Into> - + FromEncodedPoint - + ToEncodedPoint - + Zeroize, + AffinePoint: Copy + Clone + Debug + ToEncodedPoint + Zeroize, ProjectivePoint: From>, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, @@ -94,13 +86,7 @@ where C: Curve + ProjectiveArithmetic, FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField> + Clone + Zeroize, - AffinePoint: Clone - + Debug - + Default - + Into> - + FromEncodedPoint - + ToEncodedPoint - + Zeroize, + AffinePoint: Copy + Clone + Debug + ToEncodedPoint + Zeroize, ProjectivePoint: From>, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index 609ed6571..6e0e35bce 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -20,16 +20,13 @@ use generic_array::ArrayLength; /// /// These are a thin wrapper around [`AffinePoint`] which simplifies /// encoding/decoding. -#[derive(Clone, Debug)] +#[derive(Copy, Clone, Debug)] pub struct PublicKey where C: Curve + ProjectiveArithmetic, FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField>, - AffinePoint: Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, - ProjectivePoint: From>, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + AffinePoint: Copy + Clone + Debug, { point: AffinePoint, } @@ -39,10 +36,7 @@ where C: Curve + ProjectiveArithmetic, FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField>, - AffinePoint: Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, - ProjectivePoint: From>, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + AffinePoint: Copy + Clone + Debug, { /// Convert an [`AffinePoint`] into a [`PublicKey`] pub fn from_affine(point: AffinePoint) -> Self { @@ -55,7 +49,12 @@ where /// 2.3.3 (page 10). /// /// - pub fn from_sec1_bytes(bytes: &[u8]) -> Result { + pub fn from_sec1_bytes(bytes: &[u8]) -> Result + where + Self: TryFrom, Error = Error>, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, + { EncodedPoint::from_bytes(bytes) .map_err(|_| Error) .and_then(TryInto::try_into) @@ -69,7 +68,10 @@ where } /// Convert this [`PublicKey`] to a [`ProjectivePoint`] for the given curve - pub fn to_projective(&self) -> ProjectivePoint { + pub fn to_projective(&self) -> ProjectivePoint + where + ProjectivePoint: From>, + { self.point.clone().into() } } @@ -79,10 +81,7 @@ where C: Curve + ProjectiveArithmetic, FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField>, - AffinePoint: Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, - ProjectivePoint: From>, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + AffinePoint: Copy + Clone + Debug, { fn as_ref(&self) -> &AffinePoint { self.as_affine() @@ -94,7 +93,7 @@ where C: Curve + ProjectiveArithmetic, FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField>, - AffinePoint: Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, + AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, ProjectivePoint: From>, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, @@ -111,7 +110,7 @@ where C: Curve + ProjectiveArithmetic, FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField>, - AffinePoint: Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, + AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, ProjectivePoint: From>, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, @@ -128,7 +127,7 @@ where C: Curve + ProjectiveArithmetic + point::Compression, FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField>, - AffinePoint: Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, + AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, ProjectivePoint: From>, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, @@ -143,7 +142,7 @@ where C: Curve + ProjectiveArithmetic + point::Compression, FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField>, - AffinePoint: Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, + AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, ProjectivePoint: From>, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, @@ -158,7 +157,7 @@ where C: Curve + ProjectiveArithmetic, FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField>, - AffinePoint: Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, + AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, ProjectivePoint: From>, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, @@ -174,7 +173,7 @@ where C: Curve + ProjectiveArithmetic, FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField>, - AffinePoint: Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, + AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, ProjectivePoint: From>, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, @@ -186,18 +185,6 @@ where } } -impl Copy for PublicKey -where - C: Curve + ProjectiveArithmetic, - FieldBytes: From> + for<'r> From<&'r Scalar>, - Scalar: PrimeField>, - AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, - ProjectivePoint: From>, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, -{ -} - impl Eq for PublicKey where C: Curve + ProjectiveArithmetic, diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index e05e4d22c..48e74e107 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -17,16 +17,12 @@ use zeroize::Zeroize; #[cfg(feature = "arithmetic")] use crate::{ - consts::U1, ff::PrimeField, - generic_array::ArrayLength, group::{Curve as _, Group}, - ops::Add, public_key::PublicKey, rand_core::{CryptoRng, RngCore}, scalar::{NonZeroScalar, Scalar}, - sec1::{FromEncodedPoint, ToEncodedPoint, UncompressedPointSize, UntaggedPointSize}, - weierstrass, AffinePoint, ProjectiveArithmetic, ProjectivePoint, + weierstrass, AffinePoint, ProjectiveArithmetic, }; /// Inner value stored by a [`SecretKey`]. @@ -157,10 +153,7 @@ where C: weierstrass::Curve + ProjectiveArithmetic + SecretValue>, FieldBytes: From> + for<'a> From<&'a Scalar>, Scalar: PrimeField> + Zeroize, - AffinePoint: Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, - ProjectivePoint: From>, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + AffinePoint: Copy + Clone + Debug + Default, { PublicKey::from_affine((C::ProjectivePoint::generator() * self.secret_scalar()).to_affine()) } From fdff330484c9d03f67ba1eda533a24e757f3e204 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 2 Dec 2020 19:01:42 -0800 Subject: [PATCH 0301/1461] elliptic-curve: add explicit Copy impl for PublicKey (#379) The derived impl appears to have the incorrect bounds --- elliptic-curve/src/public_key.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index 6e0e35bce..c48ea70df 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -20,7 +20,7 @@ use generic_array::ArrayLength; /// /// These are a thin wrapper around [`AffinePoint`] which simplifies /// encoding/decoding. -#[derive(Copy, Clone, Debug)] +#[derive(Clone, Debug)] pub struct PublicKey where C: Curve + ProjectiveArithmetic, @@ -185,6 +185,15 @@ where } } +impl Copy for PublicKey +where + C: Curve + ProjectiveArithmetic, + FieldBytes: From> + for<'r> From<&'r Scalar>, + Scalar: PrimeField>, + AffinePoint: Copy + Clone + Debug, +{ +} + impl Eq for PublicKey where C: Curve + ProjectiveArithmetic, From 9fc65e992de4ea0446bbdc863619d21354b87687 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 4 Dec 2020 13:03:06 -0800 Subject: [PATCH 0302/1461] elliptic-curve: PKCS#8 support for `SecretKey` (#381) Adds initial support for parsing PKCS#8-encoded ECC secret keys. This is presently somewhat difficult to test within this crate (which should be addressed regardless) as it relies on generic parameters of a curve implementation, however this has been tested concretely against the `p256` crate which has tests that exercise it in this PR: https://github.com/RustCrypto/elliptic-curves/pull/243 --- Cargo.lock | 15 +++++--- Cargo.toml | 4 +++ elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/ecdh.rs | 3 +- elliptic-curve/src/error.rs | 7 ++++ elliptic-curve/src/lib.rs | 26 ++++++++++---- elliptic-curve/src/secret_key.rs | 61 +++++++++++++++++++++++++++++++- 7 files changed, 104 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dd3e6aa61..c206ef0ed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -93,9 +93,8 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fc33f77ab0b4232f30cb9049a156775c5ad814b030e929d234d14cd6d7ec17f" +version = "0.3.0-pre" +source = "git+https://github.com/RustCrypto/utils.git#a9ebedcd9be0af538c9aef319d2025fa607e9566" [[package]] name = "cpuid-bool" @@ -148,12 +147,12 @@ name = "elliptic-curve" version = "0.7.0-pre" dependencies = [ "bitvec", - "const-oid", "digest 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "ff", "generic-array 0.14.4", "group", "hex-literal", + "pkcs8", "rand_core", "subtle", "zeroize", @@ -261,6 +260,14 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +[[package]] +name = "pkcs8" +version = "0.0.0" +source = "git+https://github.com/RustCrypto/utils.git#a9ebedcd9be0af538c9aef319d2025fa607e9566" +dependencies = [ + "const-oid", +] + [[package]] name = "proc-macro-hack" version = "0.5.18" diff --git a/Cargo.toml b/Cargo.toml index 943b0d7a1..31f01b7fe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,3 +10,7 @@ members = [ "signature/async", "universal-hash", ] + +[patch.crates-io] +const-oid = { git = "https://github.com/RustCrypto/utils.git" } +pkcs8 = { git = "https://github.com/RustCrypto/utils.git" } diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 54b51d99f..97d2a551a 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -20,7 +20,7 @@ digest = { version = "0.9", optional = true } ff = { version = "0.8", optional = true, default-features = false } group = { version = "0.8", optional = true, default-features = false } generic-array = { version = "0.14", default-features = false } -oid = { package = "const-oid", version = "0.2", optional = true } +pkcs8 = { version = "0", optional = true } rand_core = { version = "0.5", default-features = false } subtle = { version = "2.3", default-features = false } zeroize = { version = "1", optional = true, default-features = false } diff --git a/elliptic-curve/src/ecdh.rs b/elliptic-curve/src/ecdh.rs index 252d9cd5e..e9a717771 100644 --- a/elliptic-curve/src/ecdh.rs +++ b/elliptic-curve/src/ecdh.rs @@ -75,7 +75,8 @@ where /// Compute a Diffie-Hellman shared secret from an ephemeral secret and the /// public key of the other participant in the exchange. pub fn diffie_hellman(&self, public_key: &PublicKey) -> SharedSecret { - let shared_secret = public_key.to_projective() * &self.scalar; + #[allow(clippy::op_ref)] + let shared_secret = public_key.to_projective() * &*self.scalar; // SharedSecret::new expects an uncompressed point SharedSecret::new(shared_secret.to_affine().to_encoded_point(false)) } diff --git a/elliptic-curve/src/error.rs b/elliptic-curve/src/error.rs index 0a1ab14a8..5657ae359 100644 --- a/elliptic-curve/src/error.rs +++ b/elliptic-curve/src/error.rs @@ -12,5 +12,12 @@ impl Display for Error { } } +#[cfg(feature = "pkcs8")] +impl From for Error { + fn from(_: pkcs8::Error) -> Error { + Error + } +} + #[cfg(feature = "std")] impl std::error::Error for Error {} diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 7617d044c..1e71c3f35 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -71,8 +71,8 @@ pub use group::{self, Group}; #[cfg(feature = "digest")] pub use digest::{self, Digest}; -#[cfg(feature = "oid")] -pub use oid; +#[cfg(feature = "pkcs8")] +pub use pkcs8; #[cfg(feature = "zeroize")] pub use secret_key::SecretKey; @@ -82,6 +82,13 @@ pub use zeroize; use core::{fmt::Debug, ops::Add}; use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; +/// Algorithm [`ObjectIdentifier`] for elliptic curve public key cryptography. +/// +#[cfg(feature = "pkcs8")] +#[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))] +pub const ALGORITHM_OID: pkcs8::ObjectIdentifier = + pkcs8::ObjectIdentifier::new(&[1, 2, 840, 10045, 2, 1]); + /// Elliptic curve. /// /// This trait is intended to be impl'd by a ZST which represents a concrete @@ -115,10 +122,15 @@ pub trait FromDigest { D: Digest; } -/// Associate an object identifier (OID) with a curve -#[cfg(feature = "oid")] -#[cfg_attr(docsrs, doc(cfg(feature = "oid")))] -pub trait Identifier: Curve { +/// Associate an [`ObjectIdentifier`][`pkcs8::ObjectIdentifier`] (OID) with an +/// elliptic curve algorithm implementation. +/// +/// This is used as as the `parameters` of an `AlgorithmIdentifier` as +/// described in RFC 5280 Section 4.1.1.2: +/// +#[cfg(feature = "pkcs8")] +#[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))] +pub trait AlgorithmParameters: Curve { /// Object Identifier (OID) for this curve - const OID: oid::ObjectIdentifier; + const OID: pkcs8::ObjectIdentifier; } diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 48e74e107..a514335ba 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -25,6 +25,9 @@ use crate::{ weierstrass, AffinePoint, ProjectiveArithmetic, }; +#[cfg(feature = "pkcs8")] +use crate::{generic_array::typenum::Unsigned, AlgorithmParameters, ALGORITHM_OID}; + /// Inner value stored by a [`SecretKey`]. pub trait SecretValue: Curve { /// Inner secret value. @@ -100,7 +103,7 @@ where Self { secret_value } } - /// Deserialize this secret key from a bytestring + /// Deserialize raw private scalar as a big endian integer pub fn from_bytes(bytes: impl AsRef<[u8]>) -> Result { bytes .as_ref() @@ -111,6 +114,62 @@ where .ok_or(Error) } + /// Deserialize PKCS#8-encoded private key from ASN.1 DER + #[cfg(feature = "pkcs8")] + #[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))] + pub fn from_pkcs8_der(bytes: &[u8]) -> Result + where + C: AlgorithmParameters, + { + let private_key_info = pkcs8::PrivateKeyInfo::from_der(bytes)?; + + if private_key_info.algorithm.oid != ALGORITHM_OID + || private_key_info.algorithm.parameters != Some(C::OID) + { + return Err(Error); + } + + Self::from_pkcs8_private_key(private_key_info.private_key) + } + + /// Parse the `private_key` field of a PKCS#8-encoded private key's + /// `PrivateKeyInfo`. + #[cfg(feature = "pkcs8")] + #[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))] + fn from_pkcs8_private_key(bytes: &[u8]) -> Result + where + C: AlgorithmParameters, + { + // Ensure private key is AT LEAST as long as a scalar field element + // for this curve along with the following overhead: + // + // 2-bytes: SEQUENCE header: tag byte + length + // 3-bytes: INTEGER version: tag byte + length + value + // 2-bytes: OCTET STRING header: tag byte + length + if bytes.len() < 2 + 3 + 2 + C::FieldSize::to_usize() { + return Err(Error); + } + + // Check key begins with ASN.1 DER SEQUENCE tag (0x30) + valid length, + // where the length omits the leading SEQUENCE header (tag + length byte) + if bytes[0] != 0x30 || bytes[1].checked_add(2).unwrap() as usize != bytes.len() { + return Err(Error); + } + + // Validate version field (ASN.1 DER INTEGER value: 1) + if bytes[2..=4] != [0x02, 0x01, 0x01] { + return Err(Error); + } + + // Validate ASN.1 DER OCTET STRING header: tag (0x04) + valid length + if bytes[5] != 0x04 || bytes[6] as usize != C::FieldSize::to_usize() { + return Err(Error); + } + + // TODO(tarcieri): extract and validate public key + Ok(Self::from_bytes(&bytes[7..(7 + C::FieldSize::to_usize())])?) + } + /// Expose the byte serialization of the value this [`SecretKey`] wraps pub fn to_bytes(&self) -> FieldBytes { self.secret_value.clone().into() From 8f8a4be95733a14639612dc3921cd3ca6d722bd1 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 4 Dec 2020 14:08:33 -0800 Subject: [PATCH 0303/1461] elliptic-curve: PKCS#8 PEM support (#382) Support for decoding PEM-encoded PKCS#8 `SecretKey`s --- .github/workflows/elliptic-curve.yml | 2 + Cargo.lock | 15 +++++++- elliptic-curve/Cargo.toml | 1 + elliptic-curve/src/secret_key.rs | 57 +++++++++++++++++++++++----- 4 files changed, 64 insertions(+), 11 deletions(-) diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index 3da08cdd0..78dc890dc 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -38,6 +38,8 @@ jobs: - run: cargo build --no-default-features --release --target ${{ matrix.target }} - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features arithmetic - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features ecdh + - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features pem + - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features pkcs8 - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features zeroize test: runs-on: ubuntu-latest diff --git a/Cargo.lock b/Cargo.lock index c206ef0ed..5cbf5b989 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -94,7 +94,7 @@ dependencies = [ [[package]] name = "const-oid" version = "0.3.0-pre" -source = "git+https://github.com/RustCrypto/utils.git#a9ebedcd9be0af538c9aef319d2025fa607e9566" +source = "git+https://github.com/RustCrypto/utils.git#8285d34b124c726a350e6108f9fb284787fd3976" [[package]] name = "cpuid-bool" @@ -263,9 +263,11 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "pkcs8" version = "0.0.0" -source = "git+https://github.com/RustCrypto/utils.git#a9ebedcd9be0af538c9aef319d2025fa607e9566" +source = "git+https://github.com/RustCrypto/utils.git#8285d34b124c726a350e6108f9fb284787fd3976" dependencies = [ "const-oid", + "subtle-encoding", + "zeroize", ] [[package]] @@ -350,6 +352,15 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "343f3f510c2915908f155e94f17220b19ccfacf2a64a2a5d8004f2c3e311e7fd" +[[package]] +name = "subtle-encoding" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dcb1ed7b8330c5eed5441052651dd7a12c75e2ed88f2ec024ae1fa3a5e59945" +dependencies = [ + "zeroize", +] + [[package]] name = "syn" version = "1.0.40" diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 97d2a551a..45495ba77 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -33,6 +33,7 @@ default = ["arithmetic"] alloc = [] arithmetic = ["bitvec", "ff", "group"] ecdh = ["arithmetic", "zeroize"] +pem = ["pkcs8/pem"] std = ["alloc"] [package.metadata.docs.rs] diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index a514335ba..d9252cc9d 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -28,6 +28,9 @@ use crate::{ #[cfg(feature = "pkcs8")] use crate::{generic_array::typenum::Unsigned, AlgorithmParameters, ALGORITHM_OID}; +#[cfg(feature = "pem")] +use core::str::FromStr; + /// Inner value stored by a [`SecretKey`]. pub trait SecretValue: Curve { /// Inner secret value. @@ -115,31 +118,51 @@ where } /// Deserialize PKCS#8-encoded private key from ASN.1 DER + /// (binary format). #[cfg(feature = "pkcs8")] #[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))] pub fn from_pkcs8_der(bytes: &[u8]) -> Result where C: AlgorithmParameters, { - let private_key_info = pkcs8::PrivateKeyInfo::from_der(bytes)?; - - if private_key_info.algorithm.oid != ALGORITHM_OID - || private_key_info.algorithm.parameters != Some(C::OID) - { - return Err(Error); - } + Self::from_pkcs8_private_key_info(pkcs8::PrivateKeyInfo::from_der(bytes)?) + } - Self::from_pkcs8_private_key(private_key_info.private_key) + /// Deserialize PKCS#8-encoded private key from PEM. + /// + /// Keys in this format begin with the following delimiter: + /// + /// ```text + /// -----BEGIN PRIVATE KEY----- + /// ``` + #[cfg(feature = "pem")] + #[cfg_attr(docsrs, doc(cfg(feature = "pem")))] + pub fn from_pkcs8_pem(s: &str) -> Result + where + C: AlgorithmParameters, + { + let pkcs8_doc = pkcs8::Document::from_pem(s)?; + Self::from_pkcs8_private_key_info(pkcs8_doc.private_key_info()) } /// Parse the `private_key` field of a PKCS#8-encoded private key's /// `PrivateKeyInfo`. #[cfg(feature = "pkcs8")] #[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))] - fn from_pkcs8_private_key(bytes: &[u8]) -> Result + fn from_pkcs8_private_key_info( + private_key_info: pkcs8::PrivateKeyInfo<'_>, + ) -> Result where C: AlgorithmParameters, { + if private_key_info.algorithm.oid != ALGORITHM_OID + || private_key_info.algorithm.parameters != Some(C::OID) + { + return Err(Error); + } + + let bytes = private_key_info.private_key; + // Ensure private key is AT LEAST as long as a scalar field element // for this curve along with the following overhead: // @@ -231,11 +254,27 @@ where } } +#[cfg(feature = "pem")] +#[cfg_attr(docsrs, doc(cfg(feature = "pem")))] +impl FromStr for SecretKey +where + C: Curve + AlgorithmParameters + SecretValue, + C::Secret: Clone + Zeroize, + FieldBytes: From, +{ + type Err = Error; + + fn from_str(s: &str) -> Result { + Self::from_pkcs8_pem(s) + } +} + impl Debug for SecretKey where C: Curve + SecretValue, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // TODO(tarcieri): use `debug_struct` and `finish_non_exhaustive` when stable write!(f, "SecretKey<{:?}>{{ ... }}", C::default()) } } From cd6c0a006ca570c32cdb3a72ffbd6796231a162c Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 4 Dec 2020 14:41:04 -0800 Subject: [PATCH 0304/1461] elliptic-curve: impl FromPkcs8 trait on SecretKey (#383) Added in this `pkcs8` PR: https://github.com/RustCrypto/utils/pull/96 --- Cargo.lock | 4 +- elliptic-curve/src/secret_key.rs | 133 +++++++++++++------------------ 2 files changed, 58 insertions(+), 79 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5cbf5b989..8356458bc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -94,7 +94,7 @@ dependencies = [ [[package]] name = "const-oid" version = "0.3.0-pre" -source = "git+https://github.com/RustCrypto/utils.git#8285d34b124c726a350e6108f9fb284787fd3976" +source = "git+https://github.com/RustCrypto/utils.git#4183dbfdab9797d2b90e11e19b8750b426d2e179" [[package]] name = "cpuid-bool" @@ -263,7 +263,7 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "pkcs8" version = "0.0.0" -source = "git+https://github.com/RustCrypto/utils.git#8285d34b124c726a350e6108f9fb284787fd3976" +source = "git+https://github.com/RustCrypto/utils.git#4183dbfdab9797d2b90e11e19b8750b426d2e179" dependencies = [ "const-oid", "subtle-encoding", diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index d9252cc9d..e8d9f62b2 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -27,6 +27,8 @@ use crate::{ #[cfg(feature = "pkcs8")] use crate::{generic_array::typenum::Unsigned, AlgorithmParameters, ALGORITHM_OID}; +#[cfg(feature = "pkcs8")] +use pkcs8::FromPkcs8; #[cfg(feature = "pem")] use core::str::FromStr; @@ -117,82 +119,6 @@ where .ok_or(Error) } - /// Deserialize PKCS#8-encoded private key from ASN.1 DER - /// (binary format). - #[cfg(feature = "pkcs8")] - #[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))] - pub fn from_pkcs8_der(bytes: &[u8]) -> Result - where - C: AlgorithmParameters, - { - Self::from_pkcs8_private_key_info(pkcs8::PrivateKeyInfo::from_der(bytes)?) - } - - /// Deserialize PKCS#8-encoded private key from PEM. - /// - /// Keys in this format begin with the following delimiter: - /// - /// ```text - /// -----BEGIN PRIVATE KEY----- - /// ``` - #[cfg(feature = "pem")] - #[cfg_attr(docsrs, doc(cfg(feature = "pem")))] - pub fn from_pkcs8_pem(s: &str) -> Result - where - C: AlgorithmParameters, - { - let pkcs8_doc = pkcs8::Document::from_pem(s)?; - Self::from_pkcs8_private_key_info(pkcs8_doc.private_key_info()) - } - - /// Parse the `private_key` field of a PKCS#8-encoded private key's - /// `PrivateKeyInfo`. - #[cfg(feature = "pkcs8")] - #[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))] - fn from_pkcs8_private_key_info( - private_key_info: pkcs8::PrivateKeyInfo<'_>, - ) -> Result - where - C: AlgorithmParameters, - { - if private_key_info.algorithm.oid != ALGORITHM_OID - || private_key_info.algorithm.parameters != Some(C::OID) - { - return Err(Error); - } - - let bytes = private_key_info.private_key; - - // Ensure private key is AT LEAST as long as a scalar field element - // for this curve along with the following overhead: - // - // 2-bytes: SEQUENCE header: tag byte + length - // 3-bytes: INTEGER version: tag byte + length + value - // 2-bytes: OCTET STRING header: tag byte + length - if bytes.len() < 2 + 3 + 2 + C::FieldSize::to_usize() { - return Err(Error); - } - - // Check key begins with ASN.1 DER SEQUENCE tag (0x30) + valid length, - // where the length omits the leading SEQUENCE header (tag + length byte) - if bytes[0] != 0x30 || bytes[1].checked_add(2).unwrap() as usize != bytes.len() { - return Err(Error); - } - - // Validate version field (ASN.1 DER INTEGER value: 1) - if bytes[2..=4] != [0x02, 0x01, 0x01] { - return Err(Error); - } - - // Validate ASN.1 DER OCTET STRING header: tag (0x04) + valid length - if bytes[5] != 0x04 || bytes[6] as usize != C::FieldSize::to_usize() { - return Err(Error); - } - - // TODO(tarcieri): extract and validate public key - Ok(Self::from_bytes(&bytes[7..(7 + C::FieldSize::to_usize())])?) - } - /// Expose the byte serialization of the value this [`SecretKey`] wraps pub fn to_bytes(&self) -> FieldBytes { self.secret_value.clone().into() @@ -254,6 +180,59 @@ where } } +#[cfg(feature = "pkcs8")] +#[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))] +impl FromPkcs8 for SecretKey +where + C: Curve + AlgorithmParameters + SecretValue, + C::Secret: Clone + Zeroize, + FieldBytes: From, +{ + fn from_pkcs8_private_key_info( + private_key_info: pkcs8::PrivateKeyInfo<'_>, + ) -> pkcs8::Result + where + C: AlgorithmParameters, + { + if private_key_info.algorithm.oid != ALGORITHM_OID + || private_key_info.algorithm.parameters != Some(C::OID) + { + return Err(pkcs8::Error); + } + + let bytes = private_key_info.private_key; + + // Ensure private key is AT LEAST as long as a scalar field element + // for this curve along with the following overhead: + // + // 2-bytes: SEQUENCE header: tag byte + length + // 3-bytes: INTEGER version: tag byte + length + value + // 2-bytes: OCTET STRING header: tag byte + length + if bytes.len() < 2 + 3 + 2 + C::FieldSize::to_usize() { + return Err(pkcs8::Error); + } + + // Check key begins with ASN.1 DER SEQUENCE tag (0x30) + valid length, + // where the length omits the leading SEQUENCE header (tag + length byte) + if bytes[0] != 0x30 || bytes[1].checked_add(2).unwrap() as usize != bytes.len() { + return Err(pkcs8::Error); + } + + // Validate version field (ASN.1 DER INTEGER value: 1) + if bytes[2..=4] != [0x02, 0x01, 0x01] { + return Err(pkcs8::Error); + } + + // Validate ASN.1 DER OCTET STRING header: tag (0x04) + valid length + if bytes[5] != 0x04 || bytes[6] as usize != C::FieldSize::to_usize() { + return Err(pkcs8::Error); + } + + // TODO(tarcieri): extract and validate public key + Self::from_bytes(&bytes[7..(7 + C::FieldSize::to_usize())]).map_err(|_| pkcs8::Error) + } +} + #[cfg(feature = "pem")] #[cfg_attr(docsrs, doc(cfg(feature = "pem")))] impl FromStr for SecretKey @@ -265,7 +244,7 @@ where type Err = Error; fn from_str(s: &str) -> Result { - Self::from_pkcs8_pem(s) + Self::from_pkcs8_pem(s).map_err(|_| Error) } } From 5d5754259a6801f5e32373e635be6865ac510e73 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 4 Dec 2020 15:00:08 -0800 Subject: [PATCH 0305/1461] elliptic-curve: minor documentation improvement (#384) --- elliptic-curve/src/error.rs | 2 +- elliptic-curve/src/lib.rs | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/elliptic-curve/src/error.rs b/elliptic-curve/src/error.rs index 5657ae359..15da4f90f 100644 --- a/elliptic-curve/src/error.rs +++ b/elliptic-curve/src/error.rs @@ -1,4 +1,4 @@ -//! Error type +//! Error type. use core::fmt::{self, Display}; diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 1e71c3f35..aea1078b8 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -82,8 +82,10 @@ pub use zeroize; use core::{fmt::Debug, ops::Add}; use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; -/// Algorithm [`ObjectIdentifier`] for elliptic curve public key cryptography. -/// +/// Algorithm [`ObjectIdentifier`][`pkcs8::ObjectIdentifier`] for elliptic +/// curve public key cryptography. +/// +/// #[cfg(feature = "pkcs8")] #[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))] pub const ALGORITHM_OID: pkcs8::ObjectIdentifier = From 2425c994969708c5089ef74f4463ff8140fc175c Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 5 Dec 2020 10:41:27 -0800 Subject: [PATCH 0306/1461] elliptic-curve: impl `pkcs8::FromPublicKey` for `PublicKey` (#385) Support for parsing `PublicKey` from DER and PEM encoded documents containing X.509 SubjectPublicKeyInfo. These are one of the common formats for public keys (especially in the OpenSSL ecosystem). Keys in this format begin with: -----BEGIN PUBLIC KEY----- --- Cargo.lock | 6 +-- Cargo.toml | 1 - elliptic-curve/src/public_key.rs | 77 ++++++++++++++++++++++++++++++++ elliptic-curve/src/secret_key.rs | 29 +++++++++--- 4 files changed, 103 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8356458bc..c60c0d1c0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -93,8 +93,8 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.3.0-pre" -source = "git+https://github.com/RustCrypto/utils.git#4183dbfdab9797d2b90e11e19b8750b426d2e179" +version = "0.3.1" +source = "git+https://github.com/RustCrypto/utils.git#aa28abd645c444ed832d4a0adf9bd7189501d076" [[package]] name = "cpuid-bool" @@ -263,7 +263,7 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "pkcs8" version = "0.0.0" -source = "git+https://github.com/RustCrypto/utils.git#4183dbfdab9797d2b90e11e19b8750b426d2e179" +source = "git+https://github.com/RustCrypto/utils.git#aa28abd645c444ed832d4a0adf9bd7189501d076" dependencies = [ "const-oid", "subtle-encoding", diff --git a/Cargo.toml b/Cargo.toml index 31f01b7fe..c82783df0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,5 +12,4 @@ members = [ ] [patch.crates-io] -const-oid = { git = "https://github.com/RustCrypto/utils.git" } pkcs8 = { git = "https://github.com/RustCrypto/utils.git" } diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index c48ea70df..d83ad5cf3 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -16,10 +16,39 @@ use core::{ use ff::PrimeField; use generic_array::ArrayLength; +#[cfg(feature = "pkcs8")] +use crate::{AlgorithmParameters, ALGORITHM_OID}; +#[cfg(feature = "pkcs8")] +use pkcs8::FromPublicKey; + +#[cfg(feature = "pem")] +use core::str::FromStr; + /// Elliptic curve public keys. /// /// These are a thin wrapper around [`AffinePoint`] which simplifies /// encoding/decoding. +/// +/// # Parsing "SPKI" Keys +/// +/// X.509 `SubjectPublicKeyInfo` (SPKI) is a commonly used format for encoding +/// public keys, notably public keys corresponding to PKCS#8 private keys. +/// (especially ones generated by OpenSSL). +/// +/// Keys in SPKI format are either binary (ASN.1 BER/DER), or PEM encoded +/// (ASCII) and begin with the following: +/// +/// ```text +/// -----BEGIN PUBLIC KEY----- +/// ``` +/// +/// To decode an elliptic curve public key from SPKI, enable the `pkcs8` +/// feature of this crate (or the `pkcs8` feature of a specific RustCrypto +/// elliptic curve crate) and use the [`pkcs8::FromPublicKey`] trait to +/// parse it. +/// +/// When the `pem` feature of this crate (or a specific RustCrypto elliptic +/// curve crate) is enabled, a [`FromStr`] impl is also available. #[derive(Clone, Debug)] pub struct PublicKey where @@ -222,3 +251,51 @@ where self.to_encoded_point(false) == other.to_encoded_point(false) } } + +#[cfg(feature = "pkcs8")] +#[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))] +impl FromPublicKey for PublicKey +where + Self: TryFrom, Error = Error>, + C: Curve + AlgorithmParameters + ProjectiveArithmetic, + FieldBytes: From> + for<'r> From<&'r Scalar>, + Scalar: PrimeField>, + AffinePoint: Copy + Clone + Debug, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + fn from_spki(spki: pkcs8::SubjectPublicKeyInfo<'_>) -> pkcs8::Result { + if spki.algorithm.oid != ALGORITHM_OID || spki.algorithm.parameters != Some(C::OID) { + return Err(pkcs8::Error); + } + + // Strip leading `0` byte if it exists + // TODO(tarcieri): determine if there's actually any case where this byte doesn't exist + let bytes = match spki.subject_public_key.get(0) { + Some(0) => &spki.subject_public_key[1..], + Some(_) => spki.subject_public_key, + None => return Err(pkcs8::Error), + }; + + Self::from_sec1_bytes(bytes).map_err(|_| pkcs8::Error) + } +} + +#[cfg(feature = "pem")] +#[cfg_attr(docsrs, doc(cfg(feature = "pem")))] +impl FromStr for PublicKey +where + Self: TryFrom, Error = Error>, + C: Curve + AlgorithmParameters + ProjectiveArithmetic, + FieldBytes: From> + for<'r> From<&'r Scalar>, + Scalar: PrimeField>, + AffinePoint: Copy + Clone + Debug, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + type Err = Error; + + fn from_str(s: &str) -> Result { + Self::from_public_key_pem(s).map_err(|_| Error) + } +} diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index e8d9f62b2..86f91109f 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -28,7 +28,7 @@ use crate::{ #[cfg(feature = "pkcs8")] use crate::{generic_array::typenum::Unsigned, AlgorithmParameters, ALGORITHM_OID}; #[cfg(feature = "pkcs8")] -use pkcs8::FromPkcs8; +use pkcs8::FromPrivateKey; #[cfg(feature = "pem")] use core::str::FromStr; @@ -77,6 +77,26 @@ where /// This type wraps a secret scalar value, helping to prevent accidental /// exposure and securely erasing the value from memory when dropped /// (when the `zeroize` feature of this crate is enabled). +/// +/// # Parsing PKCS#8 Keys +/// +/// PKCS#8 is a commonly used format for encoding secret keys (especially ones +/// generated by OpenSSL). +/// +/// Keys in PKCS#8 format are either binary (ASN.1 BER/DER), or PEM encoded +/// (ASCII) and begin with the following: +/// +/// ```text +/// -----BEGIN PRIVATE KEY----- +/// ``` +/// +/// To decode an elliptic curve private key from PKCS#8, enable the `pkcs8` +/// feature of this crate (or the `pkcs8` feature of a specific RustCrypto +/// elliptic curve crate) and use the [`pkcs8::FromPrivateKey`] trait to +/// parse it. +/// +/// When the `pem` feature of this crate (or a specific RustCrypto elliptic +/// curve crate) is enabled, a [`FromStr`] impl is also available. #[derive(Clone)] pub struct SecretKey { /// Secret value (i.e. secret scalar) @@ -182,7 +202,7 @@ where #[cfg(feature = "pkcs8")] #[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))] -impl FromPkcs8 for SecretKey +impl FromPrivateKey for SecretKey where C: Curve + AlgorithmParameters + SecretValue, C::Secret: Clone + Zeroize, @@ -190,10 +210,7 @@ where { fn from_pkcs8_private_key_info( private_key_info: pkcs8::PrivateKeyInfo<'_>, - ) -> pkcs8::Result - where - C: AlgorithmParameters, - { + ) -> pkcs8::Result { if private_key_info.algorithm.oid != ALGORITHM_OID || private_key_info.algorithm.parameters != Some(C::OID) { From 2221f59715a9594e807e0d51b99f04cf0c1454da Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 5 Dec 2020 11:02:16 -0800 Subject: [PATCH 0307/1461] elliptic-curve: use `pkcs8` crate's v0.1 release (#386) --- Cargo.lock | 10 ++++++---- Cargo.toml | 3 --- elliptic-curve/Cargo.toml | 2 +- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c60c0d1c0..e23b6c0ae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -93,8 +93,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.3.1" -source = "git+https://github.com/RustCrypto/utils.git#aa28abd645c444ed832d4a0adf9bd7189501d076" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4fa30214c17255a4c120bd6a199a61bfacb28e4a9f0be8eecf629f2847e84d4" [[package]] name = "cpuid-bool" @@ -262,8 +263,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "pkcs8" -version = "0.0.0" -source = "git+https://github.com/RustCrypto/utils.git#aa28abd645c444ed832d4a0adf9bd7189501d076" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2298039b56d6be1d9bf341c9ba6aa0936bd508152c2829c8cab6d3f57675f4" dependencies = [ "const-oid", "subtle-encoding", diff --git a/Cargo.toml b/Cargo.toml index c82783df0..943b0d7a1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,3 @@ members = [ "signature/async", "universal-hash", ] - -[patch.crates-io] -pkcs8 = { git = "https://github.com/RustCrypto/utils.git" } diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 45495ba77..f26655db8 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -20,7 +20,7 @@ digest = { version = "0.9", optional = true } ff = { version = "0.8", optional = true, default-features = false } group = { version = "0.8", optional = true, default-features = false } generic-array = { version = "0.14", default-features = false } -pkcs8 = { version = "0", optional = true } +pkcs8 = { version = "0.1", optional = true } rand_core = { version = "0.5", default-features = false } subtle = { version = "2.3", default-features = false } zeroize = { version = "1", optional = true, default-features = false } From 41f8e00b7121997f3e0b32961ab7c5ccc9cc4bf4 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 6 Dec 2020 06:27:28 -0800 Subject: [PATCH 0308/1461] elliptic-curve v0.7.0 (#387) --- Cargo.lock | 2 +- crypto/Cargo.toml | 2 +- elliptic-curve/CHANGELOG.md | 28 ++++++++++++++++++++++++++++ elliptic-curve/Cargo.toml | 2 +- 4 files changed, 31 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e23b6c0ae..152c18443 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -145,7 +145,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.7.0-pre" +version = "0.7.0" dependencies = [ "bitvec", "digest 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index b11faf574..12ddcc28a 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -15,7 +15,7 @@ edition = "2018" aead = { version = "0.3", optional = true, path = "../aead" } cipher = { version = "=0.3.0-pre", optional = true, path = "../cipher" } digest = { version = "0.9", optional = true, path = "../digest" } -elliptic-curve = { version = "=0.7.0-pre", optional = true, path = "../elliptic-curve" } +elliptic-curve = { version = "0.7", optional = true, path = "../elliptic-curve" } mac = { version = "=0.11.0-pre", package = "crypto-mac", optional = true, path = "../crypto-mac" } signature = { version = "1.2.0", optional = true, default-features = false, path = "../signature" } universal-hash = { version = "0.4", optional = true, path = "../universal-hash" } diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index 4be92102b..e4f6e9e20 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,34 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.7.0 (2020-12-06) +### Added +- Impl `pkcs8::FromPublicKey` for `PublicKey` ([#385]) +- Impl `pkcs8::FromPrivateKey` trait for `SecretKey` ([#381], [#383]) +- PKCS#8 PEM support ([#382]) +- `SecretKey::secret_value()` method ([#375]) +- `PublicKey` type ([#363], [#366]) + +### Changed +- Rename `PublicKey::from_bytes()` to `::from_sec1_bytes()` ([#376]) +- `sec1::EncodedPoint` uses `Option` instead of `subtle::CtOption` ([#367]) +- Bump `const-oid` to v0.3; MSRV 1.46+ ([#365], [#381]) + +### Fixed +- `ecdh` rustdoc ([#364]) + +[#385]: https://github.com/RustCrypto/traits/pull/385 +[#383]: https://github.com/RustCrypto/traits/pull/383 +[#382]: https://github.com/RustCrypto/traits/pull/382 +[#381]: https://github.com/RustCrypto/traits/pull/381 +[#376]: https://github.com/RustCrypto/traits/pull/376 +[#375]: https://github.com/RustCrypto/traits/pull/375 +[#367]: https://github.com/RustCrypto/traits/pull/367 +[#366]: https://github.com/RustCrypto/traits/pull/366 +[#365]: https://github.com/RustCrypto/traits/pull/365 +[#364]: https://github.com/RustCrypto/traits/pull/364 +[#363]: https://github.com/RustCrypto/traits/pull/363 + ## 0.6.6 (2020-10-08) ### Added - Derive `Clone` on `SecretBytes` ([#330]) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index f26655db8..7d692dc9b 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -5,7 +5,7 @@ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. """ -version = "0.7.0-pre" # Also update html_root_url in lib.rs when bumping this +version = "0.7.0" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" repository = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve" From b7e7a084537633a0a7dd36ffa87062b329a88eec Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Dec 2020 05:57:18 -0800 Subject: [PATCH 0309/1461] build(deps): bump pkcs8 from 0.1.0 to 0.1.1 (#388) Bumps [pkcs8](https://github.com/RustCrypto/utils) from 0.1.0 to 0.1.1. - [Release notes](https://github.com/RustCrypto/utils/releases) - [Commits](https://github.com/RustCrypto/utils/compare/pkcs8-v0.1.0...pkcs8-v0.1.1) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 152c18443..6ad4847d1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -263,9 +263,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "pkcs8" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2298039b56d6be1d9bf341c9ba6aa0936bd508152c2829c8cab6d3f57675f4" +checksum = "6529960a627342f19f68d43a07b268c98fd347e68668df3743a3cb9211c0975f" dependencies = [ "const-oid", "subtle-encoding", From 7b56fe1c518427506064eb0b216a9bf503b74224 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 7 Dec 2020 07:16:06 -0800 Subject: [PATCH 0310/1461] elliptic-curve: better document PKCS#8 traits (#389) --- elliptic-curve/src/public_key.rs | 5 +++-- elliptic-curve/src/secret_key.rs | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index d83ad5cf3..607acb576 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -44,8 +44,9 @@ use core::str::FromStr; /// /// To decode an elliptic curve public key from SPKI, enable the `pkcs8` /// feature of this crate (or the `pkcs8` feature of a specific RustCrypto -/// elliptic curve crate) and use the [`pkcs8::FromPublicKey`] trait to -/// parse it. +/// elliptic curve crate) and use the +/// [`elliptic_curve::pkcs8::FromPublicKey`][`pkcs8::FromPublicKey`] +/// trait to parse it. /// /// When the `pem` feature of this crate (or a specific RustCrypto elliptic /// curve crate) is enabled, a [`FromStr`] impl is also available. diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 86f91109f..f38c6ea5a 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -92,8 +92,9 @@ where /// /// To decode an elliptic curve private key from PKCS#8, enable the `pkcs8` /// feature of this crate (or the `pkcs8` feature of a specific RustCrypto -/// elliptic curve crate) and use the [`pkcs8::FromPrivateKey`] trait to -/// parse it. +/// elliptic curve crate) and use the +/// [`elliptic_curve::pkcs8::FromPrivateKey`][`pkcs8::FromPrivateKey`] +/// trait to parse it. /// /// When the `pem` feature of this crate (or a specific RustCrypto elliptic /// curve crate) is enabled, a [`FromStr`] impl is also available. From e9c6862d2feb1d180f1dc40f834d49cb7e2dc67c Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 7 Dec 2020 07:23:23 -0800 Subject: [PATCH 0311/1461] elliptic-curve: constrain `SecretKey::secret_value` exposure (#390) ...to only return `NonZeroScalar` when the `arithmetic` feature is enabled and the curve impl's `ProjectiveArithmetic`. Otherwise the `SecretValue::Secret` type is not intended to be part of the public API. --- elliptic-curve/src/secret_key.rs | 89 +++++++++++++++++--------------- 1 file changed, 48 insertions(+), 41 deletions(-) diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index f38c6ea5a..d3fa2217f 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -33,45 +33,6 @@ use pkcs8::FromPrivateKey; #[cfg(feature = "pem")] use core::str::FromStr; -/// Inner value stored by a [`SecretKey`]. -pub trait SecretValue: Curve { - /// Inner secret value. - /// - /// ⚠️ WARNING ⚠️ - /// - /// This type is not intended to be part of the public API and in future - /// versions of this crate we will try to explore ways to hide it. - /// - /// Crates such as `k256` and `p256` conditionally define this type - /// differently depending on what cargo features are enabled. - /// This means any consumers of this crate attempting to use this type - /// may experience breakages if the cargo features are not what are - /// expected. - /// - /// We regret exposing it as part of the public API for now, however if - /// you do reference this type as a downstream consumer of a curve crate, - /// be aware you will experience breakages! - type Secret: Into> + Zeroize; - - /// Parse the secret value from bytes - // TODO(tarcieri): make this constant time? - fn from_secret_bytes(bytes: &FieldBytes) -> Option; -} - -#[cfg(feature = "arithmetic")] -impl SecretValue for C -where - C: Curve + ProjectiveArithmetic, - FieldBytes: From> + for<'a> From<&'a Scalar>, - Scalar: PrimeField> + Zeroize, -{ - type Secret = NonZeroScalar; - - fn from_secret_bytes(repr: &FieldBytes) -> Option> { - NonZeroScalar::from_repr(repr.clone()) - } -} - /// Elliptic curve secret keys. /// /// This type wraps a secret scalar value, helping to prevent accidental @@ -145,14 +106,21 @@ where self.secret_value.clone().into() } - /// Borrow the inner generic secret value. + /// Borrow the inner [`NonZeroScalar`] secret value. /// /// # Warning /// /// This value is key material. /// /// Please treat it with the care it deserves! - pub fn secret_value(&self) -> &C::Secret { + #[cfg(feature = "arithmetic")] + #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] + pub fn secret_value(&self) -> &NonZeroScalar + where + C: ProjectiveArithmetic + SecretValue>, + FieldBytes: From> + for<'a> From<&'a Scalar>, + Scalar: PrimeField> + Zeroize, + { &self.secret_value } @@ -285,6 +253,45 @@ where } } +/// Inner value stored by a [`SecretKey`]. +pub trait SecretValue: Curve { + /// Inner secret value. + /// + /// ⚠️ WARNING ⚠️ + /// + /// This type is not intended to be part of the public API and in future + /// versions of this crate we will try to explore ways to hide it. + /// + /// Crates such as `k256` and `p256` conditionally define this type + /// differently depending on what cargo features are enabled. + /// This means any consumers of this crate attempting to use this type + /// may experience breakages if the cargo features are not what are + /// expected. + /// + /// We regret exposing it as part of the public API for now, however if + /// you do reference this type as a downstream consumer of a curve crate, + /// be aware you will experience breakages! + type Secret: Into> + Zeroize; + + /// Parse the secret value from bytes + // TODO(tarcieri): make this constant time? + fn from_secret_bytes(bytes: &FieldBytes) -> Option; +} + +#[cfg(feature = "arithmetic")] +impl SecretValue for C +where + C: Curve + ProjectiveArithmetic, + FieldBytes: From> + for<'a> From<&'a Scalar>, + Scalar: PrimeField> + Zeroize, +{ + type Secret = NonZeroScalar; + + fn from_secret_bytes(repr: &FieldBytes) -> Option> { + NonZeroScalar::from_repr(repr.clone()) + } +} + /// Newtype wrapper for [`FieldBytes`] which impls [`Zeroize`]. /// /// This allows it to fulfill the [`Zeroize`] bound on [`SecretValue::Secret`]. From 4ceb08a46d5eee25504257bf835ad56ed7becd9b Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 7 Dec 2020 07:37:24 -0800 Subject: [PATCH 0312/1461] elliptic-curve v0.7.1 (#391) --- Cargo.lock | 2 +- elliptic-curve/CHANGELOG.md | 8 +++++++- elliptic-curve/Cargo.toml | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6ad4847d1..2c5a1d712 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -145,7 +145,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.7.0" +version = "0.7.1" dependencies = [ "bitvec", "digest 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index e4f6e9e20..504a5b707 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,7 +4,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 0.7.0 (2020-12-06) +## 0.7.1 (2020-12-07) +### Changed +- Have `SecretKey::secret_value` always return `NonZeroScalar` ([#390]) + +[#390]: https://github.com/RustCrypto/traits/pull/390 + +## 0.7.0 (2020-12-06) [YANKED] ### Added - Impl `pkcs8::FromPublicKey` for `PublicKey` ([#385]) - Impl `pkcs8::FromPrivateKey` trait for `SecretKey` ([#381], [#383]) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 7d692dc9b..d82fee56a 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -5,7 +5,7 @@ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. """ -version = "0.7.0" # Also update html_root_url in lib.rs when bumping this +version = "0.7.1" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" repository = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve" From 19b9cf51b113ed3e1f3471ca72258836bf166db9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 10 Dec 2020 04:46:13 -0800 Subject: [PATCH 0313/1461] build(deps): bump zeroize from 1.1.1 to 1.2.0 (#393) Bumps [zeroize](https://github.com/iqlusioninc/crates) from 1.1.1 to 1.2.0. - [Release notes](https://github.com/iqlusioninc/crates/releases) - [Commits](https://github.com/iqlusioninc/crates/compare/zeroize/v1.1.1...zeroize/v1.2.0) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2c5a1d712..58632b46c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -420,6 +420,6 @@ checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" [[package]] name = "zeroize" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f33972566adbd2d3588b0491eb94b98b43695c4ef897903470ede4f3f5a28a" +checksum = "81a974bcdd357f0dca4d41677db03436324d45a4c9ed2d0b873a5a360ce41c36" From 509a971b10e831a8229b3f96ef3906179ad5c262 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 16 Dec 2020 16:30:52 -0800 Subject: [PATCH 0314/1461] elliptic-curve: add support for SEC1 identity encoding (#401) Closes #399. The `ToEncodedPoint` trait is infallible. We can either make it fallible (as attempted in #400) or add support for the SEC1 encoding for the identity point. This commit adds SEC1 support for identity, allowing `ToEncodedPoint` to remain infallible. Unfortunately breaking as it requires adding new enum variants and some method signature changes. However, that said, this should make the SEC1 implementation "complete" in that it implements the full `Elliptic-Curve-Point-to-Octet-String` encoding (and decoding). --- elliptic-curve/src/ecdh.rs | 6 +++- elliptic-curve/src/sec1.rs | 73 ++++++++++++++++++++++++++++---------- 2 files changed, 60 insertions(+), 19 deletions(-) diff --git a/elliptic-curve/src/ecdh.rs b/elliptic-curve/src/ecdh.rs index e9a717771..811aee5e3 100644 --- a/elliptic-curve/src/ecdh.rs +++ b/elliptic-curve/src/ecdh.rs @@ -153,7 +153,11 @@ where { /// Create a new shared secret from the given uncompressed curve point fn new(mut encoded_point: EncodedPoint) -> Self { - let secret_bytes = encoded_point.x().clone(); + let secret_bytes = encoded_point + .x() + .cloned() + .expect("encoded point is identity"); + encoded_point.zeroize(); Self { secret_bytes } } diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index 577d46eb2..cb66c4fd2 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -178,6 +178,11 @@ where }) } + /// Is this [`EncodedPoint`] the additive identity? (a.k.a. point at infinity) + pub fn is_identity(&self) -> bool { + self.tag().is_identity() + } + /// Is this [`EncodedPoint`] compressed? pub fn is_compressed(&self) -> bool { self.tag().is_compressed() @@ -186,7 +191,7 @@ where /// Compress this [`EncodedPoint`], returning a new [`EncodedPoint`]. pub fn compress(&self) -> Self { match self.coordinates() { - Coordinates::Compressed { .. } => self.clone(), + Coordinates::Identity | Coordinates::Compressed { .. } => self.clone(), Coordinates::Uncompressed { x, y } => Self::from_affine_coordinates(x, y, true), } } @@ -202,6 +207,7 @@ where AffinePoint: ConditionallySelectable + Default + Decompress + ToEncodedPoint, { match self.coordinates() { + Coordinates::Identity => None, Coordinates::Compressed { x, y_is_odd } => { AffinePoint::::decompress(x, Choice::from(y_is_odd as u8)) .map(|s| s.to_encoded_point(false)) @@ -236,6 +242,10 @@ where /// Get the [`Coordinates`] for this [`EncodedPoint`]. #[inline] pub fn coordinates(&self) -> Coordinates<'_, C> { + if self.is_identity() { + return Coordinates::Identity; + } + let (x, y) = self.bytes[1..].split_at(C::FieldSize::to_usize()); if self.is_compressed() { @@ -251,20 +261,23 @@ where } } - /// Get the x-coordinate for this [`EncodedPoint`] - pub fn x(&self) -> &FieldBytes { + /// Get the x-coordinate for this [`EncodedPoint`]. + /// + /// Returns `None` if this point is the identity point. + pub fn x(&self) -> Option<&FieldBytes> { match self.coordinates() { - Coordinates::Compressed { x, .. } => x, - Coordinates::Uncompressed { x, .. } => x, + Coordinates::Identity => None, + Coordinates::Compressed { x, .. } => Some(x), + Coordinates::Uncompressed { x, .. } => Some(x), } } /// Get the y-coordinate for this [`EncodedPoint`]. /// - /// Returns `None` if this point is compressed. + /// Returns `None` if this point is compressed or the identity point. pub fn y(&self) -> Option<&FieldBytes> { match self.coordinates() { - Coordinates::Compressed { .. } => None, + Coordinates::Compressed { .. } | Coordinates::Identity => None, Coordinates::Uncompressed { y, .. } => Some(y), } } @@ -318,6 +331,9 @@ where /// SEC1-encoded elliptic curve points. #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum Coordinates<'a, C: Curve> { + /// Identity point (a.k.a. point at infinity) + Identity, + /// Compressed curve point Compressed { /// x-coordinate @@ -373,6 +389,9 @@ where #[derive(Copy, Clone, Debug, Eq, PartialEq)] #[repr(u8)] pub enum Tag { + /// Identity point (`0x00`) + Identity = 0, + /// Compressed point with even y-coordinate (`0x02`) CompressedEvenY = 2, @@ -387,6 +406,7 @@ impl Tag { /// Parse a tag value from a byte pub fn from_u8(byte: u8) -> Result { match byte { + 0 => Ok(Tag::Identity), 2 => Ok(Tag::CompressedEvenY), 3 => Ok(Tag::CompressedOddY), 4 => Ok(Tag::Uncompressed), @@ -394,22 +414,24 @@ impl Tag { } } + /// Is this point the identity point? + pub fn is_identity(self) -> bool { + self == Tag::Identity + } + /// Is this point compressed? pub fn is_compressed(self) -> bool { - match self { - Tag::CompressedEvenY | Tag::CompressedOddY => true, - Tag::Uncompressed => false, - } + matches!(self, Tag::CompressedEvenY | Tag::CompressedOddY) } /// Compute the expected total message length for a message prefixed /// with this tag (including the tag byte), given the field element size /// (in bytes) for a particular elliptic curve. pub fn message_len(self, field_element_size: usize) -> usize { - 1 + if self.is_compressed() { - field_element_size - } else { - field_element_size * 2 + 1 + match self { + Tag::Identity => 0, + Tag::CompressedEvenY | Tag::CompressedOddY => field_element_size, + Tag::Uncompressed => field_element_size * 2, } } @@ -450,6 +472,9 @@ mod tests { type EncodedPoint = super::EncodedPoint; + /// Identity point + const IDENTITY_BYTES: [u8; 1] = [0]; + /// Example uncompressed point const UNCOMPRESSED_BYTES: [u8; 65] = hex!("0411111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222"); @@ -479,7 +504,7 @@ mod tests { ); assert_eq!( - compressed_even_y.x(), + compressed_even_y.x().unwrap(), &hex!("0100000000000000000000000000000000000000000000000000000000000000").into() ); assert_eq!(compressed_even_y.y(), None); @@ -504,7 +529,7 @@ mod tests { ); assert_eq!( - compressed_odd_y.x(), + compressed_odd_y.x().unwrap(), &hex!("0200000000000000000000000000000000000000000000000000000000000000").into() ); assert_eq!(compressed_odd_y.y(), None); @@ -528,7 +553,7 @@ mod tests { ); assert_eq!( - uncompressed_point.x(), + uncompressed_point.x().unwrap(), &hex!("1111111111111111111111111111111111111111111111111111111111111111").into() ); assert_eq!( @@ -537,6 +562,18 @@ mod tests { ); } + #[test] + fn decode_identity() { + let identity_point = EncodedPoint::from_bytes(&IDENTITY_BYTES[..]).unwrap(); + assert!(identity_point.is_identity()); + assert_eq!(identity_point.tag(), Tag::Identity); + assert_eq!(identity_point.len(), 1); + assert_eq!(identity_point.as_bytes(), &IDENTITY_BYTES[..]); + assert_eq!(identity_point.coordinates(), Coordinates::Identity); + assert_eq!(identity_point.x(), None); + assert_eq!(identity_point.y(), None); + } + #[test] fn decode_invalid_tag() { let mut compressed_bytes = COMPRESSED_BYTES.clone(); From 3c86a9ee16e925b2cb356893aea41746d63ad17b Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 16 Dec 2020 17:36:18 -0800 Subject: [PATCH 0315/1461] elliptic-curve: have `SecretKey::secret_scalar` return `NonZeroScalar` (#402) The `NonZeroScalar` type upholds an invariant and makes it useful in more places than a `Scalar`. --- elliptic-curve/src/secret_key.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index d3fa2217f..54f26eed6 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -133,13 +133,13 @@ where /// Please treat it with the care it deserves! #[cfg(feature = "arithmetic")] #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] - pub fn secret_scalar(&self) -> &Scalar + pub fn secret_scalar(&self) -> &NonZeroScalar where C: ProjectiveArithmetic + SecretValue>, FieldBytes: From> + for<'a> From<&'a Scalar>, Scalar: PrimeField> + Zeroize, { - self.secret_value.as_ref() + &self.secret_value } /// Get the [`PublicKey`] which corresponds to this secret key From bb042a4a9630c24aa8b8dc21b81d9b9600099133 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 16 Dec 2020 17:43:19 -0800 Subject: [PATCH 0316/1461] elliptic-curve: remove `SecretKey::secret_value` (#403) After #402, it duplicates `secret_scalar` and can therefore be removed. --- elliptic-curve/src/secret_key.rs | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 54f26eed6..8517a9dd0 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -106,24 +106,6 @@ where self.secret_value.clone().into() } - /// Borrow the inner [`NonZeroScalar`] secret value. - /// - /// # Warning - /// - /// This value is key material. - /// - /// Please treat it with the care it deserves! - #[cfg(feature = "arithmetic")] - #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] - pub fn secret_value(&self) -> &NonZeroScalar - where - C: ProjectiveArithmetic + SecretValue>, - FieldBytes: From> + for<'a> From<&'a Scalar>, - Scalar: PrimeField> + Zeroize, - { - &self.secret_value - } - /// Borrow the inner secret [`Scalar`] value. /// /// # Warning From 76c8f99c381a5b680702a933a1e98b06f672dcf4 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 16 Dec 2020 18:04:42 -0800 Subject: [PATCH 0317/1461] elliptic-curve: ensure PublicKey is not the identity point (#404) Adds an invariant to the `AffinePoint` wrapped by a `PublicKey` which ensures it is not the identity point. This is notable now that we support SEC1 encoding of identity points (#401), as it might be unexpected to end users to receive public keys which encode the identity element. --- elliptic-curve/src/ecdh.rs | 4 ++-- elliptic-curve/src/public_key.rs | 32 ++++++++++++++++++++++++-------- elliptic-curve/src/secret_key.rs | 6 +++--- 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/elliptic-curve/src/ecdh.rs b/elliptic-curve/src/ecdh.rs index 811aee5e3..c307d686d 100644 --- a/elliptic-curve/src/ecdh.rs +++ b/elliptic-curve/src/ecdh.rs @@ -31,7 +31,7 @@ use crate::{ use core::{fmt::Debug, ops::Add}; use ff::PrimeField; use generic_array::ArrayLength; -use group::{Curve as _, Group}; +use group::Curve as _; use rand_core::{CryptoRng, RngCore}; use zeroize::Zeroize; @@ -69,7 +69,7 @@ where /// /// The `compress` flag enables point compression. pub fn public_key(&self) -> PublicKey { - PublicKey::from_affine((C::ProjectivePoint::generator() * self.scalar.as_ref()).to_affine()) + PublicKey::from_secret_scalar(&self.scalar) } /// Compute a Diffie-Hellman shared secret from an ephemeral secret and the diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index 607acb576..e24ee10ca 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -2,6 +2,7 @@ use crate::{ consts::U1, + scalar::NonZeroScalar, sec1::{ EncodedPoint, FromEncodedPoint, ToEncodedPoint, UncompressedPointSize, UntaggedPointSize, }, @@ -15,6 +16,7 @@ use core::{ }; use ff::PrimeField; use generic_array::ArrayLength; +use group::{Curve as _, Group}; #[cfg(feature = "pkcs8")] use crate::{AlgorithmParameters, ALGORITHM_OID}; @@ -26,8 +28,8 @@ use core::str::FromStr; /// Elliptic curve public keys. /// -/// These are a thin wrapper around [`AffinePoint`] which simplifies -/// encoding/decoding. +/// This is a wrapper type for [`AffinePoint`] which ensures an inner +/// non-identity point and provides a common place to handle encoding/decoding. /// /// # Parsing "SPKI" Keys /// @@ -67,10 +69,24 @@ where FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField>, AffinePoint: Copy + Clone + Debug, + ProjectivePoint: From>, { /// Convert an [`AffinePoint`] into a [`PublicKey`] - pub fn from_affine(point: AffinePoint) -> Self { - Self { point } + pub fn from_affine(point: AffinePoint) -> Result { + if ProjectivePoint::::from(point).is_identity().into() { + Err(Error) + } else { + Ok(Self { point }) + } + } + + /// Compute a [`PublicKey`] from a secret [`NonZeroScalar`] value + /// (i.e. a secret key represented as a raw scalar value) + pub fn from_secret_scalar(scalar: &NonZeroScalar) -> Self { + // `NonZeroScalar` ensures the resulting point is not the identity + Self { + point: (C::ProjectivePoint::generator() * scalar).to_affine(), + } } /// Decode [`PublicKey`] (compressed or uncompressed) from the @@ -98,10 +114,7 @@ where } /// Convert this [`PublicKey`] to a [`ProjectivePoint`] for the given curve - pub fn to_projective(&self) -> ProjectivePoint - where - ProjectivePoint: From>, - { + pub fn to_projective(&self) -> ProjectivePoint { self.point.clone().into() } } @@ -112,6 +125,7 @@ where FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField>, AffinePoint: Copy + Clone + Debug, + ProjectivePoint: From>, { fn as_ref(&self) -> &AffinePoint { self.as_affine() @@ -262,6 +276,7 @@ where FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField>, AffinePoint: Copy + Clone + Debug, + ProjectivePoint: From>, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -291,6 +306,7 @@ where FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField>, AffinePoint: Copy + Clone + Debug, + ProjectivePoint: From>, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 8517a9dd0..10c6c57f3 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -18,11 +18,10 @@ use zeroize::Zeroize; #[cfg(feature = "arithmetic")] use crate::{ ff::PrimeField, - group::{Curve as _, Group}, public_key::PublicKey, rand_core::{CryptoRng, RngCore}, scalar::{NonZeroScalar, Scalar}, - weierstrass, AffinePoint, ProjectiveArithmetic, + weierstrass, AffinePoint, ProjectiveArithmetic, ProjectivePoint, }; #[cfg(feature = "pkcs8")] @@ -133,8 +132,9 @@ where FieldBytes: From> + for<'a> From<&'a Scalar>, Scalar: PrimeField> + Zeroize, AffinePoint: Copy + Clone + Debug + Default, + ProjectivePoint: From>, { - PublicKey::from_affine((C::ProjectivePoint::generator() * self.secret_scalar()).to_affine()) + PublicKey::from_secret_scalar(self.secret_scalar()) } } From 6edfb14cb317776699adba3d1c85b880e87fb792 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 16 Dec 2020 18:33:50 -0800 Subject: [PATCH 0318/1461] elliptic-curve: bump `pkcs8` crate dependency to v0.3 (#405) --- Cargo.lock | 8 ++++---- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/public_key.rs | 8 ++++---- elliptic-curve/src/secret_key.rs | 15 ++++++++------- 4 files changed, 17 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 58632b46c..20600ba7c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -93,9 +93,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.3.2" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4fa30214c17255a4c120bd6a199a61bfacb28e4a9f0be8eecf629f2847e84d4" +checksum = "069b46dab00267d018567b1154f38b706d6ed93c4915301a2fa73bc24a03a1e7" [[package]] name = "cpuid-bool" @@ -263,9 +263,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "pkcs8" -version = "0.1.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6529960a627342f19f68d43a07b268c98fd347e68668df3743a3cb9211c0975f" +checksum = "9911ed9965aeee333588f226ad2baeabda478bf5ec151550735ed1760df759ba" dependencies = [ "const-oid", "subtle-encoding", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index d82fee56a..734d1bd41 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -20,7 +20,7 @@ digest = { version = "0.9", optional = true } ff = { version = "0.8", optional = true, default-features = false } group = { version = "0.8", optional = true, default-features = false } generic-array = { version = "0.14", default-features = false } -pkcs8 = { version = "0.1", optional = true } +pkcs8 = { version = "0.3", optional = true } rand_core = { version = "0.5", default-features = false } subtle = { version = "2.3", default-features = false } zeroize = { version = "1", optional = true, default-features = false } diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index e24ee10ca..f610a2480 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -281,8 +281,8 @@ where UncompressedPointSize: ArrayLength, { fn from_spki(spki: pkcs8::SubjectPublicKeyInfo<'_>) -> pkcs8::Result { - if spki.algorithm.oid != ALGORITHM_OID || spki.algorithm.parameters != Some(C::OID) { - return Err(pkcs8::Error); + if spki.algorithm.oid != ALGORITHM_OID || spki.algorithm.parameters_oid() != Some(C::OID) { + return Err(pkcs8::Error::Decode); } // Strip leading `0` byte if it exists @@ -290,10 +290,10 @@ where let bytes = match spki.subject_public_key.get(0) { Some(0) => &spki.subject_public_key[1..], Some(_) => spki.subject_public_key, - None => return Err(pkcs8::Error), + None => return Err(pkcs8::Error::Decode), }; - Self::from_sec1_bytes(bytes).map_err(|_| pkcs8::Error) + Self::from_sec1_bytes(bytes).map_err(|_| pkcs8::Error::Decode) } } diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 10c6c57f3..ff76c43e7 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -163,9 +163,9 @@ where private_key_info: pkcs8::PrivateKeyInfo<'_>, ) -> pkcs8::Result { if private_key_info.algorithm.oid != ALGORITHM_OID - || private_key_info.algorithm.parameters != Some(C::OID) + || private_key_info.algorithm.parameters_oid() != Some(C::OID) { - return Err(pkcs8::Error); + return Err(pkcs8::Error::Decode); } let bytes = private_key_info.private_key; @@ -177,27 +177,28 @@ where // 3-bytes: INTEGER version: tag byte + length + value // 2-bytes: OCTET STRING header: tag byte + length if bytes.len() < 2 + 3 + 2 + C::FieldSize::to_usize() { - return Err(pkcs8::Error); + return Err(pkcs8::Error::Decode); } // Check key begins with ASN.1 DER SEQUENCE tag (0x30) + valid length, // where the length omits the leading SEQUENCE header (tag + length byte) if bytes[0] != 0x30 || bytes[1].checked_add(2).unwrap() as usize != bytes.len() { - return Err(pkcs8::Error); + return Err(pkcs8::Error::Decode); } // Validate version field (ASN.1 DER INTEGER value: 1) if bytes[2..=4] != [0x02, 0x01, 0x01] { - return Err(pkcs8::Error); + return Err(pkcs8::Error::Decode); } // Validate ASN.1 DER OCTET STRING header: tag (0x04) + valid length if bytes[5] != 0x04 || bytes[6] as usize != C::FieldSize::to_usize() { - return Err(pkcs8::Error); + return Err(pkcs8::Error::Decode); } // TODO(tarcieri): extract and validate public key - Self::from_bytes(&bytes[7..(7 + C::FieldSize::to_usize())]).map_err(|_| pkcs8::Error) + Self::from_bytes(&bytes[7..(7 + C::FieldSize::to_usize())]) + .map_err(|_| pkcs8::Error::Decode) } } From 2aac343217ed1a13faf1398f5af0b7cd7c8260d7 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 16 Dec 2020 18:40:15 -0800 Subject: [PATCH 0319/1461] elliptic-curve v0.8.0-pre (#406) --- Cargo.lock | 2 +- crypto/Cargo.toml | 2 +- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 20600ba7c..dca4dbec1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -145,7 +145,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.7.1" +version = "0.8.0-pre" dependencies = [ "bitvec", "digest 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 12ddcc28a..d3a54f3ca 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -15,7 +15,7 @@ edition = "2018" aead = { version = "0.3", optional = true, path = "../aead" } cipher = { version = "=0.3.0-pre", optional = true, path = "../cipher" } digest = { version = "0.9", optional = true, path = "../digest" } -elliptic-curve = { version = "0.7", optional = true, path = "../elliptic-curve" } +elliptic-curve = { version = "=0.8.0-pre", optional = true, path = "../elliptic-curve" } mac = { version = "=0.11.0-pre", package = "crypto-mac", optional = true, path = "../crypto-mac" } signature = { version = "1.2.0", optional = true, default-features = false, path = "../signature" } universal-hash = { version = "0.4", optional = true, path = "../universal-hash" } diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 734d1bd41..d5928d412 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -5,7 +5,7 @@ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. """ -version = "0.7.1" # Also update html_root_url in lib.rs when bumping this +version = "0.8.0-pre" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" repository = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve" diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index aea1078b8..69f75ab60 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -16,7 +16,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.6.6" + html_root_url = "https://docs.rs/elliptic-curve/0.8.0-pre" )] #[cfg(feature = "alloc")] From 01ee4e5e3f6b1eb454a0ab2f92c57e25ffd5e8fa Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 16 Dec 2020 19:09:59 -0800 Subject: [PATCH 0320/1461] elliptic-curve: add `sec1::Coordinates::tag` method (#407) Obtain the `Tag` needed to encode a given set of `sec1::Coordinates` --- elliptic-curve/src/sec1.rs | 77 +++++++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 30 deletions(-) diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index cb66c4fd2..e7c9374a9 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -353,36 +353,21 @@ pub enum Coordinates<'a, C: Curve> { }, } -/// Trait for deserializing a value from a SEC1 encoded curve point. -/// -/// This is intended for use with the `AffinePoint` type for a given elliptic curve. -pub trait FromEncodedPoint -where - C: Curve, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, - Self: Sized, -{ - /// Deserialize the type this trait is impl'd on from an [`EncodedPoint`]. - /// - /// # Returns - /// - /// `None` if the [`EncodedPoint`] is invalid. - fn from_encoded_point(public_key: &EncodedPoint) -> Option; -} - -/// Trait for serializing a value to a SEC1 encoded curve point. -/// -/// This is intended for use with the `AffinePoint` type for a given elliptic curve. -pub trait ToEncodedPoint -where - C: Curve, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, -{ - /// Serialize this value as a SEC1 [`EncodedPoint`], optionally applying - /// point compression. - fn to_encoded_point(&self, compress: bool) -> EncodedPoint; +impl<'a, C: Curve> Coordinates<'a, C> { + /// Get the tag value needed to encode this set of [`Coordinates`] + pub fn tag(&self) -> Tag { + match self { + Coordinates::Identity => Tag::Identity, + Coordinates::Compressed { y_is_odd, .. } => { + if *y_is_odd { + Tag::CompressedOddY + } else { + Tag::CompressedEvenY + } + } + Coordinates::Uncompressed { .. } => Tag::Uncompressed, + } + } } /// Tag byte used by the `Elliptic-Curve-Point-to-Octet-String` encoding. @@ -454,6 +439,38 @@ impl From for u8 { } } +/// Trait for deserializing a value from a SEC1 encoded curve point. +/// +/// This is intended for use with the `AffinePoint` type for a given elliptic curve. +pub trait FromEncodedPoint +where + C: Curve, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, + Self: Sized, +{ + /// Deserialize the type this trait is impl'd on from an [`EncodedPoint`]. + /// + /// # Returns + /// + /// `None` if the [`EncodedPoint`] is invalid. + fn from_encoded_point(public_key: &EncodedPoint) -> Option; +} + +/// Trait for serializing a value to a SEC1 encoded curve point. +/// +/// This is intended for use with the `AffinePoint` type for a given elliptic curve. +pub trait ToEncodedPoint +where + C: Curve, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + /// Serialize this value as a SEC1 [`EncodedPoint`], optionally applying + /// point compression. + fn to_encoded_point(&self, compress: bool) -> EncodedPoint; +} + #[cfg(test)] mod tests { use super::{Coordinates, Tag}; From b860d6ca16d96cdeefaa26ebcabe970c96e21bc7 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 16 Dec 2020 19:33:46 -0800 Subject: [PATCH 0321/1461] elliptic-curve: add `sec1::EncodedPoint::identity()` (#408) Adds a convenience method for obtaining a SEC1-encoded identity point --- elliptic-curve/src/sec1.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index e7c9374a9..62da07739 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -143,6 +143,12 @@ where .to_encoded_point(compress) } + /// Return [`EncodedPoint`] representing the additive identity + /// (a.k.a. point at infinity) + pub fn identity() -> Self { + Self::from_bytes(&[0]).unwrap() + } + /// Get the length of the encoded point in bytes pub fn len(&self) -> usize { self.tag().message_len(C::FieldSize::to_usize()) @@ -647,6 +653,14 @@ mod tests { assert_eq!(compressed_point.as_bytes(), &COMPRESSED_BYTES[..]); } + #[test] + fn identity() { + let identity_point = EncodedPoint::identity(); + assert_eq!(identity_point.tag(), Tag::Identity); + assert_eq!(identity_point.len(), 1); + assert_eq!(identity_point.as_bytes(), &IDENTITY_BYTES[..]); + } + #[cfg(feature = "alloc")] #[test] fn to_bytes() { From aac590b62befdc0eddaf0b60e9ae5028a8d93fcd Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 16 Dec 2020 20:08:26 -0800 Subject: [PATCH 0322/1461] elliptic-curve: impl `ConditionallySelectable` for `EncodedPoint` (#409) Support for conditionally selecting an `EncodedPoint` in constant time leveraging the `ConditionallySelectable` trait from the `subtle` crate. --- elliptic-curve/src/sec1.rs | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index 62da07739..d754f3a7b 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -14,23 +14,21 @@ use generic_array::{ typenum::{Unsigned, U1}, ArrayLength, GenericArray, }; +use subtle::{Choice, ConditionallySelectable}; #[cfg(feature = "alloc")] use alloc::boxed::Box; #[cfg(feature = "arithmetic")] use crate::{ - ff::PrimeField, - subtle::{Choice, ConditionallySelectable}, - weierstrass::point::Decompress, - AffinePoint, ProjectiveArithmetic, Scalar, + ff::PrimeField, weierstrass::point::Decompress, AffinePoint, ProjectiveArithmetic, Scalar, }; #[cfg(all(feature = "arithmetic", feature = "zeroize"))] -use crate::group::{Curve as _, Group}; - -#[cfg(all(feature = "arithmetic", feature = "zeroize"))] -use crate::secret_key::SecretKey; +use crate::{ + group::{Curve as _, Group}, + secret_key::SecretKey, +}; #[cfg(feature = "zeroize")] use zeroize::Zeroize; @@ -301,6 +299,24 @@ where } } +impl ConditionallySelectable for EncodedPoint +where + C: Curve, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, + as ArrayLength>::ArrayType: Copy, +{ + fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { + let mut bytes = GenericArray::default(); + + for (i, byte) in bytes.iter_mut().enumerate() { + *byte = u8::conditional_select(&a.bytes[i], &b.bytes[i], choice); + } + + Self { bytes } + } +} + impl Copy for EncodedPoint where C: Curve, From 515b00611611707782f694e4138ab3ac847814b4 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 16 Dec 2020 20:17:30 -0800 Subject: [PATCH 0323/1461] elliptic-curve: test `EncodedPoint::conditional_select` (#410) --- elliptic-curve/src/sec1.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index d754f3a7b..0e296273a 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -499,6 +499,7 @@ mod tests { use crate::{weierstrass, Curve}; use generic_array::{typenum::U32, GenericArray}; use hex_literal::hex; + use subtle::ConditionallySelectable; #[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Ord)] struct ExampleCurve; @@ -669,6 +670,18 @@ mod tests { assert_eq!(compressed_point.as_bytes(), &COMPRESSED_BYTES[..]); } + #[test] + fn conditional_select() { + let a = EncodedPoint::from_bytes(&COMPRESSED_BYTES[..]).unwrap(); + let b = EncodedPoint::from_bytes(&UNCOMPRESSED_BYTES[..]).unwrap(); + + let a_selected = EncodedPoint::conditional_select(&a, &b, 0.into()); + assert_eq!(a, a_selected); + + let b_selected = EncodedPoint::conditional_select(&a, &b, 1.into()); + assert_eq!(b, b_selected); + } + #[test] fn identity() { let identity_point = EncodedPoint::identity(); From 7879c79ba14bddc3db9e0df2502916e9bc07cf57 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 16 Dec 2020 20:28:20 -0800 Subject: [PATCH 0324/1461] elliptic-curve v0.8.0 (#411) --- Cargo.lock | 2 +- crypto/Cargo.toml | 2 +- elliptic-curve/CHANGELOG.md | 24 ++++++++++++++++++++++++ elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 2 +- 5 files changed, 28 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dca4dbec1..61cdfd727 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -145,7 +145,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.8.0-pre" +version = "0.8.0" dependencies = [ "bitvec", "digest 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index d3a54f3ca..f0f274fcb 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -15,7 +15,7 @@ edition = "2018" aead = { version = "0.3", optional = true, path = "../aead" } cipher = { version = "=0.3.0-pre", optional = true, path = "../cipher" } digest = { version = "0.9", optional = true, path = "../digest" } -elliptic-curve = { version = "=0.8.0-pre", optional = true, path = "../elliptic-curve" } +elliptic-curve = { version = "0.8", optional = true, path = "../elliptic-curve" } mac = { version = "=0.11.0-pre", package = "crypto-mac", optional = true, path = "../crypto-mac" } signature = { version = "1.2.0", optional = true, default-features = false, path = "../signature" } universal-hash = { version = "0.4", optional = true, path = "../universal-hash" } diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index 504a5b707..4a27d152a 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,30 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.8.0 (2020-12-16) +### Added +- Impl `subtle::ConditionallySelectable` for `sec1::EncodedPoint` ([#409]) +- `sec1::EncodedPoint::identity()` method ([#408]) +- `sec1::Coordinates::tag` method ([#407]) +- Support for SEC1 identity encoding ([#401]) + +### Changed +- Bump `pkcs8` crate dependency to v0.3 ([#405]) +- Ensure `PublicKey` is not the identity point ([#404]) +- Have `SecretKey::secret_scalar` return `NonZeroScalar` ([#402]) + +### Removed +- `SecretKey::secret_value` ([#403]) + +[#409]: https://github.com/RustCrypto/traits/pull/409 +[#408]: https://github.com/RustCrypto/traits/pull/408 +[#407]: https://github.com/RustCrypto/traits/pull/407 +[#405]: https://github.com/RustCrypto/traits/pull/405 +[#404]: https://github.com/RustCrypto/traits/pull/404 +[#403]: https://github.com/RustCrypto/traits/pull/403 +[#402]: https://github.com/RustCrypto/traits/pull/402 +[#401]: https://github.com/RustCrypto/traits/pull/401 + ## 0.7.1 (2020-12-07) ### Changed - Have `SecretKey::secret_value` always return `NonZeroScalar` ([#390]) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index d5928d412..ee2d5b509 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -5,7 +5,7 @@ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. """ -version = "0.8.0-pre" # Also update html_root_url in lib.rs when bumping this +version = "0.8.0" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" repository = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve" diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 69f75ab60..4359ab7ed 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -16,7 +16,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.8.0-pre" + html_root_url = "https://docs.rs/elliptic-curve/0.8.0" )] #[cfg(feature = "alloc")] From 8be528d93bf285c37c201705925743b98ceabaa8 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 16 Dec 2020 21:30:18 -0800 Subject: [PATCH 0325/1461] elliptic-curve: fix build on nightly (#412) --- elliptic-curve/src/public_key.rs | 2 +- elliptic-curve/src/sec1.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index f610a2480..45571a966 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -85,7 +85,7 @@ where pub fn from_secret_scalar(scalar: &NonZeroScalar) -> Self { // `NonZeroScalar` ensures the resulting point is not the identity Self { - point: (C::ProjectivePoint::generator() * scalar).to_affine(), + point: (C::ProjectivePoint::generator() * scalar.as_ref()).to_affine(), } } diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index 0e296273a..e27478a4f 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -136,7 +136,7 @@ where AffinePoint: ToEncodedPoint, Scalar: PrimeField> + Zeroize, { - (C::ProjectivePoint::generator() * secret_key.secret_scalar()) + (C::ProjectivePoint::generator() * secret_key.secret_scalar().as_ref()) .to_affine() .to_encoded_point(compress) } From 47154b8bbde2daa98dce8760aa57ef9d54a82a7c Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 16 Dec 2020 21:35:36 -0800 Subject: [PATCH 0326/1461] elliptic-curve v0.8.1 (#413) --- Cargo.lock | 2 +- elliptic-curve/CHANGELOG.md | 6 ++++++ elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 61cdfd727..806937081 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -145,7 +145,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.8.0" +version = "0.8.1" dependencies = [ "bitvec", "digest 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index 4a27d152a..3b38b55d8 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.8.1 (2020-12-16) +### Fixed +- Builds on Rust `nightly` compiler ([#412]) + +[#412]: https://github.com/RustCrypto/traits/pull/412 + ## 0.8.0 (2020-12-16) ### Added - Impl `subtle::ConditionallySelectable` for `sec1::EncodedPoint` ([#409]) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index ee2d5b509..0ac11f3c5 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -5,7 +5,7 @@ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. """ -version = "0.8.0" # Also update html_root_url in lib.rs when bumping this +version = "0.8.1" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" repository = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve" diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 4359ab7ed..1097bea87 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -16,7 +16,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.8.0" + html_root_url = "https://docs.rs/elliptic-curve/0.8.1" )] #[cfg(feature = "alloc")] From dda12f2ab23b1c2cb29a14011ee2e83caa5cadc2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 17 Dec 2020 05:39:39 -0800 Subject: [PATCH 0327/1461] build(deps): bump subtle from 2.3.0 to 2.4.0 (#414) Bumps [subtle](https://github.com/dalek-cryptography/subtle) from 2.3.0 to 2.4.0. - [Release notes](https://github.com/dalek-cryptography/subtle/releases) - [Changelog](https://github.com/dalek-cryptography/subtle/blob/master/CHANGELOG.md) - [Commits](https://github.com/dalek-cryptography/subtle/compare/2.3.0...2.4.0) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 806937081..a9c735371 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -350,9 +350,9 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "subtle" -version = "2.3.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "343f3f510c2915908f155e94f17220b19ccfacf2a64a2a5d8004f2c3e311e7fd" +checksum = "1e81da0851ada1f3e9d4312c704aa4f8806f0f9d69faaf8df2f3464b4a9437c2" [[package]] name = "subtle-encoding" diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 0ac11f3c5..863a4c4a5 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -22,7 +22,7 @@ group = { version = "0.8", optional = true, default-features = false } generic-array = { version = "0.14", default-features = false } pkcs8 = { version = "0.3", optional = true } rand_core = { version = "0.5", default-features = false } -subtle = { version = "2.3", default-features = false } +subtle = { version = "2.4", default-features = false } zeroize = { version = "1", optional = true, default-features = false } [dev-dependencies] From 487430a1779dbfb0d4f8c37af97f084049045ad2 Mon Sep 17 00:00:00 2001 From: Michael Rosenberg Date: Fri, 18 Dec 2020 14:15:34 -0500 Subject: [PATCH 0328/1461] Make PublicKey::from_encoded_point go through PublicKey::from_affine (#416) --- elliptic-curve/src/public_key.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index 45571a966..be2abe09b 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -208,7 +208,8 @@ where { /// Initialize [`PublicKey`] from an [`EncodedPoint`] fn from_encoded_point(encoded_point: &EncodedPoint) -> Option { - AffinePoint::::from_encoded_point(encoded_point).map(|point| Self { point }) + AffinePoint::::from_encoded_point(encoded_point) + .and_then(|point| PublicKey::from_affine(point).ok()) } } From 6d3a69e9952d4815e99e688cf7daeb1672207d3c Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 19 Dec 2020 10:22:57 -0800 Subject: [PATCH 0329/1461] elliptic-curve: low-level ECDH API (#418) Adds an `elliptic_curve::ecdh::diffie_hellman()` function which operates on types which can be coerced to `NonZeroScalar` and `AffinePoint` for a particular elliptic curve, returning a `SharedSecret` This function is an extraction of and used to implement ECDHE. This function makes it possible to perform static ECDH exchanges, although the documentation recommends using ECDHE whenever possible. --- elliptic-curve/src/ecdh.rs | 97 +++++++++++++++++++++++++++++++------- 1 file changed, 80 insertions(+), 17 deletions(-) diff --git a/elliptic-curve/src/ecdh.rs b/elliptic-curve/src/ecdh.rs index c307d686d..781ae68ba 100644 --- a/elliptic-curve/src/ecdh.rs +++ b/elliptic-curve/src/ecdh.rs @@ -1,24 +1,30 @@ -//! Elliptic Curve Diffie-Hellman (Ephemeral) Support. +//! Elliptic Curve Diffie-Hellman Support. //! //! This module contains a generic ECDH implementation which is usable with //! any elliptic curve which implements the [`ProjectiveArithmetic`] trait (presently //! the `k256` and `p256` crates) //! -//! # Usage +//! # ECDH Ephemeral (ECDHE) Usage //! -//! Have each participant generate an [`EphemeralSecret`] value, compute the -//! [`PublicKey`] for that value, exchange public keys, then each participant -//! uses their [`EphemeralSecret`] and the other participant's [`PublicKey`] -//! to compute a [`SharedSecret`] value. +//! Ephemeral Diffie-Hellman provides a one-time key exchange between two peers +//! using a randomly generated set of keys for each exchange. //! -//! # ⚠️ SECURITY WARNING ⚠️ +//! In practice ECDHE is used as part of an [Authenticated Key Exchange (AKE)][AKE] +//! protocol (e.g. [SIGMA]), where an existing cryptographic trust relationship +//! can be used to determine the authenticity of the ephemeral keys, such as +//! a digital signature. Without such an additional step, ECDHE is insecure! +//! (see security warning below) //! -//! Ephemeral Diffie-Hellman exchanges are unauthenticated and without a -//! further authentication step are trivially vulnerable to man-in-the-middle -//! attacks! +//! See the documentation for the [`EphemeralSecret`] type for more information +//! on performing ECDH ephemeral key exchanges. //! -//! These exchanges should be performed in the context of a protocol which -//! takes further steps to authenticate the peers in a key exchange. +//! # Static ECDH Usage +//! +//! Static ECDH key exchanges are supported via the low-level +//! [`diffie_hellman`] function. +//! +//! [AKE]: https://en.wikipedia.org/wiki/Authenticated_Key_Exchange +//! [SIGMA]: https://webee.technion.ac.il/~hugo/sigma-pdf.pdf use crate::{ consts::U1, @@ -28,17 +34,75 @@ use crate::{ weierstrass::Curve, AffinePoint, FieldBytes, ProjectiveArithmetic, ProjectivePoint, Scalar, }; -use core::{fmt::Debug, ops::Add}; +use core::{borrow::Borrow, fmt::Debug, ops::Add}; use ff::PrimeField; use generic_array::ArrayLength; use group::Curve as _; use rand_core::{CryptoRng, RngCore}; use zeroize::Zeroize; +/// Low-level Elliptic Curve Diffie-Hellman (ECDH) function. +/// +/// Whenever possible, we recommend using the high-level ECDH ephemeral API +/// provided by [`EphemeralSecret`]. +/// +/// However, if you are implementing a protocol which requires a static scalar +/// value as part of an ECDH exchange, this API can be used to compute a +/// [`SharedSecret`] from that value. +/// +/// Note that this API operates on the low-level [`NonZeroScalar`] and +/// [`AffinePoint`] types. If you are attempting to use the higher-level +/// [`SecretKey`][`crate::SecretKey`] and [`PublicKey`] types, you will +/// need to use the following conversions: +/// +/// ```ignore +/// let shared_secret = elliptic_curve::ecdh::diffie_hellman( +/// secret_key.secret_scalar(), +/// public_key.as_affine() +/// ); +/// ``` +pub fn diffie_hellman( + secret_key: impl Borrow>, + public_key: impl Borrow>, +) -> SharedSecret +where + C: Curve + ProjectiveArithmetic, + FieldBytes: From> + for<'r> From<&'r Scalar>, + Scalar: PrimeField> + Clone + Zeroize, + AffinePoint: Copy + Clone + Debug + ToEncodedPoint + Zeroize, + ProjectivePoint: From>, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + let shared_secret = ProjectivePoint::::from(*public_key.borrow()) * secret_key.borrow(); + + // SharedSecret::new expects an uncompressed point + // TODO(tarcieri): avoid point encoding when computing shared secret + // See: + SharedSecret::new(shared_secret.to_affine().to_encoded_point(false)) +} + /// Ephemeral Diffie-Hellman Secret. /// /// These are ephemeral "secret key" values which are deliberately designed /// to avoid being persisted. +/// +/// To perform an ephemeral Diffie-Hellman exchange, do the following: +/// +/// - Have each participant generate an [`EphemeralSecret`] value +/// - Compute the [`PublicKey`] for that value +/// - Have each peer provide their [`PublicKey`] to their counterpart +/// - Use [`EphemeralSecret`] and the other participant's [`PublicKey`] +/// to compute a [`SharedSecret`] value. +/// +/// # ⚠️ SECURITY WARNING ⚠️ +/// +/// Ephemeral Diffie-Hellman exchanges are unauthenticated and without a +/// further authentication step are trivially vulnerable to man-in-the-middle +/// attacks! +/// +/// These exchanges should be performed in the context of a protocol which +/// takes further steps to authenticate the peers in a key exchange. pub struct EphemeralSecret where C: Curve + ProjectiveArithmetic, @@ -75,10 +139,7 @@ where /// Compute a Diffie-Hellman shared secret from an ephemeral secret and the /// public key of the other participant in the exchange. pub fn diffie_hellman(&self, public_key: &PublicKey) -> SharedSecret { - #[allow(clippy::op_ref)] - let shared_secret = public_key.to_projective() * &*self.scalar; - // SharedSecret::new expects an uncompressed point - SharedSecret::new(shared_secret.to_affine().to_encoded_point(false)) + diffie_hellman(&self.scalar, public_key.as_affine()) } } @@ -132,6 +193,8 @@ where /// /// Instead, the resulting value should be used as input to a Key Derivation /// Function (KDF) or cryptographic hash function to produce a symmetric key. +// TODO(tarcieri): avoid SEC1 point encoding when computing shared secret +// See: pub struct SharedSecret where C: Curve + ProjectiveArithmetic, From 8c1239bc6a3bd8aa5a06c4a9781791867a721000 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 19 Dec 2020 10:56:07 -0800 Subject: [PATCH 0330/1461] elliptic-curve: `dev` module (#419) There is presently no good way to test traits and types in this crate which depend on a concrete curve implementation. This commit adds a `dev` module gated on an eponymous crate feature which provides a `MockCurve` type. This type does not provide a full curve arithmetic implementation (most methods are stubbed out using `unimplemented!`), but rather implements the full set of traits used in the bounds of traits defined in the `elliptic-curve` crate. This type is actually an extraction from the `ecdsa` trait, where similar testing problems were previously encountered. However, now that there's a `dev` module, the `ecdsa` crate can now use it! --- .github/workflows/elliptic-curve.yml | 1 + elliptic-curve/Cargo.toml | 1 + elliptic-curve/src/dev.rs | 570 +++++++++++++++++++++++++++ elliptic-curve/src/lib.rs | 4 + 4 files changed, 576 insertions(+) create mode 100644 elliptic-curve/src/dev.rs diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index 78dc890dc..e83d0e9f3 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -37,6 +37,7 @@ jobs: override: true - run: cargo build --no-default-features --release --target ${{ matrix.target }} - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features arithmetic + - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features dev - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features ecdh - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features pem - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features pkcs8 diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 863a4c4a5..d4011553e 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -32,6 +32,7 @@ hex-literal = "0.2" default = ["arithmetic"] alloc = [] arithmetic = ["bitvec", "ff", "group"] +dev = ["arithmetic", "digest", "zeroize"] ecdh = ["arithmetic", "zeroize"] pem = ["pkcs8/pem"] std = ["alloc"] diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs new file mode 100644 index 000000000..cba84e24b --- /dev/null +++ b/elliptic-curve/src/dev.rs @@ -0,0 +1,570 @@ +//! Development-related functionality: helpers and types for writing tests +//! against concrete implementations of the traits in this crate. + +use crate::{ + consts::U32, + digest::Digest, + ff::{Field, PrimeField}, + group, + rand_core::RngCore, + scalar::ScalarBits, + subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}, + util::{adc64, sbb64}, + weierstrass, + zeroize::Zeroize, + Curve, FromDigest, ProjectiveArithmetic, +}; +use core::{ + convert::TryInto, + iter::Sum, + ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign}, +}; + +/// Mock elliptic curve type useful for writing tests which require a concrete +/// curve type. +/// +/// Note: this type is roughly modeled off of NIST P-256, but does not provide +/// an actual cure arithmetic implementation. +#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Ord)] +pub struct MockCurve; + +impl Curve for MockCurve { + type FieldSize = U32; +} + +impl weierstrass::Curve for MockCurve {} + +impl ProjectiveArithmetic for MockCurve { + type ProjectivePoint = ProjectivePoint; +} + +/// Field element bytes. +pub type FieldBytes = crate::FieldBytes; + +/// Non-zero scalar value. +pub type NonZeroScalar = crate::scalar::NonZeroScalar; + +const LIMBS: usize = 4; + +type U256 = [u64; LIMBS]; + +// Note: P-256 modulus +const MODULUS: U256 = [ + 0xf3b9_cac2_fc63_2551, + 0xbce6_faad_a717_9e84, + 0xffff_ffff_ffff_ffff, + 0xffff_ffff_0000_0000, +]; + +/// Example scalar type +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct Scalar([u64; LIMBS]); + +impl Field for Scalar { + fn random(_rng: impl RngCore) -> Self { + unimplemented!(); + } + + fn zero() -> Self { + Self(Default::default()) + } + + fn one() -> Self { + unimplemented!(); + } + + fn is_zero(&self) -> bool { + self.ct_eq(&Self::zero()).into() + } + + #[must_use] + fn square(&self) -> Self { + unimplemented!(); + } + + #[must_use] + fn double(&self) -> Self { + unimplemented!(); + } + + fn invert(&self) -> CtOption { + unimplemented!(); + } + + fn sqrt(&self) -> CtOption { + unimplemented!(); + } +} + +impl PrimeField for Scalar { + type Repr = FieldBytes; + + #[cfg(target_pointer_width = "32")] + type ReprBits = [u32; 8]; + + #[cfg(target_pointer_width = "64")] + type ReprBits = [u64; 4]; + + const NUM_BITS: u32 = 256; + const CAPACITY: u32 = 255; + const S: u32 = 4; + + fn from_repr(bytes: FieldBytes) -> Option { + let mut w = [0u64; LIMBS]; + + // Interpret the bytes as a big-endian integer w. + w[3] = u64::from_be_bytes(bytes[0..8].try_into().unwrap()); + w[2] = u64::from_be_bytes(bytes[8..16].try_into().unwrap()); + w[1] = u64::from_be_bytes(bytes[16..24].try_into().unwrap()); + w[0] = u64::from_be_bytes(bytes[24..32].try_into().unwrap()); + + // If w is in the range [0, n) then w - n will overflow, resulting in a borrow + // value of 2^64 - 1. + let (_, borrow) = sbb64(w[0], MODULUS[0], 0); + let (_, borrow) = sbb64(w[1], MODULUS[1], borrow); + let (_, borrow) = sbb64(w[2], MODULUS[2], borrow); + let (_, borrow) = sbb64(w[3], MODULUS[3], borrow); + + if (borrow as u8) & 1 == 1 { + Some(Scalar(w)) + } else { + None + } + } + + fn to_repr(&self) -> FieldBytes { + let mut ret = FieldBytes::default(); + ret[0..8].copy_from_slice(&self.0[3].to_be_bytes()); + ret[8..16].copy_from_slice(&self.0[2].to_be_bytes()); + ret[16..24].copy_from_slice(&self.0[1].to_be_bytes()); + ret[24..32].copy_from_slice(&self.0[0].to_be_bytes()); + ret + } + + fn to_le_bits(&self) -> ScalarBits { + unimplemented!(); + } + + fn is_odd(&self) -> bool { + unimplemented!(); + } + + fn char_le_bits() -> ScalarBits { + unimplemented!(); + } + + fn multiplicative_generator() -> Self { + unimplemented!(); + } + + fn root_of_unity() -> Self { + unimplemented!(); + } +} + +impl ConditionallySelectable for Scalar { + fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { + Scalar([ + u64::conditional_select(&a.0[0], &b.0[0], choice), + u64::conditional_select(&a.0[1], &b.0[1], choice), + u64::conditional_select(&a.0[2], &b.0[2], choice), + u64::conditional_select(&a.0[3], &b.0[3], choice), + ]) + } +} + +impl ConstantTimeEq for Scalar { + fn ct_eq(&self, other: &Self) -> Choice { + self.0[0].ct_eq(&other.0[0]) + & self.0[1].ct_eq(&other.0[1]) + & self.0[2].ct_eq(&other.0[2]) + & self.0[3].ct_eq(&other.0[3]) + } +} + +impl Add for Scalar { + type Output = Scalar; + + fn add(self, _other: Scalar) -> Scalar { + unimplemented!(); + } +} + +impl Add<&Scalar> for Scalar { + type Output = Scalar; + + fn add(self, _other: &Scalar) -> Scalar { + unimplemented!(); + } +} + +impl AddAssign for Scalar { + fn add_assign(&mut self, _rhs: Scalar) { + unimplemented!(); + } +} + +impl AddAssign<&Scalar> for Scalar { + fn add_assign(&mut self, _rhs: &Scalar) { + unimplemented!(); + } +} + +impl Sub for Scalar { + type Output = Scalar; + + fn sub(self, _other: Scalar) -> Scalar { + unimplemented!(); + } +} + +impl Sub<&Scalar> for Scalar { + type Output = Scalar; + + fn sub(self, _other: &Scalar) -> Scalar { + unimplemented!(); + } +} + +impl SubAssign for Scalar { + fn sub_assign(&mut self, _rhs: Scalar) { + unimplemented!(); + } +} + +impl SubAssign<&Scalar> for Scalar { + fn sub_assign(&mut self, _rhs: &Scalar) { + unimplemented!(); + } +} + +impl Mul for Scalar { + type Output = Scalar; + + fn mul(self, _other: Scalar) -> Scalar { + unimplemented!(); + } +} + +impl Mul<&Scalar> for Scalar { + type Output = Scalar; + + fn mul(self, _other: &Scalar) -> Scalar { + unimplemented!(); + } +} + +impl MulAssign for Scalar { + fn mul_assign(&mut self, _rhs: Scalar) { + unimplemented!(); + } +} + +impl MulAssign<&Scalar> for Scalar { + fn mul_assign(&mut self, _rhs: &Scalar) { + unimplemented!(); + } +} + +impl Neg for Scalar { + type Output = Scalar; + + fn neg(self) -> Scalar { + unimplemented!(); + } +} + +impl From for Scalar { + fn from(_: u64) -> Scalar { + unimplemented!(); + } +} + +impl From for FieldBytes { + fn from(scalar: Scalar) -> Self { + Self::from(&scalar) + } +} + +impl From<&Scalar> for FieldBytes { + fn from(scalar: &Scalar) -> Self { + let mut ret = FieldBytes::default(); + ret[0..8].copy_from_slice(&scalar.0[3].to_be_bytes()); + ret[8..16].copy_from_slice(&scalar.0[2].to_be_bytes()); + ret[16..24].copy_from_slice(&scalar.0[1].to_be_bytes()); + ret[24..32].copy_from_slice(&scalar.0[0].to_be_bytes()); + ret + } +} + +impl FromDigest for Scalar { + fn from_digest(digest: D) -> Self + where + D: Digest, + { + let bytes = digest.finalize(); + + Self::sub_inner( + u64::from_be_bytes(bytes[24..32].try_into().unwrap()), + u64::from_be_bytes(bytes[16..24].try_into().unwrap()), + u64::from_be_bytes(bytes[8..16].try_into().unwrap()), + u64::from_be_bytes(bytes[0..8].try_into().unwrap()), + 0, + MODULUS[0], + MODULUS[1], + MODULUS[2], + MODULUS[3], + 0, + ) + } +} + +impl Zeroize for Scalar { + fn zeroize(&mut self) { + self.0.as_mut().zeroize() + } +} + +impl Scalar { + #[allow(clippy::too_many_arguments)] + const fn sub_inner( + l0: u64, + l1: u64, + l2: u64, + l3: u64, + l4: u64, + r0: u64, + r1: u64, + r2: u64, + r3: u64, + r4: u64, + ) -> Self { + let (w0, borrow) = sbb64(l0, r0, 0); + let (w1, borrow) = sbb64(l1, r1, borrow); + let (w2, borrow) = sbb64(l2, r2, borrow); + let (w3, borrow) = sbb64(l3, r3, borrow); + let (_, borrow) = sbb64(l4, r4, borrow); + + let (w0, carry) = adc64(w0, MODULUS[0] & borrow, 0); + let (w1, carry) = adc64(w1, MODULUS[1] & borrow, carry); + let (w2, carry) = adc64(w2, MODULUS[2] & borrow, carry); + let (w3, _) = adc64(w3, MODULUS[3] & borrow, carry); + + Scalar([w0, w1, w2, w3]) + } +} + +/// Example affine point type +#[derive(Clone, Copy, Debug)] +pub struct AffinePoint {} + +impl ConditionallySelectable for AffinePoint { + fn conditional_select(_a: &Self, _b: &Self, _choice: Choice) -> Self { + unimplemented!(); + } +} + +impl Mul for AffinePoint { + type Output = AffinePoint; + + fn mul(self, _scalar: NonZeroScalar) -> Self { + unimplemented!(); + } +} + +/// Example projective point type +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub struct ProjectivePoint {} + +impl group::Group for ProjectivePoint { + type Scalar = Scalar; + + fn random(_rng: impl RngCore) -> Self { + unimplemented!(); + } + + fn identity() -> Self { + unimplemented!(); + } + + fn generator() -> Self { + unimplemented!(); + } + + fn is_identity(&self) -> Choice { + unimplemented!(); + } + + #[must_use] + fn double(&self) -> Self { + unimplemented!(); + } +} + +impl group::Curve for ProjectivePoint { + type AffineRepr = AffinePoint; + + fn to_affine(&self) -> AffinePoint { + unimplemented!(); + } +} + +impl Add for ProjectivePoint { + type Output = ProjectivePoint; + + fn add(self, _other: ProjectivePoint) -> ProjectivePoint { + unimplemented!(); + } +} + +impl Add<&ProjectivePoint> for ProjectivePoint { + type Output = ProjectivePoint; + + fn add(self, _other: &ProjectivePoint) -> ProjectivePoint { + unimplemented!(); + } +} + +impl AddAssign for ProjectivePoint { + fn add_assign(&mut self, _rhs: ProjectivePoint) { + unimplemented!(); + } +} + +impl AddAssign<&ProjectivePoint> for ProjectivePoint { + fn add_assign(&mut self, _rhs: &ProjectivePoint) { + unimplemented!(); + } +} + +impl Sub for ProjectivePoint { + type Output = ProjectivePoint; + + fn sub(self, _other: ProjectivePoint) -> ProjectivePoint { + unimplemented!(); + } +} + +impl Sub<&ProjectivePoint> for ProjectivePoint { + type Output = ProjectivePoint; + + fn sub(self, _other: &ProjectivePoint) -> ProjectivePoint { + unimplemented!(); + } +} + +impl SubAssign for ProjectivePoint { + fn sub_assign(&mut self, _rhs: ProjectivePoint) { + unimplemented!(); + } +} + +impl SubAssign<&ProjectivePoint> for ProjectivePoint { + fn sub_assign(&mut self, _rhs: &ProjectivePoint) { + unimplemented!(); + } +} + +impl Add for ProjectivePoint { + type Output = ProjectivePoint; + + fn add(self, _other: AffinePoint) -> ProjectivePoint { + unimplemented!(); + } +} + +impl Add<&AffinePoint> for ProjectivePoint { + type Output = ProjectivePoint; + + fn add(self, _other: &AffinePoint) -> ProjectivePoint { + unimplemented!(); + } +} + +impl AddAssign for ProjectivePoint { + fn add_assign(&mut self, _rhs: AffinePoint) { + unimplemented!(); + } +} + +impl AddAssign<&AffinePoint> for ProjectivePoint { + fn add_assign(&mut self, _rhs: &AffinePoint) { + unimplemented!(); + } +} + +impl Sum for ProjectivePoint { + fn sum>(_iter: I) -> Self { + unimplemented!(); + } +} + +impl<'a> Sum<&'a ProjectivePoint> for ProjectivePoint { + fn sum>(_iter: I) -> Self { + unimplemented!(); + } +} + +impl Sub for ProjectivePoint { + type Output = ProjectivePoint; + + fn sub(self, _other: AffinePoint) -> ProjectivePoint { + unimplemented!(); + } +} + +impl Sub<&AffinePoint> for ProjectivePoint { + type Output = ProjectivePoint; + + fn sub(self, _other: &AffinePoint) -> ProjectivePoint { + unimplemented!(); + } +} + +impl SubAssign for ProjectivePoint { + fn sub_assign(&mut self, _rhs: AffinePoint) { + unimplemented!(); + } +} + +impl SubAssign<&AffinePoint> for ProjectivePoint { + fn sub_assign(&mut self, _rhs: &AffinePoint) { + unimplemented!(); + } +} + +impl Mul for ProjectivePoint { + type Output = ProjectivePoint; + + fn mul(self, _other: Scalar) -> ProjectivePoint { + unimplemented!(); + } +} + +impl Mul<&Scalar> for ProjectivePoint { + type Output = ProjectivePoint; + + fn mul(self, _other: &Scalar) -> ProjectivePoint { + unimplemented!(); + } +} + +impl MulAssign for ProjectivePoint { + fn mul_assign(&mut self, _rhs: Scalar) { + unimplemented!(); + } +} + +impl MulAssign<&Scalar> for ProjectivePoint { + fn mul_assign(&mut self, _rhs: &Scalar) { + unimplemented!(); + } +} + +impl Neg for ProjectivePoint { + type Output = ProjectivePoint; + + fn neg(self) -> ProjectivePoint { + unimplemented!(); + } +} diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 1097bea87..b6f58d061 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -41,6 +41,10 @@ pub mod public_key; #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub mod scalar; +#[cfg(feature = "dev")] +#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] +pub mod dev; + #[cfg(feature = "ecdh")] #[cfg_attr(docsrs, doc(cfg(feature = "ecdh")))] pub mod ecdh; From f4321c76c0424b454fbf5bd9c407c7b2a0db9cda Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 21 Dec 2020 16:36:20 -0800 Subject: [PATCH 0331/1461] elliptic-curve: regression test for PublicKey::from_encoded_point (#420) The invariant of `PublicKey` is that the inner affine point is *NOT* the identity, however there was a bug in the `FromEncodedPoint` implementation which was fixed in #416. However, at the time we couldn't add a regression test because there was no concrete curve type to use for writing such a test. A `MockCurve` was added in #419, so this commit uses it to write such a regression test. --- elliptic-curve/src/dev.rs | 66 ++++++++++++++++++++++++++++++-- elliptic-curve/src/lib.rs | 2 +- elliptic-curve/src/public_key.rs | 14 +++++++ 3 files changed, 78 insertions(+), 4 deletions(-) diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index cba84e24b..a18d14fa4 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -8,6 +8,7 @@ use crate::{ group, rand_core::RngCore, scalar::ScalarBits, + sec1::{FromEncodedPoint, ToEncodedPoint}, subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}, util::{adc64, sbb64}, weierstrass, @@ -38,6 +39,9 @@ impl ProjectiveArithmetic for MockCurve { type ProjectivePoint = ProjectivePoint; } +/// SEC1 encoded point. +pub type EncodedPoint = crate::sec1::EncodedPoint; + /// Field element bytes. pub type FieldBytes = crate::FieldBytes; @@ -356,7 +360,11 @@ impl Scalar { /// Example affine point type #[derive(Clone, Copy, Debug)] -pub struct AffinePoint {} +pub struct AffinePoint { + /// Is this point supposed to be the additive identity? + /// (a.k.a. point at infinity) + identity: bool, +} impl ConditionallySelectable for AffinePoint { fn conditional_select(_a: &Self, _b: &Self, _choice: Choice) -> Self { @@ -364,6 +372,28 @@ impl ConditionallySelectable for AffinePoint { } } +impl Default for AffinePoint { + fn default() -> Self { + Self { identity: true } + } +} + +impl FromEncodedPoint for AffinePoint { + fn from_encoded_point(point: &EncodedPoint) -> Option { + if point.is_identity() { + Some(Self::default()) + } else { + unimplemented!(); + } + } +} + +impl ToEncodedPoint for AffinePoint { + fn to_encoded_point(&self, _compress: bool) -> EncodedPoint { + unimplemented!(); + } +} + impl Mul for AffinePoint { type Output = AffinePoint; @@ -374,7 +404,37 @@ impl Mul for AffinePoint { /// Example projective point type #[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub struct ProjectivePoint {} +pub struct ProjectivePoint { + /// Is this point supposed to be the additive identity? + /// (a.k.a. point at infinity) + identity: bool, +} + +impl Default for ProjectivePoint { + fn default() -> Self { + Self { identity: true } + } +} + +impl From for ProjectivePoint { + fn from(point: AffinePoint) -> ProjectivePoint { + Self { + identity: point.identity, + } + } +} + +impl FromEncodedPoint for ProjectivePoint { + fn from_encoded_point(_point: &EncodedPoint) -> Option { + unimplemented!(); + } +} + +impl ToEncodedPoint for ProjectivePoint { + fn to_encoded_point(&self, _compress: bool) -> EncodedPoint { + unimplemented!(); + } +} impl group::Group for ProjectivePoint { type Scalar = Scalar; @@ -392,7 +452,7 @@ impl group::Group for ProjectivePoint { } fn is_identity(&self) -> Choice { - unimplemented!(); + Choice::from(self.identity as u8) } #[must_use] diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index b6f58d061..08fd5c5be 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -41,7 +41,7 @@ pub mod public_key; #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub mod scalar; -#[cfg(feature = "dev")] +#[cfg(any(feature = "dev"))] #[cfg_attr(docsrs, doc(cfg(feature = "dev")))] pub mod dev; diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index be2abe09b..4b06e6742 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -317,3 +317,17 @@ where Self::from_public_key_pem(s).map_err(|_| Error) } } + +#[cfg(all(feature = "dev", test))] +mod tests { + use crate::{dev::MockCurve, sec1::FromEncodedPoint}; + + type EncodedPoint = crate::sec1::EncodedPoint; + type PublicKey = super::PublicKey; + + #[test] + fn from_encoded_point_rejects_identity() { + let identity = EncodedPoint::identity(); + assert_eq!(PublicKey::from_encoded_point(&identity), None); + } +} From 23efe5b6320ec1b43e526717f542155fa26a7b00 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 21 Dec 2020 17:06:29 -0800 Subject: [PATCH 0332/1461] elliptic-curve: PKCS#8 tests (#421) Uses `MockCurve` to write tests for PKCS#8 decoding. --- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/dev.rs | 38 +++++++---- .../tests/examples/pkcs8-private-key.der | Bin 0 -> 138 bytes .../tests/examples/pkcs8-private-key.pem | 5 ++ .../tests/examples/pkcs8-public-key.der | Bin 0 -> 91 bytes .../tests/examples/pkcs8-public-key.pem | 4 ++ elliptic-curve/tests/pkcs8.rs | 61 ++++++++++++++++++ 7 files changed, 96 insertions(+), 14 deletions(-) create mode 100644 elliptic-curve/tests/examples/pkcs8-private-key.der create mode 100644 elliptic-curve/tests/examples/pkcs8-private-key.pem create mode 100644 elliptic-curve/tests/examples/pkcs8-public-key.der create mode 100644 elliptic-curve/tests/examples/pkcs8-public-key.pem create mode 100644 elliptic-curve/tests/pkcs8.rs diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index d4011553e..dd4ab63ac 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -32,7 +32,7 @@ hex-literal = "0.2" default = ["arithmetic"] alloc = [] arithmetic = ["bitvec", "ff", "group"] -dev = ["arithmetic", "digest", "zeroize"] +dev = ["arithmetic", "digest", "pkcs8", "zeroize"] ecdh = ["arithmetic", "zeroize"] pem = ["pkcs8/pem"] std = ["alloc"] diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index a18d14fa4..b928f9ff2 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -13,7 +13,7 @@ use crate::{ util::{adc64, sbb64}, weierstrass, zeroize::Zeroize, - Curve, FromDigest, ProjectiveArithmetic, + AlgorithmParameters, Curve, FromDigest, ProjectiveArithmetic, }; use core::{ convert::TryInto, @@ -39,6 +39,11 @@ impl ProjectiveArithmetic for MockCurve { type ProjectivePoint = ProjectivePoint; } +impl AlgorithmParameters for MockCurve { + /// OID for NIST P-256 + const OID: pkcs8::ObjectIdentifier = pkcs8::ObjectIdentifier::new(&[1, 2, 840, 10045, 3, 1, 7]); +} + /// SEC1 encoded point. pub type EncodedPoint = crate::sec1::EncodedPoint; @@ -48,6 +53,12 @@ pub type FieldBytes = crate::FieldBytes; /// Non-zero scalar value. pub type NonZeroScalar = crate::scalar::NonZeroScalar; +/// Public key. +pub type PublicKey = crate::PublicKey; + +/// Secret key. +pub type SecretKey = crate::SecretKey; + const LIMBS: usize = 4; type U256 = [u64; LIMBS]; @@ -361,9 +372,8 @@ impl Scalar { /// Example affine point type #[derive(Clone, Copy, Debug)] pub struct AffinePoint { - /// Is this point supposed to be the additive identity? - /// (a.k.a. point at infinity) - identity: bool, + /// Wrap [`EncodedPoint`] to allow certain conversions + inner: EncodedPoint, } impl ConditionallySelectable for AffinePoint { @@ -374,23 +384,25 @@ impl ConditionallySelectable for AffinePoint { impl Default for AffinePoint { fn default() -> Self { - Self { identity: true } + Self { + inner: EncodedPoint::identity(), + } } } impl FromEncodedPoint for AffinePoint { fn from_encoded_point(point: &EncodedPoint) -> Option { - if point.is_identity() { - Some(Self::default()) - } else { - unimplemented!(); - } + Some(Self { inner: *point }) } } impl ToEncodedPoint for AffinePoint { - fn to_encoded_point(&self, _compress: bool) -> EncodedPoint { - unimplemented!(); + fn to_encoded_point(&self, compress: bool) -> EncodedPoint { + if compress == self.inner.is_compressed() { + self.inner + } else { + unimplemented!(); + } } } @@ -419,7 +431,7 @@ impl Default for ProjectivePoint { impl From for ProjectivePoint { fn from(point: AffinePoint) -> ProjectivePoint { Self { - identity: point.identity, + identity: point.inner.is_identity(), } } } diff --git a/elliptic-curve/tests/examples/pkcs8-private-key.der b/elliptic-curve/tests/examples/pkcs8-private-key.der new file mode 100644 index 0000000000000000000000000000000000000000..c0de45ef22f512ba6a199fa9d57e08e5f95ef7e8 GIT binary patch literal 138 zcmXqLY-eI*Fc4;A*J|@PXUoLM#sOw9GqSVf8e}suGO{RSCOH;{NhO=`K6rj3^V5Qm zNuhmGEN$Ic^IN^z(mN!27rHPzF|f$2`M)(@U+4Xext*`gz112;Re~CH-z}Ia#@1+l q!}5Ink;Wx1lMH<8zGWR0-}kS1#f5&+c().unwrap(); + + // Ensure key parses equivalently to DER + let der_key = SecretKey::from_pkcs8_der(&PKCS8_PRIVATE_KEY_DER[..]).unwrap(); + assert_eq!(secret_key.to_bytes(), der_key.to_bytes()); +} + +#[test] +#[cfg(feature = "pem")] +fn parse_pkcs8_public_key_from_pem() { + let public_key = PKCS8_PUBLIC_KEY_PEM.parse::().unwrap(); + + // Ensure key parses equivalently to DER + let der_key = PublicKey::from_public_key_der(&PKCS8_PUBLIC_KEY_DER[..]).unwrap(); + assert_eq!(public_key, der_key); +} From 0d2b2a053f371f822cf45f6a79a99f922dfff955 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 21 Dec 2020 18:56:14 -0800 Subject: [PATCH 0333/1461] elliptic-curve: use `der` crate to parse `SecretKey` (#422) Replaces the previous handrolled ASN.1 DER parsing code with a parser based on the `der` crate. --- Cargo.lock | 18 ++++-- Cargo.toml | 3 + elliptic-curve/src/public_key.rs | 13 ++--- elliptic-curve/src/secret_key.rs | 99 ++++++++++++++++++++------------ 4 files changed, 83 insertions(+), 50 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a9c735371..f20e08324 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -93,9 +93,8 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "069b46dab00267d018567b1154f38b706d6ed93c4915301a2fa73bc24a03a1e7" +version = "0.4.1" +source = "git+https://github.com/RustCrypto/utils.git#022007f591e92bfb14a16bd3192309d398d2f2f0" [[package]] name = "cpuid-bool" @@ -126,6 +125,14 @@ dependencies = [ "subtle", ] +[[package]] +name = "der" +version = "0.0.0" +source = "git+https://github.com/RustCrypto/utils.git#022007f591e92bfb14a16bd3192309d398d2f2f0" +dependencies = [ + "const-oid", +] + [[package]] name = "digest" version = "0.9.0" @@ -264,10 +271,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "pkcs8" version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9911ed9965aeee333588f226ad2baeabda478bf5ec151550735ed1760df759ba" +source = "git+https://github.com/RustCrypto/utils.git#022007f591e92bfb14a16bd3192309d398d2f2f0" dependencies = [ - "const-oid", + "der", "subtle-encoding", "zeroize", ] diff --git a/Cargo.toml b/Cargo.toml index 943b0d7a1..c82783df0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,3 +10,6 @@ members = [ "signature/async", "universal-hash", ] + +[patch.crates-io] +pkcs8 = { git = "https://github.com/RustCrypto/utils.git" } diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index 4b06e6742..95b95fd37 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -286,15 +286,12 @@ where return Err(pkcs8::Error::Decode); } - // Strip leading `0` byte if it exists - // TODO(tarcieri): determine if there's actually any case where this byte doesn't exist - let bytes = match spki.subject_public_key.get(0) { - Some(0) => &spki.subject_public_key[1..], - Some(_) => spki.subject_public_key, - None => return Err(pkcs8::Error::Decode), - }; + // Look for a leading `0x00` byte in the bitstring + if spki.subject_public_key.get(0).cloned() != Some(0x00) { + return Err(pkcs8::Error::Decode); + } - Self::from_sec1_bytes(bytes).map_err(|_| pkcs8::Error::Decode) + Self::from_sec1_bytes(&spki.subject_public_key[1..]).map_err(|_| pkcs8::Error::Decode) } } diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index ff76c43e7..d7376004f 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -25,9 +25,18 @@ use crate::{ }; #[cfg(feature = "pkcs8")] -use crate::{generic_array::typenum::Unsigned, AlgorithmParameters, ALGORITHM_OID}; -#[cfg(feature = "pkcs8")] -use pkcs8::FromPrivateKey; +use { + crate::{ + sec1::{self, UncompressedPointSize, UntaggedPointSize}, + AlgorithmParameters, ALGORITHM_OID, + }, + core::ops::Add, + generic_array::{typenum::U1, ArrayLength}, + pkcs8::{ + der::{self, Decodable}, + FromPrivateKey, + }, +}; #[cfg(feature = "pem")] use core::str::FromStr; @@ -155,9 +164,11 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))] impl FromPrivateKey for SecretKey where - C: Curve + AlgorithmParameters + SecretValue, + C: weierstrass::Curve + AlgorithmParameters + SecretValue, C::Secret: Clone + Zeroize, FieldBytes: From, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, { fn from_pkcs8_private_key_info( private_key_info: pkcs8::PrivateKeyInfo<'_>, @@ -168,37 +179,51 @@ where return Err(pkcs8::Error::Decode); } - let bytes = private_key_info.private_key; - - // Ensure private key is AT LEAST as long as a scalar field element - // for this curve along with the following overhead: - // - // 2-bytes: SEQUENCE header: tag byte + length - // 3-bytes: INTEGER version: tag byte + length + value - // 2-bytes: OCTET STRING header: tag byte + length - if bytes.len() < 2 + 3 + 2 + C::FieldSize::to_usize() { - return Err(pkcs8::Error::Decode); - } - - // Check key begins with ASN.1 DER SEQUENCE tag (0x30) + valid length, - // where the length omits the leading SEQUENCE header (tag + length byte) - if bytes[0] != 0x30 || bytes[1].checked_add(2).unwrap() as usize != bytes.len() { - return Err(pkcs8::Error::Decode); - } - - // Validate version field (ASN.1 DER INTEGER value: 1) - if bytes[2..=4] != [0x02, 0x01, 0x01] { - return Err(pkcs8::Error::Decode); - } - - // Validate ASN.1 DER OCTET STRING header: tag (0x04) + valid length - if bytes[5] != 0x04 || bytes[6] as usize != C::FieldSize::to_usize() { - return Err(pkcs8::Error::Decode); - } - - // TODO(tarcieri): extract and validate public key - Self::from_bytes(&bytes[7..(7 + C::FieldSize::to_usize())]) - .map_err(|_| pkcs8::Error::Decode) + let mut decoder = der::Decoder::new(private_key_info.private_key); + + let result = decoder.sequence(|decoder| { + // Parse and validate `version` INTEGER. + if i8::decode(decoder)? != 1 { + return Err(der::ErrorKind::Value { + tag: der::Tag::Integer, + } + .into()); + } + + let secret_key_field = decoder.octet_string()?; + let secret_key = Self::from_bytes(secret_key_field).map_err(|_| { + der::Error::from(der::ErrorKind::Value { + tag: der::Tag::Sequence, + }) + })?; + + let public_key_field = decoder.any()?; + public_key_field + .tag() + .assert_eq(der::Tag::ContextSpecific1)?; + + let mut public_key_decoder = der::Decoder::new(public_key_field.as_bytes()); + let public_key_bitstring = public_key_decoder.bit_string()?.as_bytes(); + + // Look for a leading `0x00` byte in the bitstring + if public_key_bitstring.get(0).cloned() != Some(0x00) { + return Err(der::ErrorKind::Value { + tag: der::Tag::BitString, + } + .into()); + } + + // TODO(tarcieri): add validations for public key + sec1::EncodedPoint::::from_bytes(&public_key_bitstring[1..]).map_err(|_| { + der::Error::from(der::ErrorKind::Value { + tag: der::Tag::BitString, + }) + })?; + + Ok(secret_key) + })?; + + Ok(decoder.finish(result)?) } } @@ -206,9 +231,11 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "pem")))] impl FromStr for SecretKey where - C: Curve + AlgorithmParameters + SecretValue, + C: weierstrass::Curve + AlgorithmParameters + SecretValue, C::Secret: Clone + Zeroize, FieldBytes: From, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, { type Err = Error; From 1ad0a7da6c8f301a20bf07b6f0336c3b6990279a Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 21 Dec 2020 20:39:54 -0800 Subject: [PATCH 0334/1461] elliptic-curve: impl `pkcs8::ToPrivateKey` for `SecretKey` (#423) Adds support for serializing `SecretKey` as PKCS#8. --- Cargo.lock | 6 +- elliptic-curve/Cargo.toml | 4 +- elliptic-curve/src/public_key.rs | 32 ++++- elliptic-curve/src/secret_key.rs | 104 +------------- elliptic-curve/src/secret_key/pkcs8.rs | 181 +++++++++++++++++++++++++ elliptic-curve/tests/pkcs8.rs | 8 +- 6 files changed, 221 insertions(+), 114 deletions(-) create mode 100644 elliptic-curve/src/secret_key/pkcs8.rs diff --git a/Cargo.lock b/Cargo.lock index f20e08324..3a2eb25c8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -94,7 +94,7 @@ dependencies = [ [[package]] name = "const-oid" version = "0.4.1" -source = "git+https://github.com/RustCrypto/utils.git#022007f591e92bfb14a16bd3192309d398d2f2f0" +source = "git+https://github.com/RustCrypto/utils.git#005b32230010de490fc75d6ca6e58dd8b0c90837" [[package]] name = "cpuid-bool" @@ -128,7 +128,7 @@ dependencies = [ [[package]] name = "der" version = "0.0.0" -source = "git+https://github.com/RustCrypto/utils.git#022007f591e92bfb14a16bd3192309d398d2f2f0" +source = "git+https://github.com/RustCrypto/utils.git#005b32230010de490fc75d6ca6e58dd8b0c90837" dependencies = [ "const-oid", ] @@ -271,7 +271,7 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "pkcs8" version = "0.3.2" -source = "git+https://github.com/RustCrypto/utils.git#022007f591e92bfb14a16bd3192309d398d2f2f0" +source = "git+https://github.com/RustCrypto/utils.git#005b32230010de490fc75d6ca6e58dd8b0c90837" dependencies = [ "der", "subtle-encoding", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index dd4ab63ac..6f01e45cb 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -32,9 +32,9 @@ hex-literal = "0.2" default = ["arithmetic"] alloc = [] arithmetic = ["bitvec", "ff", "group"] -dev = ["arithmetic", "digest", "pkcs8", "zeroize"] +dev = ["arithmetic", "digest", "pem", "zeroize"] ecdh = ["arithmetic", "zeroize"] -pem = ["pkcs8/pem"] +pem = ["alloc", "pkcs8/pem"] std = ["alloc"] [package.metadata.docs.rs] diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index 95b95fd37..f2799b73a 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -19,12 +19,17 @@ use generic_array::ArrayLength; use group::{Curve as _, Group}; #[cfg(feature = "pkcs8")] -use crate::{AlgorithmParameters, ALGORITHM_OID}; -#[cfg(feature = "pkcs8")] -use pkcs8::FromPublicKey; +use { + crate::{AlgorithmParameters, ALGORITHM_OID}, + pkcs8::FromPublicKey, +}; #[cfg(feature = "pem")] -use core::str::FromStr; +use { + alloc::vec::Vec, + core::str::FromStr, + pkcs8::der::{self, Encodable}, +}; /// Elliptic curve public keys. /// @@ -117,6 +122,25 @@ where pub fn to_projective(&self) -> ProjectivePoint { self.point.clone().into() } + + /// Encode this public key as an ASN.1 DER bitstring as used in both + /// PKCS#8 private keys and SPKI public keys. + #[cfg(feature = "pem")] + pub(crate) fn to_der_bitstring(&self) -> Vec + where + AffinePoint: Default + FromEncodedPoint + ToEncodedPoint, + ProjectivePoint: From>, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, + { + let mut body_bytes = Vec::new(); + body_bytes.push(0); + body_bytes.extend_from_slice(self.to_encoded_point(false).as_ref()); + + der::BitString::new(&body_bytes) + .and_then(|bit_string| bit_string.to_vec()) + .expect("DER encoding error") + } } impl AsRef> for PublicKey diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index d7376004f..2aa4e9272 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -7,6 +7,9 @@ //! When the `zeroize` feature of this crate is enabled, it also handles //! zeroing it out of memory securely on drop. +#[cfg(feature = "pkcs8")] +mod pkcs8; + use crate::{error::Error, Curve, FieldBytes}; use core::{ convert::{TryFrom, TryInto}, @@ -24,23 +27,6 @@ use crate::{ weierstrass, AffinePoint, ProjectiveArithmetic, ProjectivePoint, }; -#[cfg(feature = "pkcs8")] -use { - crate::{ - sec1::{self, UncompressedPointSize, UntaggedPointSize}, - AlgorithmParameters, ALGORITHM_OID, - }, - core::ops::Add, - generic_array::{typenum::U1, ArrayLength}, - pkcs8::{ - der::{self, Decodable}, - FromPrivateKey, - }, -}; - -#[cfg(feature = "pem")] -use core::str::FromStr; - /// Elliptic curve secret keys. /// /// This type wraps a secret scalar value, helping to prevent accidental @@ -160,90 +146,6 @@ where } } -#[cfg(feature = "pkcs8")] -#[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))] -impl FromPrivateKey for SecretKey -where - C: weierstrass::Curve + AlgorithmParameters + SecretValue, - C::Secret: Clone + Zeroize, - FieldBytes: From, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, -{ - fn from_pkcs8_private_key_info( - private_key_info: pkcs8::PrivateKeyInfo<'_>, - ) -> pkcs8::Result { - if private_key_info.algorithm.oid != ALGORITHM_OID - || private_key_info.algorithm.parameters_oid() != Some(C::OID) - { - return Err(pkcs8::Error::Decode); - } - - let mut decoder = der::Decoder::new(private_key_info.private_key); - - let result = decoder.sequence(|decoder| { - // Parse and validate `version` INTEGER. - if i8::decode(decoder)? != 1 { - return Err(der::ErrorKind::Value { - tag: der::Tag::Integer, - } - .into()); - } - - let secret_key_field = decoder.octet_string()?; - let secret_key = Self::from_bytes(secret_key_field).map_err(|_| { - der::Error::from(der::ErrorKind::Value { - tag: der::Tag::Sequence, - }) - })?; - - let public_key_field = decoder.any()?; - public_key_field - .tag() - .assert_eq(der::Tag::ContextSpecific1)?; - - let mut public_key_decoder = der::Decoder::new(public_key_field.as_bytes()); - let public_key_bitstring = public_key_decoder.bit_string()?.as_bytes(); - - // Look for a leading `0x00` byte in the bitstring - if public_key_bitstring.get(0).cloned() != Some(0x00) { - return Err(der::ErrorKind::Value { - tag: der::Tag::BitString, - } - .into()); - } - - // TODO(tarcieri): add validations for public key - sec1::EncodedPoint::::from_bytes(&public_key_bitstring[1..]).map_err(|_| { - der::Error::from(der::ErrorKind::Value { - tag: der::Tag::BitString, - }) - })?; - - Ok(secret_key) - })?; - - Ok(decoder.finish(result)?) - } -} - -#[cfg(feature = "pem")] -#[cfg_attr(docsrs, doc(cfg(feature = "pem")))] -impl FromStr for SecretKey -where - C: weierstrass::Curve + AlgorithmParameters + SecretValue, - C::Secret: Clone + Zeroize, - FieldBytes: From, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, -{ - type Err = Error; - - fn from_str(s: &str) -> Result { - Self::from_pkcs8_pem(s).map_err(|_| Error) - } -} - impl Debug for SecretKey where C: Curve + SecretValue, diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs new file mode 100644 index 000000000..45e1a611f --- /dev/null +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -0,0 +1,181 @@ +//! PKCS#8 encoding/decoding support + +use super::{SecretKey, SecretValue}; +use crate::{ + sec1::{self, UncompressedPointSize, UntaggedPointSize}, + weierstrass, AlgorithmParameters, FieldBytes, ALGORITHM_OID, +}; +use core::ops::Add; +use generic_array::{typenum::U1, ArrayLength}; +use pkcs8::{ + der::{self, Decodable}, + FromPrivateKey, +}; +use zeroize::Zeroize; + +// Imports for the `ToPrivateKey` impl +// TODO(tarcieri): use weak activation of `pkcs8/alloc` for gating `ToPrivateKey` impl +#[cfg(all(feature = "pem"))] +use { + crate::{ + error::Error, + ff::PrimeField, + scalar::{NonZeroScalar, Scalar}, + sec1::{FromEncodedPoint, ToEncodedPoint}, + AffinePoint, ProjectiveArithmetic, ProjectivePoint, + }, + alloc::vec::Vec, + core::{fmt::Debug, iter}, + pkcs8::ToPrivateKey, +}; + +// Imports for actual PEM support +#[cfg(feature = "pem")] +use core::str::FromStr; + +/// Version +const VERSION: i8 = 1; + +/// Encoding error message +const ENCODING_ERROR_MSG: &str = "DER encoding error"; + +#[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))] +impl FromPrivateKey for SecretKey +where + C: weierstrass::Curve + AlgorithmParameters + SecretValue, + C::Secret: Clone + Zeroize, + FieldBytes: From, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + fn from_pkcs8_private_key_info( + private_key_info: pkcs8::PrivateKeyInfo<'_>, + ) -> pkcs8::Result { + if private_key_info.algorithm.oid != ALGORITHM_OID + || private_key_info.algorithm.parameters_oid() != Some(C::OID) + { + return Err(pkcs8::Error::Decode); + } + + let mut decoder = der::Decoder::new(private_key_info.private_key); + + let result = decoder.sequence(|decoder| { + if i8::decode(decoder)? != VERSION { + return Err(der::ErrorKind::Value { + tag: der::Tag::Integer, + } + .into()); + } + + let secret_key_field = decoder.octet_string()?; + let secret_key = Self::from_bytes(secret_key_field).map_err(|_| { + der::Error::from(der::ErrorKind::Value { + tag: der::Tag::Sequence, + }) + })?; + + let public_key_field = decoder.any()?; + public_key_field + .tag() + .assert_eq(der::Tag::ContextSpecific1)?; + + let mut public_key_decoder = der::Decoder::new(public_key_field.as_bytes()); + let public_key_bitstring = public_key_decoder.bit_string()?.as_bytes(); + + // Look for a leading `0x00` byte in the bitstring + if public_key_bitstring.get(0).cloned() != Some(0x00) { + return Err(der::ErrorKind::Value { + tag: der::Tag::BitString, + } + .into()); + } + + // TODO(tarcieri): add validations for public key + sec1::EncodedPoint::::from_bytes(&public_key_bitstring[1..]).map_err(|_| { + der::Error::from(der::ErrorKind::Value { + tag: der::Tag::BitString, + }) + })?; + + Ok(secret_key) + })?; + + Ok(decoder.finish(result)?) + } +} + +// TODO(tarcieri): use weak activation of `pkcs8/alloc` for this when possible +// It doesn't strictly depend on `pkcs8/pem` but we can't easily activate `pkcs8/alloc` +// without adding a separate crate feature just for this functionality. +#[cfg(feature = "pem")] +#[cfg_attr(docsrs, doc(cfg(feature = "pem")))] +impl ToPrivateKey for SecretKey +where + C: weierstrass::Curve + + AlgorithmParameters + + ProjectiveArithmetic + + SecretValue>, + FieldBytes: From> + for<'a> From<&'a Scalar>, + Scalar: PrimeField> + Zeroize, + AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, + ProjectivePoint: From>, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + fn to_pkcs8_der(&self) -> pkcs8::PrivateKeyDocument { + let mut secret_key_bytes = self.to_bytes(); + let secret_key_field = der::OctetString::new(&secret_key_bytes).expect(ENCODING_ERROR_MSG); + + let public_key_bytes = self.public_key().to_der_bitstring(); + let public_key_field = + der::Any::new(der::Tag::ContextSpecific1, &public_key_bytes).expect(ENCODING_ERROR_MSG); + + let der_message_fields: &[&dyn der::Encodable] = + &[&VERSION, &secret_key_field, &public_key_field]; + let encoded_len = der::sequence::encoded_len(der_message_fields) + .expect(ENCODING_ERROR_MSG) + .to_usize(); + + let mut der_message = Vec::new(); + der_message.reserve(encoded_len); + der_message.extend(iter::repeat(0).take(encoded_len)); + + let mut encoder = der::Encoder::new(&mut der_message); + encoder + .sequence(der_message_fields) + .expect(ENCODING_ERROR_MSG); + encoder.finish().expect(ENCODING_ERROR_MSG); + + let algorithm = pkcs8::AlgorithmIdentifier { + oid: ALGORITHM_OID, + parameters: Some(C::OID.into()), + }; + + let result = pkcs8::PrivateKeyInfo { + algorithm, + private_key: &der_message, + } + .to_der(); + + secret_key_bytes.zeroize(); + der_message.zeroize(); + result + } +} + +#[cfg(feature = "pem")] +#[cfg_attr(docsrs, doc(cfg(feature = "pem")))] +impl FromStr for SecretKey +where + C: weierstrass::Curve + AlgorithmParameters + SecretValue, + C::Secret: Clone + Zeroize, + FieldBytes: From, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + type Err = Error; + + fn from_str(s: &str) -> Result { + Self::from_pkcs8_pem(s).map_err(|_| Error) + } +} diff --git a/elliptic-curve/tests/pkcs8.rs b/elliptic-curve/tests/pkcs8.rs index 8bdb1b08c..f0ced6423 100644 --- a/elliptic-curve/tests/pkcs8.rs +++ b/elliptic-curve/tests/pkcs8.rs @@ -24,14 +24,14 @@ const PKCS8_PRIVATE_KEY_PEM: &str = include_str!("examples/pkcs8-private-key.pem const PKCS8_PUBLIC_KEY_PEM: &str = include_str!("examples/pkcs8-public-key.pem"); #[test] -fn parse_pkcs8_private_key_from_der() { +fn decode_pkcs8_private_key_from_der() { let secret_key = SecretKey::from_pkcs8_der(&PKCS8_PRIVATE_KEY_DER[..]).unwrap(); let expected_scalar = hex!("69624171561A63340DE0E7D869F2A05492558E1A04868B6A9F854A866788188D"); assert_eq!(secret_key.to_bytes().as_slice(), &expected_scalar[..]); } #[test] -fn parse_pkcs8_public_key_from_der() { +fn decode_pkcs8_public_key_from_der() { let public_key = PublicKey::from_public_key_der(&PKCS8_PUBLIC_KEY_DER[..]).unwrap(); let expected_sec1_point = hex!("041CACFFB55F2F2CEFD89D89EB374B2681152452802DEEA09916068137D839CF7FC481A44492304D7EF66AC117BEFE83A8D08F155F2B52F9F618DD447029048E0F"); assert_eq!( @@ -42,7 +42,7 @@ fn parse_pkcs8_public_key_from_der() { #[test] #[cfg(feature = "pem")] -fn parse_pkcs8_private_key_from_pem() { +fn decode_pkcs8_private_key_from_pem() { let secret_key = PKCS8_PRIVATE_KEY_PEM.parse::().unwrap(); // Ensure key parses equivalently to DER @@ -52,7 +52,7 @@ fn parse_pkcs8_private_key_from_pem() { #[test] #[cfg(feature = "pem")] -fn parse_pkcs8_public_key_from_pem() { +fn decode_pkcs8_public_key_from_pem() { let public_key = PKCS8_PUBLIC_KEY_PEM.parse::().unwrap(); // Ensure key parses equivalently to DER From a499a3cc62be019878e79e307634381f68901219 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 21 Dec 2020 20:54:41 -0800 Subject: [PATCH 0335/1461] elliptic-curve: PKCS#8 cleanups (#424) --- elliptic-curve/src/secret_key.rs | 5 ++++- elliptic-curve/src/secret_key/pkcs8.rs | 7 ++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 2aa4e9272..022557019 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -27,6 +27,9 @@ use crate::{ weierstrass, AffinePoint, ProjectiveArithmetic, ProjectivePoint, }; +#[cfg(all(docsrs, feature = "pkcs8"))] +use {crate::pkcs8::FromPrivateKey, core::str::FromStr}; + /// Elliptic curve secret keys. /// /// This type wraps a secret scalar value, helping to prevent accidental @@ -48,7 +51,7 @@ use crate::{ /// To decode an elliptic curve private key from PKCS#8, enable the `pkcs8` /// feature of this crate (or the `pkcs8` feature of a specific RustCrypto /// elliptic curve crate) and use the -/// [`elliptic_curve::pkcs8::FromPrivateKey`][`pkcs8::FromPrivateKey`] +/// [`elliptic_curve::pkcs8::FromPrivateKey`][`FromPrivateKey`] /// trait to parse it. /// /// When the `pem` feature of this crate (or a specific RustCrypto elliptic diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs index 45e1a611f..a1293b178 100644 --- a/elliptic-curve/src/secret_key/pkcs8.rs +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -20,7 +20,7 @@ use { crate::{ error::Error, ff::PrimeField, - scalar::{NonZeroScalar, Scalar}, + scalar::Scalar, sec1::{FromEncodedPoint, ToEncodedPoint}, AffinePoint, ProjectiveArithmetic, ProjectivePoint, }, @@ -111,10 +111,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "pem")))] impl ToPrivateKey for SecretKey where - C: weierstrass::Curve - + AlgorithmParameters - + ProjectiveArithmetic - + SecretValue>, + C: weierstrass::Curve + AlgorithmParameters + ProjectiveArithmetic, FieldBytes: From> + for<'a> From<&'a Scalar>, Scalar: PrimeField> + Zeroize, AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, From 6380870fe0f9b74ccf4ad8edee3540401cdbfdfa Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 21 Dec 2020 21:25:11 -0800 Subject: [PATCH 0336/1461] elliptic-curve: bump `pkcs8` dependency to v0.3.3 (#425) --- Cargo.lock | 13 ++++++++----- Cargo.toml | 3 --- elliptic-curve/Cargo.toml | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3a2eb25c8..e5dc631dc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -94,7 +94,8 @@ dependencies = [ [[package]] name = "const-oid" version = "0.4.1" -source = "git+https://github.com/RustCrypto/utils.git#005b32230010de490fc75d6ca6e58dd8b0c90837" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5d82796b70971fbb603900a5edc797a4d9be0f9ec1257f83a1dba0aa374e3e9" [[package]] name = "cpuid-bool" @@ -127,8 +128,9 @@ dependencies = [ [[package]] name = "der" -version = "0.0.0" -source = "git+https://github.com/RustCrypto/utils.git#005b32230010de490fc75d6ca6e58dd8b0c90837" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51f59c66c30bb7445c8320a5f9233e437e3572368099f25532a59054328899b4" dependencies = [ "const-oid", ] @@ -270,8 +272,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "pkcs8" -version = "0.3.2" -source = "git+https://github.com/RustCrypto/utils.git#005b32230010de490fc75d6ca6e58dd8b0c90837" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4839a901843f3942576e65857f0ebf2e190ef7024d3c62a94099ba3f819ad1d" dependencies = [ "der", "subtle-encoding", diff --git a/Cargo.toml b/Cargo.toml index c82783df0..943b0d7a1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,3 @@ members = [ "signature/async", "universal-hash", ] - -[patch.crates-io] -pkcs8 = { git = "https://github.com/RustCrypto/utils.git" } diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 6f01e45cb..e8a37ab31 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -20,7 +20,7 @@ digest = { version = "0.9", optional = true } ff = { version = "0.8", optional = true, default-features = false } group = { version = "0.8", optional = true, default-features = false } generic-array = { version = "0.14", default-features = false } -pkcs8 = { version = "0.3", optional = true } +pkcs8 = { version = "0.3.3", optional = true } rand_core = { version = "0.5", default-features = false } subtle = { version = "2.4", default-features = false } zeroize = { version = "1", optional = true, default-features = false } From 37ddc60b05afd86d4a2b01fd2723be1d7a54e343 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 22 Dec 2020 06:55:09 -0800 Subject: [PATCH 0337/1461] elliptic-curve: impl `pkcs8::ToPublicKey` for `PublicKey` (#427) Adds support for serializing `PublicKey` as ASN.1 DER and PEM. --- elliptic-curve/src/lib.rs | 8 ++++ elliptic-curve/src/public_key.rs | 58 ++++++++++++++++++++++---- elliptic-curve/src/secret_key/pkcs8.rs | 32 +++++++------- 3 files changed, 73 insertions(+), 25 deletions(-) diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 08fd5c5be..f99381092 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -139,4 +139,12 @@ pub trait FromDigest { pub trait AlgorithmParameters: Curve { /// Object Identifier (OID) for this curve const OID: pkcs8::ObjectIdentifier; + + /// Get the [`pkcs8::AlgorithmIdentifier`] for this curve + fn algorithm_identifier() -> pkcs8::AlgorithmIdentifier { + pkcs8::AlgorithmIdentifier { + oid: ALGORITHM_OID, + parameters: Some(Self::OID.into()), + } + } } diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index f2799b73a..09d4df868 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -26,9 +26,12 @@ use { #[cfg(feature = "pem")] use { - alloc::vec::Vec, + alloc::{ + string::{String, ToString}, + vec::Vec, + }, core::str::FromStr, - pkcs8::der::{self, Encodable}, + pkcs8::ToPublicKey, }; /// Elliptic curve public keys. @@ -133,13 +136,10 @@ where UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { - let mut body_bytes = Vec::new(); - body_bytes.push(0); - body_bytes.extend_from_slice(self.to_encoded_point(false).as_ref()); - - der::BitString::new(&body_bytes) - .and_then(|bit_string| bit_string.to_vec()) - .expect("DER encoding error") + let mut bitstring = Vec::new(); + bitstring.push(0); + bitstring.extend_from_slice(self.to_encoded_point(false).as_ref()); + bitstring } } @@ -319,6 +319,29 @@ where } } +#[cfg(feature = "pem")] +#[cfg_attr(docsrs, doc(cfg(feature = "pem")))] +impl ToPublicKey for PublicKey +where + C: Curve + AlgorithmParameters + ProjectiveArithmetic, + FieldBytes: From> + for<'r> From<&'r Scalar>, + Scalar: PrimeField>, + AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, + ProjectivePoint: From>, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + fn to_public_key_der(&self) -> pkcs8::PublicKeyDocument { + let public_key_bytes = self.to_der_bitstring(); + + pkcs8::SubjectPublicKeyInfo { + algorithm: C::algorithm_identifier(), + subject_public_key: &public_key_bytes, + } + .to_der() + } +} + #[cfg(feature = "pem")] #[cfg_attr(docsrs, doc(cfg(feature = "pem")))] impl FromStr for PublicKey @@ -339,6 +362,23 @@ where } } +#[cfg(feature = "pem")] +#[cfg_attr(docsrs, doc(cfg(feature = "pem")))] +impl ToString for PublicKey +where + C: Curve + AlgorithmParameters + ProjectiveArithmetic, + FieldBytes: From> + for<'r> From<&'r Scalar>, + Scalar: PrimeField>, + AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, + ProjectivePoint: From>, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + fn to_string(&self) -> String { + self.to_public_key_pem() + } +} + #[cfg(all(feature = "dev", test))] mod tests { use crate::{dev::MockCurve, sec1::FromEncodedPoint}; diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs index a1293b178..138219682 100644 --- a/elliptic-curve/src/secret_key/pkcs8.rs +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -26,7 +26,8 @@ use { }, alloc::vec::Vec, core::{fmt::Debug, iter}, - pkcs8::ToPrivateKey, + pkcs8::{der::Encodable, ToPrivateKey}, + zeroize::Zeroizing, }; // Imports for actual PEM support @@ -37,6 +38,7 @@ use core::str::FromStr; const VERSION: i8 = 1; /// Encoding error message +#[cfg(feature = "pem")] const ENCODING_ERROR_MSG: &str = "DER encoding error"; #[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))] @@ -120,20 +122,25 @@ where UncompressedPointSize: ArrayLength, { fn to_pkcs8_der(&self) -> pkcs8::PrivateKeyDocument { + // TODO(tarcieri): wrap `secret_key_bytes` in `Zeroizing` let mut secret_key_bytes = self.to_bytes(); let secret_key_field = der::OctetString::new(&secret_key_bytes).expect(ENCODING_ERROR_MSG); - let public_key_bytes = self.public_key().to_der_bitstring(); + let public_key_body = self.public_key().to_der_bitstring(); + let public_key_bytes = der::BitString::new(&public_key_body) + .and_then(|bit_string| bit_string.to_vec()) + .expect("DER encoding error"); let public_key_field = der::Any::new(der::Tag::ContextSpecific1, &public_key_bytes).expect(ENCODING_ERROR_MSG); - let der_message_fields: &[&dyn der::Encodable] = + let der_message_fields: &[&dyn Encodable] = &[&VERSION, &secret_key_field, &public_key_field]; + let encoded_len = der::sequence::encoded_len(der_message_fields) .expect(ENCODING_ERROR_MSG) .to_usize(); - let mut der_message = Vec::new(); + let mut der_message = Zeroizing::new(Vec::new()); der_message.reserve(encoded_len); der_message.extend(iter::repeat(0).take(encoded_len)); @@ -141,22 +148,15 @@ where encoder .sequence(der_message_fields) .expect(ENCODING_ERROR_MSG); - encoder.finish().expect(ENCODING_ERROR_MSG); - let algorithm = pkcs8::AlgorithmIdentifier { - oid: ALGORITHM_OID, - parameters: Some(C::OID.into()), - }; + encoder.finish().expect(ENCODING_ERROR_MSG); + secret_key_bytes.zeroize(); - let result = pkcs8::PrivateKeyInfo { - algorithm, + pkcs8::PrivateKeyInfo { + algorithm: C::algorithm_identifier(), private_key: &der_message, } - .to_der(); - - secret_key_bytes.zeroize(); - der_message.zeroize(); - result + .to_der() } } From bd58701c82cf88c344646f42e55f7580c03f6a91 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 22 Dec 2020 07:13:50 -0800 Subject: [PATCH 0338/1461] elliptic-curve v0.8.2 (#428) --- Cargo.lock | 2 +- elliptic-curve/CHANGELOG.md | 24 ++++++++++++++++++++++++ elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 2 +- 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e5dc631dc..0cd820586 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -154,7 +154,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.8.1" +version = "0.8.2" dependencies = [ "bitvec", "digest 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index 3b38b55d8..09961c134 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,30 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.8.2 (2020-12-22) +### Added +- Low-level ECDH API ([#418]) +- `dev` module ([#419]) +- Impl `pkcs8::ToPrivateKey` for `SecretKey` ([#423]) +- Impl `pkcs8::ToPublicKey` for `PublicKey` ([#427]) + +### Changed +- Bump `subtle` dependency to 2.4.0 ([#414]) +- Bump `pkcs8` dependency to v0.3.3 ([#425]) +- Use `der` crate to parse `SecretKey` ([#422]) + +### Fixed +- Make `PublicKey::from_encoded_point` go through `PublicKey::from_affine` ([#416]) + +[#414]: https://github.com/RustCrypto/traits/pull/414 +[#416]: https://github.com/RustCrypto/traits/pull/416 +[#418]: https://github.com/RustCrypto/traits/pull/418 +[#419]: https://github.com/RustCrypto/traits/pull/419 +[#422]: https://github.com/RustCrypto/traits/pull/422 +[#423]: https://github.com/RustCrypto/traits/pull/423 +[#425]: https://github.com/RustCrypto/traits/pull/425 +[#427]: https://github.com/RustCrypto/traits/pull/427 + ## 0.8.1 (2020-12-16) ### Fixed - Builds on Rust `nightly` compiler ([#412]) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index e8a37ab31..acc649283 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -5,7 +5,7 @@ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. """ -version = "0.8.1" # Also update html_root_url in lib.rs when bumping this +version = "0.8.2" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" repository = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve" diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index f99381092..34e4e0861 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -16,7 +16,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.8.1" + html_root_url = "https://docs.rs/elliptic-curve/0.8.2" )] #[cfg(feature = "alloc")] From d04bdc0a08ca983a50abce283364025e9e1a69a8 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 22 Dec 2020 07:33:10 -0800 Subject: [PATCH 0339/1461] elliptic-curve: fix regression for `pem`+`zeroize` features (#429) ...in the case when the `arithmetic` feature is disabled, as used by the `p384` crate (which does support PKCS#8, but does not provide an arithmetic backend) Also adds tests for this combination in CI to prevent further regressions. --- .github/workflows/elliptic-curve.yml | 1 + elliptic-curve/src/secret_key/pkcs8.rs | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index e83d0e9f3..0b83fdc41 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -42,6 +42,7 @@ jobs: - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features pem - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features pkcs8 - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features zeroize + - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features pem,zeroize test: runs-on: ubuntu-latest strategy: diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs index 138219682..2750a864c 100644 --- a/elliptic-curve/src/secret_key/pkcs8.rs +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -15,10 +15,9 @@ use zeroize::Zeroize; // Imports for the `ToPrivateKey` impl // TODO(tarcieri): use weak activation of `pkcs8/alloc` for gating `ToPrivateKey` impl -#[cfg(all(feature = "pem"))] +#[cfg(all(feature = "arithmetic", feature = "pem"))] use { crate::{ - error::Error, ff::PrimeField, scalar::Scalar, sec1::{FromEncodedPoint, ToEncodedPoint}, @@ -32,13 +31,13 @@ use { // Imports for actual PEM support #[cfg(feature = "pem")] -use core::str::FromStr; +use {crate::error::Error, core::str::FromStr}; /// Version const VERSION: i8 = 1; /// Encoding error message -#[cfg(feature = "pem")] +#[cfg(all(feature = "arithmetic", feature = "pem"))] const ENCODING_ERROR_MSG: &str = "DER encoding error"; #[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))] @@ -109,7 +108,8 @@ where // TODO(tarcieri): use weak activation of `pkcs8/alloc` for this when possible // It doesn't strictly depend on `pkcs8/pem` but we can't easily activate `pkcs8/alloc` // without adding a separate crate feature just for this functionality. -#[cfg(feature = "pem")] +#[cfg(all(feature = "arithmetic", feature = "pem"))] +#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] #[cfg_attr(docsrs, doc(cfg(feature = "pem")))] impl ToPrivateKey for SecretKey where From d7cd86ee8137b4e81ce48b17ae11eeb12d62f5e8 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 22 Dec 2020 07:45:52 -0800 Subject: [PATCH 0340/1461] elliptic-curve v0.8.3 (#430) --- Cargo.lock | 2 +- elliptic-curve/CHANGELOG.md | 12 +++++++++--- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 2 +- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0cd820586..564401e55 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -154,7 +154,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.8.2" +version = "0.8.3" dependencies = [ "bitvec", "digest 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index 09961c134..5a9812894 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,7 +4,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 0.8.2 (2020-12-22) +## 0.8.3 (2020-12-22) +### Fixed +- Regression in combination of `pem`+`zeroize` features ([#429]) + +[#429]: https://github.com/RustCrypto/traits/pull/429 + +## 0.8.2 (2020-12-22) [YANKED] ### Added - Low-level ECDH API ([#418]) - `dev` module ([#419]) @@ -28,13 +34,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [#425]: https://github.com/RustCrypto/traits/pull/425 [#427]: https://github.com/RustCrypto/traits/pull/427 -## 0.8.1 (2020-12-16) +## 0.8.1 (2020-12-16) [YANKED] ### Fixed - Builds on Rust `nightly` compiler ([#412]) [#412]: https://github.com/RustCrypto/traits/pull/412 -## 0.8.0 (2020-12-16) +## 0.8.0 (2020-12-16) [YANKED] ### Added - Impl `subtle::ConditionallySelectable` for `sec1::EncodedPoint` ([#409]) - `sec1::EncodedPoint::identity()` method ([#408]) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index acc649283..8ad8e7128 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -5,7 +5,7 @@ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. """ -version = "0.8.2" # Also update html_root_url in lib.rs when bumping this +version = "0.8.3" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" repository = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve" diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 34e4e0861..671df368a 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -16,7 +16,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.8.2" + html_root_url = "https://docs.rs/elliptic-curve/0.8.3" )] #[cfg(feature = "alloc")] From 4524ad40a71e2593931e5c3ebe5ca30023172587 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 23 Dec 2020 11:01:49 -0800 Subject: [PATCH 0341/1461] elliptic-curve: fix nightly regression (and add nightly CI) (#432) This is the second such regression we've had recently (see also #412). It seems to be some sort of trait resolution change/breakage, although beyond that I'm not sure what the problem is. --- .github/workflows/elliptic-curve.yml | 1 + elliptic-curve/src/ecdh.rs | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index 0b83fdc41..e5748876e 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -50,6 +50,7 @@ jobs: rust: - 1.46.0 # MSRV - stable + - nightly steps: - uses: actions/checkout@v1 - uses: actions-rs/toolchain@v1 diff --git a/elliptic-curve/src/ecdh.rs b/elliptic-curve/src/ecdh.rs index 781ae68ba..df4192e00 100644 --- a/elliptic-curve/src/ecdh.rs +++ b/elliptic-curve/src/ecdh.rs @@ -74,7 +74,8 @@ where UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { - let shared_secret = ProjectivePoint::::from(*public_key.borrow()) * secret_key.borrow(); + let shared_secret = + ProjectivePoint::::from(*public_key.borrow()) * secret_key.borrow().as_ref(); // SharedSecret::new expects an uncompressed point // TODO(tarcieri): avoid point encoding when computing shared secret From fb84fc2528b8419d3b3cf29d93eb8a6217f1c141 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 23 Dec 2020 11:06:24 -0800 Subject: [PATCH 0342/1461] elliptic-curve v0.8.4 (#433) --- Cargo.lock | 2 +- elliptic-curve/CHANGELOG.md | 6 ++++++ elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 564401e55..bbe5421f8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -154,7 +154,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.8.3" +version = "0.8.4" dependencies = [ "bitvec", "digest 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index 5a9812894..704aa3463 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.8.4 (2020-12-23) +### Fixed +- Rust `nightly` regression ([#432]) + +[#432]: https://github.com/RustCrypto/traits/pull/432 + ## 0.8.3 (2020-12-22) ### Fixed - Regression in combination of `pem`+`zeroize` features ([#429]) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 8ad8e7128..ac25b0cf8 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -5,7 +5,7 @@ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. """ -version = "0.8.3" # Also update html_root_url in lib.rs when bumping this +version = "0.8.4" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" repository = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve" diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 671df368a..717100cd8 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -16,7 +16,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.8.3" + html_root_url = "https://docs.rs/elliptic-curve/0.8.4" )] #[cfg(feature = "alloc")] From d5d137d17ac51b0b31854b2693de6ec4ffc9fb8d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 29 Dec 2020 17:38:53 -0800 Subject: [PATCH 0343/1461] cipher: v0.3 changes (#435) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - remove `SeekNum` impls for signed integers - fix block mode compilation bug - change `SeekNum` impls to fit with the new `BlockBuffer` - return `SeenNum` impl for `i32` - re-export `blobby` from root - reorganize modules Co-authored-by: Артём Павлов [Artyom Pavlov] --- cipher/src/block.rs | 16 +-- cipher/src/common.rs | 79 +++++++++++ cipher/src/dev.rs | 2 + cipher/src/{block/dev.rs => dev/block.rs} | 16 +-- cipher/src/{stream/dev.rs => dev/stream.rs} | 14 +- cipher/src/errors.rs | 2 +- cipher/src/lib.rs | 17 +-- cipher/src/stream.rs | 142 +++----------------- crypto-mac/src/lib.rs | 6 +- 9 files changed, 136 insertions(+), 158 deletions(-) create mode 100644 cipher/src/common.rs create mode 100644 cipher/src/dev.rs rename cipher/src/{block/dev.rs => dev/block.rs} (91%) rename cipher/src/{stream/dev.rs => dev/stream.rs} (93%) diff --git a/cipher/src/block.rs b/cipher/src/block.rs index 16205ba86..4e08dc259 100644 --- a/cipher/src/block.rs +++ b/cipher/src/block.rs @@ -9,21 +9,17 @@ //! [1]: https://en.wikipedia.org/wiki/Block_cipher //! [2]: https://en.wikipedia.org/wiki/Symmetric-key_algorithm -#[cfg(feature = "dev")] -#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] -pub mod dev; - use crate::errors::InvalidLength; use core::convert::TryInto; use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; /// Key for an algorithm that implements [`NewBlockCipher`]. -pub type Key = GenericArray::KeySize>; +pub type BlockCipherKey = GenericArray::KeySize>; /// Block on which a [`BlockCipher`] operates. pub type Block = GenericArray::BlockSize>; -/// Blocks being acted over in parallel. +/// Block on which a [`BlockCipher`] operates in parallel. pub type ParBlocks = GenericArray, ::ParBlocks>; /// Instantiate a [`BlockCipher`] algorithm. @@ -32,13 +28,13 @@ pub trait NewBlockCipher: Sized { type KeySize: ArrayLength; /// Create new block cipher instance from key with fixed size. - fn new(key: &Key) -> Self; + fn new(key: &BlockCipherKey) -> Self; /// Create new block cipher instance from key with variable size. /// /// Default implementation will accept only keys with length equal to /// `KeySize`, but some ciphers can accept range of key lengths. - fn new_varkey(key: &[u8]) -> Result { + fn new_var(key: &[u8]) -> Result { if key.len() != Self::KeySize::to_usize() { Err(InvalidLength) } else { @@ -57,7 +53,7 @@ pub trait BlockCipher { type ParBlocks: ArrayLength>; } -/// Encrypt-only functionality for block ciphers +/// Encrypt-only functionality for block ciphers. pub trait BlockEncrypt: BlockCipher { /// Encrypt block in-place fn encrypt_block(&self, block: &mut Block); @@ -94,7 +90,7 @@ pub trait BlockEncrypt: BlockCipher { } } -/// Decrypt-only functionality for block ciphers +/// Decrypt-only functionality for block ciphers. pub trait BlockDecrypt: BlockCipher { /// Decrypt block in-place fn decrypt_block(&self, block: &mut Block); diff --git a/cipher/src/common.rs b/cipher/src/common.rs new file mode 100644 index 000000000..ef7e7d6d6 --- /dev/null +++ b/cipher/src/common.rs @@ -0,0 +1,79 @@ +use crate::{errors::InvalidLength, BlockCipher, NewBlockCipher}; +use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; + +/// Key for an algorithm that implements [`NewCipher`]. +pub type CipherKey = GenericArray::KeySize>; + +/// Nonce for an algorithm that implements [`NewCipher`]. +pub type Nonce = GenericArray::NonceSize>; + +/// Cipher creation trait. +/// +/// It can be used for creation of block modes, synchronous and asynchronous stream ciphers. +pub trait NewCipher: Sized { + /// Key size in bytes + type KeySize: ArrayLength; + + /// Nonce size in bytes + type NonceSize: ArrayLength; + + /// Create new stream cipher instance from variable length key and nonce. + fn new(key: &CipherKey, nonce: &Nonce) -> Self; + + /// Create new stream cipher instance from variable length key and nonce. + #[inline] + fn new_var(key: &[u8], nonce: &[u8]) -> Result { + let kl = Self::KeySize::to_usize(); + let nl = Self::NonceSize::to_usize(); + if key.len() != kl || nonce.len() != nl { + Err(InvalidLength) + } else { + let key = GenericArray::from_slice(key); + let nonce = GenericArray::from_slice(nonce); + Ok(Self::new(key, nonce)) + } + } +} + +/// Trait for types which can be initialized from a block cipher and nonce. +pub trait FromBlockCipher { + /// Block cipher + type BlockCipher: BlockCipher; + /// Nonce size in bytes + type NonceSize: ArrayLength; + + /// Instantiate a stream cipher from a block cipher + fn from_block_cipher( + cipher: Self::BlockCipher, + nonce: &GenericArray, + ) -> Self; +} + +impl NewCipher for C +where + C: FromBlockCipher, + C::BlockCipher: NewBlockCipher, +{ + type KeySize = <::BlockCipher as NewBlockCipher>::KeySize; + type NonceSize = ::NonceSize; + + fn new(key: &CipherKey, nonce: &Nonce) -> C { + C::from_block_cipher( + <::BlockCipher as NewBlockCipher>::new(key), + nonce, + ) + } + + fn new_var(key: &[u8], nonce: &[u8]) -> Result { + if nonce.len() != Self::NonceSize::USIZE { + Err(InvalidLength) + } else { + C::BlockCipher::new_var(key) + .map_err(|_| InvalidLength) + .map(|cipher| { + let nonce = GenericArray::from_slice(nonce); + Self::from_block_cipher(cipher, nonce) + }) + } + } +} diff --git a/cipher/src/dev.rs b/cipher/src/dev.rs new file mode 100644 index 000000000..6bedbe989 --- /dev/null +++ b/cipher/src/dev.rs @@ -0,0 +1,2 @@ +mod block; +mod stream; diff --git a/cipher/src/block/dev.rs b/cipher/src/dev/block.rs similarity index 91% rename from cipher/src/block/dev.rs rename to cipher/src/dev/block.rs index 8c4f2fda9..e3ac0867b 100644 --- a/cipher/src/block/dev.rs +++ b/cipher/src/dev/block.rs @@ -9,13 +9,13 @@ macro_rules! block_cipher_test { ($name:ident, $test_name:expr, $cipher:ty) => { #[test] fn $name() { - use cipher::block::{ - dev::blobby::Blob3Iterator, BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher, - }; use cipher::generic_array::{typenum::Unsigned, GenericArray}; + use cipher::{ + blobby::Blob3Iterator, BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher, + }; fn run_test(key: &[u8], pt: &[u8], ct: &[u8]) -> bool { - let state = <$cipher as NewBlockCipher>::new_varkey(key).unwrap(); + let state = <$cipher as NewBlockCipher>::new_var(key).unwrap(); let mut block = GenericArray::clone_from_slice(pt); state.encrypt_block(&mut block); @@ -37,7 +37,7 @@ macro_rules! block_cipher_test { type Block = GenericArray; type ParBlock = GenericArray; - let state = <$cipher as NewBlockCipher>::new_varkey(key).unwrap(); + let state = <$cipher as NewBlockCipher>::new_var(key).unwrap(); let block = Block::clone_from_slice(pt); let mut blocks1 = ParBlock::default(); @@ -113,12 +113,12 @@ macro_rules! block_cipher_bench { ($cipher:path, $key_len:expr) => { extern crate test; - use cipher::block::{BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher}; + use cipher::{BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher}; use test::Bencher; #[bench] pub fn encrypt(bh: &mut Bencher) { - let state = <$cipher>::new_varkey(&[1u8; $key_len]).unwrap(); + let state = <$cipher>::new_var(&[1u8; $key_len]).unwrap(); let mut block = Default::default(); bh.iter(|| { @@ -130,7 +130,7 @@ macro_rules! block_cipher_bench { #[bench] pub fn decrypt(bh: &mut Bencher) { - let state = <$cipher>::new_varkey(&[1u8; $key_len]).unwrap(); + let state = <$cipher>::new_var(&[1u8; $key_len]).unwrap(); let mut block = Default::default(); bh.iter(|| { diff --git a/cipher/src/stream/dev.rs b/cipher/src/dev/stream.rs similarity index 93% rename from cipher/src/stream/dev.rs rename to cipher/src/dev/stream.rs index 92e5c9331..e83b7af11 100644 --- a/cipher/src/stream/dev.rs +++ b/cipher/src/dev/stream.rs @@ -3,12 +3,12 @@ /// Test core functionality of synchronous stream cipher #[macro_export] #[cfg_attr(docsrs, doc(cfg(feature = "dev")))] -macro_rules! stream_cipher_sync_test { +macro_rules! stream_cipher_test { ($name:ident, $cipher:ty, $test_name:expr) => { #[test] fn $name() { use cipher::generic_array::GenericArray; - use cipher::stream::{blobby::Blob4Iterator, NewStreamCipher, SyncStreamCipher}; + use cipher::{blobby::Blob4Iterator, NewCipher, StreamCipher}; let data = include_bytes!(concat!("data/", $test_name, ".blb")); for (i, row) in Blob4Iterator::new(data).unwrap().enumerate() { @@ -44,7 +44,7 @@ macro_rules! stream_cipher_seek_test { #[test] fn $name() { use cipher::generic_array::GenericArray; - use cipher::stream::{NewStreamCipher, SyncStreamCipher, SyncStreamCipherSeek}; + use cipher::{NewCipher, StreamCipher, StreamCipherSeek}; fn get_cipher() -> $cipher { <$cipher>::new(&Default::default(), &Default::default()) @@ -97,7 +97,7 @@ macro_rules! stream_cipher_async_test { #[test] fn $name() { use cipher::generic_array::GenericArray; - use cipher::stream::{blobby::Blob4Iterator, NewStreamCipher, StreamCipher}; + use cipher::{blobby::Blob4Iterator, AsyncStreamCipher, NewCipher}; fn run_test( key: &[u8], @@ -172,8 +172,7 @@ macro_rules! stream_cipher_sync_bench { ($cipher:path) => { extern crate test; - use cipher::generic_array::GenericArray; - use cipher::stream::{NewStreamCipher, SyncStreamCipher}; + use cipher::{generic_array::GenericArray, NewCipher, StreamCipher}; use test::Bencher; #[inline(never)] @@ -225,8 +224,7 @@ macro_rules! stream_cipher_async_bench { ($cipher:path) => { extern crate test; - use cipher::generic_array::GenericArray; - use cipher::stream::{NewStreamCipher, StreamCipher}; + use cipher::{generic_array::GenericArray, AsyncStreamCipher, NewCipher}; use test::Bencher; #[inline(never)] diff --git a/cipher/src/errors.rs b/cipher/src/errors.rs index 089a7a077..f52736517 100644 --- a/cipher/src/errors.rs +++ b/cipher/src/errors.rs @@ -1,4 +1,4 @@ -//! Error types +//! Error types. use core::fmt; diff --git a/cipher/src/lib.rs b/cipher/src/lib.rs index 5a9dcd182..d0766d8de 100644 --- a/cipher/src/lib.rs +++ b/cipher/src/lib.rs @@ -16,14 +16,15 @@ #[cfg(feature = "std")] extern crate std; -pub mod block; +#[cfg(feature = "dev")] +pub use blobby; + +mod block; +mod common; +#[cfg(feature = "dev")] +mod dev; pub mod errors; -pub mod stream; +mod stream; -pub use crate::{ - block::{ - BlockCipher, BlockDecrypt, BlockDecryptMut, BlockEncrypt, BlockEncryptMut, NewBlockCipher, - }, - stream::{NewStreamCipher, StreamCipher, SyncStreamCipher, SyncStreamCipherSeek}, -}; +pub use crate::{block::*, common::*, stream::*}; pub use generic_array::{self, typenum::consts}; diff --git a/cipher/src/stream.rs b/cipher/src/stream.rs index f5daf01e3..843ff56eb 100644 --- a/cipher/src/stream.rs +++ b/cipher/src/stream.rs @@ -3,56 +3,11 @@ //! See [RustCrypto/stream-ciphers](https://github.com/RustCrypto/stream-ciphers) //! for ciphers implementation. -#[cfg(feature = "dev")] -mod dev; - -#[cfg(feature = "dev")] -pub use blobby; - -use crate::{ - block::{BlockCipher, NewBlockCipher}, - errors::{InvalidLength, LoopError, OverflowError}, -}; +use crate::errors::{LoopError, OverflowError}; use core::convert::{TryFrom, TryInto}; -use generic_array::typenum::Unsigned; -use generic_array::{ArrayLength, GenericArray}; - -/// Key for an algorithm that implements [`NewStreamCipher`]. -pub type Key = GenericArray::KeySize>; - -/// Nonce for an algorithm that implements [`NewStreamCipher`]. -pub type Nonce = GenericArray::NonceSize>; - -/// Stream cipher creation trait. -/// -/// It can be used for creation of synchronous and asynchronous ciphers. -pub trait NewStreamCipher: Sized { - /// Key size in bytes - type KeySize: ArrayLength; - - /// Nonce size in bytes - type NonceSize: ArrayLength; - - /// Create new stream cipher instance from variable length key and nonce. - fn new(key: &Key, nonce: &Nonce) -> Self; - - /// Create new stream cipher instance from variable length key and nonce. - #[inline] - fn new_var(key: &[u8], nonce: &[u8]) -> Result { - let kl = Self::KeySize::to_usize(); - let nl = Self::NonceSize::to_usize(); - if key.len() != kl || nonce.len() != nl { - Err(InvalidLength) - } else { - let key = GenericArray::from_slice(key); - let nonce = GenericArray::from_slice(nonce); - Ok(Self::new(key, nonce)) - } - } -} /// Synchronous stream cipher core trait. -pub trait SyncStreamCipher { +pub trait StreamCipher { /// Apply keystream to the data. /// /// It will XOR generated keystream with the data, which can be both @@ -63,10 +18,7 @@ pub trait SyncStreamCipher { /// method will panic without modifying the provided `data`. #[inline] fn apply_keystream(&mut self, data: &mut [u8]) { - let res = self.try_apply_keystream(data); - if res.is_err() { - panic!("stream cipher loop detected"); - } + self.try_apply_keystream(data).unwrap(); } /// Apply keystream to the data, but return an error if end of a keystream @@ -82,7 +34,7 @@ pub trait SyncStreamCipher { /// Methods of this trait are generic over the [`SeekNum`] trait, which is /// implemented for primitive numeric types, i.e.: `i/u8`, `i/u16`, `i/u32`, /// `i/u64`, `i/u128`, and `i/usize`. -pub trait SyncStreamCipherSeek { +pub trait StreamCipherSeek { /// Try to get current keystream position /// /// Returns [`LoopError`] if position can not be represented by type `T` @@ -91,7 +43,7 @@ pub trait SyncStreamCipherSeek { /// Try to seek to the given position /// /// Returns [`LoopError`] if provided position value is bigger than - /// keystream leangth + /// keystream length. fn try_seek(&mut self, pos: T) -> Result<(), LoopError>; /// Get current keystream position @@ -111,12 +63,8 @@ pub trait SyncStreamCipherSeek { } } -/// Stream cipher core trait which covers both synchronous and asynchronous -/// ciphers. -/// -/// Note that for synchronous ciphers `encrypt` and `decrypt` are equivalent to -/// each other. -pub trait StreamCipher { +/// Asynchronous stream cipher core trait. +pub trait AsyncStreamCipher { /// Encrypt data in place. fn encrypt(&mut self, data: &mut [u8]); @@ -124,19 +72,7 @@ pub trait StreamCipher { fn decrypt(&mut self, data: &mut [u8]); } -impl StreamCipher for C { - #[inline(always)] - fn encrypt(&mut self, data: &mut [u8]) { - SyncStreamCipher::apply_keystream(self, data); - } - - #[inline(always)] - fn decrypt(&mut self, data: &mut [u8]) { - SyncStreamCipher::apply_keystream(self, data); - } -} - -impl SyncStreamCipher for &mut C { +impl StreamCipher for &mut C { #[inline] fn apply_keystream(&mut self, data: &mut [u8]) { C::apply_keystream(self, data); @@ -148,54 +84,11 @@ impl SyncStreamCipher for &mut C { } } -/// Trait for initializing a stream cipher from a block cipher -pub trait FromBlockCipher { - /// Block cipher - type BlockCipher: BlockCipher; - /// Nonce size in bytes - type NonceSize: ArrayLength; - - /// Instantiate a stream cipher from a block cipher - fn from_block_cipher( - cipher: Self::BlockCipher, - nonce: &GenericArray, - ) -> Self; -} - -impl NewStreamCipher for C -where - C: FromBlockCipher, - C::BlockCipher: NewBlockCipher, -{ - type KeySize = <::BlockCipher as NewBlockCipher>::KeySize; - type NonceSize = ::NonceSize; - - fn new(key: &Key, nonce: &Nonce) -> C { - C::from_block_cipher( - <::BlockCipher as NewBlockCipher>::new(key), - nonce, - ) - } - - fn new_var(key: &[u8], nonce: &[u8]) -> Result { - if nonce.len() != Self::NonceSize::USIZE { - Err(InvalidLength) - } else { - C::BlockCipher::new_varkey(key) - .map_err(|_| InvalidLength) - .map(|cipher| { - let nonce = GenericArray::from_slice(nonce); - Self::from_block_cipher(cipher, nonce) - }) - } - } -} - /// Trait implemented for numeric types which can be used with the -/// [`SyncStreamCipherSeek`] trait. +/// [`StreamCipherSeek`] trait. /// /// This trait is implemented for primitive numeric types, i.e. `i/u8`, -/// `i/u16`, `i/u32`, `i/u64`, `i/u128`, and `i/usize`. It is not intended +/// `u16`, `u32`, `u64`, `u128`, `usize`, and `i32`. It is not intended /// to be implemented in third-party crates. #[rustfmt::skip] pub trait SeekNum: @@ -221,8 +114,17 @@ macro_rules! impl_seek_num { impl SeekNum for $t { fn from_block_byte>(block: T, byte: u8, bs: u8) -> Result { debug_assert!(byte < bs); - let block = block.try_into().map_err(|_| OverflowError)?; - let pos = block.checked_mul(bs as Self).ok_or(OverflowError)? + (byte as Self); + let pos = block + .try_into() + .ok() + .and_then(|v| match byte == 0 { + true => Some(v), + // if `byte` is not zero, then block counter was incremented + false => v.checked_sub(1), + }) + .and_then(|v| v.checked_mul(bs as Self)) + .and_then(|v| v.checked_add(byte as Self)) + .ok_or(OverflowError)?; Ok(pos) } @@ -237,4 +139,4 @@ macro_rules! impl_seek_num { }; } -impl_seek_num! { u8 i8 u16 i16 u32 i32 u64 i64 u128 i128 isize usize } +impl_seek_num! { u8 u16 u32 u64 u128 usize i32 } diff --git a/crypto-mac/src/lib.rs b/crypto-mac/src/lib.rs index 51e26bc09..c5d08e925 100644 --- a/crypto-mac/src/lib.rs +++ b/crypto-mac/src/lib.rs @@ -45,7 +45,7 @@ pub trait NewMac: Sized { /// /// Default implementation will accept only keys with length equal to /// `KeySize`, but some MACs can accept range of key lengths. - fn new_varkey(key: &[u8]) -> Result { + fn new_var(key: &[u8]) -> Result { if key.len() != Self::KeySize::to_usize() { Err(InvalidKeyLength) } else { @@ -151,8 +151,8 @@ where Self::from_cipher(cipher) } - fn new_varkey(key: &[u8]) -> Result { - ::Cipher::new_varkey(key) + fn new_var(key: &[u8]) -> Result { + ::Cipher::new_var(key) .map_err(|_| InvalidKeyLength) .map(Self::from_cipher) } From 629d323d33b91ce952a195998de43090f12687ae Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 29 Dec 2020 17:55:42 -0800 Subject: [PATCH 0344/1461] cipher v0.3.0-pre.2 (#438) --- Cargo.lock | 2 +- cipher/Cargo.toml | 2 +- crypto-mac/Cargo.toml | 2 +- crypto/Cargo.toml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bbe5421f8..9be4836fe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -85,7 +85,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cipher" -version = "0.3.0-pre" +version = "0.3.0-pre.2" dependencies = [ "blobby 0.3.0", "generic-array 0.14.4", diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index 9c37e7aa6..75f5980b6 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "cipher" description = "Traits for describing block ciphers and stream ciphers" -version = "0.3.0-pre" +version = "0.3.0-pre.2" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/crypto-mac/Cargo.toml b/crypto-mac/Cargo.toml index 7be37f044..70b1f833f 100644 --- a/crypto-mac/Cargo.toml +++ b/crypto-mac/Cargo.toml @@ -13,7 +13,7 @@ categories = ["cryptography", "no-std"] [dependencies] generic-array = "0.14" -cipher = { version = "=0.3.0-pre", optional = true, path = "../cipher" } +cipher = { version = "=0.3.0-pre.2", optional = true, path = "../cipher" } subtle = { version = "2", default-features = false } blobby = { version = "0.3", optional = true } diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index f0f274fcb..56f9a6844 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -13,7 +13,7 @@ edition = "2018" [dependencies] aead = { version = "0.3", optional = true, path = "../aead" } -cipher = { version = "=0.3.0-pre", optional = true, path = "../cipher" } +cipher = { version = "=0.3.0-pre.2", optional = true, path = "../cipher" } digest = { version = "0.9", optional = true, path = "../digest" } elliptic-curve = { version = "0.8", optional = true, path = "../elliptic-curve" } mac = { version = "=0.11.0-pre", package = "crypto-mac", optional = true, path = "../crypto-mac" } From 2f6287c288f22c477e3c881b3ff48a0fed06ad66 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 29 Dec 2020 20:09:24 -0800 Subject: [PATCH 0345/1461] cipher: revert SeekNum::from_block_byte change (#439) This reverts the implementation of `SeekNum::from_block_byte` which was merged as part of #435. I'm not exactly sure what the issue is and it's somewhat difficult to debug in that it's code that involves both generics and macros causing an error as part of any failure in a long chain of checked arithmetic, which I'm trying to debug from the context of a concrete stream cipher impl (both `chacha20` and `salsa20`) where it's operating over a generic type. The error manifests as `OverflowError`: https://github.com/RustCrypto/stream-ciphers/pull/205#issuecomment-752314229 This commit reverts to the previous implementation, which is at least much simpler. --- cipher/src/stream.rs | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/cipher/src/stream.rs b/cipher/src/stream.rs index 843ff56eb..3bea72828 100644 --- a/cipher/src/stream.rs +++ b/cipher/src/stream.rs @@ -114,17 +114,8 @@ macro_rules! impl_seek_num { impl SeekNum for $t { fn from_block_byte>(block: T, byte: u8, bs: u8) -> Result { debug_assert!(byte < bs); - let pos = block - .try_into() - .ok() - .and_then(|v| match byte == 0 { - true => Some(v), - // if `byte` is not zero, then block counter was incremented - false => v.checked_sub(1), - }) - .and_then(|v| v.checked_mul(bs as Self)) - .and_then(|v| v.checked_add(byte as Self)) - .ok_or(OverflowError)?; + let block = block.try_into().map_err(|_| OverflowError)?; + let pos = block.checked_mul(bs as Self).ok_or(OverflowError)? + (byte as Self); Ok(pos) } From 5aa64b2e6ef59106011fefd8138f3785947f207c Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 29 Dec 2020 20:18:05 -0800 Subject: [PATCH 0346/1461] cipher v0.3.0-pre.3 (#440) --- Cargo.lock | 2 +- cipher/Cargo.toml | 2 +- crypto-mac/Cargo.toml | 2 +- crypto/Cargo.toml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9be4836fe..b30bd4168 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -85,7 +85,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cipher" -version = "0.3.0-pre.2" +version = "0.3.0-pre.3" dependencies = [ "blobby 0.3.0", "generic-array 0.14.4", diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index 75f5980b6..73eceb484 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "cipher" description = "Traits for describing block ciphers and stream ciphers" -version = "0.3.0-pre.2" +version = "0.3.0-pre.3" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/crypto-mac/Cargo.toml b/crypto-mac/Cargo.toml index 70b1f833f..47548ce18 100644 --- a/crypto-mac/Cargo.toml +++ b/crypto-mac/Cargo.toml @@ -13,7 +13,7 @@ categories = ["cryptography", "no-std"] [dependencies] generic-array = "0.14" -cipher = { version = "=0.3.0-pre.2", optional = true, path = "../cipher" } +cipher = { version = "=0.3.0-pre.3", optional = true, path = "../cipher" } subtle = { version = "2", default-features = false } blobby = { version = "0.3", optional = true } diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 56f9a6844..f76488368 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -13,7 +13,7 @@ edition = "2018" [dependencies] aead = { version = "0.3", optional = true, path = "../aead" } -cipher = { version = "=0.3.0-pre.2", optional = true, path = "../cipher" } +cipher = { version = "=0.3.0-pre.3", optional = true, path = "../cipher" } digest = { version = "0.9", optional = true, path = "../digest" } elliptic-curve = { version = "0.8", optional = true, path = "../elliptic-curve" } mac = { version = "=0.11.0-pre", package = "crypto-mac", optional = true, path = "../crypto-mac" } From f40e69880966707cbea4d8cb804474a2ad67d9e9 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 30 Dec 2020 06:50:00 -0800 Subject: [PATCH 0347/1461] cipher: block cipher trait blanket impls for refs (#441) Previously `cipher` contained blanket impls of block cipher traits for reference types, which was leveraged in e.g. `aes-gcm` and `aes-gcm-siv`. However, somewhere in the course of refactoring they were removed. This commit adds them back. --- cipher/src/block.rs | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/cipher/src/block.rs b/cipher/src/block.rs index 4e08dc259..8643fcad9 100644 --- a/cipher/src/block.rs +++ b/cipher/src/block.rs @@ -156,3 +156,44 @@ impl BlockDecryptMut for Alg { self.decrypt_block(block); } } + +// Impls of block cipher traits for reference types + +impl BlockCipher for &Alg { + type BlockSize = Alg::BlockSize; + type ParBlocks = Alg::ParBlocks; +} + +impl BlockEncrypt for &Alg { + #[inline] + fn encrypt_block(&self, block: &mut Block) { + Alg::encrypt_block(self, block); + } + + #[inline] + fn encrypt_par_blocks(&self, blocks: &mut ParBlocks) { + Alg::encrypt_par_blocks(self, blocks); + } + + #[inline] + fn encrypt_blocks(&self, blocks: &mut [Block]) { + Alg::encrypt_blocks(self, blocks); + } +} + +impl BlockDecrypt for &Alg { + #[inline] + fn decrypt_block(&self, block: &mut Block) { + Alg::decrypt_block(self, block); + } + + #[inline] + fn decrypt_par_blocks(&self, blocks: &mut ParBlocks) { + Alg::decrypt_par_blocks(self, blocks); + } + + #[inline] + fn decrypt_blocks(&self, blocks: &mut [Block]) { + Alg::decrypt_blocks(self, blocks); + } +} From 9ecdcfc42bcc7dea78cd1273aebdf387b3378eb2 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 30 Dec 2020 08:08:43 -0800 Subject: [PATCH 0348/1461] cipher + crypto-mac: use `new_from_slice(s)` naming convention (#442) Renames `new_var`(key) methods to use `new_from_slice(s)` as discussed earlier here: https://github.com/RustCrypto/traits/pull/435#discussion_r550227781 --- cipher/src/block.rs | 2 +- cipher/src/common.rs | 11 ++++++----- cipher/src/dev/block.rs | 8 ++++---- cipher/src/dev/stream.rs | 6 +++--- crypto-mac/src/dev.rs | 4 ++-- crypto-mac/src/lib.rs | 6 +++--- 6 files changed, 19 insertions(+), 18 deletions(-) diff --git a/cipher/src/block.rs b/cipher/src/block.rs index 8643fcad9..d38da8f5d 100644 --- a/cipher/src/block.rs +++ b/cipher/src/block.rs @@ -34,7 +34,7 @@ pub trait NewBlockCipher: Sized { /// /// Default implementation will accept only keys with length equal to /// `KeySize`, but some ciphers can accept range of key lengths. - fn new_var(key: &[u8]) -> Result { + fn new_from_slice(key: &[u8]) -> Result { if key.len() != Self::KeySize::to_usize() { Err(InvalidLength) } else { diff --git a/cipher/src/common.rs b/cipher/src/common.rs index ef7e7d6d6..cd97524a6 100644 --- a/cipher/src/common.rs +++ b/cipher/src/common.rs @@ -17,12 +17,13 @@ pub trait NewCipher: Sized { /// Nonce size in bytes type NonceSize: ArrayLength; - /// Create new stream cipher instance from variable length key and nonce. + /// Create new stream cipher instance from key and nonce arrays. fn new(key: &CipherKey, nonce: &Nonce) -> Self; - /// Create new stream cipher instance from variable length key and nonce. + /// Create new stream cipher instance from variable length key and nonce + /// given as byte slices. #[inline] - fn new_var(key: &[u8], nonce: &[u8]) -> Result { + fn new_from_slices(key: &[u8], nonce: &[u8]) -> Result { let kl = Self::KeySize::to_usize(); let nl = Self::NonceSize::to_usize(); if key.len() != kl || nonce.len() != nl { @@ -64,11 +65,11 @@ where ) } - fn new_var(key: &[u8], nonce: &[u8]) -> Result { + fn new_from_slices(key: &[u8], nonce: &[u8]) -> Result { if nonce.len() != Self::NonceSize::USIZE { Err(InvalidLength) } else { - C::BlockCipher::new_var(key) + C::BlockCipher::new_from_slice(key) .map_err(|_| InvalidLength) .map(|cipher| { let nonce = GenericArray::from_slice(nonce); diff --git a/cipher/src/dev/block.rs b/cipher/src/dev/block.rs index e3ac0867b..fc53b9435 100644 --- a/cipher/src/dev/block.rs +++ b/cipher/src/dev/block.rs @@ -15,7 +15,7 @@ macro_rules! block_cipher_test { }; fn run_test(key: &[u8], pt: &[u8], ct: &[u8]) -> bool { - let state = <$cipher as NewBlockCipher>::new_var(key).unwrap(); + let state = <$cipher as NewBlockCipher>::new_from_slice(key).unwrap(); let mut block = GenericArray::clone_from_slice(pt); state.encrypt_block(&mut block); @@ -37,7 +37,7 @@ macro_rules! block_cipher_test { type Block = GenericArray; type ParBlock = GenericArray; - let state = <$cipher as NewBlockCipher>::new_var(key).unwrap(); + let state = <$cipher as NewBlockCipher>::new_from_slice(key).unwrap(); let block = Block::clone_from_slice(pt); let mut blocks1 = ParBlock::default(); @@ -118,7 +118,7 @@ macro_rules! block_cipher_bench { #[bench] pub fn encrypt(bh: &mut Bencher) { - let state = <$cipher>::new_var(&[1u8; $key_len]).unwrap(); + let state = <$cipher>::new_from_slice(&[1u8; $key_len]).unwrap(); let mut block = Default::default(); bh.iter(|| { @@ -130,7 +130,7 @@ macro_rules! block_cipher_bench { #[bench] pub fn decrypt(bh: &mut Bencher) { - let state = <$cipher>::new_var(&[1u8; $key_len]).unwrap(); + let state = <$cipher>::new_from_slice(&[1u8; $key_len]).unwrap(); let mut block = Default::default(); bh.iter(|| { diff --git a/cipher/src/dev/stream.rs b/cipher/src/dev/stream.rs index e83b7af11..43757ffa1 100644 --- a/cipher/src/dev/stream.rs +++ b/cipher/src/dev/stream.rs @@ -15,7 +15,7 @@ macro_rules! stream_cipher_test { let [key, iv, pt, ct] = row.unwrap(); for chunk_n in 1..256 { - let mut mode = <$cipher>::new_var(key, iv).unwrap(); + let mut mode = <$cipher>::new_from_slices(key, iv).unwrap(); let mut pt = pt.to_vec(); for chunk in pt.chunks_mut(chunk_n) { mode.apply_keystream(chunk); @@ -106,7 +106,7 @@ macro_rules! stream_cipher_async_test { ciphertext: &[u8], ) -> Option<&'static str> { for n in 1..=plaintext.len() { - let mut mode = <$cipher>::new_var(key, iv).unwrap(); + let mut mode = <$cipher>::new_from_slices(key, iv).unwrap(); let mut buf = plaintext.to_vec(); for chunk in buf.chunks_mut(n) { mode.encrypt(chunk); @@ -117,7 +117,7 @@ macro_rules! stream_cipher_async_test { } for n in 1..=plaintext.len() { - let mut mode = <$cipher>::new_var(key, iv).unwrap(); + let mut mode = <$cipher>::new_from_slices(key, iv).unwrap(); let mut buf = ciphertext.to_vec(); for chunk in buf.chunks_mut(n) { mode.decrypt(chunk); diff --git a/crypto-mac/src/dev.rs b/crypto-mac/src/dev.rs index e2348501e..16ed20d66 100644 --- a/crypto-mac/src/dev.rs +++ b/crypto-mac/src/dev.rs @@ -13,7 +13,7 @@ macro_rules! new_test { use crypto_mac::{Mac, NewMac}; fn run_test(key: &[u8], input: &[u8], tag: &[u8]) -> Option<&'static str> { - let mut mac = <$mac as NewMac>::new_varkey(key).unwrap(); + let mut mac = <$mac as NewMac>::new_from_slice(key).unwrap(); mac.update(input); let result = mac.finalize_reset(); if &result.into_bytes()[..] != tag { @@ -25,7 +25,7 @@ macro_rules! new_test { return Some("after reset"); } - let mut mac = <$mac as NewMac>::new_varkey(key).unwrap(); + let mut mac = <$mac as NewMac>::new_from_slice(key).unwrap(); // test reading byte by byte for i in 0..input.len() { mac.update(&input[i..i + 1]); diff --git a/crypto-mac/src/lib.rs b/crypto-mac/src/lib.rs index c5d08e925..1f101f157 100644 --- a/crypto-mac/src/lib.rs +++ b/crypto-mac/src/lib.rs @@ -45,7 +45,7 @@ pub trait NewMac: Sized { /// /// Default implementation will accept only keys with length equal to /// `KeySize`, but some MACs can accept range of key lengths. - fn new_var(key: &[u8]) -> Result { + fn new_from_slice(key: &[u8]) -> Result { if key.len() != Self::KeySize::to_usize() { Err(InvalidKeyLength) } else { @@ -151,8 +151,8 @@ where Self::from_cipher(cipher) } - fn new_var(key: &[u8]) -> Result { - ::Cipher::new_var(key) + fn new_from_slice(key: &[u8]) -> Result { + ::Cipher::new_from_slice(key) .map_err(|_| InvalidKeyLength) .map(Self::from_cipher) } From 2e9d89d009b448f51c003e286fdf1af0adb83931 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 30 Dec 2020 08:16:31 -0800 Subject: [PATCH 0349/1461] cipher v0.3.0-pre.4 (#443) --- Cargo.lock | 2 +- cipher/Cargo.toml | 2 +- crypto-mac/Cargo.toml | 2 +- crypto/Cargo.toml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b30bd4168..433b33cba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -85,7 +85,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cipher" -version = "0.3.0-pre.3" +version = "0.3.0-pre.4" dependencies = [ "blobby 0.3.0", "generic-array 0.14.4", diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index 73eceb484..ba9210b0f 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "cipher" description = "Traits for describing block ciphers and stream ciphers" -version = "0.3.0-pre.3" +version = "0.3.0-pre.4" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/crypto-mac/Cargo.toml b/crypto-mac/Cargo.toml index 47548ce18..6c2ebefe6 100644 --- a/crypto-mac/Cargo.toml +++ b/crypto-mac/Cargo.toml @@ -13,7 +13,7 @@ categories = ["cryptography", "no-std"] [dependencies] generic-array = "0.14" -cipher = { version = "=0.3.0-pre.3", optional = true, path = "../cipher" } +cipher = { version = "=0.3.0-pre.4", optional = true, path = "../cipher" } subtle = { version = "2", default-features = false } blobby = { version = "0.3", optional = true } diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index f76488368..ae54b55a2 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -13,7 +13,7 @@ edition = "2018" [dependencies] aead = { version = "0.3", optional = true, path = "../aead" } -cipher = { version = "=0.3.0-pre.3", optional = true, path = "../cipher" } +cipher = { version = "=0.3.0-pre.4", optional = true, path = "../cipher" } digest = { version = "0.9", optional = true, path = "../digest" } elliptic-curve = { version = "0.8", optional = true, path = "../elliptic-curve" } mac = { version = "=0.11.0-pre", package = "crypto-mac", optional = true, path = "../crypto-mac" } From 92dc55f31726bf6144a955ab65fe389f212b4ea2 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 3 Jan 2021 08:12:25 -0800 Subject: [PATCH 0350/1461] aead: `stream` module (#436) Implementation of the STREAM construction as described in the paper "Online Authenticated-Encryption and its Nonce-Reuse Misuse-Resistance": https://eprint.iacr.org/2015/189.pdf The implementation is generic over AEAD ciphers and is factored into a low-level `StreamPrimitive` trait (permitting different "flavors" of STREAM) as well as higher-level stateful `Encryptor` and `Decryptor` objects which are generic over `StreamPrimitive` types. Includes two concrete implementations of `StreamPrimitive`: - `StreamBE32`: the original version of STREAM described in the paper, with a nonce in the form: `prefix || counter || last_block`, where `counter` is a 32-bit big endian-encoded integer, and `last_block` is a 1-byte flag. - `StreamLE31`: uses a 31-bit counter and 1-bit last block flag, packed into the last 4 bytes of the nonce as a little endian integer. Using little endian provides better performance on commonly used CPU architectures, and using a 1-bit last block flag ensures the user-facing STREAM nonce is even numbered in terms of bytes (e.g. for a 96-bit nonce it'd be 64-bits or 8-bytes instead of a 7-byte nonce using the construction described in the paper) and also avoids wasting bits. --- .github/workflows/aead.yml | 8 +- aead/Cargo.toml | 3 +- aead/src/lib.rs | 4 + aead/src/stream.rs | 417 +++++++++++++++++++++++++++++++++++++ 4 files changed, 428 insertions(+), 4 deletions(-) create mode 100644 aead/src/stream.rs diff --git a/.github/workflows/aead.yml b/.github/workflows/aead.yml index ec0978796..ed1acd4b2 100644 --- a/.github/workflows/aead.yml +++ b/.github/workflows/aead.yml @@ -35,7 +35,9 @@ jobs: toolchain: ${{ matrix.rust }} target: ${{ matrix.target }} override: true - - run: cargo build --no-default-features --release --target ${{ matrix.target }} + - run: cargo build --target ${{ matrix.target }} --release --no-default-features + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features stream + test: runs-on: ubuntu-latest strategy: @@ -50,6 +52,6 @@ jobs: profile: minimal toolchain: ${{ matrix.rust }} - run: cargo check --all-features - - run: cargo test --no-default-features --release + - run: cargo test --release --no-default-features - run: cargo test --release - - run: cargo test --all-features --release + - run: cargo test --release --all-features diff --git a/aead/Cargo.toml b/aead/Cargo.toml index 99b6fa646..580faecfc 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -19,8 +19,9 @@ blobby = { version = "0.3", optional = true } [features] default = ["alloc"] alloc = [] -std = ["alloc"] dev = ["blobby"] +std = ["alloc"] +stream = [] [package.metadata.docs.rs] all-features = true diff --git a/aead/src/lib.rs b/aead/src/lib.rs index dc37133ba..2b5703d35 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -32,6 +32,10 @@ extern crate std; #[cfg_attr(docsrs, doc(cfg(feature = "dev")))] pub mod dev; +#[cfg(feature = "stream")] +#[cfg_attr(docsrs, doc(cfg(feature = "stream")))] +pub mod stream; + pub use generic_array::{self, typenum::consts}; #[cfg(feature = "heapless")] diff --git a/aead/src/stream.rs b/aead/src/stream.rs new file mode 100644 index 000000000..d2ec4d491 --- /dev/null +++ b/aead/src/stream.rs @@ -0,0 +1,417 @@ +//! Streaming AEAD support. +//! +//! Implementation of the STREAM online authenticated encryption construction +//! as described in the paper +//! [Online Authenticated-Encryption and its Nonce-Reuse Misuse-Resistance][1]. +//! +//! ## About +//! +//! The STREAM construction supports encrypting/decrypting sequences of AEAD +//! message segments, which is useful in cases where the overall message is too +//! large to fit in a single buffer and needs to be processed incrementally. +//! +//! STREAM defends against reordering and truncation attacks which are common +//! in naive schemes which attempt to provide these properties, and is proven +//! to meet the security definition of "nonce-based online authenticated +//! encryption" (nOAE) as given in the aforementioned paper. +//! +//! [1]: https://eprint.iacr.org/2015/189.pdf + +use crate::{AeadInPlace, Buffer, Error, Key, NewAead}; +use core::ops::{AddAssign, Sub}; +use generic_array::{ + typenum::{Unsigned, U4, U5}, + ArrayLength, GenericArray, +}; + +/// Nonce as used by a given AEAD construction and STREAM primitive. +pub type Nonce = GenericArray>; + +/// Size of a nonce as used by a STREAM construction, sans the overhead of +/// the STREAM protocol itself. +pub type NonceSize = + <::NonceSize as Sub<>::NonceOverhead>>::Output; + +/// STREAM encryptor instantiated with [`StreamBE32`] as the underlying +/// STREAM primitive. +pub type EncryptorBE32 = Encryptor>; + +/// STREAM decryptor instantiated with [`StreamBE32`] as the underlying +/// STREAM primitive. +pub type DecryptorBE32 = Decryptor>; + +/// STREAM encryptor instantiated with [`StreamLE31`] as the underlying +/// STREAM primitive. +pub type EncryptorLE31 = Encryptor>; + +/// STREAM decryptor instantiated with [`StreamLE31`] as the underlying +/// STREAM primitive. +pub type DecryptorLE31 = Decryptor>; + +/// Create a new STREAM from the provided AEAD. +pub trait NewStream: StreamPrimitive +where + A: AeadInPlace, + A::NonceSize: Sub, + NonceSize: ArrayLength, +{ + /// Create a new STREAM with the given key and nonce. + fn new(key: &Key, nonce: &Nonce) -> Self + where + A: NewAead, + Self: Sized, + { + Self::from_aead(A::new(key), nonce) + } + + /// Create a new STREAM from the given AEAD cipher. + fn from_aead(aead: A, nonce: &Nonce) -> Self; +} + +/// Low-level STREAM implementation. +/// +/// This trait provides a particular "flavor" of STREAM, as there are +/// different ways the specifics of the construction can be implemented. +/// +/// Deliberately immutable and stateless to permit parallel operation. +pub trait StreamPrimitive +where + A: AeadInPlace, + A::NonceSize: Sub, + NonceSize: ArrayLength, +{ + /// Number of bytes this STREAM primitive requires from the nonce. + type NonceOverhead: ArrayLength; + + /// Type used as the STREAM counter. + type Counter: AddAssign + Copy + Default + Eq; + + /// Value to use when incrementing the STREAM counter (i.e. one) + const COUNTER_INCR: Self::Counter; + + /// Maximum value of the STREAM counter. + const COUNTER_MAX: Self::Counter; + + /// Encrypt an AEAD message in-place at the given position in the STREAM. + fn encrypt_in_place( + &self, + position: Self::Counter, + last_block: bool, + associated_data: &[u8], + buffer: &mut dyn Buffer, + ) -> Result<(), Error>; + + /// Decrypt an AEAD message in-place at the given position in the STREAM. + fn decrypt_in_place( + &self, + position: Self::Counter, + last_block: bool, + associated_data: &[u8], + buffer: &mut dyn Buffer, + ) -> Result<(), Error>; + + /// Obtain [`Encryptor`] for this [`StreamPrimitive`]. + fn encryptor(self) -> Encryptor + where + Self: Sized, + { + Encryptor::from_stream_primitive(self) + } + + /// Obtain [`Decryptor`] for this [`StreamPrimitive`]. + fn decryptor(self) -> Decryptor + where + Self: Sized, + { + Decryptor::from_stream_primitive(self) + } +} + +/// Implement a stateful STREAM object (i.e. encryptor or decryptor) +macro_rules! impl_stream_object { + ( + $name:ident, + $next_method:tt, + $last_method:tt, + $op_method:tt, + $op_desc:expr, + $obj_desc:expr + ) => { + #[doc = "Stateful STREAM object which can"] + #[doc = $op_desc] + #[doc = "AEAD messages one-at-a-time."] + #[doc = ""] + #[doc = "This corresponds to the "] + #[doc = $obj_desc] + #[doc = "object as defined in the paper"] + #[doc = "[Online Authenticated-Encryption and its Nonce-Reuse Misuse-Resistance][1]."] + #[doc = ""] + #[doc = "[1]: https://eprint.iacr.org/2015/189.pdf"] + pub struct $name + where + A: AeadInPlace, + S: StreamPrimitive, + A::NonceSize: Sub<>::NonceOverhead>, + NonceSize: ArrayLength, + { + /// Underlying STREAM primitive. + stream: S, + + /// Current position in the STREAM. + position: S::Counter, + } + + impl $name + where + A: AeadInPlace, + S: StreamPrimitive, + A::NonceSize: Sub<>::NonceOverhead>, + NonceSize: ArrayLength, + { + #[doc = "Create a"] + #[doc = $obj_desc] + #[doc = "object from the given AEAD key and nonce."] + pub fn new(key: &Key, nonce: &Nonce) -> Self + where + A: NewAead, + S: NewStream + { + Self::from_stream_primitive(S::new(key, nonce)) + } + + #[doc = "Create a"] + #[doc = $obj_desc] + #[doc = "object from the given AEAD primitive."] + pub fn from_aead(aead: A, nonce: &Nonce) -> Self + where + A: NewAead, + S: NewStream + { + Self::from_stream_primitive(S::from_aead(aead, nonce)) + } + + #[doc = "Create a"] + #[doc = $obj_desc] + #[doc = "object from the given STREAM primitive."] + pub fn from_stream_primitive(stream: S) -> Self { + Self { + stream, + position: Default::default(), + } + } + + #[doc = "Use the underlying AEAD to"] + #[doc = $op_desc] + #[doc = "the next AEAD message in this STREAM in-place."] + pub fn $next_method( + &mut self, + associated_data: &[u8], + buffer: &mut dyn Buffer, + ) -> Result<(), Error> { + if self.position == S::COUNTER_MAX { + // Counter overflow. Note that the maximum counter value is + // deliberately disallowed, as it would preclude being able + // to encrypt a last block (i.e. with `$last_method`) + return Err(Error); + } + + self.stream.$op_method(self.position, false, associated_data, buffer)?; + + // Note: overflow checked above + self.position += S::COUNTER_INCR; + Ok(()) + } + + #[doc = "Use the underlying AEAD to"] + #[doc = $op_desc] + #[doc = "the last AEAD message in this STREAM in-place,"] + #[doc = "consuming the "] + #[doc = $obj_desc] + #[doc = "object in order to prevent further use."] + pub fn $last_method( + self, + associated_data: &[u8], + buffer: &mut dyn Buffer + ) -> Result<(), Error> { + self.stream.$op_method(self.position, true, associated_data, buffer) + } + } + } +} + +impl_stream_object!( + Encryptor, + encrypt_next_in_place, + encrypt_last_in_place, + encrypt_in_place, + "encrypt", + "ℰ STREAM encryptor" +); + +impl_stream_object!( + Decryptor, + decrypt_next_in_place, + decrypt_last_in_place, + decrypt_in_place, + "decrypt", + "𝒟 STREAM decryptor" +); + +/// The original "Rogaway-flavored" STREAM as described in the paper +/// [Online Authenticated-Encryption and its Nonce-Reuse Misuse-Resistance][1]. +/// +/// Uses a 32-bit big endian counter and 1-byte "last block" flag stored as +/// the last 5-bytes of the AEAD nonce. +/// +/// [1]: https://eprint.iacr.org/2015/189.pdf +pub struct StreamBE32 +where + A: AeadInPlace, + A::NonceSize: Sub, + <::NonceSize as Sub>::Output: ArrayLength, +{ + /// Underlying AEAD cipher + aead: A, + + /// Nonce (sans STREAM overhead) + nonce: Nonce, +} + +impl StreamPrimitive for StreamBE32 +where + A: AeadInPlace, + A::NonceSize: Sub, + <::NonceSize as Sub>::Output: ArrayLength, +{ + type NonceOverhead = U5; + type Counter = u32; + const COUNTER_INCR: u32 = 1; + const COUNTER_MAX: u32 = core::u32::MAX; + + fn encrypt_in_place( + &self, + position: u32, + last_block: bool, + associated_data: &[u8], + buffer: &mut dyn Buffer, + ) -> Result<(), Error> { + let nonce = self.aead_nonce(position, last_block); + self.aead.encrypt_in_place(&nonce, associated_data, buffer) + } + + fn decrypt_in_place( + &self, + position: Self::Counter, + last_block: bool, + associated_data: &[u8], + buffer: &mut dyn Buffer, + ) -> Result<(), Error> { + let nonce = self.aead_nonce(position, last_block); + self.aead.decrypt_in_place(&nonce, associated_data, buffer) + } +} + +impl StreamBE32 +where + A: AeadInPlace, + A::NonceSize: Sub, + <::NonceSize as Sub>::Output: ArrayLength, +{ + /// Compute the full AEAD nonce including the STREAM counter and last + /// block flag. + fn aead_nonce(&self, position: u32, last_block: bool) -> crate::Nonce { + let mut result = GenericArray::default(); + + // TODO(tarcieri): use `generic_array::sequence::Concat` (or const generics) + let (prefix, tail) = result.split_at_mut(NonceSize::::to_usize()); + prefix.copy_from_slice(&self.nonce); + + let (counter, flag) = tail.split_at_mut(4); + counter.copy_from_slice(&position.to_be_bytes()); + flag[0] = last_block as u8; + + result + } +} + +/// STREAM as instantiated with a 31-bit little endian counter and 1-bit +/// "last block" flag stored as the most significant bit of the counter +/// when interpreted as a 32-bit integer. +/// +/// The 31-bit + 1-bit value is stored as the last 4 bytes of the AEAD nonce. +pub struct StreamLE31 +where + A: AeadInPlace, + A::NonceSize: Sub, + <::NonceSize as Sub>::Output: ArrayLength, +{ + /// Underlying AEAD cipher + aead: A, + + /// Nonce (sans STREAM overhead) + nonce: Nonce, +} + +impl StreamPrimitive for StreamLE31 +where + A: AeadInPlace, + A::NonceSize: Sub, + <::NonceSize as Sub>::Output: ArrayLength, +{ + type NonceOverhead = U4; + type Counter = u32; + const COUNTER_INCR: u32 = 1; + const COUNTER_MAX: u32 = 0xfff_ffff; + + fn encrypt_in_place( + &self, + position: u32, + last_block: bool, + associated_data: &[u8], + buffer: &mut dyn Buffer, + ) -> Result<(), Error> { + let nonce = self.aead_nonce(position, last_block)?; + self.aead.encrypt_in_place(&nonce, associated_data, buffer) + } + + fn decrypt_in_place( + &self, + position: Self::Counter, + last_block: bool, + associated_data: &[u8], + buffer: &mut dyn Buffer, + ) -> Result<(), Error> { + let nonce = self.aead_nonce(position, last_block)?; + self.aead.decrypt_in_place(&nonce, associated_data, buffer) + } +} + +impl StreamLE31 +where + A: AeadInPlace, + A::NonceSize: Sub, + <::NonceSize as Sub>::Output: ArrayLength, +{ + /// Compute the full AEAD nonce including the STREAM counter and last + /// block flag. + fn aead_nonce( + &self, + position: u32, + last_block: bool, + ) -> Result, Error> { + if position > Self::COUNTER_MAX { + return Err(Error); + } + + let mut result = GenericArray::default(); + + // TODO(tarcieri): use `generic_array::sequence::Concat` (or const generics) + let (prefix, tail) = result.split_at_mut(NonceSize::::to_usize()); + prefix.copy_from_slice(&self.nonce); + + let position_with_flag = position | ((last_block as u32) << 31); + tail.copy_from_slice(&position_with_flag.to_le_bytes()); + + Ok(result) + } +} From e4b1c9f35709afa6bebc32bd05ce885bf9a9d1c1 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 3 Jan 2021 08:31:51 -0800 Subject: [PATCH 0351/1461] aead: impl NewStream for StreamBE32/StreamLE31 (#445) Support for instantiating STREAM primitives --- aead/src/stream.rs | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/aead/src/stream.rs b/aead/src/stream.rs index d2ec4d491..3e220b6fb 100644 --- a/aead/src/stream.rs +++ b/aead/src/stream.rs @@ -277,6 +277,20 @@ where nonce: Nonce, } +impl NewStream for StreamBE32 +where + A: AeadInPlace, + A::NonceSize: Sub, + <::NonceSize as Sub>::Output: ArrayLength, +{ + fn from_aead(aead: A, nonce: &Nonce) -> Self { + Self { + aead, + nonce: nonce.clone(), + } + } +} + impl StreamPrimitive for StreamBE32 where A: AeadInPlace, @@ -352,6 +366,20 @@ where nonce: Nonce, } +impl NewStream for StreamLE31 +where + A: AeadInPlace, + A::NonceSize: Sub, + <::NonceSize as Sub>::Output: ArrayLength, +{ + fn from_aead(aead: A, nonce: &Nonce) -> Self { + Self { + aead, + nonce: nonce.clone(), + } + } +} + impl StreamPrimitive for StreamLE31 where A: AeadInPlace, From dda4f9bb1d5b634f59810263617f08f7c63d377d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 5 Jan 2021 06:37:15 -0800 Subject: [PATCH 0352/1461] password-hash crate (#437) Adds a crate containing a no_std-friendly stack-allocated implementation of the PHC string format specification, and a `PasswordHasher` trait for operating over password hashing functions generically. --- .github/workflows/password-hash.yml | 59 ++++ Cargo.lock | 7 + Cargo.toml | 1 + password-hash/CHANGELOG.md | 6 + password-hash/Cargo.toml | 24 ++ password-hash/LICENSE-APACHE | 201 ++++++++++++++ password-hash/LICENSE-MIT | 25 ++ password-hash/README.md | 65 +++++ password-hash/src/b64.rs | 323 ++++++++++++++++++++++ password-hash/src/errors.rs | 299 ++++++++++++++++++++ password-hash/src/ident.rs | 238 ++++++++++++++++ password-hash/src/lib.rs | 267 ++++++++++++++++++ password-hash/src/output.rs | 241 ++++++++++++++++ password-hash/src/params.rs | 367 ++++++++++++++++++++++++ password-hash/src/params/value.rs | 413 ++++++++++++++++++++++++++++ password-hash/src/salt.rs | 255 +++++++++++++++++ password-hash/tests/b64.rs | 51 ++++ password-hash/tests/encoding.rs | 144 ++++++++++ password-hash/tests/hashing.rs | 64 +++++ password-hash/tests/test_vectors.rs | 56 ++++ 20 files changed, 3106 insertions(+) create mode 100644 .github/workflows/password-hash.yml create mode 100644 password-hash/CHANGELOG.md create mode 100644 password-hash/Cargo.toml create mode 100644 password-hash/LICENSE-APACHE create mode 100644 password-hash/LICENSE-MIT create mode 100644 password-hash/README.md create mode 100644 password-hash/src/b64.rs create mode 100644 password-hash/src/errors.rs create mode 100644 password-hash/src/ident.rs create mode 100644 password-hash/src/lib.rs create mode 100644 password-hash/src/output.rs create mode 100644 password-hash/src/params.rs create mode 100644 password-hash/src/params/value.rs create mode 100644 password-hash/src/salt.rs create mode 100644 password-hash/tests/b64.rs create mode 100644 password-hash/tests/encoding.rs create mode 100644 password-hash/tests/hashing.rs create mode 100644 password-hash/tests/test_vectors.rs diff --git a/.github/workflows/password-hash.yml b/.github/workflows/password-hash.yml new file mode 100644 index 000000000..3ac77672e --- /dev/null +++ b/.github/workflows/password-hash.yml @@ -0,0 +1,59 @@ +name: password-hash + +on: + pull_request: + paths: + - "password-hash/**" + - "Cargo.*" + push: + branches: master + +defaults: + run: + working-directory: password-hash + +env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + rust: + - 1.47.0 # MSRV + - stable + target: + - thumbv7em-none-eabi + - wasm32-unknown-unknown + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ matrix.rust }} + target: ${{ matrix.target }} + override: true + profile: minimal + - run: cargo build --target ${{ matrix.target }} --release --no-default-features + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features rand_core + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,rand_core + + test: + runs-on: ubuntu-latest + strategy: + matrix: + rust: + - 1.47.0 # MSRV + - stable + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ matrix.rust }} + profile: minimal + override: true + - run: cargo check --all-features + - run: cargo test --release + - run: cargo test --release --all-features diff --git a/Cargo.lock b/Cargo.lock index 433b33cba..dc25cecfb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -270,6 +270,13 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +[[package]] +name = "password-hash" +version = "0.0.0" +dependencies = [ + "rand_core", +] + [[package]] name = "pkcs8" version = "0.3.3" diff --git a/Cargo.toml b/Cargo.toml index 943b0d7a1..9db9bf636 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ members = [ "crypto", "digest", "elliptic-curve", + "password-hash", "signature", "signature/async", "universal-hash", diff --git a/password-hash/CHANGELOG.md b/password-hash/CHANGELOG.md new file mode 100644 index 000000000..1d013ff92 --- /dev/null +++ b/password-hash/CHANGELOG.md @@ -0,0 +1,6 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml new file mode 100644 index 000000000..9986c0390 --- /dev/null +++ b/password-hash/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "password-hash" +description = """ +Traits which describe the functionality of password hashing algorithms, +as well as a `no_std`-friendly implementation of the PHC string format +(a well-defined subset of the Modular Crypt Format a.k.a. MCF) +""" +version = "0.0.0" +authors = ["RustCrypto Developers"] +license = "MIT OR Apache-2.0" +readme = "README.md" +edition = "2018" +documentation = "https://docs.rs/password-hash" +repository = "https://github.com/RustCrypto/traits/tree/master/password-hash" +categories = ["cryptography", "no-std"] +keywords = ["crypt", "mcf", "password", "pbkdf", "phc"] + +[dependencies] +rand_core = { version = "0.5", optional = true } + +[features] +default = ["rand_core"] +alloc = [] +std = ["alloc"] diff --git a/password-hash/LICENSE-APACHE b/password-hash/LICENSE-APACHE new file mode 100644 index 000000000..78173fa2e --- /dev/null +++ b/password-hash/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/password-hash/LICENSE-MIT b/password-hash/LICENSE-MIT new file mode 100644 index 000000000..f39f9ff82 --- /dev/null +++ b/password-hash/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2020 RustCrypto Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/password-hash/README.md b/password-hash/README.md new file mode 100644 index 000000000..7f025a280 --- /dev/null +++ b/password-hash/README.md @@ -0,0 +1,65 @@ +# RustCrypto: Password Hashing Traits + +[![crate][crate-image]][crate-link] +[![Docs][docs-image]][docs-link] +![Apache2/MIT licensed][license-image] +![Rust Version][rustc-image] +[![Project Chat][chat-image]][chat-link] +[![Build Status][build-image]][build-link] + +Traits which describe the functionality of [password hashing algorithms]. + +Includes a `no_std`-friendly implementation of the [PHC string format] +(a well-defined subset of the Modular Crypt Format a.k.a. MCF) which +uses the traits this crate defines. + +See [RustCrypto/password-hashes] for algorithm implementations which use +these traits. + +[Documentation][docs-link] + +## Minimum Supported Rust Version + +Rust **1.47** or higher. + +Minimum supported Rust version may be changed in the future, but it will be +accompanied by a minor version bump. + +## SemVer Policy + +- All on-by-default features of this library are covered by SemVer +- MSRV is considered exempt from SemVer as noted above + +## License + +Licensed under either of: + +- [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0) +- [MIT license](https://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall be +dual licensed as above, without any additional terms or conditions. + +[//]: # (badges) + +[crate-image]: https://img.shields.io/crates/v/password-hash.svg +[crate-link]: https://crates.io/crates/password-hash +[docs-image]: https://docs.rs/password-hash/badge.svg +[docs-link]: https://docs.rs/password-hash/ +[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.47+-blue.svg +[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg +[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260046-password-hashes +[build-image]: https://github.com/RustCrypto/traits/workflows/password-hash/badge.svg?branch=master&event=push +[build-link]: https://github.com/RustCrypto/traits/actions?query=workflow:password-hash + +[//]: # (general links) + +[password hashing algorithms]: https://en.wikipedia.org/wiki/Cryptographic_hash_function#Password_verification +[PHC string format]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md +[RustCrypto/password-hashes]: https://github.com/RustCrypto/password-hashes diff --git a/password-hash/src/b64.rs b/password-hash/src/b64.rs new file mode 100644 index 000000000..b10674567 --- /dev/null +++ b/password-hash/src/b64.rs @@ -0,0 +1,323 @@ +//! "B64" encoding. +//! +//! Subset of the standard Base64 encoding (RFC 4648, section 4) which omits +//! padding (`=`) as well as extra whitespace, as described in the PHC string +//! format specification: +//! +//! +//! +//! Supports the Base64 character subset: `[A-Z]`, `[a-z]`, `[0-9]`, `+`, `/` +//! +//! Adapted from the following constant-time C++ implementation of Base64: +//! +//! +//! +//! Copyright (c) 2014 Steve "Sc00bz" Thomas (steve at tobtu dot com). +//! Derived code is dual licensed MIT + Apache 2 (with permission from Sc00bz). + +use crate::errors::B64Error; +use core::str; + +#[cfg(feature = "alloc")] +use alloc::{string::String, vec::Vec}; + +/// Error message to use when performing encoding operations which we expect +/// will never fail, i.e. the message passed to `expect()`. +const ENCODING_ERROR: &str = "B64 encoding error"; + +/// Encode the input byte slice as "B64", writing the result into the provided +/// destination slice, and returning an ASCII-encoded string value. +pub fn encode<'a>(src: &[u8], dst: &'a mut [u8]) -> Result<&'a str, B64Error> { + if encoded_len(src) > dst.len() { + return Err(B64Error::LengthInvalid); + } + + let mut src_offset: usize = 0; + let mut dst_offset: usize = 0; + let mut src_length: usize = src.len(); + + while src_length >= 3 { + encode_3bytes( + &src[src_offset..(src_offset + 3)], + &mut dst[dst_offset..(dst_offset + 4)], + ); + + src_offset += 3; + dst_offset += 4; + src_length -= 3; + } + + if src_length > 0 { + let remaining = &src[src_offset..(src_offset + src_length)]; + let mut tmp_in = [0u8; 3]; + tmp_in[..src_length].copy_from_slice(remaining); + + let mut tmp_out = [0u8; 4]; + encode_3bytes(&tmp_in, &mut tmp_out); + + let len = encoded_len(remaining); + dst[dst_offset..(dst_offset + len)].copy_from_slice(&tmp_out[..len]); + dst_offset += len; + } + + Ok(str::from_utf8(&dst[..dst_offset]).expect(ENCODING_ERROR)) +} + +/// Encode the input byte slice as a "B64"-encoded [`String`]. +#[cfg(feature = "alloc")] +#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] +pub fn encode_string(input: &[u8]) -> String { + let expected_len = encoded_len(input); + let mut output = vec![0u8; expected_len]; + let actual_len = encode(input, &mut output).expect(ENCODING_ERROR).len(); + debug_assert_eq!(expected_len, actual_len); + String::from_utf8(output).expect(ENCODING_ERROR) +} + +/// Get the "B64"-encoded length of the given byte slice. +pub const fn encoded_len(bytes: &[u8]) -> usize { + let q = bytes.len() * 4; + let r = q % 3; + (q / 3) + (r != 0) as usize +} + +/// "B64" decode the given source byte slice into the provided destination +/// buffer. +pub fn decode<'a>(src: &str, dst: &'a mut [u8]) -> Result<&'a [u8], B64Error> { + if decoded_len(src) > dst.len() { + return Err(B64Error::LengthInvalid); + } + + let src = src.as_bytes(); + + if !src.is_empty() && char::from(src[src.len() - 1]).is_whitespace() { + return Err(B64Error::TrailingWhitespace); + } + + let mut src_offset: usize = 0; + let mut dst_offset: usize = 0; + let mut src_length: usize = src.len(); + let mut err: isize = 0; + + while src_length > 4 { + err |= decode_3bytes( + &src[src_offset..(src_offset + 4)], + &mut dst[dst_offset..(dst_offset + 3)], + ); + src_offset += 4; + dst_offset += 3; + src_length -= 4; + } + + if src_length > 0 { + let mut i = 0; + let mut tmp_out = [0u8; 3]; + let mut tmp_in = [b'A'; 4]; + + while i < src_length { + tmp_in[i] = src[src_offset + i]; + i += 1; + } + + if i < 2 { + err = 1; + } + + src_length = i - 1; + err |= decode_3bytes(&tmp_in, &mut tmp_out); + dst[dst_offset..(dst_offset + src_length)].copy_from_slice(&tmp_out[..src_length]); + dst_offset += i - 1; + } + + if err == 0 { + Ok(&dst[..dst_offset]) + } else { + Err(B64Error::EncodingInvalid) + } +} + +/// Decode a "B64"-encoded string into a byte vector. +#[cfg(feature = "alloc")] +#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] +pub fn decode_vec(input: &str) -> Result, B64Error> { + let expected_len = decoded_len(input); + let mut output = vec![0u8; expected_len]; + let actual_len = decode(input, &mut output)?.len(); + debug_assert_eq!(expected_len, actual_len); + Ok(output) +} + +/// Get the length of the output from decoding the provided "B64"-encoded input. +pub const fn decoded_len(bytes: &str) -> usize { + (bytes.len() * 3) / 4 +} + +// B64 character set: +// [A-Z] [a-z] [0-9] + / +// 0x41-0x5a, 0x61-0x7a, 0x30-0x39, 0x2b, 0x2f + +#[inline] +fn encode_3bytes(src: &[u8], dst: &mut [u8]) { + debug_assert_eq!(src.len(), 3); + debug_assert!(dst.len() >= 4, "dst too short: {}", dst.len()); + + let b0 = src[0] as isize; + let b1 = src[1] as isize; + let b2 = src[2] as isize; + + dst[0] = encode_6bits(b0 >> 2); + dst[1] = encode_6bits(((b0 << 4) | (b1 >> 4)) & 63); + dst[2] = encode_6bits(((b1 << 2) | (b2 >> 6)) & 63); + dst[3] = encode_6bits(b2 & 63); +} + +#[inline] +fn encode_6bits(src: isize) -> u8 { + let mut diff = 0x41isize; + + // if (in > 25) diff += 0x61 - 0x41 - 26; // 6 + diff += ((25isize - src) >> 8) & 6; + + // if (in > 51) diff += 0x30 - 0x61 - 26; // -75 + diff -= ((51isize - src) >> 8) & 75; + + // if (in > 61) diff += 0x2b - 0x30 - 10; // -15 + diff -= ((61isize - src) >> 8) & 15; + + // if (in > 62) diff += 0x2f - 0x2b - 1; // 3 + diff += ((62isize - src) >> 8) & 3; + + (src + diff) as u8 +} + +#[inline] +fn decode_3bytes(src: &[u8], dst: &mut [u8]) -> isize { + debug_assert_eq!(src.len(), 4); + debug_assert!(dst.len() >= 3, "dst too short: {}", dst.len()); + + let c0 = decode_6bits(src[0]); + let c1 = decode_6bits(src[1]); + let c2 = decode_6bits(src[2]); + let c3 = decode_6bits(src[3]); + + dst[0] = ((c0 << 2) | (c1 >> 4)) as u8; + dst[1] = ((c1 << 4) | (c2 >> 2)) as u8; + dst[2] = ((c2 << 6) | c3) as u8; + + ((c0 | c1 | c2 | c3) >> 8) & 1 +} + +#[inline] +fn decode_6bits(src: u8) -> isize { + let ch = src as isize; + let mut ret: isize = -1; + + // if (ch > 0x40 && ch < 0x5b) ret += ch - 0x41 + 1; // -64 + ret += (((64isize - ch) & (ch - 91isize)) >> 8) & (ch - 64isize); + + // if (ch > 0x60 && ch < 0x7b) ret += ch - 0x61 + 26 + 1; // -70 + ret += (((96isize - ch) & (ch - 123isize)) >> 8) & (ch - 70isize); + + // if (ch > 0x2f && ch < 0x3a) ret += ch - 0x30 + 52 + 1; // 5 + ret += (((47isize - ch) & (ch - 58isize)) >> 8) & (ch + 5isize); + + // if (ch == 0x2b) ret += 62 + 1; + ret += (((42isize - ch) & (ch - 44isize)) >> 8) & 63; + + // if (ch == 0x2f) ret += 63 + 1; + ret + ((((46isize - ch) & (ch - 48isize)) >> 8) & 64) +} + +#[cfg(test)] +mod tests { + use super::*; + + /// "B64" test vector + struct TestVector { + /// Raw bytes. + raw: &'static [u8], + + /// "B64" encoded. + b64: &'static str, + } + + const TEST_VECTORS: &[TestVector] = &[ + TestVector { raw: b"", b64: "" }, + TestVector { + raw: b"\0", + b64: "AA", + }, + TestVector { + raw: b"***", + b64: "Kioq", + }, + TestVector { + raw: b"\x01\x02\x03\x04", + b64: "AQIDBA", + }, + TestVector { + raw: b"\xAD\xAD\xAD\xAD\xAD", + b64: "ra2tra0", + }, + TestVector { + raw: b"\xFF\xFF\xFF\xFF\xFF", + b64: "//////8", + }, + TestVector { + raw: b"\x40\xC1\x3F\xBD\x05\x4C\x72\x2A\xA3\xC2\xF2\x11\x73\xC0\x69\xEA\ + \x49\x7D\x35\x29\x6B\xCC\x24\x65\xF6\xF9\xD0\x41\x08\x7B\xD7\xA9", + b64: "QME/vQVMciqjwvIRc8Bp6kl9NSlrzCRl9vnQQQh716k", + }, + ]; + + #[test] + fn encode_test_vectors() { + let mut buf = [0u8; 1024]; + + for vector in TEST_VECTORS { + let out = encode(vector.raw, &mut buf).unwrap(); + assert_eq!(encoded_len(vector.raw), vector.b64.len()); + assert_eq!(vector.b64, &out[..]); + } + } + + #[test] + fn decode_test_vectors() { + let mut buf = [0u8; 1024]; + + for vector in TEST_VECTORS { + let out = decode(vector.b64, &mut buf).unwrap(); + assert_eq!(decoded_len(vector.b64), out.len()); + assert_eq!(vector.raw, &out[..]); + } + } + + #[test] + fn encode_and_decode_various_lengths() { + let data = [b'X'; 64]; + let mut inbuf = [0u8; 1024]; + let mut outbuf = [0u8; 1024]; + + for i in 0..data.len() { + let encoded = encode(&data[..i], &mut inbuf).unwrap(); + + // Make sure it round trips + let decoded = decode(encoded, &mut outbuf).unwrap(); + assert_eq!(decoded, &data[..i]); + } + } + + #[test] + fn reject_trailing_equals() { + let input = "QME/vQVMciqjwvIRc8Bp6kl9NSlrzCRl9vnQQQh716k="; + let mut buf = [0u8; 1024]; + assert_eq!(decode(input, &mut buf), Err(B64Error::EncodingInvalid)); + } + + #[test] + fn reject_trailing_whitespace() { + let input = "QME/vQVMciqjwvIRc8Bp6kl9NSlrzCRl9vnQQQh716k\n"; + let mut buf = [0u8; 1024]; + assert_eq!(decode(input, &mut buf), Err(B64Error::TrailingWhitespace)); + } +} diff --git a/password-hash/src/errors.rs b/password-hash/src/errors.rs new file mode 100644 index 000000000..0610b2ba5 --- /dev/null +++ b/password-hash/src/errors.rs @@ -0,0 +1,299 @@ +//! Error types. + +use core::fmt; + +#[cfg(docsrs)] +use crate::PasswordHasher; + +/// "B64" encoding errors. +/// +/// +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum B64Error { + /// Encoding error. + EncodingInvalid, + + /// Invalid length. + LengthInvalid, + + /// Trailing whitespace characters. + TrailingWhitespace, +} + +impl fmt::Display for B64Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + match self { + Self::EncodingInvalid => f.write_str("invalid B64 encoding"), + Self::LengthInvalid => f.write_str("B64 encoded data has invalid length"), + Self::TrailingWhitespace => f.write_str("B64 encoded data has trailing whitespace"), + } + } +} + +#[cfg(feature = "std")] +impl std::error::Error for B64Error {} + +/// Password hash errors. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum HashError { + /// Hash output error. + Hash(OutputError), + + /// Params error. + Params(ParamsError), + + /// Parse error. + Parse(ParseError), + + /// Salt error. + Salt(SaltError), +} + +impl fmt::Display for HashError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + match self { + Self::Hash(err) => write!(f, "invalid password hash: {}", err), + Self::Params(err) => write!(f, "invalid params: {}", err), + Self::Parse(err) => write!(f, "parse error: {}", err), + Self::Salt(err) => write!(f, "invalid salt: {}", err), + } + } +} + +impl From for HashError { + fn from(err: OutputError) -> HashError { + HashError::Hash(err) + } +} + +impl From for HashError { + fn from(err: ParamsError) -> HashError { + match err { + ParamsError::Parse(e) => e.into(), + _ => HashError::Params(err), + } + } +} + +impl From for HashError { + fn from(err: ParseError) -> HashError { + HashError::Parse(err) + } +} + +impl From for HashError { + fn from(err: SaltError) -> HashError { + HashError::Salt(err) + } +} + +#[cfg(feature = "std")] +impl std::error::Error for HashError {} + +/// Parameter-related errors. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum ParamsError { + /// Duplicate parameter name encountered. + DuplicateName, + + /// Maximum number of parameters exceeded. + MaxExceeded, + + /// Parse errors. + Parse(ParseError), +} + +impl fmt::Display for ParamsError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + match self { + Self::DuplicateName => f.write_str("duplicate parameter"), + Self::MaxExceeded => f.write_str("maximum number of parameters reached"), + Self::Parse(err) => write!(f, "{}", err), + } + } +} + +impl From for ParamsError { + fn from(err: ParseError) -> ParamsError { + Self::Parse(err) + } +} + +#[cfg(feature = "std")] +impl std::error::Error for ParamsError {} + +/// Parsing errors. +#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)] +pub struct ParseError { + /// Ident contains an invalid character. + pub invalid_char: Option, + + /// Ident is too long. + pub too_long: bool, +} + +impl ParseError { + /// Create a parse error for the case where something is too long. + pub(crate) fn too_long() -> Self { + Self { + invalid_char: None, + too_long: true, + } + } + + /// Did the error occur because the input string was empty? + pub fn is_empty(self) -> bool { + self.invalid_char.is_none() && !self.too_long + } +} + +impl fmt::Display for ParseError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + f.write_str("PHC string parse error: ")?; + + if self.is_empty() { + return f.write_str("empty strings not permitted"); + } + + if let Some(invalid_char) = self.invalid_char { + write!(f, "invalid character '{}'", invalid_char)?; + + if self.too_long { + f.write_str(", ")?; + } + } + + if self.too_long { + // TODO(tarcieri): include const generic maximum length + f.write_str("too long")?; + } + + Ok(()) + } +} + +#[cfg(feature = "std")] +impl std::error::Error for ParseError {} + +/// Errors generating password hashes using a [`PasswordHashingFunction`]. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum PhfError { + /// Unsupported algorithm. + Algorithm, + + /// Cryptographic error. + Crypto, + + /// Error generating output. + Output(OutputError), + + /// Invalid parameter. + Param, + + /// Invalid password. + Password, +} + +impl fmt::Display for PhfError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + match self { + Self::Algorithm => write!(f, "unsupported algorithm"), + Self::Crypto => write!(f, "cryptographic error"), + Self::Output(err) => write!(f, "PHF output error: {}", err), + Self::Param => write!(f, "invalid algorithm parameter"), + Self::Password => write!(f, "invalid password"), + } + } +} + +impl From for PhfError { + fn from(err: OutputError) -> PhfError { + PhfError::Output(err) + } +} + +#[cfg(feature = "std")] +impl std::error::Error for PhfError {} + +/// Password hash function output (i.e. hash/digest) errors. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum OutputError { + /// "B64" encoding error. + B64(B64Error), + + /// Output too short (min 10-bytes). + TooShort, + + /// Output too long (max 64-bytes). + TooLong, +} + +impl fmt::Display for OutputError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + match self { + Self::B64(err) => write!(f, "{}", err), + Self::TooShort => f.write_str("PHF output too short (min 10-bytes)"), + Self::TooLong => f.write_str("PHF output too long (max 64-bytes)"), + } + } +} + +impl From for OutputError { + fn from(err: B64Error) -> OutputError { + OutputError::B64(err) + } +} + +#[cfg(feature = "std")] +impl std::error::Error for OutputError {} + +/// Salt-related errors. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum SaltError { + /// "B64" encoding error. + B64(B64Error), + + /// Salt too short (min 4-bytes). + TooShort, + + /// Salt too long (max 48-bytes). + TooLong, +} + +impl fmt::Display for SaltError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + match self { + Self::B64(err) => write!(f, "{}", err), + Self::TooShort => f.write_str("salt too short (min 4-bytes)"), + Self::TooLong => f.write_str("salt too long (max 48-bytes)"), + } + } +} + +impl From for SaltError { + fn from(err: B64Error) -> SaltError { + SaltError::B64(err) + } +} + +#[cfg(feature = "std")] +impl std::error::Error for SaltError {} + +/// Password verification errors. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub struct VerifyError; + +impl fmt::Display for VerifyError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + f.write_str("password verification error") + } +} + +impl From for VerifyError { + fn from(_: PhfError) -> VerifyError { + VerifyError + } +} + +#[cfg(feature = "std")] +impl std::error::Error for VerifyError {} diff --git a/password-hash/src/ident.rs b/password-hash/src/ident.rs new file mode 100644 index 000000000..67af14525 --- /dev/null +++ b/password-hash/src/ident.rs @@ -0,0 +1,238 @@ +//! Algorithm or parameter identifier. +//! +//! Implements the following parts of the [PHC string format specification][1]: +//! +//! > The function symbolic name is a sequence of characters in: `[a-z0-9-]` +//! > (lowercase letters, digits, and the minus sign). No other character is +//! > allowed. Each function defines its own identifier (or identifiers in case +//! > of a function family); identifiers should be explicit (human readable, +//! > not a single digit), with a length of about 5 to 10 characters. An +//! > identifier name MUST NOT exceed 32 characters in length. +//! > +//! > Each parameter name shall be a sequence of characters in: `[a-z0-9-]` +//! > (lowercase letters, digits, and the minus sign). No other character is +//! > allowed. Parameter names SHOULD be readable for a human user. A +//! > parameter name MUST NOT exceed 32 characters in length. +//! +//! [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md + +use crate::errors::ParseError; +use core::{convert::TryFrom, fmt, ops::Deref, str}; + +/// Maximum size of an identifier. +const MAX_LENGTH: usize = 32; + +/// Algorithm or parameter identifier. +/// +/// This type encompasses both the "function symbolic name" and "parameter name" +/// use cases as described in the [PHC string format specification][1]. +/// +/// # Constraints +/// - ASCII-encoded string consisting of the characters `[a-z0-9-]` +/// (lowercase letters, digits, and the minus sign) +/// - Minimum length: 1 ASCII character (i.e. 1-byte) +/// - Maximum length: 32 ASCII characters (i.e. 32-bytes) +/// +/// [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md +#[derive(Copy, Clone, Eq, Hash, PartialEq, PartialOrd, Ord)] +pub struct Ident<'a>(&'a str); + +impl<'a> Ident<'a> { + /// Maximum length of an [`Ident`] - 32 ASCII characters (i.e. 32-bytes). + /// + /// This value corresponds to the maximum size of a function symbolic names + /// and parameter names according to the PHC string format. + pub const fn max_len() -> usize { + MAX_LENGTH + } + + /// Parse an [`Ident`] from a string. + /// + /// # Panics + /// + /// Must conform to the contraints given in the type-level documentation, + /// or else it will panic. + /// + /// This method is intended for use in a `const` context where instead of + /// panicking it will cause a compile error. + /// + /// For fallible non-panicking parsing of an [`Ident`], use the [`FromStr`] + /// impl on this type instead, e.g. `s.parse::()`. + pub const fn new(s: &'a str) -> Self { + let input = s.as_bytes(); + + /// Constant panicking assertion. + // TODO(tarcieri): use const panic when stable. + // See: https://github.com/rust-lang/rust/issues/51999 + macro_rules! const_assert { + ($bool:expr, $msg:expr) => { + [$msg][!$bool as usize] + }; + } + + const_assert!(!input.is_empty(), "PHC ident string can't be empty"); + const_assert!(input.len() <= MAX_LENGTH, "PHC ident string too long"); + + macro_rules! validate_chars { + ($($pos:expr),+) => { + $( + if $pos < input.len() { + const_assert!( + is_char_valid(input[$pos]), + "invalid character in PHC string ident" + ); + } + )+ + }; + } + + validate_chars!( + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31 + ); + + Self(s) + } + + /// Borrow this ident as a `str` + pub fn as_str(&self) -> &'a str { + self.0 + } +} + +impl<'a> AsRef for Ident<'a> { + fn as_ref(&self) -> &str { + self.as_str() + } +} + +impl<'a> Deref for Ident<'a> { + type Target = str; + + fn deref(&self) -> &str { + self.as_str() + } +} + +// Note: this uses `TryFrom` instead of `FromStr` to support a lifetime on +// the `str` the value is being parsed from. +impl<'a> TryFrom<&'a str> for Ident<'a> { + type Error = ParseError; + + fn try_from(s: &'a str) -> Result { + if s.is_empty() { + return Err(ParseError::default()); + } + + let bytes = s.as_bytes(); + let too_long = bytes.len() > MAX_LENGTH; + + for &c in bytes { + if !is_char_valid(c) { + return Err(ParseError { + invalid_char: Some(c.into()), + too_long, + }); + } + } + + if too_long { + return Err(ParseError::too_long()); + } + + Ok(Self::new(s)) + } +} + +impl<'a> fmt::Display for Ident<'a> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(&*self) + } +} + +impl<'a> fmt::Debug for Ident<'a> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_tuple("Ident").field(&self.as_ref()).finish() + } +} + +/// Ensure the given ASCII character (i.e. byte) is allowed in an [`Ident`]. +const fn is_char_valid(c: u8) -> bool { + matches!(c, b'a'..=b'z' | b'0'..=b'9' | b'-') +} + +#[cfg(test)] +mod tests { + use super::Ident; + use core::convert::TryFrom; + + // Invalid ident examples + const INVALID_EMPTY: &str = ""; + const INVALID_CHAR: &str = "argon2;d"; + const INVALID_TOO_LONG: &str = "012345678911234567892123456789312"; + const INVALID_CHAR_AND_TOO_LONG: &str = "0!2345678911234567892123456789312"; + + #[test] + fn parse_valid() { + let valid_examples = ["6", "x", "argon2d", "01234567891123456789212345678931"]; + + for &example in &valid_examples { + let const_val = Ident::new(example); + let try_from_val = Ident::try_from(example).unwrap(); + assert_eq!(example, &*const_val); + assert_eq!(example, &*try_from_val); + } + } + + #[test] + #[should_panic] + fn reject_empty_const() { + Ident::new(INVALID_EMPTY); + } + + #[test] + fn reject_empty_fallible() { + let err = Ident::try_from(INVALID_EMPTY).err().unwrap(); + assert_eq!(err.invalid_char, None); + assert!(!err.too_long); + } + + #[test] + #[should_panic] + fn reject_invalid_char_const() { + Ident::new(INVALID_CHAR); + } + + #[test] + fn reject_invalid_char_fallible() { + let err = Ident::try_from(INVALID_CHAR).err().unwrap(); + assert_eq!(err.invalid_char, Some(';')); + assert!(!err.too_long); + } + + #[test] + #[should_panic] + fn reject_too_long_const() { + Ident::new(INVALID_TOO_LONG); + } + + #[test] + fn reject_too_long_fallible() { + let err = Ident::try_from(INVALID_TOO_LONG).err().unwrap(); + assert_eq!(err.invalid_char, None); + assert!(err.too_long); + } + + #[test] + #[should_panic] + fn reject_invalid_char_and_too_long_const() { + Ident::new(INVALID_CHAR_AND_TOO_LONG); + } + + #[test] + fn reject_invalid_char_and_too_long_fallible() { + let err = Ident::try_from(INVALID_CHAR_AND_TOO_LONG).err().unwrap(); + assert_eq!(err.invalid_char, Some('!')); + assert!(err.too_long); + } +} diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs new file mode 100644 index 000000000..e36d3fdf2 --- /dev/null +++ b/password-hash/src/lib.rs @@ -0,0 +1,267 @@ +//! This crate defines a set of traits which describe the functionality of +//! [password hashing algorithms]. +//! +//! Provides a `no_std`-friendly implementation of the [PHC string format specification] +//! (a well-defined subset of the [Modular Crypt Format a.k.a. MCF][MCF]) which +//! works in conjunction with the traits this crate defines. +//! +//! See [RustCrypto/password-hashes] for algorithm implementations which use +//! this crate for interoperability. +//! +//! # Usage +//! +//! This crate represents password hashes using the [`PasswordHash`] type, which +//! represents a parsed "PHC string" with the following format: +//! +//! ```text +//! $[$=(,=)*][$[$]] +//! ``` +//! +//! For more information, please see the documentation for [`PasswordHash`]. +//! +//! [password hashing algorithms]: https://en.wikipedia.org/wiki/Cryptographic_hash_function#Password_verification +//! [PHC string format specification]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md +//! [MCF]: https://passlib.readthedocs.io/en/stable/modular_crypt_format.html +//! [RustCrypto/password-hashes]: https://github.com/RustCrypto/password-hashes + +#![no_std] +#![cfg_attr(docsrs, feature(doc_cfg))] +#![doc( + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" +)] +#![allow(clippy::len_without_is_empty)] +#![forbid(unsafe_code)] +#![warn(missing_docs, rust_2018_idioms)] + +#[cfg(feature = "alloc")] +#[macro_use] +extern crate alloc; + +#[cfg(feature = "std")] +extern crate std; + +pub mod b64; +pub mod errors; +pub mod params; + +mod ident; +mod output; +mod salt; + +pub use crate::{ + errors::{HashError, PhfError, VerifyError}, + ident::Ident, + output::Output, + params::Params, + salt::Salt, +}; + +use core::{convert::TryFrom, fmt}; + +/// Separator character used in password hashes (e.g. `$6$...`). +const PASSWORD_HASH_SEPARATOR: char = '$'; + +/// Trait for password hashing functions. +pub trait PasswordHasher { + /// Compute a [`PasswordHash`] from the given [`Algorithm`] (or the + /// recommended default), password, salt, and optional [`Params`]. + /// + /// Use [`Params::new`] or [`Params::default`] to use the default + /// parameters for a given algorithm. + fn hash_password<'a>( + &self, + algorithm: Option>, + password: &[u8], + salt: Salt, + params: Params<'a>, + ) -> Result, PhfError>; + + /// Compute this password hashing function against the provided password + /// using the parameters from the provided password hash and see if the + /// computed output matches. + fn verify_password(&self, password: &[u8], hash: &PasswordHash<'_>) -> Result<(), VerifyError> { + if let (Some(salt), Some(expected_output)) = (&hash.salt, &hash.hash) { + let computed_hash = + self.hash_password(Some(hash.algorithm), password, *salt, hash.params.clone())?; + + if let Some(computed_output) = &computed_hash.hash { + // See notes on `Output` about the use of a constant-time comparison + if expected_output == computed_output { + return Ok(()); + } + } + } + + Err(VerifyError) + } +} + +/// Password hash. +/// +/// This type corresponds to the parsed representation of a PHC string as +/// described in the [PHC string format specification][1]. +/// +/// PHC strings have the following format: +/// +/// ```text +/// $[$=(,=)*][$[$]] +/// ``` +/// +/// where: +/// +/// - `` is the symbolic name for the function +/// - `` is a parameter name +/// - `` is a parameter value +/// - `` is an encoding of the salt +/// - `` is an encoding of the hash output +/// +/// The string is then the concatenation, in that order, of: +/// +/// - a `$` sign; +/// - the function symbolic name; +/// - optionally, a `$` sign followed by one or several parameters, each with a `name=value` format; +/// the parameters are separated by commas; +/// - optionally, a `$` sign followed by the (encoded) salt value; +/// - optionally, a `$` sign followed by the (encoded) hash output (the hash output may be present +/// only if the salt is present). +/// +/// [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#specification +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct PasswordHash<'a> { + /// Password hashing [`Algorithm`]. + /// + /// This corresponds to the `` field in a PHC string, a.k.a. the + /// symbolic name for the function. + pub algorithm: Ident<'a>, + + /// Algorithm-specific [`Params`]. + /// + /// This corresponds to the set of `$=(,=)*` + /// name/value pairs in a PHC string. + pub params: Params<'a>, + + /// [`Salt`] string for personalizing a password hash output. + /// + /// This corresponds to the `` value in a PHC string. + pub salt: Option, + + /// Password hashing function [`Output`], a.k.a. hash/digest. + /// + /// This corresponds to the `` output in a PHC string. + pub hash: Option, +} + +impl<'a> PasswordHash<'a> { + /// Parse a password hash from a string in the PHC string format. + pub fn new(s: &'a str) -> Result { + use errors::ParseError; + + if s.is_empty() { + return Err(ParseError::default().into()); + } + + let mut fields = s.split(PASSWORD_HASH_SEPARATOR); + let beginning = fields.next().expect("no first field"); + + if let Some(first_char) = beginning.chars().next() { + return Err(ParseError { + invalid_char: Some(first_char), + too_long: false, + } + .into()); + } + + let algorithm = fields + .next() + .ok_or_else(ParseError::default) + .and_then(Ident::try_from)?; + + let mut params = Params::new(); + let mut salt = None; + let mut hash = None; + + if let Some(field) = fields.next() { + if field.contains(params::PAIR_DELIMITER) { + params = Params::try_from(field)?; + + if let Some(s) = fields.next() { + salt = Some(s.parse()?); + } + } else { + salt = Some(field.parse()?); + } + } + + if let Some(field) = fields.next() { + hash = Some(field.parse()?); + } + + if fields.next().is_some() { + return Err(ParseError::too_long().into()); + } + + Ok(Self { + algorithm, + params, + salt, + hash, + }) + } + + /// Generate a password hash using the supplied algorithm. + pub fn generate( + phf: impl PasswordHasher, + password: impl AsRef<[u8]>, + salt: Salt, + params: Params<'a>, + ) -> Result { + phf.hash_password(None, password.as_ref(), salt, params) + } + + /// Verify this password hash using the specified set of supported + /// [`PasswordHashingFunction`] objects. + pub fn verify_password( + &self, + phfs: &[&dyn PasswordHasher], + password: impl AsRef<[u8]>, + ) -> Result<(), VerifyError> { + for &phf in phfs { + if phf.verify_password(password.as_ref(), self).is_ok() { + return Ok(()); + } + } + + Err(VerifyError) + } +} + +// Note: this uses `TryFrom` instead of `FromStr` to support a lifetime on +// the `str` the value is being parsed from. +impl<'a> TryFrom<&'a str> for PasswordHash<'a> { + type Error = HashError; + + fn try_from(s: &'a str) -> Result { + Self::new(s) + } +} + +impl<'a> fmt::Display for PasswordHash<'a> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}{}", PASSWORD_HASH_SEPARATOR, self.algorithm)?; + + if !self.params.is_empty() { + write!(f, "{}{}", PASSWORD_HASH_SEPARATOR, self.params)?; + } + + if let Some(salt) = &self.salt { + write!(f, "{}{}", PASSWORD_HASH_SEPARATOR, salt)?; + } + + if let Some(hash) = &self.hash { + write!(f, "{}{}", PASSWORD_HASH_SEPARATOR, hash)?; + } + + Ok(()) + } +} diff --git a/password-hash/src/output.rs b/password-hash/src/output.rs new file mode 100644 index 000000000..3199f7615 --- /dev/null +++ b/password-hash/src/output.rs @@ -0,0 +1,241 @@ +//! Outputs from password hashing functions. + +use crate::{b64, errors::OutputError}; +use core::{cmp::PartialEq, convert::TryFrom, fmt, ops::Deref, str::FromStr}; + +/// Maximum length of password hash function outputs. +const MAX_LENGTH: usize = 64; + +/// Output from password hashing functions, i.e. the "hash" or "digest" +/// as raw bytes. +/// +/// The [`Output`] type implements the RECOMMENDED best practices described in +/// the [PHC string format specification][1], namely: +/// +/// > The hash output, for a verification, must be long enough to make preimage +/// > attacks at least as hard as password guessing. To promote wide acceptance, +/// > a default output size of 256 bits (32 bytes, encoded as 43 characters) is +/// > recommended. Function implementations SHOULD NOT allow outputs of less +/// > than 80 bits to be used for password verification. +/// +/// # Recommended length +/// Per the description above, the recommended default length for an [`Output`] +/// of a password hashing function is **32-bytes** (256-bits). +/// +/// # Constraints +/// The above guidelines are interpreted into the following constraints: +/// +/// - Minimum length: **10**-bytes (80-bits) +/// - Maximum length: **64**-bytes (512-bits) +/// +/// The specific recommendation of a 64-byte maximum length is taken as a best +/// practice from the hash output guidelines for [Argon2 Encoding][2] given in +/// the same document: +/// +/// > The hash output...length shall be between 12 and 64 bytes (16 and 86 +/// > characters, respectively). The default output length is 32 bytes +/// > (43 characters). +/// +/// Based on this guidance, this type enforces an upper bound of 64-bytes +/// as a reasonable maximum, and recommends using 32-bytes. +/// +/// # Constant-time comparisons +/// The [`PartialEq`] and [`Eq`] trait impls for [`Output`] provide a +/// non-short-circuiting equality comparison. +/// +/// There are few cases where this may actually helpful from a practical +/// perspective, namely cases where salts are predictable by an attacker. +/// Due to the limited degree in which such comparisons may be helpful, +/// this crate does not loop in additional dependencies for +/// constant-time comparisons (e.g. `subtle`). +/// +/// The extent to which constant-time comparisons of password hashes is +/// actually helpful in practical contexts [topic of considerable debate][3]. +/// This library has elected to use a non-short-circuiting comparison as a +/// safer ("belt-and-suspenders") default, and also to +/// [head off any potential debates around the issue][4]. +/// +/// [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#function-duties +/// [2]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#argon2-encoding +/// [3]: https://github.com/codahale/bcrypt-ruby/issues/42 +/// [4]: https://twitter.com/coda/status/866310352606068736 +#[derive(Copy, Clone, Eq)] +pub struct Output { + /// Byte array containing a password hashing function output. + bytes: [u8; MAX_LENGTH], + + /// Length of the password hashing function output in bytes. + length: u8, +} + +impl Output { + /// Minimum length of [`Output`] string: 10-bytes. + /// + /// See type-level documentation about [`Output`] for more information. + pub const fn min_len() -> usize { + 10 + } + + /// Maximum length of [`Output`] string: 64-bytes. + /// + /// See type-level documentation about [`Output`] for more information. + pub const fn max_len() -> usize { + MAX_LENGTH + } + + /// Maximum length of [`Output`] when encoded as [`b64`] string: 86-bytes + /// (i.e. 86 ASCII characters) + pub const fn b64_max_len() -> usize { + ((MAX_LENGTH * 4) / 3) + 1 + } + + /// Create a [`Output`] from the given byte slice, validating it according + /// to [`Output::min_len`] and [`Output::max_len`] length restrictions. + pub fn new(input: &[u8]) -> Result { + if input.len() < Self::min_len() { + return Err(OutputError::TooShort); + } + + if input.len() > Self::max_len() { + return Err(OutputError::TooLong); + } + + let mut bytes = [0u8; MAX_LENGTH]; + bytes[..input.len()].copy_from_slice(input); + + Ok(Self { + bytes, + length: input.len() as u8, + }) + } + + /// Parse [`b64`]-encoded [`Output`], i.e. using the PHC string + /// specification's restricted interpretation of Base64. + pub fn b64_decode(input: &str) -> Result { + if b64::decoded_len(input) > MAX_LENGTH { + return Err(OutputError::TooLong); + } + + let mut bytes = [0u8; MAX_LENGTH]; + b64::decode(input, &mut bytes) + .map_err(Into::into) + .and_then(Self::new) + } + + /// Write [`b64`]-encoded [`Output`] to the provided buffer, returning + /// a sub-slice containing the encoded data. + /// + /// Returns an error if the buffer is too short to contain the output. + pub fn b64_encode<'a>(&self, out: &'a mut [u8]) -> Result<&'a str, OutputError> { + Ok(b64::encode(self.as_ref(), out)?) + } + + /// Get the length of this [`Output`] when encoded as [`b64`]. + pub fn b64_len(&self) -> usize { + b64::encoded_len(self.as_ref()) + } +} + +impl AsRef<[u8]> for Output { + fn as_ref(&self) -> &[u8] { + &self.bytes[..(self.length as usize)] + } +} + +impl Deref for Output { + type Target = [u8]; + + fn deref(&self) -> &[u8] { + self.as_ref() + } +} + +impl FromStr for Output { + type Err = OutputError; + + fn from_str(s: &str) -> Result { + Self::b64_decode(s) + } +} + +impl PartialEq for Output { + fn eq(&self, other: &Self) -> bool { + if self.len() != other.len() { + return false; + } + + self.as_ref() + .iter() + .zip(other.as_ref().iter()) + .fold(0, |acc, (a, b)| acc | (a ^ b)) + == 0 + } +} + +impl TryFrom<&[u8]> for Output { + type Error = OutputError; + + fn try_from(input: &[u8]) -> Result { + Self::new(input) + } +} + +impl fmt::Display for Output { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut buffer = [0u8; Self::b64_max_len()]; + f.write_str(self.b64_encode(&mut buffer).map_err(|_| fmt::Error)?) + } +} + +impl fmt::Debug for Output { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Output(\"{}\")", self) + } +} + +#[cfg(test)] +mod tests { + use super::{Output, OutputError}; + + #[test] + fn new_with_valid_min_length_input() { + let bytes = [10u8; 10]; + let output = Output::new(&bytes).unwrap(); + assert_eq!(output.as_ref(), &bytes); + } + + #[test] + fn new_with_valid_max_length_input() { + let bytes = [64u8; 64]; + let output = Output::new(&bytes).unwrap(); + assert_eq!(output.as_ref(), &bytes); + } + + #[test] + fn reject_new_too_short() { + let bytes = [9u8; 9]; + let err = Output::new(&bytes).err().unwrap(); + assert_eq!(err, OutputError::TooShort); + } + + #[test] + fn reject_new_too_long() { + let bytes = [65u8; 65]; + let err = Output::new(&bytes).err().unwrap(); + assert_eq!(err, OutputError::TooLong); + } + + #[test] + fn partialeq_true() { + let a = Output::new(&[1u8; 32]).unwrap(); + let b = Output::new(&[1u8; 32]).unwrap(); + assert_eq!(a, b); + } + + #[test] + fn partialeq_false() { + let a = Output::new(&[1u8; 32]).unwrap(); + let b = Output::new(&[2u8; 32]).unwrap(); + assert_ne!(a, b); + } +} diff --git a/password-hash/src/params.rs b/password-hash/src/params.rs new file mode 100644 index 000000000..27fd9321c --- /dev/null +++ b/password-hash/src/params.rs @@ -0,0 +1,367 @@ +//! Algorithm parameters. + +mod value; + +pub use self::value::{Decimal, Value, ValueStr}; + +use crate::{ + errors::{ParamsError, ParseError}, + Ident, +}; +use core::{ + convert::{TryFrom, TryInto}, + fmt, + iter::FromIterator, + ops::Index, + slice, +}; + +/// Individual parameter name/value pair. +pub type Pair<'a> = (Ident<'a>, Value<'a>); + +/// Delimiter character between name/value pairs. +pub(crate) const PAIR_DELIMITER: char = '='; + +/// Delimiter character between parameters. +pub(crate) const PARAMS_DELIMITER: char = ','; + +/// Maximum number of supported parameters. +const MAX_LENGTH: usize = 8; + +/// Algorithm parameters. +/// +/// The [PHC string format specification][1] defines a set of optional +/// algorithm-specific name/value pairs which can be encoded into a +/// PHC-formatted parameter string as follows: +/// +/// ```text +/// $=(,=)* +/// ``` +/// +/// This type represents that set of parameters. +/// +/// [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#specification +#[derive(Clone, Default, Eq, PartialEq)] +pub struct Params<'a> { + /// Name/value pairs. + /// + /// Name (i.e. the [`Ident`]) *MUST* be unique. + pairs: [Option>; MAX_LENGTH], +} + +impl<'a> Params<'a> { + /// Create new empty [`Params`]. + pub fn new() -> Self { + Self::default() + } + + /// Instantiate [`Params`] from a slice of name/value pairs. + pub fn from_slice(pairs: &[Pair<'a>]) -> Result { + let mut result = Self::default(); + + for (name, value) in pairs.iter().cloned() { + result = result.add(name, value)?; + } + + Ok(result) + } + + /// Add another pair to the [`Params`]. + pub fn add(mut self, name: Ident<'a>, value: Value<'a>) -> Result { + for entry in &mut self.pairs { + match entry { + Some((n, _)) => { + // If slot is occupied, ensure the name isn't a duplicate + if *n == name { + // TODO(tarcieri): make idempotent? (i.e. ignore dupes if the value is the same) + return Err(ParamsError::DuplicateName); + } + } + None => { + // Use free slot if available + *entry = Some((name, value)); + return Ok(self); + } + } + } + + Err(ParamsError::MaxExceeded) + } + + /// Get a parameter value by name. + pub fn get(&self, name: Ident<'a>) -> Option<&Value<'a>> { + for entry in &self.pairs { + match entry { + Some((n, v)) => { + if *n == name { + return Some(v); + } + } + None => return None, + } + } + + None + } + + /// Iterate over the parameters using [`Iter`]. + pub fn iter(&self) -> Iter<'a, '_> { + Iter { + inner: self.pairs.iter(), + } + } + + /// Get the count of the number of parameters. + pub fn len(&self) -> usize { + self.iter().count() + } + + /// Is this set of parameters empty? + pub fn is_empty(&self) -> bool { + self.len() == 0 + } +} + +impl<'a> FromIterator> for Params<'a> { + fn from_iter(iter: I) -> Self + where + I: IntoIterator>, + { + iter.into_iter() + .fold(Params::new(), |params, (name, value)| { + params.add(name, value).expect("error adding param") + }) + } +} + +// Note: this uses `TryFrom` instead of `FromStr` to support a lifetime on +// the `str` the value is being parsed from. +impl<'a> TryFrom<&'a str> for Params<'a> { + type Error = ParamsError; + + fn try_from(input: &'a str) -> Result { + let mut params = Params::new(); + + if input.is_empty() { + return Ok(params); + } + + for mut param in input + .split(PARAMS_DELIMITER) + .map(|p| p.split(PAIR_DELIMITER)) + { + let name = param.next().ok_or(ParseError { + invalid_char: Some(PAIR_DELIMITER), + too_long: false, + })?; + + let value = param.next().ok_or(ParseError { + invalid_char: Some(PAIR_DELIMITER), + too_long: false, + })?; + + if param.next().is_some() { + return Err(ParseError::too_long().into()); + } + + params = params.add(name.try_into()?, value.try_into()?)?; + } + + Ok(params) + } +} + +impl<'a> Index> for Params<'a> { + type Output = Value<'a>; + + fn index(&self, name: Ident<'a>) -> &Value<'a> { + self.get(name) + .unwrap_or_else(|| panic!("no parameter with name `{}`", name)) + } +} + +impl<'a> Index<&'a str> for Params<'a> { + type Output = Value<'a>; + + fn index(&self, name: &'a str) -> &Value<'a> { + &self[Ident::try_from(name).expect("invalid parameter name")] + } +} + +impl<'a> fmt::Display for Params<'a> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let n = self.len(); + + for (i, (name, value)) in self.iter().enumerate() { + write!(f, "{}{}{}", name, PAIR_DELIMITER, value)?; + + if i + 1 != n { + write!(f, "{}", PARAMS_DELIMITER)?; + } + } + + Ok(()) + } +} + +impl<'a> fmt::Debug for Params<'a> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_map() + .entries( + self.iter() + .map(|&(ref name, ref value)| (name.as_str(), value)), + ) + .finish() + } +} + +/// Iterator over algorithm parameters stored in a [`Params`] struct. +pub struct Iter<'a, 'b> { + /// Inner slice iterator this newtype wrapper is built upon. + inner: slice::Iter<'b, Option>>, +} + +impl<'a, 'b> Iterator for Iter<'a, 'b> { + type Item = &'b Pair<'a>; + + fn next(&mut self) -> Option<&'b Pair<'a>> { + self.inner.next()?.as_ref() + } +} + +#[cfg(test)] +mod tests { + use super::{FromIterator, Ident, Params, ParamsError}; + use core::convert::TryFrom; + + #[cfg(feature = "alloc")] + use alloc::string::ToString; + + #[test] + fn add_chain() { + let params = Params::new() + .add(Ident::new("a"), 1i32.into()) + .and_then(|p| p.add(Ident::new("b"), 2i32.into())) + .and_then(|p| p.add(Ident::new("c"), 3i32.into())) + .unwrap(); + + assert_eq!(params.len(), 3); + assert_eq!(params["a"].decimal().unwrap(), 1); + assert_eq!(params["b"].decimal().unwrap(), 2); + assert_eq!(params["c"].decimal().unwrap(), 3); + } + + #[test] + fn duplicate_names() { + let name = Ident::new("a"); + let params = Params::new().add(name, 1i32.into()).unwrap(); + let err = params.add(name, 2i32.into()).err().unwrap(); + assert_eq!(err, ParamsError::DuplicateName); + } + + #[test] + fn from_slice() { + let params = Params::from_slice(&[ + (Ident::new("a"), 1i32.into()), + (Ident::new("b"), 2i32.into()), + (Ident::new("c"), 3i32.into()), + ]) + .unwrap(); + + assert_eq!(params.len(), 3); + assert_eq!(params["a"].decimal().unwrap(), 1); + assert_eq!(params["b"].decimal().unwrap(), 2); + assert_eq!(params["c"].decimal().unwrap(), 3); + } + + #[test] + fn from_iterator() { + let params = Params::from_iter( + [ + (Ident::new("a"), 1i32.into()), + (Ident::new("b"), 2i32.into()), + (Ident::new("c"), 3i32.into()), + ] + .iter() + .cloned(), + ); + + assert_eq!(params.len(), 3); + assert_eq!(params["a"].decimal().unwrap(), 1); + assert_eq!(params["b"].decimal().unwrap(), 2); + assert_eq!(params["c"].decimal().unwrap(), 3); + } + + #[test] + fn iter() { + let params = Params::from_slice(&[ + (Ident::new("a"), 1i32.into()), + (Ident::new("b"), 2i32.into()), + (Ident::new("c"), 3i32.into()), + ]) + .unwrap(); + + let mut i = params.iter(); + assert_eq!(i.next(), Some(&(Ident::new("a"), 1i32.into()))); + assert_eq!(i.next(), Some(&(Ident::new("b"), 2i32.into()))); + assert_eq!(i.next(), Some(&(Ident::new("c"), 3i32.into()))); + assert_eq!(i.next(), None); + } + + // + // `FromStr` tests + // + + #[test] + fn parse_empty() { + let params = Params::try_from("").unwrap(); + assert!(params.is_empty()); + } + + #[test] + fn parse_one() { + let params = Params::try_from("a=1").unwrap(); + assert_eq!(params.len(), 1); + assert_eq!(params["a"].decimal().unwrap(), 1); + } + + #[test] + fn parse_many() { + let params = Params::try_from("a=1,b=2,c=3").unwrap(); + assert_eq!(params.len(), 3); + assert_eq!(params["a"].decimal().unwrap(), 1); + assert_eq!(params["b"].decimal().unwrap(), 2); + assert_eq!(params["c"].decimal().unwrap(), 3); + } + + // + // `Display` tests + // + + #[test] + #[cfg(feature = "alloc")] + fn display_empty() { + let params = Params::new(); + assert_eq!(params.to_string(), ""); + } + + #[test] + #[cfg(feature = "alloc")] + fn display_one() { + let params = Params::from_slice(&[(Ident::new("a"), 1i32.into())]).unwrap(); + assert_eq!(params.to_string(), "a=1"); + } + + #[test] + #[cfg(feature = "alloc")] + fn display_many() { + let params = Params::from_slice(&[ + (Ident::new("a"), 1i32.into()), + (Ident::new("b"), 2i32.into()), + (Ident::new("c"), 3i32.into()), + ]) + .unwrap(); + + assert_eq!(params.to_string(), "a=1,b=2,c=3"); + } +} diff --git a/password-hash/src/params/value.rs b/password-hash/src/params/value.rs new file mode 100644 index 000000000..cea9da2ef --- /dev/null +++ b/password-hash/src/params/value.rs @@ -0,0 +1,413 @@ +//! Algorithm parameter value as defined by the [PHC string format]. +//! +//! Implements the following parts of the specification: +//! +//! > The value for each parameter consists in characters in: `[a-zA-Z0-9/+.-]` +//! > (lowercase letters, uppercase letters, digits, /, +, . and -). No other +//! > character is allowed. Interpretation of the value depends on the +//! > parameter and the function. The function specification MUST unambiguously +//! > define the set of valid parameter values. The function specification MUST +//! > define a maximum length (in characters) for each parameter. For numerical +//! > parameters, functions SHOULD use plain decimal encoding (other encodings +//! > are possible as long as they are clearly defined). +//! +//! [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md + +use crate::{ + b64, + errors::{B64Error, ParseError}, +}; +use core::{convert::TryFrom, fmt, str}; + +/// Maximum size of a parameter value in ASCII characters. +const MAX_LENGTH: usize = 48; + +/// Type used to represent decimal (i.e. integer) values. +pub type Decimal = i32; + +/// Algorithm parameter value. +/// +/// Provides an enum over [`Decimal`] and string (i.e. [`ValueStr`]) values +/// to allow ergonomically using and parsing integer values, which is the +/// main use case for this type. +#[derive(Copy, Clone, Eq, PartialEq)] +pub enum Value<'a> { + /// Decimal value. + Decimal(Decimal), + + /// String value. + Str(ValueStr<'a>), +} + +impl<'a> Value<'a> { + /// Parse a [`Value`] from the provided `str`, validating it according to + /// the PHC string format's rules. + pub fn new(input: &'a str) -> Result { + ValueStr::new(input).map(Value::Str) + } + + /// Borrow the inner value as a `str`, if it is one. + /// + /// Returns `None` if the inner value is a [`Value::Decimal`]. + pub fn as_str(&self) -> Option<&'a str> { + match self { + Self::Decimal(_) => None, + Self::Str(s) => Some(s.as_str()), + } + } + + /// Parse a [`Decimal`] from this [`Value`]. + /// + /// If this value is a [`Value::Decimal`], the decimal value is returned, + /// otherwise if it's a [`Value::Str`] the value is parsed using the + /// [`ValueStr::decimal`] method. + pub fn decimal(&self) -> Result { + match self { + Self::Decimal(x) => Ok(*x), + Self::Str(s) => s.decimal(), + } + } + + /// Does this value parse successfully as a decimal? + pub fn is_decimal(&self) -> bool { + self.decimal().is_ok() + } +} + +impl<'a> From for Value<'a> { + fn from(decimal: Decimal) -> Value<'a> { + Value::Decimal(decimal) + } +} + +impl<'a> TryFrom for Value<'a> { + type Error = ParseError; + + fn try_from(decimal: u32) -> Result, ParseError> { + i32::try_from(decimal) + .ok() + .map(Into::into) + .ok_or_else(ParseError::too_long) + } +} + +impl<'a> TryFrom<&'a str> for Value<'a> { + type Error = ParseError; + + fn try_from(input: &'a str) -> Result { + Self::new(input) + } +} + +impl<'a> fmt::Display for Value<'a> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Decimal(x) => write!(f, "{}", x), + Self::Str(s) => f.write_str(s.as_str()), + } + } +} + +impl<'a> fmt::Debug for Value<'a> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Decimal(x) => f.debug_tuple("Value::Decimal").field(x).finish(), + Self::Str(s) => f.debug_tuple("Value::Str").field(s).finish(), + } + } +} + +/// Algorithm parameter value string. +/// +/// Parameter values are defined in the [PHC string format specification][1]. +/// +/// # Constraints +/// - ASCII-encoded string consisting of the characters `[a-zA-Z0-9/+.-]` +/// (lowercase letters, digits, and the minus sign) +/// - Minimum length: 0 (i.e. empty values are allowed) +/// - Maximum length: 48 ASCII characters (i.e. 48-bytes) +/// +/// # Additional Notes +/// The PHC spec allows for algorithm-defined maximum lengths for parameter +/// values, however in the interest of interoperability this library defines a +/// [`Value::max_len`] of 48 ASCII characters. +/// +/// [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md +/// [2]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#argon2-encoding +#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)] +pub struct ValueStr<'a>(&'a str); + +impl<'a> ValueStr<'a> { + /// Maximum length of an [`ValueStr`] - 48 ASCII characters (i.e. 48-bytes). + /// + /// This value is selected based on the maximum value size used in the + /// [Argon2 Encoding][1] as described in the PHC string format specification. + /// Namely the `data` parameter, when encoded as B64, can be up to 43 + /// characters. + /// + /// This implementation rounds that up to 48 as a safe maximum limit. + /// + /// [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#argon2-encoding + pub const fn max_len() -> usize { + MAX_LENGTH + } + + /// Parse a [`ValueStr`] from the provided `str`, validating it according to + /// the PHC string format's rules. + pub fn new(input: &'a str) -> Result { + let too_long = input.as_bytes().len() > MAX_LENGTH; + + // Check that the characters are permitted in a PHC parameter value. + assert_valid_value(input).map_err(|mut e| { + e.too_long = too_long; + e + })?; + + if too_long { + return Err(ParseError::too_long()); + } + + Ok(Self(input)) + } + + /// Attempt to decode a [`b64`]-encoded [`ValueStr`], writing the decoded + /// result into the provided buffer, and returning a slice of the buffer + /// containing the decoded result on success. + /// + /// Examples of "B64"-encoded parameters in practice are the `keyid` and + /// `data` parameters used by the [Argon2 Encoding][1] as described in the + /// PHC string format specification. + /// + /// [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#argon2-encoding + pub fn b64_decode<'b>(&self, buf: &'b mut [u8]) -> Result<&'b [u8], B64Error> { + b64::decode(self.as_str(), buf) + } + + /// Borrow this value as a `str`. + pub fn as_str(&self) -> &'a str { + self.0 + } + + /// Borrow this value as bytes. + pub fn as_bytes(&self) -> &'a [u8] { + self.as_str().as_bytes() + } + + /// Get the length of this value in ASCII characters. + pub fn len(&self) -> usize { + self.as_str().len() + } + + /// Is this value empty? + pub fn is_empty(&self) -> bool { + self.as_str().is_empty() + } + + /// Attempt to parse this [`ValueStr`] as a PHC-encoded decimal (i.e. integer). + /// + /// Decimal values are integers which follow the rules given in the + /// ["Decimal Encoding" section of the PHC string format specification][1]. + /// + /// The decimal encoding rules are as follows: + /// > For an integer value x, its decimal encoding consist in the following: + /// > + /// > - If x < 0, then its decimal encoding is the minus sign - followed by the decimal + /// encoding of -x. + /// > - If x = 0, then its decimal encoding is the single character 0. + /// > - If x > 0, then its decimal encoding is the smallest sequence of ASCII digits that + /// > matches its value (i.e. there is no leading zero). + /// > + /// > Thus, a value is a valid decimal for an integer x if and only if all of the following hold true: + /// > + /// > - The first character is either a - sign, or an ASCII digit. + /// > - All characters other than the first are ASCII digits. + /// > - If the first character is - sign, then there is at least another character, and the + /// second character is not a 0. + /// > - If the string consists in more than one character, then the first one cannot be a 0. + /// + /// [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#decimal-encoding + // TODO(tarcieri): support for negative decimal values (is there a use case?) + pub fn decimal(&self) -> Result { + let value = self.as_str(); + + // Empty strings aren't decimals + if value.is_empty() { + return Err(ParseError::default()); + } + + // Ensure all characters are digits + for char in value.chars() { + if !matches!(char, '0'..='9') { + return Err(ParseError { + invalid_char: Some(char), + too_long: false, + }); + } + } + + // Disallow leading zeroes + if value.starts_with('0') && value.len() > 1 { + return Err(ParseError { + invalid_char: Some('0'), + too_long: false, + }); + } + + value.parse().map_err(|_| { + // In theory a value overflow should be the only potential error here. + // When `ParseIntError::kind` is stable it might be good to double check: + // + ParseError::too_long() + }) + } + + /// Does this value parse successfully as a decimal? + pub fn is_decimal(&self) -> bool { + self.decimal().is_ok() + } +} + +impl<'a> AsRef for ValueStr<'a> { + fn as_ref(&self) -> &str { + self.as_str() + } +} + +impl<'a> TryFrom<&'a str> for ValueStr<'a> { + type Error = ParseError; + + fn try_from(input: &'a str) -> Result { + Self::new(input) + } +} + +impl<'a> TryFrom> for Decimal { + type Error = ParseError; + + fn try_from(value: ValueStr<'a>) -> Result { + Decimal::try_from(&value) + } +} + +impl<'a> TryFrom<&ValueStr<'a>> for Decimal { + type Error = ParseError; + + fn try_from(value: &ValueStr<'a>) -> Result { + value.decimal() + } +} + +impl<'a> fmt::Display for ValueStr<'a> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.as_str()) + } +} + +/// Are all of the given bytes allowed in a [`Value`]? +fn assert_valid_value(input: &str) -> Result<(), ParseError> { + for char in input.chars() { + if !is_char_valid(char) { + return Err(ParseError { + invalid_char: Some(char), + too_long: false, + }); + } + } + + Ok(()) +} + +/// Ensure the given ASCII character (i.e. byte) is allowed in a [`Value`]. +fn is_char_valid(c: char) -> bool { + matches!(c, 'A' ..= 'Z' | 'a'..='z' | '0'..='9' | '/' | '+' | '.' | '-') +} + +#[cfg(test)] +mod tests { + use super::ValueStr; + use core::convert::TryFrom; + + // Invalid value examples + const INVALID_CHAR: &str = "x;y"; + const INVALID_TOO_LONG: &str = "0123456789112345678921234567893123456789412345678"; + const INVALID_CHAR_AND_TOO_LONG: &str = "0!23456789112345678921234567893123456789412345678"; + + // + // Decimal parsing tests + // + + #[test] + fn decimal_value() { + let valid_decimals = &[("0", 0i32), ("1", 1i32), ("2147483647", i32::MAX)]; + + for &(s, i) in valid_decimals { + let value = ValueStr::new(s).unwrap(); + assert!(value.is_decimal()); + assert_eq!(value.decimal().unwrap(), i) + } + } + + #[test] + fn reject_decimal_with_leading_zero() { + let value = ValueStr::new("01").unwrap(); + let err = i32::try_from(value).err().unwrap(); + assert_eq!(err.invalid_char, Some('0')); + } + + #[test] + fn reject_overlong_decimal() { + let value = ValueStr::new("2147483648").unwrap(); + let err = i32::try_from(value).err().unwrap(); + assert!(err.too_long); + } + + #[test] + fn reject_negative() { + let value = ValueStr::new("-1").unwrap(); + let err = i32::try_from(value).err().unwrap(); + assert_eq!(err.invalid_char, Some('-')); + } + + // + // String parsing tests + // + + #[test] + fn string_value() { + let valid_examples = [ + "", + "X", + "x", + "xXx", + "a+b.c-d", + "1/2", + "01234567891123456789212345678931", + ]; + + for &example in &valid_examples { + let value = ValueStr::new(example).unwrap(); + assert_eq!(value.as_str(), example); + } + } + + #[test] + fn reject_invalid_char() { + let err = ValueStr::new(INVALID_CHAR).err().unwrap(); + assert_eq!(err.invalid_char, Some(';')); + assert!(!err.too_long); + } + + #[test] + fn reject_too_long() { + let err = ValueStr::new(INVALID_TOO_LONG).err().unwrap(); + assert_eq!(err.invalid_char, None); + assert!(err.too_long); + } + + #[test] + fn reject_invalid_char_and_too_long() { + let err = ValueStr::new(INVALID_CHAR_AND_TOO_LONG).err().unwrap(); + assert_eq!(err.invalid_char, Some('!')); + assert!(err.too_long); + } +} diff --git a/password-hash/src/salt.rs b/password-hash/src/salt.rs new file mode 100644 index 000000000..9978455a2 --- /dev/null +++ b/password-hash/src/salt.rs @@ -0,0 +1,255 @@ +//! Salt string support implementing the PHC string format specification's +//! RECOMMENDED best practices. + +use crate::{b64, errors::SaltError}; +use core::{ + convert::TryFrom, + fmt, + ops::Deref, + str::{self, FromStr}, +}; + +#[cfg(feature = "rand_core")] +use rand_core::{CryptoRng, RngCore}; + +/// Recommended length of a [`Salt`] according to the [PHC string format][1]. +/// +/// [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#function-duties +#[cfg(feature = "rand_core")] +const RECOMMENDED_LENGTH: usize = 16; + +/// Maximum length of a [`Salt`]. +const MAX_LENGTH: usize = 48; + +/// Salt string. +/// +/// In password hashing, a "salt" is an additional value used to +/// personalize/tweak the output of a password hashing function for a given +/// input password. +/// +/// Salts help defend against attacks based on precomputed tables of hashed +/// passwords, i.e. "[rainbow tables][1]". +/// +/// The [`Salt`] type implements the RECOMMENDED best practices for salts +/// described in the [PHC string format specification][2], namely: +/// +/// > - Maximum lengths for salt, output and parameter values are meant to help +/// > consumer implementations, in particular written in C and using +/// > stack-allocated buffers. These buffers must account for the worst case, +/// > i.e. the maximum defined length. Therefore, keep these lengths low. +/// > - The role of salts is to achieve uniqueness. A random salt is fine for +/// > that as long as its length is sufficient; a 16-byte salt would work well +/// > (by definition, UUID are very good salts, and they encode over exactly +/// > 16 bytes). 16 bytes encode as 22 characters in B64. Functions should +/// > disallow salt values that are too small for security (4 bytes should be +/// > viewed as an absolute minimum). +/// +/// # Recommended length +/// The recommended default length for a salt string is **16-bytes** (128-bits). +/// +/// See below for rationale. +/// +/// # Constraints +/// The above guidelines are interpreted into the following constraints: +/// +/// - Minimum length: **4**-bytes +/// - Maximum length: **48**-bytes +/// +/// A maximum length is enforced based on the above recommendation for +/// supporting stack-allocated buffers (which this library uses), and the +/// specific determination of 48-bytes is taken as a best practice from the +/// [Argon2 Encoding][3] specification in the same document: +/// +/// > The length in bytes of the salt is between 8 and 48 bytes, thus +/// > yielding a length in characters between 11 and 64 characters (and that +/// > length is never equal to 1 modulo 4). The default byte length of the salt +/// > is 16 bytes (22 characters in B64 encoding). An encoded UUID, or a +/// > sequence of 16 bytes produced with a cryptographically strong PRNG, are +/// > appropriate salt values. +/// > +/// > The Argon2 specification states that the salt can be much longer, up +/// > to 2^32-1 bytes, but this makes little sense for password hashing. +/// > Specifying a relatively small maximum length allows for parsing with a +/// > stack allocated buffer.) +/// +/// Based on this guidance, this type enforces an upper bound of 48-bytes +/// as a reasonable maximum, and recommends using 16-bytes. +/// +/// [1]: https://en.wikipedia.org/wiki/Rainbow_table +/// [2]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#function-duties +/// [3]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#argon2-encoding +#[derive(Copy, Clone, Eq, PartialEq)] +pub struct Salt { + /// Byte array containing a salt value. + bytes: [u8; MAX_LENGTH], + + /// Length of the salt in bytes. + length: u8, +} + +impl Salt { + /// Minimum length of a [`Salt`] string: 2-bytes. + /// + /// NOTE: this is below the recommended + pub const fn min_len() -> usize { + 4 + } + + /// Maximum length of a [`Salt`] string: 48-bytes. + /// + /// See type-level documentation about [`Salt`] for more information. + pub const fn max_len() -> usize { + MAX_LENGTH + } + + /// Maximum length of a [`Salt`] when encoded as [`b64`] string: 64-bytes + /// (i.e. 64 ASCII characters) + pub const fn b64_max_len() -> usize { + (MAX_LENGTH * 4) / 3 + } + + /// Generate a random [`Salt`] using the provided [`CryptoRng`]. + /// + /// Uses the [PHC string format's recommended guidelines][1] of a 16-byte + /// salt value: + /// + /// > The role of salts is to achieve uniqueness. A random salt is fine for + /// > that as long as its length is sufficient; a 16-byte salt would work + /// > well (by definition, UUID are very good salts, and they encode over + /// > exactly 16 bytes). + /// + /// [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#function-duties + #[cfg(feature = "rand_core")] + pub fn random(mut rng: impl CryptoRng + RngCore) -> Self { + let mut bytes = [0u8; MAX_LENGTH]; + rng.fill_bytes(&mut bytes[..RECOMMENDED_LENGTH]); + + Self { + bytes, + length: RECOMMENDED_LENGTH as u8, + } + } + + /// Create a [`Salt`] from the given byte slice, validating it according + /// to [`Salt::min_len`] and [`Salt::max_len`] length restrictions. + pub fn new(input: &[u8]) -> Result { + if input.len() < Self::min_len() { + return Err(SaltError::TooShort); + } + + if input.len() > Self::max_len() { + return Err(SaltError::TooLong); + } + + let mut bytes = [0u8; MAX_LENGTH]; + bytes[..input.len()].copy_from_slice(input); + + Ok(Self { + bytes, + length: input.len() as u8, + }) + } + + /// Parse a [`b64`]-encoded salt string, i.e. using the PHC string + /// specification's restricted interpretation of Base64. + pub fn b64_decode(input: &str) -> Result { + if b64::decoded_len(input) > MAX_LENGTH { + return Err(SaltError::TooLong); + } + + let mut bytes = [0u8; MAX_LENGTH]; + b64::decode(input, &mut bytes) + .map_err(Into::into) + .and_then(Self::new) + } + + /// Write [`b64`]-encoded salt string to the provided buffer, returning + /// a sub-slice containing the encoded data. + /// + /// Returns an error if the buffer is too short to contain the output. + pub fn b64_encode<'a>(&self, out: &'a mut [u8]) -> Result<&'a str, SaltError> { + Ok(b64::encode(self.as_ref(), out)?) + } + + /// Get the length of this salt string when encoded as [`b64`]. + pub fn b64_len(&self) -> usize { + b64::encoded_len(self.as_ref()) + } +} + +impl AsRef<[u8]> for Salt { + fn as_ref(&self) -> &[u8] { + &self.bytes[..(self.length as usize)] + } +} + +impl Deref for Salt { + type Target = [u8]; + + fn deref(&self) -> &[u8] { + self.as_ref() + } +} + +impl FromStr for Salt { + type Err = SaltError; + + fn from_str(s: &str) -> Result { + Self::b64_decode(s) + } +} + +impl TryFrom<&[u8]> for Salt { + type Error = SaltError; + + fn try_from(input: &[u8]) -> Result { + Self::new(input) + } +} + +impl fmt::Display for Salt { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut buffer = [0u8; Self::b64_max_len()]; + f.write_str(self.b64_encode(&mut buffer).map_err(|_| fmt::Error)?) + } +} + +impl fmt::Debug for Salt { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Salt(\"{}\")", self) + } +} + +#[cfg(test)] +mod tests { + use super::{Salt, SaltError}; + + #[test] + fn new_with_valid_min_length_input() { + let bytes = [4u8; 4]; + let salt = Salt::new(&bytes).unwrap(); + assert_eq!(salt.as_ref(), &bytes); + } + + #[test] + fn new_with_valid_max_length_input() { + let bytes = [48u8; 48]; + let salt = Salt::new(&bytes).unwrap(); + assert_eq!(salt.as_ref(), &bytes); + } + + #[test] + fn reject_new_too_short() { + for &too_short in &[&b""[..], &b"\x01"[..], &b"\x02\x02"[..], &b"\x03\x03"[..]] { + let err = Salt::new(too_short).err().unwrap(); + assert_eq!(err, SaltError::TooShort); + } + } + + #[test] + fn reject_new_too_long() { + let bytes = [49u8; 49]; + let err = Salt::new(&bytes).err().unwrap(); + assert_eq!(err, SaltError::TooLong); + } +} diff --git a/password-hash/tests/b64.rs b/password-hash/tests/b64.rs new file mode 100644 index 000000000..04b86aad9 --- /dev/null +++ b/password-hash/tests/b64.rs @@ -0,0 +1,51 @@ +//! "B64" encoding tests. +//! +//! Subset of the standard Base64 encoding (RFC 4648, section 4) which omits +//! padding (`=`) as well as extra whitespace, as described in the PHC string +//! format specification: +//! +//! + +use password_hash::{Output, Salt}; + +#[cfg(feature = "alloc")] +use password_hash::b64; + +// Example salt encoded as a B64 string. +const EXAMPLE_SALT_B64: &str = "REVBREJFRUZERUFEQkVFRg"; +const EXAMPLE_SALT_RAW: &[u8] = b"DEADBEEFDEADBEEF"; + +// Example PHF output encoded as a B64 string. +const EXAMPLE_OUTPUT_B64: &str = + "REVBREJFRUZERUFEQkVFRkRFQURCRUVGREVBREJFRUZERUFEQkVFRkRFQURCRUVGREVBREJFRUZERUFEQkVFRg"; +const EXAMPLE_OUTPUT_RAW: &[u8] = + b"DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF"; + +#[test] +fn salt_roundtrip() { + let salt = EXAMPLE_SALT_B64.parse::().unwrap(); + assert_eq!(salt.as_ref(), EXAMPLE_SALT_RAW); + assert_eq!(salt.to_string(), EXAMPLE_SALT_B64); +} + +#[test] +fn output_roundtrip() { + let out = EXAMPLE_OUTPUT_B64.parse::().unwrap(); + assert_eq!(out.as_ref(), EXAMPLE_OUTPUT_RAW); + assert_eq!(out.to_string(), EXAMPLE_OUTPUT_B64); +} + +#[cfg(feature = "alloc")] +#[test] +fn encode_string() { + assert_eq!(b64::encode_string(EXAMPLE_OUTPUT_RAW), EXAMPLE_OUTPUT_B64); +} + +#[cfg(feature = "alloc")] +#[test] +fn decode_vec() { + assert_eq!( + b64::decode_vec(EXAMPLE_OUTPUT_B64).unwrap(), + EXAMPLE_OUTPUT_RAW + ); +} diff --git a/password-hash/tests/encoding.rs b/password-hash/tests/encoding.rs new file mode 100644 index 000000000..8467f2221 --- /dev/null +++ b/password-hash/tests/encoding.rs @@ -0,0 +1,144 @@ +//! Tests for `PasswordHash` encoding/decoding. +//! +//! Each test implements a different permutation of the possible combinations +//! of the string encoding, and ensures password hashes round trip under each +//! of the conditions. + +#![cfg(feature = "registry")] + +use core::convert::TryInto; +use password_hash::{algorithm::argon2, Algorithm, Params, PasswordHash}; + +const EXAMPLE_ALGORITHM: Algorithm = Algorithm::Argon2(argon2::Variant::D); +const EXAMPLE_SALT: &[u8] = &[ + 0xb1, 0xa9, 0x6d, 0xb1, 0xa9, 0x6d, 0xb1, 0xa9, 0x6d, 0xb1, 0xa9, 0x6d, 0xb1, 0xa9, 0x6d, 0xb0, +]; +const EXAMPLE_HASH: &[u8] = &[ + 0x85, 0xab, 0x21, 0x85, 0xab, 0x21, 0x85, 0xab, 0x21, 0x85, 0xab, 0x21, 0x85, 0xab, 0x21, 0x85, + 0xab, 0x21, 0x85, 0xab, 0x21, 0x85, 0xab, 0x21, 0x85, 0xab, 0x21, 0x85, 0xab, 0x21, 0x85, 0xab, +]; + +/// Example parameters +fn example_params() -> Params { + Params::from_slice(&[ + ("a".parse().unwrap(), 1i32.into()), + ("b".parse().unwrap(), 2i32.into()), + ("c".parse().unwrap(), 3i32.into()), + ]) + .unwrap() +} + +#[test] +fn algorithm_alone() { + let ph = PasswordHash::from(EXAMPLE_ALGORITHM); + + let s = ph.to_string(); + assert_eq!(s, "$argon2d"); + + let ph2 = s.parse::().unwrap(); + assert_eq!(ph, ph2); +} + +#[test] +fn params() { + let ph = PasswordHash { + algorithm: EXAMPLE_ALGORITHM, + params: example_params(), + salt: None, + hash: None, + }; + + let s = ph.to_string(); + assert_eq!(s, "$argon2d$a=1,b=2,c=3"); + + let ph2 = s.parse::().unwrap(); + assert_eq!(ph, ph2); +} + +#[test] +fn salt() { + let ph = PasswordHash { + algorithm: EXAMPLE_ALGORITHM, + params: Params::new(), + salt: Some(EXAMPLE_SALT.try_into().unwrap()), + hash: None, + }; + + let s = ph.to_string(); + assert_eq!(s, "$argon2d$saltsaltsaltsaltsaltsA"); + + let ph2 = s.parse::().unwrap(); + assert_eq!(ph, ph2); +} + +#[test] +fn one_param_and_salt() { + let params = Params::from_slice(&[("a".parse().unwrap(), 1i32.into())]).unwrap(); + + let ph = PasswordHash { + algorithm: EXAMPLE_ALGORITHM, + params, + salt: Some(EXAMPLE_SALT.try_into().unwrap()), + hash: None, + }; + + let s = ph.to_string(); + assert_eq!(s, "$argon2d$a=1$saltsaltsaltsaltsaltsA"); + + let ph2 = s.parse::().unwrap(); + assert_eq!(ph, ph2); +} + +#[test] +fn params_and_salt() { + let ph = PasswordHash { + algorithm: EXAMPLE_ALGORITHM, + params: example_params(), + salt: Some(EXAMPLE_SALT.try_into().unwrap()), + hash: None, + }; + + let s = ph.to_string(); + assert_eq!(s, "$argon2d$a=1,b=2,c=3$saltsaltsaltsaltsaltsA"); + + let ph2 = s.parse::().unwrap(); + assert_eq!(ph, ph2); +} + +#[test] +fn salt_and_hash() { + let ph = PasswordHash { + algorithm: EXAMPLE_ALGORITHM, + params: Params::default(), + salt: Some(EXAMPLE_SALT.try_into().unwrap()), + hash: Some(EXAMPLE_HASH.try_into().unwrap()), + }; + + let s = ph.to_string(); + assert_eq!( + s, + "$argon2d$saltsaltsaltsaltsaltsA$hashhashhashhashhashhashhashhashhashhashhas" + ); + + let ph2 = s.parse::().unwrap(); + assert_eq!(ph, ph2); +} + +#[test] +fn all_fields() { + let ph = PasswordHash { + algorithm: EXAMPLE_ALGORITHM, + params: example_params(), + salt: Some(EXAMPLE_SALT.try_into().unwrap()), + hash: Some(EXAMPLE_HASH.try_into().unwrap()), + }; + + let s = ph.to_string(); + assert_eq!( + s, + "$argon2d$a=1,b=2,c=3$saltsaltsaltsaltsaltsA$hashhashhashhashhashhashhashhashhashhashhas" + ); + + let ph2 = s.parse::().unwrap(); + assert_eq!(ph, ph2); +} diff --git a/password-hash/tests/hashing.rs b/password-hash/tests/hashing.rs new file mode 100644 index 000000000..ab855576b --- /dev/null +++ b/password-hash/tests/hashing.rs @@ -0,0 +1,64 @@ +/// Password hashing tests +pub use password_hash::{ + Ident, Output, Params, PasswordHash, PasswordHasher, PhfError, Salt, VerifyError, +}; + +const ALG: Ident = Ident::new("example"); + +/// Stub password hashing function for testing. +pub struct StubFunction; + +impl PasswordHasher for StubFunction { + fn hash_password<'a>( + &self, + algorithm: Option>, + password: &[u8], + salt: Salt, + params: Params<'a>, + ) -> Result, PhfError> { + let mut output = Vec::new(); + + if let Some(alg) = algorithm { + if alg != ALG { + return Err(PhfError::Algorithm); + } + } + + for slice in &[b"pw", password, b",salt:", salt.as_ref()] { + output.extend_from_slice(slice); + } + + let hash = Output::new(&output)?; + + Ok(PasswordHash { + algorithm: ALG, + params, + salt: Some(salt), + hash: Some(hash), + }) + } +} + +#[test] +fn verify_password_hash() { + let valid_password = "test password"; + let salt = Salt::new(b"test salt").unwrap(); + let params = Params::new(); + let hash = PasswordHash::generate(StubFunction, valid_password, salt, params.clone()).unwrap(); + + // Sanity tests for StubFunction impl above + assert_eq!(hash.algorithm, ALG); + assert_eq!(hash.salt.unwrap(), salt); + assert_eq!(hash.params, params); + + // Tests for generic password verification logic + assert_eq!( + hash.verify_password(&[&StubFunction], valid_password), + Ok(()) + ); + + assert_eq!( + hash.verify_password(&[&StubFunction], "wrong password"), + Err(VerifyError) + ); +} diff --git a/password-hash/tests/test_vectors.rs b/password-hash/tests/test_vectors.rs new file mode 100644 index 000000000..c460a3b05 --- /dev/null +++ b/password-hash/tests/test_vectors.rs @@ -0,0 +1,56 @@ +//! Test vectors for commonly used password hashing algorithms. + +#![cfg(feature = "registry")] + +use password_hash::{ + algorithm::{argon2, bcrypt}, + Algorithm, PasswordHash, +}; + +const ARGON2ID_HASH: &str = + "$argon2id$m=65536,t=3,p=2$c29tZXNhbHQ$RdescudvJCsgt3ub+b+dWRWJTmaaJObG"; +const BCRYPT_HASH: &str = "$2b$MTIzNA$i5btSOiulHhaPHPbgNUGdObga/GCAVG/y5HHY1ra7L0C9dpCaw8u"; +const SCRYPT_HASH: &str = + "$scrypt$epIxT/h6HbbwHaehFnh/bw$7H0vsXlY8UxxyW/BWx/9GuY7jEvGjT71GFd6O4SZND0"; + +#[test] +fn argon2id() { + let ph = ARGON2ID_HASH.parse::().unwrap(); + assert_eq!(ph.algorithm, Algorithm::Argon2(argon2::Variant::ID)); + assert_eq!(ph.params.len(), 3); + assert_eq!(ph.params["m"], 65536.into()); + assert_eq!(ph.params["t"], 3.into()); + assert_eq!(ph.params["p"], 2.into()); + assert_eq!(ph.salt.unwrap().to_string(), "c29tZXNhbHQ"); + assert_eq!( + ph.hash.unwrap().to_string(), + "RdescudvJCsgt3ub+b+dWRWJTmaaJObG" + ); + assert_eq!(ph.to_string(), ARGON2ID_HASH); +} + +#[test] +fn bcrypt() { + let ph = BCRYPT_HASH.parse::().unwrap(); + assert_eq!(ph.algorithm, Algorithm::Bcrypt(bcrypt::Variant::B)); + assert_eq!(ph.params.len(), 0); + assert_eq!(ph.salt.unwrap().to_string(), "MTIzNA"); + assert_eq!( + ph.hash.unwrap().to_string(), + "i5btSOiulHhaPHPbgNUGdObga/GCAVG/y5HHY1ra7L0C9dpCaw8u" + ); + assert_eq!(ph.to_string(), BCRYPT_HASH); +} + +#[test] +fn scrypt() { + let ph = SCRYPT_HASH.parse::().unwrap(); + assert_eq!(ph.algorithm, Algorithm::Scrypt); + assert_eq!(ph.params.len(), 0); + assert_eq!(ph.salt.unwrap().to_string(), "epIxT/h6HbbwHaehFnh/bw"); + assert_eq!( + ph.hash.unwrap().to_string(), + "7H0vsXlY8UxxyW/BWx/9GuY7jEvGjT71GFd6O4SZND0" + ); + assert_eq!(ph.to_string(), SCRYPT_HASH); +} From 20f6d24d0ff87f167cbfccd794388b4f6276dd66 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 5 Jan 2021 06:49:53 -0800 Subject: [PATCH 0353/1461] aead: add `alloc`-based APIs to `stream` module (#447) Adds a corresponding set of allocating APIs to `StreamPrimitive`, `Decryptor`, and `Encryptor`. --- aead/src/stream.rs | 96 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 90 insertions(+), 6 deletions(-) diff --git a/aead/src/stream.rs b/aead/src/stream.rs index 3e220b6fb..554284b35 100644 --- a/aead/src/stream.rs +++ b/aead/src/stream.rs @@ -24,6 +24,9 @@ use generic_array::{ ArrayLength, GenericArray, }; +#[cfg(feature = "alloc")] +use {crate::Payload, alloc::vec::Vec}; + /// Nonce as used by a given AEAD construction and STREAM primitive. pub type Nonce = GenericArray>; @@ -110,6 +113,39 @@ where buffer: &mut dyn Buffer, ) -> Result<(), Error>; + /// Encrypt the given plaintext payload, and return the resulting + /// ciphertext as a vector of bytes. + #[cfg(feature = "alloc")] + #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] + fn encrypt<'msg, 'aad>( + &self, + position: Self::Counter, + last_block: bool, + plaintext: impl Into>, + ) -> Result, Error> { + let payload = plaintext.into(); + let mut buffer = Vec::with_capacity(payload.msg.len() + A::TagSize::to_usize()); + buffer.extend_from_slice(payload.msg); + self.encrypt_in_place(position, last_block, payload.aad, &mut buffer)?; + Ok(buffer) + } + + /// Decrypt the given ciphertext slice, and return the resulting plaintext + /// as a vector of bytes. + #[cfg(feature = "alloc")] + #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] + fn decrypt<'msg, 'aad>( + &self, + position: Self::Counter, + last_block: bool, + ciphertext: impl Into>, + ) -> Result, Error> { + let payload = ciphertext.into(); + let mut buffer = Vec::from(payload.msg); + self.decrypt_in_place(position, last_block, payload.aad, &mut buffer)?; + Ok(buffer) + } + /// Obtain [`Encryptor`] for this [`StreamPrimitive`]. fn encryptor(self) -> Encryptor where @@ -132,8 +168,11 @@ macro_rules! impl_stream_object { ( $name:ident, $next_method:tt, + $next_in_place_method:tt, $last_method:tt, - $op_method:tt, + $last_in_place_method:tt, + $op:tt, + $in_place_op:tt, $op_desc:expr, $obj_desc:expr ) => { @@ -200,10 +239,34 @@ macro_rules! impl_stream_object { } } + #[doc = "Use the underlying AEAD to"] + #[doc = $op_desc] + #[doc = "the next AEAD message in this STREAM, returning the"] + #[doc = "result as a [`Vec`]."] + #[cfg(feature = "alloc")] + #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] + pub fn $next_method<'msg, 'aad>( + &mut self, + payload: impl Into>, + ) -> Result, Error> { + if self.position == S::COUNTER_MAX { + // Counter overflow. Note that the maximum counter value is + // deliberately disallowed, as it would preclude being able + // to encrypt a last block (i.e. with `$last_in_place_method`) + return Err(Error); + } + + let result = self.stream.$op(self.position, false, payload)?; + + // Note: overflow checked above + self.position += S::COUNTER_INCR; + Ok(result) + } + #[doc = "Use the underlying AEAD to"] #[doc = $op_desc] #[doc = "the next AEAD message in this STREAM in-place."] - pub fn $next_method( + pub fn $next_in_place_method( &mut self, associated_data: &[u8], buffer: &mut dyn Buffer, @@ -211,29 +274,44 @@ macro_rules! impl_stream_object { if self.position == S::COUNTER_MAX { // Counter overflow. Note that the maximum counter value is // deliberately disallowed, as it would preclude being able - // to encrypt a last block (i.e. with `$last_method`) + // to encrypt a last block (i.e. with `$last_in_place_method`) return Err(Error); } - self.stream.$op_method(self.position, false, associated_data, buffer)?; + self.stream.$in_place_op(self.position, false, associated_data, buffer)?; // Note: overflow checked above self.position += S::COUNTER_INCR; Ok(()) } + #[doc = "Use the underlying AEAD to"] + #[doc = $op_desc] + #[doc = "the last AEAD message in this STREAM,"] + #[doc = "consuming the "] + #[doc = $obj_desc] + #[doc = "object in order to prevent further use."] + #[cfg(feature = "alloc")] + #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] + pub fn $last_method<'msg, 'aad>( + self, + payload: impl Into>, + ) -> Result, Error> { + self.stream.$op(self.position, true, payload) + } + #[doc = "Use the underlying AEAD to"] #[doc = $op_desc] #[doc = "the last AEAD message in this STREAM in-place,"] #[doc = "consuming the "] #[doc = $obj_desc] #[doc = "object in order to prevent further use."] - pub fn $last_method( + pub fn $last_in_place_method( self, associated_data: &[u8], buffer: &mut dyn Buffer ) -> Result<(), Error> { - self.stream.$op_method(self.position, true, associated_data, buffer) + self.stream.$in_place_op(self.position, true, associated_data, buffer) } } } @@ -241,8 +319,11 @@ macro_rules! impl_stream_object { impl_stream_object!( Encryptor, + encrypt_next, encrypt_next_in_place, + encrypt_last, encrypt_last_in_place, + encrypt, encrypt_in_place, "encrypt", "ℰ STREAM encryptor" @@ -250,8 +331,11 @@ impl_stream_object!( impl_stream_object!( Decryptor, + decrypt_next, decrypt_next_in_place, + decrypt_last, decrypt_last_in_place, + decrypt, decrypt_in_place, "decrypt", "𝒟 STREAM decryptor" From 79668938724515a84a85eef14c59df87c3bddd89 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 5 Jan 2021 07:28:25 -0800 Subject: [PATCH 0354/1461] password-hash: rustdoc fixups (#449) Fixes some dangling rustdoc links left over from refactoring. --- password-hash/src/errors.rs | 2 +- password-hash/src/ident.rs | 4 ++-- password-hash/src/lib.rs | 9 +++++---- password-hash/src/params/value.rs | 2 +- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/password-hash/src/errors.rs b/password-hash/src/errors.rs index 0610b2ba5..e917f3b97 100644 --- a/password-hash/src/errors.rs +++ b/password-hash/src/errors.rs @@ -175,7 +175,7 @@ impl fmt::Display for ParseError { #[cfg(feature = "std")] impl std::error::Error for ParseError {} -/// Errors generating password hashes using a [`PasswordHashingFunction`]. +/// Errors generating password hashes using a [`PasswordHasher`]. #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum PhfError { /// Unsupported algorithm. diff --git a/password-hash/src/ident.rs b/password-hash/src/ident.rs index 67af14525..93aa89b20 100644 --- a/password-hash/src/ident.rs +++ b/password-hash/src/ident.rs @@ -56,8 +56,8 @@ impl<'a> Ident<'a> { /// This method is intended for use in a `const` context where instead of /// panicking it will cause a compile error. /// - /// For fallible non-panicking parsing of an [`Ident`], use the [`FromStr`] - /// impl on this type instead, e.g. `s.parse::()`. + /// For fallible non-panicking parsing of an [`Ident`], use the [`TryFrom`] + /// impl on this type instead. pub const fn new(s: &'a str) -> Self { let input = s.as_bytes(); diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index e36d3fdf2..763d9248b 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -64,8 +64,9 @@ const PASSWORD_HASH_SEPARATOR: char = '$'; /// Trait for password hashing functions. pub trait PasswordHasher { - /// Compute a [`PasswordHash`] from the given [`Algorithm`] (or the - /// recommended default), password, salt, and optional [`Params`]. + /// Compute a [`PasswordHash`] with the given algorithm [`Ident`] + /// (or `None` for the recommended default), password, salt, and optional + /// [`Params`]. /// /// Use [`Params::new`] or [`Params::default`] to use the default /// parameters for a given algorithm. @@ -129,7 +130,7 @@ pub trait PasswordHasher { /// [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#specification #[derive(Clone, Debug, Eq, PartialEq)] pub struct PasswordHash<'a> { - /// Password hashing [`Algorithm`]. + /// Password hashing algorithm identifier. /// /// This corresponds to the `` field in a PHC string, a.k.a. the /// symbolic name for the function. @@ -220,7 +221,7 @@ impl<'a> PasswordHash<'a> { } /// Verify this password hash using the specified set of supported - /// [`PasswordHashingFunction`] objects. + /// [`PasswordHasher`] trait objects. pub fn verify_password( &self, phfs: &[&dyn PasswordHasher], diff --git a/password-hash/src/params/value.rs b/password-hash/src/params/value.rs index cea9da2ef..967174868 100644 --- a/password-hash/src/params/value.rs +++ b/password-hash/src/params/value.rs @@ -130,7 +130,7 @@ impl<'a> fmt::Debug for Value<'a> { /// # Additional Notes /// The PHC spec allows for algorithm-defined maximum lengths for parameter /// values, however in the interest of interoperability this library defines a -/// [`Value::max_len`] of 48 ASCII characters. +/// [`ValueStr::max_len`] of 48 ASCII characters. /// /// [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md /// [2]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#argon2-encoding From 65af769b309a215f43b1a0335bb65a49d3667554 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 5 Jan 2021 14:34:25 -0800 Subject: [PATCH 0355/1461] password-hash: remove B64 restrictions on Salt (#451) Changes the `Salt` type to be a simple newtype of `ValueStr`. Since the `Salt` value is now borrowed, this unfortunately removes the ability to generate a random salt into a buffer, so this PR also removes the `rand_core` dependency. We can potentially revisit adding a type like `SaltBuf` to use for an owned salt value. --- .github/workflows/password-hash.yml | 2 - Cargo.lock | 3 - password-hash/Cargo.toml | 4 - password-hash/src/errors.rs | 12 +- password-hash/src/lib.rs | 15 ++- password-hash/src/salt.rs | 177 ++++++++++------------------ password-hash/tests/b64.rs | 9 +- password-hash/tests/hashing.rs | 6 +- 8 files changed, 84 insertions(+), 144 deletions(-) diff --git a/.github/workflows/password-hash.yml b/.github/workflows/password-hash.yml index 3ac77672e..52b090ba2 100644 --- a/.github/workflows/password-hash.yml +++ b/.github/workflows/password-hash.yml @@ -37,8 +37,6 @@ jobs: profile: minimal - run: cargo build --target ${{ matrix.target }} --release --no-default-features - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc - - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features rand_core - - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,rand_core test: runs-on: ubuntu-latest diff --git a/Cargo.lock b/Cargo.lock index dc25cecfb..30bc2695d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -273,9 +273,6 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "password-hash" version = "0.0.0" -dependencies = [ - "rand_core", -] [[package]] name = "pkcs8" diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index 9986c0390..046912f69 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -15,10 +15,6 @@ repository = "https://github.com/RustCrypto/traits/tree/master/password-hash" categories = ["cryptography", "no-std"] keywords = ["crypt", "mcf", "password", "pbkdf", "phc"] -[dependencies] -rand_core = { version = "0.5", optional = true } - [features] -default = ["rand_core"] alloc = [] std = ["alloc"] diff --git a/password-hash/src/errors.rs b/password-hash/src/errors.rs index e917f3b97..38d456451 100644 --- a/password-hash/src/errors.rs +++ b/password-hash/src/errors.rs @@ -250,8 +250,8 @@ impl std::error::Error for OutputError {} /// Salt-related errors. #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum SaltError { - /// "B64" encoding error. - B64(B64Error), + /// Parse errors. + Parse(ParseError), /// Salt too short (min 4-bytes). TooShort, @@ -263,16 +263,16 @@ pub enum SaltError { impl fmt::Display for SaltError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { match self { - Self::B64(err) => write!(f, "{}", err), + Self::Parse(err) => write!(f, "{}", err), Self::TooShort => f.write_str("salt too short (min 4-bytes)"), Self::TooLong => f.write_str("salt too long (max 48-bytes)"), } } } -impl From for SaltError { - fn from(err: B64Error) -> SaltError { - SaltError::B64(err) +impl From for SaltError { + fn from(err: ParseError) -> SaltError { + SaltError::Parse(err) } } diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index 763d9248b..f4f6eddc4 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -57,7 +57,10 @@ pub use crate::{ salt::Salt, }; -use core::{convert::TryFrom, fmt}; +use core::{ + convert::{TryFrom, TryInto}, + fmt, +}; /// Separator character used in password hashes (e.g. `$6$...`). const PASSWORD_HASH_SEPARATOR: char = '$'; @@ -74,7 +77,7 @@ pub trait PasswordHasher { &self, algorithm: Option>, password: &[u8], - salt: Salt, + salt: Salt<'a>, params: Params<'a>, ) -> Result, PhfError>; @@ -145,7 +148,7 @@ pub struct PasswordHash<'a> { /// [`Salt`] string for personalizing a password hash output. /// /// This corresponds to the `` value in a PHC string. - pub salt: Option, + pub salt: Option>, /// Password hashing function [`Output`], a.k.a. hash/digest. /// @@ -187,10 +190,10 @@ impl<'a> PasswordHash<'a> { params = Params::try_from(field)?; if let Some(s) = fields.next() { - salt = Some(s.parse()?); + salt = Some(s.try_into()?); } } else { - salt = Some(field.parse()?); + salt = Some(field.try_into()?); } } @@ -214,7 +217,7 @@ impl<'a> PasswordHash<'a> { pub fn generate( phf: impl PasswordHasher, password: impl AsRef<[u8]>, - salt: Salt, + salt: Salt<'a>, params: Params<'a>, ) -> Result { phf.hash_password(None, password.as_ref(), salt, params) diff --git a/password-hash/src/salt.rs b/password-hash/src/salt.rs index 9978455a2..84655f64a 100644 --- a/password-hash/src/salt.rs +++ b/password-hash/src/salt.rs @@ -1,26 +1,14 @@ -//! Salt string support implementing the PHC string format specification's -//! RECOMMENDED best practices. +//! Salt string support. -use crate::{b64, errors::SaltError}; +use crate::{ + errors::{B64Error, SaltError}, + params::ValueStr, +}; use core::{ - convert::TryFrom, - fmt, - ops::Deref, - str::{self, FromStr}, + convert::{TryFrom, TryInto}, + fmt, str, }; -#[cfg(feature = "rand_core")] -use rand_core::{CryptoRng, RngCore}; - -/// Recommended length of a [`Salt`] according to the [PHC string format][1]. -/// -/// [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#function-duties -#[cfg(feature = "rand_core")] -const RECOMMENDED_LENGTH: usize = 16; - -/// Maximum length of a [`Salt`]. -const MAX_LENGTH: usize = 48; - /// Salt string. /// /// In password hashing, a "salt" is an additional value used to @@ -50,7 +38,14 @@ const MAX_LENGTH: usize = 48; /// See below for rationale. /// /// # Constraints -/// The above guidelines are interpreted into the following constraints: +/// Salt strings are constrained to the following set of characters per the +/// PHC spec: +/// +/// > The salt consists in a sequence of characters in: `[a-zA-Z0-9/+.-]` +/// > (lowercase letters, uppercase letters, digits, /, +, . and -). +/// +/// Additionally the following length restrictions are enforced based on the +/// guidelines from the spec: /// /// - Minimum length: **4**-bytes /// - Maximum length: **48**-bytes @@ -79,18 +74,13 @@ const MAX_LENGTH: usize = 48; /// [2]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#function-duties /// [3]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#argon2-encoding #[derive(Copy, Clone, Eq, PartialEq)] -pub struct Salt { - /// Byte array containing a salt value. - bytes: [u8; MAX_LENGTH], +pub struct Salt<'a>(ValueStr<'a>); - /// Length of the salt in bytes. - length: u8, -} - -impl Salt { +impl<'a> Salt<'a> { /// Minimum length of a [`Salt`] string: 2-bytes. /// /// NOTE: this is below the recommended + // TODO(tarcieri): support shorter salts for MCF? pub const fn min_len() -> usize { 4 } @@ -99,40 +89,18 @@ impl Salt { /// /// See type-level documentation about [`Salt`] for more information. pub const fn max_len() -> usize { - MAX_LENGTH + ValueStr::max_len() } - /// Maximum length of a [`Salt`] when encoded as [`b64`] string: 64-bytes - /// (i.e. 64 ASCII characters) - pub const fn b64_max_len() -> usize { - (MAX_LENGTH * 4) / 3 + /// Recommended length of a salt: 16-bytes. + pub const fn recommended_len() -> usize { + 16 } - /// Generate a random [`Salt`] using the provided [`CryptoRng`]. - /// - /// Uses the [PHC string format's recommended guidelines][1] of a 16-byte - /// salt value: - /// - /// > The role of salts is to achieve uniqueness. A random salt is fine for - /// > that as long as its length is sufficient; a 16-byte salt would work - /// > well (by definition, UUID are very good salts, and they encode over - /// > exactly 16 bytes). - /// - /// [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#function-duties - #[cfg(feature = "rand_core")] - pub fn random(mut rng: impl CryptoRng + RngCore) -> Self { - let mut bytes = [0u8; MAX_LENGTH]; - rng.fill_bytes(&mut bytes[..RECOMMENDED_LENGTH]); - - Self { - bytes, - length: RECOMMENDED_LENGTH as u8, - } - } - - /// Create a [`Salt`] from the given byte slice, validating it according - /// to [`Salt::min_len`] and [`Salt::max_len`] length restrictions. - pub fn new(input: &[u8]) -> Result { + /// Create a [`Salt`] from the given `str`, validating it according to + /// [`Salt::min_len`] and [`Salt::max_len`] length restrictions. + pub fn new(input: &'a str) -> Result { + // TODO(tarcieri): support shorter salts for MCF? if input.len() < Self::min_len() { return Err(SaltError::TooShort); } @@ -141,82 +109,57 @@ impl Salt { return Err(SaltError::TooLong); } - let mut bytes = [0u8; MAX_LENGTH]; - bytes[..input.len()].copy_from_slice(input); - - Ok(Self { - bytes, - length: input.len() as u8, - }) - } - - /// Parse a [`b64`]-encoded salt string, i.e. using the PHC string - /// specification's restricted interpretation of Base64. - pub fn b64_decode(input: &str) -> Result { - if b64::decoded_len(input) > MAX_LENGTH { - return Err(SaltError::TooLong); - } - - let mut bytes = [0u8; MAX_LENGTH]; - b64::decode(input, &mut bytes) - .map_err(Into::into) - .and_then(Self::new) + Ok(Self(input.try_into()?)) } - /// Write [`b64`]-encoded salt string to the provided buffer, returning - /// a sub-slice containing the encoded data. + /// Attempt to decode a [`b64`][`crate::b64`]-encoded [`Salt`], writing the + /// decoded result into the provided buffer, and returning a slice of the + /// buffer containing the decoded result on success. /// - /// Returns an error if the buffer is too short to contain the output. - pub fn b64_encode<'a>(&self, out: &'a mut [u8]) -> Result<&'a str, SaltError> { - Ok(b64::encode(self.as_ref(), out)?) + /// [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#argon2-encoding + pub fn b64_decode<'b>(&self, buf: &'b mut [u8]) -> Result<&'b [u8], B64Error> { + self.0.b64_decode(buf) } - /// Get the length of this salt string when encoded as [`b64`]. - pub fn b64_len(&self) -> usize { - b64::encoded_len(self.as_ref()) + /// Borrow this value as a `str`. + pub fn as_str(&self) -> &'a str { + self.0.as_str() } -} -impl AsRef<[u8]> for Salt { - fn as_ref(&self) -> &[u8] { - &self.bytes[..(self.length as usize)] + /// Borrow this value as bytes. + pub fn as_bytes(&self) -> &'a [u8] { + self.as_str().as_bytes() } -} - -impl Deref for Salt { - type Target = [u8]; - fn deref(&self) -> &[u8] { - self.as_ref() + /// Get the length of this value in ASCII characters. + pub fn len(&self) -> usize { + self.as_str().len() } } -impl FromStr for Salt { - type Err = SaltError; - - fn from_str(s: &str) -> Result { - Self::b64_decode(s) +impl<'a> AsRef for Salt<'a> { + fn as_ref(&self) -> &str { + self.as_str() } } -impl TryFrom<&[u8]> for Salt { +impl<'a> TryFrom<&'a str> for Salt<'a> { type Error = SaltError; - fn try_from(input: &[u8]) -> Result { + fn try_from(input: &'a str) -> Result { Self::new(input) } } -impl fmt::Display for Salt { +impl<'a> fmt::Display for Salt<'a> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut buffer = [0u8; Self::b64_max_len()]; - f.write_str(self.b64_encode(&mut buffer).map_err(|_| fmt::Error)?) + f.write_str(self.as_str()) } } -impl fmt::Debug for Salt { +impl<'a> fmt::Debug for Salt<'a> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "Salt(\"{}\")", self) + write!(f, "Salt({:?})", self.as_ref()) } } @@ -226,21 +169,21 @@ mod tests { #[test] fn new_with_valid_min_length_input() { - let bytes = [4u8; 4]; - let salt = Salt::new(&bytes).unwrap(); - assert_eq!(salt.as_ref(), &bytes); + let s = "abcd"; + let salt = Salt::new(s).unwrap(); + assert_eq!(salt.as_ref(), s); } #[test] fn new_with_valid_max_length_input() { - let bytes = [48u8; 48]; - let salt = Salt::new(&bytes).unwrap(); - assert_eq!(salt.as_ref(), &bytes); + let s = "012345678911234567892123456789312345678941234567"; + let salt = Salt::new(s).unwrap(); + assert_eq!(salt.as_ref(), s); } #[test] fn reject_new_too_short() { - for &too_short in &[&b""[..], &b"\x01"[..], &b"\x02\x02"[..], &b"\x03\x03"[..]] { + for &too_short in &["", "a", "ab", "abc"] { let err = Salt::new(too_short).err().unwrap(); assert_eq!(err, SaltError::TooShort); } @@ -248,8 +191,8 @@ mod tests { #[test] fn reject_new_too_long() { - let bytes = [49u8; 49]; - let err = Salt::new(&bytes).err().unwrap(); + let s = "0123456789112345678921234567893123456789412345678"; + let err = Salt::new(s).err().unwrap(); assert_eq!(err, SaltError::TooLong); } } diff --git a/password-hash/tests/b64.rs b/password-hash/tests/b64.rs index 04b86aad9..a93f2dbfd 100644 --- a/password-hash/tests/b64.rs +++ b/password-hash/tests/b64.rs @@ -23,9 +23,12 @@ const EXAMPLE_OUTPUT_RAW: &[u8] = #[test] fn salt_roundtrip() { - let salt = EXAMPLE_SALT_B64.parse::().unwrap(); - assert_eq!(salt.as_ref(), EXAMPLE_SALT_RAW); - assert_eq!(salt.to_string(), EXAMPLE_SALT_B64); + let mut buffer = [0u8; 64]; + let salt = Salt::new(EXAMPLE_SALT_B64).unwrap(); + assert_eq!(salt.as_ref(), EXAMPLE_SALT_B64); + + let salt_decoded = salt.b64_decode(&mut buffer).unwrap(); + assert_eq!(salt_decoded, EXAMPLE_SALT_RAW); } #[test] diff --git a/password-hash/tests/hashing.rs b/password-hash/tests/hashing.rs index ab855576b..4b812e958 100644 --- a/password-hash/tests/hashing.rs +++ b/password-hash/tests/hashing.rs @@ -13,7 +13,7 @@ impl PasswordHasher for StubFunction { &self, algorithm: Option>, password: &[u8], - salt: Salt, + salt: Salt<'a>, params: Params<'a>, ) -> Result, PhfError> { let mut output = Vec::new(); @@ -24,7 +24,7 @@ impl PasswordHasher for StubFunction { } } - for slice in &[b"pw", password, b",salt:", salt.as_ref()] { + for slice in &[b"pw", password, b",salt:", salt.as_bytes()] { output.extend_from_slice(slice); } @@ -42,7 +42,7 @@ impl PasswordHasher for StubFunction { #[test] fn verify_password_hash() { let valid_password = "test password"; - let salt = Salt::new(b"test salt").unwrap(); + let salt = Salt::new("test-salt").unwrap(); let params = Params::new(); let hash = PasswordHash::generate(StubFunction, valid_password, salt, params.clone()).unwrap(); From c541031fd892a1d115b43a0609f0b2f4dd53737b Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 5 Jan 2021 19:23:06 -0800 Subject: [PATCH 0356/1461] password-hash: simplify error types (#453) Consolidates ParseError and SaltError into a single enum --- password-hash/src/errors.rs | 97 +++++-------------------------- password-hash/src/ident.rs | 23 +++----- password-hash/src/lib.rs | 12 ++-- password-hash/src/params.rs | 16 +++-- password-hash/src/params/value.rs | 60 +++++++------------ password-hash/src/salt.rs | 18 +++--- 6 files changed, 65 insertions(+), 161 deletions(-) diff --git a/password-hash/src/errors.rs b/password-hash/src/errors.rs index 38d456451..8552fd57c 100644 --- a/password-hash/src/errors.rs +++ b/password-hash/src/errors.rs @@ -44,9 +44,6 @@ pub enum HashError { /// Parse error. Parse(ParseError), - - /// Salt error. - Salt(SaltError), } impl fmt::Display for HashError { @@ -55,7 +52,6 @@ impl fmt::Display for HashError { Self::Hash(err) => write!(f, "invalid password hash: {}", err), Self::Params(err) => write!(f, "invalid params: {}", err), Self::Parse(err) => write!(f, "parse error: {}", err), - Self::Salt(err) => write!(f, "invalid salt: {}", err), } } } @@ -81,12 +77,6 @@ impl From for HashError { } } -impl From for HashError { - fn from(err: SaltError) -> HashError { - HashError::Salt(err) - } -} - #[cfg(feature = "std")] impl std::error::Error for HashError {} @@ -122,53 +112,30 @@ impl From for ParamsError { #[cfg(feature = "std")] impl std::error::Error for ParamsError {} -/// Parsing errors. -#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)] -pub struct ParseError { - /// Ident contains an invalid character. - pub invalid_char: Option, +/// Parse errors. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum ParseError { + /// Invalid empty input. + Empty, - /// Ident is too long. - pub too_long: bool, -} + /// Input contains invalid character. + InvalidChar(char), -impl ParseError { - /// Create a parse error for the case where something is too long. - pub(crate) fn too_long() -> Self { - Self { - invalid_char: None, - too_long: true, - } - } + /// Input too short. + TooShort, - /// Did the error occur because the input string was empty? - pub fn is_empty(self) -> bool { - self.invalid_char.is_none() && !self.too_long - } + /// Input too long. + TooLong, } impl fmt::Display for ParseError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - f.write_str("PHC string parse error: ")?; - - if self.is_empty() { - return f.write_str("empty strings not permitted"); - } - - if let Some(invalid_char) = self.invalid_char { - write!(f, "invalid character '{}'", invalid_char)?; - - if self.too_long { - f.write_str(", ")?; - } - } - - if self.too_long { - // TODO(tarcieri): include const generic maximum length - f.write_str("too long")?; + match self { + Self::Empty => f.write_str("invalid empty input"), + Self::InvalidChar(char) => write!(f, "invalid character '{}'", char), + Self::TooShort => f.write_str("too short"), + Self::TooLong => f.write_str("too long"), } - - Ok(()) } } @@ -247,38 +214,6 @@ impl From for OutputError { #[cfg(feature = "std")] impl std::error::Error for OutputError {} -/// Salt-related errors. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum SaltError { - /// Parse errors. - Parse(ParseError), - - /// Salt too short (min 4-bytes). - TooShort, - - /// Salt too long (max 48-bytes). - TooLong, -} - -impl fmt::Display for SaltError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - match self { - Self::Parse(err) => write!(f, "{}", err), - Self::TooShort => f.write_str("salt too short (min 4-bytes)"), - Self::TooLong => f.write_str("salt too long (max 48-bytes)"), - } - } -} - -impl From for SaltError { - fn from(err: ParseError) -> SaltError { - SaltError::Parse(err) - } -} - -#[cfg(feature = "std")] -impl std::error::Error for SaltError {} - /// Password verification errors. #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub struct VerifyError; diff --git a/password-hash/src/ident.rs b/password-hash/src/ident.rs index 93aa89b20..0092cfdec 100644 --- a/password-hash/src/ident.rs +++ b/password-hash/src/ident.rs @@ -121,7 +121,7 @@ impl<'a> TryFrom<&'a str> for Ident<'a> { fn try_from(s: &'a str) -> Result { if s.is_empty() { - return Err(ParseError::default()); + return Err(ParseError::Empty); } let bytes = s.as_bytes(); @@ -129,15 +129,12 @@ impl<'a> TryFrom<&'a str> for Ident<'a> { for &c in bytes { if !is_char_valid(c) { - return Err(ParseError { - invalid_char: Some(c.into()), - too_long, - }); + return Err(ParseError::InvalidChar(c.into())); } } if too_long { - return Err(ParseError::too_long()); + return Err(ParseError::TooLong); } Ok(Self::new(s)) @@ -163,7 +160,7 @@ const fn is_char_valid(c: u8) -> bool { #[cfg(test)] mod tests { - use super::Ident; + use super::{Ident, ParseError}; use core::convert::TryFrom; // Invalid ident examples @@ -193,8 +190,7 @@ mod tests { #[test] fn reject_empty_fallible() { let err = Ident::try_from(INVALID_EMPTY).err().unwrap(); - assert_eq!(err.invalid_char, None); - assert!(!err.too_long); + assert_eq!(err, ParseError::Empty); } #[test] @@ -206,8 +202,7 @@ mod tests { #[test] fn reject_invalid_char_fallible() { let err = Ident::try_from(INVALID_CHAR).err().unwrap(); - assert_eq!(err.invalid_char, Some(';')); - assert!(!err.too_long); + assert_eq!(err, ParseError::InvalidChar(';')); } #[test] @@ -219,8 +214,7 @@ mod tests { #[test] fn reject_too_long_fallible() { let err = Ident::try_from(INVALID_TOO_LONG).err().unwrap(); - assert_eq!(err.invalid_char, None); - assert!(err.too_long); + assert_eq!(err, ParseError::TooLong); } #[test] @@ -232,7 +226,6 @@ mod tests { #[test] fn reject_invalid_char_and_too_long_fallible() { let err = Ident::try_from(INVALID_CHAR_AND_TOO_LONG).err().unwrap(); - assert_eq!(err.invalid_char, Some('!')); - assert!(err.too_long); + assert_eq!(err, ParseError::InvalidChar('!')); } } diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index f4f6eddc4..6aaf8c61d 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -162,23 +162,19 @@ impl<'a> PasswordHash<'a> { use errors::ParseError; if s.is_empty() { - return Err(ParseError::default().into()); + return Err(ParseError::Empty.into()); } let mut fields = s.split(PASSWORD_HASH_SEPARATOR); let beginning = fields.next().expect("no first field"); if let Some(first_char) = beginning.chars().next() { - return Err(ParseError { - invalid_char: Some(first_char), - too_long: false, - } - .into()); + return Err(ParseError::InvalidChar(first_char).into()); } let algorithm = fields .next() - .ok_or_else(ParseError::default) + .ok_or(ParseError::TooShort) .and_then(Ident::try_from)?; let mut params = Params::new(); @@ -202,7 +198,7 @@ impl<'a> PasswordHash<'a> { } if fields.next().is_some() { - return Err(ParseError::too_long().into()); + return Err(ParseError::TooLong.into()); } Ok(Self { diff --git a/password-hash/src/params.rs b/password-hash/src/params.rs index 27fd9321c..b15ce7e14 100644 --- a/password-hash/src/params.rs +++ b/password-hash/src/params.rs @@ -150,18 +150,16 @@ impl<'a> TryFrom<&'a str> for Params<'a> { .split(PARAMS_DELIMITER) .map(|p| p.split(PAIR_DELIMITER)) { - let name = param.next().ok_or(ParseError { - invalid_char: Some(PAIR_DELIMITER), - too_long: false, - })?; + let name = param + .next() + .ok_or(ParseError::InvalidChar(PAIR_DELIMITER))?; - let value = param.next().ok_or(ParseError { - invalid_char: Some(PAIR_DELIMITER), - too_long: false, - })?; + let value = param + .next() + .ok_or(ParseError::InvalidChar(PAIR_DELIMITER))?; if param.next().is_some() { - return Err(ParseError::too_long().into()); + return Err(ParseError::TooLong.into()); } params = params.add(name.try_into()?, value.try_into()?)?; diff --git a/password-hash/src/params/value.rs b/password-hash/src/params/value.rs index 967174868..2b5520cc2 100644 --- a/password-hash/src/params/value.rs +++ b/password-hash/src/params/value.rs @@ -87,7 +87,7 @@ impl<'a> TryFrom for Value<'a> { i32::try_from(decimal) .ok() .map(Into::into) - .ok_or_else(ParseError::too_long) + .ok_or(ParseError::TooLong) } } @@ -155,18 +155,12 @@ impl<'a> ValueStr<'a> { /// Parse a [`ValueStr`] from the provided `str`, validating it according to /// the PHC string format's rules. pub fn new(input: &'a str) -> Result { - let too_long = input.as_bytes().len() > MAX_LENGTH; - - // Check that the characters are permitted in a PHC parameter value. - assert_valid_value(input).map_err(|mut e| { - e.too_long = too_long; - e - })?; - - if too_long { - return Err(ParseError::too_long()); + if input.as_bytes().len() > MAX_LENGTH { + return Err(ParseError::TooLong); } + // Check that the characters are permitted in a PHC parameter value. + assert_valid_value(input)?; Ok(Self(input)) } @@ -232,32 +226,26 @@ impl<'a> ValueStr<'a> { // Empty strings aren't decimals if value.is_empty() { - return Err(ParseError::default()); + return Err(ParseError::Empty); } // Ensure all characters are digits - for char in value.chars() { - if !matches!(char, '0'..='9') { - return Err(ParseError { - invalid_char: Some(char), - too_long: false, - }); + for c in value.chars() { + if !matches!(c, '0'..='9') { + return Err(ParseError::InvalidChar(c)); } } // Disallow leading zeroes if value.starts_with('0') && value.len() > 1 { - return Err(ParseError { - invalid_char: Some('0'), - too_long: false, - }); + return Err(ParseError::InvalidChar('0')); } value.parse().map_err(|_| { // In theory a value overflow should be the only potential error here. // When `ParseIntError::kind` is stable it might be good to double check: // - ParseError::too_long() + ParseError::TooLong }) } @@ -305,12 +293,9 @@ impl<'a> fmt::Display for ValueStr<'a> { /// Are all of the given bytes allowed in a [`Value`]? fn assert_valid_value(input: &str) -> Result<(), ParseError> { - for char in input.chars() { - if !is_char_valid(char) { - return Err(ParseError { - invalid_char: Some(char), - too_long: false, - }); + for c in input.chars() { + if !is_char_valid(c) { + return Err(ParseError::InvalidChar(c)); } } @@ -324,7 +309,7 @@ fn is_char_valid(c: char) -> bool { #[cfg(test)] mod tests { - use super::ValueStr; + use super::{ParseError, ValueStr}; use core::convert::TryFrom; // Invalid value examples @@ -351,21 +336,21 @@ mod tests { fn reject_decimal_with_leading_zero() { let value = ValueStr::new("01").unwrap(); let err = i32::try_from(value).err().unwrap(); - assert_eq!(err.invalid_char, Some('0')); + assert!(matches!(err, ParseError::InvalidChar('0'))); } #[test] fn reject_overlong_decimal() { let value = ValueStr::new("2147483648").unwrap(); let err = i32::try_from(value).err().unwrap(); - assert!(err.too_long); + assert_eq!(err, ParseError::TooLong); } #[test] fn reject_negative() { let value = ValueStr::new("-1").unwrap(); let err = i32::try_from(value).err().unwrap(); - assert_eq!(err.invalid_char, Some('-')); + assert!(matches!(err, ParseError::InvalidChar('-'))); } // @@ -393,21 +378,18 @@ mod tests { #[test] fn reject_invalid_char() { let err = ValueStr::new(INVALID_CHAR).err().unwrap(); - assert_eq!(err.invalid_char, Some(';')); - assert!(!err.too_long); + assert!(matches!(err, ParseError::InvalidChar(';'))); } #[test] fn reject_too_long() { let err = ValueStr::new(INVALID_TOO_LONG).err().unwrap(); - assert_eq!(err.invalid_char, None); - assert!(err.too_long); + assert_eq!(err, ParseError::TooLong); } #[test] fn reject_invalid_char_and_too_long() { let err = ValueStr::new(INVALID_CHAR_AND_TOO_LONG).err().unwrap(); - assert_eq!(err.invalid_char, Some('!')); - assert!(err.too_long); + assert_eq!(err, ParseError::TooLong); } } diff --git a/password-hash/src/salt.rs b/password-hash/src/salt.rs index 84655f64a..d93541d96 100644 --- a/password-hash/src/salt.rs +++ b/password-hash/src/salt.rs @@ -1,7 +1,7 @@ //! Salt string support. use crate::{ - errors::{B64Error, SaltError}, + errors::{B64Error, ParseError}, params::ValueStr, }; use core::{ @@ -99,14 +99,14 @@ impl<'a> Salt<'a> { /// Create a [`Salt`] from the given `str`, validating it according to /// [`Salt::min_len`] and [`Salt::max_len`] length restrictions. - pub fn new(input: &'a str) -> Result { + pub fn new(input: &'a str) -> Result { // TODO(tarcieri): support shorter salts for MCF? if input.len() < Self::min_len() { - return Err(SaltError::TooShort); + return Err(ParseError::TooShort); } if input.len() > Self::max_len() { - return Err(SaltError::TooLong); + return Err(ParseError::TooLong); } Ok(Self(input.try_into()?)) @@ -144,9 +144,9 @@ impl<'a> AsRef for Salt<'a> { } impl<'a> TryFrom<&'a str> for Salt<'a> { - type Error = SaltError; + type Error = ParseError; - fn try_from(input: &'a str) -> Result { + fn try_from(input: &'a str) -> Result { Self::new(input) } } @@ -165,7 +165,7 @@ impl<'a> fmt::Debug for Salt<'a> { #[cfg(test)] mod tests { - use super::{Salt, SaltError}; + use super::{ParseError, Salt}; #[test] fn new_with_valid_min_length_input() { @@ -185,7 +185,7 @@ mod tests { fn reject_new_too_short() { for &too_short in &["", "a", "ab", "abc"] { let err = Salt::new(too_short).err().unwrap(); - assert_eq!(err, SaltError::TooShort); + assert_eq!(err, ParseError::TooShort); } } @@ -193,6 +193,6 @@ mod tests { fn reject_new_too_long() { let s = "0123456789112345678921234567893123456789412345678"; let err = Salt::new(s).err().unwrap(); - assert_eq!(err, SaltError::TooLong); + assert_eq!(err, ParseError::TooLong); } } From 0c8f887baaefcbf972f2a4e7880de0e1dd6c3dbb Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 5 Jan 2021 21:20:45 -0800 Subject: [PATCH 0357/1461] password-hash: simplify module structure (#454) --- password-hash/src/lib.rs | 24 +++++++++++++----------- password-hash/src/params.rs | 13 +++++-------- password-hash/src/salt.rs | 2 +- password-hash/src/{params => }/value.rs | 0 4 files changed, 19 insertions(+), 20 deletions(-) rename password-hash/src/{params => }/value.rs (100%) diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index 6aaf8c61d..ef3f58955 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -41,13 +41,10 @@ extern crate alloc; #[cfg(feature = "std")] extern crate std; -pub mod b64; -pub mod errors; -pub mod params; - -mod ident; -mod output; -mod salt; +use core::{ + convert::{TryFrom, TryInto}, + fmt, +}; pub use crate::{ errors::{HashError, PhfError, VerifyError}, @@ -55,12 +52,17 @@ pub use crate::{ output::Output, params::Params, salt::Salt, + value::{Decimal, Value, ValueStr}, }; -use core::{ - convert::{TryFrom, TryInto}, - fmt, -}; +pub mod b64; +pub mod errors; + +mod ident; +mod output; +mod params; +mod salt; +mod value; /// Separator character used in password hashes (e.g. `$6$...`). const PASSWORD_HASH_SEPARATOR: char = '$'; diff --git a/password-hash/src/params.rs b/password-hash/src/params.rs index b15ce7e14..bdb400f9d 100644 --- a/password-hash/src/params.rs +++ b/password-hash/src/params.rs @@ -1,11 +1,8 @@ //! Algorithm parameters. -mod value; - -pub use self::value::{Decimal, Value, ValueStr}; - use crate::{ errors::{ParamsError, ParseError}, + value::Value, Ident, }; use core::{ @@ -104,7 +101,7 @@ impl<'a> Params<'a> { None } - /// Iterate over the parameters using [`Iter`]. + /// Iterate over the parameters. pub fn iter(&self) -> Iter<'a, '_> { Iter { inner: self.pairs.iter(), @@ -229,11 +226,11 @@ impl<'a, 'b> Iterator for Iter<'a, 'b> { #[cfg(test)] mod tests { - use super::{FromIterator, Ident, Params, ParamsError}; - use core::convert::TryFrom; - #[cfg(feature = "alloc")] use alloc::string::ToString; + use core::convert::TryFrom; + + use super::{FromIterator, Ident, Params, ParamsError}; #[test] fn add_chain() { diff --git a/password-hash/src/salt.rs b/password-hash/src/salt.rs index d93541d96..520c7fa80 100644 --- a/password-hash/src/salt.rs +++ b/password-hash/src/salt.rs @@ -2,7 +2,7 @@ use crate::{ errors::{B64Error, ParseError}, - params::ValueStr, + ValueStr, }; use core::{ convert::{TryFrom, TryInto}, diff --git a/password-hash/src/params/value.rs b/password-hash/src/value.rs similarity index 100% rename from password-hash/src/params/value.rs rename to password-hash/src/value.rs From 80b4bcb6bffd40e8b13515e010621992fb291330 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 5 Jan 2021 21:48:23 -0800 Subject: [PATCH 0358/1461] password-hash: add `version` field (#456) Support for PHC string variant with an additional version field: https://github.com/P-H-C/phc-string-format/pull/4 This is used by Argon2. --- password-hash/src/lib.rs | 50 +++++++++++++++++++++++++---- password-hash/tests/hashing.rs | 1 + password-hash/tests/test_vectors.rs | 41 +++++++++++------------ 3 files changed, 62 insertions(+), 30 deletions(-) diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index ef3f58955..07c34a1c0 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -141,6 +141,18 @@ pub struct PasswordHash<'a> { /// symbolic name for the function. pub algorithm: Ident<'a>, + /// Optional version field. + /// + /// An augmented form of the PHC string format used by Argon2 includes + /// an additional version field out-of-band from other parameters: + /// + /// ```text + /// $[$v=][$=(,=)*][$[$]] + /// ``` + /// + /// See: + pub version: Option, + /// Algorithm-specific [`Params`]. /// /// This corresponds to the set of `$=(,=)*` @@ -179,22 +191,41 @@ impl<'a> PasswordHash<'a> { .ok_or(ParseError::TooShort) .and_then(Ident::try_from)?; + let mut version = None; let mut params = Params::new(); let mut salt = None; let mut hash = None; - if let Some(field) = fields.next() { + let mut next_field = fields.next(); + + if let Some(field) = next_field { + // v= + if field.starts_with("v=") && !field.contains(params::PARAMS_DELIMITER) { + version = Some(ValueStr::new(&field[2..]).and_then(|value| value.decimal())?); + next_field = None; + } + } + + if next_field.is_none() { + next_field = fields.next(); + } + + if let Some(field) = next_field { + // = if field.contains(params::PAIR_DELIMITER) { params = Params::try_from(field)?; - - if let Some(s) = fields.next() { - salt = Some(s.try_into()?); - } - } else { - salt = Some(field.try_into()?); + next_field = None; } } + if next_field.is_none() { + next_field = fields.next(); + } + + if let Some(s) = next_field { + salt = Some(s.try_into()?); + } + if let Some(field) = fields.next() { hash = Some(field.parse()?); } @@ -205,6 +236,7 @@ impl<'a> PasswordHash<'a> { Ok(Self { algorithm, + version, params, salt, hash, @@ -252,6 +284,10 @@ impl<'a> fmt::Display for PasswordHash<'a> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}{}", PASSWORD_HASH_SEPARATOR, self.algorithm)?; + if let Some(version) = self.version { + write!(f, "{}v={}", PASSWORD_HASH_SEPARATOR, version)?; + } + if !self.params.is_empty() { write!(f, "{}{}", PASSWORD_HASH_SEPARATOR, self.params)?; } diff --git a/password-hash/tests/hashing.rs b/password-hash/tests/hashing.rs index 4b812e958..a90969235 100644 --- a/password-hash/tests/hashing.rs +++ b/password-hash/tests/hashing.rs @@ -32,6 +32,7 @@ impl PasswordHasher for StubFunction { Ok(PasswordHash { algorithm: ALG, + version: None, params, salt: Some(salt), hash: Some(hash), diff --git a/password-hash/tests/test_vectors.rs b/password-hash/tests/test_vectors.rs index c460a3b05..37ad2d977 100644 --- a/password-hash/tests/test_vectors.rs +++ b/password-hash/tests/test_vectors.rs @@ -1,38 +1,32 @@ //! Test vectors for commonly used password hashing algorithms. -#![cfg(feature = "registry")] +use password_hash::{Ident, PasswordHash}; -use password_hash::{ - algorithm::{argon2, bcrypt}, - Algorithm, PasswordHash, -}; - -const ARGON2ID_HASH: &str = - "$argon2id$m=65536,t=3,p=2$c29tZXNhbHQ$RdescudvJCsgt3ub+b+dWRWJTmaaJObG"; +const ARGON2D_HASH: &str = + "$argon2d$v=19$m=512,t=3,p=2$5VtWOO3cGWYQHEMaYGbsfQ$AcmqasQgW/wI6wAHAMk4aQ"; const BCRYPT_HASH: &str = "$2b$MTIzNA$i5btSOiulHhaPHPbgNUGdObga/GCAVG/y5HHY1ra7L0C9dpCaw8u"; const SCRYPT_HASH: &str = "$scrypt$epIxT/h6HbbwHaehFnh/bw$7H0vsXlY8UxxyW/BWx/9GuY7jEvGjT71GFd6O4SZND0"; #[test] fn argon2id() { - let ph = ARGON2ID_HASH.parse::().unwrap(); - assert_eq!(ph.algorithm, Algorithm::Argon2(argon2::Variant::ID)); + let ph = PasswordHash::new(ARGON2D_HASH).unwrap(); + assert_eq!(ph.algorithm, Ident::new("argon2d")); + assert_eq!(ph.version, Some(19)); assert_eq!(ph.params.len(), 3); - assert_eq!(ph.params["m"], 65536.into()); - assert_eq!(ph.params["t"], 3.into()); - assert_eq!(ph.params["p"], 2.into()); - assert_eq!(ph.salt.unwrap().to_string(), "c29tZXNhbHQ"); - assert_eq!( - ph.hash.unwrap().to_string(), - "RdescudvJCsgt3ub+b+dWRWJTmaaJObG" - ); - assert_eq!(ph.to_string(), ARGON2ID_HASH); + assert_eq!(ph.params["m"].decimal().unwrap(), 512); + assert_eq!(ph.params["t"].decimal().unwrap(), 3); + assert_eq!(ph.params["p"].decimal().unwrap(), 2); + assert_eq!(ph.salt.unwrap().as_ref(), "5VtWOO3cGWYQHEMaYGbsfQ"); + assert_eq!(ph.hash.unwrap().to_string(), "AcmqasQgW/wI6wAHAMk4aQ"); + assert_eq!(ph.to_string(), ARGON2D_HASH); } #[test] fn bcrypt() { - let ph = BCRYPT_HASH.parse::().unwrap(); - assert_eq!(ph.algorithm, Algorithm::Bcrypt(bcrypt::Variant::B)); + let ph = PasswordHash::new(BCRYPT_HASH).unwrap(); + assert_eq!(ph.algorithm, Ident::new("2b")); + assert_eq!(ph.version, None); assert_eq!(ph.params.len(), 0); assert_eq!(ph.salt.unwrap().to_string(), "MTIzNA"); assert_eq!( @@ -44,8 +38,9 @@ fn bcrypt() { #[test] fn scrypt() { - let ph = SCRYPT_HASH.parse::().unwrap(); - assert_eq!(ph.algorithm, Algorithm::Scrypt); + let ph = PasswordHash::new(SCRYPT_HASH).unwrap(); + assert_eq!(ph.algorithm, Ident::new("scrypt")); + assert_eq!(ph.version, None); assert_eq!(ph.params.len(), 0); assert_eq!(ph.salt.unwrap().to_string(), "epIxT/h6HbbwHaehFnh/bw"); assert_eq!( From fad96a6cd3c9731d5edcbf9c87348e70475ed142 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 6 Jan 2021 07:57:12 -0800 Subject: [PATCH 0359/1461] elliptic-curve: bump `ff` and `group` crates to v0.9.0 (#452) Also bumps `rand_core` to v0.6 (for the `elliptic-curve` crate only). This is a breaking change, so the `elliptic-curve` crate version is also bumped to v0.9.0-pre. --- Cargo.lock | 39 +++++++++++++++++--------- crypto/Cargo.toml | 2 +- elliptic-curve/Cargo.toml | 10 +++---- elliptic-curve/src/ecdh.rs | 10 ------- elliptic-curve/src/lib.rs | 18 ++++++------ elliptic-curve/src/point.rs | 1 - elliptic-curve/src/public_key.rs | 16 ----------- elliptic-curve/src/scalar.rs | 12 +------- elliptic-curve/src/sec1.rs | 3 -- elliptic-curve/src/secret_key.rs | 4 --- elliptic-curve/src/secret_key/pkcs8.rs | 1 - 11 files changed, 41 insertions(+), 75 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 30bc2695d..ce6f95631 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -41,12 +41,13 @@ dependencies = [ [[package]] name = "bitvec" -version = "0.18.3" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64143ed23541fe0c6e2235905eaae37ceae1ca69e14dce4afcd6ec9643359d00" +checksum = "f5011ffc90248764d7005b0e10c7294f5aa1bd87d9dd7248f4ad475b347c294d" dependencies = [ "funty", "radium", + "tap", "wyz", ] @@ -154,7 +155,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.8.4" +version = "0.9.0-pre" dependencies = [ "bitvec", "digest 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -163,19 +164,19 @@ dependencies = [ "group", "hex-literal", "pkcs8", - "rand_core", + "rand_core 0.6.1", "subtle", "zeroize", ] [[package]] name = "ff" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01646e077d4ebda82b73f1bca002ea1e91561a77df2431a9e79729bcc31950ef" +checksum = "72a4d941a5b7c2a75222e2d44fcdf634a67133d9db31e177ae5ff6ecda852bfe" dependencies = [ "bitvec", - "rand_core", + "rand_core 0.6.1", "subtle", ] @@ -215,12 +216,12 @@ dependencies = [ [[package]] name = "group" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc11f9f5fbf1943b48ae7c2bf6846e7d827a512d1be4f23af708f5ca5d01dde1" +checksum = "61b3c1e8b4f1ca07e6605ea1be903a5f6956aec5c8a67fd44d56076631675ed8" dependencies = [ "ff", - "rand_core", + "rand_core 0.6.1", "subtle", ] @@ -311,9 +312,9 @@ dependencies = [ [[package]] name = "radium" -version = "0.3.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "def50a86306165861203e7f84ecffbbdfdea79f0e51039b33de1e952358c47ac" +checksum = "e9e006811e1fdd12672b0820a7f44c18dde429f367d50cec003d22aa9b3c8ddc" [[package]] name = "rand_core" @@ -321,6 +322,12 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +[[package]] +name = "rand_core" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c026d7df8b298d90ccbbc5190bd04d85e159eaf5576caeacf8741da93ccbd2e5" + [[package]] name = "sha2" version = "0.9.2" @@ -340,7 +347,7 @@ version = "1.2.2" dependencies = [ "digest 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal", - "rand_core", + "rand_core 0.5.1", "sha2", "signature_derive", ] @@ -399,6 +406,12 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "tap" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36474e732d1affd3a6ed582781b3683df3d0563714c59c39591e8ff707cf078e" + [[package]] name = "typenum" version = "1.12.0" diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index ae54b55a2..41436093e 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -15,7 +15,7 @@ edition = "2018" aead = { version = "0.3", optional = true, path = "../aead" } cipher = { version = "=0.3.0-pre.4", optional = true, path = "../cipher" } digest = { version = "0.9", optional = true, path = "../digest" } -elliptic-curve = { version = "0.8", optional = true, path = "../elliptic-curve" } +elliptic-curve = { version = "=0.9.0-pre", optional = true, path = "../elliptic-curve" } mac = { version = "=0.11.0-pre", package = "crypto-mac", optional = true, path = "../crypto-mac" } signature = { version = "1.2.0", optional = true, default-features = false, path = "../signature" } universal-hash = { version = "0.4", optional = true, path = "../universal-hash" } diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index ac25b0cf8..f30e1142e 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -5,7 +5,7 @@ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. """ -version = "0.8.4" # Also update html_root_url in lib.rs when bumping this +version = "0.9.0-pre" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" repository = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve" @@ -15,13 +15,13 @@ categories = ["cryptography", "no-std"] keywords = ["crypto", "ecc", "elliptic", "weierstrass"] [dependencies] -bitvec = { version = "0.18", optional = true, default-features = false } +bitvec = { version = "0.20", optional = true, default-features = false } digest = { version = "0.9", optional = true } -ff = { version = "0.8", optional = true, default-features = false } -group = { version = "0.8", optional = true, default-features = false } +ff = { version = "0.9", optional = true, default-features = false } +group = { version = "0.9", optional = true, default-features = false } generic-array = { version = "0.14", default-features = false } pkcs8 = { version = "0.3.3", optional = true } -rand_core = { version = "0.5", default-features = false } +rand_core = { version = "0.6", default-features = false } subtle = { version = "2.4", default-features = false } zeroize = { version = "1", optional = true, default-features = false } diff --git a/elliptic-curve/src/ecdh.rs b/elliptic-curve/src/ecdh.rs index df4192e00..248015fcc 100644 --- a/elliptic-curve/src/ecdh.rs +++ b/elliptic-curve/src/ecdh.rs @@ -67,7 +67,6 @@ pub fn diffie_hellman( ) -> SharedSecret where C: Curve + ProjectiveArithmetic, - FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField> + Clone + Zeroize, AffinePoint: Copy + Clone + Debug + ToEncodedPoint + Zeroize, ProjectivePoint: From>, @@ -107,7 +106,6 @@ where pub struct EphemeralSecret where C: Curve + ProjectiveArithmetic, - FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField> + Zeroize, { scalar: NonZeroScalar, @@ -116,7 +114,6 @@ where impl EphemeralSecret where C: Curve + ProjectiveArithmetic, - FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField> + Clone + Zeroize, AffinePoint: Copy + Clone + Debug + ToEncodedPoint + Zeroize, ProjectivePoint: From>, @@ -147,7 +144,6 @@ where impl From<&EphemeralSecret> for PublicKey where C: Curve + ProjectiveArithmetic, - FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField> + Clone + Zeroize, AffinePoint: Copy + Clone + Debug + ToEncodedPoint + Zeroize, ProjectivePoint: From>, @@ -162,7 +158,6 @@ where impl Zeroize for EphemeralSecret where C: Curve + ProjectiveArithmetic, - FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField> + Zeroize, { fn zeroize(&mut self) { @@ -173,7 +168,6 @@ where impl Drop for EphemeralSecret where C: Curve + ProjectiveArithmetic, - FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField> + Zeroize, { fn drop(&mut self) { @@ -199,7 +193,6 @@ where pub struct SharedSecret where C: Curve + ProjectiveArithmetic, - FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField>, { /// Computed secret value @@ -209,7 +202,6 @@ where impl SharedSecret where C: Curve + ProjectiveArithmetic, - FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField>, AffinePoint: Zeroize, UntaggedPointSize: Add + ArrayLength, @@ -240,7 +232,6 @@ where impl Zeroize for SharedSecret where C: Curve + ProjectiveArithmetic, - FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField>, { fn zeroize(&mut self) { @@ -251,7 +242,6 @@ where impl Drop for SharedSecret where C: Curve + ProjectiveArithmetic, - FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField>, { fn drop(&mut self) { diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 717100cd8..94c57d736 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -60,17 +60,15 @@ pub use rand_core; pub use subtle; #[cfg(feature = "arithmetic")] -pub use self::{ - point::{AffinePoint, ProjectiveArithmetic, ProjectivePoint}, - public_key::PublicKey, - scalar::Scalar, +pub use { + crate::{ + point::{AffinePoint, ProjectiveArithmetic, ProjectivePoint}, + public_key::PublicKey, + scalar::Scalar, + }, + ff::{self, BitView, Field}, + group::{self, Group}, }; -#[cfg(feature = "arithmetic")] -pub use bitvec::view::BitView; // TODO: https://github.com/zkcrypto/ff/pull/40 -#[cfg(feature = "arithmetic")] -pub use ff::{self, Field}; -#[cfg(feature = "arithmetic")] -pub use group::{self, Group}; #[cfg(feature = "digest")] pub use digest::{self, Digest}; diff --git a/elliptic-curve/src/point.rs b/elliptic-curve/src/point.rs index c0b067508..8003b0eb8 100644 --- a/elliptic-curve/src/point.rs +++ b/elliptic-curve/src/point.rs @@ -5,7 +5,6 @@ use crate::{Curve, FieldBytes, Scalar}; /// Elliptic curve with projective arithmetic implementation. pub trait ProjectiveArithmetic: Curve where - FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: ff::PrimeField>, { /// Elliptic curve point in projective coordinates. diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index 09d4df868..9f8da5e1a 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -64,7 +64,6 @@ use { pub struct PublicKey where C: Curve + ProjectiveArithmetic, - FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField>, AffinePoint: Copy + Clone + Debug, { @@ -74,7 +73,6 @@ where impl PublicKey where C: Curve + ProjectiveArithmetic, - FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField>, AffinePoint: Copy + Clone + Debug, ProjectivePoint: From>, @@ -146,7 +144,6 @@ where impl AsRef> for PublicKey where C: Curve + ProjectiveArithmetic, - FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField>, AffinePoint: Copy + Clone + Debug, ProjectivePoint: From>, @@ -159,7 +156,6 @@ where impl TryFrom> for PublicKey where C: Curve + ProjectiveArithmetic, - FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField>, AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, ProjectivePoint: From>, @@ -176,7 +172,6 @@ where impl TryFrom<&EncodedPoint> for PublicKey where C: Curve + ProjectiveArithmetic, - FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField>, AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, ProjectivePoint: From>, @@ -193,7 +188,6 @@ where impl From> for EncodedPoint where C: Curve + ProjectiveArithmetic + point::Compression, - FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField>, AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, ProjectivePoint: From>, @@ -208,7 +202,6 @@ where impl From<&PublicKey> for EncodedPoint where C: Curve + ProjectiveArithmetic + point::Compression, - FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField>, AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, ProjectivePoint: From>, @@ -223,7 +216,6 @@ where impl FromEncodedPoint for PublicKey where C: Curve + ProjectiveArithmetic, - FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField>, AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, ProjectivePoint: From>, @@ -240,7 +232,6 @@ where impl ToEncodedPoint for PublicKey where C: Curve + ProjectiveArithmetic, - FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField>, AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, ProjectivePoint: From>, @@ -257,7 +248,6 @@ where impl Copy for PublicKey where C: Curve + ProjectiveArithmetic, - FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField>, AffinePoint: Copy + Clone + Debug, { @@ -266,7 +256,6 @@ where impl Eq for PublicKey where C: Curve + ProjectiveArithmetic, - FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField>, AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, ProjectivePoint: From>, @@ -278,7 +267,6 @@ where impl PartialEq for PublicKey where C: Curve + ProjectiveArithmetic, - FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField>, AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, ProjectivePoint: From>, @@ -298,7 +286,6 @@ impl FromPublicKey for PublicKey where Self: TryFrom, Error = Error>, C: Curve + AlgorithmParameters + ProjectiveArithmetic, - FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField>, AffinePoint: Copy + Clone + Debug, ProjectivePoint: From>, @@ -324,7 +311,6 @@ where impl ToPublicKey for PublicKey where C: Curve + AlgorithmParameters + ProjectiveArithmetic, - FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField>, AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, ProjectivePoint: From>, @@ -348,7 +334,6 @@ impl FromStr for PublicKey where Self: TryFrom, Error = Error>, C: Curve + AlgorithmParameters + ProjectiveArithmetic, - FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField>, AffinePoint: Copy + Clone + Debug, ProjectivePoint: From>, @@ -367,7 +352,6 @@ where impl ToString for PublicKey where C: Curve + AlgorithmParameters + ProjectiveArithmetic, - FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField>, AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, ProjectivePoint: From>, diff --git a/elliptic-curve/src/scalar.rs b/elliptic-curve/src/scalar.rs index a1db5b830..374a1a6a1 100644 --- a/elliptic-curve/src/scalar.rs +++ b/elliptic-curve/src/scalar.rs @@ -33,7 +33,6 @@ pub type ScalarBits = BitArray as PrimeField>::ReprBits>; pub struct NonZeroScalar where C: Curve + ProjectiveArithmetic, - FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField>, { scalar: Scalar, @@ -42,7 +41,6 @@ where impl NonZeroScalar where C: Curve + ProjectiveArithmetic, - FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField>, { /// Generate a random `NonZeroScalar` @@ -74,7 +72,6 @@ where impl AsRef> for NonZeroScalar where C: Curve + ProjectiveArithmetic, - FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField>, { fn as_ref(&self) -> &Scalar { @@ -85,7 +82,6 @@ where impl ConditionallySelectable for NonZeroScalar where C: Curve + ProjectiveArithmetic, - FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField>, { fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { @@ -98,7 +94,6 @@ where impl Copy for NonZeroScalar where C: Curve + ProjectiveArithmetic, - FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField>, { } @@ -106,7 +101,6 @@ where impl Deref for NonZeroScalar where C: Curve + ProjectiveArithmetic, - FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField>, { type Target = Scalar; @@ -119,18 +113,16 @@ where impl From> for FieldBytes where C: Curve + ProjectiveArithmetic, - FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField>, { fn from(scalar: NonZeroScalar) -> FieldBytes { - scalar.scalar.into() + scalar.scalar.to_repr() } } impl Invert for NonZeroScalar where C: Curve + ProjectiveArithmetic, - FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField> + Invert, { type Output = Scalar; @@ -144,7 +136,6 @@ where impl TryFrom<&[u8]> for NonZeroScalar where C: Curve + ProjectiveArithmetic, - FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField>, { type Error = Error; @@ -162,7 +153,6 @@ where impl Zeroize for NonZeroScalar where C: Curve + ProjectiveArithmetic, - FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField> + Zeroize, { fn zeroize(&mut self) { diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index e27478a4f..976812023 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -132,7 +132,6 @@ where pub fn from_secret_key(secret_key: &SecretKey, compress: bool) -> Self where C: Curve + ProjectiveArithmetic, - FieldBytes: From> + for<'r> From<&'r Scalar>, AffinePoint: ToEncodedPoint, Scalar: PrimeField> + Zeroize, { @@ -171,7 +170,6 @@ where pub fn to_untagged_bytes(&self) -> Option>> where C: Curve + ProjectiveArithmetic, - FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField>, AffinePoint: ConditionallySelectable + Default + Decompress + ToEncodedPoint, { @@ -206,7 +204,6 @@ where pub fn decompress(&self) -> Option where C: Curve + ProjectiveArithmetic, - FieldBytes: From> + for<'r> From<&'r Scalar>, Scalar: PrimeField>, AffinePoint: ConditionallySelectable + Default + Decompress + ToEncodedPoint, { diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 022557019..7aef7dd4e 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -74,7 +74,6 @@ where pub fn random(rng: impl CryptoRng + RngCore) -> Self where C: ProjectiveArithmetic + SecretValue>, - FieldBytes: From> + for<'a> From<&'a Scalar>, Scalar: PrimeField> + Zeroize, { Self { @@ -115,7 +114,6 @@ where pub fn secret_scalar(&self) -> &NonZeroScalar where C: ProjectiveArithmetic + SecretValue>, - FieldBytes: From> + for<'a> From<&'a Scalar>, Scalar: PrimeField> + Zeroize, { &self.secret_value @@ -127,7 +125,6 @@ where pub fn public_key(&self) -> PublicKey where C: weierstrass::Curve + ProjectiveArithmetic + SecretValue>, - FieldBytes: From> + for<'a> From<&'a Scalar>, Scalar: PrimeField> + Zeroize, AffinePoint: Copy + Clone + Debug + Default, ProjectivePoint: From>, @@ -197,7 +194,6 @@ pub trait SecretValue: Curve { impl SecretValue for C where C: Curve + ProjectiveArithmetic, - FieldBytes: From> + for<'a> From<&'a Scalar>, Scalar: PrimeField> + Zeroize, { type Secret = NonZeroScalar; diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs index 2750a864c..bc260d38b 100644 --- a/elliptic-curve/src/secret_key/pkcs8.rs +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -114,7 +114,6 @@ where impl ToPrivateKey for SecretKey where C: weierstrass::Curve + AlgorithmParameters + ProjectiveArithmetic, - FieldBytes: From> + for<'a> From<&'a Scalar>, Scalar: PrimeField> + Zeroize, AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, ProjectivePoint: From>, From 33c8a5347bc4b2e6740eb8d9f64b86f60a91c48c Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 6 Jan 2021 08:09:07 -0800 Subject: [PATCH 0360/1461] signature: bump `rand_core` dependency to v0.6 (#457) --- Cargo.lock | 14 ++++---------- signature/Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ce6f95631..7c6df6239 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -164,7 +164,7 @@ dependencies = [ "group", "hex-literal", "pkcs8", - "rand_core 0.6.1", + "rand_core", "subtle", "zeroize", ] @@ -176,7 +176,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72a4d941a5b7c2a75222e2d44fcdf634a67133d9db31e177ae5ff6ecda852bfe" dependencies = [ "bitvec", - "rand_core 0.6.1", + "rand_core", "subtle", ] @@ -221,7 +221,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61b3c1e8b4f1ca07e6605ea1be903a5f6956aec5c8a67fd44d56076631675ed8" dependencies = [ "ff", - "rand_core 0.6.1", + "rand_core", "subtle", ] @@ -316,12 +316,6 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e9e006811e1fdd12672b0820a7f44c18dde429f367d50cec003d22aa9b3c8ddc" -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" - [[package]] name = "rand_core" version = "0.6.1" @@ -347,7 +341,7 @@ version = "1.2.2" dependencies = [ "digest 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal", - "rand_core 0.5.1", + "rand_core", "sha2", "signature_derive", ] diff --git a/signature/Cargo.toml b/signature/Cargo.toml index d365473ee..a86bb4aee 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -17,7 +17,7 @@ optional = true default-features = false [dependencies.rand_core] -version = "0.5" +version = "0.6" optional = true default-features = false From 89549f28c7235c0199819506798a782cd9b80903 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 6 Jan 2021 08:24:22 -0800 Subject: [PATCH 0361/1461] signature/derive: fix rustdoc links (#458) Links were previously busted. Not sure if there's better way to link to types in an external crate which will render correctly on https://docs.rs but this should at least fix the immediate problem. --- signature/derive/src/lib.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/signature/derive/src/lib.rs b/signature/derive/src/lib.rs index 1059318de..be067427c 100644 --- a/signature/derive/src/lib.rs +++ b/signature/derive/src/lib.rs @@ -45,6 +45,9 @@ decl_derive! { /// complete signature algorithm implementation. /// /// [`Digest`]: https://docs.rs/digest/latest/digest/trait.Digest.html + /// [`DigestSigner`]: https://docs.rs/signature/latest/signature/trait.DigestSigner.html + /// [`PrehashSignature`]: https://docs.rs/signature/latest/signature/trait.PrehashSignature.html + /// [`PrehashSignature::Digest`]: https://docs.rs/signature/latest/signature/trait.PrehashSignature.html#associated-types derive_signer } @@ -79,6 +82,9 @@ decl_derive! { /// complete signature algorithm implementation. /// /// [`Digest`]: https://docs.rs/digest/latest/digest/trait.Digest.html + /// [`DigestVerifier`]: https://docs.rs/signature/latest/signature/trait.DigestVerifier.html + /// [`PrehashSignature`]: https://docs.rs/signature/latest/signature/trait.PrehashSignature.html + /// [`PrehashSignature::Digest`]: https://docs.rs/signature/latest/signature/trait.PrehashSignature.html#associated-types derive_verifier } From 21da02e25896f27e2be681cb744c350050c2e7c6 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 6 Jan 2021 08:31:02 -0800 Subject: [PATCH 0362/1461] signature-derive v1.0.0-pre.3 (#459) --- Cargo.lock | 2 +- signature/Cargo.toml | 2 +- signature/derive/CHANGELOG.md | 6 ++++++ signature/derive/Cargo.toml | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7c6df6239..f3fa64a58 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -348,7 +348,7 @@ dependencies = [ [[package]] name = "signature_derive" -version = "1.0.0-pre.2" +version = "1.0.0-pre.3" dependencies = [ "proc-macro2", "quote", diff --git a/signature/Cargo.toml b/signature/Cargo.toml index a86bb4aee..d840e6ab2 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -22,7 +22,7 @@ optional = true default-features = false [dependencies.signature_derive] -version = "= 1.0.0-pre.2" +version = "= 1.0.0-pre.3" optional = true path = "derive" diff --git a/signature/derive/CHANGELOG.md b/signature/derive/CHANGELOG.md index eb7886b25..711385824 100644 --- a/signature/derive/CHANGELOG.md +++ b/signature/derive/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 1.0.0-pre.3 (2021-01-06) +### Fixed +- rustdoc links ([#458]) + +[#458]: https://github.com/RustCrypto/traits/pull/458 + ## 1.0.0-pre.2 (2020-04-19) ### Changed - Rename `DigestSignature` => `PrehashSignature` ([#96]) diff --git a/signature/derive/Cargo.toml b/signature/derive/Cargo.toml index 836e7baa7..f5487cbf3 100644 --- a/signature/derive/Cargo.toml +++ b/signature/derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "signature_derive" -version = "1.0.0-pre.2" +version = "1.0.0-pre.3" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" description = "Custom derive support for the 'signature' crate" From 404c5b453ad77618b7484c4e17504fbe339c36f2 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 6 Jan 2021 08:39:32 -0800 Subject: [PATCH 0363/1461] signature v1.3.0 (#460) --- Cargo.lock | 2 +- signature/CHANGELOG.md | 8 ++++++++ signature/Cargo.toml | 2 +- signature/src/lib.rs | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f3fa64a58..e359f1e1c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -337,7 +337,7 @@ dependencies = [ [[package]] name = "signature" -version = "1.2.2" +version = "1.3.0" dependencies = [ "digest 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal", diff --git a/signature/CHANGELOG.md b/signature/CHANGELOG.md index 9bce8732f..fc4f8ef4a 100644 --- a/signature/CHANGELOG.md +++ b/signature/CHANGELOG.md @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 1.3.0 (2021-01-06) +### Changed +- Bump `rand_core` to v0.6 ([#457]) +- Bump `signature-derive` v1.0.0-pre.3 ([#459]) + +[#457]: https://github.com/RustCrypto/traits/pull/457 +[#459]: https://github.com/RustCrypto/traits/pull/459 + ## 1.2.2 (2020-07-29) ### Added - `RandomizedDigestSigner` ([#235]) diff --git a/signature/Cargo.toml b/signature/Cargo.toml index d840e6ab2..4bbe927b1 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "1.2.2" # Also update html_root_url in lib.rs when bumping this +version = "1.3.0" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/signature" diff --git a/signature/src/lib.rs b/signature/src/lib.rs index 9a1cdab9a..034651e4f 100644 --- a/signature/src/lib.rs +++ b/signature/src/lib.rs @@ -160,7 +160,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_root_url = "https://docs.rs/signature/1.2.2" + html_root_url = "https://docs.rs/signature/1.3.0" )] #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms, unused_qualifications)] From 5d1ee6ba3983162b3fbde30aee8c3ee3703c041c Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 6 Jan 2021 08:56:57 -0800 Subject: [PATCH 0364/1461] async-signature+crypto: bump `signature` requirement to v1.3.0 (#461) --- crypto/Cargo.toml | 2 +- signature/async/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 41436093e..26c5c9332 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -17,7 +17,7 @@ cipher = { version = "=0.3.0-pre.4", optional = true, path = "../cipher" } digest = { version = "0.9", optional = true, path = "../digest" } elliptic-curve = { version = "=0.9.0-pre", optional = true, path = "../elliptic-curve" } mac = { version = "=0.11.0-pre", package = "crypto-mac", optional = true, path = "../crypto-mac" } -signature = { version = "1.2.0", optional = true, default-features = false, path = "../signature" } +signature = { version = "1.3.0", optional = true, default-features = false, path = "../signature" } universal-hash = { version = "0.4", optional = true, path = "../universal-hash" } [features] diff --git a/signature/async/Cargo.toml b/signature/async/Cargo.toml index dafbc68d6..b5206b47a 100644 --- a/signature/async/Cargo.toml +++ b/signature/async/Cargo.toml @@ -13,7 +13,7 @@ categories = ["cryptography", "no-std"] [dependencies] async-trait = "0.1" -signature = { version = "1.2.0", path = ".." } +signature = { version = "1.3.0", path = ".." } [features] digest = ["signature/digest-preview"] From ab5638ff4051ecbdf448988997a7328a496d2baf Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 8 Jan 2021 07:33:26 -0800 Subject: [PATCH 0365/1461] password-hash: Modular Crypt Format (MCF) support (#462) Implements a minimal trait for upgrading raw MCF hash strings to `PasswordHash` (PHC string format). Also provides a default `verify_mcf_hash` method which computes a `PasswordHash` on the fly and verifies it using the `PasswordHasher` trait. --- password-hash/src/lib.rs | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index 07c34a1c0..1ae297402 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -1,7 +1,8 @@ //! This crate defines a set of traits which describe the functionality of //! [password hashing algorithms]. //! -//! Provides a `no_std`-friendly implementation of the [PHC string format specification] +//! Provides a `no_std`-friendly implementation of the +//! [Password Hashing Competition (PHC) string format specification][PHC] //! (a well-defined subset of the [Modular Crypt Format a.k.a. MCF][MCF]) which //! works in conjunction with the traits this crate defines. //! @@ -20,7 +21,7 @@ //! For more information, please see the documentation for [`PasswordHash`]. //! //! [password hashing algorithms]: https://en.wikipedia.org/wiki/Cryptographic_hash_function#Password_verification -//! [PHC string format specification]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md +//! [PHC]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md //! [MCF]: https://passlib.readthedocs.io/en/stable/modular_crypt_format.html //! [RustCrypto/password-hashes]: https://github.com/RustCrypto/password-hashes @@ -103,6 +104,31 @@ pub trait PasswordHasher { } } +/// Trait for password hashing algorithms which support the legacy +/// [Modular Crypt Format (MCF)][MCF]. +/// +/// [MCF]: https://passlib.readthedocs.io/en/stable/modular_crypt_format.html +pub trait McfHasher { + /// Upgrade an MCF hash to a PHC hash. MCF follow this rough format: + /// + /// ```text + /// $$ + /// ``` + /// + /// MCF hashes are otherwise largely unstructured and parsed according to + /// algorithm-specific rules so hashers must parse a raw string themselves. + fn upgrade_mcf_hash(hash: &str) -> Result, PhfError>; + + /// Verify a password hash in MCF format against the provided password. + fn verify_mcf_hash(&self, password: &[u8], mcf_hash: &str) -> Result<(), VerifyError> + where + Self: PasswordHasher, + { + let phc_hash = Self::upgrade_mcf_hash(mcf_hash)?; + self.verify_password(password, &phc_hash) + } +} + /// Password hash. /// /// This type corresponds to the parsed representation of a PHC string as From b2e9bfb9dd2ba3d787ee0a2fe845b61c17a74236 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 11 Jan 2021 06:09:58 -0800 Subject: [PATCH 0366/1461] elliptic-curve: bump pkcs8 to v0.4.0-pre (#463) This prerelease includes this change which handles decoding/encoding the leading octet of ASN.1 BIT STRINGs: https://github.com/RustCrypto/utils/pull/193 --- Cargo.lock | 8 +++---- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/public_key.rs | 32 ++++---------------------- elliptic-curve/src/secret_key/pkcs8.rs | 23 +++++++----------- 4 files changed, 17 insertions(+), 48 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e359f1e1c..99a335df6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -129,9 +129,9 @@ dependencies = [ [[package]] name = "der" -version = "0.1.0" +version = "0.2.0-pre" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51f59c66c30bb7445c8320a5f9233e437e3572368099f25532a59054328899b4" +checksum = "ce3c2453c3322800962d0630f6e4e64a398ffea370e43a4ceb24d02f724441f4" dependencies = [ "const-oid", ] @@ -277,9 +277,9 @@ version = "0.0.0" [[package]] name = "pkcs8" -version = "0.3.3" +version = "0.4.0-pre" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4839a901843f3942576e65857f0ebf2e190ef7024d3c62a94099ba3f819ad1d" +checksum = "9df125c6bec8ba2195e9ef3064e610c9aa00362b38f502ca348e4383eaeef102" dependencies = [ "der", "subtle-encoding", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index f30e1142e..0e91bdfc8 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -20,7 +20,7 @@ digest = { version = "0.9", optional = true } ff = { version = "0.9", optional = true, default-features = false } group = { version = "0.9", optional = true, default-features = false } generic-array = { version = "0.14", default-features = false } -pkcs8 = { version = "0.3.3", optional = true } +pkcs8 = { version = "0.4.0-pre", optional = true } rand_core = { version = "0.6", default-features = false } subtle = { version = "2.4", default-features = false } zeroize = { version = "1", optional = true, default-features = false } diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index 9f8da5e1a..c93619343 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -26,10 +26,7 @@ use { #[cfg(feature = "pem")] use { - alloc::{ - string::{String, ToString}, - vec::Vec, - }, + alloc::string::{String, ToString}, core::str::FromStr, pkcs8::ToPublicKey, }; @@ -123,22 +120,6 @@ where pub fn to_projective(&self) -> ProjectivePoint { self.point.clone().into() } - - /// Encode this public key as an ASN.1 DER bitstring as used in both - /// PKCS#8 private keys and SPKI public keys. - #[cfg(feature = "pem")] - pub(crate) fn to_der_bitstring(&self) -> Vec - where - AffinePoint: Default + FromEncodedPoint + ToEncodedPoint, - ProjectivePoint: From>, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, - { - let mut bitstring = Vec::new(); - bitstring.push(0); - bitstring.extend_from_slice(self.to_encoded_point(false).as_ref()); - bitstring - } } impl AsRef> for PublicKey @@ -297,12 +278,7 @@ where return Err(pkcs8::Error::Decode); } - // Look for a leading `0x00` byte in the bitstring - if spki.subject_public_key.get(0).cloned() != Some(0x00) { - return Err(pkcs8::Error::Decode); - } - - Self::from_sec1_bytes(&spki.subject_public_key[1..]).map_err(|_| pkcs8::Error::Decode) + Self::from_sec1_bytes(&spki.subject_public_key).map_err(|_| pkcs8::Error::Decode) } } @@ -318,11 +294,11 @@ where UncompressedPointSize: ArrayLength, { fn to_public_key_der(&self) -> pkcs8::PublicKeyDocument { - let public_key_bytes = self.to_der_bitstring(); + let public_key_bytes = self.to_encoded_point(false); pkcs8::SubjectPublicKeyInfo { algorithm: C::algorithm_identifier(), - subject_public_key: &public_key_bytes, + subject_public_key: public_key_bytes.as_ref(), } .to_der() } diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs index bc260d38b..21044a127 100644 --- a/elliptic-curve/src/secret_key/pkcs8.rs +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -68,36 +68,28 @@ where .into()); } - let secret_key_field = decoder.octet_string()?; - let secret_key = Self::from_bytes(secret_key_field).map_err(|_| { + let secret_key = Self::from_bytes(decoder.octet_string()?).map_err(|_| { der::Error::from(der::ErrorKind::Value { tag: der::Tag::Sequence, }) })?; let public_key_field = decoder.any()?; + public_key_field .tag() .assert_eq(der::Tag::ContextSpecific1)?; - let mut public_key_decoder = der::Decoder::new(public_key_field.as_bytes()); - let public_key_bitstring = public_key_decoder.bit_string()?.as_bytes(); + let public_key_bytes = der::Decoder::new(public_key_field.as_bytes()).bit_string()?; - // Look for a leading `0x00` byte in the bitstring - if public_key_bitstring.get(0).cloned() != Some(0x00) { + // TODO(tarcieri): validate public key matches secret key + if sec1::EncodedPoint::::from_bytes(public_key_bytes.as_ref()).is_err() { return Err(der::ErrorKind::Value { tag: der::Tag::BitString, } .into()); } - // TODO(tarcieri): add validations for public key - sec1::EncodedPoint::::from_bytes(&public_key_bitstring[1..]).map_err(|_| { - der::Error::from(der::ErrorKind::Value { - tag: der::Tag::BitString, - }) - })?; - Ok(secret_key) })?; @@ -125,10 +117,11 @@ where let mut secret_key_bytes = self.to_bytes(); let secret_key_field = der::OctetString::new(&secret_key_bytes).expect(ENCODING_ERROR_MSG); - let public_key_body = self.public_key().to_der_bitstring(); - let public_key_bytes = der::BitString::new(&public_key_body) + let public_key_body = self.public_key().to_encoded_point(false); + let public_key_bytes = der::BitString::new(public_key_body.as_ref()) .and_then(|bit_string| bit_string.to_vec()) .expect("DER encoding error"); + let public_key_field = der::Any::new(der::Tag::ContextSpecific1, &public_key_bytes).expect(ENCODING_ERROR_MSG); From 20ff729af0f1dcd9070b8c6a16e43627ab971dc8 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 11 Jan 2021 06:18:52 -0800 Subject: [PATCH 0367/1461] elliptic-curve: bump `hex-literal` to v0.3 (#464) --- Cargo.lock | 10 ++++++++-- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 99a335df6..01c40cea0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -162,7 +162,7 @@ dependencies = [ "ff", "generic-array 0.14.4", "group", - "hex-literal", + "hex-literal 0.3.1", "pkcs8", "rand_core", "subtle", @@ -256,6 +256,12 @@ dependencies = [ "proc-macro-hack", ] +[[package]] +name = "hex-literal" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5af1f635ef1bc545d78392b136bfe1c9809e029023c84a3638a864a10b8819c8" + [[package]] name = "hex-literal-impl" version = "0.2.2" @@ -340,7 +346,7 @@ name = "signature" version = "1.3.0" dependencies = [ "digest 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "hex-literal", + "hex-literal 0.2.1", "rand_core", "sha2", "signature_derive", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 0e91bdfc8..d78e19355 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -26,7 +26,7 @@ subtle = { version = "2.4", default-features = false } zeroize = { version = "1", optional = true, default-features = false } [dev-dependencies] -hex-literal = "0.2" +hex-literal = "0.3" [features] default = ["arithmetic"] From 6589fa3db21b51a25a0e59eb47f78d34dbe9c601 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 11 Jan 2021 09:28:52 -0800 Subject: [PATCH 0368/1461] password-hash: rename `PhfError` => `HasherError` (#465) The previous name is a holdover from the old trait name (`PasswordHashingFunction`) --- password-hash/src/errors.rs | 84 +++++++++++++++++----------------- password-hash/src/lib.rs | 8 ++-- password-hash/tests/hashing.rs | 6 +-- 3 files changed, 49 insertions(+), 49 deletions(-) diff --git a/password-hash/src/errors.rs b/password-hash/src/errors.rs index 8552fd57c..2ca30f4f6 100644 --- a/password-hash/src/errors.rs +++ b/password-hash/src/errors.rs @@ -80,6 +80,46 @@ impl From for HashError { #[cfg(feature = "std")] impl std::error::Error for HashError {} +/// Errors generating password hashes using a [`PasswordHasher`]. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum HasherError { + /// Unsupported algorithm. + Algorithm, + + /// Cryptographic error. + Crypto, + + /// Error generating output. + Output(OutputError), + + /// Invalid parameter. + Param, + + /// Invalid password. + Password, +} + +impl fmt::Display for HasherError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + match self { + Self::Algorithm => write!(f, "unsupported algorithm"), + Self::Crypto => write!(f, "cryptographic error"), + Self::Output(err) => write!(f, "PHF output error: {}", err), + Self::Param => write!(f, "invalid algorithm parameter"), + Self::Password => write!(f, "invalid password"), + } + } +} + +impl From for HasherError { + fn from(err: OutputError) -> HasherError { + HasherError::Output(err) + } +} + +#[cfg(feature = "std")] +impl std::error::Error for HasherError {} + /// Parameter-related errors. #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum ParamsError { @@ -142,46 +182,6 @@ impl fmt::Display for ParseError { #[cfg(feature = "std")] impl std::error::Error for ParseError {} -/// Errors generating password hashes using a [`PasswordHasher`]. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum PhfError { - /// Unsupported algorithm. - Algorithm, - - /// Cryptographic error. - Crypto, - - /// Error generating output. - Output(OutputError), - - /// Invalid parameter. - Param, - - /// Invalid password. - Password, -} - -impl fmt::Display for PhfError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - match self { - Self::Algorithm => write!(f, "unsupported algorithm"), - Self::Crypto => write!(f, "cryptographic error"), - Self::Output(err) => write!(f, "PHF output error: {}", err), - Self::Param => write!(f, "invalid algorithm parameter"), - Self::Password => write!(f, "invalid password"), - } - } -} - -impl From for PhfError { - fn from(err: OutputError) -> PhfError { - PhfError::Output(err) - } -} - -#[cfg(feature = "std")] -impl std::error::Error for PhfError {} - /// Password hash function output (i.e. hash/digest) errors. #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum OutputError { @@ -224,8 +224,8 @@ impl fmt::Display for VerifyError { } } -impl From for VerifyError { - fn from(_: PhfError) -> VerifyError { +impl From for VerifyError { + fn from(_: HasherError) -> VerifyError { VerifyError } } diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index 1ae297402..c2891d131 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -48,7 +48,7 @@ use core::{ }; pub use crate::{ - errors::{HashError, PhfError, VerifyError}, + errors::{HashError, HasherError, VerifyError}, ident::Ident, output::Output, params::Params, @@ -82,7 +82,7 @@ pub trait PasswordHasher { password: &[u8], salt: Salt<'a>, params: Params<'a>, - ) -> Result, PhfError>; + ) -> Result, HasherError>; /// Compute this password hashing function against the provided password /// using the parameters from the provided password hash and see if the @@ -117,7 +117,7 @@ pub trait McfHasher { /// /// MCF hashes are otherwise largely unstructured and parsed according to /// algorithm-specific rules so hashers must parse a raw string themselves. - fn upgrade_mcf_hash(hash: &str) -> Result, PhfError>; + fn upgrade_mcf_hash(hash: &str) -> Result, HasherError>; /// Verify a password hash in MCF format against the provided password. fn verify_mcf_hash(&self, password: &[u8], mcf_hash: &str) -> Result<(), VerifyError> @@ -275,7 +275,7 @@ impl<'a> PasswordHash<'a> { password: impl AsRef<[u8]>, salt: Salt<'a>, params: Params<'a>, - ) -> Result { + ) -> Result { phf.hash_password(None, password.as_ref(), salt, params) } diff --git a/password-hash/tests/hashing.rs b/password-hash/tests/hashing.rs index a90969235..51befbf9e 100644 --- a/password-hash/tests/hashing.rs +++ b/password-hash/tests/hashing.rs @@ -1,6 +1,6 @@ /// Password hashing tests pub use password_hash::{ - Ident, Output, Params, PasswordHash, PasswordHasher, PhfError, Salt, VerifyError, + HasherError, Ident, Output, Params, PasswordHash, PasswordHasher, Salt, VerifyError, }; const ALG: Ident = Ident::new("example"); @@ -15,12 +15,12 @@ impl PasswordHasher for StubFunction { password: &[u8], salt: Salt<'a>, params: Params<'a>, - ) -> Result, PhfError> { + ) -> Result, HasherError> { let mut output = Vec::new(); if let Some(alg) = algorithm { if alg != ALG { - return Err(PhfError::Algorithm); + return Err(HasherError::Algorithm); } } From 22a86e40d828c937a1d51cad5f6dc8fc4de332d0 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 11 Jan 2021 09:49:19 -0800 Subject: [PATCH 0369/1461] password-hash: remove negative decimal support (#466) Changes the `Decimal` type alias from `i32` to `u32`. If a particular algorithm actually needs to parse a negative value, it's still possible to parse it directly from a `ValueStr` (which this commit notes in the documentation). --- password-hash/src/params.rs | 42 ++++++++++++++++----------------- password-hash/src/value.rs | 33 ++++++++++---------------- password-hash/tests/encoding.rs | 8 +++---- 3 files changed, 38 insertions(+), 45 deletions(-) diff --git a/password-hash/src/params.rs b/password-hash/src/params.rs index bdb400f9d..34b5f8619 100644 --- a/password-hash/src/params.rs +++ b/password-hash/src/params.rs @@ -235,9 +235,9 @@ mod tests { #[test] fn add_chain() { let params = Params::new() - .add(Ident::new("a"), 1i32.into()) - .and_then(|p| p.add(Ident::new("b"), 2i32.into())) - .and_then(|p| p.add(Ident::new("c"), 3i32.into())) + .add(Ident::new("a"), 1u32.into()) + .and_then(|p| p.add(Ident::new("b"), 2u32.into())) + .and_then(|p| p.add(Ident::new("c"), 3u32.into())) .unwrap(); assert_eq!(params.len(), 3); @@ -249,17 +249,17 @@ mod tests { #[test] fn duplicate_names() { let name = Ident::new("a"); - let params = Params::new().add(name, 1i32.into()).unwrap(); - let err = params.add(name, 2i32.into()).err().unwrap(); + let params = Params::new().add(name, 1u32.into()).unwrap(); + let err = params.add(name, 2u32.into()).err().unwrap(); assert_eq!(err, ParamsError::DuplicateName); } #[test] fn from_slice() { let params = Params::from_slice(&[ - (Ident::new("a"), 1i32.into()), - (Ident::new("b"), 2i32.into()), - (Ident::new("c"), 3i32.into()), + (Ident::new("a"), 1u32.into()), + (Ident::new("b"), 2u32.into()), + (Ident::new("c"), 3u32.into()), ]) .unwrap(); @@ -273,9 +273,9 @@ mod tests { fn from_iterator() { let params = Params::from_iter( [ - (Ident::new("a"), 1i32.into()), - (Ident::new("b"), 2i32.into()), - (Ident::new("c"), 3i32.into()), + (Ident::new("a"), 1u32.into()), + (Ident::new("b"), 2u32.into()), + (Ident::new("c"), 3u32.into()), ] .iter() .cloned(), @@ -290,16 +290,16 @@ mod tests { #[test] fn iter() { let params = Params::from_slice(&[ - (Ident::new("a"), 1i32.into()), - (Ident::new("b"), 2i32.into()), - (Ident::new("c"), 3i32.into()), + (Ident::new("a"), 1u32.into()), + (Ident::new("b"), 2u32.into()), + (Ident::new("c"), 3u32.into()), ]) .unwrap(); let mut i = params.iter(); - assert_eq!(i.next(), Some(&(Ident::new("a"), 1i32.into()))); - assert_eq!(i.next(), Some(&(Ident::new("b"), 2i32.into()))); - assert_eq!(i.next(), Some(&(Ident::new("c"), 3i32.into()))); + assert_eq!(i.next(), Some(&(Ident::new("a"), 1u32.into()))); + assert_eq!(i.next(), Some(&(Ident::new("b"), 2u32.into()))); + assert_eq!(i.next(), Some(&(Ident::new("c"), 3u32.into()))); assert_eq!(i.next(), None); } @@ -343,7 +343,7 @@ mod tests { #[test] #[cfg(feature = "alloc")] fn display_one() { - let params = Params::from_slice(&[(Ident::new("a"), 1i32.into())]).unwrap(); + let params = Params::from_slice(&[(Ident::new("a"), 1u32.into())]).unwrap(); assert_eq!(params.to_string(), "a=1"); } @@ -351,9 +351,9 @@ mod tests { #[cfg(feature = "alloc")] fn display_many() { let params = Params::from_slice(&[ - (Ident::new("a"), 1i32.into()), - (Ident::new("b"), 2i32.into()), - (Ident::new("c"), 3i32.into()), + (Ident::new("a"), 1u32.into()), + (Ident::new("b"), 2u32.into()), + (Ident::new("c"), 3u32.into()), ]) .unwrap(); diff --git a/password-hash/src/value.rs b/password-hash/src/value.rs index 2b5520cc2..4fc438834 100644 --- a/password-hash/src/value.rs +++ b/password-hash/src/value.rs @@ -23,7 +23,7 @@ use core::{convert::TryFrom, fmt, str}; const MAX_LENGTH: usize = 48; /// Type used to represent decimal (i.e. integer) values. -pub type Decimal = i32; +pub type Decimal = u32; /// Algorithm parameter value. /// @@ -80,17 +80,6 @@ impl<'a> From for Value<'a> { } } -impl<'a> TryFrom for Value<'a> { - type Error = ParseError; - - fn try_from(decimal: u32) -> Result, ParseError> { - i32::try_from(decimal) - .ok() - .map(Into::into) - .ok_or(ParseError::TooLong) - } -} - impl<'a> TryFrom<&'a str> for Value<'a> { type Error = ParseError; @@ -206,7 +195,7 @@ impl<'a> ValueStr<'a> { /// > For an integer value x, its decimal encoding consist in the following: /// > /// > - If x < 0, then its decimal encoding is the minus sign - followed by the decimal - /// encoding of -x. + /// > encoding of -x. /// > - If x = 0, then its decimal encoding is the single character 0. /// > - If x > 0, then its decimal encoding is the smallest sequence of ASCII digits that /// > matches its value (i.e. there is no leading zero). @@ -216,11 +205,15 @@ impl<'a> ValueStr<'a> { /// > - The first character is either a - sign, or an ASCII digit. /// > - All characters other than the first are ASCII digits. /// > - If the first character is - sign, then there is at least another character, and the - /// second character is not a 0. + /// > second character is not a 0. /// > - If the string consists in more than one character, then the first one cannot be a 0. /// + /// Note: this implementation does not support negative decimals despite + /// them being allowed per the spec above. If you need to parse a negative + /// number, please parse it from the string representation directly e.g. + /// `value.as_str().parse::()` + /// /// [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#decimal-encoding - // TODO(tarcieri): support for negative decimal values (is there a use case?) pub fn decimal(&self) -> Result { let value = self.as_str(); @@ -323,7 +316,7 @@ mod tests { #[test] fn decimal_value() { - let valid_decimals = &[("0", 0i32), ("1", 1i32), ("2147483647", i32::MAX)]; + let valid_decimals = &[("0", 0u32), ("1", 1u32), ("4294967295", u32::MAX)]; for &(s, i) in valid_decimals { let value = ValueStr::new(s).unwrap(); @@ -335,21 +328,21 @@ mod tests { #[test] fn reject_decimal_with_leading_zero() { let value = ValueStr::new("01").unwrap(); - let err = i32::try_from(value).err().unwrap(); + let err = u32::try_from(value).err().unwrap(); assert!(matches!(err, ParseError::InvalidChar('0'))); } #[test] fn reject_overlong_decimal() { - let value = ValueStr::new("2147483648").unwrap(); - let err = i32::try_from(value).err().unwrap(); + let value = ValueStr::new("4294967296").unwrap(); + let err = u32::try_from(value).err().unwrap(); assert_eq!(err, ParseError::TooLong); } #[test] fn reject_negative() { let value = ValueStr::new("-1").unwrap(); - let err = i32::try_from(value).err().unwrap(); + let err = u32::try_from(value).err().unwrap(); assert!(matches!(err, ParseError::InvalidChar('-'))); } diff --git a/password-hash/tests/encoding.rs b/password-hash/tests/encoding.rs index 8467f2221..02b75d881 100644 --- a/password-hash/tests/encoding.rs +++ b/password-hash/tests/encoding.rs @@ -21,9 +21,9 @@ const EXAMPLE_HASH: &[u8] = &[ /// Example parameters fn example_params() -> Params { Params::from_slice(&[ - ("a".parse().unwrap(), 1i32.into()), - ("b".parse().unwrap(), 2i32.into()), - ("c".parse().unwrap(), 3i32.into()), + ("a".parse().unwrap(), 1u32.into()), + ("b".parse().unwrap(), 2u32.into()), + ("c".parse().unwrap(), 3u32.into()), ]) .unwrap() } @@ -73,7 +73,7 @@ fn salt() { #[test] fn one_param_and_salt() { - let params = Params::from_slice(&[("a".parse().unwrap(), 1i32.into())]).unwrap(); + let params = Params::from_slice(&[("a".parse().unwrap(), 1u32.into())]).unwrap(); let ph = PasswordHash { algorithm: EXAMPLE_ALGORITHM, From c6d8f09c4d6ac7fbe751bbfde8073cc86f87a87d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 11 Jan 2021 10:53:29 -0800 Subject: [PATCH 0370/1461] password-hash: add HasherError::Parse variant (#467) --- password-hash/src/errors.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/password-hash/src/errors.rs b/password-hash/src/errors.rs index 2ca30f4f6..fc052582d 100644 --- a/password-hash/src/errors.rs +++ b/password-hash/src/errors.rs @@ -95,6 +95,9 @@ pub enum HasherError { /// Invalid parameter. Param, + /// Parse error. + Parse(ParseError), + /// Invalid password. Password, } @@ -106,6 +109,7 @@ impl fmt::Display for HasherError { Self::Crypto => write!(f, "cryptographic error"), Self::Output(err) => write!(f, "PHF output error: {}", err), Self::Param => write!(f, "invalid algorithm parameter"), + Self::Parse(err) => write!(f, "{}", err), Self::Password => write!(f, "invalid password"), } } @@ -117,6 +121,12 @@ impl From for HasherError { } } +impl From for HasherError { + fn from(err: ParseError) -> HasherError { + HasherError::Parse(err) + } +} + #[cfg(feature = "std")] impl std::error::Error for HasherError {} From c2e7ffa744b3f55a9dd1d928646b3cf94b486366 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 11 Jan 2021 11:57:24 -0800 Subject: [PATCH 0371/1461] password-hash: add `Output::init_with` method (#468) Handles checking the output length against the allowed min/max lengths as well as allocating and slicing the array which `Output` wraps. --- password-hash/src/output.rs | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/password-hash/src/output.rs b/password-hash/src/output.rs index 3199f7615..d6cd7bb79 100644 --- a/password-hash/src/output.rs +++ b/password-hash/src/output.rs @@ -92,20 +92,35 @@ impl Output { /// Create a [`Output`] from the given byte slice, validating it according /// to [`Output::min_len`] and [`Output::max_len`] length restrictions. pub fn new(input: &[u8]) -> Result { - if input.len() < Self::min_len() { + Self::init_with(input.len(), |bytes| { + bytes.copy_from_slice(input); + Ok(()) + }) + } + + /// Initialize an [`Output`] using the provided method, which is given + /// a mutable byte slice into which it should write the output. + /// + /// The `output_size` (in bytes) must be known in advance, as well as at + /// least [`Output::min_len`] bytes and at most [`Output::max_len`] bytes. + pub fn init_with(output_size: usize, f: F) -> Result + where + F: FnOnce(&mut [u8]) -> Result<(), OutputError>, + { + if output_size < Self::min_len() { return Err(OutputError::TooShort); } - if input.len() > Self::max_len() { + if output_size > Self::max_len() { return Err(OutputError::TooLong); } let mut bytes = [0u8; MAX_LENGTH]; - bytes[..input.len()].copy_from_slice(input); + f(&mut bytes[..output_size])?; Ok(Self { bytes, - length: input.len() as u8, + length: output_size as u8, }) } From 6eac8605ae0276da26ac326df9e59a2a544d5ee2 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 11 Jan 2021 15:05:51 -0800 Subject: [PATCH 0372/1461] password-hash: remove `Deref` impl on `Output` (#469) The `Output` type now has some inherent methods, at which point a `Deref` impl generally stops making sense. This commit replaces it with an `as_bytes()` inherent method, as well as the previously existing `AsRef<[u8]>` impl. --- password-hash/src/output.rs | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/password-hash/src/output.rs b/password-hash/src/output.rs index d6cd7bb79..2acc7a137 100644 --- a/password-hash/src/output.rs +++ b/password-hash/src/output.rs @@ -1,7 +1,7 @@ //! Outputs from password hashing functions. use crate::{b64, errors::OutputError}; -use core::{cmp::PartialEq, convert::TryFrom, fmt, ops::Deref, str::FromStr}; +use core::{cmp::PartialEq, convert::TryFrom, fmt, str::FromStr}; /// Maximum length of password hash function outputs. const MAX_LENGTH: usize = 64; @@ -124,6 +124,16 @@ impl Output { }) } + /// Borrow the output value as a byte slice. + pub fn as_bytes(&self) -> &[u8] { + &self.bytes[..self.len()] + } + + /// Get the length of the output value as a byte slice. + pub fn len(&self) -> usize { + usize::from(self.length) + } + /// Parse [`b64`]-encoded [`Output`], i.e. using the PHC string /// specification's restricted interpretation of Base64. pub fn b64_decode(input: &str) -> Result { @@ -153,15 +163,7 @@ impl Output { impl AsRef<[u8]> for Output { fn as_ref(&self) -> &[u8] { - &self.bytes[..(self.length as usize)] - } -} - -impl Deref for Output { - type Target = [u8]; - - fn deref(&self) -> &[u8] { - self.as_ref() + self.as_bytes() } } @@ -179,6 +181,8 @@ impl PartialEq for Output { return false; } + // Non-short-circuiting comparison. + // See "Constant-time comparisons" documentation above. self.as_ref() .iter() .zip(other.as_ref().iter()) From 526494e147639d3b568bc489f3081ad57522c636 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 11 Jan 2021 15:46:23 -0800 Subject: [PATCH 0373/1461] password-hash: add HasherError::B64 variant (#470) Useful for reporting "B64" decoding errors, e.g. with salts --- password-hash/src/errors.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/password-hash/src/errors.rs b/password-hash/src/errors.rs index fc052582d..4cccfe7cf 100644 --- a/password-hash/src/errors.rs +++ b/password-hash/src/errors.rs @@ -86,6 +86,9 @@ pub enum HasherError { /// Unsupported algorithm. Algorithm, + /// "B64" encoding error. + B64(B64Error), + /// Cryptographic error. Crypto, @@ -106,6 +109,7 @@ impl fmt::Display for HasherError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { match self { Self::Algorithm => write!(f, "unsupported algorithm"), + Self::B64(err) => write!(f, "{}", err), Self::Crypto => write!(f, "cryptographic error"), Self::Output(err) => write!(f, "PHF output error: {}", err), Self::Param => write!(f, "invalid algorithm parameter"), @@ -115,6 +119,12 @@ impl fmt::Display for HasherError { } } +impl From for HasherError { + fn from(err: B64Error) -> HasherError { + HasherError::B64(err) + } +} + impl From for HasherError { fn from(err: OutputError) -> HasherError { HasherError::Output(err) From 6a32b15b062089595befb87aa9941b972075686a Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 11 Jan 2021 16:55:11 -0800 Subject: [PATCH 0374/1461] password-hash: have McfHasher::upgrade_mcf_hash take &self (#471) For consistency --- password-hash/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index c2891d131..edb05348e 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -117,14 +117,14 @@ pub trait McfHasher { /// /// MCF hashes are otherwise largely unstructured and parsed according to /// algorithm-specific rules so hashers must parse a raw string themselves. - fn upgrade_mcf_hash(hash: &str) -> Result, HasherError>; + fn upgrade_mcf_hash(&self, hash: &str) -> Result, HasherError>; /// Verify a password hash in MCF format against the provided password. fn verify_mcf_hash(&self, password: &[u8], mcf_hash: &str) -> Result<(), VerifyError> where Self: PasswordHasher, { - let phc_hash = Self::upgrade_mcf_hash(mcf_hash)?; + let phc_hash = self.upgrade_mcf_hash(mcf_hash)?; self.verify_password(password, &phc_hash) } } From a9efe295fa96eebe56f64c65070adcfe55973e44 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 11 Jan 2021 17:02:12 -0800 Subject: [PATCH 0375/1461] password-hash: reorder PasswordHasher::hash_password args (#472) Makes `password` the first argument, and have the others follow the order they appear in a password hash. --- password-hash/src/lib.rs | 8 ++++---- password-hash/tests/hashing.rs | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index edb05348e..2c3052e52 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -78,10 +78,10 @@ pub trait PasswordHasher { /// parameters for a given algorithm. fn hash_password<'a>( &self, - algorithm: Option>, password: &[u8], - salt: Salt<'a>, + algorithm: Option>, params: Params<'a>, + salt: Salt<'a>, ) -> Result, HasherError>; /// Compute this password hashing function against the provided password @@ -90,7 +90,7 @@ pub trait PasswordHasher { fn verify_password(&self, password: &[u8], hash: &PasswordHash<'_>) -> Result<(), VerifyError> { if let (Some(salt), Some(expected_output)) = (&hash.salt, &hash.hash) { let computed_hash = - self.hash_password(Some(hash.algorithm), password, *salt, hash.params.clone())?; + self.hash_password(password, Some(hash.algorithm), hash.params.clone(), *salt)?; if let Some(computed_output) = &computed_hash.hash { // See notes on `Output` about the use of a constant-time comparison @@ -276,7 +276,7 @@ impl<'a> PasswordHash<'a> { salt: Salt<'a>, params: Params<'a>, ) -> Result { - phf.hash_password(None, password.as_ref(), salt, params) + phf.hash_password(password.as_ref(), None, params, salt) } /// Verify this password hash using the specified set of supported diff --git a/password-hash/tests/hashing.rs b/password-hash/tests/hashing.rs index 51befbf9e..daf3bdd5b 100644 --- a/password-hash/tests/hashing.rs +++ b/password-hash/tests/hashing.rs @@ -11,10 +11,10 @@ pub struct StubFunction; impl PasswordHasher for StubFunction { fn hash_password<'a>( &self, - algorithm: Option>, password: &[u8], - salt: Salt<'a>, + algorithm: Option>, params: Params<'a>, + salt: Salt<'a>, ) -> Result, HasherError> { let mut output = Vec::new(); From 4cea65187144438e616f42e00d86ad8550d66280 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 11 Jan 2021 17:21:44 -0800 Subject: [PATCH 0376/1461] password-hash: add lifetime to McfHasher::upgrade_mcf_hash (#473) Allows the returned `PasswordHash<'a>` to reference data from the original MCF password hash. --- password-hash/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index 2c3052e52..77836dfae 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -117,7 +117,7 @@ pub trait McfHasher { /// /// MCF hashes are otherwise largely unstructured and parsed according to /// algorithm-specific rules so hashers must parse a raw string themselves. - fn upgrade_mcf_hash(&self, hash: &str) -> Result, HasherError>; + fn upgrade_mcf_hash<'a>(&self, hash: &'a str) -> Result, HasherError>; /// Verify a password hash in MCF format against the provided password. fn verify_mcf_hash(&self, password: &[u8], mcf_hash: &str) -> Result<(), VerifyError> From 450d3de854f1177d41fc2f0c1f0a24e16726cad1 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 12 Jan 2021 09:50:44 -0800 Subject: [PATCH 0377/1461] password-hash: use `b64ct` crate (#474) This crate is an extraction of the previous `b64` module into its own crate for reusability: https://github.com/RustCrypto/utils/pull/200 --- Cargo.lock | 9 + password-hash/Cargo.toml | 7 +- password-hash/src/b64.rs | 323 ------------------------------------ password-hash/src/errors.rs | 41 +---- password-hash/src/lib.rs | 6 +- password-hash/src/salt.rs | 7 +- password-hash/src/value.rs | 7 +- 7 files changed, 28 insertions(+), 372 deletions(-) delete mode 100644 password-hash/src/b64.rs diff --git a/Cargo.lock b/Cargo.lock index 01c40cea0..14c302bdb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -39,6 +39,12 @@ dependencies = [ "syn", ] +[[package]] +name = "b64ct" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a293adc36d315fd3f03a3c4a5594b0a30be4678cbae95ce9b430e9b8d6e34032" + [[package]] name = "bitvec" version = "0.20.1" @@ -280,6 +286,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "password-hash" version = "0.0.0" +dependencies = [ + "b64ct", +] [[package]] name = "pkcs8" diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index 046912f69..03a837c4b 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -15,6 +15,9 @@ repository = "https://github.com/RustCrypto/traits/tree/master/password-hash" categories = ["cryptography", "no-std"] keywords = ["crypt", "mcf", "password", "pbkdf", "phc"] +[dependencies] +b64ct = "0.1" + [features] -alloc = [] -std = ["alloc"] +alloc = ["b64ct/alloc"] +std = ["alloc", "b64ct/std"] diff --git a/password-hash/src/b64.rs b/password-hash/src/b64.rs deleted file mode 100644 index b10674567..000000000 --- a/password-hash/src/b64.rs +++ /dev/null @@ -1,323 +0,0 @@ -//! "B64" encoding. -//! -//! Subset of the standard Base64 encoding (RFC 4648, section 4) which omits -//! padding (`=`) as well as extra whitespace, as described in the PHC string -//! format specification: -//! -//! -//! -//! Supports the Base64 character subset: `[A-Z]`, `[a-z]`, `[0-9]`, `+`, `/` -//! -//! Adapted from the following constant-time C++ implementation of Base64: -//! -//! -//! -//! Copyright (c) 2014 Steve "Sc00bz" Thomas (steve at tobtu dot com). -//! Derived code is dual licensed MIT + Apache 2 (with permission from Sc00bz). - -use crate::errors::B64Error; -use core::str; - -#[cfg(feature = "alloc")] -use alloc::{string::String, vec::Vec}; - -/// Error message to use when performing encoding operations which we expect -/// will never fail, i.e. the message passed to `expect()`. -const ENCODING_ERROR: &str = "B64 encoding error"; - -/// Encode the input byte slice as "B64", writing the result into the provided -/// destination slice, and returning an ASCII-encoded string value. -pub fn encode<'a>(src: &[u8], dst: &'a mut [u8]) -> Result<&'a str, B64Error> { - if encoded_len(src) > dst.len() { - return Err(B64Error::LengthInvalid); - } - - let mut src_offset: usize = 0; - let mut dst_offset: usize = 0; - let mut src_length: usize = src.len(); - - while src_length >= 3 { - encode_3bytes( - &src[src_offset..(src_offset + 3)], - &mut dst[dst_offset..(dst_offset + 4)], - ); - - src_offset += 3; - dst_offset += 4; - src_length -= 3; - } - - if src_length > 0 { - let remaining = &src[src_offset..(src_offset + src_length)]; - let mut tmp_in = [0u8; 3]; - tmp_in[..src_length].copy_from_slice(remaining); - - let mut tmp_out = [0u8; 4]; - encode_3bytes(&tmp_in, &mut tmp_out); - - let len = encoded_len(remaining); - dst[dst_offset..(dst_offset + len)].copy_from_slice(&tmp_out[..len]); - dst_offset += len; - } - - Ok(str::from_utf8(&dst[..dst_offset]).expect(ENCODING_ERROR)) -} - -/// Encode the input byte slice as a "B64"-encoded [`String`]. -#[cfg(feature = "alloc")] -#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] -pub fn encode_string(input: &[u8]) -> String { - let expected_len = encoded_len(input); - let mut output = vec![0u8; expected_len]; - let actual_len = encode(input, &mut output).expect(ENCODING_ERROR).len(); - debug_assert_eq!(expected_len, actual_len); - String::from_utf8(output).expect(ENCODING_ERROR) -} - -/// Get the "B64"-encoded length of the given byte slice. -pub const fn encoded_len(bytes: &[u8]) -> usize { - let q = bytes.len() * 4; - let r = q % 3; - (q / 3) + (r != 0) as usize -} - -/// "B64" decode the given source byte slice into the provided destination -/// buffer. -pub fn decode<'a>(src: &str, dst: &'a mut [u8]) -> Result<&'a [u8], B64Error> { - if decoded_len(src) > dst.len() { - return Err(B64Error::LengthInvalid); - } - - let src = src.as_bytes(); - - if !src.is_empty() && char::from(src[src.len() - 1]).is_whitespace() { - return Err(B64Error::TrailingWhitespace); - } - - let mut src_offset: usize = 0; - let mut dst_offset: usize = 0; - let mut src_length: usize = src.len(); - let mut err: isize = 0; - - while src_length > 4 { - err |= decode_3bytes( - &src[src_offset..(src_offset + 4)], - &mut dst[dst_offset..(dst_offset + 3)], - ); - src_offset += 4; - dst_offset += 3; - src_length -= 4; - } - - if src_length > 0 { - let mut i = 0; - let mut tmp_out = [0u8; 3]; - let mut tmp_in = [b'A'; 4]; - - while i < src_length { - tmp_in[i] = src[src_offset + i]; - i += 1; - } - - if i < 2 { - err = 1; - } - - src_length = i - 1; - err |= decode_3bytes(&tmp_in, &mut tmp_out); - dst[dst_offset..(dst_offset + src_length)].copy_from_slice(&tmp_out[..src_length]); - dst_offset += i - 1; - } - - if err == 0 { - Ok(&dst[..dst_offset]) - } else { - Err(B64Error::EncodingInvalid) - } -} - -/// Decode a "B64"-encoded string into a byte vector. -#[cfg(feature = "alloc")] -#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] -pub fn decode_vec(input: &str) -> Result, B64Error> { - let expected_len = decoded_len(input); - let mut output = vec![0u8; expected_len]; - let actual_len = decode(input, &mut output)?.len(); - debug_assert_eq!(expected_len, actual_len); - Ok(output) -} - -/// Get the length of the output from decoding the provided "B64"-encoded input. -pub const fn decoded_len(bytes: &str) -> usize { - (bytes.len() * 3) / 4 -} - -// B64 character set: -// [A-Z] [a-z] [0-9] + / -// 0x41-0x5a, 0x61-0x7a, 0x30-0x39, 0x2b, 0x2f - -#[inline] -fn encode_3bytes(src: &[u8], dst: &mut [u8]) { - debug_assert_eq!(src.len(), 3); - debug_assert!(dst.len() >= 4, "dst too short: {}", dst.len()); - - let b0 = src[0] as isize; - let b1 = src[1] as isize; - let b2 = src[2] as isize; - - dst[0] = encode_6bits(b0 >> 2); - dst[1] = encode_6bits(((b0 << 4) | (b1 >> 4)) & 63); - dst[2] = encode_6bits(((b1 << 2) | (b2 >> 6)) & 63); - dst[3] = encode_6bits(b2 & 63); -} - -#[inline] -fn encode_6bits(src: isize) -> u8 { - let mut diff = 0x41isize; - - // if (in > 25) diff += 0x61 - 0x41 - 26; // 6 - diff += ((25isize - src) >> 8) & 6; - - // if (in > 51) diff += 0x30 - 0x61 - 26; // -75 - diff -= ((51isize - src) >> 8) & 75; - - // if (in > 61) diff += 0x2b - 0x30 - 10; // -15 - diff -= ((61isize - src) >> 8) & 15; - - // if (in > 62) diff += 0x2f - 0x2b - 1; // 3 - diff += ((62isize - src) >> 8) & 3; - - (src + diff) as u8 -} - -#[inline] -fn decode_3bytes(src: &[u8], dst: &mut [u8]) -> isize { - debug_assert_eq!(src.len(), 4); - debug_assert!(dst.len() >= 3, "dst too short: {}", dst.len()); - - let c0 = decode_6bits(src[0]); - let c1 = decode_6bits(src[1]); - let c2 = decode_6bits(src[2]); - let c3 = decode_6bits(src[3]); - - dst[0] = ((c0 << 2) | (c1 >> 4)) as u8; - dst[1] = ((c1 << 4) | (c2 >> 2)) as u8; - dst[2] = ((c2 << 6) | c3) as u8; - - ((c0 | c1 | c2 | c3) >> 8) & 1 -} - -#[inline] -fn decode_6bits(src: u8) -> isize { - let ch = src as isize; - let mut ret: isize = -1; - - // if (ch > 0x40 && ch < 0x5b) ret += ch - 0x41 + 1; // -64 - ret += (((64isize - ch) & (ch - 91isize)) >> 8) & (ch - 64isize); - - // if (ch > 0x60 && ch < 0x7b) ret += ch - 0x61 + 26 + 1; // -70 - ret += (((96isize - ch) & (ch - 123isize)) >> 8) & (ch - 70isize); - - // if (ch > 0x2f && ch < 0x3a) ret += ch - 0x30 + 52 + 1; // 5 - ret += (((47isize - ch) & (ch - 58isize)) >> 8) & (ch + 5isize); - - // if (ch == 0x2b) ret += 62 + 1; - ret += (((42isize - ch) & (ch - 44isize)) >> 8) & 63; - - // if (ch == 0x2f) ret += 63 + 1; - ret + ((((46isize - ch) & (ch - 48isize)) >> 8) & 64) -} - -#[cfg(test)] -mod tests { - use super::*; - - /// "B64" test vector - struct TestVector { - /// Raw bytes. - raw: &'static [u8], - - /// "B64" encoded. - b64: &'static str, - } - - const TEST_VECTORS: &[TestVector] = &[ - TestVector { raw: b"", b64: "" }, - TestVector { - raw: b"\0", - b64: "AA", - }, - TestVector { - raw: b"***", - b64: "Kioq", - }, - TestVector { - raw: b"\x01\x02\x03\x04", - b64: "AQIDBA", - }, - TestVector { - raw: b"\xAD\xAD\xAD\xAD\xAD", - b64: "ra2tra0", - }, - TestVector { - raw: b"\xFF\xFF\xFF\xFF\xFF", - b64: "//////8", - }, - TestVector { - raw: b"\x40\xC1\x3F\xBD\x05\x4C\x72\x2A\xA3\xC2\xF2\x11\x73\xC0\x69\xEA\ - \x49\x7D\x35\x29\x6B\xCC\x24\x65\xF6\xF9\xD0\x41\x08\x7B\xD7\xA9", - b64: "QME/vQVMciqjwvIRc8Bp6kl9NSlrzCRl9vnQQQh716k", - }, - ]; - - #[test] - fn encode_test_vectors() { - let mut buf = [0u8; 1024]; - - for vector in TEST_VECTORS { - let out = encode(vector.raw, &mut buf).unwrap(); - assert_eq!(encoded_len(vector.raw), vector.b64.len()); - assert_eq!(vector.b64, &out[..]); - } - } - - #[test] - fn decode_test_vectors() { - let mut buf = [0u8; 1024]; - - for vector in TEST_VECTORS { - let out = decode(vector.b64, &mut buf).unwrap(); - assert_eq!(decoded_len(vector.b64), out.len()); - assert_eq!(vector.raw, &out[..]); - } - } - - #[test] - fn encode_and_decode_various_lengths() { - let data = [b'X'; 64]; - let mut inbuf = [0u8; 1024]; - let mut outbuf = [0u8; 1024]; - - for i in 0..data.len() { - let encoded = encode(&data[..i], &mut inbuf).unwrap(); - - // Make sure it round trips - let decoded = decode(encoded, &mut outbuf).unwrap(); - assert_eq!(decoded, &data[..i]); - } - } - - #[test] - fn reject_trailing_equals() { - let input = "QME/vQVMciqjwvIRc8Bp6kl9NSlrzCRl9vnQQQh716k="; - let mut buf = [0u8; 1024]; - assert_eq!(decode(input, &mut buf), Err(B64Error::EncodingInvalid)); - } - - #[test] - fn reject_trailing_whitespace() { - let input = "QME/vQVMciqjwvIRc8Bp6kl9NSlrzCRl9vnQQQh716k\n"; - let mut buf = [0u8; 1024]; - assert_eq!(decode(input, &mut buf), Err(B64Error::TrailingWhitespace)); - } -} diff --git a/password-hash/src/errors.rs b/password-hash/src/errors.rs index 4cccfe7cf..dddc96ed3 100644 --- a/password-hash/src/errors.rs +++ b/password-hash/src/errors.rs @@ -1,38 +1,11 @@ //! Error types. +use crate::b64; use core::fmt; #[cfg(docsrs)] use crate::PasswordHasher; -/// "B64" encoding errors. -/// -/// -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum B64Error { - /// Encoding error. - EncodingInvalid, - - /// Invalid length. - LengthInvalid, - - /// Trailing whitespace characters. - TrailingWhitespace, -} - -impl fmt::Display for B64Error { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - match self { - Self::EncodingInvalid => f.write_str("invalid B64 encoding"), - Self::LengthInvalid => f.write_str("B64 encoded data has invalid length"), - Self::TrailingWhitespace => f.write_str("B64 encoded data has trailing whitespace"), - } - } -} - -#[cfg(feature = "std")] -impl std::error::Error for B64Error {} - /// Password hash errors. #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum HashError { @@ -87,7 +60,7 @@ pub enum HasherError { Algorithm, /// "B64" encoding error. - B64(B64Error), + B64(b64::Error), /// Cryptographic error. Crypto, @@ -119,8 +92,8 @@ impl fmt::Display for HasherError { } } -impl From for HasherError { - fn from(err: B64Error) -> HasherError { +impl From for HasherError { + fn from(err: b64::Error) -> HasherError { HasherError::B64(err) } } @@ -206,7 +179,7 @@ impl std::error::Error for ParseError {} #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum OutputError { /// "B64" encoding error. - B64(B64Error), + B64(b64::Error), /// Output too short (min 10-bytes). TooShort, @@ -225,8 +198,8 @@ impl fmt::Display for OutputError { } } -impl From for OutputError { - fn from(err: B64Error) -> OutputError { +impl From for OutputError { + fn from(err: b64::Error) -> OutputError { OutputError::B64(err) } } diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index 77836dfae..d786137c0 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -35,8 +35,7 @@ #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] -#[cfg(feature = "alloc")] -#[macro_use] +#[cfg(all(feature = "alloc", test))] extern crate alloc; #[cfg(feature = "std")] @@ -56,7 +55,8 @@ pub use crate::{ value::{Decimal, Value, ValueStr}, }; -pub mod b64; +pub use b64ct as b64; + pub mod errors; mod ident; diff --git a/password-hash/src/salt.rs b/password-hash/src/salt.rs index 520c7fa80..ca0a0f13b 100644 --- a/password-hash/src/salt.rs +++ b/password-hash/src/salt.rs @@ -1,9 +1,6 @@ //! Salt string support. -use crate::{ - errors::{B64Error, ParseError}, - ValueStr, -}; +use crate::{b64, errors::ParseError, ValueStr}; use core::{ convert::{TryFrom, TryInto}, fmt, str, @@ -117,7 +114,7 @@ impl<'a> Salt<'a> { /// buffer containing the decoded result on success. /// /// [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#argon2-encoding - pub fn b64_decode<'b>(&self, buf: &'b mut [u8]) -> Result<&'b [u8], B64Error> { + pub fn b64_decode<'b>(&self, buf: &'b mut [u8]) -> Result<&'b [u8], b64::Error> { self.0.b64_decode(buf) } diff --git a/password-hash/src/value.rs b/password-hash/src/value.rs index 4fc438834..8e9114f4c 100644 --- a/password-hash/src/value.rs +++ b/password-hash/src/value.rs @@ -13,10 +13,7 @@ //! //! [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md -use crate::{ - b64, - errors::{B64Error, ParseError}, -}; +use crate::{b64, errors::ParseError}; use core::{convert::TryFrom, fmt, str}; /// Maximum size of a parameter value in ASCII characters. @@ -162,7 +159,7 @@ impl<'a> ValueStr<'a> { /// PHC string format specification. /// /// [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#argon2-encoding - pub fn b64_decode<'b>(&self, buf: &'b mut [u8]) -> Result<&'b [u8], B64Error> { + pub fn b64_decode<'b>(&self, buf: &'b mut [u8]) -> Result<&'b [u8], b64::Error> { b64::decode(self.as_str(), buf) } From ba9272e1f353296da4fdb14e24a5e85580f61a34 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 13 Jan 2021 07:48:15 -0800 Subject: [PATCH 0378/1461] elliptic-curve: simplify ECDH trait bounds (#475) Closes #417 Removes all SEC1 encoding-related concerns from the ECDH API, which are a legacy from when there wasn't a `PublicKey` type. Replaces them with a `SharedSecret: From<&AffinePoint>` bound which is intended to be satisfied by a curve-specific conversion. --- elliptic-curve/src/ecdh.rs | 92 +++++++++++++------------------------- 1 file changed, 32 insertions(+), 60 deletions(-) diff --git a/elliptic-curve/src/ecdh.rs b/elliptic-curve/src/ecdh.rs index 248015fcc..ca54775dd 100644 --- a/elliptic-curve/src/ecdh.rs +++ b/elliptic-curve/src/ecdh.rs @@ -27,16 +27,11 @@ //! [SIGMA]: https://webee.technion.ac.il/~hugo/sigma-pdf.pdf use crate::{ - consts::U1, - public_key::PublicKey, - scalar::NonZeroScalar, - sec1::{EncodedPoint, ToEncodedPoint, UncompressedPointSize, UntaggedPointSize}, - weierstrass::Curve, - AffinePoint, FieldBytes, ProjectiveArithmetic, ProjectivePoint, Scalar, + public_key::PublicKey, scalar::NonZeroScalar, weierstrass::Curve, AffinePoint, FieldBytes, + ProjectiveArithmetic, ProjectivePoint, Scalar, }; -use core::{borrow::Borrow, fmt::Debug, ops::Add}; +use core::{borrow::Borrow, fmt::Debug}; use ff::PrimeField; -use generic_array::ArrayLength; use group::Curve as _; use rand_core::{CryptoRng, RngCore}; use zeroize::Zeroize; @@ -68,18 +63,15 @@ pub fn diffie_hellman( where C: Curve + ProjectiveArithmetic, Scalar: PrimeField> + Clone + Zeroize, - AffinePoint: Copy + Clone + Debug + ToEncodedPoint + Zeroize, + AffinePoint: Copy + Clone + Debug + Zeroize, ProjectivePoint: From>, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + SharedSecret: for<'a> From<&'a AffinePoint>, { - let shared_secret = - ProjectivePoint::::from(*public_key.borrow()) * secret_key.borrow().as_ref(); - - // SharedSecret::new expects an uncompressed point - // TODO(tarcieri): avoid point encoding when computing shared secret - // See: - SharedSecret::new(shared_secret.to_affine().to_encoded_point(false)) + let public_point = ProjectivePoint::::from(*public_key.borrow()); + let mut secret_point = (public_point * secret_key.borrow().as_ref()).to_affine(); + let shared_secret = SharedSecret::from(&secret_point); + secret_point.zeroize(); + shared_secret } /// Ephemeral Diffie-Hellman Secret. @@ -115,10 +107,9 @@ impl EphemeralSecret where C: Curve + ProjectiveArithmetic, Scalar: PrimeField> + Clone + Zeroize, - AffinePoint: Copy + Clone + Debug + ToEncodedPoint + Zeroize, + AffinePoint: Copy + Clone + Debug + Zeroize, ProjectivePoint: From>, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + SharedSecret: for<'a> From<&'a AffinePoint>, { /// Generate a cryptographically random [`EphemeralSecret`]. pub fn random(rng: impl CryptoRng + RngCore) -> Self { @@ -145,10 +136,9 @@ impl From<&EphemeralSecret> for PublicKey where C: Curve + ProjectiveArithmetic, Scalar: PrimeField> + Clone + Zeroize, - AffinePoint: Copy + Clone + Debug + ToEncodedPoint + Zeroize, + AffinePoint: Copy + Clone + Debug + Zeroize, ProjectivePoint: From>, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + SharedSecret: for<'a> From<&'a AffinePoint>, { fn from(ephemeral_secret: &EphemeralSecret) -> Self { ephemeral_secret.public_key() @@ -188,36 +178,14 @@ where /// /// Instead, the resulting value should be used as input to a Key Derivation /// Function (KDF) or cryptographic hash function to produce a symmetric key. -// TODO(tarcieri): avoid SEC1 point encoding when computing shared secret -// See: -pub struct SharedSecret -where - C: Curve + ProjectiveArithmetic, - Scalar: PrimeField>, -{ +// TODO(tarcieri): KDF traits and support for deriving uniform keys +// See: https://github.com/RustCrypto/traits/issues/5 +pub struct SharedSecret { /// Computed secret value secret_bytes: FieldBytes, } -impl SharedSecret -where - C: Curve + ProjectiveArithmetic, - Scalar: PrimeField>, - AffinePoint: Zeroize, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, -{ - /// Create a new shared secret from the given uncompressed curve point - fn new(mut encoded_point: EncodedPoint) -> Self { - let secret_bytes = encoded_point - .x() - .cloned() - .expect("encoded point is identity"); - - encoded_point.zeroize(); - Self { secret_bytes } - } - +impl SharedSecret { /// Shared secret value, serialized as bytes. /// /// As noted in the comments for this struct, this value is non-uniform and @@ -229,21 +197,25 @@ where } } -impl Zeroize for SharedSecret -where - C: Curve + ProjectiveArithmetic, - Scalar: PrimeField>, -{ +impl From> for SharedSecret { + /// NOTE: this impl is intended to be used by curve implementations to + /// instantiate a [`SharedSecret`] value from their respective + /// [`AffinePoint`] type. + /// + /// Curve implementations should provide the field element representing + /// the affine x-coordinate as `secret_bytes`. + fn from(secret_bytes: FieldBytes) -> Self { + Self { secret_bytes } + } +} + +impl Zeroize for SharedSecret { fn zeroize(&mut self) { self.secret_bytes.zeroize() } } -impl Drop for SharedSecret -where - C: Curve + ProjectiveArithmetic, - Scalar: PrimeField>, -{ +impl Drop for SharedSecret { fn drop(&mut self) { self.zeroize(); } From cd0a0aef3d480458ae21901316e4acbff77f574a Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Wed, 13 Jan 2021 23:19:57 +0300 Subject: [PATCH 0379/1461] Add deps.rs badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5dd0f5f44..0e6f8ec20 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# RustCrypto: Traits ![Rust Version][rustc-image] [![Project Chat][chat-image]][chat-link] +# RustCrypto: Traits ![Rust Version][rustc-image] [![Project Chat][chat-image]][chat-link] [![dependency status](https://deps.rs/repo/github/RustCrypto/traits/status.svg)](https://deps.rs/repo/github/RustCrypto/traits) Collection of traits which describe functionality of cryptographic primitives. From e3d8fe0fbd3d6c39bc476278a3f2455068a2113b Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Wed, 13 Jan 2021 23:58:37 +0300 Subject: [PATCH 0380/1461] Compactify deps.rs badge --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0e6f8ec20..0e7b80b00 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# RustCrypto: Traits ![Rust Version][rustc-image] [![Project Chat][chat-image]][chat-link] [![dependency status](https://deps.rs/repo/github/RustCrypto/traits/status.svg)](https://deps.rs/repo/github/RustCrypto/traits) +# RustCrypto: Traits ![Rust Version][rustc-image] [![Project Chat][chat-image]][chat-link] [![dependency status][deps-image]][deps] Collection of traits which describe functionality of cryptographic primitives. @@ -48,6 +48,8 @@ dual licensed as above, without any additional terms or conditions. [rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/ +[deps-image]: https://deps.rs/repo/github/RustCrypto/traits/status.svg +[deps]: https://deps.rs/repo/github/RustCrypto/traits [//]: # (crates) From d26072e596652c4b1f82dd8f07f4225a07b745c7 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 15 Jan 2021 11:05:40 -0800 Subject: [PATCH 0381/1461] password-hash: add associated Params type to PasswordHasher (#476) Adds an associated type for algorithm parameters, then handles automatically converting to them when using higher-level APIs. --- password-hash/src/lib.rs | 70 ++++++++++++++++++++++----------- password-hash/src/params.rs | 44 ++++++++++----------- password-hash/tests/encoding.rs | 12 +++--- password-hash/tests/hashing.rs | 44 ++++++++++++++++----- 4 files changed, 108 insertions(+), 62 deletions(-) diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index d786137c0..be5b70a47 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -41,35 +41,41 @@ extern crate alloc; #[cfg(feature = "std")] extern crate std; -use core::{ - convert::{TryFrom, TryInto}, - fmt, -}; +pub mod errors; + +mod ident; +mod output; +mod params; +mod salt; +mod value; pub use crate::{ errors::{HashError, HasherError, VerifyError}, ident::Ident, output::Output, - params::Params, + params::ParamsBuf, salt::Salt, value::{Decimal, Value, ValueStr}, }; pub use b64ct as b64; -pub mod errors; - -mod ident; -mod output; -mod params; -mod salt; -mod value; +use core::{ + convert::{TryFrom, TryInto}, + fmt::{self, Debug}, +}; /// Separator character used in password hashes (e.g. `$6$...`). const PASSWORD_HASH_SEPARATOR: char = '$'; /// Trait for password hashing functions. pub trait PasswordHasher { + /// Algorithm-specific parameters. + type Params: Clone + + Debug + + for<'a> TryFrom<&'a ParamsBuf<'a>, Error = HasherError> + + for<'a> TryInto, Error = HasherError>; + /// Compute a [`PasswordHash`] with the given algorithm [`Ident`] /// (or `None` for the recommended default), password, salt, and optional /// [`Params`]. @@ -80,17 +86,34 @@ pub trait PasswordHasher { &self, password: &[u8], algorithm: Option>, - params: Params<'a>, + params: Self::Params, salt: Salt<'a>, ) -> Result, HasherError>; +} +/// Trait for password verification. +/// +/// Automatically impl'd for any type that impls [`PasswordHasher`]. +/// +/// This trait is object safe and can be used to implement abstractions over +/// multiple password hashing algorithms. One such abstraction is provided by +/// the [`PasswordHash::verify_password`] method. +pub trait PasswordVerifier { /// Compute this password hashing function against the provided password /// using the parameters from the provided password hash and see if the /// computed output matches. + fn verify_password(&self, password: &[u8], hash: &PasswordHash<'_>) -> Result<(), VerifyError>; +} + +impl PasswordVerifier for T { fn verify_password(&self, password: &[u8], hash: &PasswordHash<'_>) -> Result<(), VerifyError> { if let (Some(salt), Some(expected_output)) = (&hash.salt, &hash.hash) { - let computed_hash = - self.hash_password(password, Some(hash.algorithm), hash.params.clone(), *salt)?; + let computed_hash = self.hash_password( + password, + Some(hash.algorithm), + T::Params::try_from(&hash.params)?, + *salt, + )?; if let Some(computed_output) = &computed_hash.hash { // See notes on `Output` about the use of a constant-time comparison @@ -122,10 +145,9 @@ pub trait McfHasher { /// Verify a password hash in MCF format against the provided password. fn verify_mcf_hash(&self, password: &[u8], mcf_hash: &str) -> Result<(), VerifyError> where - Self: PasswordHasher, + Self: PasswordVerifier, { - let phc_hash = self.upgrade_mcf_hash(mcf_hash)?; - self.verify_password(password, &phc_hash) + self.verify_password(password, &self.upgrade_mcf_hash(mcf_hash)?) } } @@ -183,7 +205,7 @@ pub struct PasswordHash<'a> { /// /// This corresponds to the set of `$=(,=)*` /// name/value pairs in a PHC string. - pub params: Params<'a>, + pub params: ParamsBuf<'a>, /// [`Salt`] string for personalizing a password hash output. /// @@ -218,7 +240,7 @@ impl<'a> PasswordHash<'a> { .and_then(Ident::try_from)?; let mut version = None; - let mut params = Params::new(); + let mut params = ParamsBuf::new(); let mut salt = None; let mut hash = None; @@ -239,7 +261,7 @@ impl<'a> PasswordHash<'a> { if let Some(field) = next_field { // = if field.contains(params::PAIR_DELIMITER) { - params = Params::try_from(field)?; + params = ParamsBuf::try_from(field)?; next_field = None; } } @@ -274,16 +296,16 @@ impl<'a> PasswordHash<'a> { phf: impl PasswordHasher, password: impl AsRef<[u8]>, salt: Salt<'a>, - params: Params<'a>, + params: &ParamsBuf<'a>, ) -> Result { - phf.hash_password(password.as_ref(), None, params, salt) + phf.hash_password(password.as_ref(), None, params.try_into()?, salt) } /// Verify this password hash using the specified set of supported /// [`PasswordHasher`] trait objects. pub fn verify_password( &self, - phfs: &[&dyn PasswordHasher], + phfs: &[&dyn PasswordVerifier], password: impl AsRef<[u8]>, ) -> Result<(), VerifyError> { for &phf in phfs { diff --git a/password-hash/src/params.rs b/password-hash/src/params.rs index 34b5f8619..2f488c17d 100644 --- a/password-hash/src/params.rs +++ b/password-hash/src/params.rs @@ -39,14 +39,14 @@ const MAX_LENGTH: usize = 8; /// /// [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#specification #[derive(Clone, Default, Eq, PartialEq)] -pub struct Params<'a> { +pub struct ParamsBuf<'a> { /// Name/value pairs. /// /// Name (i.e. the [`Ident`]) *MUST* be unique. pairs: [Option>; MAX_LENGTH], } -impl<'a> Params<'a> { +impl<'a> ParamsBuf<'a> { /// Create new empty [`Params`]. pub fn new() -> Self { Self::default() @@ -119,13 +119,13 @@ impl<'a> Params<'a> { } } -impl<'a> FromIterator> for Params<'a> { +impl<'a> FromIterator> for ParamsBuf<'a> { fn from_iter(iter: I) -> Self where I: IntoIterator>, { iter.into_iter() - .fold(Params::new(), |params, (name, value)| { + .fold(ParamsBuf::new(), |params, (name, value)| { params.add(name, value).expect("error adding param") }) } @@ -133,11 +133,11 @@ impl<'a> FromIterator> for Params<'a> { // Note: this uses `TryFrom` instead of `FromStr` to support a lifetime on // the `str` the value is being parsed from. -impl<'a> TryFrom<&'a str> for Params<'a> { +impl<'a> TryFrom<&'a str> for ParamsBuf<'a> { type Error = ParamsError; fn try_from(input: &'a str) -> Result { - let mut params = Params::new(); + let mut params = ParamsBuf::new(); if input.is_empty() { return Ok(params); @@ -166,7 +166,7 @@ impl<'a> TryFrom<&'a str> for Params<'a> { } } -impl<'a> Index> for Params<'a> { +impl<'a> Index> for ParamsBuf<'a> { type Output = Value<'a>; fn index(&self, name: Ident<'a>) -> &Value<'a> { @@ -175,7 +175,7 @@ impl<'a> Index> for Params<'a> { } } -impl<'a> Index<&'a str> for Params<'a> { +impl<'a> Index<&'a str> for ParamsBuf<'a> { type Output = Value<'a>; fn index(&self, name: &'a str) -> &Value<'a> { @@ -183,7 +183,7 @@ impl<'a> Index<&'a str> for Params<'a> { } } -impl<'a> fmt::Display for Params<'a> { +impl<'a> fmt::Display for ParamsBuf<'a> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let n = self.len(); @@ -199,7 +199,7 @@ impl<'a> fmt::Display for Params<'a> { } } -impl<'a> fmt::Debug for Params<'a> { +impl<'a> fmt::Debug for ParamsBuf<'a> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_map() .entries( @@ -230,11 +230,11 @@ mod tests { use alloc::string::ToString; use core::convert::TryFrom; - use super::{FromIterator, Ident, Params, ParamsError}; + use super::{FromIterator, Ident, ParamsBuf, ParamsError}; #[test] fn add_chain() { - let params = Params::new() + let params = ParamsBuf::new() .add(Ident::new("a"), 1u32.into()) .and_then(|p| p.add(Ident::new("b"), 2u32.into())) .and_then(|p| p.add(Ident::new("c"), 3u32.into())) @@ -249,14 +249,14 @@ mod tests { #[test] fn duplicate_names() { let name = Ident::new("a"); - let params = Params::new().add(name, 1u32.into()).unwrap(); + let params = ParamsBuf::new().add(name, 1u32.into()).unwrap(); let err = params.add(name, 2u32.into()).err().unwrap(); assert_eq!(err, ParamsError::DuplicateName); } #[test] fn from_slice() { - let params = Params::from_slice(&[ + let params = ParamsBuf::from_slice(&[ (Ident::new("a"), 1u32.into()), (Ident::new("b"), 2u32.into()), (Ident::new("c"), 3u32.into()), @@ -271,7 +271,7 @@ mod tests { #[test] fn from_iterator() { - let params = Params::from_iter( + let params = ParamsBuf::from_iter( [ (Ident::new("a"), 1u32.into()), (Ident::new("b"), 2u32.into()), @@ -289,7 +289,7 @@ mod tests { #[test] fn iter() { - let params = Params::from_slice(&[ + let params = ParamsBuf::from_slice(&[ (Ident::new("a"), 1u32.into()), (Ident::new("b"), 2u32.into()), (Ident::new("c"), 3u32.into()), @@ -309,20 +309,20 @@ mod tests { #[test] fn parse_empty() { - let params = Params::try_from("").unwrap(); + let params = ParamsBuf::try_from("").unwrap(); assert!(params.is_empty()); } #[test] fn parse_one() { - let params = Params::try_from("a=1").unwrap(); + let params = ParamsBuf::try_from("a=1").unwrap(); assert_eq!(params.len(), 1); assert_eq!(params["a"].decimal().unwrap(), 1); } #[test] fn parse_many() { - let params = Params::try_from("a=1,b=2,c=3").unwrap(); + let params = ParamsBuf::try_from("a=1,b=2,c=3").unwrap(); assert_eq!(params.len(), 3); assert_eq!(params["a"].decimal().unwrap(), 1); assert_eq!(params["b"].decimal().unwrap(), 2); @@ -336,21 +336,21 @@ mod tests { #[test] #[cfg(feature = "alloc")] fn display_empty() { - let params = Params::new(); + let params = ParamsBuf::new(); assert_eq!(params.to_string(), ""); } #[test] #[cfg(feature = "alloc")] fn display_one() { - let params = Params::from_slice(&[(Ident::new("a"), 1u32.into())]).unwrap(); + let params = ParamsBuf::from_slice(&[(Ident::new("a"), 1u32.into())]).unwrap(); assert_eq!(params.to_string(), "a=1"); } #[test] #[cfg(feature = "alloc")] fn display_many() { - let params = Params::from_slice(&[ + let params = ParamsBuf::from_slice(&[ (Ident::new("a"), 1u32.into()), (Ident::new("b"), 2u32.into()), (Ident::new("c"), 3u32.into()), diff --git a/password-hash/tests/encoding.rs b/password-hash/tests/encoding.rs index 02b75d881..10d7bafba 100644 --- a/password-hash/tests/encoding.rs +++ b/password-hash/tests/encoding.rs @@ -7,7 +7,7 @@ #![cfg(feature = "registry")] use core::convert::TryInto; -use password_hash::{algorithm::argon2, Algorithm, Params, PasswordHash}; +use password_hash::{algorithm::argon2, Algorithm, ParamsBuf, PasswordHash}; const EXAMPLE_ALGORITHM: Algorithm = Algorithm::Argon2(argon2::Variant::D); const EXAMPLE_SALT: &[u8] = &[ @@ -19,8 +19,8 @@ const EXAMPLE_HASH: &[u8] = &[ ]; /// Example parameters -fn example_params() -> Params { - Params::from_slice(&[ +fn example_params() -> ParamsBuf { + ParamsBuf::from_slice(&[ ("a".parse().unwrap(), 1u32.into()), ("b".parse().unwrap(), 2u32.into()), ("c".parse().unwrap(), 3u32.into()), @@ -59,7 +59,7 @@ fn params() { fn salt() { let ph = PasswordHash { algorithm: EXAMPLE_ALGORITHM, - params: Params::new(), + params: ParamsBuf::new(), salt: Some(EXAMPLE_SALT.try_into().unwrap()), hash: None, }; @@ -73,7 +73,7 @@ fn salt() { #[test] fn one_param_and_salt() { - let params = Params::from_slice(&[("a".parse().unwrap(), 1u32.into())]).unwrap(); + let params = ParamsBuf::from_slice(&[("a".parse().unwrap(), 1u32.into())]).unwrap(); let ph = PasswordHash { algorithm: EXAMPLE_ALGORITHM, @@ -109,7 +109,7 @@ fn params_and_salt() { fn salt_and_hash() { let ph = PasswordHash { algorithm: EXAMPLE_ALGORITHM, - params: Params::default(), + params: ParamsBuf::default(), salt: Some(EXAMPLE_SALT.try_into().unwrap()), hash: Some(EXAMPLE_HASH.try_into().unwrap()), }; diff --git a/password-hash/tests/hashing.rs b/password-hash/tests/hashing.rs index daf3bdd5b..ae53a52e3 100644 --- a/password-hash/tests/hashing.rs +++ b/password-hash/tests/hashing.rs @@ -1,19 +1,23 @@ -/// Password hashing tests +//! Password hashing tests + pub use password_hash::{ - HasherError, Ident, Output, Params, PasswordHash, PasswordHasher, Salt, VerifyError, + HasherError, Ident, Output, ParamsBuf, PasswordHash, PasswordHasher, Salt, VerifyError, }; +use std::convert::{TryFrom, TryInto}; const ALG: Ident = Ident::new("example"); /// Stub password hashing function for testing. -pub struct StubFunction; +pub struct StubPasswordHasher; + +impl PasswordHasher for StubPasswordHasher { + type Params = StubParams; -impl PasswordHasher for StubFunction { fn hash_password<'a>( &self, password: &[u8], algorithm: Option>, - params: Params<'a>, + params: StubParams, salt: Salt<'a>, ) -> Result, HasherError> { let mut output = Vec::new(); @@ -33,19 +37,39 @@ impl PasswordHasher for StubFunction { Ok(PasswordHash { algorithm: ALG, version: None, - params, + params: params.try_into()?, salt: Some(salt), hash: Some(hash), }) } } +/// Stub parameters +#[derive(Clone, Debug)] +pub struct StubParams; + +impl<'a> TryFrom<&'a ParamsBuf<'a>> for StubParams { + type Error = HasherError; + + fn try_from(_: &'a ParamsBuf<'a>) -> Result { + Ok(Self) + } +} + +impl<'a> TryFrom for ParamsBuf<'a> { + type Error = HasherError; + + fn try_from(_: StubParams) -> Result { + Ok(Self::default()) + } +} + #[test] fn verify_password_hash() { let valid_password = "test password"; let salt = Salt::new("test-salt").unwrap(); - let params = Params::new(); - let hash = PasswordHash::generate(StubFunction, valid_password, salt, params.clone()).unwrap(); + let params = ParamsBuf::new(); + let hash = PasswordHash::generate(StubPasswordHasher, valid_password, salt, ¶ms).unwrap(); // Sanity tests for StubFunction impl above assert_eq!(hash.algorithm, ALG); @@ -54,12 +78,12 @@ fn verify_password_hash() { // Tests for generic password verification logic assert_eq!( - hash.verify_password(&[&StubFunction], valid_password), + hash.verify_password(&[&StubPasswordHasher], valid_password), Ok(()) ); assert_eq!( - hash.verify_password(&[&StubFunction], "wrong password"), + hash.verify_password(&[&StubPasswordHasher], "wrong password"), Err(VerifyError) ); } From 8c0ead96042eda8dd3031ebb7224965163d0e0f3 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 16 Jan 2021 07:47:23 -0800 Subject: [PATCH 0382/1461] password-hash: ParamsString refactor (#477) Replaces a structured type with a builder for params strings which can also parse the in-place via an iterator. The previous implementation had a size of 320(!) bytes despite the fact all of the string data was borrowed. It's considerably more efficient to have a buffer type that can build the parameter string which is internally stored as a byte array. The new implementation uses a 127-byte array with a 1-byte length for a struct which is a total of 128-bytes. This length was picked in part by adding headroom to a maximally long Argon2 params string, which looks roughly like this: m=4294967296,t=4294967296,keyid=XXXXXXXXXXX,data=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX This string contains all Argon2 parameters at maximum length which comes to a total of 92-bytes, which means 127 provides 35 bytes of headroom. The implementation is written in such a way that it should be easy to swap out a `String` for backing storage when the `alloc` feature is enabled, if it turns out the 128-byte size is suboptimal. --- password-hash/src/errors.rs | 18 +- password-hash/src/lib.rs | 28 +- password-hash/src/params.rs | 436 ++++++++++++++++------------ password-hash/src/salt.rs | 6 +- password-hash/src/value.rs | 127 ++------ password-hash/tests/encoding.rs | 12 +- password-hash/tests/hashing.rs | 12 +- password-hash/tests/test_vectors.rs | 8 +- 8 files changed, 314 insertions(+), 333 deletions(-) diff --git a/password-hash/src/errors.rs b/password-hash/src/errors.rs index dddc96ed3..993b92837 100644 --- a/password-hash/src/errors.rs +++ b/password-hash/src/errors.rs @@ -69,7 +69,7 @@ pub enum HasherError { Output(OutputError), /// Invalid parameter. - Param, + Params(ParamsError), /// Parse error. Parse(ParseError), @@ -85,7 +85,7 @@ impl fmt::Display for HasherError { Self::B64(err) => write!(f, "{}", err), Self::Crypto => write!(f, "cryptographic error"), Self::Output(err) => write!(f, "PHF output error: {}", err), - Self::Param => write!(f, "invalid algorithm parameter"), + Self::Params(err) => write!(f, "{}", err), Self::Parse(err) => write!(f, "{}", err), Self::Password => write!(f, "invalid password"), } @@ -104,6 +104,12 @@ impl From for HasherError { } } +impl From for HasherError { + fn from(err: ParamsError) -> HasherError { + HasherError::Params(err) + } +} + impl From for HasherError { fn from(err: ParseError) -> HasherError { HasherError::Parse(err) @@ -119,6 +125,12 @@ pub enum ParamsError { /// Duplicate parameter name encountered. DuplicateName, + /// Invalid parameter name. + InvalidName, + + /// Invalid parameter value. + InvalidValue, + /// Maximum number of parameters exceeded. MaxExceeded, @@ -130,6 +142,8 @@ impl fmt::Display for ParamsError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { match self { Self::DuplicateName => f.write_str("duplicate parameter"), + Self::InvalidName => f.write_str("invalid parameter name"), + Self::InvalidValue => f.write_str("invalid parameter value"), Self::MaxExceeded => f.write_str("maximum number of parameters reached"), Self::Parse(err) => write!(f, "{}", err), } diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index be5b70a47..99d1e48ca 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -53,9 +53,9 @@ pub use crate::{ errors::{HashError, HasherError, VerifyError}, ident::Ident, output::Output, - params::ParamsBuf, + params::ParamsString, salt::Salt, - value::{Decimal, Value, ValueStr}, + value::{Decimal, Value}, }; pub use b64ct as b64; @@ -73,15 +73,13 @@ pub trait PasswordHasher { /// Algorithm-specific parameters. type Params: Clone + Debug - + for<'a> TryFrom<&'a ParamsBuf<'a>, Error = HasherError> - + for<'a> TryInto, Error = HasherError>; + + Default + + for<'a> TryFrom<&'a ParamsString, Error = HasherError> + + for<'a> TryInto; /// Compute a [`PasswordHash`] with the given algorithm [`Ident`] - /// (or `None` for the recommended default), password, salt, and optional - /// [`Params`]. - /// - /// Use [`Params::new`] or [`Params::default`] to use the default - /// parameters for a given algorithm. + /// (or `None` for the recommended default), password, salt, and + /// parameters. fn hash_password<'a>( &self, password: &[u8], @@ -201,11 +199,11 @@ pub struct PasswordHash<'a> { /// See: pub version: Option, - /// Algorithm-specific [`Params`]. + /// Algorithm-specific parameters. /// /// This corresponds to the set of `$=(,=)*` /// name/value pairs in a PHC string. - pub params: ParamsBuf<'a>, + pub params: ParamsString, /// [`Salt`] string for personalizing a password hash output. /// @@ -240,7 +238,7 @@ impl<'a> PasswordHash<'a> { .and_then(Ident::try_from)?; let mut version = None; - let mut params = ParamsBuf::new(); + let mut params = ParamsString::new(); let mut salt = None; let mut hash = None; @@ -249,7 +247,7 @@ impl<'a> PasswordHash<'a> { if let Some(field) = next_field { // v= if field.starts_with("v=") && !field.contains(params::PARAMS_DELIMITER) { - version = Some(ValueStr::new(&field[2..]).and_then(|value| value.decimal())?); + version = Some(Value::new(&field[2..]).and_then(|value| value.decimal())?); next_field = None; } } @@ -261,7 +259,7 @@ impl<'a> PasswordHash<'a> { if let Some(field) = next_field { // = if field.contains(params::PAIR_DELIMITER) { - params = ParamsBuf::try_from(field)?; + params = field.parse()?; next_field = None; } } @@ -296,7 +294,7 @@ impl<'a> PasswordHash<'a> { phf: impl PasswordHasher, password: impl AsRef<[u8]>, salt: Salt<'a>, - params: &ParamsBuf<'a>, + params: &ParamsString, ) -> Result { phf.hash_password(password.as_ref(), None, params.try_into()?, salt) } diff --git a/password-hash/src/params.rs b/password-hash/src/params.rs index 2f488c17d..07db0f70d 100644 --- a/password-hash/src/params.rs +++ b/password-hash/src/params.rs @@ -2,15 +2,14 @@ use crate::{ errors::{ParamsError, ParseError}, - value::Value, + value::{Decimal, Value}, Ident, }; use core::{ convert::{TryFrom, TryInto}, - fmt, + fmt::{self, Write}, iter::FromIterator, - ops::Index, - slice, + str::{self, FromStr}, }; /// Individual parameter name/value pair. @@ -23,9 +22,13 @@ pub(crate) const PAIR_DELIMITER: char = '='; pub(crate) const PARAMS_DELIMITER: char = ','; /// Maximum number of supported parameters. -const MAX_LENGTH: usize = 8; +const MAX_LENGTH: usize = 127; -/// Algorithm parameters. +/// Error message used with `expect` for when internal invariants are violated +/// (i.e. the contents of a [`ParamsString`] should always be valid) +const INVARIANT_VIOLATED_MSG: &str = "PHC params invariant violated"; + +/// Algorithm parameter string. /// /// The [PHC string format specification][1] defines a set of optional /// algorithm-specific name/value pairs which can be encoded into a @@ -39,267 +42,320 @@ const MAX_LENGTH: usize = 8; /// /// [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#specification #[derive(Clone, Default, Eq, PartialEq)] -pub struct ParamsBuf<'a> { - /// Name/value pairs. - /// - /// Name (i.e. the [`Ident`]) *MUST* be unique. - pairs: [Option>; MAX_LENGTH], -} +pub struct ParamsString(Buffer); -impl<'a> ParamsBuf<'a> { - /// Create new empty [`Params`]. +impl ParamsString { + /// Create new empty [`ParamsString`]. pub fn new() -> Self { Self::default() } - /// Instantiate [`Params`] from a slice of name/value pairs. - pub fn from_slice(pairs: &[Pair<'a>]) -> Result { - let mut result = Self::default(); + /// Add a key/value pair with a string value to the [`ParamsString`]. + pub fn add_str<'a>( + &mut self, + name: impl TryInto>, + value: impl TryInto>, + ) -> Result<(), ParamsError> { + let name = name.try_into().map_err(|_| ParamsError::InvalidName)?; + let value = value.try_into().map_err(|_| ParamsError::InvalidValue)?; + self.add(name, value) + } - for (name, value) in pairs.iter().cloned() { - result = result.add(name, value)?; - } + /// Add a key/value pair with a decimal value to the [`ParamsString`]. + pub fn add_decimal<'a>( + &mut self, + name: impl TryInto>, + value: Decimal, + ) -> Result<(), ParamsError> { + let name = name.try_into().map_err(|_| ParamsError::InvalidName)?; + self.add(name, value) + } - Ok(result) - } - - /// Add another pair to the [`Params`]. - pub fn add(mut self, name: Ident<'a>, value: Value<'a>) -> Result { - for entry in &mut self.pairs { - match entry { - Some((n, _)) => { - // If slot is occupied, ensure the name isn't a duplicate - if *n == name { - // TODO(tarcieri): make idempotent? (i.e. ignore dupes if the value is the same) - return Err(ParamsError::DuplicateName); - } - } - None => { - // Use free slot if available - *entry = Some((name, value)); - return Ok(self); - } - } - } + /// Borrow the contents of this [`ParamsString`] as a byte slice. + pub fn as_bytes(&self) -> &[u8] { + self.as_str().as_bytes() + } - Err(ParamsError::MaxExceeded) + /// Borrow the contents of this [`ParamsString`] as a `str`. + pub fn as_str(&self) -> &str { + self.0.as_ref() } - /// Get a parameter value by name. - pub fn get(&self, name: Ident<'a>) -> Option<&Value<'a>> { - for entry in &self.pairs { - match entry { - Some((n, v)) => { - if *n == name { - return Some(v); - } - } - None => return None, - } - } + /// Get the count of the number ASCII characters in this [`ParamsString`]. + pub fn len(&self) -> usize { + self.as_str().len() + } - None + /// Is this set of parameters empty? + pub fn is_empty(&self) -> bool { + self.len() == 0 } /// Iterate over the parameters. - pub fn iter(&self) -> Iter<'a, '_> { - Iter { - inner: self.pairs.iter(), + pub fn iter(&self) -> Iter<'_> { + Iter::new(self.as_str()) + } + + /// Get a parameter [`Value`] by name. + pub fn get<'a>(&self, name: impl TryInto>) -> Option> { + let name = name.try_into().ok()?; + + for (n, v) in self.iter() { + if name == n { + return Some(v); + } } + + None } - /// Get the count of the number of parameters. - pub fn len(&self) -> usize { - self.iter().count() + /// Get a parameter as a `str`. + pub fn get_str<'a>(&self, name: impl TryInto>) -> Option<&str> { + self.get(name).map(|value| value.as_str()) } - /// Is this set of parameters empty? - pub fn is_empty(&self) -> bool { - self.len() == 0 + /// Get a parameter as a [`Decimal`]. + /// + /// See [`Value::decimal`] for format information. + pub fn get_decimal<'a>(&self, name: impl TryInto>) -> Option { + self.get(name).and_then(|value| value.decimal().ok()) } -} -impl<'a> FromIterator> for ParamsBuf<'a> { - fn from_iter(iter: I) -> Self - where - I: IntoIterator>, - { - iter.into_iter() - .fold(ParamsBuf::new(), |params, (name, value)| { - params.add(name, value).expect("error adding param") - }) + /// Add a value to this [`ParamsString`] using the provided callback. + fn add(&mut self, name: Ident<'_>, value: impl fmt::Display) -> Result<(), ParamsError> { + if self.get(name).is_some() { + return Err(ParamsError::DuplicateName); + } + + let orig_len = self.0.length; + + if !self.is_empty() { + self.0 + .write_char(PARAMS_DELIMITER) + .map_err(|_| ParamsError::MaxExceeded)? + } + + if write!(self.0, "{}={}", name, value).is_err() { + self.0.length = orig_len; + return Err(ParamsError::MaxExceeded); + } + + Ok(()) } } -// Note: this uses `TryFrom` instead of `FromStr` to support a lifetime on -// the `str` the value is being parsed from. -impl<'a> TryFrom<&'a str> for ParamsBuf<'a> { - type Error = ParamsError; +impl FromStr for ParamsString { + type Err = ParamsError; - fn try_from(input: &'a str) -> Result { - let mut params = ParamsBuf::new(); + fn from_str(s: &str) -> Result { + if s.as_bytes().len() > MAX_LENGTH { + return Err(ParamsError::MaxExceeded); + } - if input.is_empty() { - return Ok(params); + if s.is_empty() { + return Ok(ParamsString::new()); } - for mut param in input - .split(PARAMS_DELIMITER) - .map(|p| p.split(PAIR_DELIMITER)) - { - let name = param + // Validate the string is well-formed + for mut param in s.split(PARAMS_DELIMITER).map(|p| p.split(PAIR_DELIMITER)) { + // Validate name + param .next() - .ok_or(ParseError::InvalidChar(PAIR_DELIMITER))?; + .ok_or(ParseError::InvalidChar(PAIR_DELIMITER)) + .and_then(Ident::try_from)?; - let value = param + // Validate value + param .next() - .ok_or(ParseError::InvalidChar(PAIR_DELIMITER))?; + .ok_or(ParseError::InvalidChar(PAIR_DELIMITER)) + .and_then(Value::try_from)?; if param.next().is_some() { return Err(ParseError::TooLong.into()); } - - params = params.add(name.try_into()?, value.try_into()?)?; } - Ok(params) + let mut bytes = [0u8; MAX_LENGTH]; + bytes[..s.as_bytes().len()].copy_from_slice(s.as_bytes()); + + Ok(Self(Buffer { + bytes, + length: s.as_bytes().len() as u8, + })) } } -impl<'a> Index> for ParamsBuf<'a> { - type Output = Value<'a>; +impl<'a> FromIterator> for ParamsString { + fn from_iter(iter: I) -> Self + where + I: IntoIterator>, + { + let mut params = ParamsString::new(); - fn index(&self, name: Ident<'a>) -> &Value<'a> { - self.get(name) - .unwrap_or_else(|| panic!("no parameter with name `{}`", name)) + for pair in iter { + params.add_str(pair.0, pair.1).expect("PHC params error"); + } + + params } } -impl<'a> Index<&'a str> for ParamsBuf<'a> { - type Output = Value<'a>; - - fn index(&self, name: &'a str) -> &Value<'a> { - &self[Ident::try_from(name).expect("invalid parameter name")] +impl fmt::Display for ParamsString { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.as_str()) } } -impl<'a> fmt::Display for ParamsBuf<'a> { +impl fmt::Debug for ParamsString { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let n = self.len(); + f.debug_map().entries(self.iter()).finish() + } +} - for (i, (name, value)) in self.iter().enumerate() { - write!(f, "{}{}{}", name, PAIR_DELIMITER, value)?; +/// Iterator over algorithm parameters stored in a [`ParamsString`] struct. +pub struct Iter<'a> { + inner: Option>, +} - if i + 1 != n { - write!(f, "{}", PARAMS_DELIMITER)?; +impl<'a> Iter<'a> { + /// Create a new [`Iter`]. + fn new(s: &'a str) -> Self { + if s.is_empty() { + Self { inner: None } + } else { + Self { + inner: Some(s.split(PARAMS_DELIMITER)), } } + } +} - Ok(()) +impl<'a> Iterator for Iter<'a> { + type Item = Pair<'a>; + + fn next(&mut self) -> Option> { + let mut param = self.inner.as_mut()?.next()?.split(PAIR_DELIMITER); + let name = Ident::new(param.next().expect(INVARIANT_VIOLATED_MSG)); + let value = Value::try_from(param.next().expect(INVARIANT_VIOLATED_MSG)) + .expect(INVARIANT_VIOLATED_MSG); + + debug_assert_eq!(param.next(), None); + Some((name, value)) } } -impl<'a> fmt::Debug for ParamsBuf<'a> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_map() - .entries( - self.iter() - .map(|&(ref name, ref value)| (name.as_str(), value)), - ) - .finish() +/// Parameter buffer. +#[derive(Clone, Debug, Eq)] +struct Buffer { + /// Byte array containing an ASCII-encoded string. + bytes: [u8; MAX_LENGTH], + + /// Length of the string in ASCII characters (i.e. bytes). + length: u8, +} + +impl AsRef for Buffer { + fn as_ref(&self) -> &str { + str::from_utf8(&self.bytes[..(self.length as usize)]).expect(INVARIANT_VIOLATED_MSG) } } -/// Iterator over algorithm parameters stored in a [`Params`] struct. -pub struct Iter<'a, 'b> { - /// Inner slice iterator this newtype wrapper is built upon. - inner: slice::Iter<'b, Option>>, +impl Default for Buffer { + fn default() -> Buffer { + Buffer { + bytes: [0u8; MAX_LENGTH], + length: 0, + } + } +} + +impl PartialEq for Buffer { + fn eq(&self, other: &Self) -> bool { + // Ensure comparisons always honor the initialized portion of the buffer + self.as_ref().eq(other.as_ref()) + } } -impl<'a, 'b> Iterator for Iter<'a, 'b> { - type Item = &'b Pair<'a>; +impl Write for Buffer { + fn write_str(&mut self, input: &str) -> fmt::Result { + let bytes = input.as_bytes(); + let length = self.length as usize; - fn next(&mut self) -> Option<&'b Pair<'a>> { - self.inner.next()?.as_ref() + if length + bytes.len() > MAX_LENGTH { + return Err(fmt::Error); + } + + self.bytes[length..(length + bytes.len())].copy_from_slice(bytes); + self.length += bytes.len() as u8; + + Ok(()) } } #[cfg(test)] mod tests { + use super::{FromIterator, Ident, ParamsError, ParamsString, Value}; + #[cfg(feature = "alloc")] use alloc::string::ToString; - use core::convert::TryFrom; - - use super::{FromIterator, Ident, ParamsBuf, ParamsError}; + use core::{convert::TryFrom, str::FromStr}; #[test] - fn add_chain() { - let params = ParamsBuf::new() - .add(Ident::new("a"), 1u32.into()) - .and_then(|p| p.add(Ident::new("b"), 2u32.into())) - .and_then(|p| p.add(Ident::new("c"), 3u32.into())) - .unwrap(); - - assert_eq!(params.len(), 3); - assert_eq!(params["a"].decimal().unwrap(), 1); - assert_eq!(params["b"].decimal().unwrap(), 2); - assert_eq!(params["c"].decimal().unwrap(), 3); + fn add() { + let mut params = ParamsString::new(); + params.add_str("a", "1").unwrap(); + params.add_decimal("b", 2).unwrap(); + params.add_str("c", "3").unwrap(); + + assert_eq!(params.iter().count(), 3); + assert_eq!(params.get_decimal("a").unwrap(), 1); + assert_eq!(params.get_decimal("b").unwrap(), 2); + assert_eq!(params.get_decimal("c").unwrap(), 3); } #[test] fn duplicate_names() { let name = Ident::new("a"); - let params = ParamsBuf::new().add(name, 1u32.into()).unwrap(); - let err = params.add(name, 2u32.into()).err().unwrap(); - assert_eq!(err, ParamsError::DuplicateName); - } - - #[test] - fn from_slice() { - let params = ParamsBuf::from_slice(&[ - (Ident::new("a"), 1u32.into()), - (Ident::new("b"), 2u32.into()), - (Ident::new("c"), 3u32.into()), - ]) - .unwrap(); + let mut params = ParamsString::new(); + params.add_decimal(name, 1).unwrap(); - assert_eq!(params.len(), 3); - assert_eq!(params["a"].decimal().unwrap(), 1); - assert_eq!(params["b"].decimal().unwrap(), 2); - assert_eq!(params["c"].decimal().unwrap(), 3); + let err = params.add_decimal(name, 2u32.into()).err().unwrap(); + assert_eq!(err, ParamsError::DuplicateName); } #[test] - fn from_iterator() { - let params = ParamsBuf::from_iter( + fn from_iter() { + let params = ParamsString::from_iter( [ - (Ident::new("a"), 1u32.into()), - (Ident::new("b"), 2u32.into()), - (Ident::new("c"), 3u32.into()), + (Ident::new("a"), Value::try_from("1").unwrap()), + (Ident::new("b"), Value::try_from("2").unwrap()), + (Ident::new("c"), Value::try_from("3").unwrap()), ] .iter() .cloned(), ); - assert_eq!(params.len(), 3); - assert_eq!(params["a"].decimal().unwrap(), 1); - assert_eq!(params["b"].decimal().unwrap(), 2); - assert_eq!(params["c"].decimal().unwrap(), 3); + assert_eq!(params.iter().count(), 3); + assert_eq!(params.get_decimal("a").unwrap(), 1); + assert_eq!(params.get_decimal("b").unwrap(), 2); + assert_eq!(params.get_decimal("c").unwrap(), 3); } #[test] fn iter() { - let params = ParamsBuf::from_slice(&[ - (Ident::new("a"), 1u32.into()), - (Ident::new("b"), 2u32.into()), - (Ident::new("c"), 3u32.into()), - ]) - .unwrap(); + let mut params = ParamsString::new(); + params.add_str("a", "1").unwrap(); + params.add_str("b", "2").unwrap(); + params.add_str("c", "3").unwrap(); let mut i = params.iter(); - assert_eq!(i.next(), Some(&(Ident::new("a"), 1u32.into()))); - assert_eq!(i.next(), Some(&(Ident::new("b"), 2u32.into()))); - assert_eq!(i.next(), Some(&(Ident::new("c"), 3u32.into()))); + + for (name, value) in &[("a", "1"), ("b", "2"), ("c", "3")] { + let name = Ident::new(name); + let value = Value::try_from(*value).unwrap(); + assert_eq!(i.next(), Some((name, value))); + } + assert_eq!(i.next(), None); } @@ -309,24 +365,24 @@ mod tests { #[test] fn parse_empty() { - let params = ParamsBuf::try_from("").unwrap(); + let params = ParamsString::from_str("").unwrap(); assert!(params.is_empty()); } #[test] fn parse_one() { - let params = ParamsBuf::try_from("a=1").unwrap(); - assert_eq!(params.len(), 1); - assert_eq!(params["a"].decimal().unwrap(), 1); + let params = ParamsString::from_str("a=1").unwrap(); + assert_eq!(params.iter().count(), 1); + assert_eq!(params.get("a").unwrap().decimal().unwrap(), 1); } #[test] fn parse_many() { - let params = ParamsBuf::try_from("a=1,b=2,c=3").unwrap(); - assert_eq!(params.len(), 3); - assert_eq!(params["a"].decimal().unwrap(), 1); - assert_eq!(params["b"].decimal().unwrap(), 2); - assert_eq!(params["c"].decimal().unwrap(), 3); + let params = ParamsString::from_str("a=1,b=2,c=3").unwrap(); + assert_eq!(params.iter().count(), 3); + assert_eq!(params.get_decimal("a").unwrap(), 1); + assert_eq!(params.get_decimal("b").unwrap(), 2); + assert_eq!(params.get_decimal("c").unwrap(), 3); } // @@ -336,27 +392,21 @@ mod tests { #[test] #[cfg(feature = "alloc")] fn display_empty() { - let params = ParamsBuf::new(); + let params = ParamsString::new(); assert_eq!(params.to_string(), ""); } #[test] #[cfg(feature = "alloc")] fn display_one() { - let params = ParamsBuf::from_slice(&[(Ident::new("a"), 1u32.into())]).unwrap(); + let params = ParamsString::from_str("a=1").unwrap(); assert_eq!(params.to_string(), "a=1"); } #[test] #[cfg(feature = "alloc")] fn display_many() { - let params = ParamsBuf::from_slice(&[ - (Ident::new("a"), 1u32.into()), - (Ident::new("b"), 2u32.into()), - (Ident::new("c"), 3u32.into()), - ]) - .unwrap(); - + let params = ParamsString::from_str("a=1,b=2,c=3").unwrap(); assert_eq!(params.to_string(), "a=1,b=2,c=3"); } } diff --git a/password-hash/src/salt.rs b/password-hash/src/salt.rs index ca0a0f13b..a1a617440 100644 --- a/password-hash/src/salt.rs +++ b/password-hash/src/salt.rs @@ -1,6 +1,6 @@ //! Salt string support. -use crate::{b64, errors::ParseError, ValueStr}; +use crate::{b64, errors::ParseError, Value}; use core::{ convert::{TryFrom, TryInto}, fmt, str, @@ -71,7 +71,7 @@ use core::{ /// [2]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#function-duties /// [3]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#argon2-encoding #[derive(Copy, Clone, Eq, PartialEq)] -pub struct Salt<'a>(ValueStr<'a>); +pub struct Salt<'a>(Value<'a>); impl<'a> Salt<'a> { /// Minimum length of a [`Salt`] string: 2-bytes. @@ -86,7 +86,7 @@ impl<'a> Salt<'a> { /// /// See type-level documentation about [`Salt`] for more information. pub const fn max_len() -> usize { - ValueStr::max_len() + Value::max_len() } /// Recommended length of a salt: 16-bytes. diff --git a/password-hash/src/value.rs b/password-hash/src/value.rs index 8e9114f4c..bfc8743d5 100644 --- a/password-hash/src/value.rs +++ b/password-hash/src/value.rs @@ -22,87 +22,6 @@ const MAX_LENGTH: usize = 48; /// Type used to represent decimal (i.e. integer) values. pub type Decimal = u32; -/// Algorithm parameter value. -/// -/// Provides an enum over [`Decimal`] and string (i.e. [`ValueStr`]) values -/// to allow ergonomically using and parsing integer values, which is the -/// main use case for this type. -#[derive(Copy, Clone, Eq, PartialEq)] -pub enum Value<'a> { - /// Decimal value. - Decimal(Decimal), - - /// String value. - Str(ValueStr<'a>), -} - -impl<'a> Value<'a> { - /// Parse a [`Value`] from the provided `str`, validating it according to - /// the PHC string format's rules. - pub fn new(input: &'a str) -> Result { - ValueStr::new(input).map(Value::Str) - } - - /// Borrow the inner value as a `str`, if it is one. - /// - /// Returns `None` if the inner value is a [`Value::Decimal`]. - pub fn as_str(&self) -> Option<&'a str> { - match self { - Self::Decimal(_) => None, - Self::Str(s) => Some(s.as_str()), - } - } - - /// Parse a [`Decimal`] from this [`Value`]. - /// - /// If this value is a [`Value::Decimal`], the decimal value is returned, - /// otherwise if it's a [`Value::Str`] the value is parsed using the - /// [`ValueStr::decimal`] method. - pub fn decimal(&self) -> Result { - match self { - Self::Decimal(x) => Ok(*x), - Self::Str(s) => s.decimal(), - } - } - - /// Does this value parse successfully as a decimal? - pub fn is_decimal(&self) -> bool { - self.decimal().is_ok() - } -} - -impl<'a> From for Value<'a> { - fn from(decimal: Decimal) -> Value<'a> { - Value::Decimal(decimal) - } -} - -impl<'a> TryFrom<&'a str> for Value<'a> { - type Error = ParseError; - - fn try_from(input: &'a str) -> Result { - Self::new(input) - } -} - -impl<'a> fmt::Display for Value<'a> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::Decimal(x) => write!(f, "{}", x), - Self::Str(s) => f.write_str(s.as_str()), - } - } -} - -impl<'a> fmt::Debug for Value<'a> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::Decimal(x) => f.debug_tuple("Value::Decimal").field(x).finish(), - Self::Str(s) => f.debug_tuple("Value::Str").field(s).finish(), - } - } -} - /// Algorithm parameter value string. /// /// Parameter values are defined in the [PHC string format specification][1]. @@ -116,15 +35,15 @@ impl<'a> fmt::Debug for Value<'a> { /// # Additional Notes /// The PHC spec allows for algorithm-defined maximum lengths for parameter /// values, however in the interest of interoperability this library defines a -/// [`ValueStr::max_len`] of 48 ASCII characters. +/// [`Value::max_len`] of 48 ASCII characters. /// /// [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md /// [2]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#argon2-encoding #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)] -pub struct ValueStr<'a>(&'a str); +pub struct Value<'a>(&'a str); -impl<'a> ValueStr<'a> { - /// Maximum length of an [`ValueStr`] - 48 ASCII characters (i.e. 48-bytes). +impl<'a> Value<'a> { + /// Maximum length of an [`Value`] - 48 ASCII characters (i.e. 48-bytes). /// /// This value is selected based on the maximum value size used in the /// [Argon2 Encoding][1] as described in the PHC string format specification. @@ -138,7 +57,7 @@ impl<'a> ValueStr<'a> { MAX_LENGTH } - /// Parse a [`ValueStr`] from the provided `str`, validating it according to + /// Parse a [`Value`] from the provided `str`, validating it according to /// the PHC string format's rules. pub fn new(input: &'a str) -> Result { if input.as_bytes().len() > MAX_LENGTH { @@ -150,7 +69,7 @@ impl<'a> ValueStr<'a> { Ok(Self(input)) } - /// Attempt to decode a [`b64`]-encoded [`ValueStr`], writing the decoded + /// Attempt to decode a [`b64`]-encoded [`Value`], writing the decoded /// result into the provided buffer, and returning a slice of the buffer /// containing the decoded result on success. /// @@ -183,7 +102,7 @@ impl<'a> ValueStr<'a> { self.as_str().is_empty() } - /// Attempt to parse this [`ValueStr`] as a PHC-encoded decimal (i.e. integer). + /// Attempt to parse this [`Value`] as a PHC-encoded decimal (i.e. integer). /// /// Decimal values are integers which follow the rules given in the /// ["Decimal Encoding" section of the PHC string format specification][1]. @@ -245,13 +164,13 @@ impl<'a> ValueStr<'a> { } } -impl<'a> AsRef for ValueStr<'a> { +impl<'a> AsRef for Value<'a> { fn as_ref(&self) -> &str { self.as_str() } } -impl<'a> TryFrom<&'a str> for ValueStr<'a> { +impl<'a> TryFrom<&'a str> for Value<'a> { type Error = ParseError; fn try_from(input: &'a str) -> Result { @@ -259,23 +178,23 @@ impl<'a> TryFrom<&'a str> for ValueStr<'a> { } } -impl<'a> TryFrom> for Decimal { +impl<'a> TryFrom> for Decimal { type Error = ParseError; - fn try_from(value: ValueStr<'a>) -> Result { + fn try_from(value: Value<'a>) -> Result { Decimal::try_from(&value) } } -impl<'a> TryFrom<&ValueStr<'a>> for Decimal { +impl<'a> TryFrom<&Value<'a>> for Decimal { type Error = ParseError; - fn try_from(value: &ValueStr<'a>) -> Result { + fn try_from(value: &Value<'a>) -> Result { value.decimal() } } -impl<'a> fmt::Display for ValueStr<'a> { +impl<'a> fmt::Display for Value<'a> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(self.as_str()) } @@ -299,7 +218,7 @@ fn is_char_valid(c: char) -> bool { #[cfg(test)] mod tests { - use super::{ParseError, ValueStr}; + use super::{ParseError, Value}; use core::convert::TryFrom; // Invalid value examples @@ -316,7 +235,7 @@ mod tests { let valid_decimals = &[("0", 0u32), ("1", 1u32), ("4294967295", u32::MAX)]; for &(s, i) in valid_decimals { - let value = ValueStr::new(s).unwrap(); + let value = Value::new(s).unwrap(); assert!(value.is_decimal()); assert_eq!(value.decimal().unwrap(), i) } @@ -324,21 +243,21 @@ mod tests { #[test] fn reject_decimal_with_leading_zero() { - let value = ValueStr::new("01").unwrap(); + let value = Value::new("01").unwrap(); let err = u32::try_from(value).err().unwrap(); assert!(matches!(err, ParseError::InvalidChar('0'))); } #[test] fn reject_overlong_decimal() { - let value = ValueStr::new("4294967296").unwrap(); + let value = Value::new("4294967296").unwrap(); let err = u32::try_from(value).err().unwrap(); assert_eq!(err, ParseError::TooLong); } #[test] fn reject_negative() { - let value = ValueStr::new("-1").unwrap(); + let value = Value::new("-1").unwrap(); let err = u32::try_from(value).err().unwrap(); assert!(matches!(err, ParseError::InvalidChar('-'))); } @@ -360,26 +279,26 @@ mod tests { ]; for &example in &valid_examples { - let value = ValueStr::new(example).unwrap(); + let value = Value::new(example).unwrap(); assert_eq!(value.as_str(), example); } } #[test] fn reject_invalid_char() { - let err = ValueStr::new(INVALID_CHAR).err().unwrap(); + let err = Value::new(INVALID_CHAR).err().unwrap(); assert!(matches!(err, ParseError::InvalidChar(';'))); } #[test] fn reject_too_long() { - let err = ValueStr::new(INVALID_TOO_LONG).err().unwrap(); + let err = Value::new(INVALID_TOO_LONG).err().unwrap(); assert_eq!(err, ParseError::TooLong); } #[test] fn reject_invalid_char_and_too_long() { - let err = ValueStr::new(INVALID_CHAR_AND_TOO_LONG).err().unwrap(); + let err = Value::new(INVALID_CHAR_AND_TOO_LONG).err().unwrap(); assert_eq!(err, ParseError::TooLong); } } diff --git a/password-hash/tests/encoding.rs b/password-hash/tests/encoding.rs index 10d7bafba..44a3c070f 100644 --- a/password-hash/tests/encoding.rs +++ b/password-hash/tests/encoding.rs @@ -7,7 +7,7 @@ #![cfg(feature = "registry")] use core::convert::TryInto; -use password_hash::{algorithm::argon2, Algorithm, ParamsBuf, PasswordHash}; +use password_hash::{algorithm::argon2, Algorithm, ParamsString, PasswordHash}; const EXAMPLE_ALGORITHM: Algorithm = Algorithm::Argon2(argon2::Variant::D); const EXAMPLE_SALT: &[u8] = &[ @@ -19,8 +19,8 @@ const EXAMPLE_HASH: &[u8] = &[ ]; /// Example parameters -fn example_params() -> ParamsBuf { - ParamsBuf::from_slice(&[ +fn example_params() -> ParamsString { + ParamsString::from_pairs(&[ ("a".parse().unwrap(), 1u32.into()), ("b".parse().unwrap(), 2u32.into()), ("c".parse().unwrap(), 3u32.into()), @@ -59,7 +59,7 @@ fn params() { fn salt() { let ph = PasswordHash { algorithm: EXAMPLE_ALGORITHM, - params: ParamsBuf::new(), + params: ParamsString::new(), salt: Some(EXAMPLE_SALT.try_into().unwrap()), hash: None, }; @@ -73,7 +73,7 @@ fn salt() { #[test] fn one_param_and_salt() { - let params = ParamsBuf::from_slice(&[("a".parse().unwrap(), 1u32.into())]).unwrap(); + let params = ParamsString::from_pairs(&[("a".parse().unwrap(), 1u32.into())]).unwrap(); let ph = PasswordHash { algorithm: EXAMPLE_ALGORITHM, @@ -109,7 +109,7 @@ fn params_and_salt() { fn salt_and_hash() { let ph = PasswordHash { algorithm: EXAMPLE_ALGORITHM, - params: ParamsBuf::default(), + params: ParamsString::default(), salt: Some(EXAMPLE_SALT.try_into().unwrap()), hash: Some(EXAMPLE_HASH.try_into().unwrap()), }; diff --git a/password-hash/tests/hashing.rs b/password-hash/tests/hashing.rs index ae53a52e3..f898f27d4 100644 --- a/password-hash/tests/hashing.rs +++ b/password-hash/tests/hashing.rs @@ -1,7 +1,7 @@ //! Password hashing tests pub use password_hash::{ - HasherError, Ident, Output, ParamsBuf, PasswordHash, PasswordHasher, Salt, VerifyError, + HasherError, Ident, Output, ParamsString, PasswordHash, PasswordHasher, Salt, VerifyError, }; use std::convert::{TryFrom, TryInto}; @@ -45,18 +45,18 @@ impl PasswordHasher for StubPasswordHasher { } /// Stub parameters -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Default)] pub struct StubParams; -impl<'a> TryFrom<&'a ParamsBuf<'a>> for StubParams { +impl<'a> TryFrom<&'a ParamsString> for StubParams { type Error = HasherError; - fn try_from(_: &'a ParamsBuf<'a>) -> Result { + fn try_from(_: &'a ParamsString) -> Result { Ok(Self) } } -impl<'a> TryFrom for ParamsBuf<'a> { +impl<'a> TryFrom for ParamsString { type Error = HasherError; fn try_from(_: StubParams) -> Result { @@ -68,7 +68,7 @@ impl<'a> TryFrom for ParamsBuf<'a> { fn verify_password_hash() { let valid_password = "test password"; let salt = Salt::new("test-salt").unwrap(); - let params = ParamsBuf::new(); + let params = ParamsString::new(); let hash = PasswordHash::generate(StubPasswordHasher, valid_password, salt, ¶ms).unwrap(); // Sanity tests for StubFunction impl above diff --git a/password-hash/tests/test_vectors.rs b/password-hash/tests/test_vectors.rs index 37ad2d977..95d097379 100644 --- a/password-hash/tests/test_vectors.rs +++ b/password-hash/tests/test_vectors.rs @@ -13,10 +13,10 @@ fn argon2id() { let ph = PasswordHash::new(ARGON2D_HASH).unwrap(); assert_eq!(ph.algorithm, Ident::new("argon2d")); assert_eq!(ph.version, Some(19)); - assert_eq!(ph.params.len(), 3); - assert_eq!(ph.params["m"].decimal().unwrap(), 512); - assert_eq!(ph.params["t"].decimal().unwrap(), 3); - assert_eq!(ph.params["p"].decimal().unwrap(), 2); + assert_eq!(ph.params.iter().count(), 3); + assert_eq!(ph.params.get_decimal("m").unwrap(), 512); + assert_eq!(ph.params.get_decimal("t").unwrap(), 3); + assert_eq!(ph.params.get_decimal("p").unwrap(), 2); assert_eq!(ph.salt.unwrap().as_ref(), "5VtWOO3cGWYQHEMaYGbsfQ"); assert_eq!(ph.hash.unwrap().to_string(), "AcmqasQgW/wI6wAHAMk4aQ"); assert_eq!(ph.to_string(), ARGON2D_HASH); From 7875ef692a006cf3fc5188c208569c9e27a30032 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Mon, 18 Jan 2021 13:43:44 +0000 Subject: [PATCH 0383/1461] digest: add block-level API (#380) --- Cargo.lock | 40 +++++---- crypto/Cargo.toml | 2 +- digest/CHANGELOG.md | 9 ++ digest/Cargo.toml | 6 +- digest/src/core_api.rs | 164 +++++++++++++++++++++++++++++++++++ digest/src/dev.rs | 56 +----------- digest/src/digest.rs | 39 +++++++-- digest/src/dyn_digest.rs | 50 +++++++++-- digest/src/errors.rs | 14 --- digest/src/fixed.rs | 71 ---------------- digest/src/lib.rs | 179 ++++++++++++++++++++++++++------------- digest/src/variable.rs | 106 ----------------------- digest/src/xof.rs | 102 ---------------------- 13 files changed, 397 insertions(+), 441 deletions(-) create mode 100644 digest/src/core_api.rs delete mode 100644 digest/src/errors.rs delete mode 100644 digest/src/fixed.rs delete mode 100644 digest/src/variable.rs delete mode 100644 digest/src/xof.rs diff --git a/Cargo.lock b/Cargo.lock index 14c302bdb..baa72179d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,7 +4,7 @@ name = "aead" version = "0.3.2" dependencies = [ - "blobby 0.3.0", + "blobby", "generic-array 0.14.4", "heapless", ] @@ -57,12 +57,6 @@ dependencies = [ "wyz", ] -[[package]] -name = "blobby" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "517e75eae2ab6547f6a32ca5eefce861ecb5ec4c57a4c015e82503f71a7c63a9" - [[package]] name = "blobby" version = "0.3.0" @@ -78,6 +72,15 @@ dependencies = [ "generic-array 0.14.4", ] +[[package]] +name = "block-buffer" +version = "0.10.0-pre" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5ae77a4961d75e3e4505bbe155705bda23ff5948209c8face08f75c2cd52a0" +dependencies = [ + "generic-array 0.14.4", +] + [[package]] name = "byteorder" version = "1.3.4" @@ -94,7 +97,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" name = "cipher" version = "0.3.0-pre.4" dependencies = [ - "blobby 0.3.0", + "blobby", "generic-array 0.14.4", ] @@ -117,7 +120,7 @@ dependencies = [ "aead", "cipher", "crypto-mac", - "digest 0.9.0", + "digest 0.10.0-pre", "elliptic-curve", "signature", "universal-hash", @@ -127,7 +130,7 @@ dependencies = [ name = "crypto-mac" version = "0.11.0-pre" dependencies = [ - "blobby 0.3.0", + "blobby", "cipher", "generic-array 0.14.4", "subtle", @@ -145,17 +148,18 @@ dependencies = [ [[package]] name = "digest" version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ - "blobby 0.2.0", "generic-array 0.14.4", ] [[package]] name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +version = "0.10.0-pre" dependencies = [ + "blobby", + "block-buffer 0.10.0-pre", "generic-array 0.14.4", ] @@ -164,7 +168,7 @@ name = "elliptic-curve" version = "0.9.0-pre" dependencies = [ "bitvec", - "digest 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.9.0", "ff", "generic-array 0.14.4", "group", @@ -343,10 +347,10 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e7aab86fe2149bad8c507606bdb3f4ef5e7b2380eb92350f56122cca72a42a8" dependencies = [ - "block-buffer", + "block-buffer 0.9.0", "cfg-if", "cpuid-bool", - "digest 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.9.0", "opaque-debug", ] @@ -354,7 +358,7 @@ dependencies = [ name = "signature" version = "1.3.0" dependencies = [ - "digest 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.9.0", "hex-literal 0.2.1", "rand_core", "sha2", diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 26c5c9332..efa129c3c 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -14,7 +14,7 @@ edition = "2018" [dependencies] aead = { version = "0.3", optional = true, path = "../aead" } cipher = { version = "=0.3.0-pre.4", optional = true, path = "../cipher" } -digest = { version = "0.9", optional = true, path = "../digest" } +digest = { version = "0.10.0-pre", optional = true, path = "../digest" } elliptic-curve = { version = "=0.9.0-pre", optional = true, path = "../elliptic-curve" } mac = { version = "=0.11.0-pre", package = "crypto-mac", optional = true, path = "../crypto-mac" } signature = { version = "1.3.0", optional = true, default-features = false, path = "../signature" } diff --git a/digest/CHANGELOG.md b/digest/CHANGELOG.md index 03f0ad387..0b8547c6f 100644 --- a/digest/CHANGELOG.md +++ b/digest/CHANGELOG.md @@ -5,6 +5,15 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.10.0 (2021-01-18) +### Breaking changes +- Dirty traits are removed and instead block-level traits are introduced. +Variable output traits are removed as well in favor of fixed output tratis, +implementors of variable output hashes are expected to be generic over +output size. ([#380]) + +[#380]: https://github.com/RustCrypto/traits/pull/380 + ## 0.9.0 (2020-06-09) ### Added - `ExtendableOutputDirty` and `VariableOutputDirty` traits ([#183]) diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 5c0652e08..e41667c40 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "digest" description = "Traits for cryptographic hash functions" -version = "0.9.0" +version = "0.10.0-pre" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" @@ -13,12 +13,14 @@ categories = ["cryptography", "no-std"] [dependencies] generic-array = "0.14" -blobby = { version = "0.2", optional = true } +blobby = { version = "0.3", optional = true } +block-buffer = { version = "0.10.0-pre", optional = true } [features] alloc = [] std = ["alloc"] dev = ["blobby"] +core-api = ["block-buffer"] [package.metadata.docs.rs] all-features = true diff --git a/digest/src/core_api.rs b/digest/src/core_api.rs new file mode 100644 index 000000000..8201ced45 --- /dev/null +++ b/digest/src/core_api.rs @@ -0,0 +1,164 @@ +use crate::{ExtendableOutput, FixedOutput, Reset, Update, XofReader}; +use block_buffer::BlockBuffer; +use generic_array::{ArrayLength, GenericArray}; + +/// Trait for updating hasher state with input data divided into blocks. +pub trait UpdateCore { + /// Block size in bytes. + type BlockSize: ArrayLength; + + /// Update the hasher state using the provided data. + fn update_blocks(&mut self, blocks: &[GenericArray]); +} + +/// Trait for fixed-output digest implementations to use to retrieve the +/// hash output. +/// +/// Usage of this trait in user code is discouraged. Instead use core algorithm +/// wrapped by [`crate::CoreWrapper`], which implements the [`FixedOutput`] +/// trait. +pub trait FixedOutputCore: crate::UpdateCore { + /// Digest output size in bytes. + type OutputSize: ArrayLength; + + /// Retrieve result into provided buffer using remaining data stored + /// in the block buffer and leave hasher in a dirty state. + /// + /// This method is expected to only be called once unless [`Reset::reset`] + /// is called, after which point it can be called again and reset again + /// (and so on). + fn finalize_fixed_core( + &mut self, + buffer: &mut block_buffer::BlockBuffer, + out: &mut GenericArray, + ); +} + +/// Trait for extendable-output function (XOF) core implementations to use to +/// retrieve the hash output. +/// +/// Usage of this trait in user code is discouraged. Instead use core algorithm +/// wrapped by [`crate::CoreWrapper`], which implements the +/// [`ExtendableOutput`] trait. +pub trait ExtendableOutputCore: crate::UpdateCore { + /// XOF reader core state. + type ReaderCore: XofReaderCore; + + /// Retrieve XOF reader using remaining data stored in the block buffer + /// and leave hasher in a dirty state. + /// + /// This method is expected to only be called once unless [`Reset::reset`] + /// is called, after which point it can be called again and reset again + /// (and so on). + fn finalize_xof_core( + &mut self, + buffer: &mut block_buffer::BlockBuffer, + ) -> Self::ReaderCore; +} + +/// Core reader trait for extendable-output function (XOF) result. +pub trait XofReaderCore { + /// Block size in bytes. + type BlockSize: ArrayLength; + + /// Read next XOF block. + fn read_block(&mut self) -> GenericArray; +} + +/// Wrapper around core trait implementations. +/// +/// It handles data buffering and implements the mid-level traits. +#[derive(Clone, Default)] +pub struct CoreWrapper> { + core: C, + buffer: BlockBuffer, +} + +impl Reset for CoreWrapper { + #[inline] + fn reset(&mut self) { + self.core.reset(); + self.buffer.reset(); + } +} + +impl Update for CoreWrapper { + #[inline] + fn update(&mut self, input: &[u8]) { + let Self { core, buffer } = self; + buffer.digest_blocks(input, |blocks| core.update_blocks(blocks)); + } +} + +impl FixedOutput for CoreWrapper { + type OutputSize = D::OutputSize; + + #[inline] + fn finalize_into(mut self, out: &mut GenericArray) { + let Self { core, buffer } = &mut self; + core.finalize_fixed_core(buffer, out); + } + + #[inline] + fn finalize_into_reset(&mut self, out: &mut GenericArray) { + let Self { core, buffer } = self; + core.finalize_fixed_core(buffer, out); + self.reset(); + } +} + +impl XofReader for CoreWrapper { + #[inline] + fn read(&mut self, buffer: &mut [u8]) { + let Self { core, buffer: buf } = self; + buf.set_data(buffer, || core.read_block()); + } +} + +impl ExtendableOutput for CoreWrapper { + type Reader = CoreWrapper::BlockSize>; + + #[inline] + fn finalize_xof(mut self) -> Self::Reader { + let Self { core, buffer } = &mut self; + let reader_core = core.finalize_xof_core(buffer); + CoreWrapper { + core: reader_core, + buffer: Default::default(), + } + } + + #[inline] + fn finalize_xof_reset(&mut self) -> Self::Reader { + let Self { core, buffer } = self; + let reader_core = core.finalize_xof_core(buffer); + self.reset(); + CoreWrapper { + core: reader_core, + buffer: Default::default(), + } + } +} + +#[cfg(feature = "std")] +impl std::io::Write for CoreWrapper { + #[inline] + fn write(&mut self, buf: &[u8]) -> std::io::Result { + Update::update(self, buf); + Ok(buf.len()) + } + + #[inline] + fn flush(&mut self) -> std::io::Result<()> { + Ok(()) + } +} + +#[cfg(feature = "std")] +impl std::io::Read for CoreWrapper { + #[inline] + fn read(&mut self, buf: &mut [u8]) -> std::io::Result { + XofReader::read(self, buf); + Ok(buf.len()) + } +} diff --git a/digest/src/dev.rs b/digest/src/dev.rs index c205cab43..f3f8e2208 100644 --- a/digest/src/dev.rs +++ b/digest/src/dev.rs @@ -2,7 +2,7 @@ pub use blobby; -use super::{ExtendableOutput, Reset, Update, VariableOutput, XofReader}; +use super::{ExtendableOutput, Reset, Update, XofReader}; use core::fmt::Debug; /// Define test @@ -15,9 +15,7 @@ macro_rules! new_test { use digest::dev::blobby::Blob2Iterator; let data = include_bytes!(concat!("data/", $test_name, ".blb")); - for (i, row) in Blob2Iterator::new(data).unwrap().enumerate() { - let input = row[0]; - let output = row[1]; + for (i, [input, output]) in Blob2Iterator::new(data).unwrap().enumerate() { if let Some(desc) = $test_func::<$hasher>(input, output) { panic!( "\n\ @@ -165,56 +163,6 @@ where None } -/// Variable-output digest test -pub fn variable_test(input: &[u8], output: &[u8]) -> Option<&'static str> -where - D: Update + VariableOutput + Reset + Debug + Clone, -{ - let mut hasher = D::new(output.len()).unwrap(); - let mut buf = [0u8; 128]; - let buf = &mut buf[..output.len()]; - // Test that it works when accepting the message all at once - hasher.update(input); - let mut hasher2 = hasher.clone(); - hasher.finalize_variable(|res| buf.copy_from_slice(res)); - if buf != output { - return Some("whole message"); - } - - // Test if reset works correctly - hasher2.reset(); - hasher2.update(input); - hasher2.finalize_variable(|res| buf.copy_from_slice(res)); - if buf != output { - return Some("whole message after reset"); - } - - // Test that it works when accepting the message in pieces - let mut hasher = D::new(output.len()).unwrap(); - let len = input.len(); - let mut left = len; - while left > 0 { - let take = (left + 1) / 2; - hasher.update(&input[len - left..take + len - left]); - left -= take; - } - hasher.finalize_variable(|res| buf.copy_from_slice(res)); - if buf != output { - return Some("message in pieces"); - } - - // Test processing byte-by-byte - let mut hasher = D::new(output.len()).unwrap(); - for chunk in input.chunks(1) { - hasher.update(chunk) - } - hasher.finalize_variable(|res| buf.copy_from_slice(res)); - if buf != output { - return Some("message byte-by-byte"); - } - None -} - /// Define benchmark #[macro_export] #[cfg_attr(docsrs, doc(cfg(feature = "dev")))] diff --git a/digest/src/digest.rs b/digest/src/digest.rs index ef72951d8..674a4e636 100644 --- a/digest/src/digest.rs +++ b/digest/src/digest.rs @@ -32,6 +32,12 @@ pub trait Digest { /// re-creation. fn finalize_reset(&mut self) -> Output; + /// Write result into provided array and consume the hasher instance. + fn finalize_into(self, out: &mut GenericArray); + + /// Write result into provided array and reset the hasher instance. + fn finalize_into_reset(&mut self, out: &mut GenericArray); + /// Reset hasher instance to its initial state. fn reset(&mut self); @@ -52,39 +58,56 @@ pub trait Digest { impl Digest for D { type OutputSize = ::OutputSize; + #[inline] fn new() -> Self { Self::default() } + #[inline] fn update(&mut self, data: impl AsRef<[u8]>) { - Update::update(self, data); + Update::update(self, data.as_ref()); } - fn chain(self, data: impl AsRef<[u8]>) -> Self + #[inline] + fn chain(mut self, data: impl AsRef<[u8]>) -> Self where Self: Sized, { - Update::chain(self, data) + Update::update(&mut self, data.as_ref()); + self } + #[inline] fn finalize(self) -> Output { self.finalize_fixed() } + #[inline] fn finalize_reset(&mut self) -> Output { - let res = self.clone().finalize_fixed(); - self.reset(); - res + self.finalize_fixed_reset() + } + + #[inline] + fn finalize_into(self, out: &mut Output) { + self.finalize_into(out); + } + + #[inline] + fn finalize_into_reset(&mut self, out: &mut Output) { + self.finalize_into_reset(out); } + #[inline] fn reset(&mut self) { - ::reset(self) + Reset::reset(self) } + #[inline] fn output_size() -> usize { Self::OutputSize::to_usize() } + #[inline] fn digest(data: &[u8]) -> Output { let mut hasher = Self::default(); Update::update(&mut hasher, data); @@ -92,5 +115,5 @@ impl Digest for D { } } -/// Output of a [`Digest`] function +/// Fixed of fixed-sized hash-function used by [`Digest`] methods. pub type Output = GenericArray::OutputSize>; diff --git a/digest/src/dyn_digest.rs b/digest/src/dyn_digest.rs index 156f9bdbf..f6936badd 100644 --- a/digest/src/dyn_digest.rs +++ b/digest/src/dyn_digest.rs @@ -1,8 +1,8 @@ -#![cfg(feature = "alloc")] use alloc::boxed::Box; +use core::fmt; use super::{FixedOutput, Reset, Update}; -use generic_array::typenum::Unsigned; +use generic_array::{typenum::Unsigned, GenericArray}; /// The `DynDigest` trait is a modification of `Digest` trait suitable /// for trait objects. @@ -19,6 +19,16 @@ pub trait DynDigest { /// Retrieve result and consume boxed hasher instance fn finalize(self: Box) -> Box<[u8]>; + /// Write result into provided array and consume the hasher instance. + /// + /// Returns error if buffer length is not equal to `output_size`. + fn finalize_into(self, buf: &mut [u8]) -> Result<(), InvalidBufferLength>; + + /// Write result into provided array and reset the hasher instance. + /// + /// Returns error if buffer length is not equal to `output_size`. + fn finalize_into_reset(&mut self, out: &mut [u8]) -> Result<(), InvalidBufferLength>; + /// Reset hasher instance to its initial state. fn reset(&mut self); @@ -35,15 +45,31 @@ impl DynDigest for D { } fn finalize_reset(&mut self) -> Box<[u8]> { - let res = self.finalize_fixed_reset().to_vec().into_boxed_slice(); - Reset::reset(self); - res + self.finalize_fixed_reset().to_vec().into_boxed_slice() } fn finalize(self: Box) -> Box<[u8]> { self.finalize_fixed().to_vec().into_boxed_slice() } + fn finalize_into(self, buf: &mut [u8]) -> Result<(), InvalidBufferLength> { + if buf.len() == self.output_size() { + self.finalize_into(GenericArray::from_mut_slice(buf)); + Ok(()) + } else { + Err(InvalidBufferLength) + } + } + + fn finalize_into_reset(&mut self, buf: &mut [u8]) -> Result<(), InvalidBufferLength> { + if buf.len() == self.output_size() { + self.finalize_into_reset(GenericArray::from_mut_slice(buf)); + Ok(()) + } else { + Err(InvalidBufferLength) + } + } + fn reset(&mut self) { Reset::reset(self); } @@ -62,3 +88,17 @@ impl Clone for Box { self.box_clone() } } + +/// Buffer length is not equal to the hash output size. +#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] +#[derive(Default, Debug, Copy, Clone, Eq, PartialEq)] +pub struct InvalidBufferLength; + +impl fmt::Display for InvalidBufferLength { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("invalid buffer length") + } +} + +#[cfg(feature = "std")] +impl std::error::Error for InvalidBufferLength {} diff --git a/digest/src/errors.rs b/digest/src/errors.rs deleted file mode 100644 index 6071e456b..000000000 --- a/digest/src/errors.rs +++ /dev/null @@ -1,14 +0,0 @@ -use core::fmt; - -/// The error type for variable hasher initialization -#[derive(Clone, Copy, Debug, Default)] -pub struct InvalidOutputSize; - -impl fmt::Display for InvalidOutputSize { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str("invalid output size") - } -} - -#[cfg(feature = "std")] -impl std::error::Error for InvalidOutputSize {} diff --git a/digest/src/fixed.rs b/digest/src/fixed.rs deleted file mode 100644 index 432a6c42c..000000000 --- a/digest/src/fixed.rs +++ /dev/null @@ -1,71 +0,0 @@ -//! Fixed-size output digest support - -use crate::Reset; -use generic_array::{ArrayLength, GenericArray}; - -/// Trait for returning digest result with the fixed size -pub trait FixedOutput { - /// Output size for fixed output digest - type OutputSize: ArrayLength; - - /// Write result into provided array and consume the hasher instance. - fn finalize_into(self, out: &mut GenericArray); - - /// Write result into provided array and reset the hasher instance. - fn finalize_into_reset(&mut self, out: &mut GenericArray); - - /// Retrieve result and consume the hasher instance. - #[inline] - fn finalize_fixed(self) -> GenericArray - where - Self: Sized, - { - let mut out = Default::default(); - self.finalize_into(&mut out); - out - } - - /// Retrieve result and reset the hasher instance. - #[inline] - fn finalize_fixed_reset(&mut self) -> GenericArray { - let mut out = Default::default(); - self.finalize_into_reset(&mut out); - out - } -} - -/// Trait for fixed-output digest implementations to use to retrieve the -/// hash output. -/// -/// Usage of this trait in user code is discouraged. Instead use the -/// [`FixedOutput::finalize_fixed`] or [`FixedOutput::finalize_fixed_reset`] -/// methods. -/// -/// Types which impl this trait along with [`Reset`] will receive a blanket -/// impl of [`FixedOutput`]. -pub trait FixedOutputDirty { - /// Output size for fixed output digest - type OutputSize: ArrayLength; - - /// Retrieve result into provided buffer and leave hasher in a dirty state. - /// - /// This method is expected to only be called once unless - /// [`Reset::reset`] is called, after which point it can be - /// called again and reset again (and so on). - fn finalize_into_dirty(&mut self, out: &mut GenericArray); -} - -impl FixedOutput for D { - type OutputSize = D::OutputSize; - - #[inline] - fn finalize_into(mut self, out: &mut GenericArray) { - self.finalize_into_dirty(out); - } - - #[inline] - fn finalize_into_reset(&mut self, out: &mut GenericArray) { - self.finalize_into_dirty(out); - self.reset(); - } -} diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 9ded58214..b93746e61 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -7,18 +7,20 @@ //! //! - **High-level convenience traits**: [`Digest`], [`DynDigest`]. They are wrappers //! around lower-level traits for most common hash-function use-cases. -//! - **Mid-level traits**: [`Update`], [`BlockInput`], [`Reset`], [`FixedOutput`], -//! [`VariableOutput`], [`ExtendableOutput`]. These traits atomically describe -//! available functionality of hash function implementations. -//! - **Low-level traits**: [`FixedOutputDirty`], [`VariableOutputDirty`], -//! [`ExtendableOutputDirty`]. These traits are intended to be implemented by -//! low-level algorithm providers only and simplify the amount of work -//! implementers need to do and therefore shouldn't be used in +//! - **Mid-level traits**: [`Update`], [`FixedOutput`], [`ExtendableOutput`], [`Reset`]. +//! These traits atomically describe available functionality of hash function +//! implementations. +//! - **Low-level traits**: [`UpdateCore`], [`FixedOutputCore`], +//! [`ExtendableOutputCore`]. These traits operate at a block-level and do not +//! contain any built-in buffering. They are intended to be implemented +//! by low-level algorithm providers only and simplify the amount of work +//! implementers need to do and therefore usually shouldn't be used in //! application-level code. //! //! Additionally hash functions implement traits from the standard library: -//! `Default`, `Clone`, `Write`. The latter is feature-gated behind `std` feature, -//! which is usually enabled by default by hash implementation crates. +//! [`Default`], [`Clone`], [`Write`][std::io::Write]. The latter is +//! feature-gated behind `std` feature, which is usually enabled by default +//! by hash implementation crates. //! //! The [`Digest`] trait is the most commonly used trait. @@ -38,76 +40,133 @@ extern crate alloc; #[cfg(feature = "std")] extern crate std; +#[cfg(feature = "alloc")] +use alloc::boxed::Box; + #[cfg(feature = "dev")] #[cfg_attr(docsrs, doc(cfg(feature = "dev")))] pub mod dev; +#[cfg(feature = "core-api")] +mod core_api; mod digest; +#[cfg(feature = "alloc")] mod dyn_digest; -mod errors; -mod fixed; -mod variable; -mod xof; +#[cfg(feature = "core-api")] +pub use crate::core_api::{CoreWrapper, ExtendableOutputCore, FixedOutputCore, UpdateCore}; pub use crate::digest::{Digest, Output}; -pub use crate::errors::InvalidOutputSize; -pub use crate::fixed::{FixedOutput, FixedOutputDirty}; -pub use crate::variable::{VariableOutput, VariableOutputDirty}; -pub use crate::xof::{ExtendableOutput, ExtendableOutputDirty, XofReader}; -pub use generic_array::{self, typenum::consts}; - +#[cfg(feature = "core-api")] +pub use block_buffer; #[cfg(feature = "alloc")] -pub use dyn_digest::DynDigest; - -use generic_array::ArrayLength; +pub use dyn_digest::{DynDigest, InvalidBufferLength}; +pub use generic_array::{self, typenum::consts, ArrayLength, GenericArray}; -/// Trait for updating digest state with input data. +/// Trait for updating hasher state with input data. pub trait Update { - /// Digest input data. - /// - /// This method can be called repeatedly, e.g. for processing streaming - /// messages. - fn update(&mut self, data: impl AsRef<[u8]>); + /// Update the hasher state using the provided data. + fn update(&mut self, data: &[u8]); +} + +/// Trait for resetting hasher instances +pub trait Reset { + /// Reset hasher instance to its initial state. + fn reset(&mut self); +} + +/// Trait for returning digest result with the fixed size +pub trait FixedOutput { + /// Output size for fixed output digest + type OutputSize: ArrayLength; - /// Digest input data in a chained manner. - fn chain(mut self, data: impl AsRef<[u8]>) -> Self + /// Write result into provided array and consume the hasher instance. + fn finalize_into(self, out: &mut GenericArray) + where + Self: Sized; + + /// Write result into provided array and reset the hasher instance. + fn finalize_into_reset(&mut self, out: &mut GenericArray); + + /// Retrieve result and consume the hasher instance. + #[inline] + fn finalize_fixed(self) -> GenericArray where Self: Sized, { - self.update(data); - self + let mut out = Default::default(); + self.finalize_into(&mut out); + out } -} -/// Trait to indicate that digest function processes data in blocks of size -/// `BlockSize`. -/// -/// The main usage of this trait is for implementing HMAC generically. -pub trait BlockInput { - /// Block size - type BlockSize: ArrayLength; + /// Retrieve result and reset the hasher instance. + #[inline] + fn finalize_fixed_reset(&mut self) -> GenericArray { + let mut out = Default::default(); + self.finalize_into_reset(&mut out); + out + } } -/// Trait for resetting hash instances -pub trait Reset { - /// Reset hasher instance to its initial state and return current state. - fn reset(&mut self); +/// Trait for describing readers which are used to extract extendable output +/// from XOF (extendable-output function) result. +pub trait XofReader { + /// Read output into the `buffer`. Can be called an unlimited number of times. + fn read(&mut self, buffer: &mut [u8]); + + /// Read output into a boxed slice of the specified size. + /// + /// Can be called an unlimited number of times in combination with `read`. + /// + /// `Box<[u8]>` is used instead of `Vec` to save stack space, since + /// they have size of 2 and 3 words respectively. + #[cfg(feature = "alloc")] + #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] + fn read_boxed(&mut self, n: usize) -> Box<[u8]> { + let mut buf = vec![0u8; n].into_boxed_slice(); + self.read(&mut buf); + buf + } } -#[macro_export] -/// Implements `std::io::Write` trait for implementer of [`Update`] -macro_rules! impl_write { - ($hasher:ident) => { - #[cfg(feature = "std")] - impl std::io::Write for $hasher { - fn write(&mut self, buf: &[u8]) -> std::io::Result { - Update::update(self, buf); - Ok(buf.len()) - } - - fn flush(&mut self) -> std::io::Result<()> { - Ok(()) - } - } - }; +/// Trait which describes extendable-output functions (XOF). +pub trait ExtendableOutput { + /// Reader + type Reader: XofReader; + + /// Retrieve XOF reader and consume hasher instance. + fn finalize_xof(self) -> Self::Reader + where + Self: Sized; + + /// Retrieve XOF reader and reset hasher instance state. + fn finalize_xof_reset(&mut self) -> Self::Reader; + + /// Retrieve result into a boxed slice of the specified size and consume + /// the hasher. + /// + /// `Box<[u8]>` is used instead of `Vec` to save stack space, since + /// they have size of 2 and 3 words respectively. + #[cfg(feature = "alloc")] + #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] + fn finalize_boxed(self, n: usize) -> Box<[u8]> + where + Self: Sized, + { + let mut buf = vec![0u8; n].into_boxed_slice(); + self.finalize_xof().read(&mut buf); + buf + } + + /// Retrieve result into a boxed slice of the specified size and reset + /// the hasher's state. + /// + /// `Box<[u8]>` is used instead of `Vec` to save stack space, since + /// they have size of 2 and 3 words respectively. + #[cfg(feature = "alloc")] + #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] + fn finalize_boxed_reset(&mut self, n: usize) -> Box<[u8]> { + let mut buf = vec![0u8; n].into_boxed_slice(); + self.finalize_xof_reset().read(&mut buf); + buf + } } diff --git a/digest/src/variable.rs b/digest/src/variable.rs deleted file mode 100644 index 7f444931f..000000000 --- a/digest/src/variable.rs +++ /dev/null @@ -1,106 +0,0 @@ -//! Variable-sized output digest support - -use crate::{InvalidOutputSize, Reset}; - -#[cfg(feature = "alloc")] -use alloc::boxed::Box; - -/// Trait for returning digest result with the variable size -pub trait VariableOutput: Sized { - /// Create new hasher instance with the given output size. - /// - /// It will return `Err(InvalidOutputSize)` in case if hasher can not return - /// specified output size. It will always return an error if output size - /// equals to zero. - fn new(output_size: usize) -> Result; - - /// Get output size of the hasher instance provided to the `new` method - fn output_size(&self) -> usize; - - /// Retrieve result via closure and consume hasher. - /// - /// Closure is guaranteed to be called, length of the buffer passed to it - /// will be equal to `output_size`. - fn finalize_variable(self, f: impl FnOnce(&[u8])); - - /// Retrieve result via closure and reset the hasher state. - /// - /// Closure is guaranteed to be called, length of the buffer passed to it - /// will be equal to `output_size`. - fn finalize_variable_reset(&mut self, f: impl FnOnce(&[u8])); - - /// Retrieve result into a boxed slice and consume hasher. - /// - /// `Box<[u8]>` is used instead of `Vec` to save stack space, since - /// they have size of 2 and 3 words respectively. - #[cfg(feature = "alloc")] - #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] - fn finalize_boxed(self) -> Box<[u8]> { - let n = self.output_size(); - let mut buf = vec![0u8; n].into_boxed_slice(); - self.finalize_variable(|res| buf.copy_from_slice(res)); - buf - } - - /// Retrieve result into a boxed slice and reset hasher state. - /// - /// `Box<[u8]>` is used instead of `Vec` to save stack space, since - /// they have size of 2 and 3 words respectively. - #[cfg(feature = "alloc")] - #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] - fn finalize_boxed_reset(&mut self) -> Box<[u8]> { - let n = self.output_size(); - let mut buf = vec![0u8; n].into_boxed_slice(); - self.finalize_variable_reset(|res| buf.copy_from_slice(res)); - buf - } -} - -/// Trait for variable-sized output digest implementations to use to retrieve -/// the hash output. -/// -/// Usage of this trait in user code is discouraged. Instead use the -/// [`VariableOutput::finalize_variable`] or -/// [`VariableOutput::finalize_variable_reset`] methods. -/// -/// Types which impl this trait along with [`Reset`] will receive a blanket -/// impl of [`VariableOutput`]. -pub trait VariableOutputDirty: Sized { - /// Create new hasher instance with the given output size. - /// - /// It will return `Err(InvalidOutputSize)` in case if hasher can not return - /// specified output size. It will always return an error if output size - /// equals to zero. - fn new(output_size: usize) -> Result; - - /// Get output size of the hasher instance provided to the `new` method - fn output_size(&self) -> usize; - - /// Retrieve result into provided buffer and leave hasher in a dirty state. - /// - /// This method is expected to only be called once unless - /// [`Reset::reset`] is called, after which point it can be - /// called again and reset again (and so on). - fn finalize_variable_dirty(&mut self, f: impl FnOnce(&[u8])); -} - -impl VariableOutput for D { - fn new(output_size: usize) -> Result { - ::new(output_size) - } - - fn output_size(&self) -> usize { - ::output_size(self) - } - - #[inline] - fn finalize_variable(mut self, f: impl FnOnce(&[u8])) { - self.finalize_variable_dirty(f); - } - - #[inline] - fn finalize_variable_reset(&mut self, f: impl FnOnce(&[u8])) { - self.finalize_variable_dirty(f); - self.reset(); - } -} diff --git a/digest/src/xof.rs b/digest/src/xof.rs deleted file mode 100644 index 0a41833b0..000000000 --- a/digest/src/xof.rs +++ /dev/null @@ -1,102 +0,0 @@ -//! Extendable-Output Function (XOF) support - -use crate::Reset; - -#[cfg(feature = "alloc")] -use alloc::boxed::Box; - -/// Trait for describing readers which are used to extract extendable output -/// from XOF (extendable-output function) result. -pub trait XofReader { - /// Read output into the `buffer`. Can be called an unlimited number of times. - fn read(&mut self, buffer: &mut [u8]); - - /// Read output into a boxed slice of the specified size. - /// - /// Can be called an unlimited number of times in combination with `read`. - /// - /// `Box<[u8]>` is used instead of `Vec` to save stack space, since - /// they have size of 2 and 3 words respectively. - #[cfg(feature = "alloc")] - #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] - fn read_boxed(&mut self, n: usize) -> Box<[u8]> { - let mut buf = vec![0u8; n].into_boxed_slice(); - self.read(&mut buf); - buf - } -} - -/// Trait which describes extendable-output functions (XOF). -pub trait ExtendableOutput: Sized { - /// Reader - type Reader: XofReader; - - /// Retrieve XOF reader and consume hasher instance. - fn finalize_xof(self) -> Self::Reader; - - /// Retrieve XOF reader and reset hasher instance state. - fn finalize_xof_reset(&mut self) -> Self::Reader; - - /// Retrieve result into a boxed slice of the specified size and consume - /// the hasher. - /// - /// `Box<[u8]>` is used instead of `Vec` to save stack space, since - /// they have size of 2 and 3 words respectively. - #[cfg(feature = "alloc")] - #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] - fn finalize_boxed(self, n: usize) -> Box<[u8]> { - let mut buf = vec![0u8; n].into_boxed_slice(); - self.finalize_xof().read(&mut buf); - buf - } - - /// Retrieve result into a boxed slice of the specified size and reset - /// the hasher's state. - /// - /// `Box<[u8]>` is used instead of `Vec` to save stack space, since - /// they have size of 2 and 3 words respectively. - #[cfg(feature = "alloc")] - #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] - fn finalize_boxed_reset(&mut self, n: usize) -> Box<[u8]> { - let mut buf = vec![0u8; n].into_boxed_slice(); - self.finalize_xof_reset().read(&mut buf); - buf - } -} - -/// Trait for extendable-output function (XOF) implementations to use to -/// retrieve the hash output. -/// -/// Usage of this trait in user code is discouraged. Instead use the -/// [`ExtendableOutput::finalize_xof`] or -/// [`ExtendableOutput::finalize_xof_reset`] methods. -/// -/// Types which impl this trait along with [`Reset`] will receive a blanket -/// impl of [`ExtendableOutput`]. -pub trait ExtendableOutputDirty: Sized { - /// Reader - type Reader: XofReader; - - /// Retrieve XOF reader. - /// - /// This method is expected to only be called once unless - /// [`Reset::reset`] is called, after which point it can be - /// called again and reset again (and so on). - fn finalize_xof_dirty(&mut self) -> Self::Reader; -} - -impl ExtendableOutput for X { - type Reader = X::Reader; - - #[inline] - fn finalize_xof(mut self) -> Self::Reader { - self.finalize_xof_dirty() - } - - #[inline] - fn finalize_xof_reset(&mut self) -> Self::Reader { - let reader = self.finalize_xof_dirty(); - self.reset(); - reader - } -} From 4c1597f275436d18ebcfc803e1aa13d27da8b43e Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Mon, 18 Jan 2021 16:46:15 +0300 Subject: [PATCH 0384/1461] digest: test `core-api` feature --- .github/workflows/digest.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/digest.yml b/.github/workflows/digest.yml index 516d8ad80..da00f2b12 100644 --- a/.github/workflows/digest.yml +++ b/.github/workflows/digest.yml @@ -51,6 +51,7 @@ jobs: toolchain: ${{ matrix.rust }} - run: cargo check --all-features - run: cargo test --release + - run: cargo test --features core-api --release - run: cargo test --features dev --release - run: cargo test --features alloc --release - run: cargo test --features std --release From 813dcae7c4d1f5f4db019edbc50bce91213b072a Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Mon, 18 Jan 2021 16:21:42 +0000 Subject: [PATCH 0385/1461] digest: v0.10.0 improvements (#479) --- Cargo.lock | 14 +++++++-- digest/Cargo.toml | 3 +- digest/src/core_api.rs | 66 ++++++++++++++++++++++++++++++------------ digest/src/lib.rs | 15 ++++++---- 4 files changed, 71 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index baa72179d..95cf0a1a8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -77,6 +77,16 @@ name = "block-buffer" version = "0.10.0-pre" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a5ae77a4961d75e3e4505bbe155705bda23ff5948209c8face08f75c2cd52a0" +dependencies = [ + "block-padding", + "generic-array 0.14.4", +] + +[[package]] +name = "block-padding" +version = "0.3.0-pre" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3992d179d1dd2fa87869057217d43cf88ad31d4e44738d159a5a6caafdf63ae6" dependencies = [ "generic-array 0.14.4", ] @@ -120,7 +130,7 @@ dependencies = [ "aead", "cipher", "crypto-mac", - "digest 0.10.0-pre", + "digest 0.10.0-pre.1", "elliptic-curve", "signature", "universal-hash", @@ -156,7 +166,7 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.0-pre" +version = "0.10.0-pre.1" dependencies = [ "blobby", "block-buffer 0.10.0-pre", diff --git a/digest/Cargo.toml b/digest/Cargo.toml index e41667c40..fdf97d138 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "digest" description = "Traits for cryptographic hash functions" -version = "0.10.0-pre" +version = "0.10.0-pre.1" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" @@ -21,6 +21,7 @@ alloc = [] std = ["alloc"] dev = ["blobby"] core-api = ["block-buffer"] +block-padding = ["block-buffer/block-padding"] [package.metadata.docs.rs] all-features = true diff --git a/digest/src/core_api.rs b/digest/src/core_api.rs index 8201ced45..f37e6a62b 100644 --- a/digest/src/core_api.rs +++ b/digest/src/core_api.rs @@ -1,7 +1,14 @@ use crate::{ExtendableOutput, FixedOutput, Reset, Update, XofReader}; use block_buffer::BlockBuffer; +use core::fmt; use generic_array::{ArrayLength, GenericArray}; +/// Trait which stores algorithm name constant, used in `Debug` implementations. +pub trait AlgorithmName { + /// Algorithm name. + const NAME: &'static str; +} + /// Trait for updating hasher state with input data divided into blocks. pub trait UpdateCore { /// Block size in bytes. @@ -15,9 +22,9 @@ pub trait UpdateCore { /// hash output. /// /// Usage of this trait in user code is discouraged. Instead use core algorithm -/// wrapped by [`crate::CoreWrapper`], which implements the [`FixedOutput`] +/// wrapped by [`BlockBufferWrapper`], which implements the [`FixedOutput`] /// trait. -pub trait FixedOutputCore: crate::UpdateCore { +pub trait FixedOutputCore: UpdateCore { /// Digest output size in bytes. type OutputSize: ArrayLength; @@ -38,9 +45,9 @@ pub trait FixedOutputCore: crate::UpdateCore { /// retrieve the hash output. /// /// Usage of this trait in user code is discouraged. Instead use core algorithm -/// wrapped by [`crate::CoreWrapper`], which implements the +/// wrapped by [`BlockBufferWrapper`], which implements the /// [`ExtendableOutput`] trait. -pub trait ExtendableOutputCore: crate::UpdateCore { +pub trait ExtendableOutputCore: UpdateCore { /// XOF reader core state. type ReaderCore: XofReaderCore; @@ -65,16 +72,39 @@ pub trait XofReaderCore { fn read_block(&mut self) -> GenericArray; } -/// Wrapper around core trait implementations. +/// Wrapper around [`UpdateCore`] implementations. +/// +/// It handles data buffering and implements the mid-level traits. +#[derive(Clone, Default)] +pub struct UpdateCoreWrapper { + core: T, + buffer: BlockBuffer, +} + +/// Wrapper around [`XofReaderCore`] implementations. /// /// It handles data buffering and implements the mid-level traits. #[derive(Clone, Default)] -pub struct CoreWrapper> { - core: C, - buffer: BlockBuffer, +pub struct XofReaderCoreWrapper { + core: T, + buffer: BlockBuffer, +} + +impl fmt::Debug for UpdateCoreWrapper { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + f.write_str(T::NAME)?; + f.write_str(" { .. }") + } +} + +impl fmt::Debug for XofReaderCoreWrapper { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + f.write_str(T::NAME)?; + f.write_str(" { .. }") + } } -impl Reset for CoreWrapper { +impl Reset for UpdateCoreWrapper { #[inline] fn reset(&mut self) { self.core.reset(); @@ -82,7 +112,7 @@ impl Reset for CoreWrapper { } } -impl Update for CoreWrapper { +impl Update for UpdateCoreWrapper { #[inline] fn update(&mut self, input: &[u8]) { let Self { core, buffer } = self; @@ -90,7 +120,7 @@ impl Update for CoreWrapper { } } -impl FixedOutput for CoreWrapper { +impl FixedOutput for UpdateCoreWrapper { type OutputSize = D::OutputSize; #[inline] @@ -107,7 +137,7 @@ impl FixedOutput for CoreWrapper { } } -impl XofReader for CoreWrapper { +impl XofReader for XofReaderCoreWrapper { #[inline] fn read(&mut self, buffer: &mut [u8]) { let Self { core, buffer: buf } = self; @@ -115,14 +145,14 @@ impl XofReader for CoreWrapper { } } -impl ExtendableOutput for CoreWrapper { - type Reader = CoreWrapper::BlockSize>; +impl ExtendableOutput for UpdateCoreWrapper { + type Reader = XofReaderCoreWrapper; #[inline] fn finalize_xof(mut self) -> Self::Reader { let Self { core, buffer } = &mut self; let reader_core = core.finalize_xof_core(buffer); - CoreWrapper { + XofReaderCoreWrapper { core: reader_core, buffer: Default::default(), } @@ -133,7 +163,7 @@ impl ExtendableOutput for CoreWrapper ExtendableOutput for CoreWrapper std::io::Write for CoreWrapper { +impl std::io::Write for UpdateCoreWrapper { #[inline] fn write(&mut self, buf: &[u8]) -> std::io::Result { Update::update(self, buf); @@ -155,7 +185,7 @@ impl std::io::Write for CoreWrapper { } #[cfg(feature = "std")] -impl std::io::Read for CoreWrapper { +impl std::io::Read for XofReaderCoreWrapper { #[inline] fn read(&mut self, buf: &mut [u8]) -> std::io::Result { XofReader::read(self, buf); diff --git a/digest/src/lib.rs b/digest/src/lib.rs index b93746e61..13a3683ed 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -11,11 +11,11 @@ //! These traits atomically describe available functionality of hash function //! implementations. //! - **Low-level traits**: [`UpdateCore`], [`FixedOutputCore`], -//! [`ExtendableOutputCore`]. These traits operate at a block-level and do not -//! contain any built-in buffering. They are intended to be implemented -//! by low-level algorithm providers only and simplify the amount of work -//! implementers need to do and therefore usually shouldn't be used in -//! application-level code. +//! [`ExtendableOutputCore`], [`AlgorithmName`]. These traits operate at +//! a block-level and do not contain any built-in buffering. They are intended +//! to be implemented by low-level algorithm providers only and simplify +//! the amount of work implementers need to do and therefore usually shouldn't +//! be used in application-level code. //! //! Additionally hash functions implement traits from the standard library: //! [`Default`], [`Clone`], [`Write`][std::io::Write]. The latter is @@ -54,7 +54,10 @@ mod digest; mod dyn_digest; #[cfg(feature = "core-api")] -pub use crate::core_api::{CoreWrapper, ExtendableOutputCore, FixedOutputCore, UpdateCore}; +pub use crate::core_api::{ + AlgorithmName, ExtendableOutputCore, FixedOutputCore, UpdateCore, UpdateCoreWrapper, + XofReaderCoreWrapper, +}; pub use crate::digest::{Digest, Output}; #[cfg(feature = "core-api")] pub use block_buffer; From 1920c9b278433a1e04e836f02aeb8fb0c0f796ba Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 19 Jan 2021 18:01:06 -0800 Subject: [PATCH 0386/1461] password-hash: bump `b64ct` to v0.2 (#482) --- Cargo.lock | 4 ++-- password-hash/Cargo.toml | 2 +- password-hash/src/errors.rs | 12 ++++++++++++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 95cf0a1a8..5cc7e4482 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -41,9 +41,9 @@ dependencies = [ [[package]] name = "b64ct" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a293adc36d315fd3f03a3c4a5594b0a30be4678cbae95ce9b430e9b8d6e34032" +checksum = "524df4b3f9e9925f37c0d9beec6fbc2dac691b188f3f331ab12c5587ebe6766e" [[package]] name = "bitvec" diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index 03a837c4b..1d206063f 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -16,7 +16,7 @@ categories = ["cryptography", "no-std"] keywords = ["crypt", "mcf", "password", "pbkdf", "phc"] [dependencies] -b64ct = "0.1" +b64ct = "0.2" [features] alloc = ["b64ct/alloc"] diff --git a/password-hash/src/errors.rs b/password-hash/src/errors.rs index 993b92837..967f22150 100644 --- a/password-hash/src/errors.rs +++ b/password-hash/src/errors.rs @@ -98,6 +98,12 @@ impl From for HasherError { } } +impl From for HasherError { + fn from(_: b64::InvalidLengthError) -> HasherError { + HasherError::B64(b64::Error::InvalidLength) + } +} + impl From for HasherError { fn from(err: OutputError) -> HasherError { HasherError::Output(err) @@ -218,6 +224,12 @@ impl From for OutputError { } } +impl From for OutputError { + fn from(_: b64::InvalidLengthError) -> OutputError { + OutputError::B64(b64::Error::InvalidLength) + } +} + #[cfg(feature = "std")] impl std::error::Error for OutputError {} From 0376c75f72a78d167da143aa68b407c4275ac8e9 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 21 Jan 2021 13:51:30 -0800 Subject: [PATCH 0387/1461] elliptic-curve: JWK support (#483) Generic implementation of JSON Web Keys (JWK) for the `"kty":"EC"` case as described in RFC 7518 Section 6: Cryptographic Algorithms for Keys. Uses `serde_json` for serialization with non-derived/minified implementations of serde's `Deserialize` and `Serialize` traits. The implementation is `no_std`-friendly, but requires `alloc`. --- .github/workflows/elliptic-curve.yml | 1 + Cargo.lock | 61 ++- elliptic-curve/Cargo.toml | 4 + elliptic-curve/src/dev.rs | 9 + elliptic-curve/src/error.rs | 2 +- elliptic-curve/src/jwk.rs | 778 +++++++++++++++++++++++++++ elliptic-curve/src/lib.rs | 10 +- elliptic-curve/src/ops.rs | 2 +- elliptic-curve/src/public_key.rs | 68 ++- elliptic-curve/src/scalar.rs | 2 +- elliptic-curve/src/secret_key.rs | 72 ++- 11 files changed, 982 insertions(+), 27 deletions(-) create mode 100644 elliptic-curve/src/jwk.rs diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index e5748876e..15d6cb6e9 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -39,6 +39,7 @@ jobs: - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features arithmetic - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features dev - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features ecdh + - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features jwk - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features pem - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features pkcs8 - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features zeroize diff --git a/Cargo.lock b/Cargo.lock index 5cc7e4482..209ab332c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,12 +11,13 @@ dependencies = [ [[package]] name = "as-slice" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37dfb65bc03b2bc85ee827004f14a6817e04160e3b1a28931986a666a9290e70" +checksum = "bb4d1c23475b74e3672afa8c2be22040b8b7783ad9b461021144ed10a46bb0e6" dependencies = [ "generic-array 0.12.3", "generic-array 0.13.2", + "generic-array 0.14.4", "stable_deref_trait", ] @@ -93,9 +94,9 @@ dependencies = [ [[package]] name = "byteorder" -version = "1.3.4" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" +checksum = "ae44d1a3d5a19df61dd0c8beb138458ac2a53a7ac09eba97d55592540004306b" [[package]] name = "cfg-if" @@ -177,6 +178,7 @@ dependencies = [ name = "elliptic-curve" version = "0.9.0-pre" dependencies = [ + "b64ct", "bitvec", "digest 0.9.0", "ff", @@ -185,6 +187,8 @@ dependencies = [ "hex-literal 0.3.1", "pkcs8", "rand_core", + "serde", + "serde_json", "subtle", "zeroize", ] @@ -202,9 +206,9 @@ dependencies = [ [[package]] name = "funty" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ba62103ce691c2fd80fbae2213dfdda9ce60804973ac6b6e97de818ea7f52c8" +checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" [[package]] name = "generic-array" @@ -291,6 +295,12 @@ dependencies = [ "proc-macro-hack", ] +[[package]] +name = "itoa" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" + [[package]] name = "opaque-debug" version = "0.3.0" @@ -317,24 +327,24 @@ dependencies = [ [[package]] name = "proc-macro-hack" -version = "0.5.18" +version = "0.5.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99c605b9a0adc77b7211c6b1f722dcb613d68d66859a44f3d485a6da332b0598" +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" [[package]] name = "proc-macro2" -version = "1.0.20" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "175c513d55719db99da20232b06cda8bab6b83ec2d04e3283edf0213c37c1a29" +checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" dependencies = [ "unicode-xid", ] [[package]] name = "quote" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" +checksum = "991431c3519a3f36861882da93630ce66b52918dcf1b8e2fd66b397fc96f28df" dependencies = [ "proc-macro2", ] @@ -351,6 +361,29 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c026d7df8b298d90ccbbc5190bd04d85e159eaf5576caeacf8741da93ccbd2e5" +[[package]] +name = "ryu" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" + +[[package]] +name = "serde" +version = "1.0.120" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "166b2349061381baf54a58e4b13c89369feb0ef2eaa57198899e2312aac30aab" + +[[package]] +name = "serde_json" +version = "1.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fceb2595057b6891a4ee808f70054bd2d12f0e97f1cbb78689b59f676df325a" +dependencies = [ + "itoa", + "ryu", + "serde", +] + [[package]] name = "sha2" version = "0.9.2" @@ -408,9 +441,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.40" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "963f7d3cc59b59b9325165add223142bbf1df27655d07789f109896d353d8350" +checksum = "cc60a3d73ea6594cd712d830cc1f0390fd71542d8c8cd24e70cc54cdfd5e05d5" dependencies = [ "proc-macro2", "quote", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index d78e19355..f22abe80f 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -15,6 +15,7 @@ categories = ["cryptography", "no-std"] keywords = ["crypto", "ecc", "elliptic", "weierstrass"] [dependencies] +b64ct = { version = "0.2", optional = true, default-features = false } bitvec = { version = "0.20", optional = true, default-features = false } digest = { version = "0.9", optional = true } ff = { version = "0.9", optional = true, default-features = false } @@ -22,6 +23,8 @@ group = { version = "0.9", optional = true, default-features = false } generic-array = { version = "0.14", default-features = false } pkcs8 = { version = "0.4.0-pre", optional = true } rand_core = { version = "0.6", default-features = false } +serde = { version = "1", optional = true, default-features = false } +serde_json = { version = "1", optional = true, default-features = false, features = ["alloc"] } subtle = { version = "2.4", default-features = false } zeroize = { version = "1", optional = true, default-features = false } @@ -34,6 +37,7 @@ alloc = [] arithmetic = ["bitvec", "ff", "group"] dev = ["arithmetic", "digest", "pem", "zeroize"] ecdh = ["arithmetic", "zeroize"] +jwk = ["alloc", "b64ct/alloc", "serde", "serde_json", "zeroize/alloc"] pem = ["alloc", "pkcs8/pem"] std = ["alloc"] diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index b928f9ff2..91e268381 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -21,6 +21,9 @@ use core::{ ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign}, }; +#[cfg(feature = "jwk")] +use crate::JwkParameters; + /// Mock elliptic curve type useful for writing tests which require a concrete /// curve type. /// @@ -44,6 +47,12 @@ impl AlgorithmParameters for MockCurve { const OID: pkcs8::ObjectIdentifier = pkcs8::ObjectIdentifier::new(&[1, 2, 840, 10045, 3, 1, 7]); } +#[cfg(feature = "jwk")] +#[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] +impl JwkParameters for MockCurve { + const CRV: &'static str = "P-256"; +} + /// SEC1 encoded point. pub type EncodedPoint = crate::sec1::EncodedPoint; diff --git a/elliptic-curve/src/error.rs b/elliptic-curve/src/error.rs index 15da4f90f..c00eaab7a 100644 --- a/elliptic-curve/src/error.rs +++ b/elliptic-curve/src/error.rs @@ -3,7 +3,7 @@ use core::fmt::{self, Display}; /// Elliptic curve errors -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, Eq, PartialEq)] pub struct Error; impl Display for Error { diff --git a/elliptic-curve/src/jwk.rs b/elliptic-curve/src/jwk.rs new file mode 100644 index 000000000..cc20bc64b --- /dev/null +++ b/elliptic-curve/src/jwk.rs @@ -0,0 +1,778 @@ +//! JSON Web Key (JWK) Support. +//! +//! Specified in RFC 7518 Section 6: Cryptographic Algorithms for Keys: +//! + +use crate::{ + sec1::{Coordinates, EncodedPoint, UncompressedPointSize, UntaggedPointSize}, + secret_key::{SecretKey, SecretValue}, + weierstrass::Curve, + Error, FieldBytes, +}; +use alloc::{ + borrow::ToOwned, + format, + string::{String, ToString}, +}; +use core::{ + convert::{TryFrom, TryInto}, + fmt::{self, Debug}, + marker::PhantomData, + ops::Add, + str::{self, FromStr}, +}; +use generic_array::{typenum::U1, ArrayLength}; +use serde::{de, ser, Deserialize, Serialize}; +use zeroize::{Zeroize, Zeroizing}; + +#[cfg(feature = "arithmetic")] +use crate::{ + ff::PrimeField, + public_key::PublicKey, + sec1::{FromEncodedPoint, ToEncodedPoint}, + AffinePoint, ProjectiveArithmetic, ProjectivePoint, Scalar, +}; + +/// Key Type (`kty`) for elliptic curve keys. +pub const EC_KTY: &str = "EC"; + +/// Deserialization error message. +const DE_ERROR_MSG: &str = "struct JwkEcKey with 5 elements"; + +/// Name of the JWK type +const JWK_TYPE_NAME: &str = "JwkEcKey"; + +/// Field names +const FIELDS: &[&str] = &["kty", "crv", "x", "y", "d"]; + +/// Elliptic curve parameters used by JSON Web Keys. +#[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] +pub trait JwkParameters: Curve { + /// The `crv` parameter which identifies a particular elliptic curve + /// as defined in RFC 7518 Section 6.2.1.1: + /// + /// + /// Curve values are registered in the IANA "JSON Web Key Elliptic Curve" + /// registry defined in RFC 7518 Section 7.6: + /// + const CRV: &'static str; +} + +/// JWK elliptic curve keys with a `kty` of `"EC"`. +/// +/// They can represent either a public/private keypair, or just a public key, +/// depending on whether or not the `d` parameter is present. +// TODO(tarcieri): eagerly decode or validate `x`, `y`, and `d` as Base64 +#[derive(Clone)] +#[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] +pub struct JwkEcKey { + /// The `crv` parameter which identifies a particular elliptic curve + /// as defined in RFC 7518 Section 6.2.1.1: + /// + crv: String, + + /// The x-coordinate of the elliptic curve point which is the public key + /// value associated with this JWK as defined in RFC 7518 6.2.1.2: + /// + x: String, + + /// The y-coordinate of the elliptic curve point which is the public key + /// value associated with this JWK as defined in RFC 7518 6.2.1.3: + /// + y: String, + + /// The `d` ECC private key parameter as described in RFC 7518 6.2.2.1: + /// + /// + /// Value is optional and if omitted, this JWK represents a private key. + /// + /// Inner value is encoded according to the `Integer-to-Octet-String` + /// conversion as defined in SEC1 section 2.3.7: + /// + d: Option, +} + +impl JwkEcKey { + /// Get the `crv` parameter for this JWK. + pub fn crv(&self) -> &str { + &self.crv + } + + /// Is this JWK a keypair that includes a private key? + pub fn is_keypair(&self) -> bool { + self.d.is_some() + } + + /// Does this JWK contain only a public key? + pub fn is_public_key(&self) -> bool { + self.d.is_none() + } + + /// Decode a JWK into a [`PublicKey`]. + #[cfg(feature = "arithmetic")] + #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] + pub fn to_public_key(&self) -> Result, Error> + where + C: Curve + JwkParameters + ProjectiveArithmetic, + AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, + ProjectivePoint: From>, + Scalar: PrimeField>, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, + { + self.try_into() + } + + /// Decode a JWK into a [`SecretKey`]. + #[cfg(feature = "arithmetic")] + #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] + pub fn to_secret_key(&self) -> Result, Error> + where + C: Curve + JwkParameters + SecretValue, + C::Secret: Clone + Zeroize, + FieldBytes: From, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, + { + self.try_into() + } +} + +impl FromStr for JwkEcKey { + type Err = Error; + + fn from_str(s: &str) -> Result { + serde_json::from_str(s).map_err(|_| Error) + } +} + +impl ToString for JwkEcKey { + fn to_string(&self) -> String { + serde_json::to_string(self).expect("JWK encoding error") + } +} + +impl TryFrom for EncodedPoint +where + C: Curve + JwkParameters, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + type Error = Error; + + fn try_from(jwk: JwkEcKey) -> Result, Error> { + (&jwk).try_into() + } +} + +impl TryFrom<&JwkEcKey> for EncodedPoint +where + C: Curve + JwkParameters, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + type Error = Error; + + fn try_from(jwk: &JwkEcKey) -> Result, Error> { + if jwk.crv != C::CRV { + return Err(Error); + } + + let x = decode_base64url_fe::(&jwk.x)?; + let y = decode_base64url_fe::(&jwk.y)?; + Ok(EncodedPoint::from_affine_coordinates(&x, &y, false)) + } +} + +impl TryFrom> for JwkEcKey +where + C: Curve + JwkParameters, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + type Error = Error; + + fn try_from(point: EncodedPoint) -> Result { + (&point).try_into() + } +} + +impl TryFrom<&EncodedPoint> for JwkEcKey +where + C: Curve + JwkParameters, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + type Error = Error; + + fn try_from(point: &EncodedPoint) -> Result { + match point.coordinates() { + Coordinates::Uncompressed { x, y } => Ok(JwkEcKey { + crv: C::CRV.to_owned(), + x: encode_base64url(x), + y: encode_base64url(y), + d: None, + }), + _ => Err(Error), + } + } +} + +impl TryFrom for SecretKey +where + C: Curve + JwkParameters + SecretValue, + C::Secret: Clone + Zeroize, + FieldBytes: From, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + type Error = Error; + + fn try_from(jwk: JwkEcKey) -> Result, Error> { + (&jwk).try_into() + } +} + +impl TryFrom<&JwkEcKey> for SecretKey +where + C: Curve + JwkParameters + SecretValue, + C::Secret: Clone + Zeroize, + FieldBytes: From, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + type Error = Error; + + fn try_from(jwk: &JwkEcKey) -> Result, Error> { + if let Some(d_base64) = &jwk.d { + // TODO(tarcieri): validate public key matches private key + let _pk = EncodedPoint::::try_from(jwk)?; + + let mut d_bytes = decode_base64url_fe::(d_base64)?; + let result = SecretKey::from_bytes(&d_bytes); + d_bytes.zeroize(); + result + } else { + Err(Error) + } + } +} + +#[cfg(feature = "arithmetic")] +#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] +impl From> for JwkEcKey +where + C: Curve + JwkParameters + ProjectiveArithmetic, + AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, + ProjectivePoint: From>, + Scalar: PrimeField> + Zeroize, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + fn from(sk: SecretKey) -> JwkEcKey { + (&sk).into() + } +} + +#[cfg(feature = "arithmetic")] +#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] +impl From<&SecretKey> for JwkEcKey +where + C: Curve + JwkParameters + ProjectiveArithmetic, + AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, + ProjectivePoint: From>, + Scalar: PrimeField> + Zeroize, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + fn from(sk: &SecretKey) -> JwkEcKey { + let mut jwk = sk.public_key().to_jwk(); + let mut d = sk.to_bytes(); + jwk.d = Some(encode_base64url(&d)); + d.zeroize(); + jwk + } +} + +#[cfg(feature = "arithmetic")] +#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] +impl TryFrom for PublicKey +where + C: Curve + JwkParameters + ProjectiveArithmetic, + AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, + ProjectivePoint: From>, + Scalar: PrimeField>, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + type Error = Error; + + fn try_from(jwk: JwkEcKey) -> Result, Error> { + (&jwk).try_into() + } +} + +#[cfg(feature = "arithmetic")] +#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] +impl TryFrom<&JwkEcKey> for PublicKey +where + C: Curve + JwkParameters + ProjectiveArithmetic, + AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, + ProjectivePoint: From>, + Scalar: PrimeField>, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + type Error = Error; + + fn try_from(jwk: &JwkEcKey) -> Result, Error> { + EncodedPoint::::try_from(jwk).and_then(PublicKey::try_from) + } +} + +#[cfg(feature = "arithmetic")] +#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] +impl From> for JwkEcKey +where + C: Curve + JwkParameters + ProjectiveArithmetic, + AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, + ProjectivePoint: From>, + Scalar: PrimeField>, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + fn from(pk: PublicKey) -> JwkEcKey { + (&pk).into() + } +} + +#[cfg(feature = "arithmetic")] +#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] +impl From<&PublicKey> for JwkEcKey +where + C: Curve + JwkParameters + ProjectiveArithmetic, + AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, + ProjectivePoint: From>, + Scalar: PrimeField>, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + fn from(pk: &PublicKey) -> JwkEcKey { + pk.to_encoded_point(false) + .try_into() + .expect("JWK encoding error") + } +} + +impl Debug for JwkEcKey { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let d = if self.d.is_some() { + "Some(...)" + } else { + "None" + }; + + // NOTE: this implementation omits the `d` private key parameter + f.debug_struct(JWK_TYPE_NAME) + .field("crv", &self.crv) + .field("x", &self.x) + .field("y", &self.y) + .field("d", &d) + .finish() + } +} + +impl PartialEq for JwkEcKey { + fn eq(&self, other: &Self) -> bool { + use subtle::ConstantTimeEq; + + // Compare private key in constant time + let d_eq = match &self.d { + Some(d1) => match &other.d { + Some(d2) => d1.as_bytes().ct_eq(d2.as_bytes()).into(), + None => other.d.is_none(), + }, + None => other.d.is_none(), + }; + + self.crv == other.crv && self.x == other.x && self.y == other.y && d_eq + } +} + +impl Eq for JwkEcKey {} + +impl Drop for JwkEcKey { + fn drop(&mut self) { + self.zeroize(); + } +} + +impl Zeroize for JwkEcKey { + fn zeroize(&mut self) { + if let Some(d) = &mut self.d { + d.zeroize(); + } + } +} + +impl<'de> Deserialize<'de> for JwkEcKey { + fn deserialize(deserializer: D) -> Result + where + D: de::Deserializer<'de>, + { + /// Field positions + enum Field { + Kty, + Crv, + X, + Y, + D, + } + + /// Field visitor + struct FieldVisitor; + + impl<'de> de::Visitor<'de> for FieldVisitor { + type Value = Field; + + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Formatter::write_str(formatter, "field identifier") + } + + fn visit_u64(self, value: u64) -> Result + where + E: de::Error, + { + match value { + 0 => Ok(Field::Kty), + 1 => Ok(Field::Crv), + 2 => Ok(Field::X), + 3 => Ok(Field::Y), + 4 => Ok(Field::D), + _ => Err(de::Error::invalid_value( + de::Unexpected::Unsigned(value), + &"field index 0 <= i < 5", + )), + } + } + + fn visit_str(self, value: &str) -> Result + where + E: de::Error, + { + self.visit_bytes(value.as_bytes()) + } + + fn visit_bytes(self, value: &[u8]) -> Result + where + E: de::Error, + { + match value { + b"kty" => Ok(Field::Kty), + b"crv" => Ok(Field::Crv), + b"x" => Ok(Field::X), + b"y" => Ok(Field::Y), + b"d" => Ok(Field::D), + _ => Err(de::Error::unknown_field( + &String::from_utf8_lossy(value), + FIELDS, + )), + } + } + } + + impl<'de> Deserialize<'de> for Field { + #[inline] + fn deserialize(__deserializer: D) -> Result + where + D: de::Deserializer<'de>, + { + de::Deserializer::deserialize_identifier(__deserializer, FieldVisitor) + } + } + + struct Visitor<'de> { + marker: PhantomData, + lifetime: PhantomData<&'de ()>, + } + + impl<'de> de::Visitor<'de> for Visitor<'de> { + type Value = JwkEcKey; + + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Formatter::write_str(formatter, "struct JwkEcKey") + } + + #[inline] + fn visit_seq(self, mut seq: A) -> Result + where + A: de::SeqAccess<'de>, + { + let kty = de::SeqAccess::next_element::(&mut seq)? + .ok_or_else(|| de::Error::invalid_length(0, &DE_ERROR_MSG))?; + + if kty != EC_KTY { + return Err(de::Error::custom(format!("unsupported JWK kty: {:?}", kty))); + } + + let crv = de::SeqAccess::next_element::(&mut seq)? + .ok_or_else(|| de::Error::invalid_length(1, &DE_ERROR_MSG))?; + + let x = de::SeqAccess::next_element::(&mut seq)? + .ok_or_else(|| de::Error::invalid_length(2, &DE_ERROR_MSG))?; + + let y = de::SeqAccess::next_element::(&mut seq)? + .ok_or_else(|| de::Error::invalid_length(3, &DE_ERROR_MSG))?; + + let d = de::SeqAccess::next_element::>(&mut seq)? + .ok_or_else(|| de::Error::invalid_length(4, &DE_ERROR_MSG))?; + + Ok(JwkEcKey { crv, x, y, d }) + } + + #[inline] + fn visit_map(self, mut map: A) -> Result + where + A: de::MapAccess<'de>, + { + let mut kty: Option = None; + let mut crv: Option = None; + let mut x: Option = None; + let mut y: Option = None; + let mut d: Option = None; + + while let Some(key) = de::MapAccess::next_key::(&mut map)? { + match key { + Field::Kty => { + if kty.is_none() { + kty = Some(de::MapAccess::next_value::(&mut map)?); + } else { + return Err(de::Error::duplicate_field(FIELDS[0])); + } + } + Field::Crv => { + if crv.is_none() { + crv = Some(de::MapAccess::next_value::(&mut map)?); + } else { + return Err(de::Error::duplicate_field(FIELDS[1])); + } + } + Field::X => { + if x.is_none() { + x = Some(de::MapAccess::next_value::(&mut map)?); + } else { + return Err(de::Error::duplicate_field(FIELDS[2])); + } + } + Field::Y => { + if y.is_none() { + y = Some(de::MapAccess::next_value::(&mut map)?); + } else { + return Err(de::Error::duplicate_field(FIELDS[3])); + } + } + Field::D => { + if d.is_none() { + d = de::MapAccess::next_value::>(&mut map)?; + } else { + return Err(de::Error::duplicate_field(FIELDS[4])); + } + } + } + } + + let kty = kty.ok_or_else(|| de::Error::missing_field("kty"))?; + + if kty != EC_KTY { + return Err(de::Error::custom(format!("unsupported JWK kty: {}", kty))); + } + + let crv = crv.ok_or_else(|| de::Error::missing_field("crv"))?; + let x = x.ok_or_else(|| de::Error::missing_field("x"))?; + let y = y.ok_or_else(|| de::Error::missing_field("y"))?; + + Ok(JwkEcKey { crv, x, y, d }) + } + } + + de::Deserializer::deserialize_struct( + deserializer, + JWK_TYPE_NAME, + FIELDS, + Visitor { + marker: PhantomData::, + lifetime: PhantomData, + }, + ) + } +} + +impl Serialize for JwkEcKey { + fn serialize(&self, serializer: S) -> Result + where + S: ser::Serializer, + { + use ser::SerializeStruct; + + let mut state = ser::Serializer::serialize_struct(serializer, JWK_TYPE_NAME, 5)?; + + for (i, field) in [EC_KTY, &self.crv, &self.x, &self.y].iter().enumerate() { + state.serialize_field(FIELDS[i], field)?; + } + + if let Some(d) = &self.d { + state.serialize_field("d", d)?; + } + + ser::SerializeStruct::end(state) + } +} + +/// Decode a Base64url-encoded field element +fn decode_base64url_fe(s: &str) -> Result, Error> { + let mut bytes = Zeroizing::new(s.as_bytes().to_vec()); + + // Translate Base64url to traditional Base64 + // TODO(tarcieri): constant time implementation (in `b64ct` crate?) + for byte in bytes.iter_mut() { + match *byte { + b'A'..=b'Z' | b'a'..=b'z' | b'0'..=b'9' => (), + b'-' => *byte = b'+', + b'_' => *byte = b'/', + _ => return Err(Error), + } + } + + let s = str::from_utf8(&bytes).map_err(|_| Error)?; + let mut result = FieldBytes::::default(); + b64ct::decode(s, &mut result).map_err(|_| Error)?; + Ok(result) +} + +/// Encode a field element as Base64url +fn encode_base64url(bytes: &[u8]) -> String { + let mut b64 = b64ct::encode_string(&bytes).into_bytes(); + + // Translate traditional Base64 to Base64url + // TODO(tarcieri): constant time implementation (in `b64ct` crate?) + for byte in b64.iter_mut() { + match *byte { + b'A'..=b'Z' | b'a'..=b'z' | b'0'..=b'9' => (), + b'+' => *byte = b'-', + b'/' => *byte = b'_', + _ => unreachable!(), // would be a bug in `b64ct` + } + } + + String::from_utf8(b64).unwrap() +} + +#[cfg(test)] +mod tests { + use super::*; + + #[cfg(feature = "dev")] + use crate::dev::MockCurve; + + /// Example private key. From RFC 7518 Appendix C: + /// + const JWK_PRIVATE_KEY: &str = r#" + { + "kty":"EC", + "crv":"P-256", + "x":"gI0GAILBdu7T53akrFmMyGcsF3n5dO7MmwNBHKW5SV0", + "y":"SLW_xSffzlPWrHEVI30DHM_4egVwt3NQqeUD7nMFpps", + "d":"0_NxaRPUMQoAJt50Gz8YiTr8gRTwyEaCumd-MToTmIo" + } + "#; + + /// Example public key. + const JWK_PUBLIC_KEY: &str = r#" + { + "kty":"EC", + "crv":"P-256", + "x":"gI0GAILBdu7T53akrFmMyGcsF3n5dO7MmwNBHKW5SV0", + "y":"SLW_xSffzlPWrHEVI30DHM_4egVwt3NQqeUD7nMFpps" + } + "#; + + /// Example unsupported JWK (RSA key) + const UNSUPPORTED_JWK: &str = r#" + { + "kty":"RSA", + "kid":"cc34c0a0-bd5a-4a3c-a50d-a2a7db7643df", + "use":"sig", + "n":"pjdss8ZaDfEH6K6U7GeW2nxDqR4IP049fk1fK0lndimbMMVBdPv_hSpm8T8EtBDxrUdi1OHZfMhUixGaut-3nQ4GG9nM249oxhCtxqqNvEXrmQRGqczyLxuh-fKn9Fg--hS9UpazHpfVAFnB5aCfXoNhPuI8oByyFKMKaOVgHNqP5NBEqabiLftZD3W_lsFCPGuzr4Vp0YS7zS2hDYScC2oOMu4rGU1LcMZf39p3153Cq7bS2Xh6Y-vw5pwzFYZdjQxDn8x8BG3fJ6j8TGLXQsbKH1218_HcUJRvMwdpbUQG5nvA2GXVqLqdwp054Lzk9_B_f1lVrmOKuHjTNHq48w", + "e":"AQAB", + "d":"ksDmucdMJXkFGZxiomNHnroOZxe8AmDLDGO1vhs-POa5PZM7mtUPonxwjVmthmpbZzla-kg55OFfO7YcXhg-Hm2OWTKwm73_rLh3JavaHjvBqsVKuorX3V3RYkSro6HyYIzFJ1Ek7sLxbjDRcDOj4ievSX0oN9l-JZhaDYlPlci5uJsoqro_YrE0PRRWVhtGynd-_aWgQv1YzkfZuMD-hJtDi1Im2humOWxA4eZrFs9eG-whXcOvaSwO4sSGbS99ecQZHM2TcdXeAs1PvjVgQ_dKnZlGN3lTWoWfQP55Z7Tgt8Nf1q4ZAKd-NlMe-7iqCFfsnFwXjSiaOa2CRGZn-Q", + "p":"4A5nU4ahEww7B65yuzmGeCUUi8ikWzv1C81pSyUKvKzu8CX41hp9J6oRaLGesKImYiuVQK47FhZ--wwfpRwHvSxtNU9qXb8ewo-BvadyO1eVrIk4tNV543QlSe7pQAoJGkxCia5rfznAE3InKF4JvIlchyqs0RQ8wx7lULqwnn0", + "q":"ven83GM6SfrmO-TBHbjTk6JhP_3CMsIvmSdo4KrbQNvp4vHO3w1_0zJ3URkmkYGhz2tgPlfd7v1l2I6QkIh4Bumdj6FyFZEBpxjE4MpfdNVcNINvVj87cLyTRmIcaGxmfylY7QErP8GFA-k4UoH_eQmGKGK44TRzYj5hZYGWIC8", + "dp":"lmmU_AG5SGxBhJqb8wxfNXDPJjf__i92BgJT2Vp4pskBbr5PGoyV0HbfUQVMnw977RONEurkR6O6gxZUeCclGt4kQlGZ-m0_XSWx13v9t9DIbheAtgVJ2mQyVDvK4m7aRYlEceFh0PsX8vYDS5o1txgPwb3oXkPTtrmbAGMUBpE", + "dq":"mxRTU3QDyR2EnCv0Nl0TCF90oliJGAHR9HJmBe__EjuCBbwHfcT8OG3hWOv8vpzokQPRl5cQt3NckzX3fs6xlJN4Ai2Hh2zduKFVQ2p-AF2p6Yfahscjtq-GY9cB85NxLy2IXCC0PF--Sq9LOrTE9QV988SJy_yUrAjcZ5MmECk", + "qi":"ldHXIrEmMZVaNwGzDF9WG8sHj2mOZmQpw9yrjLK9hAsmsNr5LTyqWAqJIYZSwPTYWhY4nu2O0EY9G9uYiqewXfCKw_UngrJt8Xwfq1Zruz0YY869zPN4GiE9-9rzdZB33RBw8kIOquY3MK74FMwCihYx_LiU2YTHkaoJ3ncvtvg" + } + "#; + + #[test] + fn parse_private_key() { + let jwk = JwkEcKey::from_str(JWK_PRIVATE_KEY).unwrap(); + assert_eq!(jwk.crv, "P-256"); + assert_eq!(jwk.x, "gI0GAILBdu7T53akrFmMyGcsF3n5dO7MmwNBHKW5SV0"); + assert_eq!(jwk.y, "SLW_xSffzlPWrHEVI30DHM_4egVwt3NQqeUD7nMFpps"); + assert_eq!( + jwk.d.as_ref().unwrap(), + "0_NxaRPUMQoAJt50Gz8YiTr8gRTwyEaCumd-MToTmIo" + ); + } + + #[test] + fn parse_public_key() { + let jwk = JwkEcKey::from_str(JWK_PUBLIC_KEY).unwrap(); + assert_eq!(jwk.crv, "P-256"); + assert_eq!(jwk.x, "gI0GAILBdu7T53akrFmMyGcsF3n5dO7MmwNBHKW5SV0"); + assert_eq!(jwk.y, "SLW_xSffzlPWrHEVI30DHM_4egVwt3NQqeUD7nMFpps"); + assert_eq!(jwk.d, None); + } + + #[test] + fn parse_unsupported() { + assert_eq!(JwkEcKey::from_str(UNSUPPORTED_JWK), Err(Error)); + } + + #[test] + fn serialize_private_key() { + let actual = JwkEcKey::from_str(JWK_PRIVATE_KEY).unwrap().to_string(); + let expected: String = JWK_PRIVATE_KEY.split_whitespace().collect(); + assert_eq!(actual, expected); + } + + #[test] + fn serialize_public_key() { + let actual = JwkEcKey::from_str(JWK_PUBLIC_KEY).unwrap().to_string(); + let expected: String = JWK_PUBLIC_KEY.split_whitespace().collect(); + assert_eq!(actual, expected); + } + + #[cfg(feature = "dev")] + #[test] + fn jwk_into_encoded_point() { + let jwk = JwkEcKey::from_str(JWK_PUBLIC_KEY).unwrap(); + let point = EncodedPoint::::try_from(&jwk).unwrap(); + let (x, y) = match point.coordinates() { + Coordinates::Uncompressed { x, y } => (x, y), + other => panic!("unexpected coordinates: {:?}", other), + }; + + assert_eq!(&decode_base64url_fe::(&jwk.x).unwrap(), x); + assert_eq!(&decode_base64url_fe::(&jwk.y).unwrap(), y); + } + + #[cfg(feature = "dev")] + #[test] + fn encoded_point_into_jwk() { + let jwk = JwkEcKey::from_str(JWK_PUBLIC_KEY).unwrap(); + let point = EncodedPoint::::try_from(&jwk).unwrap(); + let jwk2 = JwkEcKey::try_from(point).unwrap(); + assert_eq!(jwk, jwk2); + } +} diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 94c57d736..adf65564e 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -36,12 +36,12 @@ pub mod weierstrass; pub mod point; #[cfg(feature = "arithmetic")] #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] -pub mod public_key; +mod public_key; #[cfg(feature = "arithmetic")] #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub mod scalar; -#[cfg(any(feature = "dev"))] +#[cfg(feature = "dev")] #[cfg_attr(docsrs, doc(cfg(feature = "dev")))] pub mod dev; @@ -49,6 +49,9 @@ pub mod dev; #[cfg_attr(docsrs, doc(cfg(feature = "ecdh")))] pub mod ecdh; +#[cfg(feature = "jwk")] +mod jwk; + #[cfg(feature = "zeroize")] #[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] pub mod secret_key; @@ -73,6 +76,9 @@ pub use { #[cfg(feature = "digest")] pub use digest::{self, Digest}; +#[cfg(feature = "jwk")] +pub use crate::jwk::{JwkEcKey, JwkParameters}; + #[cfg(feature = "pkcs8")] pub use pkcs8; diff --git a/elliptic-curve/src/ops.rs b/elliptic-curve/src/ops.rs index fe6ffe75c..fee8fda98 100644 --- a/elliptic-curve/src/ops.rs +++ b/elliptic-curve/src/ops.rs @@ -1,4 +1,4 @@ -//! Traits for arithmetic operations on elliptic curve field elements +//! Traits for arithmetic operations on elliptic curve field elements. pub use core::ops::{Add, AddAssign, Mul, Neg, Sub, SubAssign}; diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index c93619343..863053cbb 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -18,6 +18,9 @@ use ff::PrimeField; use generic_array::ArrayLength; use group::{Curve as _, Group}; +#[cfg(feature = "jwk")] +use crate::{JwkEcKey, JwkParameters}; + #[cfg(feature = "pkcs8")] use { crate::{AlgorithmParameters, ALGORITHM_OID}, @@ -25,11 +28,10 @@ use { }; #[cfg(feature = "pem")] -use { - alloc::string::{String, ToString}, - core::str::FromStr, - pkcs8::ToPublicKey, -}; +use {core::str::FromStr, pkcs8::ToPublicKey}; + +#[cfg(any(feature = "jwk", feature = "pem"))] +use alloc::string::{String, ToString}; /// Elliptic curve public keys. /// @@ -61,8 +63,8 @@ use { pub struct PublicKey where C: Curve + ProjectiveArithmetic, - Scalar: PrimeField>, AffinePoint: Copy + Clone + Debug, + Scalar: PrimeField>, { point: AffinePoint, } @@ -70,9 +72,9 @@ where impl PublicKey where C: Curve + ProjectiveArithmetic, - Scalar: PrimeField>, AffinePoint: Copy + Clone + Debug, ProjectivePoint: From>, + Scalar: PrimeField>, { /// Convert an [`AffinePoint`] into a [`PublicKey`] pub fn from_affine(point: AffinePoint) -> Result { @@ -120,6 +122,58 @@ where pub fn to_projective(&self) -> ProjectivePoint { self.point.clone().into() } + + /// Parse a [`JwkEcKey`] JSON Web Key (JWK) into a [`PublicKey`]. + #[cfg(feature = "jwk")] + #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] + pub fn from_jwk(jwk: &JwkEcKey) -> Result + where + C: JwkParameters, + AffinePoint: Default + FromEncodedPoint + ToEncodedPoint, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, + { + jwk.try_into() + } + + /// Parse a string containing a JSON Web Key (JWK) into a [`PublicKey`]. + #[cfg(feature = "jwk")] + #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] + pub fn from_jwk_str(jwk: &str) -> Result + where + C: JwkParameters, + AffinePoint: Default + FromEncodedPoint + ToEncodedPoint, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, + { + jwk.parse::().and_then(|jwk| Self::from_jwk(&jwk)) + } + + /// Serialize this public key as [`JwkEcKey`] JSON Web Key (JWK). + #[cfg(feature = "jwk")] + #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] + pub fn to_jwk(&self) -> JwkEcKey + where + C: JwkParameters, + AffinePoint: Default + FromEncodedPoint + ToEncodedPoint, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, + { + self.into() + } + + /// Serialize this public key as JSON Web Key (JWK) string. + #[cfg(feature = "jwk")] + #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] + pub fn to_jwk_string(&self) -> String + where + C: JwkParameters, + AffinePoint: Default + FromEncodedPoint + ToEncodedPoint, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, + { + self.to_jwk().to_string() + } } impl AsRef> for PublicKey diff --git a/elliptic-curve/src/scalar.rs b/elliptic-curve/src/scalar.rs index 374a1a6a1..32ed613b6 100644 --- a/elliptic-curve/src/scalar.rs +++ b/elliptic-curve/src/scalar.rs @@ -1,4 +1,4 @@ -//! Scalar types +//! Scalar types. use crate::{ ops::Invert, diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 7aef7dd4e..f93bf47f9 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -1,4 +1,4 @@ -//! Secret keys for elliptic curves (i.e. private scalars) +//! Secret keys for elliptic curves (i.e. private scalars). //! //! The [`SecretKey`] type is a wrapper around a secret scalar value which is //! designed to prevent unintentional exposure (e.g. via `Debug` or other @@ -27,6 +27,20 @@ use crate::{ weierstrass, AffinePoint, ProjectiveArithmetic, ProjectivePoint, }; +#[cfg(feature = "jwk")] +use crate::{ + generic_array::{typenum::U1, ArrayLength}, + jwk::{JwkEcKey, JwkParameters}, + ops::Add, + sec1::{UncompressedPointSize, UntaggedPointSize}, +}; + +#[cfg(all(feature = "arithmetic", feature = "jwk"))] +use { + crate::sec1::{FromEncodedPoint, ToEncodedPoint}, + alloc::string::{String, ToString}, +}; + #[cfg(all(docsrs, feature = "pkcs8"))] use {crate::pkcs8::FromPrivateKey, core::str::FromStr}; @@ -131,6 +145,62 @@ where { PublicKey::from_secret_scalar(self.secret_scalar()) } + + /// Parse a [`JwkEcKey`] JSON Web Key (JWK) into a [`SecretKey`]. + #[cfg(feature = "jwk")] + #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] + pub fn from_jwk(jwk: &JwkEcKey) -> Result + where + C: JwkParameters, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, + { + jwk.try_into() + } + + /// Parse a string containing a JSON Web Key (JWK) into a [`SecretKey`]. + #[cfg(feature = "jwk")] + #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] + pub fn from_jwk_str(jwk: &str) -> Result + where + C: JwkParameters, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, + { + jwk.parse::().and_then(|jwk| Self::from_jwk(&jwk)) + } + + /// Serialize this secret key as [`JwkEcKey`] JSON Web Key (JWK). + #[cfg(all(feature = "arithmetic", feature = "jwk"))] + #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] + #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] + pub fn to_jwk(&self) -> JwkEcKey + where + C: JwkParameters + ProjectiveArithmetic, + AffinePoint: Copy + Debug + Default + FromEncodedPoint + ToEncodedPoint, + ProjectivePoint: From>, + Scalar: PrimeField> + Zeroize, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, + { + self.into() + } + + /// Serialize this secret key as JSON Web Key (JWK) string. + #[cfg(all(feature = "arithmetic", feature = "jwk"))] + #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] + #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] + pub fn to_jwk_string(&self) -> String + where + C: JwkParameters + ProjectiveArithmetic, + AffinePoint: Copy + Debug + Default + FromEncodedPoint + ToEncodedPoint, + ProjectivePoint: From>, + Scalar: PrimeField> + Zeroize, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, + { + self.to_jwk().to_string() + } } impl TryFrom<&[u8]> for SecretKey From 795c9a6eea641adaa35ea0d5c9dd0e0ae9aa8c9e Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 21 Jan 2021 14:00:43 -0800 Subject: [PATCH 0388/1461] elliptic-curve: remove direct `bitvec` dependency (#484) Now that zkcrypto/ff#40 is merged, the `ff` crate re-exports the types from `bitvec` that we previously needed to import directly. This means that `elliptic-curve` no-longer needs to depend on the `bitvec` crate directly, but instead we can use it only transitively via the `ff` crate. --- Cargo.lock | 1 - elliptic-curve/Cargo.toml | 3 +-- elliptic-curve/src/scalar.rs | 5 ++--- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 209ab332c..5127f008c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -179,7 +179,6 @@ name = "elliptic-curve" version = "0.9.0-pre" dependencies = [ "b64ct", - "bitvec", "digest 0.9.0", "ff", "generic-array 0.14.4", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index f22abe80f..730f2b5c3 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -16,7 +16,6 @@ keywords = ["crypto", "ecc", "elliptic", "weierstrass"] [dependencies] b64ct = { version = "0.2", optional = true, default-features = false } -bitvec = { version = "0.20", optional = true, default-features = false } digest = { version = "0.9", optional = true } ff = { version = "0.9", optional = true, default-features = false } group = { version = "0.9", optional = true, default-features = false } @@ -34,7 +33,7 @@ hex-literal = "0.3" [features] default = ["arithmetic"] alloc = [] -arithmetic = ["bitvec", "ff", "group"] +arithmetic = ["ff", "group"] dev = ["arithmetic", "digest", "pem", "zeroize"] ecdh = ["arithmetic", "zeroize"] jwk = ["alloc", "b64ct/alloc", "serde", "serde_json", "zeroize/alloc"] diff --git a/elliptic-curve/src/scalar.rs b/elliptic-curve/src/scalar.rs index 32ed613b6..611216d7e 100644 --- a/elliptic-curve/src/scalar.rs +++ b/elliptic-curve/src/scalar.rs @@ -5,9 +5,8 @@ use crate::{ rand_core::{CryptoRng, RngCore}, Curve, Error, FieldBytes, ProjectiveArithmetic, }; -use bitvec::{array::BitArray, order::Lsb0}; use core::{convert::TryFrom, ops::Deref}; -use ff::{Field, PrimeField}; +use ff::{Field, FieldBits, PrimeField}; use generic_array::{typenum::Unsigned, GenericArray}; use group::Group; use subtle::{Choice, ConditionallySelectable, CtOption}; @@ -19,7 +18,7 @@ use zeroize::Zeroize; pub type Scalar = <::ProjectivePoint as Group>::Scalar; /// Bit representation of a scalar field element of a given curve. -pub type ScalarBits = BitArray as PrimeField>::ReprBits>; +pub type ScalarBits = FieldBits< as PrimeField>::ReprBits>; /// Non-zero scalar type. /// From bb2c4f0b1baec38a03032f0d82239668ce393a6e Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 21 Jan 2021 15:35:58 -0800 Subject: [PATCH 0389/1461] elliptic-curve: add sec1::ValidatePublicKey trait (#485) Adds a trait for validating that a given encoded point is correct for a given secret value. This allows the PKCS#8 and JWK key format parsers to validate that the public key contained in a given keypair matches the corresponding private key. --- elliptic-curve/Cargo.toml | 3 +- elliptic-curve/src/dev.rs | 98 +++++++++++++++++++------- elliptic-curve/src/jwk.rs | 20 +++--- elliptic-curve/src/sec1.rs | 64 ++++++++++++++++- elliptic-curve/src/secret_key.rs | 10 +-- elliptic-curve/src/secret_key/pkcs8.rs | 19 ++--- elliptic-curve/tests/pkcs8.rs | 35 ++++----- 7 files changed, 176 insertions(+), 73 deletions(-) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 730f2b5c3..a47bdf942 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -19,6 +19,7 @@ b64ct = { version = "0.2", optional = true, default-features = false } digest = { version = "0.9", optional = true } ff = { version = "0.9", optional = true, default-features = false } group = { version = "0.9", optional = true, default-features = false } +hex-literal = { version = "0.3", optional = true } generic-array = { version = "0.14", default-features = false } pkcs8 = { version = "0.4.0-pre", optional = true } rand_core = { version = "0.6", default-features = false } @@ -34,7 +35,7 @@ hex-literal = "0.3" default = ["arithmetic"] alloc = [] arithmetic = ["ff", "group"] -dev = ["arithmetic", "digest", "pem", "zeroize"] +dev = ["arithmetic", "digest", "hex-literal", "pem", "zeroize"] ecdh = ["arithmetic", "zeroize"] jwk = ["alloc", "b64ct/alloc", "serde", "serde_json", "zeroize/alloc"] pem = ["alloc", "pkcs8/pem"] diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 91e268381..041126f42 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -20,10 +20,15 @@ use core::{ iter::Sum, ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign}, }; +use hex_literal::hex; #[cfg(feature = "jwk")] use crate::JwkParameters; +/// Pseudo-coordinate for fixed-based scalar mult output +pub const PSEUDO_COORDINATE_FIXED_BASE_MUL: [u8; 32] = + hex!("deadbeef00000000000000000000000000000000000000000000000000000001"); + /// Mock elliptic curve type useful for writing tests which require a concrete /// curve type. /// @@ -379,10 +384,19 @@ impl Scalar { } /// Example affine point type -#[derive(Clone, Copy, Debug)] -pub struct AffinePoint { - /// Wrap [`EncodedPoint`] to allow certain conversions - inner: EncodedPoint, +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum AffinePoint { + /// Result of fixed-based scalar multiplication + FixedBaseOutput(Scalar), + + /// Is this point the identity point? + Identity, + + /// Is this point the generator point? + Generator, + + /// Is this point a different point corresponding to a given [`EncodedPoint`] + Other(EncodedPoint), } impl ConditionallySelectable for AffinePoint { @@ -393,24 +407,36 @@ impl ConditionallySelectable for AffinePoint { impl Default for AffinePoint { fn default() -> Self { - Self { - inner: EncodedPoint::identity(), - } + Self::Identity } } impl FromEncodedPoint for AffinePoint { fn from_encoded_point(point: &EncodedPoint) -> Option { - Some(Self { inner: *point }) + if point.is_identity() { + Some(Self::Identity) + } else { + Some(Self::Other(*point)) + } } } impl ToEncodedPoint for AffinePoint { fn to_encoded_point(&self, compress: bool) -> EncodedPoint { - if compress == self.inner.is_compressed() { - self.inner - } else { - unimplemented!(); + match self { + Self::FixedBaseOutput(scalar) => EncodedPoint::from_affine_coordinates( + &scalar.to_repr(), + &PSEUDO_COORDINATE_FIXED_BASE_MUL.into(), + false, + ), + Self::Other(point) => { + if compress == point.is_compressed() { + *point + } else { + unimplemented!(); + } + } + _ => unimplemented!(), } } } @@ -425,22 +451,33 @@ impl Mul for AffinePoint { /// Example projective point type #[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub struct ProjectivePoint { - /// Is this point supposed to be the additive identity? - /// (a.k.a. point at infinity) - identity: bool, +pub enum ProjectivePoint { + /// Result of fixed-based scalar multiplication + FixedBaseOutput(Scalar), + + /// Is this point the identity point? + Identity, + + /// Is this point the generator point? + Generator, + + /// Is this point a different point corresponding to a given [`AffinePoint`] + Other(AffinePoint), } impl Default for ProjectivePoint { fn default() -> Self { - Self { identity: true } + Self::Identity } } impl From for ProjectivePoint { fn from(point: AffinePoint) -> ProjectivePoint { - Self { - identity: point.inner.is_identity(), + match point { + AffinePoint::FixedBaseOutput(scalar) => ProjectivePoint::FixedBaseOutput(scalar), + AffinePoint::Identity => ProjectivePoint::Identity, + AffinePoint::Generator => ProjectivePoint::Generator, + other => ProjectivePoint::Other(other), } } } @@ -465,15 +502,15 @@ impl group::Group for ProjectivePoint { } fn identity() -> Self { - unimplemented!(); + Self::Identity } fn generator() -> Self { - unimplemented!(); + Self::Generator } fn is_identity(&self) -> Choice { - Choice::from(self.identity as u8) + Choice::from((self == &Self::Identity) as u8) } #[must_use] @@ -486,7 +523,11 @@ impl group::Curve for ProjectivePoint { type AffineRepr = AffinePoint; fn to_affine(&self) -> AffinePoint { - unimplemented!(); + match self { + Self::FixedBaseOutput(scalar) => AffinePoint::FixedBaseOutput(*scalar), + Self::Other(affine) => *affine, + _ => unimplemented!(), + } } } @@ -617,16 +658,19 @@ impl SubAssign<&AffinePoint> for ProjectivePoint { impl Mul for ProjectivePoint { type Output = ProjectivePoint; - fn mul(self, _other: Scalar) -> ProjectivePoint { - unimplemented!(); + fn mul(self, scalar: Scalar) -> ProjectivePoint { + match self { + Self::Generator => Self::FixedBaseOutput(scalar), + _ => unimplemented!(), + } } } impl Mul<&Scalar> for ProjectivePoint { type Output = ProjectivePoint; - fn mul(self, _other: &Scalar) -> ProjectivePoint { - unimplemented!(); + fn mul(self, scalar: &Scalar) -> ProjectivePoint { + self * *scalar } } diff --git a/elliptic-curve/src/jwk.rs b/elliptic-curve/src/jwk.rs index cc20bc64b..8ef041f92 100644 --- a/elliptic-curve/src/jwk.rs +++ b/elliptic-curve/src/jwk.rs @@ -4,7 +4,9 @@ //! use crate::{ - sec1::{Coordinates, EncodedPoint, UncompressedPointSize, UntaggedPointSize}, + sec1::{ + Coordinates, EncodedPoint, UncompressedPointSize, UntaggedPointSize, ValidatePublicKey, + }, secret_key::{SecretKey, SecretValue}, weierstrass::Curve, Error, FieldBytes, @@ -128,7 +130,7 @@ impl JwkEcKey { #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub fn to_secret_key(&self) -> Result, Error> where - C: Curve + JwkParameters + SecretValue, + C: Curve + JwkParameters + ValidatePublicKey + SecretValue, C::Secret: Clone + Zeroize, FieldBytes: From, UntaggedPointSize: Add + ArrayLength, @@ -220,7 +222,7 @@ where impl TryFrom for SecretKey where - C: Curve + JwkParameters + SecretValue, + C: Curve + JwkParameters + ValidatePublicKey + SecretValue, C::Secret: Clone + Zeroize, FieldBytes: From, UntaggedPointSize: Add + ArrayLength, @@ -235,7 +237,7 @@ where impl TryFrom<&JwkEcKey> for SecretKey where - C: Curve + JwkParameters + SecretValue, + C: Curve + JwkParameters + ValidatePublicKey + SecretValue, C::Secret: Clone + Zeroize, FieldBytes: From, UntaggedPointSize: Add + ArrayLength, @@ -245,13 +247,15 @@ where fn try_from(jwk: &JwkEcKey) -> Result, Error> { if let Some(d_base64) = &jwk.d { - // TODO(tarcieri): validate public key matches private key - let _pk = EncodedPoint::::try_from(jwk)?; - + let pk = EncodedPoint::::try_from(jwk)?; let mut d_bytes = decode_base64url_fe::(d_base64)?; let result = SecretKey::from_bytes(&d_bytes); d_bytes.zeroize(); - result + + result.and_then(|secret_key| { + C::validate_public_key(&secret_key, &pk)?; + Ok(secret_key) + }) } else { Err(Error) } diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index 976812023..1e1f3d80b 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -27,11 +27,14 @@ use crate::{ #[cfg(all(feature = "arithmetic", feature = "zeroize"))] use crate::{ group::{Curve as _, Group}, - secret_key::SecretKey, + ProjectivePoint, }; #[cfg(feature = "zeroize")] -use zeroize::Zeroize; +use crate::{ + secret_key::{SecretKey, SecretValue}, + zeroize::Zeroize, +}; /// Size of a compressed point for the given elliptic curve when encoded /// using the SEC1 `Elliptic-Curve-Point-to-Octet-String` algorithm @@ -490,6 +493,63 @@ where fn to_encoded_point(&self, compress: bool) -> EncodedPoint; } +/// Validate that the given [`EncodedPoint`] represents the encoded public key +/// value of the given secret. +/// +/// Curve implementations which also impl [`ProjectiveArithmetic`] will receive +/// a blanket default impl of this trait. +#[cfg(feature = "zeroize")] +#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] +pub trait ValidatePublicKey +where + Self: Curve + SecretValue, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + /// Validate that the given [`EncodedPoint`] is a valid public key for the + /// provided secret value. + #[allow(unused_variables)] + fn validate_public_key( + secret_key: &SecretKey, + public_key: &EncodedPoint, + ) -> Result<(), Error> { + // Provide a default "always succeeds" implementation. + // This is the intended default for curve implementations which + // do not provide an arithmetic implementation, since they have no + // way to verify this. + // + // Implementations with an arithmetic impl will receive a blanket impl + // of this trait. + Ok(()) + } +} + +#[cfg(all(feature = "arithmetic", feature = "zeroize"))] +impl ValidatePublicKey for C +where + C: Curve + ProjectiveArithmetic, + AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, + ProjectivePoint: From>, + Scalar: PrimeField> + Zeroize, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + fn validate_public_key( + secret_key: &SecretKey, + public_key: &EncodedPoint, + ) -> Result<(), Error> { + let pk = secret_key + .public_key() + .to_encoded_point(public_key.is_compressed()); + + if public_key == &pk { + Ok(()) + } else { + Err(Error) + } + } +} + #[cfg(test)] mod tests { use super::{Coordinates, Tag}; diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index f93bf47f9..2fa391a64 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -32,7 +32,7 @@ use crate::{ generic_array::{typenum::U1, ArrayLength}, jwk::{JwkEcKey, JwkParameters}, ops::Add, - sec1::{UncompressedPointSize, UntaggedPointSize}, + sec1::{UncompressedPointSize, UntaggedPointSize, ValidatePublicKey}, }; #[cfg(all(feature = "arithmetic", feature = "jwk"))] @@ -139,9 +139,9 @@ where pub fn public_key(&self) -> PublicKey where C: weierstrass::Curve + ProjectiveArithmetic + SecretValue>, - Scalar: PrimeField> + Zeroize, AffinePoint: Copy + Clone + Debug + Default, ProjectivePoint: From>, + Scalar: PrimeField> + Zeroize, { PublicKey::from_secret_scalar(self.secret_scalar()) } @@ -151,7 +151,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] pub fn from_jwk(jwk: &JwkEcKey) -> Result where - C: JwkParameters, + C: JwkParameters + ValidatePublicKey, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -163,7 +163,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] pub fn from_jwk_str(jwk: &str) -> Result where - C: JwkParameters, + C: JwkParameters + ValidatePublicKey, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -256,7 +256,7 @@ pub trait SecretValue: Curve { type Secret: Into> + Zeroize; /// Parse the secret value from bytes - // TODO(tarcieri): make this constant time? + // TODO(tarcieri): make this a `CtOption`? fn from_secret_bytes(bytes: &FieldBytes) -> Option; } diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs index 21044a127..85ef57677 100644 --- a/elliptic-curve/src/secret_key/pkcs8.rs +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -2,7 +2,7 @@ use super::{SecretKey, SecretValue}; use crate::{ - sec1::{self, UncompressedPointSize, UntaggedPointSize}, + sec1::{self, UncompressedPointSize, UntaggedPointSize, ValidatePublicKey}, weierstrass, AlgorithmParameters, FieldBytes, ALGORITHM_OID, }; use core::ops::Add; @@ -43,7 +43,7 @@ const ENCODING_ERROR_MSG: &str = "DER encoding error"; #[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))] impl FromPrivateKey for SecretKey where - C: weierstrass::Curve + AlgorithmParameters + SecretValue, + C: weierstrass::Curve + AlgorithmParameters + ValidatePublicKey + SecretValue, C::Secret: Clone + Zeroize, FieldBytes: From, UntaggedPointSize: Add + ArrayLength, @@ -82,15 +82,16 @@ where let public_key_bytes = der::Decoder::new(public_key_field.as_bytes()).bit_string()?; - // TODO(tarcieri): validate public key matches secret key - if sec1::EncodedPoint::::from_bytes(public_key_bytes.as_ref()).is_err() { - return Err(der::ErrorKind::Value { - tag: der::Tag::BitString, + if let Ok(pk) = sec1::EncodedPoint::::from_bytes(public_key_bytes.as_ref()) { + if C::validate_public_key(&secret_key, &pk).is_ok() { + return Ok(secret_key); } - .into()); } - Ok(secret_key) + Err(der::ErrorKind::Value { + tag: der::Tag::BitString, + } + .into()) })?; Ok(decoder.finish(result)?) @@ -156,7 +157,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "pem")))] impl FromStr for SecretKey where - C: weierstrass::Curve + AlgorithmParameters + SecretValue, + C: weierstrass::Curve + AlgorithmParameters + ValidatePublicKey + SecretValue, C::Secret: Clone + Zeroize, FieldBytes: From, UntaggedPointSize: Add + ArrayLength, diff --git a/elliptic-curve/tests/pkcs8.rs b/elliptic-curve/tests/pkcs8.rs index f0ced6423..8f028e056 100644 --- a/elliptic-curve/tests/pkcs8.rs +++ b/elliptic-curve/tests/pkcs8.rs @@ -7,27 +7,30 @@ use elliptic_curve::{ sec1::ToEncodedPoint, }; use hex_literal::hex; -use pkcs8::{FromPrivateKey, FromPublicKey}; - -/// DER-encoded PKCS#8 private key -const PKCS8_PRIVATE_KEY_DER: &[u8; 138] = include_bytes!("examples/pkcs8-private-key.der"); +use pkcs8::{FromPrivateKey, FromPublicKey, PrivateKeyDocument, ToPrivateKey}; /// DER-encoded PKCS#8 public key const PKCS8_PUBLIC_KEY_DER: &[u8; 91] = include_bytes!("examples/pkcs8-public-key.der"); -/// PEM-encoded PKCS#8 private key -#[cfg(feature = "pem")] -const PKCS8_PRIVATE_KEY_PEM: &str = include_str!("examples/pkcs8-private-key.pem"); - /// PEM-encoded PKCS#8 public key #[cfg(feature = "pem")] const PKCS8_PUBLIC_KEY_PEM: &str = include_str!("examples/pkcs8-public-key.pem"); +/// Example encoded scalar value +const EXAMPLE_SCALAR: [u8; 32] = + hex!("AABBCCDDEEFF0000000000000000000000000000000000000000000000000001"); + +/// Example PKCS#8 private key +fn example_private_key() -> PrivateKeyDocument { + SecretKey::from_bytes(&EXAMPLE_SCALAR) + .unwrap() + .to_pkcs8_der() +} + #[test] fn decode_pkcs8_private_key_from_der() { - let secret_key = SecretKey::from_pkcs8_der(&PKCS8_PRIVATE_KEY_DER[..]).unwrap(); - let expected_scalar = hex!("69624171561A63340DE0E7D869F2A05492558E1A04868B6A9F854A866788188D"); - assert_eq!(secret_key.to_bytes().as_slice(), &expected_scalar[..]); + let secret_key = SecretKey::from_pkcs8_der(example_private_key().as_ref()).unwrap(); + assert_eq!(secret_key.to_bytes().as_slice(), &EXAMPLE_SCALAR); } #[test] @@ -40,16 +43,6 @@ fn decode_pkcs8_public_key_from_der() { ); } -#[test] -#[cfg(feature = "pem")] -fn decode_pkcs8_private_key_from_pem() { - let secret_key = PKCS8_PRIVATE_KEY_PEM.parse::().unwrap(); - - // Ensure key parses equivalently to DER - let der_key = SecretKey::from_pkcs8_der(&PKCS8_PRIVATE_KEY_DER[..]).unwrap(); - assert_eq!(secret_key.to_bytes(), der_key.to_bytes()); -} - #[test] #[cfg(feature = "pem")] fn decode_pkcs8_public_key_from_pem() { From 005182ecb896937ba057a0fd6e7102b470792530 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 21 Jan 2021 18:10:06 -0800 Subject: [PATCH 0390/1461] elliptic-curve: leverage `der` crate's uint support (#486) Added in recent prereleases --- Cargo.lock | 29 ++++++++++---------------- Cargo.toml | 3 +++ elliptic-curve/src/jwk.rs | 2 +- elliptic-curve/src/secret_key/pkcs8.rs | 11 ++++------ 4 files changed, 19 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5127f008c..b80473c20 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -46,6 +46,11 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "524df4b3f9e9925f37c0d9beec6fbc2dac691b188f3f331ab12c5587ebe6766e" +[[package]] +name = "b64ct" +version = "0.2.0" +source = "git+https://github.com/RustCrypto/utils.git#b2b5fb554fad25071f4268bc6e8fb3d6def4bc7e" + [[package]] name = "bitvec" version = "0.20.1" @@ -115,8 +120,7 @@ dependencies = [ [[package]] name = "const-oid" version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5d82796b70971fbb603900a5edc797a4d9be0f9ec1257f83a1dba0aa374e3e9" +source = "git+https://github.com/RustCrypto/utils.git#b2b5fb554fad25071f4268bc6e8fb3d6def4bc7e" [[package]] name = "cpuid-bool" @@ -150,8 +154,7 @@ dependencies = [ [[package]] name = "der" version = "0.2.0-pre" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce3c2453c3322800962d0630f6e4e64a398ffea370e43a4ceb24d02f724441f4" +source = "git+https://github.com/RustCrypto/utils.git#b2b5fb554fad25071f4268bc6e8fb3d6def4bc7e" dependencies = [ "const-oid", ] @@ -178,7 +181,7 @@ dependencies = [ name = "elliptic-curve" version = "0.9.0-pre" dependencies = [ - "b64ct", + "b64ct 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "digest 0.9.0", "ff", "generic-array 0.14.4", @@ -310,17 +313,16 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" name = "password-hash" version = "0.0.0" dependencies = [ - "b64ct", + "b64ct 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "pkcs8" version = "0.4.0-pre" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9df125c6bec8ba2195e9ef3064e610c9aa00362b38f502ca348e4383eaeef102" +source = "git+https://github.com/RustCrypto/utils.git#b2b5fb554fad25071f4268bc6e8fb3d6def4bc7e" dependencies = [ + "b64ct 0.2.0 (git+https://github.com/RustCrypto/utils.git)", "der", - "subtle-encoding", "zeroize", ] @@ -429,15 +431,6 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e81da0851ada1f3e9d4312c704aa4f8806f0f9d69faaf8df2f3464b4a9437c2" -[[package]] -name = "subtle-encoding" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dcb1ed7b8330c5eed5441052651dd7a12c75e2ed88f2ec024ae1fa3a5e59945" -dependencies = [ - "zeroize", -] - [[package]] name = "syn" version = "1.0.58" diff --git a/Cargo.toml b/Cargo.toml index 9db9bf636..399bf302b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,3 +11,6 @@ members = [ "signature/async", "universal-hash", ] + +[patch.crates-io] +pkcs8 = { git = "https://github.com/RustCrypto/utils.git" } diff --git a/elliptic-curve/src/jwk.rs b/elliptic-curve/src/jwk.rs index 8ef041f92..af6083385 100644 --- a/elliptic-curve/src/jwk.rs +++ b/elliptic-curve/src/jwk.rs @@ -618,7 +618,7 @@ impl Serialize for JwkEcKey { { use ser::SerializeStruct; - let mut state = ser::Serializer::serialize_struct(serializer, JWK_TYPE_NAME, 5)?; + let mut state = serializer.serialize_struct(JWK_TYPE_NAME, 5)?; for (i, field) in [EC_KTY, &self.crv, &self.x, &self.y].iter().enumerate() { state.serialize_field(FIELDS[i], field)?; diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs index 85ef57677..45444ec2c 100644 --- a/elliptic-curve/src/secret_key/pkcs8.rs +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -7,10 +7,7 @@ use crate::{ }; use core::ops::Add; use generic_array::{typenum::U1, ArrayLength}; -use pkcs8::{ - der::{self, Decodable}, - FromPrivateKey, -}; +use pkcs8::{der, FromPrivateKey}; use zeroize::Zeroize; // Imports for the `ToPrivateKey` impl @@ -34,7 +31,7 @@ use { use {crate::error::Error, core::str::FromStr}; /// Version -const VERSION: i8 = 1; +const VERSION: u8 = 1; /// Encoding error message #[cfg(all(feature = "arithmetic", feature = "pem"))] @@ -61,7 +58,7 @@ where let mut decoder = der::Decoder::new(private_key_info.private_key); let result = decoder.sequence(|decoder| { - if i8::decode(decoder)? != VERSION { + if decoder.uint8()? != VERSION { return Err(der::ErrorKind::Value { tag: der::Tag::Integer, } @@ -107,9 +104,9 @@ where impl ToPrivateKey for SecretKey where C: weierstrass::Curve + AlgorithmParameters + ProjectiveArithmetic, - Scalar: PrimeField> + Zeroize, AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, ProjectivePoint: From>, + Scalar: PrimeField> + Zeroize, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { From 79281260b3dd05b59ded7452a4788be5ab160e46 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 21 Jan 2021 18:36:47 -0800 Subject: [PATCH 0391/1461] elliptic-curve: factor out `hazmat`; flatten API (#487) Flattens out the API, hiding nested modules except in places where they provide actual value. Moves some of the more problematic/confusing traits under a `hazmat` feature intended for use by curve implementations only. --- .github/workflows/elliptic-curve.yml | 3 ++- elliptic-curve/Cargo.toml | 3 ++- elliptic-curve/src/ecdh.rs | 6 +++--- elliptic-curve/src/lib.rs | 17 ++++++++--------- elliptic-curve/src/point.rs | 3 +++ elliptic-curve/src/public_key.rs | 1 + elliptic-curve/src/scalar.rs | 3 +++ elliptic-curve/src/sec1.rs | 4 ++-- elliptic-curve/src/secret_key.rs | 6 ++++++ 9 files changed, 30 insertions(+), 16 deletions(-) diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index 15d6cb6e9..301ebb930 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -39,11 +39,12 @@ jobs: - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features arithmetic - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features dev - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features ecdh + - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features hazmat - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features jwk - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features pem - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features pkcs8 - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features zeroize - - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features pem,zeroize + - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features ecdh,hazmat,jwk,pem test: runs-on: ubuntu-latest strategy: diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index a47bdf942..5e9b262dc 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -37,10 +37,11 @@ alloc = [] arithmetic = ["ff", "group"] dev = ["arithmetic", "digest", "hex-literal", "pem", "zeroize"] ecdh = ["arithmetic", "zeroize"] +hazmat = [] jwk = ["alloc", "b64ct/alloc", "serde", "serde_json", "zeroize/alloc"] pem = ["alloc", "pkcs8/pem"] std = ["alloc"] [package.metadata.docs.rs] -all-features = true +features = ["arithmetic", "ecdh", "jwk", "pem", "std"] rustdoc-args = ["--cfg", "docsrs"] diff --git a/elliptic-curve/src/ecdh.rs b/elliptic-curve/src/ecdh.rs index ca54775dd..207e80968 100644 --- a/elliptic-curve/src/ecdh.rs +++ b/elliptic-curve/src/ecdh.rs @@ -62,9 +62,9 @@ pub fn diffie_hellman( ) -> SharedSecret where C: Curve + ProjectiveArithmetic, - Scalar: PrimeField> + Clone + Zeroize, AffinePoint: Copy + Clone + Debug + Zeroize, ProjectivePoint: From>, + Scalar: PrimeField> + Clone + Zeroize, SharedSecret: for<'a> From<&'a AffinePoint>, { let public_point = ProjectivePoint::::from(*public_key.borrow()); @@ -106,9 +106,9 @@ where impl EphemeralSecret where C: Curve + ProjectiveArithmetic, - Scalar: PrimeField> + Clone + Zeroize, AffinePoint: Copy + Clone + Debug + Zeroize, ProjectivePoint: From>, + Scalar: PrimeField> + Clone + Zeroize, SharedSecret: for<'a> From<&'a AffinePoint>, { /// Generate a cryptographically random [`EphemeralSecret`]. @@ -135,9 +135,9 @@ where impl From<&EphemeralSecret> for PublicKey where C: Curve + ProjectiveArithmetic, - Scalar: PrimeField> + Clone + Zeroize, AffinePoint: Copy + Clone + Debug + Zeroize, ProjectivePoint: From>, + Scalar: PrimeField> + Clone + Zeroize, SharedSecret: for<'a> From<&'a AffinePoint>, { fn from(ephemeral_secret: &EphemeralSecret) -> Self { diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index adf65564e..7e21dd206 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -25,21 +25,18 @@ extern crate alloc; #[cfg(feature = "std")] extern crate std; -pub mod error; +mod error; pub mod ops; pub mod sec1; pub mod util; pub mod weierstrass; #[cfg(feature = "arithmetic")] -#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] -pub mod point; +mod point; #[cfg(feature = "arithmetic")] -#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] mod public_key; #[cfg(feature = "arithmetic")] -#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] -pub mod scalar; +mod scalar; #[cfg(feature = "dev")] #[cfg_attr(docsrs, doc(cfg(feature = "dev")))] @@ -53,8 +50,7 @@ pub mod ecdh; mod jwk; #[cfg(feature = "zeroize")] -#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] -pub mod secret_key; +mod secret_key; pub use self::error::Error; @@ -67,7 +63,7 @@ pub use { crate::{ point::{AffinePoint, ProjectiveArithmetic, ProjectivePoint}, public_key::PublicKey, - scalar::Scalar, + scalar::{NonZeroScalar, Scalar, ScalarBits}, }, ff::{self, BitView, Field}, group::{self, Group}, @@ -76,6 +72,9 @@ pub use { #[cfg(feature = "digest")] pub use digest::{self, Digest}; +#[cfg(all(feature = "hazmat", feature = "zeroize"))] +pub use secret_key::{SecretBytes, SecretValue}; + #[cfg(feature = "jwk")] pub use crate::jwk::{JwkEcKey, JwkParameters}; diff --git a/elliptic-curve/src/point.rs b/elliptic-curve/src/point.rs index 8003b0eb8..0365fd2af 100644 --- a/elliptic-curve/src/point.rs +++ b/elliptic-curve/src/point.rs @@ -3,6 +3,7 @@ use crate::{Curve, FieldBytes, Scalar}; /// Elliptic curve with projective arithmetic implementation. +#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub trait ProjectiveArithmetic: Curve where Scalar: ff::PrimeField>, @@ -13,9 +14,11 @@ where /// Affine point type for a given curve with a [`ProjectiveArithmetic`] /// implementation. +#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub type AffinePoint = <::ProjectivePoint as group::Curve>::AffineRepr; /// Projective point type for a given curve with a [`ProjectiveArithmetic`] /// implementation. +#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub type ProjectivePoint = ::ProjectivePoint; diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index 863053cbb..7765dd18c 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -59,6 +59,7 @@ use alloc::string::{String, ToString}; /// /// When the `pem` feature of this crate (or a specific RustCrypto elliptic /// curve crate) is enabled, a [`FromStr`] impl is also available. +#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] #[derive(Clone, Debug)] pub struct PublicKey where diff --git a/elliptic-curve/src/scalar.rs b/elliptic-curve/src/scalar.rs index 611216d7e..48db77f1a 100644 --- a/elliptic-curve/src/scalar.rs +++ b/elliptic-curve/src/scalar.rs @@ -15,9 +15,11 @@ use subtle::{Choice, ConditionallySelectable, CtOption}; use zeroize::Zeroize; /// Scalar field element for a particular elliptic curve. +#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub type Scalar = <::ProjectivePoint as Group>::Scalar; /// Bit representation of a scalar field element of a given curve. +#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub type ScalarBits = FieldBits< as PrimeField>::ReprBits>; /// Non-zero scalar type. @@ -28,6 +30,7 @@ pub type ScalarBits = FieldBits< as PrimeField>::ReprBits>; /// /// In the context of ECC, it's useful for ensuring that scalar multiplication /// cannot result in the point at infinity. +#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] #[derive(Clone)] pub struct NonZeroScalar where diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index 1e1f3d80b..238df206e 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -173,8 +173,8 @@ where pub fn to_untagged_bytes(&self) -> Option>> where C: Curve + ProjectiveArithmetic, - Scalar: PrimeField>, AffinePoint: ConditionallySelectable + Default + Decompress + ToEncodedPoint, + Scalar: PrimeField>, { self.decompress().map(|point| { let mut bytes = GenericArray::>::default(); @@ -466,10 +466,10 @@ impl From for u8 { /// This is intended for use with the `AffinePoint` type for a given elliptic curve. pub trait FromEncodedPoint where + Self: Sized, C: Curve, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, - Self: Sized, { /// Deserialize the type this trait is impl'd on from an [`EncodedPoint`]. /// diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 2fa391a64..0c3c81831 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -70,6 +70,7 @@ use {crate::pkcs8::FromPrivateKey, core::str::FromStr}; /// /// When the `pem` feature of this crate (or a specific RustCrypto elliptic /// curve crate) is enabled, a [`FromStr`] impl is also available. +#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] #[derive(Clone)] pub struct SecretKey { /// Secret value (i.e. secret scalar) @@ -236,6 +237,8 @@ where } /// Inner value stored by a [`SecretKey`]. +#[cfg_attr(docsrs, doc(cfg(feature = "hazmat")))] +#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] pub trait SecretValue: Curve { /// Inner secret value. /// @@ -261,6 +264,7 @@ pub trait SecretValue: Curve { } #[cfg(feature = "arithmetic")] +#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] impl SecretValue for C where C: Curve + ProjectiveArithmetic, @@ -276,6 +280,8 @@ where /// Newtype wrapper for [`FieldBytes`] which impls [`Zeroize`]. /// /// This allows it to fulfill the [`Zeroize`] bound on [`SecretValue::Secret`]. +#[cfg_attr(docsrs, doc(cfg(feature = "hazmat")))] +#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] #[derive(Clone)] pub struct SecretBytes(FieldBytes); From b03736b733bb22b77b1650346eaadbe6e71bfe32 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 22 Jan 2021 12:46:37 -0800 Subject: [PATCH 0392/1461] Bump `base64ct` and `der` dependencies (#488) --- Cargo.lock | 26 ++++++++++---------------- Cargo.toml | 1 + elliptic-curve/Cargo.toml | 4 ++-- elliptic-curve/src/jwk.rs | 10 +++++----- password-hash/Cargo.toml | 6 +++--- password-hash/src/lib.rs | 2 +- 6 files changed, 22 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b80473c20..86c7f52ed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -41,15 +41,9 @@ dependencies = [ ] [[package]] -name = "b64ct" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524df4b3f9e9925f37c0d9beec6fbc2dac691b188f3f331ab12c5587ebe6766e" - -[[package]] -name = "b64ct" -version = "0.2.0" -source = "git+https://github.com/RustCrypto/utils.git#b2b5fb554fad25071f4268bc6e8fb3d6def4bc7e" +name = "base64ct" +version = "0.0.0" +source = "git+https://github.com/RustCrypto/utils.git#0fe3e15b868778c92959f3fa03b62b47b6842f60" [[package]] name = "bitvec" @@ -120,7 +114,7 @@ dependencies = [ [[package]] name = "const-oid" version = "0.4.1" -source = "git+https://github.com/RustCrypto/utils.git#b2b5fb554fad25071f4268bc6e8fb3d6def4bc7e" +source = "git+https://github.com/RustCrypto/utils.git#0fe3e15b868778c92959f3fa03b62b47b6842f60" [[package]] name = "cpuid-bool" @@ -153,8 +147,8 @@ dependencies = [ [[package]] name = "der" -version = "0.2.0-pre" -source = "git+https://github.com/RustCrypto/utils.git#b2b5fb554fad25071f4268bc6e8fb3d6def4bc7e" +version = "0.2.0" +source = "git+https://github.com/RustCrypto/utils.git#0fe3e15b868778c92959f3fa03b62b47b6842f60" dependencies = [ "const-oid", ] @@ -181,7 +175,7 @@ dependencies = [ name = "elliptic-curve" version = "0.9.0-pre" dependencies = [ - "b64ct 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "base64ct", "digest 0.9.0", "ff", "generic-array 0.14.4", @@ -313,15 +307,15 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" name = "password-hash" version = "0.0.0" dependencies = [ - "b64ct 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "base64ct", ] [[package]] name = "pkcs8" version = "0.4.0-pre" -source = "git+https://github.com/RustCrypto/utils.git#b2b5fb554fad25071f4268bc6e8fb3d6def4bc7e" +source = "git+https://github.com/RustCrypto/utils.git#0fe3e15b868778c92959f3fa03b62b47b6842f60" dependencies = [ - "b64ct 0.2.0 (git+https://github.com/RustCrypto/utils.git)", + "base64ct", "der", "zeroize", ] diff --git a/Cargo.toml b/Cargo.toml index 399bf302b..68b3f4f0f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,4 +13,5 @@ members = [ ] [patch.crates-io] +base64ct = { git = "https://github.com/RustCrypto/utils.git" } pkcs8 = { git = "https://github.com/RustCrypto/utils.git" } diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 5e9b262dc..dc137d1e9 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -15,7 +15,7 @@ categories = ["cryptography", "no-std"] keywords = ["crypto", "ecc", "elliptic", "weierstrass"] [dependencies] -b64ct = { version = "0.2", optional = true, default-features = false } +base64ct = { version = "0", optional = true, default-features = false } digest = { version = "0.9", optional = true } ff = { version = "0.9", optional = true, default-features = false } group = { version = "0.9", optional = true, default-features = false } @@ -38,7 +38,7 @@ arithmetic = ["ff", "group"] dev = ["arithmetic", "digest", "hex-literal", "pem", "zeroize"] ecdh = ["arithmetic", "zeroize"] hazmat = [] -jwk = ["alloc", "b64ct/alloc", "serde", "serde_json", "zeroize/alloc"] +jwk = ["alloc", "base64ct/alloc", "serde", "serde_json", "zeroize/alloc"] pem = ["alloc", "pkcs8/pem"] std = ["alloc"] diff --git a/elliptic-curve/src/jwk.rs b/elliptic-curve/src/jwk.rs index af6083385..c841c1d09 100644 --- a/elliptic-curve/src/jwk.rs +++ b/elliptic-curve/src/jwk.rs @@ -637,7 +637,7 @@ fn decode_base64url_fe(s: &str) -> Result, Error> { let mut bytes = Zeroizing::new(s.as_bytes().to_vec()); // Translate Base64url to traditional Base64 - // TODO(tarcieri): constant time implementation (in `b64ct` crate?) + // TODO(tarcieri): constant time implementation (in `base64ct` crate?) for byte in bytes.iter_mut() { match *byte { b'A'..=b'Z' | b'a'..=b'z' | b'0'..=b'9' => (), @@ -649,22 +649,22 @@ fn decode_base64url_fe(s: &str) -> Result, Error> { let s = str::from_utf8(&bytes).map_err(|_| Error)?; let mut result = FieldBytes::::default(); - b64ct::decode(s, &mut result).map_err(|_| Error)?; + base64ct::decode(s, &mut result).map_err(|_| Error)?; Ok(result) } /// Encode a field element as Base64url fn encode_base64url(bytes: &[u8]) -> String { - let mut b64 = b64ct::encode_string(&bytes).into_bytes(); + let mut b64 = base64ct::encode_string(&bytes).into_bytes(); // Translate traditional Base64 to Base64url - // TODO(tarcieri): constant time implementation (in `b64ct` crate?) + // TODO(tarcieri): constant time implementation (in `base64ct` crate?) for byte in b64.iter_mut() { match *byte { b'A'..=b'Z' | b'a'..=b'z' | b'0'..=b'9' => (), b'+' => *byte = b'-', b'/' => *byte = b'_', - _ => unreachable!(), // would be a bug in `b64ct` + _ => unreachable!(), // would be a bug in `base64ct` } } diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index 1d206063f..eb725c97d 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -16,8 +16,8 @@ categories = ["cryptography", "no-std"] keywords = ["crypt", "mcf", "password", "pbkdf", "phc"] [dependencies] -b64ct = "0.2" +base64ct = "0" [features] -alloc = ["b64ct/alloc"] -std = ["alloc", "b64ct/std"] +alloc = ["base64ct/alloc"] +std = ["alloc", "base64ct/std"] diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index 99d1e48ca..83e3d787b 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -58,7 +58,7 @@ pub use crate::{ value::{Decimal, Value}, }; -pub use b64ct as b64; +pub use base64ct as b64; use core::{ convert::{TryFrom, TryInto}, From 93e035cf6f1b603c275dbb5dda8181b3f4da1f42 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Jan 2021 08:49:00 +0000 Subject: [PATCH 0393/1461] build(deps): bump serde from 1.0.120 to 1.0.122 (#490) --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 86c7f52ed..6740b9083 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -364,9 +364,9 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "serde" -version = "1.0.120" +version = "1.0.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "166b2349061381baf54a58e4b13c89369feb0ef2eaa57198899e2312aac30aab" +checksum = "974ef1bd2ad8a507599b336595454081ff68a9599b4890af7643c0c0ed73a62c" [[package]] name = "serde_json" From 020570a5c671c51e15e62224894443050d63efac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Jan 2021 21:44:36 -0800 Subject: [PATCH 0394/1461] build(deps): bump serde from 1.0.122 to 1.0.123 (#491) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.122 to 1.0.123. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.122...v1.0.123) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6740b9083..47e14af55 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -364,9 +364,9 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "serde" -version = "1.0.122" +version = "1.0.123" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "974ef1bd2ad8a507599b336595454081ff68a9599b4890af7643c0c0ed73a62c" +checksum = "92d5161132722baa40d802cc70b15262b98258453e85e5d1d365c757c73869ae" [[package]] name = "serde_json" From 465ddb25c009e50f083a19dd4d04c441229490b3 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 26 Jan 2021 11:51:00 -0800 Subject: [PATCH 0395/1461] Use `base64ct` v0.1.0 release (#492) Includes Base64url support (needed by `elliptic-curve` for JWK) --- Cargo.lock | 12 ++++++++--- Cargo.toml | 1 - elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/jwk.rs | 43 ++++++------------------------------- password-hash/Cargo.toml | 2 +- password-hash/src/errors.rs | 27 ++++++++++++----------- password-hash/src/lib.rs | 2 +- password-hash/src/output.rs | 4 ---- password-hash/src/salt.rs | 7 ++++-- password-hash/src/value.rs | 7 ++++-- 10 files changed, 42 insertions(+), 65 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 47e14af55..931ffef51 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -45,6 +45,12 @@ name = "base64ct" version = "0.0.0" source = "git+https://github.com/RustCrypto/utils.git#0fe3e15b868778c92959f3fa03b62b47b6842f60" +[[package]] +name = "base64ct" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c502cbac2e4ffc38047434d0c88b54da5e7c76829ff16f0a479f90116336d9f3" + [[package]] name = "bitvec" version = "0.20.1" @@ -175,7 +181,7 @@ dependencies = [ name = "elliptic-curve" version = "0.9.0-pre" dependencies = [ - "base64ct", + "base64ct 0.1.0", "digest 0.9.0", "ff", "generic-array 0.14.4", @@ -307,7 +313,7 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" name = "password-hash" version = "0.0.0" dependencies = [ - "base64ct", + "base64ct 0.1.0", ] [[package]] @@ -315,7 +321,7 @@ name = "pkcs8" version = "0.4.0-pre" source = "git+https://github.com/RustCrypto/utils.git#0fe3e15b868778c92959f3fa03b62b47b6842f60" dependencies = [ - "base64ct", + "base64ct 0.0.0", "der", "zeroize", ] diff --git a/Cargo.toml b/Cargo.toml index 68b3f4f0f..399bf302b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,5 +13,4 @@ members = [ ] [patch.crates-io] -base64ct = { git = "https://github.com/RustCrypto/utils.git" } pkcs8 = { git = "https://github.com/RustCrypto/utils.git" } diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index dc137d1e9..5ee085590 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -15,7 +15,7 @@ categories = ["cryptography", "no-std"] keywords = ["crypto", "ecc", "elliptic", "weierstrass"] [dependencies] -base64ct = { version = "0", optional = true, default-features = false } +base64ct = { version = "0.1", optional = true, default-features = false } digest = { version = "0.9", optional = true } ff = { version = "0.9", optional = true, default-features = false } group = { version = "0.9", optional = true, default-features = false } diff --git a/elliptic-curve/src/jwk.rs b/elliptic-curve/src/jwk.rs index c841c1d09..73ad6049c 100644 --- a/elliptic-curve/src/jwk.rs +++ b/elliptic-curve/src/jwk.rs @@ -16,6 +16,7 @@ use alloc::{ format, string::{String, ToString}, }; +use base64ct::url::unpadded as base64url; use core::{ convert::{TryFrom, TryInto}, fmt::{self, Debug}, @@ -25,7 +26,7 @@ use core::{ }; use generic_array::{typenum::U1, ArrayLength}; use serde::{de, ser, Deserialize, Serialize}; -use zeroize::{Zeroize, Zeroizing}; +use zeroize::Zeroize; #[cfg(feature = "arithmetic")] use crate::{ @@ -211,8 +212,8 @@ where match point.coordinates() { Coordinates::Uncompressed { x, y } => Ok(JwkEcKey { crv: C::CRV.to_owned(), - x: encode_base64url(x), - y: encode_base64url(y), + x: base64url::encode_string(x), + y: base64url::encode_string(y), d: None, }), _ => Err(Error), @@ -292,7 +293,7 @@ where fn from(sk: &SecretKey) -> JwkEcKey { let mut jwk = sk.public_key().to_jwk(); let mut d = sk.to_bytes(); - jwk.d = Some(encode_base64url(&d)); + jwk.d = Some(base64url::encode_string(&d)); d.zeroize(); jwk } @@ -634,43 +635,11 @@ impl Serialize for JwkEcKey { /// Decode a Base64url-encoded field element fn decode_base64url_fe(s: &str) -> Result, Error> { - let mut bytes = Zeroizing::new(s.as_bytes().to_vec()); - - // Translate Base64url to traditional Base64 - // TODO(tarcieri): constant time implementation (in `base64ct` crate?) - for byte in bytes.iter_mut() { - match *byte { - b'A'..=b'Z' | b'a'..=b'z' | b'0'..=b'9' => (), - b'-' => *byte = b'+', - b'_' => *byte = b'/', - _ => return Err(Error), - } - } - - let s = str::from_utf8(&bytes).map_err(|_| Error)?; let mut result = FieldBytes::::default(); - base64ct::decode(s, &mut result).map_err(|_| Error)?; + base64url::decode(s, &mut result).map_err(|_| Error)?; Ok(result) } -/// Encode a field element as Base64url -fn encode_base64url(bytes: &[u8]) -> String { - let mut b64 = base64ct::encode_string(&bytes).into_bytes(); - - // Translate traditional Base64 to Base64url - // TODO(tarcieri): constant time implementation (in `base64ct` crate?) - for byte in b64.iter_mut() { - match *byte { - b'A'..=b'Z' | b'a'..=b'z' | b'0'..=b'9' => (), - b'+' => *byte = b'-', - b'/' => *byte = b'_', - _ => unreachable!(), // would be a bug in `base64ct` - } - } - - String::from_utf8(b64).unwrap() -} - #[cfg(test)] mod tests { use super::*; diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index eb725c97d..78a3bdff7 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -16,7 +16,7 @@ categories = ["cryptography", "no-std"] keywords = ["crypt", "mcf", "password", "pbkdf", "phc"] [dependencies] -base64ct = "0" +base64ct = "0.1" [features] alloc = ["base64ct/alloc"] diff --git a/password-hash/src/errors.rs b/password-hash/src/errors.rs index 967f22150..5990354b0 100644 --- a/password-hash/src/errors.rs +++ b/password-hash/src/errors.rs @@ -1,6 +1,7 @@ //! Error types. -use crate::b64; +pub use base64ct::Error as B64Error; + use core::fmt; #[cfg(docsrs)] @@ -60,7 +61,7 @@ pub enum HasherError { Algorithm, /// "B64" encoding error. - B64(b64::Error), + B64(B64Error), /// Cryptographic error. Crypto, @@ -92,15 +93,15 @@ impl fmt::Display for HasherError { } } -impl From for HasherError { - fn from(err: b64::Error) -> HasherError { +impl From for HasherError { + fn from(err: B64Error) -> HasherError { HasherError::B64(err) } } -impl From for HasherError { - fn from(_: b64::InvalidLengthError) -> HasherError { - HasherError::B64(b64::Error::InvalidLength) +impl From for HasherError { + fn from(_: base64ct::InvalidLengthError) -> HasherError { + HasherError::B64(B64Error::InvalidLength) } } @@ -199,7 +200,7 @@ impl std::error::Error for ParseError {} #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum OutputError { /// "B64" encoding error. - B64(b64::Error), + B64(B64Error), /// Output too short (min 10-bytes). TooShort, @@ -218,15 +219,15 @@ impl fmt::Display for OutputError { } } -impl From for OutputError { - fn from(err: b64::Error) -> OutputError { +impl From for OutputError { + fn from(err: B64Error) -> OutputError { OutputError::B64(err) } } -impl From for OutputError { - fn from(_: b64::InvalidLengthError) -> OutputError { - OutputError::B64(b64::Error::InvalidLength) +impl From for OutputError { + fn from(_: base64ct::InvalidLengthError) -> OutputError { + OutputError::B64(B64Error::InvalidLength) } } diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index 83e3d787b..10ce46931 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -58,7 +58,7 @@ pub use crate::{ value::{Decimal, Value}, }; -pub use base64ct as b64; +pub use base64ct::unpadded as b64; use core::{ convert::{TryFrom, TryInto}, diff --git a/password-hash/src/output.rs b/password-hash/src/output.rs index 2acc7a137..6afd61076 100644 --- a/password-hash/src/output.rs +++ b/password-hash/src/output.rs @@ -137,10 +137,6 @@ impl Output { /// Parse [`b64`]-encoded [`Output`], i.e. using the PHC string /// specification's restricted interpretation of Base64. pub fn b64_decode(input: &str) -> Result { - if b64::decoded_len(input) > MAX_LENGTH { - return Err(OutputError::TooLong); - } - let mut bytes = [0u8; MAX_LENGTH]; b64::decode(input, &mut bytes) .map_err(Into::into) diff --git a/password-hash/src/salt.rs b/password-hash/src/salt.rs index a1a617440..d59919cf4 100644 --- a/password-hash/src/salt.rs +++ b/password-hash/src/salt.rs @@ -1,6 +1,9 @@ //! Salt string support. -use crate::{b64, errors::ParseError, Value}; +use crate::{ + errors::{B64Error, ParseError}, + Value, +}; use core::{ convert::{TryFrom, TryInto}, fmt, str, @@ -114,7 +117,7 @@ impl<'a> Salt<'a> { /// buffer containing the decoded result on success. /// /// [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#argon2-encoding - pub fn b64_decode<'b>(&self, buf: &'b mut [u8]) -> Result<&'b [u8], b64::Error> { + pub fn b64_decode<'b>(&self, buf: &'b mut [u8]) -> Result<&'b [u8], B64Error> { self.0.b64_decode(buf) } diff --git a/password-hash/src/value.rs b/password-hash/src/value.rs index bfc8743d5..b9d23451e 100644 --- a/password-hash/src/value.rs +++ b/password-hash/src/value.rs @@ -13,7 +13,10 @@ //! //! [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md -use crate::{b64, errors::ParseError}; +use crate::{ + b64, + errors::{B64Error, ParseError}, +}; use core::{convert::TryFrom, fmt, str}; /// Maximum size of a parameter value in ASCII characters. @@ -78,7 +81,7 @@ impl<'a> Value<'a> { /// PHC string format specification. /// /// [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#argon2-encoding - pub fn b64_decode<'b>(&self, buf: &'b mut [u8]) -> Result<&'b [u8], b64::Error> { + pub fn b64_decode<'b>(&self, buf: &'b mut [u8]) -> Result<&'b [u8], B64Error> { b64::decode(self.as_str(), buf) } From 0da78eabf8edeca29ca6ee433274b05ec9356ad6 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 26 Jan 2021 12:53:05 -0800 Subject: [PATCH 0396/1461] Bump `pkcs8` crate dependency to v0.4 (#493) --- Cargo.lock | 22 ++++++++++------------ Cargo.toml | 3 --- elliptic-curve/Cargo.toml | 2 +- 3 files changed, 11 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 931ffef51..7105628c2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -40,11 +40,6 @@ dependencies = [ "syn", ] -[[package]] -name = "base64ct" -version = "0.0.0" -source = "git+https://github.com/RustCrypto/utils.git#0fe3e15b868778c92959f3fa03b62b47b6842f60" - [[package]] name = "base64ct" version = "0.1.0" @@ -120,7 +115,8 @@ dependencies = [ [[package]] name = "const-oid" version = "0.4.1" -source = "git+https://github.com/RustCrypto/utils.git#0fe3e15b868778c92959f3fa03b62b47b6842f60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5d82796b70971fbb603900a5edc797a4d9be0f9ec1257f83a1dba0aa374e3e9" [[package]] name = "cpuid-bool" @@ -154,7 +150,8 @@ dependencies = [ [[package]] name = "der" version = "0.2.0" -source = "git+https://github.com/RustCrypto/utils.git#0fe3e15b868778c92959f3fa03b62b47b6842f60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65ade418c7a9e4edd2dab3b4749ef6c56ee4b137bc1600215c158cff8e5d39b2" dependencies = [ "const-oid", ] @@ -181,7 +178,7 @@ dependencies = [ name = "elliptic-curve" version = "0.9.0-pre" dependencies = [ - "base64ct 0.1.0", + "base64ct", "digest 0.9.0", "ff", "generic-array 0.14.4", @@ -313,15 +310,16 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" name = "password-hash" version = "0.0.0" dependencies = [ - "base64ct 0.1.0", + "base64ct", ] [[package]] name = "pkcs8" -version = "0.4.0-pre" -source = "git+https://github.com/RustCrypto/utils.git#0fe3e15b868778c92959f3fa03b62b47b6842f60" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8f486f758a686804c80ab239829095260ecbe46e5226e00c0b1339e76a9babc" dependencies = [ - "base64ct 0.0.0", + "base64ct", "der", "zeroize", ] diff --git a/Cargo.toml b/Cargo.toml index 399bf302b..9db9bf636 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,3 @@ members = [ "signature/async", "universal-hash", ] - -[patch.crates-io] -pkcs8 = { git = "https://github.com/RustCrypto/utils.git" } diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 5ee085590..3551ea60f 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -21,7 +21,7 @@ ff = { version = "0.9", optional = true, default-features = false } group = { version = "0.9", optional = true, default-features = false } hex-literal = { version = "0.3", optional = true } generic-array = { version = "0.14", default-features = false } -pkcs8 = { version = "0.4.0-pre", optional = true } +pkcs8 = { version = "0.4", optional = true } rand_core = { version = "0.6", default-features = false } serde = { version = "1", optional = true, default-features = false } serde_json = { version = "1", optional = true, default-features = false, features = ["alloc"] } From 143178ef7a7a76ad22f40e92ee99a207253f35d8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 28 Jan 2021 05:55:46 -0800 Subject: [PATCH 0397/1461] build(deps): bump base64ct from 0.1.0 to 0.1.1 (#494) Bumps [base64ct](https://github.com/RustCrypto/utils) from 0.1.0 to 0.1.1. - [Release notes](https://github.com/RustCrypto/utils/releases) - [Commits](https://github.com/RustCrypto/utils/compare/base64ct-v0.1.0...base64ct-v0.1.1) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7105628c2..7f6cd4fb2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -42,9 +42,9 @@ dependencies = [ [[package]] name = "base64ct" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c502cbac2e4ffc38047434d0c88b54da5e7c76829ff16f0a479f90116336d9f3" +checksum = "e96c6b8c1cac2cfe84b4ea97794c43085b401df66c466e9a863744c0489679a7" [[package]] name = "bitvec" From d49ca56e2838179ef43124e7f50425530f04d24e Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 28 Jan 2021 11:24:45 -0800 Subject: [PATCH 0398/1461] password-hash: add "simple" APIs; parameterize version (#495) Adds a "simple" API which requires only a password and salt string as inputs, using default algorithm, version, and parameters. Also passes through version field, which is needed to implement Argon2. --- password-hash/src/lib.rs | 25 ++++++++++++++++++++++--- password-hash/tests/hashing.rs | 12 ++++++------ 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index 10ce46931..24f3708c0 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -77,6 +77,24 @@ pub trait PasswordHasher { + for<'a> TryFrom<&'a ParamsString, Error = HasherError> + for<'a> TryInto; + /// Simple API for computing a [`PasswordHash`] from a password and + /// [`Salt`] value. + /// + /// Uses the default recommended parameters for a given algorithm. + fn hash_password_simple<'a>( + &self, + password: &[u8], + salt: &'a str, + ) -> Result, HasherError> { + self.hash_password( + password, + None, + None, + Self::Params::default(), + salt.try_into()?, + ) + } + /// Compute a [`PasswordHash`] with the given algorithm [`Ident`] /// (or `None` for the recommended default), password, salt, and /// parameters. @@ -84,6 +102,7 @@ pub trait PasswordHasher { &self, password: &[u8], algorithm: Option>, + version: Option, params: Self::Params, salt: Salt<'a>, ) -> Result, HasherError>; @@ -109,6 +128,7 @@ impl PasswordVerifier for T { let computed_hash = self.hash_password( password, Some(hash.algorithm), + hash.version, T::Params::try_from(&hash.params)?, *salt, )?; @@ -293,10 +313,9 @@ impl<'a> PasswordHash<'a> { pub fn generate( phf: impl PasswordHasher, password: impl AsRef<[u8]>, - salt: Salt<'a>, - params: &ParamsString, + salt: &'a str, ) -> Result { - phf.hash_password(password.as_ref(), None, params.try_into()?, salt) + phf.hash_password_simple(password.as_ref(), salt) } /// Verify this password hash using the specified set of supported diff --git a/password-hash/tests/hashing.rs b/password-hash/tests/hashing.rs index f898f27d4..bdd69205d 100644 --- a/password-hash/tests/hashing.rs +++ b/password-hash/tests/hashing.rs @@ -1,7 +1,8 @@ //! Password hashing tests pub use password_hash::{ - HasherError, Ident, Output, ParamsString, PasswordHash, PasswordHasher, Salt, VerifyError, + Decimal, HasherError, Ident, Output, ParamsString, PasswordHash, PasswordHasher, Salt, + VerifyError, }; use std::convert::{TryFrom, TryInto}; @@ -17,6 +18,7 @@ impl PasswordHasher for StubPasswordHasher { &self, password: &[u8], algorithm: Option>, + _version: Option, params: StubParams, salt: Salt<'a>, ) -> Result, HasherError> { @@ -67,14 +69,12 @@ impl<'a> TryFrom for ParamsString { #[test] fn verify_password_hash() { let valid_password = "test password"; - let salt = Salt::new("test-salt").unwrap(); - let params = ParamsString::new(); - let hash = PasswordHash::generate(StubPasswordHasher, valid_password, salt, ¶ms).unwrap(); + let salt = "test-salt"; + let hash = PasswordHash::generate(StubPasswordHasher, valid_password, salt).unwrap(); // Sanity tests for StubFunction impl above assert_eq!(hash.algorithm, ALG); - assert_eq!(hash.salt.unwrap(), salt); - assert_eq!(hash.params, params); + assert_eq!(hash.salt.unwrap().as_str(), salt); // Tests for generic password verification logic assert_eq!( From 936513dd9ea1903c3047dae0f092ae8243bae73f Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 28 Jan 2021 11:40:06 -0800 Subject: [PATCH 0399/1461] password-hash: add HasherError::Version (#496) Add an error variant for reporting invalid versions --- password-hash/src/errors.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/password-hash/src/errors.rs b/password-hash/src/errors.rs index 5990354b0..b75c7613a 100644 --- a/password-hash/src/errors.rs +++ b/password-hash/src/errors.rs @@ -77,6 +77,9 @@ pub enum HasherError { /// Invalid password. Password, + + /// Invalid algorithm version. + Version, } impl fmt::Display for HasherError { @@ -89,6 +92,7 @@ impl fmt::Display for HasherError { Self::Params(err) => write!(f, "{}", err), Self::Parse(err) => write!(f, "{}", err), Self::Password => write!(f, "invalid password"), + Self::Version => write!(f, "invalid algorithm version"), } } } From 2927b40ef3ac3b6985466f491760159dde2a1550 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Thu, 28 Jan 2021 21:01:21 +0000 Subject: [PATCH 0400/1461] digest: fix test macro (#480) --- Cargo.lock | 10 +++++----- digest/Cargo.toml | 4 ++-- digest/src/core_api.rs | 16 ++++------------ digest/src/dev.rs | 3 ++- digest/src/lib.rs | 2 +- 5 files changed, 14 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7f6cd4fb2..e4e8e5548 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -75,9 +75,9 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.10.0-pre" +version = "0.10.0-pre.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5ae77a4961d75e3e4505bbe155705bda23ff5948209c8face08f75c2cd52a0" +checksum = "ae646bb58db3c82677a9ebece843b3577e1e2e134067c3e69681ebe1e4c75f02" dependencies = [ "block-padding", "generic-array 0.14.4", @@ -131,7 +131,7 @@ dependencies = [ "aead", "cipher", "crypto-mac", - "digest 0.10.0-pre.1", + "digest 0.10.0-pre.2", "elliptic-curve", "signature", "universal-hash", @@ -167,10 +167,10 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.0-pre.1" +version = "0.10.0-pre.2" dependencies = [ "blobby", - "block-buffer 0.10.0-pre", + "block-buffer 0.10.0-pre.1", "generic-array 0.14.4", ] diff --git a/digest/Cargo.toml b/digest/Cargo.toml index fdf97d138..65e940ad4 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "digest" description = "Traits for cryptographic hash functions" -version = "0.10.0-pre.1" +version = "0.10.0-pre.2" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" @@ -14,7 +14,7 @@ categories = ["cryptography", "no-std"] [dependencies] generic-array = "0.14" blobby = { version = "0.3", optional = true } -block-buffer = { version = "0.10.0-pre", optional = true } +block-buffer = { version = "0.10.0-pre.1", optional = true } [features] alloc = [] diff --git a/digest/src/core_api.rs b/digest/src/core_api.rs index f37e6a62b..a26b006fc 100644 --- a/digest/src/core_api.rs +++ b/digest/src/core_api.rs @@ -30,10 +30,6 @@ pub trait FixedOutputCore: UpdateCore { /// Retrieve result into provided buffer using remaining data stored /// in the block buffer and leave hasher in a dirty state. - /// - /// This method is expected to only be called once unless [`Reset::reset`] - /// is called, after which point it can be called again and reset again - /// (and so on). fn finalize_fixed_core( &mut self, buffer: &mut block_buffer::BlockBuffer, @@ -53,10 +49,6 @@ pub trait ExtendableOutputCore: UpdateCore { /// Retrieve XOF reader using remaining data stored in the block buffer /// and leave hasher in a dirty state. - /// - /// This method is expected to only be called once unless [`Reset::reset`] - /// is called, after which point it can be called again and reset again - /// (and so on). fn finalize_xof_core( &mut self, buffer: &mut block_buffer::BlockBuffer, @@ -104,10 +96,10 @@ impl fmt::Debug for XofReaderCoreWrapper { } } -impl Reset for UpdateCoreWrapper { +impl Reset for UpdateCoreWrapper { #[inline] fn reset(&mut self) { - self.core.reset(); + self.core = Default::default(); self.buffer.reset(); } } @@ -120,7 +112,7 @@ impl Update for UpdateCoreWrapper { } } -impl FixedOutput for UpdateCoreWrapper { +impl FixedOutput for UpdateCoreWrapper { type OutputSize = D::OutputSize; #[inline] @@ -145,7 +137,7 @@ impl XofReader for XofReaderCoreWrapper { } } -impl ExtendableOutput for UpdateCoreWrapper { +impl ExtendableOutput for UpdateCoreWrapper { type Reader = XofReaderCoreWrapper; #[inline] diff --git a/digest/src/dev.rs b/digest/src/dev.rs index f3f8e2208..6799fea90 100644 --- a/digest/src/dev.rs +++ b/digest/src/dev.rs @@ -15,7 +15,8 @@ macro_rules! new_test { use digest::dev::blobby::Blob2Iterator; let data = include_bytes!(concat!("data/", $test_name, ".blb")); - for (i, [input, output]) in Blob2Iterator::new(data).unwrap().enumerate() { + for (i, row) in Blob2Iterator::new(data).unwrap().enumerate() { + let [input, output] = row.unwrap(); if let Some(desc) = $test_func::<$hasher>(input, output) { panic!( "\n\ diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 13a3683ed..61540f233 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -56,7 +56,7 @@ mod dyn_digest; #[cfg(feature = "core-api")] pub use crate::core_api::{ AlgorithmName, ExtendableOutputCore, FixedOutputCore, UpdateCore, UpdateCoreWrapper, - XofReaderCoreWrapper, + XofReaderCore, XofReaderCoreWrapper, }; pub use crate::digest::{Digest, Output}; #[cfg(feature = "core-api")] From fbb20ebfe89c790fb63b27a39f993017497f0f54 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 28 Jan 2021 18:38:28 -0800 Subject: [PATCH 0401/1461] password-hash: add SaltString type (#497) Add an owned stack-allocated string type for salts, which supports B64 encoding/decoding as well as random generation using rand_core's CryptoRng+RngCore. --- .github/workflows/password-hash.yml | 1 + Cargo.lock | 1 + password-hash/Cargo.toml | 1 + password-hash/src/lib.rs | 9 +-- password-hash/src/salt.rs | 112 ++++++++++++++++++++++++++-- 5 files changed, 112 insertions(+), 12 deletions(-) diff --git a/.github/workflows/password-hash.yml b/.github/workflows/password-hash.yml index 52b090ba2..326cad572 100644 --- a/.github/workflows/password-hash.yml +++ b/.github/workflows/password-hash.yml @@ -37,6 +37,7 @@ jobs: profile: minimal - run: cargo build --target ${{ matrix.target }} --release --no-default-features - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features rand_core test: runs-on: ubuntu-latest diff --git a/Cargo.lock b/Cargo.lock index e4e8e5548..99f7e1baa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -311,6 +311,7 @@ name = "password-hash" version = "0.0.0" dependencies = [ "base64ct", + "rand_core", ] [[package]] diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index 78a3bdff7..085c318e6 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -17,6 +17,7 @@ keywords = ["crypt", "mcf", "password", "pbkdf", "phc"] [dependencies] base64ct = "0.1" +rand_core = { version = "0.6", optional = true, default-features = false } [features] alloc = ["base64ct/alloc"] diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index 24f3708c0..c173266ac 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -41,8 +41,7 @@ extern crate alloc; #[cfg(feature = "std")] extern crate std; -pub mod errors; - +mod errors; mod ident; mod output; mod params; @@ -50,11 +49,11 @@ mod salt; mod value; pub use crate::{ - errors::{HashError, HasherError, VerifyError}, + errors::{B64Error, HashError, HasherError, OutputError, ParamsError, ParseError, VerifyError}, ident::Ident, output::Output, params::ParamsString, - salt::Salt, + salt::{Salt, SaltString}, value::{Decimal, Value}, }; @@ -239,8 +238,6 @@ pub struct PasswordHash<'a> { impl<'a> PasswordHash<'a> { /// Parse a password hash from a string in the PHC string format. pub fn new(s: &'a str) -> Result { - use errors::ParseError; - if s.is_empty() { return Err(ParseError::Empty.into()); } diff --git a/password-hash/src/salt.rs b/password-hash/src/salt.rs index d59919cf4..d82914f06 100644 --- a/password-hash/src/salt.rs +++ b/password-hash/src/salt.rs @@ -1,6 +1,7 @@ //! Salt string support. use crate::{ + b64, errors::{B64Error, ParseError}, Value, }; @@ -9,6 +10,13 @@ use core::{ fmt, str, }; +#[cfg(feature = "rand_core")] +use rand_core::{CryptoRng, RngCore}; + +/// Error message used with `expect` for when internal invariants are violated +/// (i.e. the contents of a [`Salt`] should always be valid) +const INVARIANT_VIOLATED_MSG: &str = "salt string invariant violated"; + /// Salt string. /// /// In password hashing, a "salt" is an additional value used to @@ -48,14 +56,14 @@ use core::{ /// guidelines from the spec: /// /// - Minimum length: **4**-bytes -/// - Maximum length: **48**-bytes +/// - Maximum length: **64**-bytes /// /// A maximum length is enforced based on the above recommendation for /// supporting stack-allocated buffers (which this library uses), and the -/// specific determination of 48-bytes is taken as a best practice from the +/// specific determination of 64-bytes is taken as a best practice from the /// [Argon2 Encoding][3] specification in the same document: /// -/// > The length in bytes of the salt is between 8 and 48 bytes, thus +/// > The length in bytes of the salt is between 8 and 64 bytes, thus /// > yielding a length in characters between 11 and 64 characters (and that /// > length is never equal to 1 modulo 4). The default byte length of the salt /// > is 16 bytes (22 characters in B64 encoding). An encoded UUID, or a @@ -67,7 +75,7 @@ use core::{ /// > Specifying a relatively small maximum length allows for parsing with a /// > stack allocated buffer.) /// -/// Based on this guidance, this type enforces an upper bound of 48-bytes +/// Based on this guidance, this type enforces an upper bound of 64-bytes /// as a reasonable maximum, and recommends using 16-bytes. /// /// [1]: https://en.wikipedia.org/wiki/Rainbow_table @@ -85,11 +93,11 @@ impl<'a> Salt<'a> { 4 } - /// Maximum length of a [`Salt`] string: 48-bytes. + /// Maximum length of a [`Salt`] string: 64-bytes. /// /// See type-level documentation about [`Salt`] for more information. pub const fn max_len() -> usize { - Value::max_len() + 64 } /// Recommended length of a salt: 16-bytes. @@ -163,6 +171,98 @@ impl<'a> fmt::Debug for Salt<'a> { } } +/// Owned stack-allocated equivalent of [`Salt`]. +#[derive(Clone, Debug, Eq)] +pub struct SaltString { + /// Byte array containing an ASCiI-encoded string. + bytes: [u8; Salt::max_len()], + + /// Length of the string in ASCII characters (i.e. bytes). + length: u8, +} + +impl SaltString { + /// Generate a random B64-encoded [`SaltString`]. + #[cfg(feature = "rand_core")] + #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] + pub fn generate(mut rng: impl CryptoRng + RngCore) -> Self { + let mut bytes = [0u8; Salt::recommended_len()]; + rng.fill_bytes(&mut bytes); + Self::b64_encode(&bytes).expect(INVARIANT_VIOLATED_MSG) + } + + /// Create a new [`SaltString`]. + pub fn new(s: &str) -> Result { + // Assert `s` parses successifully as a `Salt` + Salt::new(s)?; + + let length = s.as_bytes().len(); + + if length < Salt::max_len() { + let mut bytes = [0u8; Salt::max_len()]; + bytes[..length].copy_from_slice(s.as_bytes()); + Ok(SaltString { + bytes, + length: length as u8, + }) + } else { + Err(ParseError::TooLong) + } + } + + /// Encode the given byte slice as B64 into a new [`SaltString`]. + /// + /// Returns `None` if the slice is too long. + pub fn b64_encode(input: &[u8]) -> Result { + let mut bytes = [0u8; Salt::max_len()]; + let length = b64::encode(input, &mut bytes)?.len() as u8; + Ok(Self { bytes, length }) + } + + /// Decode this [`SaltString`] from B64 into the provided output buffer. + pub fn b64_decode<'a>(&self, buf: &'a mut [u8]) -> Result<&'a [u8], B64Error> { + self.as_salt().b64_decode(buf) + } + + /// Borrow the contents of a [`SaltString`] as a `str`. + pub fn as_str(&self) -> &str { + str::from_utf8(&self.bytes[..(self.length as usize)]).expect(INVARIANT_VIOLATED_MSG) + } + + /// Borrow the contents of a [`SaltString`] as a [`Salt`]. + pub fn as_salt(&self) -> Salt<'_> { + Salt::new(self.as_str()).expect(INVARIANT_VIOLATED_MSG) + } +} + +impl AsRef for SaltString { + fn as_ref(&self) -> &str { + self.as_str() + } +} + +impl Default for SaltString { + fn default() -> SaltString { + SaltString { + bytes: [0u8; Salt::max_len()], + length: 0, + } + } +} + +impl PartialEq for SaltString { + fn eq(&self, other: &Self) -> bool { + // Ensure comparisons always honor the initialized portion of the buffer + self.as_ref().eq(other.as_ref()) + } +} + +impl<'a> From<&'a SaltString> for Salt<'a> { + fn from(salt_string: &'a SaltString) -> Salt<'a> { + salt_string.as_salt() + } +} + #[cfg(test)] mod tests { use super::{ParseError, Salt}; From cb43f4b78fb8407f4c3bc603f5900e19bf83ae18 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 28 Jan 2021 19:34:05 -0800 Subject: [PATCH 0402/1461] password-hash v0.1.0 (#499) --- Cargo.lock | 3 ++- README.md | 3 +++ crypto/Cargo.toml | 2 ++ crypto/src/lib.rs | 4 ++++ password-hash/CHANGELOG.md | 3 +++ password-hash/Cargo.toml | 2 +- password-hash/src/lib.rs | 4 ++-- password-hash/src/output.rs | 1 + password-hash/src/salt.rs | 18 +++++++++++++++--- 9 files changed, 33 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 99f7e1baa..5a0223d58 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -133,6 +133,7 @@ dependencies = [ "crypto-mac", "digest 0.10.0-pre.2", "elliptic-curve", + "password-hash", "signature", "universal-hash", ] @@ -308,7 +309,7 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "password-hash" -version = "0.0.0" +version = "0.1.0" dependencies = [ "base64ct", "rand_core", diff --git a/README.md b/README.md index 0e7b80b00..72fb8f142 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ Collection of traits which describe functionality of cryptographic primitives. | [`crypto‑mac`] | [Message authentication code] | [![crates.io](https://img.shields.io/crates/v/crypto-mac.svg)](https://crates.io/crates/crypto-mac) | [![Documentation](https://docs.rs/crypto-mac/badge.svg)](https://docs.rs/crypto-mac) | ![build](https://github.com/RustCrypto/traits/workflows/crypto-mac/badge.svg?branch=master&event=push) | | [`digest`] | [Cryptographic hash function] | [![crates.io](https://img.shields.io/crates/v/digest.svg)](https://crates.io/crates/digest) | [![Documentation](https://docs.rs/digest/badge.svg)](https://docs.rs/digest) | ![build](https://github.com/RustCrypto/traits/workflows/digest/badge.svg?branch=master&event=push) | | [`elliptic‑curve`] | [Elliptic curve cryptography] | [![crates.io](https://img.shields.io/crates/v/elliptic-curve.svg)](https://crates.io/crates/elliptic-curve) | [![Documentation](https://docs.rs/elliptic-curve/badge.svg)](https://docs.rs/elliptic-curve) | ![build](https://github.com/RustCrypto/traits/workflows/elliptic-curve/badge.svg?branch=master&event=push) | +| [`password-hash`] | [Password hashing algorithms] | [![crates.io](https://img.shields.io/crates/v/password-hash.svg)](https://crates.io/crates/password-hash) | [![Documentation](https://docs.rs/password-hash/badge.svg)](https://docs.rs/password-hash) | ![build](https://github.com/RustCrypto/traits/workflows/password-hash/badge.svg?branch=master&event=push) | | [`signature`] | [Digital signature] | [![crates.io](https://img.shields.io/crates/v/signature.svg)](https://crates.io/crates/signature) | [![Documentation](https://docs.rs/signature/badge.svg)](https://docs.rs/signature) | ![build](https://github.com/RustCrypto/traits/workflows/signature/badge.svg?branch=master&event=push) | | [`universal‑hash`] | [Universal hash function] | [![crates.io](https://img.shields.io/crates/v/universal-hash.svg)](https://crates.io/crates/universal-hash) | [![Documentation](https://docs.rs/universal-hash/badge.svg)](https://docs.rs/universal-hash) | ![build](https://github.com/RustCrypto/traits/workflows/universal-hash/badge.svg?branch=master&event=push) | @@ -60,6 +61,7 @@ dual licensed as above, without any additional terms or conditions. [`crypto`]: https://github.com/RustCrypto/traits/tree/master/crypto [`digest`]: https://github.com/RustCrypto/traits/tree/master/digest [`elliptic‑curve`]: https://github.com/RustCrypto/traits/tree/master/elliptic-curve +[`password-hash`]: https://github.com/RustCrypto/traits/tree/master/password-hash [`signature`]: https://github.com/RustCrypto/traits/tree/master/signature [`universal‑hash`]: https://github.com/RustCrypto/traits/tree/master/universal-hash @@ -71,5 +73,6 @@ dual licensed as above, without any additional terms or conditions. [Cryptographic hash function]: https://en.wikipedia.org/wiki/Cryptographic_hash_function [Digital signature]: https://en.wikipedia.org/wiki/Digital_signature [Elliptic curve cryptography]: https://en.wikipedia.org/wiki/Elliptic-curve_cryptography +[Password hashing algorithms]: https://en.wikipedia.org/wiki/Cryptographic_hash_function#Password_verification [Stream cipher]: https://en.wikipedia.org/wiki/Stream_cipher [Universal hash function]: https://en.wikipedia.org/wiki/Universal_hashing diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index efa129c3c..d34672f8b 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -17,6 +17,7 @@ cipher = { version = "=0.3.0-pre.4", optional = true, path = "../cipher" } digest = { version = "0.10.0-pre", optional = true, path = "../digest" } elliptic-curve = { version = "=0.9.0-pre", optional = true, path = "../elliptic-curve" } mac = { version = "=0.11.0-pre", package = "crypto-mac", optional = true, path = "../crypto-mac" } +password-hash = { version = "0.1", optional = true, path = "../password-hash" } signature = { version = "1.3.0", optional = true, default-features = false, path = "../signature" } universal-hash = { version = "0.4", optional = true, path = "../universal-hash" } @@ -27,6 +28,7 @@ std = [ "digest/std", "elliptic-curve/std", "mac/std", + "password-hash/std", "signature/std", "universal-hash/std" ] diff --git a/crypto/src/lib.rs b/crypto/src/lib.rs index 9c14669a7..c57ca995e 100644 --- a/crypto/src/lib.rs +++ b/crypto/src/lib.rs @@ -28,6 +28,7 @@ //! | [`digest`](https://docs.rs/digest) | `digest` | Cryptographic hash functions | //! | [`elliptic_curve`](https://docs.rs/elliptic-curve) | `elliptic-curve` | Elliptic curve cryptography | //! | [`mac`](https://docs.rs/crypto-mac) | `mac` | Message Authentication Codes (i.e. symmetric message authentication) | +//! | [`password-hash`](https://docs.rs/password-hash) | `password-hash` | Password hashing functions | //! | [`signature`](https://docs.rs/signature) | `signature` | Digital signatures (i.e. public key-based message authentication) | //! | [`universal_hash`](https://docs.rs/universal-hash) | `universal‑hash` | Universal Hash Functions (used to build MACs) | //! @@ -57,6 +58,9 @@ pub use elliptic_curve; #[cfg(feature = "mac")] pub use mac; +#[cfg(feature = "password-hash")] +pub use password_hash; + #[cfg(feature = "signature")] pub use signature; diff --git a/password-hash/CHANGELOG.md b/password-hash/CHANGELOG.md index 1d013ff92..fe87f902b 100644 --- a/password-hash/CHANGELOG.md +++ b/password-hash/CHANGELOG.md @@ -4,3 +4,6 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## 0.1.0 (2021-01-28) +- Initial release diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index 085c318e6..4a7834b88 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -5,7 +5,7 @@ Traits which describe the functionality of password hashing algorithms, as well as a `no_std`-friendly implementation of the PHC string format (a well-defined subset of the Modular Crypt Format a.k.a. MCF) """ -version = "0.0.0" +version = "0.1.0" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index c173266ac..0155cf66b 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -29,9 +29,9 @@ #![cfg_attr(docsrs, feature(doc_cfg))] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", + html_root_url = "https://docs.rs/password-hash/0.1.0" )] -#![allow(clippy::len_without_is_empty)] #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] diff --git a/password-hash/src/output.rs b/password-hash/src/output.rs index 6afd61076..223ee9e71 100644 --- a/password-hash/src/output.rs +++ b/password-hash/src/output.rs @@ -68,6 +68,7 @@ pub struct Output { length: u8, } +#[allow(clippy::len_without_is_empty)] impl Output { /// Minimum length of [`Output`] string: 10-bytes. /// diff --git a/password-hash/src/salt.rs b/password-hash/src/salt.rs index d82914f06..e397b076e 100644 --- a/password-hash/src/salt.rs +++ b/password-hash/src/salt.rs @@ -84,6 +84,7 @@ const INVARIANT_VIOLATED_MSG: &str = "salt string invariant violated"; #[derive(Copy, Clone, Eq, PartialEq)] pub struct Salt<'a>(Value<'a>); +#[allow(clippy::len_without_is_empty)] impl<'a> Salt<'a> { /// Minimum length of a [`Salt`] string: 2-bytes. /// @@ -181,6 +182,7 @@ pub struct SaltString { length: u8, } +#[allow(clippy::len_without_is_empty)] impl SaltString { /// Generate a random B64-encoded [`SaltString`]. #[cfg(feature = "rand_core")] @@ -224,14 +226,24 @@ impl SaltString { self.as_salt().b64_decode(buf) } + /// Borrow the contents of a [`SaltString`] as a [`Salt`]. + pub fn as_salt(&self) -> Salt<'_> { + Salt::new(self.as_str()).expect(INVARIANT_VIOLATED_MSG) + } + /// Borrow the contents of a [`SaltString`] as a `str`. pub fn as_str(&self) -> &str { str::from_utf8(&self.bytes[..(self.length as usize)]).expect(INVARIANT_VIOLATED_MSG) } - /// Borrow the contents of a [`SaltString`] as a [`Salt`]. - pub fn as_salt(&self) -> Salt<'_> { - Salt::new(self.as_str()).expect(INVARIANT_VIOLATED_MSG) + /// Borrow this value as bytes. + pub fn as_bytes(&self) -> &[u8] { + self.as_str().as_bytes() + } + + /// Get the length of this value in ASCII characters. + pub fn len(&self) -> usize { + self.as_str().len() } } From c4c0d437fbc4cbf6ed8e6fe95244ba78e876a48a Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 28 Jan 2021 19:37:18 -0800 Subject: [PATCH 0403/1461] README.md: fix linewrapping (#500) --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 72fb8f142..1639ebb39 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Collection of traits which describe functionality of cryptographic primitives. | [`crypto‑mac`] | [Message authentication code] | [![crates.io](https://img.shields.io/crates/v/crypto-mac.svg)](https://crates.io/crates/crypto-mac) | [![Documentation](https://docs.rs/crypto-mac/badge.svg)](https://docs.rs/crypto-mac) | ![build](https://github.com/RustCrypto/traits/workflows/crypto-mac/badge.svg?branch=master&event=push) | | [`digest`] | [Cryptographic hash function] | [![crates.io](https://img.shields.io/crates/v/digest.svg)](https://crates.io/crates/digest) | [![Documentation](https://docs.rs/digest/badge.svg)](https://docs.rs/digest) | ![build](https://github.com/RustCrypto/traits/workflows/digest/badge.svg?branch=master&event=push) | | [`elliptic‑curve`] | [Elliptic curve cryptography] | [![crates.io](https://img.shields.io/crates/v/elliptic-curve.svg)](https://crates.io/crates/elliptic-curve) | [![Documentation](https://docs.rs/elliptic-curve/badge.svg)](https://docs.rs/elliptic-curve) | ![build](https://github.com/RustCrypto/traits/workflows/elliptic-curve/badge.svg?branch=master&event=push) | -| [`password-hash`] | [Password hashing algorithms] | [![crates.io](https://img.shields.io/crates/v/password-hash.svg)](https://crates.io/crates/password-hash) | [![Documentation](https://docs.rs/password-hash/badge.svg)](https://docs.rs/password-hash) | ![build](https://github.com/RustCrypto/traits/workflows/password-hash/badge.svg?branch=master&event=push) | +| [`password-hash`] | [Password hashing] | [![crates.io](https://img.shields.io/crates/v/password-hash.svg)](https://crates.io/crates/password-hash) | [![Documentation](https://docs.rs/password-hash/badge.svg)](https://docs.rs/password-hash) | ![build](https://github.com/RustCrypto/traits/workflows/password-hash/badge.svg?branch=master&event=push) | | [`signature`] | [Digital signature] | [![crates.io](https://img.shields.io/crates/v/signature.svg)](https://crates.io/crates/signature) | [![Documentation](https://docs.rs/signature/badge.svg)](https://docs.rs/signature) | ![build](https://github.com/RustCrypto/traits/workflows/signature/badge.svg?branch=master&event=push) | | [`universal‑hash`] | [Universal hash function] | [![crates.io](https://img.shields.io/crates/v/universal-hash.svg)](https://crates.io/crates/universal-hash) | [![Documentation](https://docs.rs/universal-hash/badge.svg)](https://docs.rs/universal-hash) | ![build](https://github.com/RustCrypto/traits/workflows/universal-hash/badge.svg?branch=master&event=push) | @@ -73,6 +73,6 @@ dual licensed as above, without any additional terms or conditions. [Cryptographic hash function]: https://en.wikipedia.org/wiki/Cryptographic_hash_function [Digital signature]: https://en.wikipedia.org/wiki/Digital_signature [Elliptic curve cryptography]: https://en.wikipedia.org/wiki/Elliptic-curve_cryptography -[Password hashing algorithms]: https://en.wikipedia.org/wiki/Cryptographic_hash_function#Password_verification +[Password hashing]: https://en.wikipedia.org/wiki/Cryptographic_hash_function#Password_verification [Stream cipher]: https://en.wikipedia.org/wiki/Stream_cipher [Universal hash function]: https://en.wikipedia.org/wiki/Universal_hashing From 4d6f0758d3dafee93b0853d718c6f25aff0b53d0 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 28 Jan 2021 19:47:40 -0800 Subject: [PATCH 0404/1461] crypto: fix links (#501) Some weren't updated from the `cryptography` crates --- crypto/Cargo.toml | 2 +- crypto/README.md | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index d34672f8b..a345e04a1 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -4,7 +4,7 @@ version = "0.2.0-pre" authors = ["The RustCrypto Project Developers"] license = "Apache-2.0 OR MIT" description = "Facade crate for the RustCrypto project's traits" -documentation = "https://docs.rs/cryptography" +documentation = "https://docs.rs/crypto" repository = "https://github.com/RustCrypto/traits" keywords = ["crypto", "encryption", "rustcrypto"] categories = ["cryptography", "no-std"] diff --git a/crypto/README.md b/crypto/README.md index 76a750403..0a512fc8e 100644 --- a/crypto/README.md +++ b/crypto/README.md @@ -1,4 +1,4 @@ -# RustCrypto: `cryptography` crate +# RustCrypto: `crypto` crate [![crate][crate-image]][crate-link] [![Docs][docs-image]][docs-link] @@ -41,16 +41,16 @@ dual licensed as above, without any additional terms or conditions. [//]: # (badges) -[crate-image]: https://img.shields.io/crates/v/cryptography.svg -[crate-link]: https://crates.io/crates/cryptography -[docs-image]: https://docs.rs/cryptography/badge.svg -[docs-link]: https://docs.rs/cryptography/ +[crate-image]: https://img.shields.io/crates/v/crypto.svg +[crate-link]: https://crates.io/crates/crypto +[docs-image]: https://docs.rs/crypto/badge.svg +[docs-link]: https://docs.rs/crypto/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg [rustc-image]: https://img.shields.io/badge/rustc-1.44+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260050-Traits -[build-image]: https://github.com/RustCrypto/traits/workflows/cryptography/badge.svg?branch=master&event=push -[build-link]: https://github.com/RustCrypto/traits/actions?query=workflow%3Acryptography +[build-image]: https://github.com/RustCrypto/traits/workflows/crypto/badge.svg?branch=master&event=push +[build-link]: https://github.com/RustCrypto/traits/actions?query=workflow:crypto [//]: # (footnotes) From 1b5396501de16fa44477994252bb49c998f4db49 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 29 Jan 2021 15:05:59 -0800 Subject: [PATCH 0405/1461] password-hash: fix encoding test (#506) It was gated under a removed cargo feature --- password-hash/tests/encoding.rs | 69 +++++++++++++++++---------------- 1 file changed, 36 insertions(+), 33 deletions(-) diff --git a/password-hash/tests/encoding.rs b/password-hash/tests/encoding.rs index 44a3c070f..107136063 100644 --- a/password-hash/tests/encoding.rs +++ b/password-hash/tests/encoding.rs @@ -4,15 +4,11 @@ //! of the string encoding, and ensures password hashes round trip under each //! of the conditions. -#![cfg(feature = "registry")] +use core::convert::{TryFrom, TryInto}; +use password_hash::{Ident, ParamsString, PasswordHash, Salt}; -use core::convert::TryInto; -use password_hash::{algorithm::argon2, Algorithm, ParamsString, PasswordHash}; - -const EXAMPLE_ALGORITHM: Algorithm = Algorithm::Argon2(argon2::Variant::D); -const EXAMPLE_SALT: &[u8] = &[ - 0xb1, 0xa9, 0x6d, 0xb1, 0xa9, 0x6d, 0xb1, 0xa9, 0x6d, 0xb1, 0xa9, 0x6d, 0xb1, 0xa9, 0x6d, 0xb0, -]; +const EXAMPLE_ALGORITHM: Ident = Ident::new("argon2d"); +const EXAMPLE_SALT: &str = "saltsaltsaltsaltsalt"; const EXAMPLE_HASH: &[u8] = &[ 0x85, 0xab, 0x21, 0x85, 0xab, 0x21, 0x85, 0xab, 0x21, 0x85, 0xab, 0x21, 0x85, 0xab, 0x21, 0x85, 0xab, 0x21, 0x85, 0xab, 0x21, 0x85, 0xab, 0x21, 0x85, 0xab, 0x21, 0x85, 0xab, 0x21, 0x85, 0xab, @@ -20,22 +16,22 @@ const EXAMPLE_HASH: &[u8] = &[ /// Example parameters fn example_params() -> ParamsString { - ParamsString::from_pairs(&[ - ("a".parse().unwrap(), 1u32.into()), - ("b".parse().unwrap(), 2u32.into()), - ("c".parse().unwrap(), 3u32.into()), - ]) - .unwrap() + let mut params = ParamsString::new(); + params.add_decimal("a", 1).unwrap(); + params.add_decimal("b", 2).unwrap(); + params.add_decimal("c", 3).unwrap(); + params } #[test] fn algorithm_alone() { - let ph = PasswordHash::from(EXAMPLE_ALGORITHM); + let ph = PasswordHash::new("$argon2d").unwrap(); + assert_eq!(ph.algorithm, EXAMPLE_ALGORITHM); let s = ph.to_string(); assert_eq!(s, "$argon2d"); - let ph2 = s.parse::().unwrap(); + let ph2 = PasswordHash::try_from(s.as_str()).unwrap(); assert_eq!(ph, ph2); } @@ -43,6 +39,7 @@ fn algorithm_alone() { fn params() { let ph = PasswordHash { algorithm: EXAMPLE_ALGORITHM, + version: None, params: example_params(), salt: None, hash: None, @@ -51,7 +48,7 @@ fn params() { let s = ph.to_string(); assert_eq!(s, "$argon2d$a=1,b=2,c=3"); - let ph2 = s.parse::().unwrap(); + let ph2 = PasswordHash::try_from(s.as_str()).unwrap(); assert_eq!(ph, ph2); } @@ -59,33 +56,36 @@ fn params() { fn salt() { let ph = PasswordHash { algorithm: EXAMPLE_ALGORITHM, + version: None, params: ParamsString::new(), - salt: Some(EXAMPLE_SALT.try_into().unwrap()), + salt: Some(Salt::new(EXAMPLE_SALT).unwrap()), hash: None, }; let s = ph.to_string(); - assert_eq!(s, "$argon2d$saltsaltsaltsaltsaltsA"); + assert_eq!(s, "$argon2d$saltsaltsaltsaltsalt"); - let ph2 = s.parse::().unwrap(); + let ph2 = PasswordHash::try_from(s.as_str()).unwrap(); assert_eq!(ph, ph2); } #[test] fn one_param_and_salt() { - let params = ParamsString::from_pairs(&[("a".parse().unwrap(), 1u32.into())]).unwrap(); + let mut params = ParamsString::new(); + params.add_decimal("a", 1).unwrap(); let ph = PasswordHash { algorithm: EXAMPLE_ALGORITHM, + version: None, params, - salt: Some(EXAMPLE_SALT.try_into().unwrap()), + salt: Some(Salt::new(EXAMPLE_SALT).unwrap()), hash: None, }; let s = ph.to_string(); - assert_eq!(s, "$argon2d$a=1$saltsaltsaltsaltsaltsA"); + assert_eq!(s, "$argon2d$a=1$saltsaltsaltsaltsalt"); - let ph2 = s.parse::().unwrap(); + let ph2 = PasswordHash::try_from(s.as_str()).unwrap(); assert_eq!(ph, ph2); } @@ -93,15 +93,16 @@ fn one_param_and_salt() { fn params_and_salt() { let ph = PasswordHash { algorithm: EXAMPLE_ALGORITHM, + version: None, params: example_params(), - salt: Some(EXAMPLE_SALT.try_into().unwrap()), + salt: Some(Salt::new(EXAMPLE_SALT).unwrap()), hash: None, }; let s = ph.to_string(); - assert_eq!(s, "$argon2d$a=1,b=2,c=3$saltsaltsaltsaltsaltsA"); + assert_eq!(s, "$argon2d$a=1,b=2,c=3$saltsaltsaltsaltsalt"); - let ph2 = s.parse::().unwrap(); + let ph2 = PasswordHash::try_from(s.as_str()).unwrap(); assert_eq!(ph, ph2); } @@ -109,18 +110,19 @@ fn params_and_salt() { fn salt_and_hash() { let ph = PasswordHash { algorithm: EXAMPLE_ALGORITHM, + version: None, params: ParamsString::default(), - salt: Some(EXAMPLE_SALT.try_into().unwrap()), + salt: Some(Salt::new(EXAMPLE_SALT).unwrap()), hash: Some(EXAMPLE_HASH.try_into().unwrap()), }; let s = ph.to_string(); assert_eq!( s, - "$argon2d$saltsaltsaltsaltsaltsA$hashhashhashhashhashhashhashhashhashhashhas" + "$argon2d$saltsaltsaltsaltsalt$hashhashhashhashhashhashhashhashhashhashhas" ); - let ph2 = s.parse::().unwrap(); + let ph2 = PasswordHash::try_from(s.as_str()).unwrap(); assert_eq!(ph, ph2); } @@ -128,17 +130,18 @@ fn salt_and_hash() { fn all_fields() { let ph = PasswordHash { algorithm: EXAMPLE_ALGORITHM, + version: None, params: example_params(), - salt: Some(EXAMPLE_SALT.try_into().unwrap()), + salt: Some(Salt::new(EXAMPLE_SALT).unwrap()), hash: Some(EXAMPLE_HASH.try_into().unwrap()), }; let s = ph.to_string(); assert_eq!( s, - "$argon2d$a=1,b=2,c=3$saltsaltsaltsaltsaltsA$hashhashhashhashhashhashhashhashhashhashhas" + "$argon2d$a=1,b=2,c=3$saltsaltsaltsaltsalt$hashhashhashhashhashhashhashhashhashhashhas" ); - let ph2 = s.parse::().unwrap(); + let ph2 = PasswordHash::try_from(s.as_str()).unwrap(); assert_eq!(ph, ph2); } From 24eaf21137e55249ec6d58fcfba207ed6232396f Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 29 Jan 2021 17:34:25 -0800 Subject: [PATCH 0406/1461] password-hash: add "Supported Crates" section to rustdoc (#509) --- password-hash/src/lib.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index 0155cf66b..43eb2c2b2 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -6,8 +6,14 @@ //! (a well-defined subset of the [Modular Crypt Format a.k.a. MCF][MCF]) which //! works in conjunction with the traits this crate defines. //! +//! # Supported Crates +//! //! See [RustCrypto/password-hashes] for algorithm implementations which use -//! this crate for interoperability. +//! this crate for interoperability: +//! +//! - [`argon2`] - Argon2 memory hard key derivation function +//! - [`pbkdf2`] - Password-Based Key Derivation Function v2 +//! - [`scrypt`] - scrypt key derivation function //! //! # Usage //! @@ -24,6 +30,9 @@ //! [PHC]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md //! [MCF]: https://passlib.readthedocs.io/en/stable/modular_crypt_format.html //! [RustCrypto/password-hashes]: https://github.com/RustCrypto/password-hashes +//! [`argon2`]: https://docs.rs/argon2 +//! [`pbkdf2`]: https://docs.rs/pbkdf2 +//! [`scrypt`]: https://docs.rs/scrypt #![no_std] #![cfg_attr(docsrs, feature(doc_cfg))] From d50727b37da4af50a57dc4361ea42306a1a50070 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 30 Jan 2021 06:16:37 -0800 Subject: [PATCH 0407/1461] aead: extract AeadCore trait (#508) Extracts a single trait for defining nonce, tag, and overhead sizes instead of repetitively defining those associated types on every other trait. This allows for fully generic `Nonce` and `Tag` type aliases. --- aead/src/lib.rs | 124 ++++++++++++++++----------------------------- aead/src/stream.rs | 28 +++++----- 2 files changed, 56 insertions(+), 96 deletions(-) diff --git a/aead/src/lib.rs b/aead/src/lib.rs index 2b5703d35..14b78db07 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -68,10 +68,10 @@ impl std::error::Error for Error {} pub type Key = GenericArray::KeySize>; /// Nonce: single-use value for ensuring ciphertexts are unique -pub type Nonce = GenericArray; +pub type Nonce = GenericArray::NonceSize>; /// Tag: authentication code which ensures ciphertexts are authentic -pub type Tag = GenericArray; +pub type Tag = GenericArray::TagSize>; /// Instantiate either a stateless [`Aead`] or stateful [`AeadMut`] algorithm. pub trait NewAead { @@ -96,13 +96,11 @@ pub trait NewAead { } } -/// Authenticated Encryption with Associated Data (AEAD) algorithm. +/// Authenticated Encryption with Associated Data (AEAD) algorithm core trait. /// -/// This trait is intended for use with stateless AEAD algorithms. The -/// [`AeadMut`] trait provides a stateful interface. -#[cfg(feature = "alloc")] -#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] -pub trait Aead { +/// Defines nonce, tag, and overhead sizes that are consumed by various other +/// `Aead*` traits. +pub trait AeadCore { /// The length of a nonce. type NonceSize: ArrayLength; @@ -112,7 +110,15 @@ pub trait Aead { /// The upper bound amount of additional space required to support a /// ciphertext vs. a plaintext. type CiphertextOverhead: ArrayLength + Unsigned; +} +/// Authenticated Encryption with Associated Data (AEAD) algorithm. +/// +/// This trait is intended for use with stateless AEAD algorithms. The +/// [`AeadMut`] trait provides a stateful interface. +#[cfg(feature = "alloc")] +#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] +pub trait Aead: AeadCore { /// Encrypt the given plaintext payload, and return the resulting /// ciphertext as a vector of bytes. /// @@ -138,7 +144,7 @@ pub trait Aead { /// ciphertext message. fn encrypt<'msg, 'aad>( &self, - nonce: &Nonce, + nonce: &Nonce, plaintext: impl Into>, ) -> Result, Error>; @@ -161,7 +167,7 @@ pub trait Aead { /// ciphertext message. fn decrypt<'msg, 'aad>( &self, - nonce: &Nonce, + nonce: &Nonce, ciphertext: impl Into>, ) -> Result, Error>; } @@ -169,17 +175,7 @@ pub trait Aead { /// Stateful Authenticated Encryption with Associated Data algorithm. #[cfg(feature = "alloc")] #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] -pub trait AeadMut { - /// The length of a nonce. - type NonceSize: ArrayLength; - - /// The maximum length of the nonce. - type TagSize: ArrayLength; - - /// The upper bound amount of additional space required to support a - /// ciphertext vs. a plaintext. - type CiphertextOverhead: ArrayLength + Unsigned; - +pub trait AeadMut: AeadCore { /// Encrypt the given plaintext slice, and return the resulting ciphertext /// as a vector of bytes. /// @@ -187,7 +183,7 @@ pub trait AeadMut { /// Associated Additional Data (AAD). fn encrypt<'msg, 'aad>( &mut self, - nonce: &Nonce, + nonce: &Nonce, plaintext: impl Into>, ) -> Result, Error>; @@ -198,7 +194,7 @@ pub trait AeadMut { /// message payloads and Associated Additional Data (AAD). fn decrypt<'msg, 'aad>( &mut self, - nonce: &Nonce, + nonce: &Nonce, ciphertext: impl Into>, ) -> Result, Error>; } @@ -216,7 +212,7 @@ macro_rules! impl_decrypt_in_place { let tag_pos = $buffer.len() - Self::TagSize::to_usize(); let (msg, tag) = $buffer.as_mut().split_at_mut(tag_pos); - $aead.decrypt_in_place_detached($nonce, $aad, msg, Tag::from_slice(tag))?; + $aead.decrypt_in_place_detached($nonce, $aad, msg, Tag::::from_slice(tag))?; $buffer.truncate(tag_pos); Ok(()) }}; @@ -225,17 +221,7 @@ macro_rules! impl_decrypt_in_place { /// In-place stateless AEAD trait. /// /// This trait is both object safe and has no dependencies on `alloc` or `std`. -pub trait AeadInPlace { - /// The length of a nonce. - type NonceSize: ArrayLength; - - /// The maximum length of the nonce. - type TagSize: ArrayLength; - - /// The upper bound amount of additional space required to support a - /// ciphertext vs. a plaintext. - type CiphertextOverhead: ArrayLength + Unsigned; - +pub trait AeadInPlace: AeadCore { /// Encrypt the given buffer containing a plaintext message in-place. /// /// The buffer must have sufficient capacity to store the ciphertext @@ -247,7 +233,7 @@ pub trait AeadInPlace { /// resulting ciphertext message. fn encrypt_in_place( &self, - nonce: &Nonce, + nonce: &Nonce, associated_data: &[u8], buffer: &mut dyn Buffer, ) -> Result<(), Error> { @@ -259,10 +245,10 @@ pub trait AeadInPlace { /// Encrypt the data in-place, returning the authentication tag fn encrypt_in_place_detached( &self, - nonce: &Nonce, + nonce: &Nonce, associated_data: &[u8], buffer: &mut [u8], - ) -> Result, Error>; + ) -> Result, Error>; /// Decrypt the message in-place, returning an error in the event the /// provided authentication tag does not match the given ciphertext. @@ -271,7 +257,7 @@ pub trait AeadInPlace { /// message upon success. fn decrypt_in_place( &self, - nonce: &Nonce, + nonce: &Nonce, associated_data: &[u8], buffer: &mut dyn Buffer, ) -> Result<(), Error> { @@ -283,27 +269,17 @@ pub trait AeadInPlace { /// is modified/unauthentic) fn decrypt_in_place_detached( &self, - nonce: &Nonce, + nonce: &Nonce, associated_data: &[u8], buffer: &mut [u8], - tag: &Tag, + tag: &Tag, ) -> Result<(), Error>; } /// In-place stateful AEAD trait. /// /// This trait is both object safe and has no dependencies on `alloc` or `std`. -pub trait AeadMutInPlace { - /// The length of a nonce. - type NonceSize: ArrayLength; - - /// The maximum length of the nonce. - type TagSize: ArrayLength; - - /// The upper bound amount of additional space required to support a - /// ciphertext vs. a plaintext. - type CiphertextOverhead: ArrayLength + Unsigned; - +pub trait AeadMutInPlace: AeadCore { /// Encrypt the given buffer containing a plaintext message in-place. /// /// The buffer must have sufficient capacity to store the ciphertext @@ -315,7 +291,7 @@ pub trait AeadMutInPlace { /// resulting ciphertext message. fn encrypt_in_place( &mut self, - nonce: &Nonce, + nonce: &Nonce, associated_data: &[u8], buffer: &mut impl Buffer, ) -> Result<(), Error> { @@ -327,10 +303,10 @@ pub trait AeadMutInPlace { /// Encrypt the data in-place, returning the authentication tag fn encrypt_in_place_detached( &mut self, - nonce: &Nonce, + nonce: &Nonce, associated_data: &[u8], buffer: &mut [u8], - ) -> Result, Error>; + ) -> Result, Error>; /// Decrypt the message in-place, returning an error in the event the /// provided authentication tag does not match the given ciphertext. @@ -339,7 +315,7 @@ pub trait AeadMutInPlace { /// message upon success. fn decrypt_in_place( &mut self, - nonce: &Nonce, + nonce: &Nonce, associated_data: &[u8], buffer: &mut impl Buffer, ) -> Result<(), Error> { @@ -351,22 +327,18 @@ pub trait AeadMutInPlace { /// is modified/unauthentic) fn decrypt_in_place_detached( &mut self, - nonce: &Nonce, + nonce: &Nonce, associated_data: &[u8], buffer: &mut [u8], - tag: &Tag, + tag: &Tag, ) -> Result<(), Error>; } #[cfg(feature = "alloc")] impl Aead for Alg { - type NonceSize = Alg::NonceSize; - type TagSize = Alg::TagSize; - type CiphertextOverhead = Alg::CiphertextOverhead; - fn encrypt<'msg, 'aad>( &self, - nonce: &Nonce, + nonce: &Nonce, plaintext: impl Into>, ) -> Result, Error> { let payload = plaintext.into(); @@ -378,7 +350,7 @@ impl Aead for Alg { fn decrypt<'msg, 'aad>( &self, - nonce: &Nonce, + nonce: &Nonce, ciphertext: impl Into>, ) -> Result, Error> { let payload = ciphertext.into(); @@ -390,13 +362,9 @@ impl Aead for Alg { #[cfg(feature = "alloc")] impl AeadMut for Alg { - type NonceSize = Alg::NonceSize; - type TagSize = Alg::TagSize; - type CiphertextOverhead = Alg::CiphertextOverhead; - fn encrypt<'msg, 'aad>( &mut self, - nonce: &Nonce, + nonce: &Nonce, plaintext: impl Into>, ) -> Result, Error> { let payload = plaintext.into(); @@ -408,7 +376,7 @@ impl AeadMut for Alg { fn decrypt<'msg, 'aad>( &mut self, - nonce: &Nonce, + nonce: &Nonce, ciphertext: impl Into>, ) -> Result, Error> { let payload = ciphertext.into(); @@ -419,13 +387,9 @@ impl AeadMut for Alg { } impl AeadMutInPlace for Alg { - type NonceSize = Alg::NonceSize; - type TagSize = Alg::TagSize; - type CiphertextOverhead = Alg::CiphertextOverhead; - fn encrypt_in_place( &mut self, - nonce: &Nonce, + nonce: &Nonce, associated_data: &[u8], buffer: &mut impl Buffer, ) -> Result<(), Error> { @@ -434,16 +398,16 @@ impl AeadMutInPlace for Alg { fn encrypt_in_place_detached( &mut self, - nonce: &Nonce, + nonce: &Nonce, associated_data: &[u8], buffer: &mut [u8], - ) -> Result, Error> { + ) -> Result, Error> { ::encrypt_in_place_detached(self, nonce, associated_data, buffer) } fn decrypt_in_place( &mut self, - nonce: &Nonce, + nonce: &Nonce, associated_data: &[u8], buffer: &mut impl Buffer, ) -> Result<(), Error> { @@ -452,10 +416,10 @@ impl AeadMutInPlace for Alg { fn decrypt_in_place_detached( &mut self, - nonce: &Nonce, + nonce: &Nonce, associated_data: &[u8], buffer: &mut [u8], - tag: &Tag, + tag: &Tag, ) -> Result<(), Error> { ::decrypt_in_place_detached(self, nonce, associated_data, buffer, tag) } diff --git a/aead/src/stream.rs b/aead/src/stream.rs index 554284b35..ae472b602 100644 --- a/aead/src/stream.rs +++ b/aead/src/stream.rs @@ -17,7 +17,7 @@ //! //! [1]: https://eprint.iacr.org/2015/189.pdf -use crate::{AeadInPlace, Buffer, Error, Key, NewAead}; +use crate::{AeadCore, AeadInPlace, Buffer, Error, Key, NewAead}; use core::ops::{AddAssign, Sub}; use generic_array::{ typenum::{Unsigned, U4, U5}, @@ -33,7 +33,7 @@ pub type Nonce = GenericArray>; /// Size of a nonce as used by a STREAM construction, sans the overhead of /// the STREAM protocol itself. pub type NonceSize = - <::NonceSize as Sub<>::NonceOverhead>>::Output; + <::NonceSize as Sub<>::NonceOverhead>>::Output; /// STREAM encryptor instantiated with [`StreamBE32`] as the underlying /// STREAM primitive. @@ -352,7 +352,7 @@ pub struct StreamBE32 where A: AeadInPlace, A::NonceSize: Sub, - <::NonceSize as Sub>::Output: ArrayLength, + <::NonceSize as Sub>::Output: ArrayLength, { /// Underlying AEAD cipher aead: A, @@ -365,7 +365,7 @@ impl NewStream for StreamBE32 where A: AeadInPlace, A::NonceSize: Sub, - <::NonceSize as Sub>::Output: ArrayLength, + <::NonceSize as Sub>::Output: ArrayLength, { fn from_aead(aead: A, nonce: &Nonce) -> Self { Self { @@ -379,7 +379,7 @@ impl StreamPrimitive for StreamBE32 where A: AeadInPlace, A::NonceSize: Sub, - <::NonceSize as Sub>::Output: ArrayLength, + <::NonceSize as Sub>::Output: ArrayLength, { type NonceOverhead = U5; type Counter = u32; @@ -413,11 +413,11 @@ impl StreamBE32 where A: AeadInPlace, A::NonceSize: Sub, - <::NonceSize as Sub>::Output: ArrayLength, + <::NonceSize as Sub>::Output: ArrayLength, { /// Compute the full AEAD nonce including the STREAM counter and last /// block flag. - fn aead_nonce(&self, position: u32, last_block: bool) -> crate::Nonce { + fn aead_nonce(&self, position: u32, last_block: bool) -> crate::Nonce { let mut result = GenericArray::default(); // TODO(tarcieri): use `generic_array::sequence::Concat` (or const generics) @@ -441,7 +441,7 @@ pub struct StreamLE31 where A: AeadInPlace, A::NonceSize: Sub, - <::NonceSize as Sub>::Output: ArrayLength, + <::NonceSize as Sub>::Output: ArrayLength, { /// Underlying AEAD cipher aead: A, @@ -454,7 +454,7 @@ impl NewStream for StreamLE31 where A: AeadInPlace, A::NonceSize: Sub, - <::NonceSize as Sub>::Output: ArrayLength, + <::NonceSize as Sub>::Output: ArrayLength, { fn from_aead(aead: A, nonce: &Nonce) -> Self { Self { @@ -468,7 +468,7 @@ impl StreamPrimitive for StreamLE31 where A: AeadInPlace, A::NonceSize: Sub, - <::NonceSize as Sub>::Output: ArrayLength, + <::NonceSize as Sub>::Output: ArrayLength, { type NonceOverhead = U4; type Counter = u32; @@ -502,15 +502,11 @@ impl StreamLE31 where A: AeadInPlace, A::NonceSize: Sub, - <::NonceSize as Sub>::Output: ArrayLength, + <::NonceSize as Sub>::Output: ArrayLength, { /// Compute the full AEAD nonce including the STREAM counter and last /// block flag. - fn aead_nonce( - &self, - position: u32, - last_block: bool, - ) -> Result, Error> { + fn aead_nonce(&self, position: u32, last_block: bool) -> Result, Error> { if position > Self::COUNTER_MAX { return Err(Error); } From 252b77f0ee659b146c8aeb711d7372471cd65d0d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 30 Jan 2021 12:46:06 -0800 Subject: [PATCH 0408/1461] aead v0.4.0-pre (#511) --- Cargo.lock | 2 +- aead/CHANGELOG.md | 10 ++++++++++ aead/Cargo.toml | 7 +++++-- aead/src/lib.rs | 3 ++- crypto/Cargo.toml | 2 +- 5 files changed, 19 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5a0223d58..dd53b95b1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,7 +2,7 @@ # It is not intended for manual editing. [[package]] name = "aead" -version = "0.3.2" +version = "0.4.0-pre" dependencies = [ "blobby", "generic-array 0.14.4", diff --git a/aead/CHANGELOG.md b/aead/CHANGELOG.md index c10fb269d..bc265665e 100644 --- a/aead/CHANGELOG.md +++ b/aead/CHANGELOG.md @@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.4.0 (UNRELEASED) +### Added +- `stream` module ([#436]) + +### Changed +- Extract `AeadCore` trait ([#508]) + +[#436]: https://github.com/RustCrypto/traits/pull/436 +[#508]: https://github.com/RustCrypto/traits/pull/508 + ## 0.3.2 (2020-07-01) ### Added - `dev` module ([#194]) diff --git a/aead/Cargo.toml b/aead/Cargo.toml index 580faecfc..38315a5a5 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -1,11 +1,14 @@ [package] name = "aead" -version = "0.3.2" +version = "0.4.0-pre" # Also update html_root_url in lib.rs when bumping this +description = """ +Traits for Authenticated Encryption with Associated Data (AEAD) algorithms, +such as AES-GCM as ChaCha20Poly1305, which provide a high-level API +""" authors = ["RustCrypto Developers"] edition = "2018" license = "MIT OR Apache-2.0" readme = "README.md" -description = "Traits for Authenticated Encryption with Associated Data (AEAD) algorithms" documentation = "https://docs.rs/aead" repository = "https://github.com/RustCrypto/traits" keywords = ["crypto", "encryption"] diff --git a/aead/src/lib.rs b/aead/src/lib.rs index 14b78db07..69afe87dc 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -18,7 +18,8 @@ #![forbid(unsafe_code)] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", + html_root_url = "https://docs.rs/aead/0.4.0-pre" )] #![warn(missing_docs, rust_2018_idioms)] diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index a345e04a1..cfdff251c 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -12,7 +12,7 @@ readme = "README.md" edition = "2018" [dependencies] -aead = { version = "0.3", optional = true, path = "../aead" } +aead = { version = "=0.4.0-pre", optional = true, path = "../aead" } cipher = { version = "=0.3.0-pre.4", optional = true, path = "../cipher" } digest = { version = "0.10.0-pre", optional = true, path = "../digest" } elliptic-curve = { version = "=0.9.0-pre", optional = true, path = "../elliptic-curve" } From 2db9e3f5a91cce93ad34dd9ced687c0f2c999283 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 31 Jan 2021 06:41:32 -0800 Subject: [PATCH 0409/1461] aead: use `new_from_slice` naming convention (#512) Following the convention introduced in #442, renames the `NewAead::new_varkey` method to `::new_from_slice`. --- aead/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aead/src/lib.rs b/aead/src/lib.rs index 69afe87dc..5d4b5f750 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -82,10 +82,10 @@ pub trait NewAead { /// Create a new AEAD instance with the given key. fn new(key: &Key) -> Self; - /// Create new AEAD instance from key with variable size. + /// Create new AEAD instance from key given as a byte slice.. /// /// Default implementation will accept only keys with length equal to `KeySize`. - fn new_varkey(key: &[u8]) -> Result + fn new_from_slice(key: &[u8]) -> Result where Self: Sized, { From 5d9f74d19b93a41f22fc377b7eb869efda3b00dd Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 31 Jan 2021 07:01:49 -0800 Subject: [PATCH 0410/1461] aead: disable alloc by default (closes #273) (#514) The `alloc` feature used to be a mandatory part of the `aead` API, but in the time since we've introduced in-place traits that allow for fully heapless usage. This commit removes it as a default feature. --- .github/workflows/aead.yml | 1 + aead/Cargo.toml | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/aead.yml b/.github/workflows/aead.yml index ed1acd4b2..90b7d4cdd 100644 --- a/.github/workflows/aead.yml +++ b/.github/workflows/aead.yml @@ -36,6 +36,7 @@ jobs: target: ${{ matrix.target }} override: true - run: cargo build --target ${{ matrix.target }} --release --no-default-features + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features stream test: diff --git a/aead/Cargo.toml b/aead/Cargo.toml index 38315a5a5..8883f592a 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -20,10 +20,9 @@ heapless = { version = "0.5", optional = true } blobby = { version = "0.3", optional = true } [features] -default = ["alloc"] +std = ["alloc"] alloc = [] dev = ["blobby"] -std = ["alloc"] stream = [] [package.metadata.docs.rs] From 37d8c8613290d729ff80d05488c9002549ef9d40 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 31 Jan 2021 18:40:14 -0800 Subject: [PATCH 0411/1461] password-hash: add basic encoding support (#515) Support for encoding `Output` using the following Base64 variants: - B64: for PHC hashes - bcrypt - `crypt(3)`: for SHA-crypt --- Cargo.lock | 4 +- password-hash/Cargo.toml | 2 +- password-hash/src/encoding.rs | 72 +++++++++++++++++++++++++++++++++++ password-hash/src/lib.rs | 2 + password-hash/src/output.rs | 47 ++++++++++++++++++++--- 5 files changed, 118 insertions(+), 9 deletions(-) create mode 100644 password-hash/src/encoding.rs diff --git a/Cargo.lock b/Cargo.lock index dd53b95b1..425c54478 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -42,9 +42,9 @@ dependencies = [ [[package]] name = "base64ct" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96c6b8c1cac2cfe84b4ea97794c43085b401df66c466e9a863744c0489679a7" +checksum = "b245b005bb8924f38647aeb31388984784a139acbe7ac6d7435fb0a11c4c83d8" [[package]] name = "bitvec" diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index 4a7834b88..a3e996d32 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -16,7 +16,7 @@ categories = ["cryptography", "no-std"] keywords = ["crypt", "mcf", "password", "pbkdf", "phc"] [dependencies] -base64ct = "0.1" +base64ct = "0.1.2" rand_core = { version = "0.6", optional = true, default-features = false } [features] diff --git a/password-hash/src/encoding.rs b/password-hash/src/encoding.rs new file mode 100644 index 000000000..009b733a0 --- /dev/null +++ b/password-hash/src/encoding.rs @@ -0,0 +1,72 @@ +//! Base64 encoding variants. + +use crate::B64Error; +use base64ct as base64; + +/// Base64 encoding variants. +#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] +pub enum Encoding { + /// "B64" encoding: standard Base64 without padding. + /// + /// ```text + /// [A-Z] [a-z] [0-9] + / + /// 0x41-0x5a, 0x61-0x7a, 0x30-0x39, 0x2b, 0x2f + /// ``` + /// + B64, + + /// bcrypt encoding. + /// + /// ```text + /// ./ [A-Z] [a-z] [0-9] + /// 0x2e-0x2f, 0x41-0x5a, 0x61-0x7a, 0x30-0x39 + /// ``` + Bcrypt, + + /// `crypt(3)` encoding. + /// + /// ```text + /// [.-9] [A-Z] [a-z] + /// 0x2e-0x39, 0x41-0x5a, 0x61-0x7a + /// ``` + Crypt, +} + +impl Default for Encoding { + fn default() -> Self { + Self::B64 + } +} + +impl Encoding { + /// Decode a Base64 string into the provided destination buffer. + pub fn decode(self, src: impl AsRef<[u8]>, dst: &mut [u8]) -> Result<&[u8], B64Error> { + match self { + Self::B64 => base64::unpadded::decode(src, dst), + Self::Bcrypt => base64::bcrypt::decode(src, dst), + Self::Crypt => base64::crypt::decode(src, dst), + } + } + + /// Encode the input byte slice as Base64. + /// + /// Writes the result into the provided destination slice, returning an + /// ASCII-encoded Base64 string value. + pub fn encode<'a>(self, src: &[u8], dst: &'a mut [u8]) -> Result<&'a str, B64Error> { + match self { + Self::B64 => base64::unpadded::encode(src, dst), + Self::Bcrypt => base64::bcrypt::encode(src, dst), + Self::Crypt => base64::crypt::encode(src, dst), + } + .map_err(Into::into) + } + + /// Get the length of Base64 produced by encoding the given bytes. + pub fn encoded_len(self, bytes: &[u8]) -> usize { + match self { + Self::B64 => base64::unpadded::encoded_len(bytes), + Self::Bcrypt => base64::bcrypt::encoded_len(bytes), + Self::Crypt => base64::crypt::encoded_len(bytes), + } + } +} diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index 43eb2c2b2..7e45d342e 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -50,6 +50,7 @@ extern crate alloc; #[cfg(feature = "std")] extern crate std; +mod encoding; mod errors; mod ident; mod output; @@ -58,6 +59,7 @@ mod salt; mod value; pub use crate::{ + encoding::Encoding, errors::{B64Error, HashError, HasherError, OutputError, ParamsError, ParseError, VerifyError}, ident::Ident, output::Output, diff --git a/password-hash/src/output.rs b/password-hash/src/output.rs index 223ee9e71..c61a7a69f 100644 --- a/password-hash/src/output.rs +++ b/password-hash/src/output.rs @@ -1,6 +1,6 @@ //! Outputs from password hashing functions. -use crate::{b64, errors::OutputError}; +use crate::{b64, Encoding, OutputError}; use core::{cmp::PartialEq, convert::TryFrom, fmt, str::FromStr}; /// Maximum length of password hash function outputs. @@ -66,6 +66,9 @@ pub struct Output { /// Length of the password hashing function output in bytes. length: u8, + + /// Encoding which output should be serialized with. + encoding: Encoding, } #[allow(clippy::len_without_is_empty)] @@ -99,6 +102,15 @@ impl Output { }) } + /// Create a [`Output`] from the given byte slice and [`Encoding`], + /// validating it according to [`Output::min_len`] and [`Output::max_len`] + /// length restrictions. + pub fn new_with_encoding(input: &[u8], encoding: Encoding) -> Result { + let mut result = Self::new(input)?; + result.encoding = encoding; + Ok(result) + } + /// Initialize an [`Output`] using the provided method, which is given /// a mutable byte slice into which it should write the output. /// @@ -122,6 +134,7 @@ impl Output { Ok(Self { bytes, length: output_size as u8, + encoding: Encoding::default(), }) } @@ -130,6 +143,11 @@ impl Output { &self.bytes[..self.len()] } + /// Get the encoding that this [`Output`] will be serialized with. + pub fn encoding(&self) -> Encoding { + self.encoding + } + /// Get the length of the output value as a byte slice. pub fn len(&self) -> usize { usize::from(self.length) @@ -138,10 +156,7 @@ impl Output { /// Parse [`b64`]-encoded [`Output`], i.e. using the PHC string /// specification's restricted interpretation of Base64. pub fn b64_decode(input: &str) -> Result { - let mut bytes = [0u8; MAX_LENGTH]; - b64::decode(input, &mut bytes) - .map_err(Into::into) - .and_then(Self::new) + Self::decode(input, Encoding::B64) } /// Write [`b64`]-encoded [`Output`] to the provided buffer, returning @@ -152,6 +167,24 @@ impl Output { Ok(b64::encode(self.as_ref(), out)?) } + /// Decode the given input string using the specified [`Encoding`]. + pub fn decode(input: &str, encoding: Encoding) -> Result { + let mut bytes = [0u8; MAX_LENGTH]; + encoding + .decode(input, &mut bytes) + .map_err(Into::into) + .and_then(|decoded| Self::new_with_encoding(decoded, encoding)) + } + + /// Encode this [`Output`] using the specified [`Encoding`]. + pub fn encode<'a>( + &self, + out: &'a mut [u8], + encoding: Encoding, + ) -> Result<&'a str, OutputError> { + Ok(encoding.encode(self.as_ref(), out)?) + } + /// Get the length of this [`Output`] when encoded as [`b64`]. pub fn b64_len(&self) -> usize { b64::encoded_len(self.as_ref()) @@ -199,7 +232,9 @@ impl TryFrom<&[u8]> for Output { impl fmt::Display for Output { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let mut buffer = [0u8; Self::b64_max_len()]; - f.write_str(self.b64_encode(&mut buffer).map_err(|_| fmt::Error)?) + self.encode(&mut buffer, self.encoding) + .map_err(|_| fmt::Error) + .and_then(|encoded| f.write_str(encoded)) } } From 831b0ae91a9770c119cc11f3c1a82bd59c9110ee Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Feb 2021 12:05:02 +0000 Subject: [PATCH 0412/1461] build(deps): bump sha2 from 0.9.2 to 0.9.3 (#516) --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 425c54478..964d2b23d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -387,9 +387,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e7aab86fe2149bad8c507606bdb3f4ef5e7b2380eb92350f56122cca72a42a8" +checksum = "fa827a14b29ab7f44778d14a88d3cb76e949c45083f7dbfa507d0cb699dc12de" dependencies = [ "block-buffer 0.9.0", "cfg-if", From d49eb6b69f45004e02b85c661e6cb7d55a404257 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 1 Feb 2021 05:01:52 -0800 Subject: [PATCH 0413/1461] aead+cipher+crypto_mac: add `generate_key` method to `New*` trait (#513) Adds an optional `generate_key` method feature-gated on `rand_core` which uses a provided `CryptoRng` to generate a random key of an appropriate size for a given algorithm. --- .github/workflows/aead.yml | 1 + .github/workflows/cipher.yml | 4 +++- .github/workflows/crypto-mac.yml | 4 +++- Cargo.lock | 3 +++ aead/Cargo.toml | 4 +++- aead/src/lib.rs | 12 ++++++++++++ cipher/Cargo.toml | 2 ++ cipher/src/block.rs | 12 ++++++++++++ cipher/src/common.rs | 14 ++++++++++++++ crypto-mac/Cargo.toml | 4 +++- crypto-mac/src/lib.rs | 12 ++++++++++++ 11 files changed, 68 insertions(+), 4 deletions(-) diff --git a/.github/workflows/aead.yml b/.github/workflows/aead.yml index 90b7d4cdd..f62d2d9fd 100644 --- a/.github/workflows/aead.yml +++ b/.github/workflows/aead.yml @@ -37,6 +37,7 @@ jobs: override: true - run: cargo build --target ${{ matrix.target }} --release --no-default-features - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features rand_core - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features stream test: diff --git a/.github/workflows/cipher.yml b/.github/workflows/cipher.yml index aaa7ad29b..2a4b449d3 100644 --- a/.github/workflows/cipher.yml +++ b/.github/workflows/cipher.yml @@ -35,7 +35,9 @@ jobs: toolchain: ${{ matrix.rust }} target: ${{ matrix.target }} override: true - - run: cargo build --no-default-features --release --target ${{ matrix.target }} + - run: cargo build --target ${{ matrix.target }} --release --no-default-features + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features rand_core + test: runs-on: ubuntu-latest strategy: diff --git a/.github/workflows/crypto-mac.yml b/.github/workflows/crypto-mac.yml index 5e4ade5dd..5336c0319 100644 --- a/.github/workflows/crypto-mac.yml +++ b/.github/workflows/crypto-mac.yml @@ -35,7 +35,9 @@ jobs: toolchain: ${{ matrix.rust }} target: ${{ matrix.target }} override: true - - run: cargo build --no-default-features --release --target ${{ matrix.target }} + - run: cargo build --target ${{ matrix.target }} --release --no-default-features + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features rand_core + test: runs-on: ubuntu-latest strategy: diff --git a/Cargo.lock b/Cargo.lock index 964d2b23d..f869e7896 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7,6 +7,7 @@ dependencies = [ "blobby", "generic-array 0.14.4", "heapless", + "rand_core", ] [[package]] @@ -110,6 +111,7 @@ version = "0.3.0-pre.4" dependencies = [ "blobby", "generic-array 0.14.4", + "rand_core", ] [[package]] @@ -145,6 +147,7 @@ dependencies = [ "blobby", "cipher", "generic-array 0.14.4", + "rand_core", "subtle", ] diff --git a/aead/Cargo.toml b/aead/Cargo.toml index 8883f592a..3f5aef454 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -16,8 +16,10 @@ categories = ["cryptography", "no-std"] [dependencies] generic-array = { version = "0.14", default-features = false } -heapless = { version = "0.5", optional = true } + blobby = { version = "0.3", optional = true } +heapless = { version = "0.5", optional = true } +rand_core = { version = "0.6", optional = true } [features] std = ["alloc"] diff --git a/aead/src/lib.rs b/aead/src/lib.rs index 5d4b5f750..1ad5007a0 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -42,6 +42,9 @@ pub use generic_array::{self, typenum::consts}; #[cfg(feature = "heapless")] pub use heapless; +#[cfg(feature = "rand_core")] +use rand_core::{CryptoRng, RngCore}; + use core::fmt; use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; @@ -95,6 +98,15 @@ pub trait NewAead { Ok(Self::new(GenericArray::from_slice(key))) } } + + /// Generate a random key for this AEAD using the provided [`CryptoRng`]. + #[cfg(feature = "rand_core")] + #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] + fn generate_key(mut rng: impl CryptoRng + RngCore) -> Key { + let mut key = Key::::default(); + rng.fill_bytes(&mut key); + key + } } /// Authenticated Encryption with Associated Data (AEAD) algorithm core trait. diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index ba9210b0f..b13ee47f4 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -13,7 +13,9 @@ categories = ["cryptography", "no-std"] [dependencies] generic-array = "0.14" + blobby = { version = "0.3", optional = true } +rand_core = { version = "0.6", optional = true } [features] std = [] diff --git a/cipher/src/block.rs b/cipher/src/block.rs index d38da8f5d..0e39ff90f 100644 --- a/cipher/src/block.rs +++ b/cipher/src/block.rs @@ -13,6 +13,9 @@ use crate::errors::InvalidLength; use core::convert::TryInto; use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; +#[cfg(feature = "rand_core")] +use rand_core::{CryptoRng, RngCore}; + /// Key for an algorithm that implements [`NewBlockCipher`]. pub type BlockCipherKey = GenericArray::KeySize>; @@ -41,6 +44,15 @@ pub trait NewBlockCipher: Sized { Ok(Self::new(GenericArray::from_slice(key))) } } + + /// Generate a random key for this block cipher using the provided [`CryptoRng`]. + #[cfg(feature = "rand_core")] + #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] + fn generate_key(mut rng: impl CryptoRng + RngCore) -> BlockCipherKey { + let mut key = BlockCipherKey::::default(); + rng.fill_bytes(&mut key); + key + } } /// Trait which marks a type as being a block cipher. diff --git a/cipher/src/common.rs b/cipher/src/common.rs index cd97524a6..849cd95be 100644 --- a/cipher/src/common.rs +++ b/cipher/src/common.rs @@ -1,6 +1,11 @@ +//! Functionality common to block ciphers and stream ciphers + use crate::{errors::InvalidLength, BlockCipher, NewBlockCipher}; use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; +#[cfg(feature = "rand_core")] +use rand_core::{CryptoRng, RngCore}; + /// Key for an algorithm that implements [`NewCipher`]. pub type CipherKey = GenericArray::KeySize>; @@ -34,6 +39,15 @@ pub trait NewCipher: Sized { Ok(Self::new(key, nonce)) } } + + /// Generate a random key for this cipher using the provided [`CryptoRng`]. + #[cfg(feature = "rand_core")] + #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] + fn generate_key(mut rng: impl CryptoRng + RngCore) -> CipherKey { + let mut key = CipherKey::::default(); + rng.fill_bytes(&mut key); + key + } } /// Trait for types which can be initialized from a block cipher and nonce. diff --git a/crypto-mac/Cargo.toml b/crypto-mac/Cargo.toml index 6c2ebefe6..12a2036aa 100644 --- a/crypto-mac/Cargo.toml +++ b/crypto-mac/Cargo.toml @@ -13,9 +13,11 @@ categories = ["cryptography", "no-std"] [dependencies] generic-array = "0.14" -cipher = { version = "=0.3.0-pre.4", optional = true, path = "../cipher" } subtle = { version = "2", default-features = false } + blobby = { version = "0.3", optional = true } +cipher = { version = "=0.3.0-pre.4", optional = true, path = "../cipher" } +rand_core = { version = "0.6", optional = true } [features] dev = ["blobby"] diff --git a/crypto-mac/src/lib.rs b/crypto-mac/src/lib.rs index 1f101f157..60e89112e 100644 --- a/crypto-mac/src/lib.rs +++ b/crypto-mac/src/lib.rs @@ -30,6 +30,9 @@ use generic_array::typenum::Unsigned; use generic_array::{ArrayLength, GenericArray}; use subtle::{Choice, ConstantTimeEq}; +#[cfg(feature = "rand_core")] +use rand_core::{CryptoRng, RngCore}; + /// Key for an algorithm that implements [`NewMac`]. pub type Key = GenericArray::KeySize>; @@ -52,6 +55,15 @@ pub trait NewMac: Sized { Ok(Self::new(GenericArray::from_slice(key))) } } + + /// Generate a random key for this MAC using the provided [`CryptoRng`]. + #[cfg(feature = "rand_core")] + #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] + fn generate_key(mut rng: impl CryptoRng + RngCore) -> Key { + let mut key = Key::::default(); + rng.fill_bytes(&mut key); + key + } } /// The [`Mac`] trait defines methods for a Message Authentication algorithm. From e29a8f56f681951435b9b03bf7ca1a569c846182 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 1 Feb 2021 05:13:55 -0800 Subject: [PATCH 0414/1461] password-hash: add encoding support to PasswordHash (#518) --- password-hash/src/lib.rs | 12 +++++++++++- password-hash/src/output.rs | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index 7e45d342e..034e43de7 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -249,6 +249,11 @@ pub struct PasswordHash<'a> { impl<'a> PasswordHash<'a> { /// Parse a password hash from a string in the PHC string format. pub fn new(s: &'a str) -> Result { + Self::parse(s, Encoding::B64) + } + + /// Parse a password hash from the given [`Encoding`]. + pub fn parse(s: &'a str, encoding: Encoding) -> Result { if s.is_empty() { return Err(ParseError::Empty.into()); } @@ -301,7 +306,7 @@ impl<'a> PasswordHash<'a> { } if let Some(field) = fields.next() { - hash = Some(field.parse()?); + hash = Some(Output::decode(field, encoding)?); } if fields.next().is_some() { @@ -341,6 +346,11 @@ impl<'a> PasswordHash<'a> { Err(VerifyError) } + + /// Get the [`Encoding`] that this [`PasswordHash`] is serialized with. + pub fn encoding(&self) -> Encoding { + self.hash.map(|h| h.encoding()).unwrap_or_default() + } } // Note: this uses `TryFrom` instead of `FromStr` to support a lifetime on diff --git a/password-hash/src/output.rs b/password-hash/src/output.rs index c61a7a69f..cd2698721 100644 --- a/password-hash/src/output.rs +++ b/password-hash/src/output.rs @@ -143,7 +143,7 @@ impl Output { &self.bytes[..self.len()] } - /// Get the encoding that this [`Output`] will be serialized with. + /// Get the [`Encoding`] that this [`Output`] is serialized with. pub fn encoding(&self) -> Encoding { self.encoding } From 80e5eb578bf5b500deb25b818a0e7ac5430d8a94 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 1 Feb 2021 08:47:54 -0800 Subject: [PATCH 0415/1461] Bump `base64ct` dependency to v0.2 (#519) --- Cargo.lock | 12 +- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/jwk.rs | 10 +- password-hash/Cargo.toml | 2 +- password-hash/src/encoding.rs | 20 ++-- password-hash/src/lib.rs | 2 - password-hash/src/output.rs | 6 +- password-hash/src/salt.rs | 8 +- password-hash/src/value.rs | 7 +- password-hash/tests/b64.rs | 54 --------- password-hash/tests/encoding.rs | 163 +++++---------------------- password-hash/tests/password_hash.rs | 147 ++++++++++++++++++++++++ 12 files changed, 207 insertions(+), 226 deletions(-) delete mode 100644 password-hash/tests/b64.rs create mode 100644 password-hash/tests/password_hash.rs diff --git a/Cargo.lock b/Cargo.lock index f869e7896..ad0fe1b75 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -47,6 +47,12 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b245b005bb8924f38647aeb31388984784a139acbe7ac6d7435fb0a11c4c83d8" +[[package]] +name = "base64ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22fb38fd6e62e4ceec8543db40ceb714454ff173451a0f2a6c8952fdf39a2d6c" + [[package]] name = "bitvec" version = "0.20.1" @@ -182,7 +188,7 @@ dependencies = [ name = "elliptic-curve" version = "0.9.0-pre" dependencies = [ - "base64ct", + "base64ct 0.2.0", "digest 0.9.0", "ff", "generic-array 0.14.4", @@ -314,7 +320,7 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" name = "password-hash" version = "0.1.0" dependencies = [ - "base64ct", + "base64ct 0.2.0", "rand_core", ] @@ -324,7 +330,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8f486f758a686804c80ab239829095260ecbe46e5226e00c0b1339e76a9babc" dependencies = [ - "base64ct", + "base64ct 0.1.2", "der", "zeroize", ] diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 3551ea60f..2333ff981 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -15,7 +15,7 @@ categories = ["cryptography", "no-std"] keywords = ["crypto", "ecc", "elliptic", "weierstrass"] [dependencies] -base64ct = { version = "0.1", optional = true, default-features = false } +base64ct = { version = "0.2", optional = true, default-features = false } digest = { version = "0.9", optional = true } ff = { version = "0.9", optional = true, default-features = false } group = { version = "0.9", optional = true, default-features = false } diff --git a/elliptic-curve/src/jwk.rs b/elliptic-curve/src/jwk.rs index 73ad6049c..0a147e5c6 100644 --- a/elliptic-curve/src/jwk.rs +++ b/elliptic-curve/src/jwk.rs @@ -16,7 +16,7 @@ use alloc::{ format, string::{String, ToString}, }; -use base64ct::url::unpadded as base64url; +use base64ct::{Base64UrlUnpadded as Base64Url, Encoding}; use core::{ convert::{TryFrom, TryInto}, fmt::{self, Debug}, @@ -212,8 +212,8 @@ where match point.coordinates() { Coordinates::Uncompressed { x, y } => Ok(JwkEcKey { crv: C::CRV.to_owned(), - x: base64url::encode_string(x), - y: base64url::encode_string(y), + x: Base64Url::encode_string(x), + y: Base64Url::encode_string(y), d: None, }), _ => Err(Error), @@ -293,7 +293,7 @@ where fn from(sk: &SecretKey) -> JwkEcKey { let mut jwk = sk.public_key().to_jwk(); let mut d = sk.to_bytes(); - jwk.d = Some(base64url::encode_string(&d)); + jwk.d = Some(Base64Url::encode_string(&d)); d.zeroize(); jwk } @@ -636,7 +636,7 @@ impl Serialize for JwkEcKey { /// Decode a Base64url-encoded field element fn decode_base64url_fe(s: &str) -> Result, Error> { let mut result = FieldBytes::::default(); - base64url::decode(s, &mut result).map_err(|_| Error)?; + Base64Url::decode(s, &mut result).map_err(|_| Error)?; Ok(result) } diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index a3e996d32..fcacd5a6a 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -16,7 +16,7 @@ categories = ["cryptography", "no-std"] keywords = ["crypt", "mcf", "password", "pbkdf", "phc"] [dependencies] -base64ct = "0.1.2" +base64ct = "0.2" rand_core = { version = "0.6", optional = true, default-features = false } [features] diff --git a/password-hash/src/encoding.rs b/password-hash/src/encoding.rs index 009b733a0..56fa4643b 100644 --- a/password-hash/src/encoding.rs +++ b/password-hash/src/encoding.rs @@ -1,7 +1,7 @@ //! Base64 encoding variants. use crate::B64Error; -use base64ct as base64; +use base64ct::{Base64Bcrypt, Base64Crypt, Base64Unpadded as B64, Encoding as _}; /// Base64 encoding variants. #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] @@ -42,9 +42,9 @@ impl Encoding { /// Decode a Base64 string into the provided destination buffer. pub fn decode(self, src: impl AsRef<[u8]>, dst: &mut [u8]) -> Result<&[u8], B64Error> { match self { - Self::B64 => base64::unpadded::decode(src, dst), - Self::Bcrypt => base64::bcrypt::decode(src, dst), - Self::Crypt => base64::crypt::decode(src, dst), + Self::B64 => B64::decode(src, dst), + Self::Bcrypt => Base64Bcrypt::decode(src, dst), + Self::Crypt => Base64Crypt::decode(src, dst), } } @@ -54,9 +54,9 @@ impl Encoding { /// ASCII-encoded Base64 string value. pub fn encode<'a>(self, src: &[u8], dst: &'a mut [u8]) -> Result<&'a str, B64Error> { match self { - Self::B64 => base64::unpadded::encode(src, dst), - Self::Bcrypt => base64::bcrypt::encode(src, dst), - Self::Crypt => base64::crypt::encode(src, dst), + Self::B64 => B64::encode(src, dst), + Self::Bcrypt => Base64Bcrypt::encode(src, dst), + Self::Crypt => Base64Crypt::encode(src, dst), } .map_err(Into::into) } @@ -64,9 +64,9 @@ impl Encoding { /// Get the length of Base64 produced by encoding the given bytes. pub fn encoded_len(self, bytes: &[u8]) -> usize { match self { - Self::B64 => base64::unpadded::encoded_len(bytes), - Self::Bcrypt => base64::bcrypt::encoded_len(bytes), - Self::Crypt => base64::crypt::encoded_len(bytes), + Self::B64 => B64::encoded_len(bytes), + Self::Bcrypt => Base64Bcrypt::encoded_len(bytes), + Self::Crypt => Base64Crypt::encoded_len(bytes), } } } diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index 034e43de7..ec2a59843 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -68,8 +68,6 @@ pub use crate::{ value::{Decimal, Value}, }; -pub use base64ct::unpadded as b64; - use core::{ convert::{TryFrom, TryInto}, fmt::{self, Debug}, diff --git a/password-hash/src/output.rs b/password-hash/src/output.rs index cd2698721..f95e41bdb 100644 --- a/password-hash/src/output.rs +++ b/password-hash/src/output.rs @@ -1,6 +1,6 @@ //! Outputs from password hashing functions. -use crate::{b64, Encoding, OutputError}; +use crate::{Encoding, OutputError}; use core::{cmp::PartialEq, convert::TryFrom, fmt, str::FromStr}; /// Maximum length of password hash function outputs. @@ -164,7 +164,7 @@ impl Output { /// /// Returns an error if the buffer is too short to contain the output. pub fn b64_encode<'a>(&self, out: &'a mut [u8]) -> Result<&'a str, OutputError> { - Ok(b64::encode(self.as_ref(), out)?) + self.encode(out, Encoding::B64) } /// Decode the given input string using the specified [`Encoding`]. @@ -187,7 +187,7 @@ impl Output { /// Get the length of this [`Output`] when encoded as [`b64`]. pub fn b64_len(&self) -> usize { - b64::encoded_len(self.as_ref()) + Encoding::B64.encoded_len(self.as_ref()) } } diff --git a/password-hash/src/salt.rs b/password-hash/src/salt.rs index e397b076e..6dc7876e1 100644 --- a/password-hash/src/salt.rs +++ b/password-hash/src/salt.rs @@ -1,10 +1,6 @@ //! Salt string support. -use crate::{ - b64, - errors::{B64Error, ParseError}, - Value, -}; +use crate::{B64Error, Encoding, ParseError, Value}; use core::{ convert::{TryFrom, TryInto}, fmt, str, @@ -217,7 +213,7 @@ impl SaltString { /// Returns `None` if the slice is too long. pub fn b64_encode(input: &[u8]) -> Result { let mut bytes = [0u8; Salt::max_len()]; - let length = b64::encode(input, &mut bytes)?.len() as u8; + let length = Encoding::B64.encode(input, &mut bytes)?.len() as u8; Ok(Self { bytes, length }) } diff --git a/password-hash/src/value.rs b/password-hash/src/value.rs index b9d23451e..4e4e278a8 100644 --- a/password-hash/src/value.rs +++ b/password-hash/src/value.rs @@ -13,10 +13,7 @@ //! //! [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md -use crate::{ - b64, - errors::{B64Error, ParseError}, -}; +use crate::{B64Error, Encoding, ParseError}; use core::{convert::TryFrom, fmt, str}; /// Maximum size of a parameter value in ASCII characters. @@ -82,7 +79,7 @@ impl<'a> Value<'a> { /// /// [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#argon2-encoding pub fn b64_decode<'b>(&self, buf: &'b mut [u8]) -> Result<&'b [u8], B64Error> { - b64::decode(self.as_str(), buf) + Encoding::B64.decode(self.as_str(), buf) } /// Borrow this value as a `str`. diff --git a/password-hash/tests/b64.rs b/password-hash/tests/b64.rs deleted file mode 100644 index a93f2dbfd..000000000 --- a/password-hash/tests/b64.rs +++ /dev/null @@ -1,54 +0,0 @@ -//! "B64" encoding tests. -//! -//! Subset of the standard Base64 encoding (RFC 4648, section 4) which omits -//! padding (`=`) as well as extra whitespace, as described in the PHC string -//! format specification: -//! -//! - -use password_hash::{Output, Salt}; - -#[cfg(feature = "alloc")] -use password_hash::b64; - -// Example salt encoded as a B64 string. -const EXAMPLE_SALT_B64: &str = "REVBREJFRUZERUFEQkVFRg"; -const EXAMPLE_SALT_RAW: &[u8] = b"DEADBEEFDEADBEEF"; - -// Example PHF output encoded as a B64 string. -const EXAMPLE_OUTPUT_B64: &str = - "REVBREJFRUZERUFEQkVFRkRFQURCRUVGREVBREJFRUZERUFEQkVFRkRFQURCRUVGREVBREJFRUZERUFEQkVFRg"; -const EXAMPLE_OUTPUT_RAW: &[u8] = - b"DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF"; - -#[test] -fn salt_roundtrip() { - let mut buffer = [0u8; 64]; - let salt = Salt::new(EXAMPLE_SALT_B64).unwrap(); - assert_eq!(salt.as_ref(), EXAMPLE_SALT_B64); - - let salt_decoded = salt.b64_decode(&mut buffer).unwrap(); - assert_eq!(salt_decoded, EXAMPLE_SALT_RAW); -} - -#[test] -fn output_roundtrip() { - let out = EXAMPLE_OUTPUT_B64.parse::().unwrap(); - assert_eq!(out.as_ref(), EXAMPLE_OUTPUT_RAW); - assert_eq!(out.to_string(), EXAMPLE_OUTPUT_B64); -} - -#[cfg(feature = "alloc")] -#[test] -fn encode_string() { - assert_eq!(b64::encode_string(EXAMPLE_OUTPUT_RAW), EXAMPLE_OUTPUT_B64); -} - -#[cfg(feature = "alloc")] -#[test] -fn decode_vec() { - assert_eq!( - b64::decode_vec(EXAMPLE_OUTPUT_B64).unwrap(), - EXAMPLE_OUTPUT_RAW - ); -} diff --git a/password-hash/tests/encoding.rs b/password-hash/tests/encoding.rs index 107136063..faaa746d5 100644 --- a/password-hash/tests/encoding.rs +++ b/password-hash/tests/encoding.rs @@ -1,147 +1,38 @@ -//! Tests for `PasswordHash` encoding/decoding. +//! Base64 encoding tests. //! -//! Each test implements a different permutation of the possible combinations -//! of the string encoding, and ensures password hashes round trip under each -//! of the conditions. - -use core::convert::{TryFrom, TryInto}; -use password_hash::{Ident, ParamsString, PasswordHash, Salt}; - -const EXAMPLE_ALGORITHM: Ident = Ident::new("argon2d"); -const EXAMPLE_SALT: &str = "saltsaltsaltsaltsalt"; -const EXAMPLE_HASH: &[u8] = &[ - 0x85, 0xab, 0x21, 0x85, 0xab, 0x21, 0x85, 0xab, 0x21, 0x85, 0xab, 0x21, 0x85, 0xab, 0x21, 0x85, - 0xab, 0x21, 0x85, 0xab, 0x21, 0x85, 0xab, 0x21, 0x85, 0xab, 0x21, 0x85, 0xab, 0x21, 0x85, 0xab, -]; - -/// Example parameters -fn example_params() -> ParamsString { - let mut params = ParamsString::new(); - params.add_decimal("a", 1).unwrap(); - params.add_decimal("b", 2).unwrap(); - params.add_decimal("c", 3).unwrap(); - params -} - -#[test] -fn algorithm_alone() { - let ph = PasswordHash::new("$argon2d").unwrap(); - assert_eq!(ph.algorithm, EXAMPLE_ALGORITHM); - - let s = ph.to_string(); - assert_eq!(s, "$argon2d"); - - let ph2 = PasswordHash::try_from(s.as_str()).unwrap(); - assert_eq!(ph, ph2); -} - -#[test] -fn params() { - let ph = PasswordHash { - algorithm: EXAMPLE_ALGORITHM, - version: None, - params: example_params(), - salt: None, - hash: None, - }; - - let s = ph.to_string(); - assert_eq!(s, "$argon2d$a=1,b=2,c=3"); - - let ph2 = PasswordHash::try_from(s.as_str()).unwrap(); - assert_eq!(ph, ph2); -} - -#[test] -fn salt() { - let ph = PasswordHash { - algorithm: EXAMPLE_ALGORITHM, - version: None, - params: ParamsString::new(), - salt: Some(Salt::new(EXAMPLE_SALT).unwrap()), - hash: None, - }; - - let s = ph.to_string(); - assert_eq!(s, "$argon2d$saltsaltsaltsaltsalt"); - - let ph2 = PasswordHash::try_from(s.as_str()).unwrap(); - assert_eq!(ph, ph2); -} - -#[test] -fn one_param_and_salt() { - let mut params = ParamsString::new(); - params.add_decimal("a", 1).unwrap(); - - let ph = PasswordHash { - algorithm: EXAMPLE_ALGORITHM, - version: None, - params, - salt: Some(Salt::new(EXAMPLE_SALT).unwrap()), - hash: None, - }; - - let s = ph.to_string(); - assert_eq!(s, "$argon2d$a=1$saltsaltsaltsaltsalt"); - - let ph2 = PasswordHash::try_from(s.as_str()).unwrap(); - assert_eq!(ph, ph2); -} +//! # B64 Notes +//! +//! "B64" is a ubset of the standard Base64 encoding (RFC 4648, section 4) which +//! omits padding (`=`) as well as extra whitespace, as described in the PHC +//! string format specification: +//! +//! -#[test] -fn params_and_salt() { - let ph = PasswordHash { - algorithm: EXAMPLE_ALGORITHM, - version: None, - params: example_params(), - salt: Some(Salt::new(EXAMPLE_SALT).unwrap()), - hash: None, - }; +use password_hash::{Output, Salt}; - let s = ph.to_string(); - assert_eq!(s, "$argon2d$a=1,b=2,c=3$saltsaltsaltsaltsalt"); +// Example salt encoded as a B64 string. +const EXAMPLE_SALT_B64: &str = "REVBREJFRUZERUFEQkVFRg"; +const EXAMPLE_SALT_RAW: &[u8] = b"DEADBEEFDEADBEEF"; - let ph2 = PasswordHash::try_from(s.as_str()).unwrap(); - assert_eq!(ph, ph2); -} +// Example PHF output encoded as a B64 string. +const EXAMPLE_OUTPUT_B64: &str = + "REVBREJFRUZERUFEQkVFRkRFQURCRUVGREVBREJFRUZERUFEQkVFRkRFQURCRUVGREVBREJFRUZERUFEQkVFRg"; +const EXAMPLE_OUTPUT_RAW: &[u8] = + b"DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF"; #[test] -fn salt_and_hash() { - let ph = PasswordHash { - algorithm: EXAMPLE_ALGORITHM, - version: None, - params: ParamsString::default(), - salt: Some(Salt::new(EXAMPLE_SALT).unwrap()), - hash: Some(EXAMPLE_HASH.try_into().unwrap()), - }; - - let s = ph.to_string(); - assert_eq!( - s, - "$argon2d$saltsaltsaltsaltsalt$hashhashhashhashhashhashhashhashhashhashhas" - ); +fn salt_roundtrip() { + let mut buffer = [0u8; 64]; + let salt = Salt::new(EXAMPLE_SALT_B64).unwrap(); + assert_eq!(salt.as_ref(), EXAMPLE_SALT_B64); - let ph2 = PasswordHash::try_from(s.as_str()).unwrap(); - assert_eq!(ph, ph2); + let salt_decoded = salt.b64_decode(&mut buffer).unwrap(); + assert_eq!(salt_decoded, EXAMPLE_SALT_RAW); } #[test] -fn all_fields() { - let ph = PasswordHash { - algorithm: EXAMPLE_ALGORITHM, - version: None, - params: example_params(), - salt: Some(Salt::new(EXAMPLE_SALT).unwrap()), - hash: Some(EXAMPLE_HASH.try_into().unwrap()), - }; - - let s = ph.to_string(); - assert_eq!( - s, - "$argon2d$a=1,b=2,c=3$saltsaltsaltsaltsalt$hashhashhashhashhashhashhashhashhashhashhas" - ); - - let ph2 = PasswordHash::try_from(s.as_str()).unwrap(); - assert_eq!(ph, ph2); +fn output_roundtrip() { + let out = EXAMPLE_OUTPUT_B64.parse::().unwrap(); + assert_eq!(out.as_ref(), EXAMPLE_OUTPUT_RAW); + assert_eq!(out.to_string(), EXAMPLE_OUTPUT_B64); } diff --git a/password-hash/tests/password_hash.rs b/password-hash/tests/password_hash.rs new file mode 100644 index 000000000..107136063 --- /dev/null +++ b/password-hash/tests/password_hash.rs @@ -0,0 +1,147 @@ +//! Tests for `PasswordHash` encoding/decoding. +//! +//! Each test implements a different permutation of the possible combinations +//! of the string encoding, and ensures password hashes round trip under each +//! of the conditions. + +use core::convert::{TryFrom, TryInto}; +use password_hash::{Ident, ParamsString, PasswordHash, Salt}; + +const EXAMPLE_ALGORITHM: Ident = Ident::new("argon2d"); +const EXAMPLE_SALT: &str = "saltsaltsaltsaltsalt"; +const EXAMPLE_HASH: &[u8] = &[ + 0x85, 0xab, 0x21, 0x85, 0xab, 0x21, 0x85, 0xab, 0x21, 0x85, 0xab, 0x21, 0x85, 0xab, 0x21, 0x85, + 0xab, 0x21, 0x85, 0xab, 0x21, 0x85, 0xab, 0x21, 0x85, 0xab, 0x21, 0x85, 0xab, 0x21, 0x85, 0xab, +]; + +/// Example parameters +fn example_params() -> ParamsString { + let mut params = ParamsString::new(); + params.add_decimal("a", 1).unwrap(); + params.add_decimal("b", 2).unwrap(); + params.add_decimal("c", 3).unwrap(); + params +} + +#[test] +fn algorithm_alone() { + let ph = PasswordHash::new("$argon2d").unwrap(); + assert_eq!(ph.algorithm, EXAMPLE_ALGORITHM); + + let s = ph.to_string(); + assert_eq!(s, "$argon2d"); + + let ph2 = PasswordHash::try_from(s.as_str()).unwrap(); + assert_eq!(ph, ph2); +} + +#[test] +fn params() { + let ph = PasswordHash { + algorithm: EXAMPLE_ALGORITHM, + version: None, + params: example_params(), + salt: None, + hash: None, + }; + + let s = ph.to_string(); + assert_eq!(s, "$argon2d$a=1,b=2,c=3"); + + let ph2 = PasswordHash::try_from(s.as_str()).unwrap(); + assert_eq!(ph, ph2); +} + +#[test] +fn salt() { + let ph = PasswordHash { + algorithm: EXAMPLE_ALGORITHM, + version: None, + params: ParamsString::new(), + salt: Some(Salt::new(EXAMPLE_SALT).unwrap()), + hash: None, + }; + + let s = ph.to_string(); + assert_eq!(s, "$argon2d$saltsaltsaltsaltsalt"); + + let ph2 = PasswordHash::try_from(s.as_str()).unwrap(); + assert_eq!(ph, ph2); +} + +#[test] +fn one_param_and_salt() { + let mut params = ParamsString::new(); + params.add_decimal("a", 1).unwrap(); + + let ph = PasswordHash { + algorithm: EXAMPLE_ALGORITHM, + version: None, + params, + salt: Some(Salt::new(EXAMPLE_SALT).unwrap()), + hash: None, + }; + + let s = ph.to_string(); + assert_eq!(s, "$argon2d$a=1$saltsaltsaltsaltsalt"); + + let ph2 = PasswordHash::try_from(s.as_str()).unwrap(); + assert_eq!(ph, ph2); +} + +#[test] +fn params_and_salt() { + let ph = PasswordHash { + algorithm: EXAMPLE_ALGORITHM, + version: None, + params: example_params(), + salt: Some(Salt::new(EXAMPLE_SALT).unwrap()), + hash: None, + }; + + let s = ph.to_string(); + assert_eq!(s, "$argon2d$a=1,b=2,c=3$saltsaltsaltsaltsalt"); + + let ph2 = PasswordHash::try_from(s.as_str()).unwrap(); + assert_eq!(ph, ph2); +} + +#[test] +fn salt_and_hash() { + let ph = PasswordHash { + algorithm: EXAMPLE_ALGORITHM, + version: None, + params: ParamsString::default(), + salt: Some(Salt::new(EXAMPLE_SALT).unwrap()), + hash: Some(EXAMPLE_HASH.try_into().unwrap()), + }; + + let s = ph.to_string(); + assert_eq!( + s, + "$argon2d$saltsaltsaltsaltsalt$hashhashhashhashhashhashhashhashhashhashhas" + ); + + let ph2 = PasswordHash::try_from(s.as_str()).unwrap(); + assert_eq!(ph, ph2); +} + +#[test] +fn all_fields() { + let ph = PasswordHash { + algorithm: EXAMPLE_ALGORITHM, + version: None, + params: example_params(), + salt: Some(Salt::new(EXAMPLE_SALT).unwrap()), + hash: Some(EXAMPLE_HASH.try_into().unwrap()), + }; + + let s = ph.to_string(); + assert_eq!( + s, + "$argon2d$a=1,b=2,c=3$saltsaltsaltsaltsalt$hashhashhashhashhashhashhashhashhashhashhas" + ); + + let ph2 = PasswordHash::try_from(s.as_str()).unwrap(); + assert_eq!(ph, ph2); +} From 130e8c431f21a43a1de36fbace59f978705ef4a4 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 1 Feb 2021 09:02:55 -0800 Subject: [PATCH 0416/1461] password-hash v0.1.1 (#520) --- Cargo.lock | 2 +- password-hash/CHANGELOG.md | 12 ++++++++++++ password-hash/Cargo.toml | 2 +- password-hash/src/lib.rs | 2 +- 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ad0fe1b75..5fafd289a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -318,7 +318,7 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "password-hash" -version = "0.1.0" +version = "0.1.1" dependencies = [ "base64ct 0.2.0", "rand_core", diff --git a/password-hash/CHANGELOG.md b/password-hash/CHANGELOG.md index fe87f902b..1ece8840a 100644 --- a/password-hash/CHANGELOG.md +++ b/password-hash/CHANGELOG.md @@ -5,5 +5,17 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.1.1 (2021-02-01) +### Added +- `Encoding` enum with bcrypt and `crypt(3)` Base64 support ([#515]) +- Support for using `PasswordHash` with an alternate `Encoding` ([#518]) + +### Changed +- Bump `base64ct` dependency to v0.2 ([#519]) + +[#515]: https://github.com/RustCrypto/traits/pull/515 +[#518]: https://github.com/RustCrypto/traits/pull/518 +[#519]: https://github.com/RustCrypto/traits/pull/519 + ## 0.1.0 (2021-01-28) - Initial release diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index fcacd5a6a..cc506a68a 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -5,7 +5,7 @@ Traits which describe the functionality of password hashing algorithms, as well as a `no_std`-friendly implementation of the PHC string format (a well-defined subset of the Modular Crypt Format a.k.a. MCF) """ -version = "0.1.0" +version = "0.1.1" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index ec2a59843..5a02c86da 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -39,7 +39,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_root_url = "https://docs.rs/password-hash/0.1.0" + html_root_url = "https://docs.rs/password-hash/0.1.1" )] #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] From f01c46e9f7316d176d5c9c5358244790bca3ed6e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Feb 2021 05:52:13 -0800 Subject: [PATCH 0417/1461] build(deps): bump pkcs8 from 0.4.0 to 0.4.1 (#521) Bumps [pkcs8](https://github.com/RustCrypto/utils) from 0.4.0 to 0.4.1. - [Release notes](https://github.com/RustCrypto/utils/releases) - [Commits](https://github.com/RustCrypto/utils/compare/pkcs8-v0.4.0...pkcs8-v0.4.1) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5fafd289a..8e58f63a7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -41,12 +41,6 @@ dependencies = [ "syn", ] -[[package]] -name = "base64ct" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b245b005bb8924f38647aeb31388984784a139acbe7ac6d7435fb0a11c4c83d8" - [[package]] name = "base64ct" version = "0.2.0" @@ -188,7 +182,7 @@ dependencies = [ name = "elliptic-curve" version = "0.9.0-pre" dependencies = [ - "base64ct 0.2.0", + "base64ct", "digest 0.9.0", "ff", "generic-array 0.14.4", @@ -320,17 +314,17 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" name = "password-hash" version = "0.1.1" dependencies = [ - "base64ct 0.2.0", + "base64ct", "rand_core", ] [[package]] name = "pkcs8" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8f486f758a686804c80ab239829095260ecbe46e5226e00c0b1339e76a9babc" +checksum = "5cf818666b471f4219a11aaca36c612697807b216b91149ed4b799bf1a5b0fd0" dependencies = [ - "base64ct 0.1.2", + "base64ct", "der", "zeroize", ] From 9d47d3a099b5f7a8027dcd5d00744117057d5701 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 3 Feb 2021 06:00:29 -0800 Subject: [PATCH 0418/1461] aead: bump `heapless` dependency to v0.6 (#522) --- Cargo.lock | 6 +++--- aead/Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8e58f63a7..6a03dd39d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -263,12 +263,12 @@ dependencies = [ [[package]] name = "heapless" -version = "0.5.6" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74911a68a1658cfcfb61bc0ccfbd536e3b6e906f8c2f7883ee50157e3e2184f1" +checksum = "efb22866f8416bc2b65389ebcb8b48e1be541650c44063ea1288d04bcf903808" dependencies = [ "as-slice", - "generic-array 0.13.2", + "generic-array 0.14.4", "hash32", "stable_deref_trait", ] diff --git a/aead/Cargo.toml b/aead/Cargo.toml index 3f5aef454..c08efd58f 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -18,7 +18,7 @@ categories = ["cryptography", "no-std"] generic-array = { version = "0.14", default-features = false } blobby = { version = "0.3", optional = true } -heapless = { version = "0.5", optional = true } +heapless = { version = "0.6", optional = true, default-features = false } rand_core = { version = "0.6", optional = true } [features] From d5c853cbc3f84609217ef16636da0fcec4f10720 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 4 Feb 2021 10:01:06 -0800 Subject: [PATCH 0419/1461] .img: add diagram of Rogaway's STREAM construction (#524) For use in `aead` crate rustdoc --- .img/rogaway-stream.svg | 1 + 1 file changed, 1 insertion(+) create mode 100644 .img/rogaway-stream.svg diff --git a/.img/rogaway-stream.svg b/.img/rogaway-stream.svg new file mode 100644 index 000000000..ac695875d --- /dev/null +++ b/.img/rogaway-stream.svg @@ -0,0 +1 @@ +stream \ No newline at end of file From 53bd56bfc43d6f82a2c9a8b7618a3c0ff36e3ea4 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 4 Feb 2021 10:12:55 -0800 Subject: [PATCH 0420/1461] aead: add STREAM diagram to rustdoc (#525) --- aead/src/stream.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/aead/src/stream.rs b/aead/src/stream.rs index ae472b602..243e875c2 100644 --- a/aead/src/stream.rs +++ b/aead/src/stream.rs @@ -15,6 +15,19 @@ //! to meet the security definition of "nonce-based online authenticated //! encryption" (nOAE) as given in the aforementioned paper. //! +//! ## Diagram +//! +//! ![STREAM Diagram](https://raw.githubusercontent.com/RustCrypto/traits/d5c853c/.img/rogaway-stream.svg) +//! +//! Legend: +//! +//! - 𝐄k: AEAD encryption under key `k` +//! - 𝐌: message +//! - 𝐍: nonce +//! - 𝐀: additional associated data +//! - 𝐂: ciphertext +//! - 𝜏: MAC tag +//! //! [1]: https://eprint.iacr.org/2015/189.pdf use crate::{AeadCore, AeadInPlace, Buffer, Error, Key, NewAead}; From 72f01d88ec33b9aa959a59ae019371b0a5b0709f Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 5 Feb 2021 07:47:42 -0800 Subject: [PATCH 0421/1461] aead v0.4.0 (#526) --- Cargo.lock | 2 +- aead/CHANGELOG.md | 14 ++++++++++++-- aead/Cargo.toml | 2 +- aead/src/lib.rs | 2 +- crypto/Cargo.toml | 2 +- 5 files changed, 16 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6a03dd39d..e514ee17d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,7 +2,7 @@ # It is not intended for manual editing. [[package]] name = "aead" -version = "0.4.0-pre" +version = "0.4.0" dependencies = [ "blobby", "generic-array 0.14.4", diff --git a/aead/CHANGELOG.md b/aead/CHANGELOG.md index bc265665e..0480de39f 100644 --- a/aead/CHANGELOG.md +++ b/aead/CHANGELOG.md @@ -5,15 +5,25 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 0.4.0 (UNRELEASED) +## 0.4.0 ### Added -- `stream` module ([#436]) +- `stream` module ([#436], [#445], [#447]) +- `NewAead::generate_key` method gated under `rand_core` feature ([#513]) ### Changed - Extract `AeadCore` trait ([#508]) +- Rename `NewAead::new_var` to `::new_from_slice` ([#512]) +- Disable alloc by default ([#514]) +- Bump `heapless` dependency to v0.6 ([#522]) [#436]: https://github.com/RustCrypto/traits/pull/436 +[#445]: https://github.com/RustCrypto/traits/pull/445 +[#447]: https://github.com/RustCrypto/traits/pull/447 [#508]: https://github.com/RustCrypto/traits/pull/508 +[#512]: https://github.com/RustCrypto/traits/pull/512 +[#513]: https://github.com/RustCrypto/traits/pull/513 +[#514]: https://github.com/RustCrypto/traits/pull/514 +[#522]: https://github.com/RustCrypto/traits/pull/522 ## 0.3.2 (2020-07-01) ### Added diff --git a/aead/Cargo.toml b/aead/Cargo.toml index c08efd58f..763141d97 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aead" -version = "0.4.0-pre" # Also update html_root_url in lib.rs when bumping this +version = "0.4.0" # Also update html_root_url in lib.rs when bumping this description = """ Traits for Authenticated Encryption with Associated Data (AEAD) algorithms, such as AES-GCM as ChaCha20Poly1305, which provide a high-level API diff --git a/aead/src/lib.rs b/aead/src/lib.rs index 1ad5007a0..cb31947b4 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -19,7 +19,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_root_url = "https://docs.rs/aead/0.4.0-pre" + html_root_url = "https://docs.rs/aead/0.4.0" )] #![warn(missing_docs, rust_2018_idioms)] diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index cfdff251c..ff4811a73 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -12,7 +12,7 @@ readme = "README.md" edition = "2018" [dependencies] -aead = { version = "=0.4.0-pre", optional = true, path = "../aead" } +aead = { version = "0.4", optional = true, path = "../aead" } cipher = { version = "=0.3.0-pre.4", optional = true, path = "../cipher" } digest = { version = "0.10.0-pre", optional = true, path = "../digest" } elliptic-curve = { version = "=0.9.0-pre", optional = true, path = "../elliptic-curve" } From ca44e25534cfacf95905b708080a7952edc8a811 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 5 Feb 2021 14:32:08 -0800 Subject: [PATCH 0422/1461] cipher: fix error message for InvalidLength (#527) --- cipher/src/errors.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cipher/src/errors.rs b/cipher/src/errors.rs index f52736517..69235fceb 100644 --- a/cipher/src/errors.rs +++ b/cipher/src/errors.rs @@ -22,7 +22,7 @@ pub struct InvalidLength; impl fmt::Display for InvalidLength { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - f.write_str("Loop Error") + f.write_str("Invalid Length") } } From 30575f98d390b8e0f9c3befa6e816e4b6e45aafb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Feb 2021 06:03:41 +0000 Subject: [PATCH 0423/1461] build(deps): bump serde_json from 1.0.61 to 1.0.62 (#530) --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e514ee17d..31bb35504 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -379,9 +379,9 @@ checksum = "92d5161132722baa40d802cc70b15262b98258453e85e5d1d365c757c73869ae" [[package]] name = "serde_json" -version = "1.0.61" +version = "1.0.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fceb2595057b6891a4ee808f70054bd2d12f0e97f1cbb78689b59f676df325a" +checksum = "ea1c6153794552ea7cf7cf63b1231a25de00ec90db326ba6264440fa08e31486" dependencies = [ "itoa", "ryu", From 5acb9f77e6fc6295ac09e9bcf2c3a1371ce69c29 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Tue, 9 Feb 2021 10:22:35 +0000 Subject: [PATCH 0424/1461] digest: variable output traits (#502) --- digest/src/core_api.rs | 173 +++++++---------------------- digest/src/core_api/ct_variable.rs | 81 ++++++++++++++ digest/src/core_api/rt_variable.rs | 112 +++++++++++++++++++ digest/src/core_api/update.rs | 96 ++++++++++++++++ digest/src/core_api/xof_reader.rs | 38 +++++++ digest/src/digest.rs | 49 +++----- digest/src/lib.rs | 149 +++++++++++++++++++------ 7 files changed, 498 insertions(+), 200 deletions(-) create mode 100644 digest/src/core_api/ct_variable.rs create mode 100644 digest/src/core_api/rt_variable.rs create mode 100644 digest/src/core_api/update.rs create mode 100644 digest/src/core_api/xof_reader.rs diff --git a/digest/src/core_api.rs b/digest/src/core_api.rs index a26b006fc..e08a131a5 100644 --- a/digest/src/core_api.rs +++ b/digest/src/core_api.rs @@ -1,13 +1,21 @@ -use crate::{ExtendableOutput, FixedOutput, Reset, Update, XofReader}; -use block_buffer::BlockBuffer; +//! Low-level core API traits. +//! +//! Usage of traits in this module in user code is discouraged. Instead use +//! core algorithm wrapped by the wrapper types, which implement the +//! higher-level traits. +use crate::InvalidOutputSize; use core::fmt; use generic_array::{ArrayLength, GenericArray}; -/// Trait which stores algorithm name constant, used in `Debug` implementations. -pub trait AlgorithmName { - /// Algorithm name. - const NAME: &'static str; -} +mod ct_variable; +mod rt_variable; +mod update; +mod xof_reader; + +pub use ct_variable::CtVariableCoreWrapper; +pub use rt_variable::RtVariableCoreWrapper; +pub use update::UpdateCoreWrapper; +pub use xof_reader::XofReaderCoreWrapper; /// Trait for updating hasher state with input data divided into blocks. pub trait UpdateCore { @@ -18,12 +26,7 @@ pub trait UpdateCore { fn update_blocks(&mut self, blocks: &[GenericArray]); } -/// Trait for fixed-output digest implementations to use to retrieve the -/// hash output. -/// -/// Usage of this trait in user code is discouraged. Instead use core algorithm -/// wrapped by [`BlockBufferWrapper`], which implements the [`FixedOutput`] -/// trait. +/// Core trait for hash functions with fixed output size. pub trait FixedOutputCore: UpdateCore { /// Digest output size in bytes. type OutputSize: ArrayLength; @@ -37,12 +40,7 @@ pub trait FixedOutputCore: UpdateCore { ); } -/// Trait for extendable-output function (XOF) core implementations to use to -/// retrieve the hash output. -/// -/// Usage of this trait in user code is discouraged. Instead use core algorithm -/// wrapped by [`BlockBufferWrapper`], which implements the -/// [`ExtendableOutput`] trait. +/// Core trait for hash functions with extendable (XOF) output size. pub trait ExtendableOutputCore: UpdateCore { /// XOF reader core state. type ReaderCore: XofReaderCore; @@ -64,123 +62,30 @@ pub trait XofReaderCore { fn read_block(&mut self) -> GenericArray; } -/// Wrapper around [`UpdateCore`] implementations. -/// -/// It handles data buffering and implements the mid-level traits. -#[derive(Clone, Default)] -pub struct UpdateCoreWrapper { - core: T, - buffer: BlockBuffer, -} - -/// Wrapper around [`XofReaderCore`] implementations. -/// -/// It handles data buffering and implements the mid-level traits. -#[derive(Clone, Default)] -pub struct XofReaderCoreWrapper { - core: T, - buffer: BlockBuffer, -} - -impl fmt::Debug for UpdateCoreWrapper { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - f.write_str(T::NAME)?; - f.write_str(" { .. }") - } -} - -impl fmt::Debug for XofReaderCoreWrapper { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - f.write_str(T::NAME)?; - f.write_str(" { .. }") - } -} - -impl Reset for UpdateCoreWrapper { - #[inline] - fn reset(&mut self) { - self.core = Default::default(); - self.buffer.reset(); - } -} - -impl Update for UpdateCoreWrapper { - #[inline] - fn update(&mut self, input: &[u8]) { - let Self { core, buffer } = self; - buffer.digest_blocks(input, |blocks| core.update_blocks(blocks)); - } -} - -impl FixedOutput for UpdateCoreWrapper { - type OutputSize = D::OutputSize; - - #[inline] - fn finalize_into(mut self, out: &mut GenericArray) { - let Self { core, buffer } = &mut self; - core.finalize_fixed_core(buffer, out); - } - - #[inline] - fn finalize_into_reset(&mut self, out: &mut GenericArray) { - let Self { core, buffer } = self; - core.finalize_fixed_core(buffer, out); - self.reset(); - } -} - -impl XofReader for XofReaderCoreWrapper { - #[inline] - fn read(&mut self, buffer: &mut [u8]) { - let Self { core, buffer: buf } = self; - buf.set_data(buffer, || core.read_block()); - } -} - -impl ExtendableOutput for UpdateCoreWrapper { - type Reader = XofReaderCoreWrapper; +/// Core trait for hash functions with variable output size. +pub trait VariableOutputCore: UpdateCore + Sized { + /// Maximum output size. + type MaxOutputSize: ArrayLength; - #[inline] - fn finalize_xof(mut self) -> Self::Reader { - let Self { core, buffer } = &mut self; - let reader_core = core.finalize_xof_core(buffer); - XofReaderCoreWrapper { - core: reader_core, - buffer: Default::default(), - } - } + /// Initialize hasher state for given output size. + /// + /// Returns [`InvalidOutputSize`] if `output_size` is equal to zero or + /// bigger than `Self::MaxOutputSize`. + fn new(output_size: usize) -> Result; - #[inline] - fn finalize_xof_reset(&mut self) -> Self::Reader { - let Self { core, buffer } = self; - let reader_core = core.finalize_xof_core(buffer); - self.reset(); - XofReaderCoreWrapper { - core: reader_core, - buffer: Default::default(), - } - } -} - -#[cfg(feature = "std")] -impl std::io::Write for UpdateCoreWrapper { - #[inline] - fn write(&mut self, buf: &[u8]) -> std::io::Result { - Update::update(self, buf); - Ok(buf.len()) - } - - #[inline] - fn flush(&mut self) -> std::io::Result<()> { - Ok(()) - } + /// Finalize hasher and return result of lenght `output_size` via closure `f`. + /// + /// `output_size` must be equal to `output_size` used during construction. + fn finalize_variable_core( + &mut self, + buffer: &mut block_buffer::BlockBuffer, + output_size: usize, + f: impl FnOnce(&[u8]), + ); } -#[cfg(feature = "std")] -impl std::io::Read for XofReaderCoreWrapper { - #[inline] - fn read(&mut self, buf: &mut [u8]) -> std::io::Result { - XofReader::read(self, buf); - Ok(buf.len()) - } +/// Trait which stores algorithm name constant, used in `Debug` implementations. +pub trait AlgorithmName { + /// Write algorithm name into `f`. + fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result; } diff --git a/digest/src/core_api/ct_variable.rs b/digest/src/core_api/ct_variable.rs new file mode 100644 index 000000000..e4e154bfa --- /dev/null +++ b/digest/src/core_api/ct_variable.rs @@ -0,0 +1,81 @@ +use super::{AlgorithmName, FixedOutputCore, UpdateCore, VariableOutputCore}; +use block_buffer::BlockBuffer; +use core::{fmt, marker::PhantomData}; +use generic_array::{ + typenum::{IsLessOrEqual, LeEq, NonZero}, + ArrayLength, GenericArray, +}; + +/// Wrapper around [`VariableOutputCore`] which selects output size +/// at compile time. +#[derive(Clone)] +pub struct CtVariableCoreWrapper +where + T: VariableOutputCore, + OutSize: ArrayLength + IsLessOrEqual, + LeEq: NonZero, +{ + inner: T, + _out: PhantomData, +} + +impl UpdateCore for CtVariableCoreWrapper +where + T: VariableOutputCore, + OutSize: ArrayLength + IsLessOrEqual, + LeEq: NonZero, +{ + type BlockSize = T::BlockSize; + + #[inline] + fn update_blocks(&mut self, blocks: &[GenericArray]) { + self.inner.update_blocks(blocks); + } +} + +impl FixedOutputCore for CtVariableCoreWrapper +where + T: VariableOutputCore, + OutSize: ArrayLength + IsLessOrEqual, + LeEq: NonZero, +{ + type OutputSize = OutSize; + + #[inline] + fn finalize_fixed_core( + &mut self, + buffer: &mut BlockBuffer, + out: &mut GenericArray, + ) { + self.inner + .finalize_variable_core(buffer, out.len(), |r| out.copy_from_slice(r)); + } +} + +impl Default for CtVariableCoreWrapper +where + T: VariableOutputCore, + OutSize: ArrayLength + IsLessOrEqual, + LeEq: NonZero, +{ + #[inline] + fn default() -> Self { + Self { + inner: T::new(OutSize::USIZE).unwrap(), + _out: Default::default(), + } + } +} + +impl AlgorithmName for CtVariableCoreWrapper +where + T: VariableOutputCore + AlgorithmName, + OutSize: ArrayLength + IsLessOrEqual, + LeEq: NonZero, +{ + fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { + T::write_alg_name(f)?; + f.write_str("_")?; + write!(f, "{}", OutSize::USIZE) + } +} diff --git a/digest/src/core_api/rt_variable.rs b/digest/src/core_api/rt_variable.rs new file mode 100644 index 000000000..5e7ceb3e0 --- /dev/null +++ b/digest/src/core_api/rt_variable.rs @@ -0,0 +1,112 @@ +use super::{AlgorithmName, UpdateCore, VariableOutputCore}; +use crate::{InvalidOutputSize, Reset, Update, VariableOutput}; +use block_buffer::BlockBuffer; +use core::fmt; +use generic_array::typenum::Unsigned; + +/// Wrapper around [`VariableOutputCore`] which selects output size +/// at run time. +#[derive(Clone)] +pub struct RtVariableCoreWrapper +where + T: VariableOutputCore + UpdateCore, +{ + core: T, + buffer: BlockBuffer, + output_size: usize, +} + +impl Reset for RtVariableCoreWrapper +where + T: VariableOutputCore + UpdateCore, +{ + #[inline] + fn reset(&mut self) { + // For correct implementations `new` should always return `Ok` + // since wrapper can be only created with valid `output_size` + if let Ok(v) = T::new(self.output_size) { + self.core = v; + } else { + debug_assert!(false); + } + self.buffer.reset(); + } +} + +impl Update for RtVariableCoreWrapper +where + T: VariableOutputCore + UpdateCore, +{ + #[inline] + fn update(&mut self, input: &[u8]) { + let Self { core, buffer, .. } = self; + buffer.digest_blocks(input, |blocks| core.update_blocks(blocks)); + } +} + +impl VariableOutput for RtVariableCoreWrapper +where + T: VariableOutputCore + UpdateCore, +{ + const MAX_OUTPUT_SIZE: usize = T::MaxOutputSize::USIZE; + + fn new(output_size: usize) -> Result { + let buffer = Default::default(); + T::new(output_size).map(|core| Self { + core, + buffer, + output_size, + }) + } + + fn output_size(&self) -> usize { + self.output_size + } + + fn finalize_variable(mut self, f: impl FnOnce(&[u8])) { + let Self { + core, + buffer, + output_size, + } = &mut self; + core.finalize_variable_core(buffer, *output_size, f); + } + + fn finalize_variable_reset(&mut self, f: impl FnOnce(&[u8])) { + let Self { + core, + buffer, + output_size, + } = self; + core.finalize_variable_core(buffer, *output_size, f); + self.reset() + } +} + +impl fmt::Debug for RtVariableCoreWrapper +where + T: VariableOutputCore + UpdateCore + AlgorithmName, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + T::write_alg_name(f)?; + f.write_str(" { .. }") + } +} + +#[cfg(feature = "std")] +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] +impl std::io::Write for RtVariableCoreWrapper +where + T: VariableOutputCore + UpdateCore, +{ + #[inline] + fn write(&mut self, buf: &[u8]) -> std::io::Result { + Update::update(self, buf); + Ok(buf.len()) + } + + #[inline] + fn flush(&mut self) -> std::io::Result<()> { + Ok(()) + } +} diff --git a/digest/src/core_api/update.rs b/digest/src/core_api/update.rs new file mode 100644 index 000000000..67a8ffc49 --- /dev/null +++ b/digest/src/core_api/update.rs @@ -0,0 +1,96 @@ +use super::{ + AlgorithmName, ExtendableOutputCore, FixedOutputCore, UpdateCore, XofReaderCoreWrapper, +}; +use crate::{ExtendableOutput, FixedOutput, Reset, Update}; +use block_buffer::BlockBuffer; +use core::fmt; +use generic_array::GenericArray; + +/// Wrapper around [`UpdateCore`] implementations. +/// +/// It handles data buffering and implements the mid-level traits. +#[derive(Clone, Default)] +pub struct UpdateCoreWrapper { + core: T, + buffer: BlockBuffer, +} + +impl fmt::Debug for UpdateCoreWrapper { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + T::write_alg_name(f)?; + f.write_str(" { .. }") + } +} + +impl Reset for UpdateCoreWrapper { + #[inline] + fn reset(&mut self) { + self.core = Default::default(); + self.buffer.reset(); + } +} + +impl Update for UpdateCoreWrapper { + #[inline] + fn update(&mut self, input: &[u8]) { + let Self { core, buffer } = self; + buffer.digest_blocks(input, |blocks| core.update_blocks(blocks)); + } +} + +impl FixedOutput for UpdateCoreWrapper { + type OutputSize = D::OutputSize; + + #[inline] + fn finalize_into(mut self, out: &mut GenericArray) { + let Self { core, buffer } = &mut self; + core.finalize_fixed_core(buffer, out); + } + + #[inline] + fn finalize_into_reset(&mut self, out: &mut GenericArray) { + let Self { core, buffer } = self; + core.finalize_fixed_core(buffer, out); + self.reset(); + } +} + +impl ExtendableOutput for UpdateCoreWrapper { + type Reader = XofReaderCoreWrapper; + + #[inline] + fn finalize_xof(mut self) -> Self::Reader { + let Self { core, buffer } = &mut self; + let reader_core = core.finalize_xof_core(buffer); + XofReaderCoreWrapper { + core: reader_core, + buffer: Default::default(), + } + } + + #[inline] + fn finalize_xof_reset(&mut self) -> Self::Reader { + let Self { core, buffer } = self; + let reader_core = core.finalize_xof_core(buffer); + self.reset(); + XofReaderCoreWrapper { + core: reader_core, + buffer: Default::default(), + } + } +} + +#[cfg(feature = "std")] +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] +impl std::io::Write for UpdateCoreWrapper { + #[inline] + fn write(&mut self, buf: &[u8]) -> std::io::Result { + Update::update(self, buf); + Ok(buf.len()) + } + + #[inline] + fn flush(&mut self) -> std::io::Result<()> { + Ok(()) + } +} diff --git a/digest/src/core_api/xof_reader.rs b/digest/src/core_api/xof_reader.rs new file mode 100644 index 000000000..2942e0627 --- /dev/null +++ b/digest/src/core_api/xof_reader.rs @@ -0,0 +1,38 @@ +use super::{AlgorithmName, XofReaderCore}; +use crate::XofReader; +use block_buffer::BlockBuffer; +use core::fmt; + +/// Wrapper around [`XofReaderCore`] implementations. +/// +/// It handles data buffering and implements the mid-level traits. +#[derive(Clone, Default)] +pub struct XofReaderCoreWrapper { + pub(super) core: T, + pub(super) buffer: BlockBuffer, +} + +impl fmt::Debug for XofReaderCoreWrapper { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + T::write_alg_name(f)?; + f.write_str(" { .. }") + } +} + +impl XofReader for XofReaderCoreWrapper { + #[inline] + fn read(&mut self, buffer: &mut [u8]) { + let Self { core, buffer: buf } = self; + buf.set_data(buffer, || core.read_block()); + } +} + +#[cfg(feature = "std")] +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] +impl std::io::Read for XofReaderCoreWrapper { + #[inline] + fn read(&mut self, buf: &mut [u8]) -> std::io::Result { + XofReader::read(self, buf); + Ok(buf.len()) + } +} diff --git a/digest/src/digest.rs b/digest/src/digest.rs index 674a4e636..5af6958c8 100644 --- a/digest/src/digest.rs +++ b/digest/src/digest.rs @@ -13,30 +13,23 @@ pub trait Digest { /// Create new hasher instance fn new() -> Self; - /// Digest data, updating the internal state. - /// - /// This method can be called repeatedly for use with streaming messages. + /// Process data, updating the internal state. fn update(&mut self, data: impl AsRef<[u8]>); - /// Digest input data in a chained manner. - fn chain(self, data: impl AsRef<[u8]>) -> Self - where - Self: Sized; + /// Process input data in a chained manner. + fn chain_update(self, data: impl AsRef<[u8]>) -> Self; /// Retrieve result and consume hasher instance. fn finalize(self) -> Output; /// Retrieve result and reset hasher instance. - /// - /// This method sometimes can be more efficient compared to hasher - /// re-creation. fn finalize_reset(&mut self) -> Output; /// Write result into provided array and consume the hasher instance. - fn finalize_into(self, out: &mut GenericArray); + fn finalize_into(self, out: &mut Output); /// Write result into provided array and reset the hasher instance. - fn finalize_into_reset(&mut self, out: &mut GenericArray); + fn finalize_into_reset(&mut self, out: &mut Output); /// Reset hasher instance to its initial state. fn reset(&mut self); @@ -44,18 +37,11 @@ pub trait Digest { /// Get output size of the hasher fn output_size() -> usize; - /// Convenience function to compute hash of the `data`. It will handle - /// hasher creation, data feeding and finalization. - /// - /// Example: - /// - /// ```rust,ignore - /// println!("{:x}", sha2::Sha256::digest(b"Hello world")); - /// ``` - fn digest(data: &[u8]) -> Output; + /// Compute hash of `data`. + fn digest(data: impl AsRef<[u8]>) -> Output; } -impl Digest for D { +impl Digest for D { type OutputSize = ::OutputSize; #[inline] @@ -69,32 +55,29 @@ impl Digest for D { } #[inline] - fn chain(mut self, data: impl AsRef<[u8]>) -> Self - where - Self: Sized, - { + fn chain_update(mut self, data: impl AsRef<[u8]>) -> Self { Update::update(&mut self, data.as_ref()); self } #[inline] fn finalize(self) -> Output { - self.finalize_fixed() + FixedOutput::finalize_fixed(self) } #[inline] fn finalize_reset(&mut self) -> Output { - self.finalize_fixed_reset() + FixedOutput::finalize_fixed_reset(self) } #[inline] fn finalize_into(self, out: &mut Output) { - self.finalize_into(out); + FixedOutput::finalize_into(self, out); } #[inline] fn finalize_into_reset(&mut self, out: &mut Output) { - self.finalize_into_reset(out); + FixedOutput::finalize_into_reset(self, out); } #[inline] @@ -108,10 +91,8 @@ impl Digest for D { } #[inline] - fn digest(data: &[u8]) -> Output { - let mut hasher = Self::default(); - Update::update(&mut hasher, data); - hasher.finalize_fixed() + fn digest(data: impl AsRef<[u8]>) -> Output { + Self::digest_fixed(data) } } diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 61540f233..814687dce 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -10,12 +10,11 @@ //! - **Mid-level traits**: [`Update`], [`FixedOutput`], [`ExtendableOutput`], [`Reset`]. //! These traits atomically describe available functionality of hash function //! implementations. -//! - **Low-level traits**: [`UpdateCore`], [`FixedOutputCore`], -//! [`ExtendableOutputCore`], [`AlgorithmName`]. These traits operate at -//! a block-level and do not contain any built-in buffering. They are intended -//! to be implemented by low-level algorithm providers only and simplify -//! the amount of work implementers need to do and therefore usually shouldn't -//! be used in application-level code. +//! - **Low-level traits** defined in the [`core_api`] module. These traits +//! operate at a block-level and do not contain any built-in buffering. +//! They are intended to be implemented by low-level algorithm providers only +//! and simplify the amount of work implementers need to do and therefore +//! usually shouldn't be used in application-level code. //! //! Additionally hash functions implement traits from the standard library: //! [`Default`], [`Clone`], [`Write`][std::io::Write]. The latter is @@ -48,22 +47,21 @@ use alloc::boxed::Box; pub mod dev; #[cfg(feature = "core-api")] -mod core_api; +#[cfg_attr(docsrs, doc(cfg(feature = "core-api")))] +pub mod core_api; mod digest; #[cfg(feature = "alloc")] mod dyn_digest; -#[cfg(feature = "core-api")] -pub use crate::core_api::{ - AlgorithmName, ExtendableOutputCore, FixedOutputCore, UpdateCore, UpdateCoreWrapper, - XofReaderCore, XofReaderCoreWrapper, -}; pub use crate::digest::{Digest, Output}; #[cfg(feature = "core-api")] +#[cfg_attr(docsrs, doc(cfg(feature = "core-api")))] pub use block_buffer; +use core::fmt; #[cfg(feature = "alloc")] pub use dyn_digest::{DynDigest, InvalidBufferLength}; -pub use generic_array::{self, typenum::consts, ArrayLength, GenericArray}; +use generic_array::ArrayLength; +pub use generic_array::{self, typenum::consts, GenericArray}; /// Trait for updating hasher state with input data. pub trait Update { @@ -78,24 +76,19 @@ pub trait Reset { } /// Trait for returning digest result with the fixed size -pub trait FixedOutput { +pub trait FixedOutput: Sized + Update + Default + Reset { /// Output size for fixed output digest type OutputSize: ArrayLength; /// Write result into provided array and consume the hasher instance. - fn finalize_into(self, out: &mut GenericArray) - where - Self: Sized; + fn finalize_into(self, out: &mut GenericArray); /// Write result into provided array and reset the hasher instance. fn finalize_into_reset(&mut self, out: &mut GenericArray); /// Retrieve result and consume the hasher instance. #[inline] - fn finalize_fixed(self) -> GenericArray - where - Self: Sized, - { + fn finalize_fixed(self) -> GenericArray { let mut out = Default::default(); self.finalize_into(&mut out); out @@ -108,6 +101,14 @@ pub trait FixedOutput { self.finalize_into_reset(&mut out); out } + + /// Compute hash of `data`. + #[inline] + fn digest_fixed(data: impl AsRef<[u8]>) -> GenericArray { + let mut hasher = Self::default(); + hasher.update(data.as_ref()); + hasher.finalize_fixed() + } } /// Trait for describing readers which are used to extract extendable output @@ -132,18 +133,23 @@ pub trait XofReader { } /// Trait which describes extendable-output functions (XOF). -pub trait ExtendableOutput { +pub trait ExtendableOutput: Sized + Update + Default + Reset { /// Reader type Reader: XofReader; /// Retrieve XOF reader and consume hasher instance. - fn finalize_xof(self) -> Self::Reader - where - Self: Sized; + fn finalize_xof(self) -> Self::Reader; /// Retrieve XOF reader and reset hasher instance state. fn finalize_xof_reset(&mut self) -> Self::Reader; + /// Compute hash of `data` and write it to `output`. + fn digest_xof(input: impl AsRef<[u8]>, output: &mut [u8]) { + let mut hasher = Self::default(); + hasher.update(input.as_ref()); + hasher.finalize_xof().read(output); + } + /// Retrieve result into a boxed slice of the specified size and consume /// the hasher. /// @@ -151,11 +157,8 @@ pub trait ExtendableOutput { /// they have size of 2 and 3 words respectively. #[cfg(feature = "alloc")] #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] - fn finalize_boxed(self, n: usize) -> Box<[u8]> - where - Self: Sized, - { - let mut buf = vec![0u8; n].into_boxed_slice(); + fn finalize_boxed(self, output_size: usize) -> Box<[u8]> { + let mut buf = vec![0u8; output_size].into_boxed_slice(); self.finalize_xof().read(&mut buf); buf } @@ -167,9 +170,91 @@ pub trait ExtendableOutput { /// they have size of 2 and 3 words respectively. #[cfg(feature = "alloc")] #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] - fn finalize_boxed_reset(&mut self, n: usize) -> Box<[u8]> { - let mut buf = vec![0u8; n].into_boxed_slice(); + fn finalize_boxed_reset(&mut self, output_size: usize) -> Box<[u8]> { + let mut buf = vec![0u8; output_size].into_boxed_slice(); self.finalize_xof_reset().read(&mut buf); buf } } + +/// Trait for variable output size hash functions. +pub trait VariableOutput: Sized + Update + Reset { + /// Maximum size of output hash. + const MAX_OUTPUT_SIZE: usize; + + /// Create new hasher instance with the given output size. + /// + /// It will return `Err(InvalidOutputSize)` in case if hasher can not return + /// hash of the specified output size. + fn new(output_size: usize) -> Result; + + /// Get output size of the hasher instance provided to the `new` method + fn output_size(&self) -> usize; + + /// Retrieve result via closure and consume hasher. + /// + /// Closure is guaranteed to be called, length of the buffer passed to it + /// will be equal to `output_size`. + fn finalize_variable(self, f: impl FnOnce(&[u8])); + + /// Retrieve result via closure and reset the hasher state. + /// + /// Closure is guaranteed to be called, length of the buffer passed to it + /// will be equal to `output_size`. + fn finalize_variable_reset(&mut self, f: impl FnOnce(&[u8])); + + /// Compute hash of `data` and write it to `output`. + /// + /// Length of the output hash is determined by `output`. If `output` is + /// bigger than `Self::MAX_OUTPUT_SIZE`, this method returns + /// `InvalidOutputSize`. + fn digest_variable( + input: impl AsRef<[u8]>, + output: &mut [u8], + ) -> Result<(), InvalidOutputSize> { + let mut hasher = Self::new(output.len())?; + hasher.update(input.as_ref()); + hasher.finalize_variable(|out| output.copy_from_slice(out)); + Ok(()) + } + + /// Retrieve result into a boxed slice and consume hasher. + /// + /// `Box<[u8]>` is used instead of `Vec` to save stack space, since + /// they have size of 2 and 3 words respectively. + #[cfg(feature = "alloc")] + #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] + fn finalize_boxed(self) -> Box<[u8]> { + let n = self.output_size(); + let mut buf = vec![0u8; n].into_boxed_slice(); + self.finalize_variable(|res| buf.copy_from_slice(res)); + buf + } + + /// Retrieve result into a boxed slice and reset hasher state. + /// + /// `Box<[u8]>` is used instead of `Vec` to save stack space, since + /// they have size of 2 and 3 words respectively. + #[cfg(feature = "alloc")] + #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] + fn finalize_boxed_reset(&mut self) -> Box<[u8]> { + let n = self.output_size(); + let mut buf = vec![0u8; n].into_boxed_slice(); + self.finalize_variable_reset(|res| buf.copy_from_slice(res)); + buf + } +} + +/// The error type for variable hasher initialization. +#[derive(Clone, Copy, Debug, Default)] +pub struct InvalidOutputSize; + +impl fmt::Display for InvalidOutputSize { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("invalid output size") + } +} + +#[cfg(feature = "std")] +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] +impl std::error::Error for InvalidOutputSize {} From 073edacf50e04c257053b6c2ef2fea8276a241e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Tue, 9 Feb 2021 15:13:25 +0300 Subject: [PATCH 0425/1461] digest v0.10.0-pre.3 --- Cargo.lock | 4 ++-- digest/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 31bb35504..319bbc0cc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -133,7 +133,7 @@ dependencies = [ "aead", "cipher", "crypto-mac", - "digest 0.10.0-pre.2", + "digest 0.10.0-pre.3", "elliptic-curve", "password-hash", "signature", @@ -171,7 +171,7 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.0-pre.2" +version = "0.10.0-pre.3" dependencies = [ "blobby", "block-buffer 0.10.0-pre.1", diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 65e940ad4..90c050642 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "digest" description = "Traits for cryptographic hash functions" -version = "0.10.0-pre.2" +version = "0.10.0-pre.3" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" From 04fd3881ae9ac9a606d81e7bf8f0a67bf72e9539 Mon Sep 17 00:00:00 2001 From: Austin Bonander Date: Tue, 9 Feb 2021 19:36:22 -0800 Subject: [PATCH 0426/1461] password-hash: add docs.rs metadata to Cargo.toml (#531) Based on this `#[cfg_attr]` it looks like this was the intention but the required lines in Cargo.toml were omitted: https://github.com/RustCrypto/traits/blob/073edacf50e04c257053b6c2ef2fea8276a241e1/password-hash/src/salt.rs#L185 --- password-hash/Cargo.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index cc506a68a..e58e3b6b9 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -22,3 +22,7 @@ rand_core = { version = "0.6", optional = true, default-features = false } [features] alloc = ["base64ct/alloc"] std = ["alloc", "base64ct/std"] + +[package.metadata.docs.rs] +rustc-args = ["--cfg", "docsrs"] +features = ["rand_core"] From 643673d37f6ae65f14adca723d0c757165703656 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 10 Feb 2021 08:59:31 -0800 Subject: [PATCH 0427/1461] elliptic-curve: remove FromDigest trait (#532) As discussed in #481, this removes the `FromDigest` trait, and with it any dependency on the `digest` crate (at least for now). The reasoning is `FromDigest` in its current form exists to solve a single concern: hash-to-scalar for the specific purposes of ECDSA, which is implemented in the `k256` and `p256` crates as a "narrow" reduction per the requirements of ECDSA. Given that, this trait is best moved to the `ecdsa` crate, clearing the way for a move generally useful, well-considered, and well-specified and standardized hash-to-curve construction as requested in #481. The plan after this is to provide an identical trait, but in the `ecdsa` crate instead of the `elliptic-curve` crate. --- Cargo.lock | 1 - elliptic-curve/Cargo.toml | 3 +-- elliptic-curve/src/dev.rs | 56 ++------------------------------------- elliptic-curve/src/lib.rs | 16 ----------- 4 files changed, 3 insertions(+), 73 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 319bbc0cc..e9fe3ed86 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -183,7 +183,6 @@ name = "elliptic-curve" version = "0.9.0-pre" dependencies = [ "base64ct", - "digest 0.9.0", "ff", "generic-array 0.14.4", "group", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 2333ff981..5c5712666 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -16,7 +16,6 @@ keywords = ["crypto", "ecc", "elliptic", "weierstrass"] [dependencies] base64ct = { version = "0.2", optional = true, default-features = false } -digest = { version = "0.9", optional = true } ff = { version = "0.9", optional = true, default-features = false } group = { version = "0.9", optional = true, default-features = false } hex-literal = { version = "0.3", optional = true } @@ -35,7 +34,7 @@ hex-literal = "0.3" default = ["arithmetic"] alloc = [] arithmetic = ["ff", "group"] -dev = ["arithmetic", "digest", "hex-literal", "pem", "zeroize"] +dev = ["arithmetic", "hex-literal", "pem", "zeroize"] ecdh = ["arithmetic", "zeroize"] hazmat = [] jwk = ["alloc", "base64ct/alloc", "serde", "serde_json", "zeroize/alloc"] diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 041126f42..8899e6031 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -3,17 +3,16 @@ use crate::{ consts::U32, - digest::Digest, ff::{Field, PrimeField}, group, rand_core::RngCore, scalar::ScalarBits, sec1::{FromEncodedPoint, ToEncodedPoint}, subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}, - util::{adc64, sbb64}, + util::sbb64, weierstrass, zeroize::Zeroize, - AlgorithmParameters, Curve, FromDigest, ProjectiveArithmetic, + AlgorithmParameters, Curve, ProjectiveArithmetic, }; use core::{ convert::TryInto, @@ -326,63 +325,12 @@ impl From<&Scalar> for FieldBytes { } } -impl FromDigest for Scalar { - fn from_digest(digest: D) -> Self - where - D: Digest, - { - let bytes = digest.finalize(); - - Self::sub_inner( - u64::from_be_bytes(bytes[24..32].try_into().unwrap()), - u64::from_be_bytes(bytes[16..24].try_into().unwrap()), - u64::from_be_bytes(bytes[8..16].try_into().unwrap()), - u64::from_be_bytes(bytes[0..8].try_into().unwrap()), - 0, - MODULUS[0], - MODULUS[1], - MODULUS[2], - MODULUS[3], - 0, - ) - } -} - impl Zeroize for Scalar { fn zeroize(&mut self) { self.0.as_mut().zeroize() } } -impl Scalar { - #[allow(clippy::too_many_arguments)] - const fn sub_inner( - l0: u64, - l1: u64, - l2: u64, - l3: u64, - l4: u64, - r0: u64, - r1: u64, - r2: u64, - r3: u64, - r4: u64, - ) -> Self { - let (w0, borrow) = sbb64(l0, r0, 0); - let (w1, borrow) = sbb64(l1, r1, borrow); - let (w2, borrow) = sbb64(l2, r2, borrow); - let (w3, borrow) = sbb64(l3, r3, borrow); - let (_, borrow) = sbb64(l4, r4, borrow); - - let (w0, carry) = adc64(w0, MODULUS[0] & borrow, 0); - let (w1, carry) = adc64(w1, MODULUS[1] & borrow, carry); - let (w2, carry) = adc64(w2, MODULUS[2] & borrow, carry); - let (w3, _) = adc64(w3, MODULUS[3] & borrow, carry); - - Scalar([w0, w1, w2, w3]) - } -} - /// Example affine point type #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum AffinePoint { diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 7e21dd206..5eb1c732c 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -69,9 +69,6 @@ pub use { group::{self, Group}, }; -#[cfg(feature = "digest")] -pub use digest::{self, Digest}; - #[cfg(all(feature = "hazmat", feature = "zeroize"))] pub use secret_key::{SecretBytes, SecretValue}; @@ -118,19 +115,6 @@ pub trait Curve: Clone + Debug + Default + Eq + Ord + Send + Sync { /// Byte representation of a base/scalar field element of a given curve. pub type FieldBytes = GenericArray::FieldSize>; -/// Instantiate this type from the output of a digest. -/// -/// This can be used for implementing hash-to-scalar (e.g. as in ECDSA) or -/// hash-to-curve algorithms. -#[cfg(feature = "digest")] -#[cfg_attr(docsrs, doc(cfg(feature = "digest")))] -pub trait FromDigest { - /// Instantiate this type from a [`Digest`] instance - fn from_digest(digest: D) -> Self - where - D: Digest; -} - /// Associate an [`ObjectIdentifier`][`pkcs8::ObjectIdentifier`] (OID) with an /// elliptic curve algorithm implementation. /// From 6b7e4d6ef2815ee33b6853adeb91d448c7dea4d8 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 10 Feb 2021 09:57:07 -0800 Subject: [PATCH 0428/1461] elliptic-curve: add `dev` support for moving FromDigest to `ecdsa` (#533) Adds support needed to move the `FromDigest` trait to the `ecdsa` crate, specifically the following: - Make `MODULUS` public - Add a `TryFrom` impl to instantiate a `Scalar` from limbs --- elliptic-curve/src/dev.rs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 8899e6031..be8cec3c5 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -3,6 +3,7 @@ use crate::{ consts::U32, + error::Error, ff::{Field, PrimeField}, group, rand_core::RngCore, @@ -15,7 +16,7 @@ use crate::{ AlgorithmParameters, Curve, ProjectiveArithmetic, }; use core::{ - convert::TryInto, + convert::{TryFrom, TryInto}, iter::Sum, ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign}, }; @@ -76,8 +77,8 @@ const LIMBS: usize = 4; type U256 = [u64; LIMBS]; -// Note: P-256 modulus -const MODULUS: U256 = [ +/// P-256 modulus +pub const MODULUS: U256 = [ 0xf3b9_cac2_fc63_2551, 0xbce6_faad_a717_9e84, 0xffff_ffff_ffff_ffff, @@ -190,6 +191,15 @@ impl PrimeField for Scalar { } } +impl TryFrom<[u64; 4]> for Scalar { + type Error = Error; + + fn try_from(limbs: [u64; 4]) -> Result { + // TODO(tarcieri): reject values that overflow the order + Ok(Scalar(limbs)) + } +} + impl ConditionallySelectable for Scalar { fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { Scalar([ From c577e14f887a0f984c6f403617aa02e893536704 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 10 Feb 2021 10:01:27 -0800 Subject: [PATCH 0429/1461] elliptic-curve: add `Result` alias (#534) As this crate has only one (opaque/unit) `Error` type, adds a `Result` type alias for simplifying errors returned using the `Error` type. --- elliptic-curve/src/dev.rs | 4 ++-- elliptic-curve/src/error.rs | 3 +++ elliptic-curve/src/lib.rs | 2 +- elliptic-curve/src/public_key.rs | 16 ++++++++-------- elliptic-curve/src/scalar.rs | 4 ++-- elliptic-curve/src/sec1.rs | 15 ++++++--------- elliptic-curve/src/secret_key.rs | 10 +++++----- elliptic-curve/src/secret_key/pkcs8.rs | 4 ++-- 8 files changed, 29 insertions(+), 29 deletions(-) diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index be8cec3c5..741b4fd39 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -3,7 +3,7 @@ use crate::{ consts::U32, - error::Error, + error::{Error, Result}, ff::{Field, PrimeField}, group, rand_core::RngCore, @@ -194,7 +194,7 @@ impl PrimeField for Scalar { impl TryFrom<[u64; 4]> for Scalar { type Error = Error; - fn try_from(limbs: [u64; 4]) -> Result { + fn try_from(limbs: [u64; 4]) -> Result { // TODO(tarcieri): reject values that overflow the order Ok(Scalar(limbs)) } diff --git a/elliptic-curve/src/error.rs b/elliptic-curve/src/error.rs index c00eaab7a..35d7f66bb 100644 --- a/elliptic-curve/src/error.rs +++ b/elliptic-curve/src/error.rs @@ -2,6 +2,9 @@ use core::fmt::{self, Display}; +/// Result type +pub type Result = core::result::Result; + /// Elliptic curve errors #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub struct Error; diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 5eb1c732c..e4c10bac9 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -52,7 +52,7 @@ mod jwk; #[cfg(feature = "zeroize")] mod secret_key; -pub use self::error::Error; +pub use self::error::{Error, Result}; pub use generic_array::{self, typenum::consts}; pub use rand_core; diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index 7765dd18c..ddf13c95f 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -7,7 +7,7 @@ use crate::{ EncodedPoint, FromEncodedPoint, ToEncodedPoint, UncompressedPointSize, UntaggedPointSize, }, weierstrass::{point, Curve}, - AffinePoint, Error, FieldBytes, ProjectiveArithmetic, ProjectivePoint, Scalar, + AffinePoint, Error, FieldBytes, ProjectiveArithmetic, ProjectivePoint, Result, Scalar, }; use core::{ convert::{TryFrom, TryInto}, @@ -78,7 +78,7 @@ where Scalar: PrimeField>, { /// Convert an [`AffinePoint`] into a [`PublicKey`] - pub fn from_affine(point: AffinePoint) -> Result { + pub fn from_affine(point: AffinePoint) -> Result { if ProjectivePoint::::from(point).is_identity().into() { Err(Error) } else { @@ -101,7 +101,7 @@ where /// 2.3.3 (page 10). /// /// - pub fn from_sec1_bytes(bytes: &[u8]) -> Result + pub fn from_sec1_bytes(bytes: &[u8]) -> Result where Self: TryFrom, Error = Error>, UntaggedPointSize: Add + ArrayLength, @@ -127,7 +127,7 @@ where /// Parse a [`JwkEcKey`] JSON Web Key (JWK) into a [`PublicKey`]. #[cfg(feature = "jwk")] #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] - pub fn from_jwk(jwk: &JwkEcKey) -> Result + pub fn from_jwk(jwk: &JwkEcKey) -> Result where C: JwkParameters, AffinePoint: Default + FromEncodedPoint + ToEncodedPoint, @@ -140,7 +140,7 @@ where /// Parse a string containing a JSON Web Key (JWK) into a [`PublicKey`]. #[cfg(feature = "jwk")] #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] - pub fn from_jwk_str(jwk: &str) -> Result + pub fn from_jwk_str(jwk: &str) -> Result where C: JwkParameters, AffinePoint: Default + FromEncodedPoint + ToEncodedPoint, @@ -200,7 +200,7 @@ where { type Error = Error; - fn try_from(encoded_point: EncodedPoint) -> Result { + fn try_from(encoded_point: EncodedPoint) -> Result { encoded_point.decode() } } @@ -216,7 +216,7 @@ where { type Error = Error; - fn try_from(encoded_point: &EncodedPoint) -> Result { + fn try_from(encoded_point: &EncodedPoint) -> Result { encoded_point.decode() } } @@ -373,7 +373,7 @@ where { type Err = Error; - fn from_str(s: &str) -> Result { + fn from_str(s: &str) -> Result { Self::from_public_key_pem(s).map_err(|_| Error) } } diff --git a/elliptic-curve/src/scalar.rs b/elliptic-curve/src/scalar.rs index 48db77f1a..961ec4697 100644 --- a/elliptic-curve/src/scalar.rs +++ b/elliptic-curve/src/scalar.rs @@ -3,7 +3,7 @@ use crate::{ ops::Invert, rand_core::{CryptoRng, RngCore}, - Curve, Error, FieldBytes, ProjectiveArithmetic, + Curve, Error, FieldBytes, ProjectiveArithmetic, Result, }; use core::{convert::TryFrom, ops::Deref}; use ff::{Field, FieldBits, PrimeField}; @@ -142,7 +142,7 @@ where { type Error = Error; - fn try_from(bytes: &[u8]) -> Result { + fn try_from(bytes: &[u8]) -> Result { if bytes.len() == C::FieldSize::to_usize() { NonZeroScalar::from_repr(GenericArray::clone_from_slice(bytes)).ok_or(Error) } else { diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index 238df206e..684ffca7f 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -5,7 +5,7 @@ //! //! -use crate::{weierstrass::Curve, Error, FieldBytes}; +use crate::{weierstrass::Curve, Error, FieldBytes, Result}; use core::{ fmt::{self, Debug}, ops::Add, @@ -77,7 +77,7 @@ where /// 2.3.3 (page 10). /// /// - pub fn from_bytes(input: impl AsRef<[u8]>) -> Result { + pub fn from_bytes(input: impl AsRef<[u8]>) -> Result { let input = input.as_ref(); // Validate tag @@ -230,7 +230,7 @@ where } /// Decode this [`EncodedPoint`] into the desired type - pub fn decode(&self) -> Result + pub fn decode(&self) -> Result where T: FromEncodedPoint, { @@ -411,7 +411,7 @@ pub enum Tag { impl Tag { /// Parse a tag value from a byte - pub fn from_u8(byte: u8) -> Result { + pub fn from_u8(byte: u8) -> Result { match byte { 0 => Ok(Tag::Identity), 2 => Ok(Tag::CompressedEvenY), @@ -512,7 +512,7 @@ where fn validate_public_key( secret_key: &SecretKey, public_key: &EncodedPoint, - ) -> Result<(), Error> { + ) -> Result<()> { // Provide a default "always succeeds" implementation. // This is the intended default for curve implementations which // do not provide an arithmetic implementation, since they have no @@ -534,10 +534,7 @@ where UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { - fn validate_public_key( - secret_key: &SecretKey, - public_key: &EncodedPoint, - ) -> Result<(), Error> { + fn validate_public_key(secret_key: &SecretKey, public_key: &EncodedPoint) -> Result<()> { let pk = secret_key .public_key() .to_encoded_point(public_key.is_compressed()); diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 0c3c81831..54a211426 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -10,7 +10,7 @@ #[cfg(feature = "pkcs8")] mod pkcs8; -use crate::{error::Error, Curve, FieldBytes}; +use crate::{Curve, Error, FieldBytes, Result}; use core::{ convert::{TryFrom, TryInto}, fmt::{self, Debug}, @@ -102,7 +102,7 @@ where } /// Deserialize raw private scalar as a big endian integer - pub fn from_bytes(bytes: impl AsRef<[u8]>) -> Result { + pub fn from_bytes(bytes: impl AsRef<[u8]>) -> Result { bytes .as_ref() .try_into() @@ -150,7 +150,7 @@ where /// Parse a [`JwkEcKey`] JSON Web Key (JWK) into a [`SecretKey`]. #[cfg(feature = "jwk")] #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] - pub fn from_jwk(jwk: &JwkEcKey) -> Result + pub fn from_jwk(jwk: &JwkEcKey) -> Result where C: JwkParameters + ValidatePublicKey, UntaggedPointSize: Add + ArrayLength, @@ -162,7 +162,7 @@ where /// Parse a string containing a JSON Web Key (JWK) into a [`SecretKey`]. #[cfg(feature = "jwk")] #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] - pub fn from_jwk_str(jwk: &str) -> Result + pub fn from_jwk_str(jwk: &str) -> Result where C: JwkParameters + ValidatePublicKey, UntaggedPointSize: Add + ArrayLength, @@ -212,7 +212,7 @@ where { type Error = Error; - fn try_from(slice: &[u8]) -> Result { + fn try_from(slice: &[u8]) -> Result { Self::from_bytes(slice) } } diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs index 45444ec2c..164f72b18 100644 --- a/elliptic-curve/src/secret_key/pkcs8.rs +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -3,7 +3,7 @@ use super::{SecretKey, SecretValue}; use crate::{ sec1::{self, UncompressedPointSize, UntaggedPointSize, ValidatePublicKey}, - weierstrass, AlgorithmParameters, FieldBytes, ALGORITHM_OID, + weierstrass, AlgorithmParameters, FieldBytes, Result, ALGORITHM_OID, }; use core::ops::Add; use generic_array::{typenum::U1, ArrayLength}; @@ -162,7 +162,7 @@ where { type Err = Error; - fn from_str(s: &str) -> Result { + fn from_str(s: &str) -> Result { Self::from_pkcs8_pem(s).map_err(|_| Error) } } From b302ba35d0c4ea226925471a1210535f58f0a931 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 10 Feb 2021 11:18:08 -0800 Subject: [PATCH 0430/1461] elliptic-curve v0.9.0 (#535) --- Cargo.lock | 2 +- crypto/Cargo.toml | 2 +- elliptic-curve/CHANGELOG.md | 28 ++++++++++++++++++++++++++++ elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 2 +- 5 files changed, 32 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e9fe3ed86..8a11576d1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -180,7 +180,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.9.0-pre" +version = "0.9.0" dependencies = [ "base64ct", "ff", diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index ff4811a73..d668f56dd 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -15,7 +15,7 @@ edition = "2018" aead = { version = "0.4", optional = true, path = "../aead" } cipher = { version = "=0.3.0-pre.4", optional = true, path = "../cipher" } digest = { version = "0.10.0-pre", optional = true, path = "../digest" } -elliptic-curve = { version = "=0.9.0-pre", optional = true, path = "../elliptic-curve" } +elliptic-curve = { version = "0.9", optional = true, path = "../elliptic-curve" } mac = { version = "=0.11.0-pre", package = "crypto-mac", optional = true, path = "../crypto-mac" } password-hash = { version = "0.1", optional = true, path = "../password-hash" } signature = { version = "1.3.0", optional = true, default-features = false, path = "../signature" } diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index 704aa3463..318e409a3 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,34 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.9.0 (2021-02-10) +### Added +- JWK support ([#483]) +- `sec1::ValidatePublicKey` trait ([#485]) +- `hazmat` crate feature ([#487]) +- `Result` alias ([#534]) + +### Changed +- Bump `ff` and `group` crates to v0.9 ([#452]) +- Simplify ECDH trait bounds ([#475]) +- Flatten API ([#487]) +- Bump `pkcs8` crate dependency to v0.4 ([#493]) + +### Removed +- Direct `bitvec` dependency ([#484]) +- `FromDigest` trait ([#532]) + +[#452]: https://github.com/RustCrypto/traits/pull/452 +[#475]: https://github.com/RustCrypto/traits/pull/475 +[#483]: https://github.com/RustCrypto/traits/pull/483 +[#484]: https://github.com/RustCrypto/traits/pull/484 +[#485]: https://github.com/RustCrypto/traits/pull/485 +[#487]: https://github.com/RustCrypto/traits/pull/487 +[#493]: https://github.com/RustCrypto/traits/pull/493 +[#432]: https://github.com/RustCrypto/traits/pull/432 +[#532]: https://github.com/RustCrypto/traits/pull/532 +[#534]: https://github.com/RustCrypto/traits/pull/534 + ## 0.8.4 (2020-12-23) ### Fixed - Rust `nightly` regression ([#432]) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 5c5712666..528cc06c9 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -5,7 +5,7 @@ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. """ -version = "0.9.0-pre" # Also update html_root_url in lib.rs when bumping this +version = "0.9.0" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" repository = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve" diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index e4c10bac9..04b26ee85 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -16,7 +16,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.8.4" + html_root_url = "https://docs.rs/elliptic-curve/0.9.0" )] #[cfg(feature = "alloc")] From ccb11bb4dde710dd4a25408c1ee61bb8f17fab8e Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 11 Feb 2021 05:36:38 -0800 Subject: [PATCH 0431/1461] elliptic-curve: documentation improvements (#539) Adds more rustdoc to the `JwkEcKey` type. --- elliptic-curve/src/error.rs | 4 ++-- elliptic-curve/src/jwk.rs | 10 +++++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/elliptic-curve/src/error.rs b/elliptic-curve/src/error.rs index 35d7f66bb..bac007a0e 100644 --- a/elliptic-curve/src/error.rs +++ b/elliptic-curve/src/error.rs @@ -2,10 +2,10 @@ use core::fmt::{self, Display}; -/// Result type +/// Result type. pub type Result = core::result::Result; -/// Elliptic curve errors +/// Elliptic curve errors. #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub struct Error; diff --git a/elliptic-curve/src/jwk.rs b/elliptic-curve/src/jwk.rs index 0a147e5c6..6d48a0c18 100644 --- a/elliptic-curve/src/jwk.rs +++ b/elliptic-curve/src/jwk.rs @@ -61,10 +61,14 @@ pub trait JwkParameters: Curve { const CRV: &'static str; } -/// JWK elliptic curve keys with a `kty` of `"EC"`. +/// JSON Web Key (JWK) with a `kty` of `"EC"` (elliptic curve). /// -/// They can represent either a public/private keypair, or just a public key, -/// depending on whether or not the `d` parameter is present. +/// Specified in [RFC 7518 Section 6: Cryptographic Algorithms for Keys][1]. +/// +/// This type can represent either a public/private keypair, or just a +/// public key, depending on whether or not the `d` parameter is present. +/// +/// [1]: https://tools.ietf.org/html/rfc7518#section-6 // TODO(tarcieri): eagerly decode or validate `x`, `y`, and `d` as Base64 #[derive(Clone)] #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] From 938fc4ccab00adead8f37bb667f41dc48eb47863 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 11 Feb 2021 05:51:12 -0800 Subject: [PATCH 0432/1461] elliptic-curve: remove BitView re-export (#540) Removes the re-export of `ff::BitView`, as the `ff` crate itself is already re-exported, so it's available as `elliptic_curve::ff::BitView`. Note that this is technically a breaking change, however the plan is to release a v0.9.1 and yank the v0.9.0 release. This is acceptable largely because the previous release is not being widely used (released 18 hours ago with 189 downloads) and therefore this change is unlikely to cause problems in practice, especially considering its relatively minor nature. --- elliptic-curve/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 04b26ee85..3f8859c82 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -65,7 +65,7 @@ pub use { public_key::PublicKey, scalar::{NonZeroScalar, Scalar, ScalarBits}, }, - ff::{self, BitView, Field}, + ff::{self, Field}, group::{self, Group}, }; From 2cfbce4d38fd1c298fd21649872ccd52e4fa8d80 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 11 Feb 2021 05:57:13 -0800 Subject: [PATCH 0433/1461] elliptic-curve v0.9.1 (#541) --- Cargo.lock | 2 +- elliptic-curve/CHANGELOG.md | 8 +++++++- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8a11576d1..616f15eda 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -180,7 +180,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.9.0" +version = "0.9.1" dependencies = [ "base64ct", "ff", diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index 318e409a3..d9de56cd2 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,7 +4,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 0.9.0 (2021-02-10) +## 0.9.1 (2021-02-11) +### Removed +- `BitView` re-export ([#540]) + +[#540]: https://github.com/RustCrypto/traits/pull/540 + +## 0.9.0 (2021-02-10) [YANKED] ### Added - JWK support ([#483]) - `sec1::ValidatePublicKey` trait ([#485]) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 528cc06c9..4c34629ab 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -5,7 +5,7 @@ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. """ -version = "0.9.0" # Also update html_root_url in lib.rs when bumping this +version = "0.9.1" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" repository = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve" diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 3f8859c82..d02052e1e 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -16,7 +16,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.9.0" + html_root_url = "https://docs.rs/elliptic-curve/0.9.1" )] #[cfg(feature = "alloc")] From 77f772a0b8db3f98fca719ca71a84af8df4d5c8d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 11 Feb 2021 06:43:46 -0800 Subject: [PATCH 0434/1461] elliptic-curve: flatten `weierstrass` module (#542) Flattens the traits previously in the `point` module into the `weierstrass` module. --- elliptic-curve/src/public_key.rs | 6 +++--- elliptic-curve/src/sec1.rs | 6 +++--- elliptic-curve/src/weierstrass.rs | 18 ++++++++++++++++-- elliptic-curve/src/weierstrass/point.rs | 18 ------------------ 4 files changed, 22 insertions(+), 26 deletions(-) delete mode 100644 elliptic-curve/src/weierstrass/point.rs diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index ddf13c95f..0fce6e206 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -6,7 +6,7 @@ use crate::{ sec1::{ EncodedPoint, FromEncodedPoint, ToEncodedPoint, UncompressedPointSize, UntaggedPointSize, }, - weierstrass::{point, Curve}, + weierstrass::{Curve, PointCompression}, AffinePoint, Error, FieldBytes, ProjectiveArithmetic, ProjectivePoint, Result, Scalar, }; use core::{ @@ -223,7 +223,7 @@ where impl From> for EncodedPoint where - C: Curve + ProjectiveArithmetic + point::Compression, + C: Curve + ProjectiveArithmetic + PointCompression, Scalar: PrimeField>, AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, ProjectivePoint: From>, @@ -237,7 +237,7 @@ where impl From<&PublicKey> for EncodedPoint where - C: Curve + ProjectiveArithmetic + point::Compression, + C: Curve + ProjectiveArithmetic + PointCompression, Scalar: PrimeField>, AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, ProjectivePoint: From>, diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index 684ffca7f..530dca790 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -21,7 +21,7 @@ use alloc::boxed::Box; #[cfg(feature = "arithmetic")] use crate::{ - ff::PrimeField, weierstrass::point::Decompress, AffinePoint, ProjectiveArithmetic, Scalar, + ff::PrimeField, weierstrass::DecompressPoint, AffinePoint, ProjectiveArithmetic, Scalar, }; #[cfg(all(feature = "arithmetic", feature = "zeroize"))] @@ -173,7 +173,7 @@ where pub fn to_untagged_bytes(&self) -> Option>> where C: Curve + ProjectiveArithmetic, - AffinePoint: ConditionallySelectable + Default + Decompress + ToEncodedPoint, + AffinePoint: ConditionallySelectable + Default + DecompressPoint + ToEncodedPoint, Scalar: PrimeField>, { self.decompress().map(|point| { @@ -208,7 +208,7 @@ where where C: Curve + ProjectiveArithmetic, Scalar: PrimeField>, - AffinePoint: ConditionallySelectable + Default + Decompress + ToEncodedPoint, + AffinePoint: ConditionallySelectable + Default + DecompressPoint + ToEncodedPoint, { match self.coordinates() { Coordinates::Identity => None, diff --git a/elliptic-curve/src/weierstrass.rs b/elliptic-curve/src/weierstrass.rs index ba05927ba..b998ea1e2 100644 --- a/elliptic-curve/src/weierstrass.rs +++ b/elliptic-curve/src/weierstrass.rs @@ -1,6 +1,20 @@ //! Elliptic curves in short Weierstrass form. -pub mod point; +use crate::FieldBytes; +use subtle::{Choice, CtOption}; -/// Marker trait for elliptic curves in short Weierstrass form +/// Marker trait for elliptic curves in short Weierstrass form. pub trait Curve: super::Curve {} + +/// Point compression settings. +pub trait PointCompression { + /// Should point compression be applied by default? + const COMPRESS_POINTS: bool; +} + +/// Attempt to decompress an elliptic curve point from its x-coordinate and +/// a boolean flag indicating whether or not the y-coordinate is odd. +pub trait DecompressPoint: Sized { + /// Attempt to decompress an elliptic curve point. + fn decompress(x: &FieldBytes, y_is_odd: Choice) -> CtOption; +} diff --git a/elliptic-curve/src/weierstrass/point.rs b/elliptic-curve/src/weierstrass/point.rs deleted file mode 100644 index e2612ad90..000000000 --- a/elliptic-curve/src/weierstrass/point.rs +++ /dev/null @@ -1,18 +0,0 @@ -//! Traits for Weierstrass elliptic curve points - -use super::Curve; -use crate::FieldBytes; -use subtle::{Choice, CtOption}; - -/// Point compression settings -pub trait Compression { - /// Should point compression be applied by default? - const COMPRESS_POINTS: bool; -} - -/// Attempt to decompress an elliptic curve point from its x-coordinate and -/// a boolean flag indicating whether or not the y-coordinate is odd. -pub trait Decompress: Sized { - /// Attempt to decompress an elliptic curve point - fn decompress(x: &FieldBytes, y_is_odd: Choice) -> CtOption; -} From 63fa88b92c70b9d1fb4571089553c05ee6caac57 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 11 Feb 2021 06:49:16 -0800 Subject: [PATCH 0435/1461] elliptic-curve v0.9.2 (#543) --- Cargo.lock | 2 +- elliptic-curve/CHANGELOG.md | 8 +++++++- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 616f15eda..b36c3b1f6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -180,7 +180,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.9.1" +version = "0.9.2" dependencies = [ "base64ct", "ff", diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index d9de56cd2..f9923d37d 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,7 +4,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 0.9.1 (2021-02-11) +## 0.9.2 (2021-02-12) +### Changed +- Flatten `weierstrass` module ([#542]) + +[#542]: https://github.com/RustCrypto/traits/pull/542 + +## 0.9.1 (2021-02-11) [YANKED] ### Removed - `BitView` re-export ([#540]) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 4c34629ab..c489134e6 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -5,7 +5,7 @@ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. """ -version = "0.9.1" # Also update html_root_url in lib.rs when bumping this +version = "0.9.2" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" repository = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve" diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index d02052e1e..0d37401da 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -16,7 +16,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.9.1" + html_root_url = "https://docs.rs/elliptic-curve/0.9.2" )] #[cfg(feature = "alloc")] From b921966c5e5d6f2ce503f71cca7f1e00d43384c5 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 11 Feb 2021 11:15:27 -0800 Subject: [PATCH 0436/1461] elliptic-curve: add doc_cfg attrs for `jwk`-gated From impls (#544) --- elliptic-curve/src/jwk.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/elliptic-curve/src/jwk.rs b/elliptic-curve/src/jwk.rs index 6d48a0c18..d84667c16 100644 --- a/elliptic-curve/src/jwk.rs +++ b/elliptic-curve/src/jwk.rs @@ -159,6 +159,7 @@ impl ToString for JwkEcKey { } } +#[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] impl TryFrom for EncodedPoint where C: Curve + JwkParameters, @@ -172,6 +173,7 @@ where } } +#[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] impl TryFrom<&JwkEcKey> for EncodedPoint where C: Curve + JwkParameters, @@ -191,6 +193,7 @@ where } } +#[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] impl TryFrom> for JwkEcKey where C: Curve + JwkParameters, @@ -204,6 +207,7 @@ where } } +#[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] impl TryFrom<&EncodedPoint> for JwkEcKey where C: Curve + JwkParameters, @@ -225,6 +229,7 @@ where } } +#[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] impl TryFrom for SecretKey where C: Curve + JwkParameters + ValidatePublicKey + SecretValue, @@ -240,6 +245,7 @@ where } } +#[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] impl TryFrom<&JwkEcKey> for SecretKey where C: Curve + JwkParameters + ValidatePublicKey + SecretValue, @@ -269,6 +275,7 @@ where #[cfg(feature = "arithmetic")] #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] +#[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] impl From> for JwkEcKey where C: Curve + JwkParameters + ProjectiveArithmetic, @@ -285,6 +292,7 @@ where #[cfg(feature = "arithmetic")] #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] +#[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] impl From<&SecretKey> for JwkEcKey where C: Curve + JwkParameters + ProjectiveArithmetic, @@ -305,6 +313,7 @@ where #[cfg(feature = "arithmetic")] #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] +#[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] impl TryFrom for PublicKey where C: Curve + JwkParameters + ProjectiveArithmetic, @@ -323,6 +332,7 @@ where #[cfg(feature = "arithmetic")] #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] +#[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] impl TryFrom<&JwkEcKey> for PublicKey where C: Curve + JwkParameters + ProjectiveArithmetic, @@ -341,6 +351,7 @@ where #[cfg(feature = "arithmetic")] #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] +#[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] impl From> for JwkEcKey where C: Curve + JwkParameters + ProjectiveArithmetic, @@ -357,6 +368,7 @@ where #[cfg(feature = "arithmetic")] #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] +#[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] impl From<&PublicKey> for JwkEcKey where C: Curve + JwkParameters + ProjectiveArithmetic, From b25b8c2461c99e2057461c9418ab174249a836ca Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Fri, 12 Feb 2021 21:43:29 +0000 Subject: [PATCH 0437/1461] Use images from RustCrypto/media (#546) --- .img/rogaway-stream.svg | 1 - aead/src/lib.rs | 4 ++-- aead/src/stream.rs | 2 +- cipher/src/lib.rs | 4 ++-- crypto-mac/src/lib.rs | 4 ++-- crypto/src/lib.rs | 4 ++-- digest/src/lib.rs | 4 ++-- elliptic-curve/src/lib.rs | 4 ++-- password-hash/src/lib.rs | 4 ++-- signature/async/src/lib.rs | 4 ++-- signature/src/lib.rs | 4 ++-- universal-hash/src/lib.rs | 4 ++-- 12 files changed, 21 insertions(+), 22 deletions(-) delete mode 100644 .img/rogaway-stream.svg diff --git a/.img/rogaway-stream.svg b/.img/rogaway-stream.svg deleted file mode 100644 index ac695875d..000000000 --- a/.img/rogaway-stream.svg +++ /dev/null @@ -1 +0,0 @@ -stream \ No newline at end of file diff --git a/aead/src/lib.rs b/aead/src/lib.rs index cb31947b4..eeadf59d3 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -17,8 +17,8 @@ #![cfg_attr(docsrs, feature(doc_cfg))] #![forbid(unsafe_code)] #![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_root_url = "https://docs.rs/aead/0.4.0" )] #![warn(missing_docs, rust_2018_idioms)] diff --git a/aead/src/stream.rs b/aead/src/stream.rs index 243e875c2..c61b76fb1 100644 --- a/aead/src/stream.rs +++ b/aead/src/stream.rs @@ -17,7 +17,7 @@ //! //! ## Diagram //! -//! ![STREAM Diagram](https://raw.githubusercontent.com/RustCrypto/traits/d5c853c/.img/rogaway-stream.svg) +//! ![STREAM Diagram](https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/img/AEADs/rogaway-stream.svg) //! //! Legend: //! diff --git a/cipher/src/lib.rs b/cipher/src/lib.rs index d0766d8de..a8fc29795 100644 --- a/cipher/src/lib.rs +++ b/cipher/src/lib.rs @@ -7,8 +7,8 @@ #![no_std] #![cfg_attr(docsrs, feature(doc_cfg))] #![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg" )] #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] diff --git a/crypto-mac/src/lib.rs b/crypto-mac/src/lib.rs index 60e89112e..543129f8c 100644 --- a/crypto-mac/src/lib.rs +++ b/crypto-mac/src/lib.rs @@ -3,8 +3,8 @@ #![no_std] #![cfg_attr(docsrs, feature(doc_cfg))] #![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg" )] #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] diff --git a/crypto/src/lib.rs b/crypto/src/lib.rs index c57ca995e..b52b4b9f9 100644 --- a/crypto/src/lib.rs +++ b/crypto/src/lib.rs @@ -37,8 +37,8 @@ #![no_std] #![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg" )] #![forbid(unsafe_code)] #![warn(rust_2018_idioms)] diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 814687dce..7256974eb 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -27,8 +27,8 @@ #![cfg_attr(docsrs, feature(doc_cfg))] #![forbid(unsafe_code)] #![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg" )] #![warn(missing_docs, rust_2018_idioms)] diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 0d37401da..42933e707 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -14,8 +14,8 @@ #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms, unused_qualifications)] #![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_root_url = "https://docs.rs/elliptic-curve/0.9.2" )] diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index 5a02c86da..77ee32b14 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -37,8 +37,8 @@ #![no_std] #![cfg_attr(docsrs, feature(doc_cfg))] #![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_root_url = "https://docs.rs/password-hash/0.1.1" )] #![forbid(unsafe_code)] diff --git a/signature/async/src/lib.rs b/signature/async/src/lib.rs index 89b6a5edc..a3f23b7f2 100644 --- a/signature/async/src/lib.rs +++ b/signature/async/src/lib.rs @@ -19,8 +19,8 @@ #![cfg_attr(docsrs, feature(doc_cfg))] #![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_root_url = "https://docs.rs/async-signature/0.0.1" )] #![forbid(unsafe_code)] diff --git a/signature/src/lib.rs b/signature/src/lib.rs index 034651e4f..7057b65d1 100644 --- a/signature/src/lib.rs +++ b/signature/src/lib.rs @@ -158,8 +158,8 @@ #![no_std] #![cfg_attr(docsrs, feature(doc_cfg))] #![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_root_url = "https://docs.rs/signature/1.3.0" )] #![forbid(unsafe_code)] diff --git a/universal-hash/src/lib.rs b/universal-hash/src/lib.rs index dc0e6f1cf..635cc1166 100644 --- a/universal-hash/src/lib.rs +++ b/universal-hash/src/lib.rs @@ -20,8 +20,8 @@ #![no_std] #![forbid(unsafe_code)] #![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg" )] #![warn(missing_docs, rust_2018_idioms)] From 1765e5c6e75fc3726725267f3cd5b41c829937b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Sat, 13 Feb 2021 00:47:06 +0300 Subject: [PATCH 0438/1461] Rename deps to deps-link --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1639ebb39..80a7411fd 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# RustCrypto: Traits ![Rust Version][rustc-image] [![Project Chat][chat-image]][chat-link] [![dependency status][deps-image]][deps] +# RustCrypto: Traits ![Rust Version][rustc-image] [![Project Chat][chat-image]][chat-link] [![dependency status][deps-image]][deps-link] Collection of traits which describe functionality of cryptographic primitives. @@ -50,7 +50,7 @@ dual licensed as above, without any additional terms or conditions. [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/ [deps-image]: https://deps.rs/repo/github/RustCrypto/traits/status.svg -[deps]: https://deps.rs/repo/github/RustCrypto/traits +[deps-link]: https://deps.rs/repo/github/RustCrypto/traits [//]: # (crates) From 0aebcb4618887a13cc69dc11ddd0ef26df6cbdef Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Feb 2021 06:03:29 -0800 Subject: [PATCH 0439/1461] build(deps): bump rand_core from 0.6.1 to 0.6.2 (#548) Bumps [rand_core](https://github.com/rust-random/rand) from 0.6.1 to 0.6.2. - [Release notes](https://github.com/rust-random/rand/releases) - [Changelog](https://github.com/rust-random/rand/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-random/rand/compare/rand_core-0.6.1...rand_core-0.6.2) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b36c3b1f6..65e4f6b7b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -360,9 +360,9 @@ checksum = "e9e006811e1fdd12672b0820a7f44c18dde429f367d50cec003d22aa9b3c8ddc" [[package]] name = "rand_core" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c026d7df8b298d90ccbbc5190bd04d85e159eaf5576caeacf8741da93ccbd2e5" +checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" [[package]] name = "ryu" From 9d4294a4288be1cb49c2487833f10f16cdb54db7 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 16 Feb 2021 19:41:47 -0800 Subject: [PATCH 0440/1461] elliptic-curve: bump `pkcs8` dependency to v0.5.0 (#549) --- Cargo.lock | 14 ++++++++++++-- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 2 +- elliptic-curve/src/public_key.rs | 2 +- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 65e4f6b7b..8ee14fe5f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -319,12 +319,13 @@ dependencies = [ [[package]] name = "pkcs8" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cf818666b471f4219a11aaca36c612697807b216b91149ed4b799bf1a5b0fd0" +checksum = "cef7f3bd1bd1bb7b347609085a8ef84e326de2e400bc2b53eba16f77a3dc5bfb" dependencies = [ "base64ct", "der", + "spki", "zeroize", ] @@ -421,6 +422,15 @@ dependencies = [ "synstructure", ] +[[package]] +name = "spki" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc22de9c8a841f9508de9f6849b018d414199e4682cc094e5677286c81de80f8" +dependencies = [ + "der", +] + [[package]] name = "stable_deref_trait" version = "1.2.0" diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index c489134e6..2559e4f17 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -20,7 +20,7 @@ ff = { version = "0.9", optional = true, default-features = false } group = { version = "0.9", optional = true, default-features = false } hex-literal = { version = "0.3", optional = true } generic-array = { version = "0.14", default-features = false } -pkcs8 = { version = "0.4", optional = true } +pkcs8 = { version = "0.5", optional = true } rand_core = { version = "0.6", default-features = false } serde = { version = "1", optional = true, default-features = false } serde_json = { version = "1", optional = true, default-features = false, features = ["alloc"] } diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 42933e707..4d1e1f20f 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -128,7 +128,7 @@ pub trait AlgorithmParameters: Curve { const OID: pkcs8::ObjectIdentifier; /// Get the [`pkcs8::AlgorithmIdentifier`] for this curve - fn algorithm_identifier() -> pkcs8::AlgorithmIdentifier { + fn algorithm_identifier() -> pkcs8::AlgorithmIdentifier<'static> { pkcs8::AlgorithmIdentifier { oid: ALGORITHM_OID, parameters: Some(Self::OID.into()), diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index 0fce6e206..a0684c39d 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -355,7 +355,7 @@ where algorithm: C::algorithm_identifier(), subject_public_key: public_key_bytes.as_ref(), } - .to_der() + .into() } } From cb47603c720478443103d9dcee0c6b1d2dcd5858 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 16 Feb 2021 19:48:37 -0800 Subject: [PATCH 0441/1461] elliptic-curve: pin `funty` to `=1.1.0` (#550) Workaround for https://github.com/bitvecto-rs/bitvec/issues/105 --- Cargo.lock | 27 ++++++++++++++------------- elliptic-curve/Cargo.toml | 1 + 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8ee14fe5f..d93100ae2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -76,9 +76,9 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.10.0-pre.1" +version = "0.10.0-pre.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae646bb58db3c82677a9ebece843b3577e1e2e134067c3e69681ebe1e4c75f02" +checksum = "9bda843099271fe07dc9638389268bf732e981d8a71d7a1472f79eb54cc5a827" dependencies = [ "block-padding", "generic-array 0.14.4", @@ -153,9 +153,9 @@ dependencies = [ [[package]] name = "der" -version = "0.2.0" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65ade418c7a9e4edd2dab3b4749ef6c56ee4b137bc1600215c158cff8e5d39b2" +checksum = "b70f809fb1678da4d5ea334095cbe8d6c64fea35fc52836db6c241caee68e17e" dependencies = [ "const-oid", ] @@ -174,7 +174,7 @@ name = "digest" version = "0.10.0-pre.3" dependencies = [ "blobby", - "block-buffer 0.10.0-pre.1", + "block-buffer 0.10.0-pre.2", "generic-array 0.14.4", ] @@ -184,6 +184,7 @@ version = "0.9.2" dependencies = [ "base64ct", "ff", + "funty", "generic-array 0.14.4", "group", "hex-literal 0.3.1", @@ -346,18 +347,18 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "991431c3519a3f36861882da93630ce66b52918dcf1b8e2fd66b397fc96f28df" +checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" dependencies = [ "proc-macro2", ] [[package]] name = "radium" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9e006811e1fdd12672b0820a7f44c18dde429f367d50cec003d22aa9b3c8ddc" +checksum = "643f8f41a8ebc4c5dc4515c82bb8abd397b527fc20fd681b7c011c2aee5d44fb" [[package]] name = "rand_core" @@ -445,9 +446,9 @@ checksum = "1e81da0851ada1f3e9d4312c704aa4f8806f0f9d69faaf8df2f3464b4a9437c2" [[package]] name = "syn" -version = "1.0.58" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc60a3d73ea6594cd712d830cc1f0390fd71542d8c8cd24e70cc54cdfd5e05d5" +checksum = "c700597eca8a5a762beb35753ef6b94df201c81cca676604f547495a0d7f0081" dependencies = [ "proc-macro2", "quote", @@ -468,9 +469,9 @@ dependencies = [ [[package]] name = "tap" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36474e732d1affd3a6ed582781b3683df3d0563714c59c39591e8ff707cf078e" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "typenum" diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 2559e4f17..2a691392e 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -17,6 +17,7 @@ keywords = ["crypto", "ecc", "elliptic", "weierstrass"] [dependencies] base64ct = { version = "0.2", optional = true, default-features = false } ff = { version = "0.9", optional = true, default-features = false } +funty = { version = "=1.1.0", default-features = false } # see https://github.com/bitvecto-rs/bitvec/issues/105 group = { version = "0.9", optional = true, default-features = false } hex-literal = { version = "0.3", optional = true } generic-array = { version = "0.14", default-features = false } From ecf3352b99d0c9563afa012b0c070881665eab6e Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 16 Feb 2021 19:54:28 -0800 Subject: [PATCH 0442/1461] elliptic-curve v0.9.3 (#551) --- Cargo.lock | 2 +- elliptic-curve/CHANGELOG.md | 12 +++++++++++- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 2 +- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d93100ae2..637738449 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -180,7 +180,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.9.2" +version = "0.9.3" dependencies = [ "base64ct", "ff", diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index f9923d37d..fc28c6483 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,7 +4,17 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 0.9.2 (2021-02-12) +## 0.9.3 (2021-02-16) +### Changed +- Bump `pkcs8` dependency to v0.5.0 ([#549]) + +### Fixed +- Workaround for bitvecto-rs/bitvec#105 ([#550]) + +[#549]: https://github.com/RustCrypto/traits/pull/549 +[#550]: https://github.com/RustCrypto/traits/pull/550 + +## 0.9.2 (2021-02-12) [YANKED] ### Changed - Flatten `weierstrass` module ([#542]) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 2a691392e..2f293472f 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -5,7 +5,7 @@ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. """ -version = "0.9.2" # Also update html_root_url in lib.rs when bumping this +version = "0.9.3" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" repository = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve" diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 4d1e1f20f..1d71cce66 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -16,7 +16,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.9.2" + html_root_url = "https://docs.rs/elliptic-curve/0.9.3" )] #[cfg(feature = "alloc")] From 090c08939158809bbbdef1baf0c0cbd82a6ce647 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 17 Feb 2021 16:10:06 -0800 Subject: [PATCH 0443/1461] ci: add `override: true` to clippy and rustfmt (#555) We intended to run clippy at lowest MSRV, but this directive was accidentally omitted leading to unintended breakages when new `stable` releases added new lints: https://github.com/RustCrypto/traits/pull/554/checks?check_run_id=1922987991 --- .github/workflows/workspace.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index 87efa633d..a90364c20 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -16,10 +16,12 @@ jobs: - uses: actions/checkout@v1 - uses: actions-rs/toolchain@v1 with: - profile: minimal - toolchain: 1.44.0 # Highest MSRV in repo + toolchain: 1.47.0 # Highest MSRV in repo components: clippy + override: true + profile: minimal - run: cargo clippy --all --all-features -- -D warnings + rustfmt: runs-on: ubuntu-latest steps: @@ -29,9 +31,10 @@ jobs: - name: Install stable toolchain uses: actions-rs/toolchain@v1 with: - profile: minimal toolchain: stable components: rustfmt + override: true + profile: minimal - name: Run cargo fmt uses: actions-rs/cargo@v1 From e0ae7495c508538ad8b80bce4e00e549dc2d4e6a Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 17 Feb 2021 16:15:20 -0800 Subject: [PATCH 0444/1461] elliptic-curve v0.8.5 (#554) Note: this commit only adds release notes. The real release is tagged here: https://github.com/RustCrypto/traits/tree/elliptic-curve-v0.8.5 --- elliptic-curve/CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index fc28c6483..cde138088 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -54,6 +54,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [#532]: https://github.com/RustCrypto/traits/pull/532 [#534]: https://github.com/RustCrypto/traits/pull/534 +## 0.8.5 (2021-02-17) +### Fixed +- Workaround for bitvecto-rs/bitvec#105 ([#553]) + +[#553]: https://github.com/RustCrypto/traits/pull/553 + ## 0.8.4 (2020-12-23) ### Fixed - Rust `nightly` regression ([#432]) From ab8229829832ad621543d72f2263383d8edaad79 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 18 Feb 2021 20:21:13 -0800 Subject: [PATCH 0445/1461] elliptic-curve: bump `pkcs8` dependency to v0.5.1 (#556) --- Cargo.lock | 12 ++++++------ elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/public_key.rs | 2 +- elliptic-curve/src/secret_key/pkcs8.rs | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 637738449..e7ce39b9d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -153,9 +153,9 @@ dependencies = [ [[package]] name = "der" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b70f809fb1678da4d5ea334095cbe8d6c64fea35fc52836db6c241caee68e17e" +checksum = "c59822d0b3c6c83d3419a6caa1b47cfefe3c494074bdc0ee95db7a52284d21e4" dependencies = [ "const-oid", ] @@ -320,9 +320,9 @@ dependencies = [ [[package]] name = "pkcs8" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cef7f3bd1bd1bb7b347609085a8ef84e326de2e400bc2b53eba16f77a3dc5bfb" +checksum = "7f3e7a05338645bdc206ac5b5883d9050ed3351776eebd577e5b15e7ca019811" dependencies = [ "base64ct", "der", @@ -425,9 +425,9 @@ dependencies = [ [[package]] name = "spki" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc22de9c8a841f9508de9f6849b018d414199e4682cc094e5677286c81de80f8" +checksum = "48250aa51181e87d253cfbef4f3652a90fa5fb9395970309c7afc01a6f860df0" dependencies = [ "der", ] diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 2f293472f..f65b3e8df 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -21,7 +21,7 @@ funty = { version = "=1.1.0", default-features = false } # see https://github.c group = { version = "0.9", optional = true, default-features = false } hex-literal = { version = "0.3", optional = true } generic-array = { version = "0.14", default-features = false } -pkcs8 = { version = "0.5", optional = true } +pkcs8 = { version = "0.5.1", optional = true } rand_core = { version = "0.6", default-features = false } serde = { version = "1", optional = true, default-features = false } serde_json = { version = "1", optional = true, default-features = false, features = ["alloc"] } diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index a0684c39d..3d6ec106d 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -329,7 +329,7 @@ where UncompressedPointSize: ArrayLength, { fn from_spki(spki: pkcs8::SubjectPublicKeyInfo<'_>) -> pkcs8::Result { - if spki.algorithm.oid != ALGORITHM_OID || spki.algorithm.parameters_oid() != Some(C::OID) { + if spki.algorithm.oid != ALGORITHM_OID || spki.algorithm.parameters_oid()? != C::OID { return Err(pkcs8::Error::Decode); } diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs index 164f72b18..603ba95e8 100644 --- a/elliptic-curve/src/secret_key/pkcs8.rs +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -50,7 +50,7 @@ where private_key_info: pkcs8::PrivateKeyInfo<'_>, ) -> pkcs8::Result { if private_key_info.algorithm.oid != ALGORITHM_OID - || private_key_info.algorithm.parameters_oid() != Some(C::OID) + || private_key_info.algorithm.parameters_oid()? != C::OID { return Err(pkcs8::Error::Decode); } From bbded2b4450172573128e3576c6327bb1845b9a2 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 18 Feb 2021 20:34:32 -0800 Subject: [PATCH 0446/1461] elliptic-curve v0.9.4 (#557) --- Cargo.lock | 2 +- elliptic-curve/CHANGELOG.md | 8 +++++++- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e7ce39b9d..de597740a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -180,7 +180,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.9.3" +version = "0.9.4" dependencies = [ "base64ct", "ff", diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index cde138088..be4f4e3ba 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,7 +4,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 0.9.3 (2021-02-16) +## 0.9.4 (2021-02-18) +### Fixed +- Breakage related to the `pkcs8` v0.5.1 crate ([#556]) + +[#556]: https://github.com/RustCrypto/traits/pull/556 + +## 0.9.3 (2021-02-16) [YANKED] ### Changed - Bump `pkcs8` dependency to v0.5.0 ([#549]) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index f65b3e8df..9f3045b16 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -5,7 +5,7 @@ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. """ -version = "0.9.3" # Also update html_root_url in lib.rs when bumping this +version = "0.9.4" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" repository = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve" diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 1d71cce66..9dcef89f0 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -16,7 +16,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.9.3" + html_root_url = "https://docs.rs/elliptic-curve/0.9.4" )] #[cfg(feature = "alloc")] From ff0b23ffe220a4580114a41bf3a4cda45cf921b7 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 20 Feb 2021 08:51:14 -0800 Subject: [PATCH 0447/1461] Cargo.lock: bump dependencies (#558) --- Cargo.lock | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index de597740a..0ac70a8d1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -116,9 +116,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5d82796b70971fbb603900a5edc797a4d9be0f9ec1257f83a1dba0aa374e3e9" +checksum = "a7e8dd5eab3bedc0f623f388e724eee9a880b3d297430e8685672e338f449a27" [[package]] name = "cpuid-bool" @@ -153,9 +153,9 @@ dependencies = [ [[package]] name = "der" -version = "0.2.5" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c59822d0b3c6c83d3419a6caa1b47cfefe3c494074bdc0ee95db7a52284d21e4" +checksum = "eeaef572ca60433089d994bca0bef5d728f37d1530c5bbee4d0d8121aeab69e5" dependencies = [ "const-oid", ] @@ -318,14 +318,25 @@ dependencies = [ "rand_core", ] +[[package]] +name = "pkcs5" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "321f456f11e455766fc424a5a1b86e6d2478a9ba40f12a06c6afc8cef33ec1d1" +dependencies = [ + "der", + "spki", +] + [[package]] name = "pkcs8" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f3e7a05338645bdc206ac5b5883d9050ed3351776eebd577e5b15e7ca019811" +checksum = "fbe017f30ae5cc01d2d0e24d8d3bcfdd63bc719c6cdc2b97e974fd933d8c7e15" dependencies = [ "base64ct", "der", + "pkcs5", "spki", "zeroize", ] From 22d456ba72e4a4162ca50df546f78e0f91e9fb77 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 22 Feb 2021 12:44:05 -0800 Subject: [PATCH 0448/1461] Cargo.lock: bump dependencies (#559) --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0ac70a8d1..5783c3f94 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -153,9 +153,9 @@ dependencies = [ [[package]] name = "der" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eeaef572ca60433089d994bca0bef5d728f37d1530c5bbee4d0d8121aeab69e5" +checksum = "ff87fc4cc42439753d09185278bb1fdee4710b5b295159cdc0789563528e776f" dependencies = [ "const-oid", ] @@ -436,9 +436,9 @@ dependencies = [ [[package]] name = "spki" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48250aa51181e87d253cfbef4f3652a90fa5fb9395970309c7afc01a6f860df0" +checksum = "b8b07e839e486ce2c6120ace6660ed71e4891eb8c88d52eecdf141e1b70effea" dependencies = [ "der", ] From 8898b8b97b20d595ee8948e7952118975f5215bb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 24 Feb 2021 05:13:08 -0800 Subject: [PATCH 0449/1461] build(deps): bump pkcs8 from 0.5.2 to 0.5.3 (#560) Bumps [pkcs8](https://github.com/RustCrypto/utils) from 0.5.2 to 0.5.3. - [Release notes](https://github.com/RustCrypto/utils/releases) - [Commits](https://github.com/RustCrypto/utils/compare/pkcs8-v0.5.2...pkcs8-v0.5.3) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 15 ++------------- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5783c3f94..3b1b1d2f4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -318,25 +318,14 @@ dependencies = [ "rand_core", ] -[[package]] -name = "pkcs5" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "321f456f11e455766fc424a5a1b86e6d2478a9ba40f12a06c6afc8cef33ec1d1" -dependencies = [ - "der", - "spki", -] - [[package]] name = "pkcs8" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbe017f30ae5cc01d2d0e24d8d3bcfdd63bc719c6cdc2b97e974fd933d8c7e15" +checksum = "6f5c4e8bd205d0d87542f13cab77a091f5cfb221592b885dfa0b2b915031a4b4" dependencies = [ "base64ct", "der", - "pkcs5", "spki", "zeroize", ] diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 9f3045b16..c17a144c1 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -21,7 +21,7 @@ funty = { version = "=1.1.0", default-features = false } # see https://github.c group = { version = "0.9", optional = true, default-features = false } hex-literal = { version = "0.3", optional = true } generic-array = { version = "0.14", default-features = false } -pkcs8 = { version = "0.5.1", optional = true } +pkcs8 = { version = "0.5.3", optional = true } rand_core = { version = "0.6", default-features = false } serde = { version = "1", optional = true, default-features = false } serde_json = { version = "1", optional = true, default-features = false, features = ["alloc"] } From 0b458af31a568cb7a6285c1a47b079edf631381d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 24 Feb 2021 12:29:54 -0800 Subject: [PATCH 0450/1461] elliptic-curve: use string-based OID constants (#561) Uses the new const-friendly OID string parser added in: https://github.com/RustCrypto/utils/pull/312 --- Cargo.lock | 4 ++-- elliptic-curve/src/dev.rs | 2 +- elliptic-curve/src/lib.rs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3b1b1d2f4..751f4d749 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -116,9 +116,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7e8dd5eab3bedc0f623f388e724eee9a880b3d297430e8685672e338f449a27" +checksum = "fb27bc55bac783b7cfd5eafba8a3e94ff6d420fc4e04970a207980683145af83" [[package]] name = "cpuid-bool" diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 741b4fd39..2d1f94247 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -49,7 +49,7 @@ impl ProjectiveArithmetic for MockCurve { impl AlgorithmParameters for MockCurve { /// OID for NIST P-256 - const OID: pkcs8::ObjectIdentifier = pkcs8::ObjectIdentifier::new(&[1, 2, 840, 10045, 3, 1, 7]); + const OID: pkcs8::ObjectIdentifier = pkcs8::ObjectIdentifier::parse("1.2.840.10045.3.1.7"); } #[cfg(feature = "jwk")] diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 9dcef89f0..78d3539c4 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -93,7 +93,7 @@ use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; #[cfg(feature = "pkcs8")] #[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))] pub const ALGORITHM_OID: pkcs8::ObjectIdentifier = - pkcs8::ObjectIdentifier::new(&[1, 2, 840, 10045, 2, 1]); + pkcs8::ObjectIdentifier::parse("1.2.840.10045.2.1"); /// Elliptic curve. /// From a57a8d386351694f5ce18da1386300cca16bdb33 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Feb 2021 06:02:48 -0800 Subject: [PATCH 0451/1461] build(deps): bump pkcs8 from 0.5.3 to 0.5.4 (#562) Bumps [pkcs8](https://github.com/RustCrypto/utils) from 0.5.3 to 0.5.4. - [Release notes](https://github.com/RustCrypto/utils/releases) - [Commits](https://github.com/RustCrypto/utils/compare/pkcs8-v0.5.3...pkcs8-v0.5.4) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 751f4d749..2e1841482 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -320,9 +320,9 @@ dependencies = [ [[package]] name = "pkcs8" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f5c4e8bd205d0d87542f13cab77a091f5cfb221592b885dfa0b2b915031a4b4" +checksum = "8ecfab38c6d0f60db6a80b1ee75f1fc980193f9963c43ee2d6f0ac6698e71d96" dependencies = [ "base64ct", "der", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index c17a144c1..9f70f476b 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -21,7 +21,7 @@ funty = { version = "=1.1.0", default-features = false } # see https://github.c group = { version = "0.9", optional = true, default-features = false } hex-literal = { version = "0.3", optional = true } generic-array = { version = "0.14", default-features = false } -pkcs8 = { version = "0.5.3", optional = true } +pkcs8 = { version = "0.5.4", optional = true } rand_core = { version = "0.6", default-features = false } serde = { version = "1", optional = true, default-features = false } serde_json = { version = "1", optional = true, default-features = false, features = ["alloc"] } From 77e0fc2c56674f606b5abfedd9eb2b5962446f4a Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Fri, 26 Feb 2021 12:47:03 +0000 Subject: [PATCH 0452/1461] Add crypto-common crate (#537) --- .github/workflows/crypto-common.yml | 57 ++++++++ .github/workflows/crypto-mac.yml | 10 +- Cargo.lock | 20 ++- Cargo.toml | 4 + cipher/Cargo.toml | 3 +- cipher/src/block.rs | 117 +++++++++++----- cipher/src/common.rs | 94 ------------- cipher/src/errors.rs | 16 +-- cipher/src/lib.rs | 4 +- crypto-common/Cargo.toml | 22 +++ crypto-common/LICENSE-APACHE | 201 ++++++++++++++++++++++++++++ crypto-common/LICENSE-MIT | 25 ++++ crypto-common/README.md | 53 ++++++++ crypto-common/src/core_api.rs | 132 ++++++++++++++++++ crypto-common/src/lib.rs | 174 ++++++++++++++++++++++++ crypto-mac/Cargo.toml | 5 +- crypto-mac/src/core_api.rs | 2 + crypto-mac/src/errors.rs | 27 ---- crypto-mac/src/lib.rs | 112 ++++------------ digest/Cargo.toml | 9 +- digest/src/core_api.rs | 59 ++++---- digest/src/core_api/ct_variable.rs | 18 ++- digest/src/core_api/rt_variable.rs | 4 +- digest/src/core_api/update.rs | 96 ------------- digest/src/core_api/xof_reader.rs | 2 +- digest/src/dev.rs | 56 +++++++- digest/src/digest.rs | 42 +++--- digest/src/dyn_digest.rs | 4 +- digest/src/lib.rs | 53 +------- 29 files changed, 936 insertions(+), 485 deletions(-) create mode 100644 .github/workflows/crypto-common.yml delete mode 100644 cipher/src/common.rs create mode 100644 crypto-common/Cargo.toml create mode 100644 crypto-common/LICENSE-APACHE create mode 100644 crypto-common/LICENSE-MIT create mode 100644 crypto-common/README.md create mode 100644 crypto-common/src/core_api.rs create mode 100644 crypto-common/src/lib.rs create mode 100644 crypto-mac/src/core_api.rs delete mode 100644 crypto-mac/src/errors.rs delete mode 100644 digest/src/core_api/update.rs diff --git a/.github/workflows/crypto-common.yml b/.github/workflows/crypto-common.yml new file mode 100644 index 000000000..3a91ff660 --- /dev/null +++ b/.github/workflows/crypto-common.yml @@ -0,0 +1,57 @@ +name: crypto-common + +on: + pull_request: + paths: + - "crypto-common/**" + - "Cargo.*" + push: + branches: master + +defaults: + run: + working-directory: crypto-common + +env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + rust: + - 1.41.0 # MSRV + - stable + target: + - thumbv7em-none-eabi + - wasm32-unknown-unknown + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.rust }} + target: ${{ matrix.target }} + override: true + - run: cargo build --no-default-features --release --target ${{ matrix.target }} + test: + runs-on: ubuntu-latest + strategy: + matrix: + rust: + - 1.41.0 # MSRV + - stable + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.rust }} + - run: cargo check --all-features + - run: cargo test + - run: cargo test --features core-api + - run: cargo test --features rand_core + - run: cargo test --features std + - run: cargo test --all-features diff --git a/.github/workflows/crypto-mac.yml b/.github/workflows/crypto-mac.yml index 5336c0319..15caa59ed 100644 --- a/.github/workflows/crypto-mac.yml +++ b/.github/workflows/crypto-mac.yml @@ -52,8 +52,8 @@ jobs: profile: minimal toolchain: ${{ matrix.rust }} - run: cargo check --all-features - - run: cargo test --release - - run: cargo test --features cipher --release - - run: cargo test --features dev --release - - run: cargo test --features std --release - - run: cargo test --all-features --release + - run: cargo test + - run: cargo test --features core-api + - run: cargo test --features dev + - run: cargo test --features std + - run: cargo test --all-features diff --git a/Cargo.lock b/Cargo.lock index 2e1841482..3ca909455 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -77,8 +77,7 @@ dependencies = [ [[package]] name = "block-buffer" version = "0.10.0-pre.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bda843099271fe07dc9638389268bf732e981d8a71d7a1472f79eb54cc5a827" +source = "git+https://github.com/RustCrypto/utils?branch=master#47b80c33dd1d83d02426152f681ab2c3acd7e40e" dependencies = [ "block-padding", "generic-array 0.14.4", @@ -87,8 +86,7 @@ dependencies = [ [[package]] name = "block-padding" version = "0.3.0-pre" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3992d179d1dd2fa87869057217d43cf88ad31d4e44738d159a5a6caafdf63ae6" +source = "git+https://github.com/RustCrypto/utils?branch=master#47b80c33dd1d83d02426152f681ab2c3acd7e40e" dependencies = [ "generic-array 0.14.4", ] @@ -110,6 +108,7 @@ name = "cipher" version = "0.3.0-pre.4" dependencies = [ "blobby", + "crypto-common", "generic-array 0.14.4", "rand_core", ] @@ -140,12 +139,21 @@ dependencies = [ "universal-hash", ] +[[package]] +name = "crypto-common" +version = "0.1.0" +dependencies = [ + "block-buffer 0.10.0-pre.2", + "generic-array 0.14.4", + "rand_core", +] + [[package]] name = "crypto-mac" version = "0.11.0-pre" dependencies = [ "blobby", - "cipher", + "crypto-common", "generic-array 0.14.4", "rand_core", "subtle", @@ -174,7 +182,7 @@ name = "digest" version = "0.10.0-pre.3" dependencies = [ "blobby", - "block-buffer 0.10.0-pre.2", + "crypto-common", "generic-array 0.14.4", ] diff --git a/Cargo.toml b/Cargo.toml index 9db9bf636..95aa71a0a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,6 +2,7 @@ members = [ "aead", "cipher", + "crypto-common", "crypto-mac", "crypto", "digest", @@ -11,3 +12,6 @@ members = [ "signature/async", "universal-hash", ] + +[patch.crates-io] +block-buffer = { git = "https://github.com/RustCrypto/utils", branch = "master" } diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index b13ee47f4..5ca5e8736 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -13,12 +13,13 @@ categories = ["cryptography", "no-std"] [dependencies] generic-array = "0.14" +crypto-common = { version = "0.1", path = "../crypto-common/" } blobby = { version = "0.3", optional = true } rand_core = { version = "0.6", optional = true } [features] -std = [] +std = ["crypto-common/std"] dev = ["blobby"] [package.metadata.docs.rs] diff --git a/cipher/src/block.rs b/cipher/src/block.rs index 0e39ff90f..30076ba16 100644 --- a/cipher/src/block.rs +++ b/cipher/src/block.rs @@ -9,15 +9,12 @@ //! [1]: https://en.wikipedia.org/wiki/Block_cipher //! [2]: https://en.wikipedia.org/wiki/Symmetric-key_algorithm -use crate::errors::InvalidLength; use core::convert::TryInto; +use crypto_common::FromKey; use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; -#[cfg(feature = "rand_core")] -use rand_core::{CryptoRng, RngCore}; - -/// Key for an algorithm that implements [`NewBlockCipher`]. -pub type BlockCipherKey = GenericArray::KeySize>; +/// Key for an algorithm that implements [`FromKey`]. +pub type BlockCipherKey = GenericArray::KeySize>; /// Block on which a [`BlockCipher`] operates. pub type Block = GenericArray::BlockSize>; @@ -25,36 +22,6 @@ pub type Block = GenericArray::BlockSize>; /// Block on which a [`BlockCipher`] operates in parallel. pub type ParBlocks = GenericArray, ::ParBlocks>; -/// Instantiate a [`BlockCipher`] algorithm. -pub trait NewBlockCipher: Sized { - /// Key size in bytes with which cipher guaranteed to be initialized. - type KeySize: ArrayLength; - - /// Create new block cipher instance from key with fixed size. - fn new(key: &BlockCipherKey) -> Self; - - /// Create new block cipher instance from key with variable size. - /// - /// Default implementation will accept only keys with length equal to - /// `KeySize`, but some ciphers can accept range of key lengths. - fn new_from_slice(key: &[u8]) -> Result { - if key.len() != Self::KeySize::to_usize() { - Err(InvalidLength) - } else { - Ok(Self::new(GenericArray::from_slice(key))) - } - } - - /// Generate a random key for this block cipher using the provided [`CryptoRng`]. - #[cfg(feature = "rand_core")] - #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] - fn generate_key(mut rng: impl CryptoRng + RngCore) -> BlockCipherKey { - let mut key = BlockCipherKey::::default(); - rng.fill_bytes(&mut key); - key - } -} - /// Trait which marks a type as being a block cipher. pub trait BlockCipher { /// Size of the block in bytes @@ -209,3 +176,81 @@ impl BlockDecrypt for &Alg { Alg::decrypt_blocks(self, blocks); } } + +/// Trait for types which can be initialized from a block cipher and nonce. +pub trait FromBlockCipherNonce { + /// Block cipher + type BlockCipher: BlockCipher; + /// Nonce size in bytes + type NonceSize: ArrayLength; + + /// Instantiate a stream cipher from a block cipher + fn from_block_cipher_nonce( + cipher: Self::BlockCipher, + nonce: &GenericArray, + ) -> Self; +} + +/// Implement [`FromKeyNonce`][crate::FromKeyNonce] for a type which implements [`FromBlockCipherNonce`]. +#[macro_export] +macro_rules! impl_from_key_nonce { + ($name:ty) => { + impl crate::FromKeyNonce for $name + where + Self: FromBlockCipherNonce, + ::BlockCipher: FromKey, + { + type KeySize = <::BlockCipher as FromKey>::KeySize; + type NonceSize = ::NonceSize; + + fn new( + key: &GenericArray, + nonce: &GenericArray, + ) -> Self { + let cipher = ::BlockCipher::new(key); + Self::from_block_cipher_nonce(cipher, nonce) + } + + fn new_from_slices( + key: &[u8], + nonce: &[u8], + ) -> Result { + use crate::errors::InvalidLength; + if nonce.len() != Self::NonceSize::USIZE { + Err(InvalidLength) + } else { + ::BlockCipher::new_from_slice(key) + .map_err(|_| InvalidLength) + .map(|cipher| { + let nonce = GenericArray::from_slice(nonce); + Self::from_block_cipher_nonce(cipher, nonce) + }) + } + } + } + }; +} + +/// Implement [`FromKey`] for a type which implements [`From`][From], +/// where `C` implements [`FromKey`]. +#[macro_export] +macro_rules! impl_from_key { + ($name:ty) => { + impl cipher::FromKey for $name + where + Self: From, + { + type KeySize = C::KeySize; + + fn new(key: &GenericArray) -> Self { + C::new(key).into() + } + + fn new_from_slice(key: &[u8]) -> Result { + C::new_from_slice(key) + .map_err(|_| cipher::errors::InvalidLength) + .map(|cipher| cipher.into()) + } + } + }; +} diff --git a/cipher/src/common.rs b/cipher/src/common.rs deleted file mode 100644 index 849cd95be..000000000 --- a/cipher/src/common.rs +++ /dev/null @@ -1,94 +0,0 @@ -//! Functionality common to block ciphers and stream ciphers - -use crate::{errors::InvalidLength, BlockCipher, NewBlockCipher}; -use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; - -#[cfg(feature = "rand_core")] -use rand_core::{CryptoRng, RngCore}; - -/// Key for an algorithm that implements [`NewCipher`]. -pub type CipherKey = GenericArray::KeySize>; - -/// Nonce for an algorithm that implements [`NewCipher`]. -pub type Nonce = GenericArray::NonceSize>; - -/// Cipher creation trait. -/// -/// It can be used for creation of block modes, synchronous and asynchronous stream ciphers. -pub trait NewCipher: Sized { - /// Key size in bytes - type KeySize: ArrayLength; - - /// Nonce size in bytes - type NonceSize: ArrayLength; - - /// Create new stream cipher instance from key and nonce arrays. - fn new(key: &CipherKey, nonce: &Nonce) -> Self; - - /// Create new stream cipher instance from variable length key and nonce - /// given as byte slices. - #[inline] - fn new_from_slices(key: &[u8], nonce: &[u8]) -> Result { - let kl = Self::KeySize::to_usize(); - let nl = Self::NonceSize::to_usize(); - if key.len() != kl || nonce.len() != nl { - Err(InvalidLength) - } else { - let key = GenericArray::from_slice(key); - let nonce = GenericArray::from_slice(nonce); - Ok(Self::new(key, nonce)) - } - } - - /// Generate a random key for this cipher using the provided [`CryptoRng`]. - #[cfg(feature = "rand_core")] - #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] - fn generate_key(mut rng: impl CryptoRng + RngCore) -> CipherKey { - let mut key = CipherKey::::default(); - rng.fill_bytes(&mut key); - key - } -} - -/// Trait for types which can be initialized from a block cipher and nonce. -pub trait FromBlockCipher { - /// Block cipher - type BlockCipher: BlockCipher; - /// Nonce size in bytes - type NonceSize: ArrayLength; - - /// Instantiate a stream cipher from a block cipher - fn from_block_cipher( - cipher: Self::BlockCipher, - nonce: &GenericArray, - ) -> Self; -} - -impl NewCipher for C -where - C: FromBlockCipher, - C::BlockCipher: NewBlockCipher, -{ - type KeySize = <::BlockCipher as NewBlockCipher>::KeySize; - type NonceSize = ::NonceSize; - - fn new(key: &CipherKey, nonce: &Nonce) -> C { - C::from_block_cipher( - <::BlockCipher as NewBlockCipher>::new(key), - nonce, - ) - } - - fn new_from_slices(key: &[u8], nonce: &[u8]) -> Result { - if nonce.len() != Self::NonceSize::USIZE { - Err(InvalidLength) - } else { - C::BlockCipher::new_from_slice(key) - .map_err(|_| InvalidLength) - .map(|cipher| { - let nonce = GenericArray::from_slice(nonce); - Self::from_block_cipher(cipher, nonce) - }) - } - } -} diff --git a/cipher/src/errors.rs b/cipher/src/errors.rs index 69235fceb..6dbb5eb25 100644 --- a/cipher/src/errors.rs +++ b/cipher/src/errors.rs @@ -2,6 +2,8 @@ use core::fmt; +pub use crypto_common::InvalidLength; + /// The error type returned when stream cipher has reached the end of a keystream. #[derive(Copy, Clone, Debug)] pub struct LoopError; @@ -15,20 +17,6 @@ impl fmt::Display for LoopError { #[cfg(feature = "std")] impl std::error::Error for LoopError {} -/// The error type returned when key and/or nonce used in stream cipher -/// initialization had an invalid length. -#[derive(Copy, Clone, Debug)] -pub struct InvalidLength; - -impl fmt::Display for InvalidLength { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - f.write_str("Invalid Length") - } -} - -#[cfg(feature = "std")] -impl std::error::Error for InvalidLength {} - /// The error type returned when a cipher position can not be represented /// by the requested type. #[derive(Copy, Clone, Debug)] diff --git a/cipher/src/lib.rs b/cipher/src/lib.rs index a8fc29795..d565f64ea 100644 --- a/cipher/src/lib.rs +++ b/cipher/src/lib.rs @@ -20,11 +20,11 @@ extern crate std; pub use blobby; mod block; -mod common; #[cfg(feature = "dev")] mod dev; pub mod errors; mod stream; -pub use crate::{block::*, common::*, stream::*}; +pub use crate::{block::*, stream::*}; +pub use crypto_common::{FromKey, FromKeyNonce}; pub use generic_array::{self, typenum::consts}; diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml new file mode 100644 index 000000000..460aa92b6 --- /dev/null +++ b/crypto-common/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "crypto-common" +description = "Common cryptographic traits" +version = "0.1.0" +authors = ["RustCrypto Developers"] +license = "MIT OR Apache-2.0" +readme = "README.md" +edition = "2018" +documentation = "https://docs.rs/crypto-common" +repository = "https://github.com/RustCrypto/traits" +keywords = ["crypto", "traits"] +categories = ["cryptography", "no-std"] + +[dependencies] +generic-array = "0.14" +rand_core = { version = "0.6", optional = true } +block-buffer = { version = "0.10.0-pre.2", optional = true } + +[features] +block-padding = ["block-buffer/block-padding"] +core-api = ["block-buffer"] +std = [] diff --git a/crypto-common/LICENSE-APACHE b/crypto-common/LICENSE-APACHE new file mode 100644 index 000000000..78173fa2e --- /dev/null +++ b/crypto-common/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/crypto-common/LICENSE-MIT b/crypto-common/LICENSE-MIT new file mode 100644 index 000000000..efb0b5f8b --- /dev/null +++ b/crypto-common/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2021 RustCrypto Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/crypto-common/README.md b/crypto-common/README.md new file mode 100644 index 000000000..70ca758cd --- /dev/null +++ b/crypto-common/README.md @@ -0,0 +1,53 @@ +# RustCrypto: Common Cryptographic Traits + +[![crate][crate-image]][crate-link] +[![Docs][docs-image]][docs-link] +![Apache2/MIT licensed][license-image] +![Rust Version][rustc-image] +[![Project Chat][chat-image]][chat-link] +[![Build Status][build-image]][build-link] + +Common traits used by cryptographic algorithms. Users should generally use +higher-level trait crates instead of this one. + +[Documentation][docs-link] + +## Minimum Supported Rust Version + +Rust **1.41** or higher. + +Minimum supported Rust version can be changed in the future, but it will be +done with a minor version bump. + +## SemVer Policy + +- All on-by-default features of this library are covered by SemVer +- MSRV is considered exempt from SemVer as noted above + +## License + +Licensed under either of: + + * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) + * [MIT license](http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall be +dual licensed as above, without any additional terms or conditions. + +[//]: # (badges) + +[crate-image]: https://img.shields.io/crates/v/crypto-common.svg +[crate-link]: https://crates.io/crates/crypto-common +[docs-image]: https://docs.rs/crypto-common/badge.svg +[docs-link]: https://docs.rs/crypto-common/ +[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg +[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg +[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260041-hashes +[build-image]: https://github.com/RustCrypto/traits/workflows/crypto-common/badge.svg?branch=master&event=push +[build-link]: https://github.com/RustCrypto/traits/actions?query=workflow%3Acrypto-common diff --git a/crypto-common/src/core_api.rs b/crypto-common/src/core_api.rs new file mode 100644 index 000000000..7def7a076 --- /dev/null +++ b/crypto-common/src/core_api.rs @@ -0,0 +1,132 @@ +//! Low-level core API traits. +use super::{FixedOutput, FixedOutputReset, Reset, Update}; +use block_buffer::DigestBuffer; +use core::fmt; +use generic_array::{ArrayLength, GenericArray}; + +/// Trait for types which consume data in blocks. +#[cfg(feature = "core-api")] +#[cfg_attr(docsrs, doc(cfg(feature = "core-api")))] +pub trait UpdateCore { + /// Block size in bytes. + type BlockSize: ArrayLength; + /// Block buffer type over which value operates. + type Buffer: DigestBuffer; + + /// Update state using the provided data blocks. + fn update_blocks(&mut self, blocks: &[GenericArray]); +} + +/// Core trait for hash functions with fixed output size. +#[cfg(feature = "core-api")] +#[cfg_attr(docsrs, doc(cfg(feature = "core-api")))] +pub trait FixedOutputCore: UpdateCore { + /// Size of result in bytes. + type OutputSize: ArrayLength; + + /// Finalize state using remaining data stored in the provided block buffer, + /// write result into provided array using and leave value in a dirty state. + fn finalize_fixed_core( + &mut self, + buffer: &mut Self::Buffer, + out: &mut GenericArray, + ); +} + +/// Trait which stores algorithm name constant, used in `Debug` implementations. +pub trait AlgorithmName { + /// Write algorithm name into `f`. + fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result; +} + +/// Wrapper around [`UpdateCore`] implementations. +/// +/// It handles data buffering and implements the slice-based traits. +#[derive(Clone, Default)] +pub struct CoreWrapper { + core: T, + buffer: T::Buffer, +} + +impl CoreWrapper { + /// Create new wrapper from `core`. + #[inline] + pub fn from_core(core: T) -> Self { + let buffer = Default::default(); + Self { core, buffer } + } + + /// Decompose wrapper into inner parts. + #[inline] + pub fn decompose(self) -> (T, T::Buffer) { + let Self { core, buffer } = self; + (core, buffer) + } +} + +impl CoreWrapper { + /// Apply function to core and buffer, return its result, + /// and reset core and buffer. + pub fn apply_reset(&mut self, mut f: impl FnMut(&mut T, &mut T::Buffer) -> V) -> V { + let Self { core, buffer } = self; + let res = f(core, buffer); + core.reset(); + buffer.reset(); + res + } +} + +impl fmt::Debug for CoreWrapper { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + T::write_alg_name(f)?; + f.write_str(" { .. }") + } +} + +impl Reset for CoreWrapper { + #[inline] + fn reset(&mut self) { + self.core.reset(); + self.buffer.reset(); + } +} + +impl Update for CoreWrapper { + #[inline] + fn update(&mut self, input: &[u8]) { + let Self { core, buffer } = self; + buffer.digest_blocks(input, |blocks| core.update_blocks(blocks)); + } +} + +impl FixedOutput for CoreWrapper { + type OutputSize = D::OutputSize; + + #[inline] + fn finalize_into(mut self, out: &mut GenericArray) { + let Self { core, buffer } = &mut self; + core.finalize_fixed_core(buffer, out); + } +} + +impl FixedOutputReset for CoreWrapper { + #[inline] + fn finalize_into_reset(&mut self, out: &mut GenericArray) { + self.apply_reset(|core, buffer| core.finalize_fixed_core(buffer, out)); + } +} + +#[cfg(feature = "std")] +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] +impl std::io::Write for CoreWrapper { + #[inline] + fn write(&mut self, buf: &[u8]) -> std::io::Result { + Update::update(self, buf); + Ok(buf.len()) + } + + #[inline] + fn flush(&mut self) -> std::io::Result<()> { + Ok(()) + } +} diff --git a/crypto-common/src/lib.rs b/crypto-common/src/lib.rs new file mode 100644 index 000000000..0189872cc --- /dev/null +++ b/crypto-common/src/lib.rs @@ -0,0 +1,174 @@ +//! Common cryptographic traits. + +#![no_std] +#![cfg_attr(docsrs, feature(doc_cfg))] +#![doc( + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" +)] +#![forbid(unsafe_code)] +#![warn(missing_docs, rust_2018_idioms)] + +#[cfg(feature = "std")] +extern crate std; + +use core::fmt; +use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; +#[cfg(feature = "rand_core")] +use rand_core::{CryptoRng, RngCore}; + +#[cfg(feature = "core-api")] +#[cfg_attr(docsrs, doc(cfg(feature = "core-api")))] +pub use block_buffer; + +#[cfg(feature = "core-api")] +#[cfg_attr(docsrs, doc(cfg(feature = "core-api")))] +pub mod core_api; + +/// Trait for types which can be created from key and nonce. +pub trait FromKeyNonce: Sized { + /// Key size in bytes. + type KeySize: ArrayLength; + + /// Nonce size in bytes. + type NonceSize: ArrayLength; + + /// Create new value from fixed length key and nonce. + fn new( + key: &GenericArray, + nonce: &GenericArray, + ) -> Self; + + /// Create new value from variable length key and nonce. + #[inline] + fn new_from_slices(key: &[u8], nonce: &[u8]) -> Result { + let kl = Self::KeySize::to_usize(); + let nl = Self::NonceSize::to_usize(); + if key.len() != kl || nonce.len() != nl { + Err(InvalidLength) + } else { + let key = GenericArray::from_slice(key); + let nonce = GenericArray::from_slice(nonce); + Ok(Self::new(key, nonce)) + } + } + + /// Generate a random key using the provided [`CryptoRng`]. + #[cfg(feature = "rand_core")] + #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] + #[inline] + fn generate_key(mut rng: impl CryptoRng + RngCore) -> GenericArray { + let mut key = GenericArray::::default(); + rng.fill_bytes(&mut key); + key + } + + /// Generate a random nonce using the provided [`CryptoRng`]. + #[cfg(feature = "rand_core")] + #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] + #[inline] + fn generate_nonce(mut rng: impl CryptoRng + RngCore) -> GenericArray { + let mut nonce = GenericArray::::default(); + rng.fill_bytes(&mut nonce); + nonce + } + + /// Generate random key and nonce using the provided [`CryptoRng`]. + #[cfg(feature = "rand_core")] + #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] + #[inline] + fn generate_key_nonce( + mut rng: impl CryptoRng + RngCore, + ) -> ( + GenericArray, + GenericArray, + ) { + (Self::generate_key(&mut rng), Self::generate_nonce(&mut rng)) + } +} + +/// Trait for types which can be created from key. +pub trait FromKey: Sized { + /// Key size in bytes. + type KeySize: ArrayLength; + + /// Create new value from fixed size key. + fn new(key: &GenericArray) -> Self; + + /// Create new value from variable size key. + fn new_from_slice(key: &[u8]) -> Result { + if key.len() != Self::KeySize::to_usize() { + Err(InvalidLength) + } else { + Ok(Self::new(GenericArray::from_slice(key))) + } + } + + /// Generate a random key using the provided [`CryptoRng`]. + #[cfg(feature = "rand_core")] + #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] + #[inline] + fn generate_key(mut rng: impl CryptoRng + RngCore) -> GenericArray { + let mut key = GenericArray::::default(); + rng.fill_bytes(&mut key); + key + } +} + +/// Trait for types which consume data. +pub trait Update { + /// Update state using the provided data. + fn update(&mut self, data: &[u8]); +} + +/// Trait for types which return fixed-sized result after finalization. +pub trait FixedOutput: Sized { + /// Size of result in bytes. + type OutputSize: ArrayLength; + + /// Consume value and write result into provided array. + fn finalize_into(self, out: &mut GenericArray); + + /// Retrieve result and consume the hasher instance. + #[inline] + fn finalize_fixed(self) -> GenericArray { + let mut out = Default::default(); + self.finalize_into(&mut out); + out + } +} + +/// Trait for types which return fixed-sized result after finalization and reset +/// values into its initial state. +pub trait FixedOutputReset: FixedOutput + Reset { + /// Write result into provided array and reset value to its initial state. + fn finalize_into_reset(&mut self, out: &mut GenericArray); + + /// Retrieve result and reset the hasher instance. + #[inline] + fn finalize_fixed_reset(&mut self) -> GenericArray { + let mut out = Default::default(); + self.finalize_into_reset(&mut out); + out + } +} + +/// Trait for resetting values to initial state. +pub trait Reset { + /// Reset value to its initial state. + fn reset(&mut self); +} + +/// The error type returned when key and/or nonce used in [`FromKey`] +/// or [`FromKeyNonce`] slice-based methods had an invalid length. +#[derive(Copy, Clone, Eq, PartialEq, Debug)] +pub struct InvalidLength; + +impl fmt::Display for InvalidLength { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + f.write_str("Invalid Length") + } +} + +#[cfg(feature = "std")] +impl std::error::Error for InvalidLength {} diff --git a/crypto-mac/Cargo.toml b/crypto-mac/Cargo.toml index 12a2036aa..8168c2bdc 100644 --- a/crypto-mac/Cargo.toml +++ b/crypto-mac/Cargo.toml @@ -13,15 +13,16 @@ categories = ["cryptography", "no-std"] [dependencies] generic-array = "0.14" +crypto-common = { version = "0.1", path = "../crypto-common/" } subtle = { version = "2", default-features = false } blobby = { version = "0.3", optional = true } -cipher = { version = "=0.3.0-pre.4", optional = true, path = "../cipher" } rand_core = { version = "0.6", optional = true } [features] dev = ["blobby"] -std = [] +core-api = ["crypto-common/core-api"] +std = ["crypto-common/std"] [package.metadata.docs.rs] all-features = true diff --git a/crypto-mac/src/core_api.rs b/crypto-mac/src/core_api.rs new file mode 100644 index 000000000..7f7e6a6ec --- /dev/null +++ b/crypto-mac/src/core_api.rs @@ -0,0 +1,2 @@ +//! Low-level core API traits. +pub use crypto_common::core_api::{AlgorithmName, CoreWrapper, FixedOutputCore, UpdateCore}; diff --git a/crypto-mac/src/errors.rs b/crypto-mac/src/errors.rs deleted file mode 100644 index 7bcb0fd34..000000000 --- a/crypto-mac/src/errors.rs +++ /dev/null @@ -1,27 +0,0 @@ -use core::fmt; - -/// Error type for signaling failed MAC verification -#[derive(Default, Debug, Copy, Clone, Eq, PartialEq)] -pub struct MacError; - -/// Error type for signaling invalid key length for MAC initialization -#[derive(Default, Debug, Copy, Clone, Eq, PartialEq)] -pub struct InvalidKeyLength; - -impl fmt::Display for MacError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str("failed MAC verification") - } -} - -impl fmt::Display for InvalidKeyLength { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str("invalid key length") - } -} - -#[cfg(feature = "std")] -impl std::error::Error for MacError {} - -#[cfg(feature = "std")] -impl std::error::Error for InvalidKeyLength {} diff --git a/crypto-mac/src/lib.rs b/crypto-mac/src/lib.rs index 543129f8c..e9db92242 100644 --- a/crypto-mac/src/lib.rs +++ b/crypto-mac/src/lib.rs @@ -21,72 +21,35 @@ use cipher::{BlockCipher, NewBlockCipher}; #[cfg_attr(docsrs, doc(cfg(feature = "dev")))] pub mod dev; -mod errors; +#[cfg(feature = "core-api")] +#[cfg_attr(docsrs, doc(cfg(feature = "core-api")))] +pub mod core_api; -pub use crate::errors::{InvalidKeyLength, MacError}; +pub use crypto_common::{FixedOutput, FixedOutputReset, FromKey, InvalidLength, Reset, Update}; pub use generic_array::{self, typenum::consts}; -use generic_array::typenum::Unsigned; -use generic_array::{ArrayLength, GenericArray}; +use core::fmt; +use generic_array::GenericArray; use subtle::{Choice, ConstantTimeEq}; -#[cfg(feature = "rand_core")] -use rand_core::{CryptoRng, RngCore}; - -/// Key for an algorithm that implements [`NewMac`]. -pub type Key = GenericArray::KeySize>; - -/// Instantiate a [`Mac`] algorithm. -pub trait NewMac: Sized { - /// Key size in bytes with which cipher guaranteed to be initialized. - type KeySize: ArrayLength; - - /// Initialize new MAC instance from key with fixed size. - fn new(key: &Key) -> Self; - - /// Initialize new MAC instance from key with variable size. - /// - /// Default implementation will accept only keys with length equal to - /// `KeySize`, but some MACs can accept range of key lengths. - fn new_from_slice(key: &[u8]) -> Result { - if key.len() != Self::KeySize::to_usize() { - Err(InvalidKeyLength) - } else { - Ok(Self::new(GenericArray::from_slice(key))) - } - } - - /// Generate a random key for this MAC using the provided [`CryptoRng`]. - #[cfg(feature = "rand_core")] - #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] - fn generate_key(mut rng: impl CryptoRng + RngCore) -> Key { - let mut key = Key::::default(); - rng.fill_bytes(&mut key); - key - } -} - -/// The [`Mac`] trait defines methods for a Message Authentication algorithm. -pub trait Mac: Clone { - /// Output size of the [[`Mac`]] - type OutputSize: ArrayLength; - - /// Update MAC state with the given data. - fn update(&mut self, data: &[u8]); - - /// Reset [`Mac`] instance. - fn reset(&mut self); +/// Key for an algorithm that implements [`FromKey`]. +pub type Key = GenericArray::KeySize>; +/// Convinience super-trait covering functionality of Message Authentication algorithms. +pub trait Mac: FromKey + Update + FixedOutput { /// Obtain the result of a [`Mac`] computation as a [`Output`] and consume /// [`Mac`] instance. - fn finalize(self) -> Output; + fn finalize(self) -> Output { + Output::new(self.finalize_fixed()) + } /// Obtain the result of a [`Mac`] computation as a [`Output`] and reset /// [`Mac`] instance. - fn finalize_reset(&mut self) -> Output { - let res = self.clone().finalize(); - self.reset(); - res + fn finalize_reset(&mut self) -> Output + where + Self: FixedOutputReset, + { + Output::new(self.finalize_fixed_reset()) } /// Check if tag/code value is correct for the processed input. @@ -101,6 +64,8 @@ pub trait Mac: Clone { } } +impl Mac for T {} + /// [`Output`] is a thin wrapper around bytes array which provides a safe `Eq` /// implementation that runs in a fixed time. #[derive(Clone)] @@ -138,34 +103,15 @@ impl PartialEq for Output { impl Eq for Output {} -#[cfg(feature = "cipher")] -#[cfg_attr(docsrs, doc(cfg(feature = "cipher")))] -/// Trait for MAC functions which can be created from block cipher. -pub trait FromBlockCipher { - /// Block cipher type - type Cipher: BlockCipher; - - /// Create new MAC isntance from provided block cipher. - fn from_cipher(cipher: Self::Cipher) -> Self; -} +/// Error type for signaling failed MAC verification +#[derive(Default, Debug, Copy, Clone, Eq, PartialEq)] +pub struct MacError; -#[cfg(feature = "cipher")] -#[cfg_attr(docsrs, doc(cfg(feature = "cipher")))] -impl NewMac for T -where - T: FromBlockCipher, - T::Cipher: NewBlockCipher, -{ - type KeySize = <::Cipher as NewBlockCipher>::KeySize; - - fn new(key: &Key) -> Self { - let cipher = ::Cipher::new(key); - Self::from_cipher(cipher) - } - - fn new_from_slice(key: &[u8]) -> Result { - ::Cipher::new_from_slice(key) - .map_err(|_| InvalidKeyLength) - .map(Self::from_cipher) +impl fmt::Display for MacError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("failed MAC verification") } } + +#[cfg(feature = "std")] +impl std::error::Error for MacError {} diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 90c050642..d1a884dee 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -13,15 +13,16 @@ categories = ["cryptography", "no-std"] [dependencies] generic-array = "0.14" +crypto-common = { version = "0.1", path = "../crypto-common/" } + blobby = { version = "0.3", optional = true } -block-buffer = { version = "0.10.0-pre.1", optional = true } [features] alloc = [] -std = ["alloc"] +std = ["alloc", "crypto-common/std"] dev = ["blobby"] -core-api = ["block-buffer"] -block-padding = ["block-buffer/block-padding"] +core-api = ["crypto-common/core-api"] +block-padding = ["crypto-common/block-padding"] [package.metadata.docs.rs] all-features = true diff --git a/digest/src/core_api.rs b/digest/src/core_api.rs index e08a131a5..63e573d33 100644 --- a/digest/src/core_api.rs +++ b/digest/src/core_api.rs @@ -4,42 +4,19 @@ //! core algorithm wrapped by the wrapper types, which implement the //! higher-level traits. use crate::InvalidOutputSize; -use core::fmt; +use crate::{ExtendableOutput, Reset}; use generic_array::{ArrayLength, GenericArray}; +pub use crypto_common::core_api::{AlgorithmName, CoreWrapper, FixedOutputCore, UpdateCore}; + mod ct_variable; mod rt_variable; -mod update; mod xof_reader; pub use ct_variable::CtVariableCoreWrapper; pub use rt_variable::RtVariableCoreWrapper; -pub use update::UpdateCoreWrapper; pub use xof_reader::XofReaderCoreWrapper; -/// Trait for updating hasher state with input data divided into blocks. -pub trait UpdateCore { - /// Block size in bytes. - type BlockSize: ArrayLength; - - /// Update the hasher state using the provided data. - fn update_blocks(&mut self, blocks: &[GenericArray]); -} - -/// Core trait for hash functions with fixed output size. -pub trait FixedOutputCore: UpdateCore { - /// Digest output size in bytes. - type OutputSize: ArrayLength; - - /// Retrieve result into provided buffer using remaining data stored - /// in the block buffer and leave hasher in a dirty state. - fn finalize_fixed_core( - &mut self, - buffer: &mut block_buffer::BlockBuffer, - out: &mut GenericArray, - ); -} - /// Core trait for hash functions with extendable (XOF) output size. pub trait ExtendableOutputCore: UpdateCore { /// XOF reader core state. @@ -47,10 +24,7 @@ pub trait ExtendableOutputCore: UpdateCore { /// Retrieve XOF reader using remaining data stored in the block buffer /// and leave hasher in a dirty state. - fn finalize_xof_core( - &mut self, - buffer: &mut block_buffer::BlockBuffer, - ) -> Self::ReaderCore; + fn finalize_xof_core(&mut self, buffer: &mut Self::Buffer) -> Self::ReaderCore; } /// Core reader trait for extendable-output function (XOF) result. @@ -78,14 +52,29 @@ pub trait VariableOutputCore: UpdateCore + Sized { /// `output_size` must be equal to `output_size` used during construction. fn finalize_variable_core( &mut self, - buffer: &mut block_buffer::BlockBuffer, + buffer: &mut Self::Buffer, output_size: usize, f: impl FnOnce(&[u8]), ); } -/// Trait which stores algorithm name constant, used in `Debug` implementations. -pub trait AlgorithmName { - /// Write algorithm name into `f`. - fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result; +impl ExtendableOutput for CoreWrapper { + type Reader = XofReaderCoreWrapper; + + #[inline] + fn finalize_xof(self) -> Self::Reader { + let (mut core, mut buffer) = self.decompose(); + let core = core.finalize_xof_core(&mut buffer); + let buffer = Default::default(); + Self::Reader { core, buffer } + } + + #[inline] + fn finalize_xof_reset(&mut self) -> Self::Reader { + self.apply_reset(|core, buffer| { + let core = core.finalize_xof_core(buffer); + let buffer = Default::default(); + Self::Reader { core, buffer } + }) + } } diff --git a/digest/src/core_api/ct_variable.rs b/digest/src/core_api/ct_variable.rs index e4e154bfa..11474326f 100644 --- a/digest/src/core_api/ct_variable.rs +++ b/digest/src/core_api/ct_variable.rs @@ -1,5 +1,4 @@ -use super::{AlgorithmName, FixedOutputCore, UpdateCore, VariableOutputCore}; -use block_buffer::BlockBuffer; +use super::{AlgorithmName, FixedOutputCore, Reset, UpdateCore, VariableOutputCore}; use core::{fmt, marker::PhantomData}; use generic_array::{ typenum::{IsLessOrEqual, LeEq, NonZero}, @@ -26,6 +25,7 @@ where LeEq: NonZero, { type BlockSize = T::BlockSize; + type Buffer = T::Buffer; #[inline] fn update_blocks(&mut self, blocks: &[GenericArray]) { @@ -44,7 +44,7 @@ where #[inline] fn finalize_fixed_core( &mut self, - buffer: &mut BlockBuffer, + buffer: &mut Self::Buffer, out: &mut GenericArray, ) { self.inner @@ -67,6 +67,18 @@ where } } +impl Reset for CtVariableCoreWrapper +where + T: VariableOutputCore, + OutSize: ArrayLength + IsLessOrEqual, + LeEq: NonZero, +{ + #[inline] + fn reset(&mut self) { + *self = Default::default(); + } +} + impl AlgorithmName for CtVariableCoreWrapper where T: VariableOutputCore + AlgorithmName, diff --git a/digest/src/core_api/rt_variable.rs b/digest/src/core_api/rt_variable.rs index 5e7ceb3e0..c9af06ae3 100644 --- a/digest/src/core_api/rt_variable.rs +++ b/digest/src/core_api/rt_variable.rs @@ -1,7 +1,7 @@ use super::{AlgorithmName, UpdateCore, VariableOutputCore}; use crate::{InvalidOutputSize, Reset, Update, VariableOutput}; -use block_buffer::BlockBuffer; use core::fmt; +use crypto_common::block_buffer::DigestBuffer; use generic_array::typenum::Unsigned; /// Wrapper around [`VariableOutputCore`] which selects output size @@ -12,7 +12,7 @@ where T: VariableOutputCore + UpdateCore, { core: T, - buffer: BlockBuffer, + buffer: T::Buffer, output_size: usize, } diff --git a/digest/src/core_api/update.rs b/digest/src/core_api/update.rs deleted file mode 100644 index 67a8ffc49..000000000 --- a/digest/src/core_api/update.rs +++ /dev/null @@ -1,96 +0,0 @@ -use super::{ - AlgorithmName, ExtendableOutputCore, FixedOutputCore, UpdateCore, XofReaderCoreWrapper, -}; -use crate::{ExtendableOutput, FixedOutput, Reset, Update}; -use block_buffer::BlockBuffer; -use core::fmt; -use generic_array::GenericArray; - -/// Wrapper around [`UpdateCore`] implementations. -/// -/// It handles data buffering and implements the mid-level traits. -#[derive(Clone, Default)] -pub struct UpdateCoreWrapper { - core: T, - buffer: BlockBuffer, -} - -impl fmt::Debug for UpdateCoreWrapper { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - T::write_alg_name(f)?; - f.write_str(" { .. }") - } -} - -impl Reset for UpdateCoreWrapper { - #[inline] - fn reset(&mut self) { - self.core = Default::default(); - self.buffer.reset(); - } -} - -impl Update for UpdateCoreWrapper { - #[inline] - fn update(&mut self, input: &[u8]) { - let Self { core, buffer } = self; - buffer.digest_blocks(input, |blocks| core.update_blocks(blocks)); - } -} - -impl FixedOutput for UpdateCoreWrapper { - type OutputSize = D::OutputSize; - - #[inline] - fn finalize_into(mut self, out: &mut GenericArray) { - let Self { core, buffer } = &mut self; - core.finalize_fixed_core(buffer, out); - } - - #[inline] - fn finalize_into_reset(&mut self, out: &mut GenericArray) { - let Self { core, buffer } = self; - core.finalize_fixed_core(buffer, out); - self.reset(); - } -} - -impl ExtendableOutput for UpdateCoreWrapper { - type Reader = XofReaderCoreWrapper; - - #[inline] - fn finalize_xof(mut self) -> Self::Reader { - let Self { core, buffer } = &mut self; - let reader_core = core.finalize_xof_core(buffer); - XofReaderCoreWrapper { - core: reader_core, - buffer: Default::default(), - } - } - - #[inline] - fn finalize_xof_reset(&mut self) -> Self::Reader { - let Self { core, buffer } = self; - let reader_core = core.finalize_xof_core(buffer); - self.reset(); - XofReaderCoreWrapper { - core: reader_core, - buffer: Default::default(), - } - } -} - -#[cfg(feature = "std")] -#[cfg_attr(docsrs, doc(cfg(feature = "std")))] -impl std::io::Write for UpdateCoreWrapper { - #[inline] - fn write(&mut self, buf: &[u8]) -> std::io::Result { - Update::update(self, buf); - Ok(buf.len()) - } - - #[inline] - fn flush(&mut self) -> std::io::Result<()> { - Ok(()) - } -} diff --git a/digest/src/core_api/xof_reader.rs b/digest/src/core_api/xof_reader.rs index 2942e0627..5d7b83520 100644 --- a/digest/src/core_api/xof_reader.rs +++ b/digest/src/core_api/xof_reader.rs @@ -1,7 +1,7 @@ use super::{AlgorithmName, XofReaderCore}; use crate::XofReader; -use block_buffer::BlockBuffer; use core::fmt; +use crypto_common::block_buffer::BlockBuffer; /// Wrapper around [`XofReaderCore`] implementations. /// diff --git a/digest/src/dev.rs b/digest/src/dev.rs index 6799fea90..926ebbd53 100644 --- a/digest/src/dev.rs +++ b/digest/src/dev.rs @@ -2,7 +2,7 @@ pub use blobby; -use super::{ExtendableOutput, Reset, Update, XofReader}; +use super::{ExtendableOutput, Reset, Update, VariableOutput, XofReader}; use core::fmt::Debug; /// Define test @@ -33,13 +33,13 @@ macro_rules! new_test { /// Module to separate Digest from other traits mod foo { - use super::super::Digest; + use super::super::{Digest, Reset}; use core::fmt::Debug; /// Digest test pub fn digest_test(input: &[u8], output: &[u8]) -> Option<&'static str> where - D: Digest + Debug + Clone, + D: Digest + Reset + Debug + Clone, { let mut hasher = D::new(); // Test that it works when accepting the message all at once @@ -164,6 +164,56 @@ where None } +/// Variable-output digest test +pub fn variable_test(input: &[u8], output: &[u8]) -> Option<&'static str> +where + D: Update + VariableOutput + Reset + Debug + Clone, +{ + let mut hasher = D::new(output.len()).unwrap(); + let mut buf = [0u8; 128]; + let buf = &mut buf[..output.len()]; + // Test that it works when accepting the message all at once + hasher.update(input); + let mut hasher2 = hasher.clone(); + hasher.finalize_variable(|res| buf.copy_from_slice(res)); + if buf != output { + return Some("whole message"); + } + + // Test if reset works correctly + hasher2.reset(); + hasher2.update(input); + hasher2.finalize_variable(|res| buf.copy_from_slice(res)); + if buf != output { + return Some("whole message after reset"); + } + + // Test that it works when accepting the message in pieces + let mut hasher = D::new(output.len()).unwrap(); + let len = input.len(); + let mut left = len; + while left > 0 { + let take = (left + 1) / 2; + hasher.update(&input[len - left..take + len - left]); + left -= take; + } + hasher.finalize_variable(|res| buf.copy_from_slice(res)); + if buf != output { + return Some("message in pieces"); + } + + // Test processing byte-by-byte + let mut hasher = D::new(output.len()).unwrap(); + for chunk in input.chunks(1) { + hasher.update(chunk) + } + hasher.finalize_variable(|res| buf.copy_from_slice(res)); + if buf != output { + return Some("message byte-by-byte"); + } + None +} + /// Define benchmark #[macro_export] #[cfg_attr(docsrs, doc(cfg(feature = "dev")))] diff --git a/digest/src/digest.rs b/digest/src/digest.rs index 5af6958c8..283245c33 100644 --- a/digest/src/digest.rs +++ b/digest/src/digest.rs @@ -1,4 +1,4 @@ -use super::{FixedOutput, Reset, Update}; +use super::{FixedOutput, FixedOutputReset, Update}; use generic_array::typenum::Unsigned; use generic_array::{ArrayLength, GenericArray}; @@ -22,17 +22,18 @@ pub trait Digest { /// Retrieve result and consume hasher instance. fn finalize(self) -> Output; - /// Retrieve result and reset hasher instance. - fn finalize_reset(&mut self) -> Output; - /// Write result into provided array and consume the hasher instance. fn finalize_into(self, out: &mut Output); - /// Write result into provided array and reset the hasher instance. - fn finalize_into_reset(&mut self, out: &mut Output); + /// Retrieve result and reset hasher instance. + fn finalize_reset(&mut self) -> Output + where + Self: FixedOutputReset; - /// Reset hasher instance to its initial state. - fn reset(&mut self); + /// Write result into provided array and reset the hasher instance. + fn finalize_into_reset(&mut self, out: &mut Output) + where + Self: FixedOutputReset; /// Get output size of the hasher fn output_size() -> usize; @@ -41,7 +42,7 @@ pub trait Digest { fn digest(data: impl AsRef<[u8]>) -> Output; } -impl Digest for D { +impl Digest for D { type OutputSize = ::OutputSize; #[inline] @@ -65,24 +66,25 @@ impl Digest for D { FixedOutput::finalize_fixed(self) } - #[inline] - fn finalize_reset(&mut self) -> Output { - FixedOutput::finalize_fixed_reset(self) - } - #[inline] fn finalize_into(self, out: &mut Output) { FixedOutput::finalize_into(self, out); } #[inline] - fn finalize_into_reset(&mut self, out: &mut Output) { - FixedOutput::finalize_into_reset(self, out); + fn finalize_reset(&mut self) -> Output + where + Self: FixedOutputReset, + { + FixedOutputReset::finalize_fixed_reset(self) } #[inline] - fn reset(&mut self) { - Reset::reset(self) + fn finalize_into_reset(&mut self, out: &mut Output) + where + Self: FixedOutputReset, + { + FixedOutputReset::finalize_into_reset(self, out); } #[inline] @@ -92,7 +94,9 @@ impl Digest for D { #[inline] fn digest(data: impl AsRef<[u8]>) -> Output { - Self::digest_fixed(data) + let mut hasher = Self::default(); + hasher.update(data.as_ref()); + hasher.finalize() } } diff --git a/digest/src/dyn_digest.rs b/digest/src/dyn_digest.rs index f6936badd..09408db59 100644 --- a/digest/src/dyn_digest.rs +++ b/digest/src/dyn_digest.rs @@ -1,7 +1,7 @@ use alloc::boxed::Box; use core::fmt; -use super::{FixedOutput, Reset, Update}; +use super::{FixedOutput, FixedOutputReset, Reset, Update}; use generic_array::{typenum::Unsigned, GenericArray}; /// The `DynDigest` trait is a modification of `Digest` trait suitable @@ -39,7 +39,7 @@ pub trait DynDigest { fn box_clone(&self) -> Box; } -impl DynDigest for D { +impl DynDigest for D { fn update(&mut self, data: &[u8]) { Update::update(self, data); } diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 7256974eb..0cb6de937 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -54,62 +54,15 @@ mod digest; mod dyn_digest; pub use crate::digest::{Digest, Output}; +use core::fmt; #[cfg(feature = "core-api")] #[cfg_attr(docsrs, doc(cfg(feature = "core-api")))] -pub use block_buffer; -use core::fmt; +pub use crypto_common::block_buffer; #[cfg(feature = "alloc")] pub use dyn_digest::{DynDigest, InvalidBufferLength}; -use generic_array::ArrayLength; pub use generic_array::{self, typenum::consts, GenericArray}; -/// Trait for updating hasher state with input data. -pub trait Update { - /// Update the hasher state using the provided data. - fn update(&mut self, data: &[u8]); -} - -/// Trait for resetting hasher instances -pub trait Reset { - /// Reset hasher instance to its initial state. - fn reset(&mut self); -} - -/// Trait for returning digest result with the fixed size -pub trait FixedOutput: Sized + Update + Default + Reset { - /// Output size for fixed output digest - type OutputSize: ArrayLength; - - /// Write result into provided array and consume the hasher instance. - fn finalize_into(self, out: &mut GenericArray); - - /// Write result into provided array and reset the hasher instance. - fn finalize_into_reset(&mut self, out: &mut GenericArray); - - /// Retrieve result and consume the hasher instance. - #[inline] - fn finalize_fixed(self) -> GenericArray { - let mut out = Default::default(); - self.finalize_into(&mut out); - out - } - - /// Retrieve result and reset the hasher instance. - #[inline] - fn finalize_fixed_reset(&mut self) -> GenericArray { - let mut out = Default::default(); - self.finalize_into_reset(&mut out); - out - } - - /// Compute hash of `data`. - #[inline] - fn digest_fixed(data: impl AsRef<[u8]>) -> GenericArray { - let mut hasher = Self::default(); - hasher.update(data.as_ref()); - hasher.finalize_fixed() - } -} +pub use crypto_common::{FixedOutput, FixedOutputReset, Reset, Update}; /// Trait for describing readers which are used to extract extendable output /// from XOF (extendable-output function) result. From a5a1302f7e9dea048d69403a93ae368f13e04e6a Mon Sep 17 00:00:00 2001 From: rvolgers <14318781+rvolgers@users.noreply.github.com> Date: Fri, 26 Feb 2021 16:44:56 +0100 Subject: [PATCH 0453/1461] Implement {to,char}_le_bits for MockCurve (#565) * Implement {to,char}_le_bits for MockCurve * rustfmt Co-authored-by: Ronald Volgers --- elliptic-curve/src/dev.rs | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 2d1f94247..97a734870 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -125,6 +125,26 @@ impl Field for Scalar { } } +#[cfg(target_pointer_width = "64")] +fn pack_bits(native: U256) -> ScalarBits { + native.into() +} + +#[cfg(target_pointer_width = "32")] +fn pack_bits(native: U256) -> ScalarBits { + [ + (native[0] & 0xffff_ffff) as u32, + (native[0] >> 32) as u32, + (native[1] & 0xffff_ffff) as u32, + (native[1] >> 32) as u32, + (native[2] & 0xffff_ffff) as u32, + (native[2] >> 32) as u32, + (native[3] & 0xffff_ffff) as u32, + (native[3] >> 32) as u32, + ] + .into() +} + impl PrimeField for Scalar { type Repr = FieldBytes; @@ -171,7 +191,7 @@ impl PrimeField for Scalar { } fn to_le_bits(&self) -> ScalarBits { - unimplemented!(); + pack_bits(self.0) } fn is_odd(&self) -> bool { @@ -179,7 +199,7 @@ impl PrimeField for Scalar { } fn char_le_bits() -> ScalarBits { - unimplemented!(); + pack_bits(MODULUS) } fn multiplicative_generator() -> Self { From 134ca6bf0ea1c09dfbb8356f85d90e8325179731 Mon Sep 17 00:00:00 2001 From: rvolgers <14318781+rvolgers@users.noreply.github.com> Date: Fri, 26 Feb 2021 21:37:37 +0100 Subject: [PATCH 0454/1461] Implement one() for mock scalar (#566) Co-authored-by: Ronald Volgers --- elliptic-curve/src/dev.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 97a734870..252c14019 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -99,7 +99,7 @@ impl Field for Scalar { } fn one() -> Self { - unimplemented!(); + Self([1, 0, 0, 0]) } fn is_zero(&self) -> bool { From f6a4c5932aac8f52f400be406d473833b51321bb Mon Sep 17 00:00:00 2001 From: David Drysdale Date: Sun, 28 Feb 2021 17:19:40 +0000 Subject: [PATCH 0455/1461] crypto-mac: add new_trunc_test macro (#568) --- crypto-mac/src/dev.rs | 60 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/crypto-mac/src/dev.rs b/crypto-mac/src/dev.rs index 16ed20d66..1c397e631 100644 --- a/crypto-mac/src/dev.rs +++ b/crypto-mac/src/dev.rs @@ -55,6 +55,66 @@ macro_rules! new_test { }; } +/// Define test that allows for truncated tag. +#[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] +macro_rules! new_trunc_test { + ($name:ident, $test_name:expr, $mac:ty) => { + #[test] + fn $name() { + use crypto_mac::dev::blobby::Blob3Iterator; + use crypto_mac::generic_array::typenum::Unsigned; + use crypto_mac::{Mac, NewMac}; + + fn run_test(key: &[u8], input: &[u8], tag: &[u8]) -> Option<&'static str> { + let mut mac = <$mac as NewMac>::new_from_slice(key).unwrap(); + mac.update(input); + let result = mac.finalize_reset(); + let mut len = <$mac as Mac>::OutputSize::to_usize(); + if tag.len() < len { + len = tag.len(); + } + if &result.into_bytes()[..len] != tag { + return Some("whole message"); + } + // test if reset worked correctly + mac.update(input); + let result = mac.finalize(); + if &result.into_bytes()[..len] != tag { + return Some("after reset"); + } + + let mut mac = <$mac as NewMac>::new_from_slice(key).unwrap(); + // test reading byte by byte + for i in 0..input.len() { + mac.update(&input[i..i + 1]); + } + let result = mac.finalize(); + if &result.into_bytes()[..len] != tag { + return Some("message byte-by-byte"); + } + None + } + + let data = include_bytes!(concat!("data/", $test_name, ".blb")); + + for (i, row) in Blob3Iterator::new(data).unwrap().enumerate() { + let [key, input, tag] = row.unwrap(); + if let Some(desc) = run_test(key, input, tag) { + panic!( + "\n\ + Failed test №{}: {}\n\ + key:\t{:?}\n\ + input:\t{:?}\n\ + tag:\t{:?}\n", + i, desc, key, input, tag, + ); + } + } + } + }; +} + /// Define benchmark #[macro_export] #[cfg_attr(docsrs, doc(cfg(feature = "dev")))] From 8ead31bb38d1fbe7c415784bd7ae75290cc4c30d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 Mar 2021 04:20:22 -0800 Subject: [PATCH 0456/1461] build(deps): bump heapless from 0.6.0 to 0.6.1 (#572) Bumps [heapless](https://github.com/japaric/heapless) from 0.6.0 to 0.6.1. - [Release notes](https://github.com/japaric/heapless/releases) - [Changelog](https://github.com/japaric/heapless/blob/master/CHANGELOG.md) - [Commits](https://github.com/japaric/heapless/compare/v0.6.0...v0.6.1) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3ca909455..fc9a779a5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12,12 +12,12 @@ dependencies = [ [[package]] name = "as-slice" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb4d1c23475b74e3672afa8c2be22040b8b7783ad9b461021144ed10a46bb0e6" +checksum = "45403b49e3954a4b8428a0ac21a4b7afadccf92bfd96273f1a58cd4812496ae0" dependencies = [ - "generic-array 0.12.3", - "generic-array 0.13.2", + "generic-array 0.12.4", + "generic-array 0.13.3", "generic-array 0.14.4", "stable_deref_trait", ] @@ -223,18 +223,18 @@ checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" [[package]] name = "generic-array" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" +checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" dependencies = [ "typenum", ] [[package]] name = "generic-array" -version = "0.13.2" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ed1e761351b56f54eb9dcd0cfaca9fd0daecf93918e1cfc01c8a3d26ee7adcd" +checksum = "f797e67af32588215eaaab8327027ee8e71b9dd0b2b26996aedf20c030fce309" dependencies = [ "typenum", ] @@ -271,9 +271,9 @@ dependencies = [ [[package]] name = "heapless" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efb22866f8416bc2b65389ebcb8b48e1be541650c44063ea1288d04bcf903808" +checksum = "634bd4d29cbf24424d0a4bfcbf80c6960129dc24424752a7d1d1390607023422" dependencies = [ "as-slice", "generic-array 0.14.4", From b875d250f634c492d6f9c080d75763d9d616ccc9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 5 Mar 2021 05:46:39 -0800 Subject: [PATCH 0457/1461] build(deps): bump async-trait from 0.1.42 to 0.1.43 (#574) Bumps [async-trait](https://github.com/dtolnay/async-trait) from 0.1.42 to 0.1.43. - [Release notes](https://github.com/dtolnay/async-trait/releases) - [Commits](https://github.com/dtolnay/async-trait/compare/0.1.42...0.1.43) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fc9a779a5..b8df65a26 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -32,9 +32,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.42" +version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d3a45e77e34375a7923b1e8febb049bb011f064714a8e17a1a616fef01da13d" +checksum = "b6287685011f026b98d26afd53251ad0101e856531b423eb2384265f7d4f5b01" dependencies = [ "proc-macro2", "quote", @@ -454,9 +454,9 @@ checksum = "1e81da0851ada1f3e9d4312c704aa4f8806f0f9d69faaf8df2f3464b4a9437c2" [[package]] name = "syn" -version = "1.0.60" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c700597eca8a5a762beb35753ef6b94df201c81cca676604f547495a0d7f0081" +checksum = "ed22b90a0e734a23a7610f4283ac9e5acfb96cbb30dfefa540d66f866f1c09c5" dependencies = [ "proc-macro2", "quote", From 616b14f5523e491e43d2b618f2f31286a3d80937 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 5 Mar 2021 05:46:52 -0800 Subject: [PATCH 0458/1461] build(deps): bump serde_json from 1.0.62 to 1.0.64 (#569) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.62 to 1.0.64. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.62...v1.0.64) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b8df65a26..302566ef3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -388,9 +388,9 @@ checksum = "92d5161132722baa40d802cc70b15262b98258453e85e5d1d365c757c73869ae" [[package]] name = "serde_json" -version = "1.0.62" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea1c6153794552ea7cf7cf63b1231a25de00ec90db326ba6264440fa08e31486" +checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" dependencies = [ "itoa", "ryu", From 3f45bf64850f8b94326c88a86b59e239d29634ef Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 5 Mar 2021 07:37:36 -0800 Subject: [PATCH 0459/1461] digest: allow DynDigest usage without `alloc` enabled (#573) Moves `alloc`-based gating for `DynDigest` to just the methods that use `Box`, which enables usage of the trait in "heapless" environments. Closes #545 --- digest/src/digest.rs | 6 ++++-- digest/src/dyn_digest.rs | 32 ++++++++++++++++++++++++++------ digest/src/lib.rs | 2 -- 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/digest/src/digest.rs b/digest/src/digest.rs index 283245c33..7c277c9a6 100644 --- a/digest/src/digest.rs +++ b/digest/src/digest.rs @@ -4,8 +4,10 @@ use generic_array::{ArrayLength, GenericArray}; /// The `Digest` trait specifies an interface common for digest functions. /// -/// It's a convenience wrapper around [`Update`], [`FixedOutput`], [`Reset`], -/// [`Clone`], and [`Default`] traits. It also provides additional convenience methods. +/// It's a convenience wrapper around [`Update`], [`FixedOutput`], +/// [`Reset`][`crate::Reset`], [`Clone`], and [`Default`] traits. +/// +/// It also provides additional convenience methods. pub trait Digest { /// Output size for `Digest` type OutputSize: ArrayLength; diff --git a/digest/src/dyn_digest.rs b/digest/src/dyn_digest.rs index 09408db59..ecafe7945 100644 --- a/digest/src/dyn_digest.rs +++ b/digest/src/dyn_digest.rs @@ -1,12 +1,12 @@ -use alloc::boxed::Box; -use core::fmt; - use super::{FixedOutput, FixedOutputReset, Reset, Update}; +use core::fmt; use generic_array::{typenum::Unsigned, GenericArray}; +#[cfg(feature = "alloc")] +use alloc::boxed::Box; + /// The `DynDigest` trait is a modification of `Digest` trait suitable /// for trait objects. -#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] pub trait DynDigest { /// Digest input data. /// @@ -14,10 +14,23 @@ pub trait DynDigest { fn update(&mut self, data: &[u8]); /// Retrieve result and reset hasher instance - fn finalize_reset(&mut self) -> Box<[u8]>; + #[cfg(feature = "alloc")] + #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] + fn finalize_reset(&mut self) -> Box<[u8]> { + let mut result = vec![0; self.output_size()]; + self.finalize_into_reset(&mut result).unwrap(); + result.into_boxed_slice() + } /// Retrieve result and consume boxed hasher instance - fn finalize(self: Box) -> Box<[u8]>; + #[cfg(feature = "alloc")] + #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] + #[allow(clippy::boxed_local)] + fn finalize(mut self: Box) -> Box<[u8]> { + let mut result = vec![0; self.output_size()]; + self.finalize_into_reset(&mut result).unwrap(); + result.into_boxed_slice() + } /// Write result into provided array and consume the hasher instance. /// @@ -36,6 +49,8 @@ pub trait DynDigest { fn output_size(&self) -> usize; /// Clone hasher state into a boxed trait object + #[cfg(feature = "alloc")] + #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] fn box_clone(&self) -> Box; } @@ -44,10 +59,12 @@ impl DynDigest for D { Update::update(self, data); } + #[cfg(feature = "alloc")] fn finalize_reset(&mut self) -> Box<[u8]> { self.finalize_fixed_reset().to_vec().into_boxed_slice() } + #[cfg(feature = "alloc")] fn finalize(self: Box) -> Box<[u8]> { self.finalize_fixed().to_vec().into_boxed_slice() } @@ -78,11 +95,14 @@ impl DynDigest for D { ::OutputSize::to_usize() } + #[cfg(feature = "alloc")] fn box_clone(&self) -> Box { Box::new(self.clone()) } } +#[cfg(feature = "alloc")] +#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] impl Clone for Box { fn clone(&self) -> Self { self.box_clone() diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 0cb6de937..2991ded68 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -50,7 +50,6 @@ pub mod dev; #[cfg_attr(docsrs, doc(cfg(feature = "core-api")))] pub mod core_api; mod digest; -#[cfg(feature = "alloc")] mod dyn_digest; pub use crate::digest::{Digest, Output}; @@ -58,7 +57,6 @@ use core::fmt; #[cfg(feature = "core-api")] #[cfg_attr(docsrs, doc(cfg(feature = "core-api")))] pub use crypto_common::block_buffer; -#[cfg(feature = "alloc")] pub use dyn_digest::{DynDigest, InvalidBufferLength}; pub use generic_array::{self, typenum::consts, GenericArray}; From 94659cf355d41f2f224cb237af0c4fada197520f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Mar 2021 05:25:47 -0800 Subject: [PATCH 0460/1461] build(deps): bump base64ct from 0.2.0 to 0.2.1 (#575) Bumps [base64ct](https://github.com/RustCrypto/utils) from 0.2.0 to 0.2.1. - [Release notes](https://github.com/RustCrypto/utils/releases) - [Commits](https://github.com/RustCrypto/utils/compare/base64ct-v0.2.0...base64ct-v0.2.1) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 302566ef3..21e6a94b2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -43,9 +43,9 @@ dependencies = [ [[package]] name = "base64ct" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22fb38fd6e62e4ceec8543db40ceb714454ff173451a0f2a6c8952fdf39a2d6c" +checksum = "7b8a45dc8036c7e52889226a96edacd45831c0dbdb8b803a58b8e0e12613b1a6" [[package]] name = "bitvec" From 5d1058c0839c9cb0ad2fbc5637f81c4d2059f8fc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Mar 2021 05:27:02 -0800 Subject: [PATCH 0461/1461] build(deps): bump async-trait from 0.1.43 to 0.1.47 (#577) Bumps [async-trait](https://github.com/dtolnay/async-trait) from 0.1.43 to 0.1.47. - [Release notes](https://github.com/dtolnay/async-trait/releases) - [Commits](https://github.com/dtolnay/async-trait/compare/0.1.43...0.1.47) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 21e6a94b2..5335ee470 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -32,9 +32,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.43" +version = "0.1.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6287685011f026b98d26afd53251ad0101e856531b423eb2384265f7d4f5b01" +checksum = "7e098e9c493fdf92832223594d9a164f96bdf17ba81a42aff86f85c76768726a" dependencies = [ "proc-macro2", "quote", From dfb90dc1dce3f53fd6638ea90bd3e0172890f364 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Fri, 12 Mar 2021 15:52:10 +0300 Subject: [PATCH 0462/1461] cipher: add block mode traits and wrappers (#567) --- .github/workflows/crypto-common.yml | 1 - Cargo.lock | 9 +- Cargo.toml | 3 +- cipher/Cargo.toml | 3 + cipher/src/block.rs | 111 +++++++--------- cipher/src/errors.rs | 36 +++++- cipher/src/lib.rs | 109 +++++++++++++++- cipher/src/mode.rs | 42 ++++++ cipher/src/mode_wrapper.rs | 194 ++++++++++++++++++++++++++++ crypto-common/Cargo.toml | 1 - crypto-common/src/lib.rs | 109 +--------------- crypto-mac/Cargo.toml | 1 + crypto-mac/src/lib.rs | 3 +- 13 files changed, 438 insertions(+), 184 deletions(-) create mode 100644 cipher/src/mode.rs create mode 100644 cipher/src/mode_wrapper.rs diff --git a/.github/workflows/crypto-common.yml b/.github/workflows/crypto-common.yml index 3a91ff660..84963aaae 100644 --- a/.github/workflows/crypto-common.yml +++ b/.github/workflows/crypto-common.yml @@ -52,6 +52,5 @@ jobs: - run: cargo check --all-features - run: cargo test - run: cargo test --features core-api - - run: cargo test --features rand_core - run: cargo test --features std - run: cargo test --all-features diff --git a/Cargo.lock b/Cargo.lock index 5335ee470..a60ffc880 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,7 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "aead" version = "0.4.0" @@ -77,7 +79,7 @@ dependencies = [ [[package]] name = "block-buffer" version = "0.10.0-pre.2" -source = "git+https://github.com/RustCrypto/utils?branch=master#47b80c33dd1d83d02426152f681ab2c3acd7e40e" +source = "git+https://github.com/RustCrypto/utils?branch=block_mode#092f0d0ea4ee317d92fbaa5bfecc4433cdcdd196" dependencies = [ "block-padding", "generic-array 0.14.4", @@ -86,7 +88,7 @@ dependencies = [ [[package]] name = "block-padding" version = "0.3.0-pre" -source = "git+https://github.com/RustCrypto/utils?branch=master#47b80c33dd1d83d02426152f681ab2c3acd7e40e" +source = "git+https://github.com/RustCrypto/utils?branch=block_mode#092f0d0ea4ee317d92fbaa5bfecc4433cdcdd196" dependencies = [ "generic-array 0.14.4", ] @@ -108,6 +110,7 @@ name = "cipher" version = "0.3.0-pre.4" dependencies = [ "blobby", + "block-buffer 0.10.0-pre.2", "crypto-common", "generic-array 0.14.4", "rand_core", @@ -145,7 +148,6 @@ version = "0.1.0" dependencies = [ "block-buffer 0.10.0-pre.2", "generic-array 0.14.4", - "rand_core", ] [[package]] @@ -153,6 +155,7 @@ name = "crypto-mac" version = "0.11.0-pre" dependencies = [ "blobby", + "cipher", "crypto-common", "generic-array 0.14.4", "rand_core", diff --git a/Cargo.toml b/Cargo.toml index 95aa71a0a..b9c153fbe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,4 +14,5 @@ members = [ ] [patch.crates-io] -block-buffer = { git = "https://github.com/RustCrypto/utils", branch = "master" } +block-buffer = { git = "https://github.com/RustCrypto/utils", branch = "block_mode" } +block-padding = { git = "https://github.com/RustCrypto/utils", branch = "block_mode" } diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index 5ca5e8736..d01e925b3 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -15,11 +15,14 @@ categories = ["cryptography", "no-std"] generic-array = "0.14" crypto-common = { version = "0.1", path = "../crypto-common/" } +block-buffer = { version = "0.10.0-pre.2", features = ["block-padding"], optional = true } blobby = { version = "0.3", optional = true } rand_core = { version = "0.6", optional = true } [features] +default = ["mode_wrapper"] std = ["crypto-common/std"] +mode_wrapper = ["block-buffer"] dev = ["blobby"] [package.metadata.docs.rs] diff --git a/cipher/src/block.rs b/cipher/src/block.rs index 30076ba16..1769c782e 100644 --- a/cipher/src/block.rs +++ b/cipher/src/block.rs @@ -1,16 +1,18 @@ -//! Traits used to define functionality of [block ciphers][1]. +//! Traits used to define functionality of [block ciphers][1] and [modes of operation][2]. //! //! # About block ciphers //! //! Block ciphers are keyed, deterministic permutations of a fixed-sized input //! "block" providing a reversible transformation to/from an encrypted output. -//! They are one of the fundamental structural components of [symmetric cryptography][2]. +//! They are one of the fundamental structural components of [symmetric cryptography][3]. //! //! [1]: https://en.wikipedia.org/wiki/Block_cipher -//! [2]: https://en.wikipedia.org/wiki/Symmetric-key_algorithm +//! [2]: https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation +//! [3]: https://en.wikipedia.org/wiki/Symmetric-key_algorithm +use crate::errors::InvalidLength; +use crate::{FromKey, FromKeyNonce}; use core::convert::TryInto; -use crypto_common::FromKey; use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; /// Key for an algorithm that implements [`FromKey`]. @@ -177,80 +179,59 @@ impl BlockDecrypt for &Alg { } } +/// Trait for types which can be initialized from a block cipher. +pub trait FromBlockCipher { + /// Block cipher used for initialization. + type BlockCipher: BlockCipher; + + /// Initialize instance from block cipher. + fn from_block_cipher(cipher: Self::BlockCipher) -> Self; +} + /// Trait for types which can be initialized from a block cipher and nonce. pub trait FromBlockCipherNonce { - /// Block cipher + /// Block cipher used for initialization. type BlockCipher: BlockCipher; - /// Nonce size in bytes + /// Nonce size in bytes. type NonceSize: ArrayLength; - /// Instantiate a stream cipher from a block cipher + /// Initialize instance from block cipher and nonce. fn from_block_cipher_nonce( cipher: Self::BlockCipher, nonce: &GenericArray, ) -> Self; } -/// Implement [`FromKeyNonce`][crate::FromKeyNonce] for a type which implements [`FromBlockCipherNonce`]. -#[macro_export] -macro_rules! impl_from_key_nonce { - ($name:ty) => { - impl crate::FromKeyNonce for $name - where - Self: FromBlockCipherNonce, - ::BlockCipher: FromKey, - { - type KeySize = <::BlockCipher as FromKey>::KeySize; - type NonceSize = ::NonceSize; - - fn new( - key: &GenericArray, - nonce: &GenericArray, - ) -> Self { - let cipher = ::BlockCipher::new(key); - Self::from_block_cipher_nonce(cipher, nonce) - } +impl FromKeyNonce for T +where + T: FromBlockCipherNonce, + T::BlockCipher: FromKey, +{ + type KeySize = ::KeySize; + type NonceSize = T::NonceSize; - fn new_from_slices( - key: &[u8], - nonce: &[u8], - ) -> Result { - use crate::errors::InvalidLength; - if nonce.len() != Self::NonceSize::USIZE { - Err(InvalidLength) - } else { - ::BlockCipher::new_from_slice(key) - .map_err(|_| InvalidLength) - .map(|cipher| { - let nonce = GenericArray::from_slice(nonce); - Self::from_block_cipher_nonce(cipher, nonce) - }) - } - } - } - }; + fn new( + key: &GenericArray, + nonce: &GenericArray, + ) -> Self { + Self::from_block_cipher_nonce(T::BlockCipher::new(key), nonce) + } } -/// Implement [`FromKey`] for a type which implements [`From`][From], -/// where `C` implements [`FromKey`]. -#[macro_export] -macro_rules! impl_from_key { - ($name:ty) => { - impl cipher::FromKey for $name - where - Self: From, - { - type KeySize = C::KeySize; - - fn new(key: &GenericArray) -> Self { - C::new(key).into() - } +impl FromKey for T +where + T: FromBlockCipher, + T::BlockCipher: FromKey, +{ + type KeySize = ::KeySize; - fn new_from_slice(key: &[u8]) -> Result { - C::new_from_slice(key) - .map_err(|_| cipher::errors::InvalidLength) - .map(|cipher| cipher.into()) - } - } - }; + fn new(key: &GenericArray) -> Self { + Self::from_block_cipher(T::BlockCipher::new(key)) + } + + fn new_from_slice(key: &[u8]) -> Result { + T::BlockCipher::new_from_slice(key) + .map_err(|_| InvalidLength) + .map(Self::from_block_cipher) + } } diff --git a/cipher/src/errors.rs b/cipher/src/errors.rs index 6dbb5eb25..644495e80 100644 --- a/cipher/src/errors.rs +++ b/cipher/src/errors.rs @@ -2,8 +2,6 @@ use core::fmt; -pub use crypto_common::InvalidLength; - /// The error type returned when stream cipher has reached the end of a keystream. #[derive(Copy, Clone, Debug)] pub struct LoopError; @@ -36,3 +34,37 @@ impl From for LoopError { #[cfg(feature = "std")] impl std::error::Error for OverflowError {} + +/// The error type returned when key and/or nonce used in the [`FromKey`] +/// and [`FromKeyNonce`] slice-based methods had an invalid length. +/// +/// [`FromKey`]: crate::FromKey +/// [`FromKeyNonce`]: crate::FromKeyNonce +#[derive(Copy, Clone, Eq, PartialEq, Debug)] +pub struct InvalidLength; + +impl fmt::Display for InvalidLength { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + f.write_str("Invalid Length") + } +} + +#[cfg(feature = "std")] +impl std::error::Error for InvalidLength {} + +/// The error type returned by the [`BlockModeEncryptWrapper`] and +/// [`BlockModeDecryptWrapper`] types. +/// +/// [`BlockModeEncryptWrapper`]: crate::BlockModeEncryptWrapper +/// [`BlockModeDecryptWrapper`]: crate::BlockModeDecryptWrapper +#[derive(Copy, Clone, Eq, PartialEq, Debug)] +pub struct BlockModeError; + +impl fmt::Display for BlockModeError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + f.write_str("Invalid Length") + } +} + +#[cfg(feature = "std")] +impl std::error::Error for BlockModeError {} diff --git a/cipher/src/lib.rs b/cipher/src/lib.rs index d565f64ea..da2951d87 100644 --- a/cipher/src/lib.rs +++ b/cipher/src/lib.rs @@ -23,8 +23,113 @@ mod block; #[cfg(feature = "dev")] mod dev; pub mod errors; +mod mode; mod stream; -pub use crate::{block::*, stream::*}; -pub use crypto_common::{FromKey, FromKeyNonce}; +#[cfg(feature = "mode_wrapper")] +mod mode_wrapper; + +pub use crate::{block::*, mode::*, stream::*}; pub use generic_array::{self, typenum::consts}; +#[cfg(feature = "mode_wrapper")] +pub use mode_wrapper::{BlockModeDecryptWrapper, BlockModeEncryptWrapper}; + +use crate::errors::InvalidLength; +use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; +#[cfg(feature = "rand_core")] +use rand_core::{CryptoRng, RngCore}; + +// note: ideally the following traits would be defined in the `crypto-common` crate, +// but it would make impossible the generic impls over `T: FromBlockCipher(Nonce)` +// in the `block` module, see the following link for proposal to change it: +// https://internals.rust-lang.org/t/14125 + +/// Trait for types which can be created from key and nonce. +pub trait FromKeyNonce: Sized { + /// Key size in bytes. + type KeySize: ArrayLength; + + /// Nonce size in bytes. + type NonceSize: ArrayLength; + + /// Create new value from fixed length key and nonce. + fn new( + key: &GenericArray, + nonce: &GenericArray, + ) -> Self; + + /// Create new value from variable length key and nonce. + #[inline] + fn new_from_slices(key: &[u8], nonce: &[u8]) -> Result { + let kl = Self::KeySize::to_usize(); + let nl = Self::NonceSize::to_usize(); + if key.len() != kl || nonce.len() != nl { + Err(InvalidLength) + } else { + let key = GenericArray::from_slice(key); + let nonce = GenericArray::from_slice(nonce); + Ok(Self::new(key, nonce)) + } + } + + /// Generate a random key using the provided [`CryptoRng`]. + #[cfg(feature = "rand_core")] + #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] + #[inline] + fn generate_key(mut rng: impl CryptoRng + RngCore) -> GenericArray { + let mut key = GenericArray::::default(); + rng.fill_bytes(&mut key); + key + } + + /// Generate a random nonce using the provided [`CryptoRng`]. + #[cfg(feature = "rand_core")] + #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] + #[inline] + fn generate_nonce(mut rng: impl CryptoRng + RngCore) -> GenericArray { + let mut nonce = GenericArray::::default(); + rng.fill_bytes(&mut nonce); + nonce + } + + /// Generate random key and nonce using the provided [`CryptoRng`]. + #[cfg(feature = "rand_core")] + #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] + #[inline] + fn generate_key_nonce( + mut rng: impl CryptoRng + RngCore, + ) -> ( + GenericArray, + GenericArray, + ) { + (Self::generate_key(&mut rng), Self::generate_nonce(&mut rng)) + } +} + +/// Trait for types which can be created from key. +pub trait FromKey: Sized { + /// Key size in bytes. + type KeySize: ArrayLength; + + /// Create new value from fixed size key. + fn new(key: &GenericArray) -> Self; + + /// Create new value from variable size key. + fn new_from_slice(key: &[u8]) -> Result { + if key.len() != Self::KeySize::to_usize() { + Err(InvalidLength) + } else { + Ok(Self::new(GenericArray::from_slice(key))) + } + } + + /// Generate a random key using the provided [`CryptoRng`]. + #[cfg(feature = "rand_core")] + #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] + #[inline] + fn generate_key(mut rng: impl CryptoRng + RngCore) -> GenericArray { + let mut key = GenericArray::::default(); + rng.fill_bytes(&mut key); + key + } +} diff --git a/cipher/src/mode.rs b/cipher/src/mode.rs new file mode 100644 index 000000000..336f50cfa --- /dev/null +++ b/cipher/src/mode.rs @@ -0,0 +1,42 @@ +use crate::{BlockCipher, FromKeyNonce}; +use generic_array::{ArrayLength, GenericArray}; + +/// Trait for types which implement a block cipher [mode of operation][1]. +/// +/// [1]: https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation +pub trait BlockMode { + /// Size of the block in bytes + type BlockSize: ArrayLength; +} + +/// Trait for a block cipher mode of operation block-level encryptor. +/// +/// This trait operates only on blocks, for convinient slice-based methods with padding +/// see the [`BlockModeEncryptWrapper`][crate::BlockModeEncryptWrapper] type. +pub trait BlockModeEncrypt: BlockMode { + /// Encrypt blocks of data. + fn encrypt_blocks(&mut self, blocks: &mut [GenericArray]); +} + +/// Trait for a block cipher mode of operation block-level decryptor. +/// +/// This trait operates only on blocks, for convinient slice-based methods with padding +/// see the [`BlockModeDecryptWrapper`][crate::BlockModeDecryptWrapper] type. +pub trait BlockModeDecrypt: BlockMode { + /// Decrypt blocks of data. + fn decrypt_blocks(&mut self, blocks: &mut [GenericArray]); +} + +/// Trait for a block mode, used to obtain the current state in the form of an IV +/// that can initialize a BlockMode later and resume the original operation. +/// +/// The IV value SHOULD be used for resuming operations only and MUST NOT be +/// exposed to attackers. Failing to comply with this requirement breaks +/// unpredictability and opens attack venues (see e.g. [1], sec. 3.6.2). +/// +/// [1]: https://www.cs.umd.edu/~jkatz/imc.html +pub trait BlockModeIvState: FromKeyNonce { + /// Returns the IV needed to process the following block. This value MUST + /// NOT be exposed to attackers. + fn iv_state(&self) -> GenericArray; +} diff --git a/cipher/src/mode_wrapper.rs b/cipher/src/mode_wrapper.rs new file mode 100644 index 000000000..36f379c3e --- /dev/null +++ b/cipher/src/mode_wrapper.rs @@ -0,0 +1,194 @@ +//! Convinience wrapper around types which implement `BlockMode`. + +use crate::errors::BlockModeError; +use crate::{BlockModeDecrypt, BlockModeEncrypt, FromBlockCipherNonce}; +use block_buffer::{block_padding::Padding, BlockBuffer, LazyBlockBuffer}; +use core::{marker::PhantomData, slice::from_mut}; +use generic_array::{typenum::Unsigned, GenericArray}; + +/// Convinience wrapper around the [`BlockModeEncrypt`] trait, which handles +/// data buffering and provides slice-based methods. +pub struct BlockModeEncryptWrapper> { + inner: M, + buffer: BlockBuffer, + _p: PhantomData

, +} + +impl FromBlockCipherNonce for BlockModeEncryptWrapper +where + M: BlockModeEncrypt + FromBlockCipherNonce, + P: Padding, +{ + type BlockCipher = M::BlockCipher; + type NonceSize = M::NonceSize; + + fn from_block_cipher_nonce( + cipher: Self::BlockCipher, + nonce: &GenericArray, + ) -> Self { + Self { + inner: M::from_block_cipher_nonce(cipher, nonce), + buffer: Default::default(), + _p: Default::default(), + } + } +} + +impl BlockModeEncryptWrapper +where + M: BlockModeEncrypt, + P: Padding, +{ + /// Encrypt part of a plaintext. + /// + /// This mehthod MUST be used in conjuction with the [`encrypt_final`][Self::encrypt_final] method, + /// otherwise plaintext will not be properly padded and may be truncated. + /// + /// The method encrypts plaintext in `data`, writes the resulting plaintext + /// into `out_buf`, and returns it in the `Ok` variant. If a whole message + /// can not be processed, it caches plaintext leftovers into inner buffer + /// for future use. + /// + /// It's recommended for `out_buf` to be at least one block longer than + /// `data`, otherwise the method can return `Err(BlockModeError)` if there is + /// not enough space for encrypted blocks. + #[inline] + pub fn encrypt_part<'a>( + &mut self, + plaintext: &[u8], + out_buf: &'a mut [u8], + ) -> Result<&'a [u8], BlockModeError> { + let Self { inner, buffer, .. } = self; + buffer + .block_mode_processing(plaintext, out_buf, |blocks| inner.encrypt_blocks(blocks)) + .map_err(|_| BlockModeError) + } + + /// Pad and encrypt plaintext. + /// + /// The method pads `plaintext` and encrypts it writing the resulting + /// ciphertext into `out_buf`. + /// + /// It's recommended for `out_buf` to be at least one block longer than + /// `data`, otherwise the method can return `Err(BlockModeError)` if there is + /// not enough space for encrypted blocks. + #[inline] + pub fn encrypt_final<'a>( + mut self, + plaintext: &[u8], + out_buf: &'a mut [u8], + ) -> Result<&'a [u8], BlockModeError> { + let Self { inner, buffer, .. } = &mut self; + let res_len = buffer + .block_mode_processing(plaintext, out_buf, |blocks| inner.encrypt_blocks(blocks)) + .map_err(|_| BlockModeError)? + .len(); + let final_block = buffer.pad_with::

(); + inner.encrypt_blocks(from_mut(final_block)); + + let bs = M::BlockSize::USIZE; + let final_len = res_len.checked_add(bs).ok_or(BlockModeError)?; + let buf = out_buf.get_mut(..final_len).ok_or(BlockModeError)?; + // note: even though `buf[t..]` and `buf[res_len..]` are guaranteed to be + // equivalent, compiler generates a panic branch for the latter. + let t = final_len - bs; + debug_assert_eq!(t, res_len); + buf[t..].copy_from_slice(final_block); + Ok(buf) + } +} + +/// Convinience wrapper around the [`BlockModeDecrypt`] trait, which handles +/// data buffering and provides slice-based methods. +pub struct BlockModeDecryptWrapper> { + inner: M, + buffer: LazyBlockBuffer, + _p: PhantomData

(buf) + } + + /// Pad input and encrypt buffer-to-buffer. Returns resulting ciphertext slice. + /// + /// Returns [`PadError`] if length of output buffer is not sufficient. + #[cfg(feature = "block-padding")] + #[cfg_attr(docsrs, doc(cfg(feature = "block-padding")))] + #[inline] + fn encrypt_padded_b2b<'a, P: Padding>( + &self, + msg: &[u8], + out_buf: &'a mut [u8], + ) -> Result<&'a [u8], PadError> { + let buf = InOutBufReserved::from_slices(msg, out_buf).map_err(|_| PadError)?; + self.encrypt_padded_inout::

(buf) } } /// Decrypt-only functionality for block ciphers. -pub trait BlockDecrypt: BlockCipher { - /// Decrypt block in-place - fn decrypt_block(&self, block: &mut Block); +pub trait BlockDecrypt: BlockSizeUser { + /// Decrypt data using backend provided to the rank-2 closure. + fn decrypt_with_backend(&self, f: impl BlockClosure); - /// Decrypt several blocks in parallel using instruction level parallelism - /// if possible. - /// - /// If `ParBlocks` equals to 1 it's equivalent to `decrypt_block`. + /// Decrypt single `inout` block. #[inline] - fn decrypt_par_blocks(&self, blocks: &mut ParBlocks) { - for block in blocks.iter_mut() { - self.decrypt_block(block); - } + fn decrypt_block_inout(&self, block: InOut<'_, '_, Block>) { + self.decrypt_with_backend(BlockCtx { block }); } - /// Decrypt a slice of blocks, leveraging parallelism when available. + /// Decrypt `inout` blocks. #[inline] - fn decrypt_blocks(&self, mut blocks: &mut [Block]) { - let pb = Self::ParBlocks::to_usize(); + fn decrypt_blocks_inout(&self, blocks: InOutBuf<'_, '_, Block>) { + self.decrypt_with_backend(BlocksCtx { blocks }); + } - if pb > 1 { - let mut iter = blocks.chunks_exact_mut(pb); + /// Decrypt single block in-place. + #[inline] + fn decrypt_block(&self, block: &mut Block) { + let block = block.into(); + self.decrypt_with_backend(BlockCtx { block }); + } - for chunk in &mut iter { - self.decrypt_par_blocks(chunk.try_into().unwrap()) - } + /// Decrypt `in_block` and write result to `out_block`. + #[inline] + fn decrypt_block_b2b(&self, in_block: &Block, out_block: &mut Block) { + let block = (in_block, out_block).into(); + self.decrypt_with_backend(BlockCtx { block }); + } - blocks = iter.into_remainder(); + /// Decrypt blocks in-place. + #[inline] + fn decrypt_blocks(&self, blocks: &mut [Block]) { + let blocks = blocks.into(); + self.decrypt_with_backend(BlocksCtx { blocks }); + } + + /// Decrypt blocks buffer-to-buffer. + /// + /// Returns [`NotEqualError`] if provided `in_blocks` and `out_blocks` + /// have different lengths. + #[inline] + fn decrypt_blocks_b2b( + &self, + in_blocks: &[Block], + out_blocks: &mut [Block], + ) -> Result<(), NotEqualError> { + InOutBuf::new(in_blocks, out_blocks) + .map(|blocks| self.decrypt_with_backend(BlocksCtx { blocks })) + } + + /// Decrypt input and unpad it. Returns resulting ciphertext slice. + /// + /// Returns [`UnpadError`] if padding is malformed or if input length is + /// not multiple of `Self::BlockSize`. + #[cfg(feature = "block-padding")] + #[cfg_attr(docsrs, doc(cfg(feature = "block-padding")))] + #[inline] + fn decrypt_padded_inout<'inp, 'out, P: Padding>( + &self, + data: InOutBuf<'inp, 'out, u8>, + ) -> Result<&'out [u8], UnpadError> { + let (mut blocks, tail) = data.into_chunks(); + if !tail.is_empty() { + return Err(UnpadError); } + self.decrypt_blocks_inout(blocks.reborrow()); + P::unpad_blocks(blocks.into_out()) + } - for block in blocks { - self.decrypt_block(block); + /// Decrypt input and unpad it in-place. Returns resulting ciphertext slice. + /// + /// Returns [`UnpadError`] if padding is malformed or if input length is + /// not multiple of `Self::BlockSize`. + #[cfg(feature = "block-padding")] + #[cfg_attr(docsrs, doc(cfg(feature = "block-padding")))] + #[inline] + fn decrypt_padded<'a, P: Padding>( + &self, + buf: &'a mut [u8], + ) -> Result<&'a [u8], UnpadError> { + self.decrypt_padded_inout::

(buf.into()) + } + + /// Decrypt input and unpad it buffer-to-buffer. Returns resulting + /// ciphertext slice. + /// + /// Returns [`UnpadError`] if padding is malformed or if input length is + /// not multiple of `Self::BlockSize`. + #[cfg(feature = "block-padding")] + #[cfg_attr(docsrs, doc(cfg(feature = "block-padding")))] + #[inline] + fn decrypt_padded_b2b<'a, P: Padding>( + &self, + in_buf: &[u8], + out_buf: &'a mut [u8], + ) -> Result<&'a [u8], UnpadError> { + if out_buf.len() < in_buf.len() { + return Err(UnpadError); } + let n = in_buf.len(); + // note: `new` always returns `Ok` here + let buf = InOutBuf::new(in_buf, &mut out_buf[..n]).map_err(|_| UnpadError)?; + self.decrypt_padded_inout::

(buf) } } -/// Encrypt-only functionality for block ciphers with mutable access to `self`. +/// Encrypt-only functionality for block ciphers and modes with mutable access to `self`. /// -/// The main use case for this trait is hardware encryption engines which -/// require `&mut self` access to an underlying hardware peripheral. -pub trait BlockEncryptMut: BlockCipher { - /// Encrypt block in-place - fn encrypt_block_mut(&mut self, block: &mut Block); -} +/// The main use case for this trait is blocks modes, but it also can be used +/// for hardware cryptographic engines which require `&mut self` access to an +/// underlying hardware peripheral. +pub trait BlockEncryptMut: BlockSizeUser + Sized { + /// Encrypt data using backend provided to the rank-2 closure. + fn encrypt_with_backend_mut(&mut self, f: impl BlockClosure); + + /// Encrypt single `inout` block. + #[inline] + fn encrypt_block_inout_mut(&mut self, block: InOut<'_, '_, Block>) { + self.encrypt_with_backend_mut(BlockCtx { block }); + } -/// Decrypt-only functionality for block ciphers with mutable access to `self`. -/// -/// The main use case for this trait is hardware encryption engines which -/// require `&mut self` access to an underlying hardware peripheral. -pub trait BlockDecryptMut: BlockCipher { - /// Decrypt block in-place - fn decrypt_block_mut(&mut self, block: &mut Block); -} + /// Encrypt `inout` blocks. + #[inline] + fn encrypt_blocks_inout_mut(&mut self, blocks: InOutBuf<'_, '_, Block>) { + self.encrypt_with_backend_mut(BlocksCtx { blocks }); + } -impl BlockEncryptMut for Alg { + /// Encrypt single block in-place. + #[inline] fn encrypt_block_mut(&mut self, block: &mut Block) { - self.encrypt_block(block); + let block = block.into(); + self.encrypt_with_backend_mut(BlockCtx { block }); } -} -impl BlockDecryptMut for Alg { - fn decrypt_block_mut(&mut self, block: &mut Block) { - self.decrypt_block(block); + /// Encrypt `in_block` and write result to `out_block`. + #[inline] + fn encrypt_block_b2b_mut(&mut self, in_block: &Block, out_block: &mut Block) { + let block = (in_block, out_block).into(); + self.encrypt_with_backend_mut(BlockCtx { block }); } -} -// Impls of block cipher traits for reference types + /// Encrypt blocks in-place. + #[inline] + fn encrypt_blocks_mut(&mut self, blocks: &mut [Block]) { + let blocks = blocks.into(); + self.encrypt_with_backend_mut(BlocksCtx { blocks }); + } -impl BlockCipher for &Alg { - type BlockSize = Alg::BlockSize; - type ParBlocks = Alg::ParBlocks; -} + /// Encrypt blocks buffer-to-buffer. + /// + /// Returns [`NotEqualError`] if provided `in_blocks` and `out_blocks` + /// have different lengths. + #[inline] + fn encrypt_blocks_b2b_mut( + &mut self, + in_blocks: &[Block], + out_blocks: &mut [Block], + ) -> Result<(), NotEqualError> { + InOutBuf::new(in_blocks, out_blocks) + .map(|blocks| self.encrypt_with_backend_mut(BlocksCtx { blocks })) + } -impl BlockEncrypt for &Alg { + /// Pad input and encrypt. Returns resulting ciphertext slice. + /// + /// Returns [`PadError`] if length of output buffer is not sufficient. + #[cfg(feature = "block-padding")] + #[cfg_attr(docsrs, doc(cfg(feature = "block-padding")))] #[inline] - fn encrypt_block(&self, block: &mut Block) { - Alg::encrypt_block(self, block); + fn encrypt_padded_inout_mut<'inp, 'out, P: Padding>( + mut self, + data: InOutBufReserved<'inp, 'out, u8>, + ) -> Result<&'out [u8], PadError> { + let mut buf = data.into_padded_blocks::()?; + self.encrypt_blocks_inout_mut(buf.get_blocks()); + if let Some(block) = buf.get_tail_block() { + self.encrypt_block_inout_mut(block); + } + Ok(buf.into_out()) } + /// Pad input and encrypt in-place. Returns resulting ciphertext slice. + /// + /// Returns [`PadError`] if length of output buffer is not sufficient. + #[cfg(feature = "block-padding")] + #[cfg_attr(docsrs, doc(cfg(feature = "block-padding")))] #[inline] - fn encrypt_par_blocks(&self, blocks: &mut ParBlocks) { - Alg::encrypt_par_blocks(self, blocks); + fn encrypt_padded_mut<'a, P: Padding>( + self, + buf: &'a mut [u8], + msg_len: usize, + ) -> Result<&'a [u8], PadError> { + let buf = InOutBufReserved::from_mut_slice(buf, msg_len).map_err(|_| PadError)?; + self.encrypt_padded_inout_mut::

(buf) } + /// Pad input and encrypt buffer-to-buffer. Returns resulting ciphertext slice. + /// + /// Returns [`PadError`] if length of output buffer is not sufficient. + #[cfg(feature = "block-padding")] + #[cfg_attr(docsrs, doc(cfg(feature = "block-padding")))] #[inline] - fn encrypt_blocks(&self, blocks: &mut [Block]) { - Alg::encrypt_blocks(self, blocks); + fn encrypt_padded_b2b_mut<'a, P: Padding>( + self, + msg: &[u8], + out_buf: &'a mut [u8], + ) -> Result<&'a [u8], PadError> { + let buf = InOutBufReserved::from_slices(msg, out_buf).map_err(|_| PadError)?; + self.encrypt_padded_inout_mut::

(buf) } } -impl BlockDecrypt for &Alg { +/// Decrypt-only functionality for block ciphers and modes with mutable access to `self`. +/// +/// The main use case for this trait is blocks modes, but it also can be used +/// for hardware cryptographic engines which require `&mut self` access to an +/// underlying hardware peripheral. +pub trait BlockDecryptMut: BlockSizeUser + Sized { + /// Decrypt data using backend provided to the rank-2 closure. + fn decrypt_with_backend_mut(&mut self, f: impl BlockClosure); + + /// Decrypt single `inout` block. #[inline] - fn decrypt_block(&self, block: &mut Block) { - Alg::decrypt_block(self, block); + fn decrypt_block_inout_mut(&mut self, block: InOut<'_, '_, Block>) { + self.decrypt_with_backend_mut(BlockCtx { block }); } + /// Decrypt `inout` blocks. #[inline] - fn decrypt_par_blocks(&self, blocks: &mut ParBlocks) { - Alg::decrypt_par_blocks(self, blocks); + fn decrypt_blocks_inout_mut(&mut self, blocks: InOutBuf<'_, '_, Block>) { + self.decrypt_with_backend_mut(BlocksCtx { blocks }); } + /// Decrypt single block in-place. #[inline] - fn decrypt_blocks(&self, blocks: &mut [Block]) { - Alg::decrypt_blocks(self, blocks); + fn decrypt_block_mut(&mut self, block: &mut Block) { + let block = block.into(); + self.decrypt_with_backend_mut(BlockCtx { block }); + } + + /// Decrypt `in_block` and write result to `out_block`. + #[inline] + fn decrypt_block_b2b_mut(&mut self, in_block: &Block, out_block: &mut Block) { + let block = (in_block, out_block).into(); + self.decrypt_with_backend_mut(BlockCtx { block }); } -} -/// Trait for types which can be initialized from a block cipher. -pub trait FromBlockCipher { - /// Block cipher used for initialization. - type BlockCipher: BlockCipher; + /// Decrypt blocks in-place. + #[inline] + fn decrypt_blocks_mut(&mut self, blocks: &mut [Block]) { + let blocks = blocks.into(); + self.decrypt_with_backend_mut(BlocksCtx { blocks }); + } - /// Initialize instance from block cipher. - fn from_block_cipher(cipher: Self::BlockCipher) -> Self; + /// Decrypt blocks buffer-to-buffer. + /// + /// Returns [`NotEqualError`] if provided `in_blocks` and `out_blocks` + /// have different lengths. + #[inline] + fn decrypt_blocks_b2b_mut( + &mut self, + in_blocks: &[Block], + out_blocks: &mut [Block], + ) -> Result<(), NotEqualError> { + InOutBuf::new(in_blocks, out_blocks) + .map(|blocks| self.decrypt_with_backend_mut(BlocksCtx { blocks })) + } + + /// Decrypt input and unpad it. Returns resulting ciphertext slice. + /// + /// Returns [`UnpadError`] if padding is malformed or if input length is + /// not multiple of `Self::BlockSize`. + #[cfg(feature = "block-padding")] + #[cfg_attr(docsrs, doc(cfg(feature = "block-padding")))] + #[inline] + fn decrypt_padded_inout_mut<'inp, 'out, P: Padding>( + mut self, + data: InOutBuf<'inp, 'out, u8>, + ) -> Result<&'out [u8], UnpadError> { + let (mut blocks, tail) = data.into_chunks(); + if !tail.is_empty() { + return Err(UnpadError); + } + self.decrypt_blocks_inout_mut(blocks.reborrow()); + P::unpad_blocks(blocks.into_out()) + } + + /// Decrypt input and unpad it in-place. Returns resulting ciphertext slice. + /// + /// Returns [`UnpadError`] if padding is malformed or if input length is + /// not multiple of `Self::BlockSize`. + #[cfg(feature = "block-padding")] + #[cfg_attr(docsrs, doc(cfg(feature = "block-padding")))] + #[inline] + fn decrypt_padded_mut<'a, P: Padding>( + self, + buf: &'a mut [u8], + ) -> Result<&'a [u8], UnpadError> { + self.decrypt_padded_inout_mut::

(buf.into()) + } + + /// Decrypt input and unpad it buffer-to-buffer. Returns resulting + /// ciphertext slice. + /// + /// Returns [`UnpadError`] if padding is malformed or if input length is + /// not multiple of `Self::BlockSize`. + #[cfg(feature = "block-padding")] + #[cfg_attr(docsrs, doc(cfg(feature = "block-padding")))] + #[inline] + fn decrypt_padded_b2b_mut<'a, P: Padding>( + self, + in_buf: &[u8], + out_buf: &'a mut [u8], + ) -> Result<&'a [u8], UnpadError> { + if out_buf.len() < in_buf.len() { + return Err(UnpadError); + } + let n = in_buf.len(); + // note: `new` always returns `Ok` here + let buf = InOutBuf::new(in_buf, &mut out_buf[..n]).map_err(|_| UnpadError)?; + self.decrypt_padded_inout_mut::

(buf) + } } -/// Trait for types which can be initialized from a block cipher and nonce. -pub trait FromBlockCipherNonce { - /// Block cipher used for initialization. - type BlockCipher: BlockCipher; - /// Nonce size in bytes. - type NonceSize: ArrayLength; +impl BlockEncryptMut for Alg { + fn encrypt_with_backend_mut(&mut self, f: impl BlockClosure) { + self.encrypt_with_backend(f); + } +} - /// Initialize instance from block cipher and nonce. - fn from_block_cipher_nonce( - cipher: Self::BlockCipher, - nonce: &GenericArray, - ) -> Self; +impl BlockDecryptMut for Alg { + fn decrypt_with_backend_mut(&mut self, f: impl BlockClosure) { + self.decrypt_with_backend(f); + } } -impl FromKeyNonce for T -where - T: FromBlockCipherNonce, - T::BlockCipher: FromKey, -{ - type KeySize = ::KeySize; - type NonceSize = T::NonceSize; +impl BlockCipher for &Alg {} - fn new( - key: &GenericArray, - nonce: &GenericArray, - ) -> Self { - Self::from_block_cipher_nonce(T::BlockCipher::new(key), nonce) +impl BlockEncrypt for &Alg { + fn encrypt_with_backend(&self, f: impl BlockClosure) { + Alg::encrypt_with_backend(self, f); } } -impl FromKey for T -where - T: FromBlockCipher, - T::BlockCipher: FromKey, -{ - type KeySize = ::KeySize; +impl BlockDecrypt for &Alg { + fn decrypt_with_backend(&self, f: impl BlockClosure) { + Alg::decrypt_with_backend(self, f); + } +} + +/// Closure used in methods which operate over separate blocks. +struct BlockCtx<'inp, 'out, BS: ArrayLength> { + block: InOut<'inp, 'out, Block>, +} - fn new(key: &GenericArray) -> Self { - Self::from_block_cipher(T::BlockCipher::new(key)) +impl<'inp, 'out, BS: ArrayLength> BlockSizeUser for BlockCtx<'inp, 'out, BS> { + type BlockSize = BS; +} + +impl<'inp, 'out, BS: ArrayLength> BlockClosure for BlockCtx<'inp, 'out, BS> { + #[inline(always)] + fn call>(self, backend: &mut B) { + backend.proc_block(self.block); } +} - fn new_from_slice(key: &[u8]) -> Result { - T::BlockCipher::new_from_slice(key) - .map_err(|_| InvalidLength) - .map(Self::from_block_cipher) +/// Closure used in methods which operate over slice of blocks. +struct BlocksCtx<'inp, 'out, BS: ArrayLength> { + blocks: InOutBuf<'inp, 'out, Block>, +} + +impl<'inp, 'out, BS: ArrayLength> BlockSizeUser for BlocksCtx<'inp, 'out, BS> { + type BlockSize = BS; +} + +impl<'inp, 'out, BS: ArrayLength> BlockClosure for BlocksCtx<'inp, 'out, BS> { + #[inline(always)] + fn call>(self, backend: &mut B) { + if B::ParBlocksSize::USIZE > 1 { + let (chunks, tail) = self.blocks.into_chunks(); + for chunk in chunks { + backend.proc_par_blocks(chunk); + } + backend.proc_tail_blocks(tail); + } else { + for block in self.blocks { + backend.proc_block(block); + } + } } } + +/// Implement simple block backend +#[macro_export] +macro_rules! impl_simple_block_encdec { + ( + <$($N:ident$(:$b0:ident$(+$b:ident)*)?),*> + $cipher:ident, $block_size:ty, $state:ident, $block:ident, + encrypt: $enc_block:block + decrypt: $dec_block:block + ) => { + impl<$($N$(:$b0$(+$b)*)?),*> $crate::BlockSizeUser for $cipher<$($N),*> { + type BlockSize = $block_size; + } + + impl<$($N$(:$b0$(+$b)*)?),*> $crate::BlockEncrypt for $cipher<$($N),*> { + fn encrypt_with_backend(&self, f: impl $crate::BlockClosure) { + struct EncBack<'a, $($N$(:$b0$(+$b)*)?),* >(&'a $cipher<$($N),*>); + + impl<'a, $($N$(:$b0$(+$b)*)?),* > $crate::BlockSizeUser for EncBack<'a, $($N),*> { + type BlockSize = $block_size; + } + + impl<'a, $($N$(:$b0$(+$b)*)?),* > $crate::ParBlocksSizeUser for EncBack<'a, $($N),*> { + type ParBlocksSize = $crate::consts::U1; + } + + impl<'a, $($N$(:$b0$(+$b)*)?),* > $crate::BlockBackend for EncBack<'a, $($N),*> { + #[inline(always)] + fn proc_block( + &mut self, + mut $block: $crate::inout::InOut<'_, '_, $crate::Block> + ) { + let $state: &$cipher<$($N),*> = self.0; + $enc_block + } + } + + f.call(&mut EncBack(self)) + } + } + + impl<$($N$(:$b0$(+$b)*)?),*> $crate::BlockDecrypt for $cipher<$($N),*> { + fn decrypt_with_backend(&self, f: impl $crate::BlockClosure) { + struct DecBack<'a, $($N$(:$b0$(+$b)*)?),* >(&'a $cipher<$($N),*>); + + impl<'a, $($N$(:$b0$(+$b)*)?),* > $crate::BlockSizeUser for DecBack<'a, $($N),*> { + type BlockSize = $block_size; + } + + impl<'a, $($N$(:$b0$(+$b)*)?),* > $crate::ParBlocksSizeUser for DecBack<'a, $($N),*> { + type ParBlocksSize = $crate::consts::U1; + } + + impl<'a, $($N$(:$b0$(+$b)*)?),* > $crate::BlockBackend for DecBack<'a, $($N),*> { + #[inline(always)] + fn proc_block( + &mut self, + mut $block: $crate::inout::InOut<'_, '_, $crate::Block> + ) { + let $state: &$cipher<$($N),*> = self.0; + $dec_block + } + } + + f.call(&mut DecBack(self)) + } + } + }; + ( + $cipher:ident, $block_size:ty, $state:ident, $block:ident, + encrypt: $enc_block:block + decrypt: $dec_block:block + ) => { + $crate::impl_simple_block_encdec!( + <> $cipher, $block_size, $state, $block, + encrypt: $enc_block + decrypt: $dec_block + ); + }; +} diff --git a/cipher/src/dev/block.rs b/cipher/src/dev/block.rs index fc53b9435..d3115c5d8 100644 --- a/cipher/src/dev/block.rs +++ b/cipher/src/dev/block.rs @@ -6,24 +6,24 @@ pub use blobby; #[macro_export] #[cfg_attr(docsrs, doc(cfg(feature = "dev")))] macro_rules! block_cipher_test { - ($name:ident, $test_name:expr, $cipher:ty) => { + ($name:ident, $test_name:expr, $cipher:ty $(,)?) => { #[test] fn $name() { - use cipher::generic_array::{typenum::Unsigned, GenericArray}; use cipher::{ - blobby::Blob3Iterator, BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher, + blobby::Blob3Iterator, generic_array::GenericArray, typenum::Unsigned, + BlockDecryptMut, BlockEncryptMut, BlockSizeUser, KeyInit, }; fn run_test(key: &[u8], pt: &[u8], ct: &[u8]) -> bool { - let state = <$cipher as NewBlockCipher>::new_from_slice(key).unwrap(); + let mut state = <$cipher as KeyInit>::new_from_slice(key).unwrap(); let mut block = GenericArray::clone_from_slice(pt); - state.encrypt_block(&mut block); + state.encrypt_block_mut(&mut block); if ct != block.as_slice() { return false; } - state.decrypt_block(&mut block); + state.decrypt_block_mut(&mut block); if pt != block.as_slice() { return false; } @@ -32,15 +32,12 @@ macro_rules! block_cipher_test { } fn run_par_test(key: &[u8], pt: &[u8]) -> bool { - type ParBlocks = <$cipher as BlockCipher>::ParBlocks; - type BlockSize = <$cipher as BlockCipher>::BlockSize; - type Block = GenericArray; - type ParBlock = GenericArray; + type Block = cipher::Block<$cipher>; - let state = <$cipher as NewBlockCipher>::new_from_slice(key).unwrap(); + let mut state = <$cipher as KeyInit>::new_from_slice(key).unwrap(); let block = Block::clone_from_slice(pt); - let mut blocks1 = ParBlock::default(); + let mut blocks1 = vec![block; 101]; for (i, b) in blocks1.iter_mut().enumerate() { *b = block; b[0] = b[0].wrapping_add(i as u8); @@ -49,9 +46,9 @@ macro_rules! block_cipher_test { // check that `encrypt_blocks` and `encrypt_block` // result in the same ciphertext - state.encrypt_blocks(&mut blocks1); + state.encrypt_blocks_mut(&mut blocks1); for b in blocks2.iter_mut() { - state.encrypt_block(b); + state.encrypt_block_mut(b); } if blocks1 != blocks2 { return false; @@ -59,9 +56,9 @@ macro_rules! block_cipher_test { // check that `encrypt_blocks` and `encrypt_block` // result in the same plaintext - state.decrypt_blocks(&mut blocks1); + state.decrypt_blocks_mut(&mut blocks1); for b in blocks2.iter_mut() { - state.decrypt_block(b); + state.decrypt_block_mut(b); } if blocks1 != blocks2 { return false; @@ -70,7 +67,6 @@ macro_rules! block_cipher_test { true } - let pb = <$cipher as BlockCipher>::ParBlocks::to_usize(); let data = include_bytes!(concat!("data/", $test_name, ".blb")); for (i, row) in Blob3Iterator::new(data).unwrap().enumerate() { let [key, pt, ct] = row.unwrap(); @@ -86,58 +82,308 @@ macro_rules! block_cipher_test { } // test parallel blocks encryption/decryption - if pb != 1 { - if !run_par_test(key, pt) { - panic!( - "\n\ - Failed parallel test №{}\n\ - key:\t{:?}\n\ - plaintext:\t{:?}\n\ - ciphertext:\t{:?}\n", - i, key, pt, ct, - ); - } + if !run_par_test(key, pt) { + panic!( + "\n\ + Failed parallel test №{}\n\ + key:\t{:?}\n\ + plaintext:\t{:?}\n\ + ciphertext:\t{:?}\n", + i, key, pt, ct, + ); + } + } + } + }; +} + +/// Define block mode encryption test +#[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] +macro_rules! block_mode_enc_test { + ($name:ident, $test_name:expr, $cipher:ty $(,)?) => { + #[test] + fn $name() { + use cipher::{ + blobby::Blob4Iterator, generic_array::GenericArray, inout::InOutBuf, + typenum::Unsigned, BlockEncryptMut, BlockSizeUser, KeyIvInit, + }; + + fn run_test(key: &[u8], iv: &[u8], pt: &[u8], ct: &[u8]) -> bool { + assert_eq!(pt.len(), ct.len()); + // test block-by-block processing + let mut state = <$cipher as KeyIvInit>::new_from_slices(key, iv).unwrap(); + + let mut out = vec![0u8; ct.len()]; + let mut buf = InOutBuf::new(pt, &mut out).unwrap(); + let (blocks, tail) = buf.reborrow().into_chunks(); + assert_eq!(tail.len(), 0); + for block in blocks { + state.encrypt_block_inout_mut(block); + } + if buf.get_out() != ct { + return false; + } + + // test multi-block processing + let mut state = <$cipher as KeyIvInit>::new_from_slices(key, iv).unwrap(); + buf.get_out().iter_mut().for_each(|b| *b = 0); + let (blocks, _) = buf.reborrow().into_chunks(); + state.encrypt_blocks_inout_mut(blocks); + if buf.get_out() != ct { + return false; + } + + true + } + + let data = include_bytes!(concat!("data/", $test_name, ".blb")); + for (i, row) in Blob4Iterator::new(data).unwrap().enumerate() { + let [key, iv, pt, ct] = row.unwrap(); + if !run_test(key, iv, pt, ct) { + panic!( + "\n\ + Failed test №{}\n\ + key:\t{:?}\n\ + iv:\t{:?}\n\ + plaintext:\t{:?}\n\ + ciphertext:\t{:?}\n", + i, key, iv, pt, ct, + ); + } + } + } + }; +} + +/// Define block mode decryption test +#[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] +macro_rules! block_mode_dec_test { + ($name:ident, $test_name:expr, $cipher:ty $(,)?) => { + #[test] + fn $name() { + use cipher::{ + blobby::Blob4Iterator, generic_array::GenericArray, inout::InOutBuf, + typenum::Unsigned, BlockDecryptMut, BlockSizeUser, KeyIvInit, + }; + + fn run_test(key: &[u8], iv: &[u8], pt: &[u8], ct: &[u8]) -> bool { + assert_eq!(pt.len(), ct.len()); + // test block-by-block processing + let mut state = <$cipher as KeyIvInit>::new_from_slices(key, iv).unwrap(); + + let mut out = vec![0u8; pt.len()]; + let mut buf = InOutBuf::new(ct, &mut out).unwrap(); + let (blocks, tail) = buf.reborrow().into_chunks(); + assert_eq!(tail.len(), 0); + for block in blocks { + state.decrypt_block_inout_mut(block); + } + if buf.get_out() != pt { + return false; + } + + // test multi-block processing + let mut state = <$cipher as KeyIvInit>::new_from_slices(key, iv).unwrap(); + buf.get_out().iter_mut().for_each(|b| *b = 0); + let (blocks, _) = buf.reborrow().into_chunks(); + state.decrypt_blocks_inout_mut(blocks); + if buf.get_out() != pt { + return false; + } + + true + } + + let data = include_bytes!(concat!("data/", $test_name, ".blb")); + for (i, row) in Blob4Iterator::new(data).unwrap().enumerate() { + let [key, iv, pt, ct] = row.unwrap(); + if !run_test(key, iv, pt, ct) { + panic!( + "\n\ + Failed test №{}\n\ + key:\t{:?}\n\ + iv:\t{:?}\n\ + plaintext:\t{:?}\n\ + ciphertext:\t{:?}\n", + i, key, iv, pt, ct, + ); } } - // test if cipher can be cloned - let key = Default::default(); - let _ = <$cipher as NewBlockCipher>::new(&key).clone(); } }; } -/// Define block cipher benchmark +/// Define `IvState` test #[macro_export] #[cfg_attr(docsrs, doc(cfg(feature = "dev")))] -macro_rules! block_cipher_bench { - ($cipher:path, $key_len:expr) => { - extern crate test; +macro_rules! iv_state_test { + ($name:ident, $cipher:ty, encrypt $(,)?) => { + $crate::iv_state_test!($name, $cipher, encrypt_blocks_mut); + }; + ($name:ident, $cipher:ty, decrypt $(,)?) => { + $crate::iv_state_test!($name, $cipher, decrypt_blocks_mut); + }; + ($name:ident, $cipher:ty, apply_ks $(,)?) => { + $crate::iv_state_test!($name, $cipher, apply_keystream_blocks); + }; + ($name:ident, $cipher:ty, $method:ident $(,)?) => { + #[test] + fn $name() { + use cipher::*; + + let mut blocks = [Block::<$cipher>::default(); 32]; + + for (i, block) in blocks.iter_mut().enumerate() { + for (j, b) in block.iter_mut().enumerate() { + *b = (i + j) as u8; + } + } + + let mut key = Key::<$cipher>::default(); + let mut iv = Iv::<$cipher>::default(); + key.iter_mut().for_each(|b| *b = 0x42); + iv.iter_mut().for_each(|b| *b = 0x24); - use cipher::{BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher}; - use test::Bencher; + let mut cipher = <$cipher>::new(&key, &iv); + let mut target = blocks.clone(); + cipher.$method(&mut target); + + for i in 0..32 { + let mut blocks = blocks.clone(); + let (b1, b2) = blocks.split_at_mut(i); + let mut cipher1 = <$cipher>::new(&key, &iv); + cipher1.$method(b1); + let temp_iv = cipher1.iv_state(); + let mut cipher2 = <$cipher>::new(&key, &temp_iv); + cipher2.$method(b2); + assert_eq!(blocks, target); + } + } + }; +} +/// Define block encryptor benchmark +#[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] +macro_rules! block_encryptor_bench { + (Key: $cipher:ty, $block_name:ident, $blocks_name:ident $(,)? ) => { + $crate::block_encryptor_bench!( + { + use $crate::KeyInit; + let key = test::black_box(Default::default()); + <$cipher>::new(&key) + }, + $cipher, + $block_name, + $blocks_name, + ); + }; + (KeyIv: $cipher:ty, $block_name:ident, $blocks_name:ident $(,)? ) => { + $crate::block_encryptor_bench!( + { + use $crate::KeyIvInit; + let key = test::black_box(Default::default()); + let iv = test::black_box(Default::default()); + <$cipher>::new(&key, &iv) + }, + $cipher, + $block_name, + $blocks_name, + ); + }; + ($init:block, $cipher:ty, $block_name:ident, $blocks_name:ident $(,)? ) => { + #[bench] + pub fn $block_name(bh: &mut test::Bencher) { + use cipher::BlockEncryptMut; + + let mut cipher = $init; + let mut blocks = vec![Default::default(); 1024]; + + bh.iter(|| { + for block in blocks.iter_mut() { + cipher.encrypt_block_mut(block); + } + test::black_box(&blocks); + }); + bh.bytes = (blocks.len() * blocks[0].len()) as u64; + } + + #[bench] + pub fn $blocks_name(bh: &mut test::Bencher) { + use cipher::BlockEncryptMut; + + let mut cipher = $init; + let mut blocks = vec![Default::default(); 1024]; + + bh.iter(|| { + cipher.encrypt_blocks_mut(&mut blocks); + test::black_box(&blocks); + }); + bh.bytes = (blocks.len() * blocks[0].len()) as u64; + } + }; +} + +/// Define block decryptor benchmark +#[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] +macro_rules! block_decryptor_bench { + (Key: $cipher:ty, $block_name:ident, $blocks_name:ident $(,)? ) => { + $crate::block_decryptor_bench!( + { + use $crate::KeyInit; + let key = test::black_box(Default::default()); + <$cipher>::new(&key) + }, + $cipher, + $block_name, + $blocks_name, + ); + }; + (KeyIv: $cipher:ty, $block_name:ident, $blocks_name:ident $(,)? ) => { + $crate::block_decryptor_bench!( + { + use $crate::KeyIvInit; + let key = test::black_box(Default::default()); + let iv = test::black_box(Default::default()); + <$cipher>::new(&key, &iv) + }, + $cipher, + $block_name, + $blocks_name, + ); + }; + ($init:block, $cipher:ty, $block_name:ident, $blocks_name:ident $(,)? ) => { #[bench] - pub fn encrypt(bh: &mut Bencher) { - let state = <$cipher>::new_from_slice(&[1u8; $key_len]).unwrap(); - let mut block = Default::default(); + pub fn $block_name(bh: &mut test::Bencher) { + use cipher::BlockDecryptMut; + + let mut cipher = $init; + let mut blocks = vec![Default::default(); 1024]; bh.iter(|| { - state.encrypt_block(&mut block); - test::black_box(&block); + for block in blocks.iter_mut() { + cipher.decrypt_block_mut(block); + } + test::black_box(&blocks); }); - bh.bytes = block.len() as u64; + bh.bytes = (blocks.len() * blocks[0].len()) as u64; } #[bench] - pub fn decrypt(bh: &mut Bencher) { - let state = <$cipher>::new_from_slice(&[1u8; $key_len]).unwrap(); - let mut block = Default::default(); + pub fn $blocks_name(bh: &mut test::Bencher) { + use cipher::BlockDecryptMut; + + let mut cipher = $init; + let mut blocks = vec![Default::default(); 1024]; bh.iter(|| { - state.decrypt_block(&mut block); - test::black_box(&block); + cipher.decrypt_blocks_mut(&mut blocks); + test::black_box(&blocks); }); - bh.bytes = block.len() as u64; + bh.bytes = (blocks.len() * blocks[0].len()) as u64; } }; } diff --git a/cipher/src/dev/stream.rs b/cipher/src/dev/stream.rs index 43757ffa1..0496345d4 100644 --- a/cipher/src/dev/stream.rs +++ b/cipher/src/dev/stream.rs @@ -4,11 +4,11 @@ #[macro_export] #[cfg_attr(docsrs, doc(cfg(feature = "dev")))] macro_rules! stream_cipher_test { - ($name:ident, $cipher:ty, $test_name:expr) => { + ($name:ident, $test_name:expr, $cipher:ty $(,)?) => { #[test] fn $name() { use cipher::generic_array::GenericArray; - use cipher::{blobby::Blob4Iterator, NewCipher, StreamCipher}; + use cipher::{blobby::Blob4Iterator, KeyIvInit, StreamCipher}; let data = include_bytes!(concat!("data/", $test_name, ".blb")); for (i, row) in Blob4Iterator::new(data).unwrap().enumerate() { @@ -44,7 +44,7 @@ macro_rules! stream_cipher_seek_test { #[test] fn $name() { use cipher::generic_array::GenericArray; - use cipher::{NewCipher, StreamCipher, StreamCipherSeek}; + use cipher::{KeyIvInit, StreamCipher, StreamCipherSeek}; fn get_cipher() -> $cipher { <$cipher>::new(&Default::default(), &Default::default()) @@ -89,153 +89,57 @@ macro_rules! stream_cipher_seek_test { }; } -/// Test core functionality of asynchronous stream cipher +/// Create stream cipher benchmarks #[macro_export] #[cfg_attr(docsrs, doc(cfg(feature = "dev")))] -macro_rules! stream_cipher_async_test { - ($name:ident, $test_name:expr, $cipher:ty) => { - #[test] - fn $name() { - use cipher::generic_array::GenericArray; - use cipher::{blobby::Blob4Iterator, AsyncStreamCipher, NewCipher}; - - fn run_test( - key: &[u8], - iv: &[u8], - plaintext: &[u8], - ciphertext: &[u8], - ) -> Option<&'static str> { - for n in 1..=plaintext.len() { - let mut mode = <$cipher>::new_from_slices(key, iv).unwrap(); - let mut buf = plaintext.to_vec(); - for chunk in buf.chunks_mut(n) { - mode.encrypt(chunk); - } - if buf != &ciphertext[..] { - return Some("encrypt"); - } - } - - for n in 1..=plaintext.len() { - let mut mode = <$cipher>::new_from_slices(key, iv).unwrap(); - let mut buf = ciphertext.to_vec(); - for chunk in buf.chunks_mut(n) { - mode.decrypt(chunk); - } - if buf != &plaintext[..] { - return Some("decrypt"); - } - } - - None - } - - let data = include_bytes!(concat!("data/", $test_name, ".blb")); - - for (i, row) in Blob4Iterator::new(data).unwrap().enumerate() { - let [key, iv, pt, ct] = row.unwrap(); - if let Some(desc) = run_test(key, iv, pt, ct) { - panic!( - "\n\ - Failed test №{}: {}\n\ - key:\t{:?}\n\ - iv:\t{:?}\n\ - plaintext:\t{:?}\n\ - ciphertext:\t{:?}\n", - i, desc, key, iv, pt, ct, - ); - } - } - } +macro_rules! stream_cipher_bench { + ( + $cipher:ty; + $($name:ident $bs:expr;)* + ) => { + $crate::stream_cipher_bench!( + Init: { + use $crate::KeyIvInit; + let key = test::black_box(Default::default()); + let iv = test::black_box(Default::default()); + <$cipher>::new(&key, &iv) + }; + $($name $bs;)* + ); }; -} - -/// Create synchronous stream cipher benchmarks -#[macro_export] -#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] -macro_rules! stream_cipher_sync_bench { - ($name:ident, $cipher:path, $data_len:expr) => { - #[bench] - pub fn $name(bh: &mut Bencher) { - let key = Default::default(); - let nonce = Default::default(); - let mut cipher = <$cipher>::new(&key, &nonce); - let mut data = get_data($data_len); - - bh.iter(|| { - cipher.apply_keystream(&mut data); - test::black_box(&data); - }); - bh.bytes = data.len() as u64; - } - }; - ($cipher:path) => { - extern crate test; - - use cipher::{generic_array::GenericArray, NewCipher, StreamCipher}; - use test::Bencher; - - #[inline(never)] - fn get_data(n: usize) -> Vec { - vec![77; n] - } - - $crate::stream_cipher_sync_bench!(bench1_10, $cipher, 10); - $crate::stream_cipher_sync_bench!(bench2_100, $cipher, 100); - $crate::stream_cipher_sync_bench!(bench3_1000, $cipher, 1000); - $crate::stream_cipher_sync_bench!(bench4_10000, $cipher, 10000); - $crate::stream_cipher_sync_bench!(bench5_100000, $cipher, 100000); - }; -} - -/// Create asynchronous stream cipher benchmarks -#[macro_export] -#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] -macro_rules! stream_cipher_async_bench { - ($enc_name:ident, $dec_name:ident, $cipher:path, $data_len:expr) => { - #[bench] - pub fn $enc_name(bh: &mut Bencher) { - let key = Default::default(); - let nonce = Default::default(); - let mut cipher = <$cipher>::new(&key, &nonce); - let mut data = get_data($data_len); - - bh.iter(|| { - cipher.encrypt(&mut data); - test::black_box(&data); - }); - bh.bytes = data.len() as u64; - } - - #[bench] - pub fn $dec_name(bh: &mut Bencher) { - let key = Default::default(); - let nonce = Default::default(); - let mut cipher = <$cipher>::new(&key, &nonce); - let mut data = get_data($data_len); - - bh.iter(|| { - cipher.decrypt(&mut data); - test::black_box(&data); - }); - bh.bytes = data.len() as u64; - } + ( + Key: $cipher:ty; + $($name:ident $bs:expr;)* + ) => { + $crate::stream_cipher_bench!( + Init: { + use $crate::KeyInit; + let key = test::black_box(Default::default()); + let iv = test::black_box(Default::default()); + <$cipher>::new(&key, &iv) + }; + $($name $bs;)* + ); }; - ($cipher:path) => { - extern crate test; - - use cipher::{generic_array::GenericArray, AsyncStreamCipher, NewCipher}; - use test::Bencher; - - #[inline(never)] - fn get_data(n: usize) -> Vec { - vec![77; n] - } - - $crate::stream_cipher_async_bench!(encrypt_10, decrypt_10, $cipher, 10); - $crate::stream_cipher_async_bench!(encrypt_100, decrypt_100, $cipher, 100); - $crate::stream_cipher_async_bench!(encrypt_1000, decrypt_1000, $cipher, 1000); - $crate::stream_cipher_async_bench!(encrypt_10000, decrypt_10000, $cipher, 10000); - $crate::stream_cipher_async_bench!(encrypt_100000, decrypt_100000, $cipher, 100000); + ( + Init: $init:expr; + $($name:ident $bs:expr;)* + ) => { + $( + #[bench] + fn $name(b: &mut test::Bencher) { + use $crate::StreamCipher; + + let mut cipher = $init; + let mut buf = vec![0; $bs]; + + b.iter(|| { + cipher.apply_keystream(&mut buf); + test::black_box(&buf); + }); + + b.bytes = $bs; + } + )* }; } diff --git a/cipher/src/errors.rs b/cipher/src/errors.rs index 644495e80..0dc32740e 100644 --- a/cipher/src/errors.rs +++ b/cipher/src/errors.rs @@ -2,18 +2,24 @@ use core::fmt; -/// The error type returned when stream cipher has reached the end of a keystream. +/// This error is returned by the [`StreamCipher`][crate::stream::StreamCipher] +/// trait methods. +/// +/// Usually it's used in cases when stream cipher has reached the end +/// of a keystream, but also can be used if lengths of provided input +/// and output buffers are not equal. #[derive(Copy, Clone, Debug)] -pub struct LoopError; +pub struct StreamCipherError; -impl fmt::Display for LoopError { +impl fmt::Display for StreamCipherError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { f.write_str("Loop Error") } } #[cfg(feature = "std")] -impl std::error::Error for LoopError {} +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] +impl std::error::Error for StreamCipherError {} /// The error type returned when a cipher position can not be represented /// by the requested type. @@ -26,45 +32,12 @@ impl fmt::Display for OverflowError { } } -impl From for LoopError { - fn from(_: OverflowError) -> LoopError { - LoopError +impl From for StreamCipherError { + fn from(_: OverflowError) -> StreamCipherError { + StreamCipherError } } #[cfg(feature = "std")] +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] impl std::error::Error for OverflowError {} - -/// The error type returned when key and/or nonce used in the [`FromKey`] -/// and [`FromKeyNonce`] slice-based methods had an invalid length. -/// -/// [`FromKey`]: crate::FromKey -/// [`FromKeyNonce`]: crate::FromKeyNonce -#[derive(Copy, Clone, Eq, PartialEq, Debug)] -pub struct InvalidLength; - -impl fmt::Display for InvalidLength { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - f.write_str("Invalid Length") - } -} - -#[cfg(feature = "std")] -impl std::error::Error for InvalidLength {} - -/// The error type returned by the [`BlockModeEncryptWrapper`] and -/// [`BlockModeDecryptWrapper`] types. -/// -/// [`BlockModeEncryptWrapper`]: crate::BlockModeEncryptWrapper -/// [`BlockModeDecryptWrapper`]: crate::BlockModeDecryptWrapper -#[derive(Copy, Clone, Eq, PartialEq, Debug)] -pub struct BlockModeError; - -impl fmt::Display for BlockModeError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - f.write_str("Invalid Length") - } -} - -#[cfg(feature = "std")] -impl std::error::Error for BlockModeError {} diff --git a/cipher/src/lib.rs b/cipher/src/lib.rs index 4a9a3ebe1..fff7fd98e 100644 --- a/cipher/src/lib.rs +++ b/cipher/src/lib.rs @@ -1,24 +1,35 @@ //! This crate defines a set of traits which describe the functionality of -//! [block ciphers][1] and [stream ciphers][2]. +//! [block ciphers][1], [block modes][2], and [stream ciphers][3]. //! //! [1]: https://en.wikipedia.org/wiki/Block_cipher -//! [2]: https://en.wikipedia.org/wiki/Stream_cipher +//! [2]: https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation +//! [3]: https://en.wikipedia.org/wiki/Stream_cipher #![no_std] #![cfg_attr(docsrs, feature(doc_cfg))] #![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg" + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", + html_root_url = "https://docs.rs/cipher/0.4.0" )] -#![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] +pub use crypto_common; +pub use inout; + #[cfg(feature = "std")] extern crate std; #[cfg(feature = "rand_core")] #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] -pub use rand_core; +pub use crypto_common::rand_core; + +#[cfg(feature = "block-padding")] +#[cfg_attr(docsrs, doc(cfg(feature = "block-padding")))] +pub use inout::block_padding; + +#[cfg(feature = "zeroize")] +pub use zeroize; #[cfg(feature = "dev")] pub use blobby; @@ -26,114 +37,31 @@ pub use blobby; mod block; #[cfg(feature = "dev")] mod dev; -pub mod errors; -mod mode; +mod errors; mod stream; - -#[cfg(feature = "mode_wrapper")] -mod mode_wrapper; - -pub use crate::{block::*, mode::*, stream::*}; -pub use generic_array::{self, typenum::consts}; -#[cfg(feature = "mode_wrapper")] -pub use mode_wrapper::{BlockModeDecryptWrapper, BlockModeEncryptWrapper}; - -use crate::errors::InvalidLength; -use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; -#[cfg(feature = "rand_core")] -use rand_core::{CryptoRng, RngCore}; - -// note: ideally the following traits would be defined in the `crypto-common` crate, -// but it would make impossible the generic impls over `T: FromBlockCipher(Nonce)` -// in the `block` module, see the following link for proposal to change it: -// https://internals.rust-lang.org/t/14125 - -/// Trait for types which can be created from key and nonce. -pub trait FromKeyNonce: Sized { - /// Key size in bytes. - type KeySize: ArrayLength; - - /// Nonce size in bytes. - type NonceSize: ArrayLength; - - /// Create new value from fixed length key and nonce. - fn new( - key: &GenericArray, - nonce: &GenericArray, - ) -> Self; - - /// Create new value from variable length key and nonce. - #[inline] - fn new_from_slices(key: &[u8], nonce: &[u8]) -> Result { - let kl = Self::KeySize::to_usize(); - let nl = Self::NonceSize::to_usize(); - if key.len() != kl || nonce.len() != nl { - Err(InvalidLength) - } else { - let key = GenericArray::from_slice(key); - let nonce = GenericArray::from_slice(nonce); - Ok(Self::new(key, nonce)) - } - } - - /// Generate a random key using the provided [`CryptoRng`]. - #[cfg(feature = "rand_core")] - #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] - #[inline] - fn generate_key(mut rng: impl CryptoRng + RngCore) -> GenericArray { - let mut key = GenericArray::::default(); - rng.fill_bytes(&mut key); - key - } - - /// Generate a random nonce using the provided [`CryptoRng`]. - #[cfg(feature = "rand_core")] - #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] - #[inline] - fn generate_nonce(mut rng: impl CryptoRng + RngCore) -> GenericArray { - let mut nonce = GenericArray::::default(); - rng.fill_bytes(&mut nonce); - nonce - } - - /// Generate random key and nonce using the provided [`CryptoRng`]. - #[cfg(feature = "rand_core")] - #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] - #[inline] - fn generate_key_nonce( - mut rng: impl CryptoRng + RngCore, - ) -> ( - GenericArray, - GenericArray, - ) { - (Self::generate_key(&mut rng), Self::generate_nonce(&mut rng)) - } +mod stream_core; +mod stream_wrapper; + +pub use crate::{block::*, errors::*, stream::*, stream_core::*, stream_wrapper::*}; +pub use crypto_common::{ + generic_array, + typenum::{self, consts}, + AlgorithmName, Block, InnerIvInit, InvalidLength, Iv, IvSizeUser, Key, KeyInit, KeyIvInit, + KeySizeUser, +}; +use generic_array::{ArrayLength, GenericArray}; + +/// Trait for loading current IV state. +pub trait IvState: IvSizeUser { + /// Returns current IV state. + fn iv_state(&self) -> Iv; } -/// Trait for types which can be created from key. -pub trait FromKey: Sized { - /// Key size in bytes. - type KeySize: ArrayLength; - - /// Create new value from fixed size key. - fn new(key: &GenericArray) -> Self; - - /// Create new value from variable size key. - fn new_from_slice(key: &[u8]) -> Result { - if key.len() != Self::KeySize::to_usize() { - Err(InvalidLength) - } else { - Ok(Self::new(GenericArray::from_slice(key))) - } - } - - /// Generate a random key using the provided [`CryptoRng`]. - #[cfg(feature = "rand_core")] - #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] - #[inline] - fn generate_key(mut rng: impl CryptoRng + RngCore) -> GenericArray { - let mut key = GenericArray::::default(); - rng.fill_bytes(&mut key); - key - } +/// Types which process blocks in parallel. +pub trait ParBlocksSizeUser: BlockSizeUser { + /// Number of blocks which can be processed in parallel. + type ParBlocksSize: ArrayLength>; } + +/// Parallel blocks on which [`ParBlocksSizeUser`] implementors operate. +pub type ParBlocks = GenericArray, ::ParBlocksSize>; diff --git a/cipher/src/mode.rs b/cipher/src/mode.rs deleted file mode 100644 index 336f50cfa..000000000 --- a/cipher/src/mode.rs +++ /dev/null @@ -1,42 +0,0 @@ -use crate::{BlockCipher, FromKeyNonce}; -use generic_array::{ArrayLength, GenericArray}; - -/// Trait for types which implement a block cipher [mode of operation][1]. -/// -/// [1]: https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation -pub trait BlockMode { - /// Size of the block in bytes - type BlockSize: ArrayLength; -} - -/// Trait for a block cipher mode of operation block-level encryptor. -/// -/// This trait operates only on blocks, for convinient slice-based methods with padding -/// see the [`BlockModeEncryptWrapper`][crate::BlockModeEncryptWrapper] type. -pub trait BlockModeEncrypt: BlockMode { - /// Encrypt blocks of data. - fn encrypt_blocks(&mut self, blocks: &mut [GenericArray]); -} - -/// Trait for a block cipher mode of operation block-level decryptor. -/// -/// This trait operates only on blocks, for convinient slice-based methods with padding -/// see the [`BlockModeDecryptWrapper`][crate::BlockModeDecryptWrapper] type. -pub trait BlockModeDecrypt: BlockMode { - /// Decrypt blocks of data. - fn decrypt_blocks(&mut self, blocks: &mut [GenericArray]); -} - -/// Trait for a block mode, used to obtain the current state in the form of an IV -/// that can initialize a BlockMode later and resume the original operation. -/// -/// The IV value SHOULD be used for resuming operations only and MUST NOT be -/// exposed to attackers. Failing to comply with this requirement breaks -/// unpredictability and opens attack venues (see e.g. [1], sec. 3.6.2). -/// -/// [1]: https://www.cs.umd.edu/~jkatz/imc.html -pub trait BlockModeIvState: FromKeyNonce { - /// Returns the IV needed to process the following block. This value MUST - /// NOT be exposed to attackers. - fn iv_state(&self) -> GenericArray; -} diff --git a/cipher/src/mode_wrapper.rs b/cipher/src/mode_wrapper.rs deleted file mode 100644 index 36f379c3e..000000000 --- a/cipher/src/mode_wrapper.rs +++ /dev/null @@ -1,194 +0,0 @@ -//! Convinience wrapper around types which implement `BlockMode`. - -use crate::errors::BlockModeError; -use crate::{BlockModeDecrypt, BlockModeEncrypt, FromBlockCipherNonce}; -use block_buffer::{block_padding::Padding, BlockBuffer, LazyBlockBuffer}; -use core::{marker::PhantomData, slice::from_mut}; -use generic_array::{typenum::Unsigned, GenericArray}; - -/// Convinience wrapper around the [`BlockModeEncrypt`] trait, which handles -/// data buffering and provides slice-based methods. -pub struct BlockModeEncryptWrapper> { - inner: M, - buffer: BlockBuffer, - _p: PhantomData

, -} - -impl FromBlockCipherNonce for BlockModeEncryptWrapper -where - M: BlockModeEncrypt + FromBlockCipherNonce, - P: Padding, -{ - type BlockCipher = M::BlockCipher; - type NonceSize = M::NonceSize; - - fn from_block_cipher_nonce( - cipher: Self::BlockCipher, - nonce: &GenericArray, - ) -> Self { - Self { - inner: M::from_block_cipher_nonce(cipher, nonce), - buffer: Default::default(), - _p: Default::default(), - } - } -} - -impl BlockModeEncryptWrapper -where - M: BlockModeEncrypt, - P: Padding, -{ - /// Encrypt part of a plaintext. - /// - /// This mehthod MUST be used in conjuction with the [`encrypt_final`][Self::encrypt_final] method, - /// otherwise plaintext will not be properly padded and may be truncated. - /// - /// The method encrypts plaintext in `data`, writes the resulting plaintext - /// into `out_buf`, and returns it in the `Ok` variant. If a whole message - /// can not be processed, it caches plaintext leftovers into inner buffer - /// for future use. - /// - /// It's recommended for `out_buf` to be at least one block longer than - /// `data`, otherwise the method can return `Err(BlockModeError)` if there is - /// not enough space for encrypted blocks. - #[inline] - pub fn encrypt_part<'a>( - &mut self, - plaintext: &[u8], - out_buf: &'a mut [u8], - ) -> Result<&'a [u8], BlockModeError> { - let Self { inner, buffer, .. } = self; - buffer - .block_mode_processing(plaintext, out_buf, |blocks| inner.encrypt_blocks(blocks)) - .map_err(|_| BlockModeError) - } - - /// Pad and encrypt plaintext. - /// - /// The method pads `plaintext` and encrypts it writing the resulting - /// ciphertext into `out_buf`. - /// - /// It's recommended for `out_buf` to be at least one block longer than - /// `data`, otherwise the method can return `Err(BlockModeError)` if there is - /// not enough space for encrypted blocks. - #[inline] - pub fn encrypt_final<'a>( - mut self, - plaintext: &[u8], - out_buf: &'a mut [u8], - ) -> Result<&'a [u8], BlockModeError> { - let Self { inner, buffer, .. } = &mut self; - let res_len = buffer - .block_mode_processing(plaintext, out_buf, |blocks| inner.encrypt_blocks(blocks)) - .map_err(|_| BlockModeError)? - .len(); - let final_block = buffer.pad_with::

(); - inner.encrypt_blocks(from_mut(final_block)); - - let bs = M::BlockSize::USIZE; - let final_len = res_len.checked_add(bs).ok_or(BlockModeError)?; - let buf = out_buf.get_mut(..final_len).ok_or(BlockModeError)?; - // note: even though `buf[t..]` and `buf[res_len..]` are guaranteed to be - // equivalent, compiler generates a panic branch for the latter. - let t = final_len - bs; - debug_assert_eq!(t, res_len); - buf[t..].copy_from_slice(final_block); - Ok(buf) - } -} - -/// Convinience wrapper around the [`BlockModeDecrypt`] trait, which handles -/// data buffering and provides slice-based methods. -pub struct BlockModeDecryptWrapper> { - inner: M, - buffer: LazyBlockBuffer, - _p: PhantomData

, -} - -impl FromBlockCipherNonce for BlockModeDecryptWrapper -where - M: BlockModeDecrypt + FromBlockCipherNonce, - P: Padding, -{ - type BlockCipher = M::BlockCipher; - type NonceSize = M::NonceSize; - - fn from_block_cipher_nonce( - cipher: Self::BlockCipher, - nonce: &GenericArray, - ) -> Self { - Self { - inner: M::from_block_cipher_nonce(cipher, nonce), - buffer: Default::default(), - _p: Default::default(), - } - } -} - -impl BlockModeDecryptWrapper -where - M: BlockModeDecrypt, - P: Padding, -{ - /// Decrypt part of a ciphertext. - /// - /// This mehthod MUST be used in conjuction with the [`decrypt_final`] method, - /// otherwise plaintext will not be properly padded and may be truncated. - /// - /// The method decrypts `ciphertext`, writes the resulting plaintext - /// into `out_buf`, and returns it in the `Ok` variant. If a whole message - /// can not be processed, it caches ciphertext leftovers into inner buffer - /// for future use. - /// - /// It's recommended for `out_buf` to be at least one block longer than - /// `data`, otherwise the method can return `Err(BlockModeError)` if there is - /// not enough space for encrypted blocks. - /// - /// [`decrypt_final`]: Self::decrypt_final - #[inline] - pub fn decrypt_part<'a>( - &mut self, - ciphertext: &[u8], - out_buf: &'a mut [u8], - ) -> Result<&'a [u8], BlockModeError> { - let Self { inner, buffer, .. } = self; - buffer - .block_mode_processing(ciphertext, out_buf, |blocks| inner.decrypt_blocks(blocks)) - .map_err(|_| BlockModeError) - } - - /// Pad and decrypt plaintext. - /// - /// The method decrypts ciphertext, writes the resulting plaintext into - /// into `out_buf`, and unpads it. - /// - /// It's recommended for `out_buf` to be at least one block longer than - /// `data`, otherwise the method can return `Err(BlockModeError)` if there is - /// not enough space for encrypted blocks. - #[inline] - pub fn decrypt_final<'a>( - mut self, - ciphertext: &[u8], - out_buf: &'a mut [u8], - ) -> Result<&'a [u8], BlockModeError> { - let Self { inner, buffer, .. } = &mut self; - let res_len = buffer - .block_mode_processing(ciphertext, out_buf, |blocks| inner.decrypt_blocks(blocks)) - .map_err(|_| BlockModeError)? - .len(); - let final_block = buffer.get_full_block().ok_or(BlockModeError)?; - inner.decrypt_blocks(from_mut(final_block)); - let tail = P::unpad(final_block).map_err(|_| BlockModeError)?; - - let tail_len = tail.len(); - let final_len = res_len.checked_add(tail_len).ok_or(BlockModeError)?; - let buf = out_buf.get_mut(..final_len).ok_or(BlockModeError)?; - // note: even though `buf[t..]` and `buf[res_len..]` are guaranteed to be - // equivalent, compiler generates a panic branch for the latter. - let t = final_len - tail_len; - debug_assert_eq!(t, res_len); - buf[t..].copy_from_slice(tail); - Ok(buf) - } -} diff --git a/cipher/src/stream.rs b/cipher/src/stream.rs index 0e7d88ede..6f0fa67ee 100644 --- a/cipher/src/stream.rs +++ b/cipher/src/stream.rs @@ -3,48 +3,159 @@ //! See [RustCrypto/stream-ciphers](https://github.com/RustCrypto/stream-ciphers) //! for ciphers implementation. -use crate::errors::{LoopError, OverflowError}; -use core::convert::{TryFrom, TryInto}; +use crate::errors::{OverflowError, StreamCipherError}; +use crate::stream_core::Counter; +use crate::{Block, BlockDecryptMut, BlockEncryptMut}; +use inout::{InOutBuf, NotEqualError}; + +/// Marker trait for block-level asynchronous stream ciphers +pub trait AsyncStreamCipher: Sized { + /// Encrypt data using `InOutBuf`. + fn encrypt_inout(mut self, data: InOutBuf<'_, '_, u8>) + where + Self: BlockEncryptMut, + { + let (blocks, mut tail) = data.into_chunks(); + self.encrypt_blocks_inout_mut(blocks); + let mut block = Block::::default(); + let n = tail.len(); + if n != 0 { + block[..n].copy_from_slice(tail.get_in()); + self.encrypt_block_mut(&mut block); + tail.get_out().copy_from_slice(&block[..n]); + } + } + + /// Decrypt data using `InOutBuf`. + fn decrypt_inout(mut self, data: InOutBuf<'_, '_, u8>) + where + Self: BlockDecryptMut, + { + let (blocks, mut tail) = data.into_chunks(); + self.decrypt_blocks_inout_mut(blocks); + let mut block = Block::::default(); + let n = tail.len(); + if n != 0 { + block[..n].copy_from_slice(tail.get_in()); + self.decrypt_block_mut(&mut block); + tail.get_out().copy_from_slice(&block[..n]); + } + } + /// Encrypt data in place. + fn encrypt(self, buf: &mut [u8]) + where + Self: BlockEncryptMut, + { + self.encrypt_inout(buf.into()); + } + + /// Decrypt data in place. + fn decrypt(self, buf: &mut [u8]) + where + Self: BlockDecryptMut, + { + self.decrypt_inout(buf.into()); + } + + /// Encrypt data from buffer to buffer. + fn encrypt_b2b(self, in_buf: &[u8], out_buf: &mut [u8]) -> Result<(), NotEqualError> + where + Self: BlockEncryptMut, + { + InOutBuf::new(in_buf, out_buf).map(|b| self.encrypt_inout(b)) + } + + /// Decrypt data from buffer to buffer. + fn decrypt_b2b(self, in_buf: &[u8], out_buf: &mut [u8]) -> Result<(), NotEqualError> + where + Self: BlockDecryptMut, + { + InOutBuf::new(in_buf, out_buf).map(|b| self.decrypt_inout(b)) + } +} /// Synchronous stream cipher core trait. pub trait StreamCipher { - /// Apply keystream to the data. + /// Apply keystream to `inout` data. + /// + /// If end of the keystream will be achieved with the given data length, + /// method will return [`StreamCipherError`] without modifying provided `data`. + fn try_apply_keystream_inout( + &mut self, + buf: InOutBuf<'_, '_, u8>, + ) -> Result<(), StreamCipherError>; + + /// Apply keystream to data behind `buf`. + /// + /// If end of the keystream will be achieved with the given data length, + /// method will return [`StreamCipherError`] without modifying provided `data`. + #[inline] + fn try_apply_keystream(&mut self, buf: &mut [u8]) -> Result<(), StreamCipherError> { + self.try_apply_keystream_inout(buf.into()) + } + + /// Apply keystream to `inout` data. /// - /// It will XOR generated keystream with the data, which can be both - /// encryption and decryption. + /// It will XOR generated keystream with the data behind `in` pointer + /// and will write result to `out` pointer. /// /// # Panics /// If end of the keystream will be reached with the given data length, /// method will panic without modifying the provided `data`. #[inline] - fn apply_keystream(&mut self, data: &mut [u8]) { - self.try_apply_keystream(data).unwrap(); + fn apply_keystream_inout(&mut self, buf: InOutBuf<'_, '_, u8>) { + self.try_apply_keystream_inout(buf).unwrap(); } - /// Apply keystream to the data, but return an error if end of a keystream - /// will be reached. + /// Apply keystream to data in-place. /// - /// If end of the keystream will be achieved with the given data length, - /// method will return `Err(LoopError)` without modifying provided `data`. - fn try_apply_keystream(&mut self, data: &mut [u8]) -> Result<(), LoopError>; + /// It will XOR generated keystream with `data` and will write result + /// to the same buffer. + /// + /// # Panics + /// If end of the keystream will be reached with the given data length, + /// method will panic without modifying the provided `data`. + #[inline] + fn apply_keystream(&mut self, buf: &mut [u8]) { + self.try_apply_keystream(buf).unwrap(); + } + + /// Apply keystream to data buffer-to-buffer. + /// + /// It will XOR generated keystream with data from the `input` buffer + /// and will write result to the `output` buffer. + /// + /// Returns [`StreamCipherError`] if provided `in_blocks` and `out_blocks` + /// have different lengths or if end of the keystream will be reached with + /// the given input data length. + #[inline] + fn apply_keystream_b2b( + &mut self, + input: &[u8], + output: &mut [u8], + ) -> Result<(), StreamCipherError> { + InOutBuf::new(input, output) + .map_err(|_| StreamCipherError) + .and_then(|buf| self.try_apply_keystream_inout(buf)) + } } /// Trait for seekable stream ciphers. /// /// Methods of this trait are generic over the [`SeekNum`] trait, which is -/// implemented for primitive numeric types, i.e.: `i/u8`, `i/u16`, `i/u32`, -/// `i/u64`, `i/u128`, and `i/usize`. +/// implemented for primitive numeric types, i.e.: `i32`, `u32`, `u64`, +/// `u128`, and `usize`. pub trait StreamCipherSeek { /// Try to get current keystream position /// - /// Returns [`LoopError`] if position can not be represented by type `T` + /// Returns [`OverflowError`] if position can not be represented by type `T` fn try_current_pos(&self) -> Result; /// Try to seek to the given position /// - /// Returns [`LoopError`] if provided position value is bigger than + /// Returns [`StreamCipherError`] if provided position value is bigger than /// keystream length. - fn try_seek(&mut self, pos: T) -> Result<(), LoopError>; + fn try_seek(&mut self, pos: T) -> Result<(), StreamCipherError>; /// Get current keystream position /// @@ -57,70 +168,51 @@ pub trait StreamCipherSeek { /// Seek to the given position /// /// # Panics - /// If provided position value is bigger than keystream length + /// If provided position value is bigger than keystream leangth fn seek(&mut self, pos: T) { self.try_seek(pos).unwrap() } } -/// Asynchronous stream cipher core trait. -pub trait AsyncStreamCipher { - /// Encrypt data in place. - fn encrypt(&mut self, data: &mut [u8]); - - /// Decrypt data in place. - fn decrypt(&mut self, data: &mut [u8]); -} - impl StreamCipher for &mut C { #[inline] - fn apply_keystream(&mut self, data: &mut [u8]) { - C::apply_keystream(self, data); - } - - #[inline] - fn try_apply_keystream(&mut self, data: &mut [u8]) -> Result<(), LoopError> { - C::try_apply_keystream(self, data) + fn try_apply_keystream_inout( + &mut self, + buf: InOutBuf<'_, '_, u8>, + ) -> Result<(), StreamCipherError> { + C::try_apply_keystream_inout(self, buf) } } /// Trait implemented for numeric types which can be used with the /// [`StreamCipherSeek`] trait. /// -/// This trait is implemented for primitive numeric types, i.e. `i/u8`, -/// `u16`, `u32`, `u64`, `u128`, `usize`, and `i32`. It is not intended -/// to be implemented in third-party crates. -#[rustfmt::skip] -pub trait SeekNum: - Sized - + TryInto + TryFrom + TryInto + TryFrom - + TryInto + TryFrom + TryInto + TryFrom - + TryInto + TryFrom + TryInto + TryFrom - + TryInto + TryFrom + TryInto + TryFrom - + TryInto + TryFrom + TryInto + TryFrom - + TryInto + TryFrom + TryInto + TryFrom -{ +/// This trait is implemented for `i32`, `u32`, `u64`, `u128`, and `usize`. +/// It is not intended to be implemented in third-party crates. +pub trait SeekNum: Sized { /// Try to get position for block number `block`, byte position inside /// block `byte`, and block size `bs`. - fn from_block_byte(block: T, byte: u8, bs: u8) -> Result; + fn from_block_byte(block: T, byte: u8, bs: u8) -> Result; /// Try to get block number and bytes position for given block size `bs`. - #[allow(clippy::wrong_self_convention)] - fn to_block_byte(self, bs: u8) -> Result<(T, u8), OverflowError>; + fn into_block_byte(self, bs: u8) -> Result<(T, u8), OverflowError>; } macro_rules! impl_seek_num { {$($t:ty )*} => { $( impl SeekNum for $t { - fn from_block_byte>(block: T, byte: u8, bs: u8) -> Result { + fn from_block_byte(block: T, byte: u8, bs: u8) -> Result { debug_assert!(byte < bs); - let block = block.try_into().map_err(|_| OverflowError)?; + let mut block: Self = block.try_into().map_err(|_| OverflowError)?; + if byte != 0 { + block -= 1; + } let pos = block.checked_mul(bs as Self).ok_or(OverflowError)? + (byte as Self); Ok(pos) } - fn to_block_byte>(self, bs: u8) -> Result<(T, u8), OverflowError> { + fn into_block_byte(self, bs: u8) -> Result<(T, u8), OverflowError> { let bs = bs as Self; let byte = self % bs; let block = T::try_from(self/bs).map_err(|_| OverflowError)?; @@ -131,4 +223,4 @@ macro_rules! impl_seek_num { }; } -impl_seek_num! { u8 u16 u32 u64 u128 usize i32 } +impl_seek_num! { i32 u32 u64 u128 usize } diff --git a/cipher/src/stream_core.rs b/cipher/src/stream_core.rs new file mode 100644 index 000000000..bb4d9a43a --- /dev/null +++ b/cipher/src/stream_core.rs @@ -0,0 +1,301 @@ +use crate::{ParBlocks, ParBlocksSizeUser, StreamCipherError}; +use crypto_common::{ + generic_array::{ArrayLength, GenericArray}, + typenum::Unsigned, + Block, BlockSizeUser, +}; +use inout::{InOut, InOutBuf}; + +/// Trait implemented by stream cipher backends. +pub trait StreamBackend: ParBlocksSizeUser { + /// Generate keystream block. + fn gen_ks_block(&mut self, block: &mut Block); + + /// Generate keystream blocks in parallel. + #[inline(always)] + fn gen_par_ks_blocks(&mut self, blocks: &mut ParBlocks) { + for block in blocks { + self.gen_ks_block(block); + } + } + + /// Generate keystream blocks. Length of the buffer MUST be smaller + /// than `Self::ParBlocksSize`. + #[inline(always)] + fn gen_tail_blocks(&mut self, blocks: &mut [Block]) { + assert!(blocks.len() < Self::ParBlocksSize::USIZE); + for block in blocks { + self.gen_ks_block(block); + } + } +} + +/// Trait for [`StreamBackend`] users. +/// +/// This trait is used to define rank-2 closures. +pub trait StreamClosure: BlockSizeUser { + /// Execute closure with the provided stream cipher backend. + fn call>(self, backend: &mut B); +} + +/// Block-level synchronous stream ciphers. +pub trait StreamCipherCore: BlockSizeUser + Sized { + /// Return number of remaining blocks before cipher wraps around. + /// + /// Returns `None` if number of remaining blocks can not be computed + /// (e.g. in ciphers based on the sponge construction) or it's too big + /// to fit into `usize`. + fn remaining_blocks(&self) -> Option; + + /// Process data using backend provided to the rank-2 closure. + fn process_with_backend(&mut self, f: impl StreamClosure); + + /// Write keystream block. + /// + /// WARNING: this method does not check number of remaining blocks! + #[inline] + fn write_keystream_block(&mut self, block: &mut Block) { + self.process_with_backend(WriteBlockCtx { block }); + } + + /// Write keystream blocks. + /// + /// WARNING: this method does not check number of remaining blocks! + #[inline] + fn write_keystream_blocks(&mut self, blocks: &mut [Block]) { + self.process_with_backend(WriteBlocksCtx { blocks }); + } + + /// Apply keystream block. + /// + /// WARNING: this method does not check number of remaining blocks! + #[inline] + fn apply_keystream_block_inout(&mut self, block: InOut<'_, '_, Block>) { + self.process_with_backend(ApplyBlockCtx { block }); + } + + /// Apply keystream blocks. + /// + /// WARNING: this method does not check number of remaining blocks! + #[inline] + fn apply_keystream_blocks(&mut self, blocks: &mut [Block]) { + self.process_with_backend(ApplyBlocksCtx { + blocks: blocks.into(), + }); + } + + /// Apply keystream blocks. + /// + /// WARNING: this method does not check number of remaining blocks! + #[inline] + fn apply_keystream_blocks_inout(&mut self, blocks: InOutBuf<'_, '_, Block>) { + self.process_with_backend(ApplyBlocksCtx { blocks }); + } + + /// Try to apply keystream to data not divided into blocks. + /// + /// Consumes cipher since it may consume final keystream block only + /// partially. + /// + /// Returns an error if number of remaining blocks is not sufficient + /// for processing the input data. + #[inline] + fn try_apply_keystream_partial( + mut self, + mut buf: InOutBuf<'_, '_, u8>, + ) -> Result<(), StreamCipherError> { + if let Some(rem) = self.remaining_blocks() { + let blocks = if buf.len() % Self::BlockSize::USIZE == 0 { + buf.len() % Self::BlockSize::USIZE + } else { + buf.len() % Self::BlockSize::USIZE + 1 + }; + if blocks > rem { + return Err(StreamCipherError); + } + } + + if buf.len() > Self::BlockSize::USIZE { + let (blocks, tail) = buf.into_chunks(); + self.apply_keystream_blocks_inout(blocks); + buf = tail; + } + let n = buf.len(); + if n == 0 { + return Ok(()); + } + let mut block = Block::::default(); + block[..n].copy_from_slice(buf.get_in()); + let t = InOutBuf::from_mut(&mut block); + self.apply_keystream_blocks_inout(t); + buf.get_out().copy_from_slice(&block[..n]); + Ok(()) + } + + /// Try to apply keystream to data not divided into blocks. + /// + /// Consumes cipher since it may consume final keystream block only + /// partially. + /// + /// # Panics + /// If number of remaining blocks is not sufficient for processing the + /// input data. + #[inline] + fn apply_keystream_partial(self, buf: InOutBuf<'_, '_, u8>) { + self.try_apply_keystream_partial(buf).unwrap() + } +} + +// note: unfortunately, currently we can not write blanket impls of +// `BlockEncryptMut` and `BlockDecryptMut` for `T: StreamCipherCore` +// since it requires mutually exlusive traits, see: +// https://github.com/rust-lang/rfcs/issues/1053 + +/// Counter type usable with [`StreamCipherCore`]. +/// +/// This trait is implemented for `i32`, `u32`, `u64`, `u128`, and `usize`. +/// It's not intended to be implemented in third-party crates, but doing so +/// is not forbidden. +pub trait Counter: + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryInto + + TryInto + + TryInto + + TryInto + + TryInto +{ +} + +/// Block-level seeking trait for stream ciphers. +pub trait StreamCipherSeekCore: StreamCipherCore { + /// Counter type used inside stream cipher. + type Counter: Counter; + + /// Get current block position. + fn get_block_pos(&self) -> Self::Counter; + + /// Set block position. + fn set_block_pos(&mut self, pos: Self::Counter); +} + +macro_rules! impl_counter { + {$($t:ty )*} => { + $( impl Counter for $t { } )* + }; +} + +impl_counter! { u32 u64 u128 } + +/// Partition buffer into 2 parts: buffer of arrays and tail. +/// +/// In case if `N` is less or equal to 1, buffer of arrays has length +/// of zero and tail is equal to `self`. +#[inline] +fn into_chunks>(buf: &mut [T]) -> (&mut [GenericArray], &mut [T]) { + use core::slice; + if N::USIZE <= 1 { + return (&mut [], buf); + } + let chunks_len = buf.len() / N::USIZE; + let tail_pos = N::USIZE * chunks_len; + let tail_len = buf.len() - tail_pos; + unsafe { + let ptr = buf.as_mut_ptr(); + let chunks = slice::from_raw_parts_mut(ptr as *mut GenericArray, chunks_len); + let tail = slice::from_raw_parts_mut(ptr.add(tail_pos), tail_len); + (chunks, tail) + } +} + +struct WriteBlockCtx<'a, BS: ArrayLength> { + block: &'a mut Block, +} +impl<'a, BS: ArrayLength> BlockSizeUser for WriteBlockCtx<'a, BS> { + type BlockSize = BS; +} +impl<'a, BS: ArrayLength> StreamClosure for WriteBlockCtx<'a, BS> { + #[inline(always)] + fn call>(self, backend: &mut B) { + backend.gen_ks_block(self.block); + } +} + +struct WriteBlocksCtx<'a, BS: ArrayLength> { + blocks: &'a mut [Block], +} +impl<'a, BS: ArrayLength> BlockSizeUser for WriteBlocksCtx<'a, BS> { + type BlockSize = BS; +} +impl<'a, BS: ArrayLength> StreamClosure for WriteBlocksCtx<'a, BS> { + #[inline(always)] + fn call>(self, backend: &mut B) { + if B::ParBlocksSize::USIZE > 1 { + let (chunks, tail) = into_chunks::<_, B::ParBlocksSize>(self.blocks); + for chunk in chunks { + backend.gen_par_ks_blocks(chunk); + } + backend.gen_tail_blocks(tail); + } else { + for block in self.blocks { + backend.gen_ks_block(block); + } + } + } +} + +struct ApplyBlockCtx<'inp, 'out, BS: ArrayLength> { + block: InOut<'inp, 'out, Block>, +} + +impl<'inp, 'out, BS: ArrayLength> BlockSizeUser for ApplyBlockCtx<'inp, 'out, BS> { + type BlockSize = BS; +} + +impl<'inp, 'out, BS: ArrayLength> StreamClosure for ApplyBlockCtx<'inp, 'out, BS> { + #[inline(always)] + fn call>(mut self, backend: &mut B) { + let mut t = Default::default(); + backend.gen_ks_block(&mut t); + self.block.xor_in2out(&t); + } +} + +struct ApplyBlocksCtx<'inp, 'out, BS: ArrayLength> { + blocks: InOutBuf<'inp, 'out, Block>, +} + +impl<'inp, 'out, BS: ArrayLength> BlockSizeUser for ApplyBlocksCtx<'inp, 'out, BS> { + type BlockSize = BS; +} + +impl<'inp, 'out, BS: ArrayLength> StreamClosure for ApplyBlocksCtx<'inp, 'out, BS> { + #[inline(always)] + #[allow(clippy::needless_range_loop)] + fn call>(self, backend: &mut B) { + if B::ParBlocksSize::USIZE > 1 { + let (chunks, mut tail) = self.blocks.into_chunks::(); + for mut chunk in chunks { + let mut tmp = Default::default(); + backend.gen_par_ks_blocks(&mut tmp); + chunk.xor_in2out(&tmp); + } + let n = tail.len(); + let mut buf = GenericArray::<_, B::ParBlocksSize>::default(); + let ks = &mut buf[..n]; + backend.gen_tail_blocks(ks); + for i in 0..n { + tail.get(i).xor_in2out(&ks[i]); + } + } else { + for mut block in self.blocks { + let mut t = Default::default(); + backend.gen_ks_block(&mut t); + block.xor_in2out(&t); + } + } + } +} diff --git a/cipher/src/stream_wrapper.rs b/cipher/src/stream_wrapper.rs new file mode 100644 index 000000000..21f861638 --- /dev/null +++ b/cipher/src/stream_wrapper.rs @@ -0,0 +1,239 @@ +use crate::{ + errors::StreamCipherError, Block, OverflowError, SeekNum, StreamCipher, StreamCipherCore, + StreamCipherSeek, StreamCipherSeekCore, +}; +use crypto_common::{ + typenum::{IsLess, Le, NonZero, Unsigned, U256}, + BlockSizeUser, Iv, IvSizeUser, Key, KeyInit, KeyIvInit, KeySizeUser, +}; +use inout::InOutBuf; +#[cfg(feature = "zeroize")] +use zeroize::{Zeroize, ZeroizeOnDrop}; + +/// Wrapper around [`StreamCipherCore`] implementations. +/// +/// It handles data buffering and implements the slice-based traits. +#[derive(Clone, Default)] +pub struct StreamCipherCoreWrapper +where + T::BlockSize: IsLess, + Le: NonZero, +{ + core: T, + buffer: Block, + pos: u8, +} + +impl StreamCipherCoreWrapper +where + T::BlockSize: IsLess, + Le: NonZero, +{ + /// Return reference to the core type. + pub fn get_core(&self) -> &T { + &self.core + } + + /// Return reference to the core type. + pub fn from_core(core: T) -> Self { + Self { + core, + buffer: Default::default(), + pos: 0, + } + } + + /// Return current cursor position. + #[inline] + fn get_pos(&self) -> usize { + let pos = self.pos as usize; + if pos >= T::BlockSize::USIZE { + debug_assert!(false); + // SAFETY: `pos` is set only to values smaller than block size + unsafe { core::hint::unreachable_unchecked() } + } + self.pos as usize + } + + /// Return size of the internall buffer in bytes. + #[inline] + fn size(&self) -> usize { + T::BlockSize::USIZE + } + + #[inline] + fn set_pos_unchecked(&mut self, pos: usize) { + debug_assert!(pos < T::BlockSize::USIZE); + self.pos = pos as u8; + } + + /// Return number of remaining bytes in the internall buffer. + #[inline] + fn remaining(&self) -> usize { + self.size() - self.get_pos() + } + + fn check_remaining(&self, dlen: usize) -> Result<(), StreamCipherError> { + let rem_blocks = match self.core.remaining_blocks() { + Some(v) => v, + None => return Ok(()), + }; + + let bytes = if self.pos == 0 { + dlen + } else { + let rem = self.remaining(); + if dlen > rem { + dlen - rem + } else { + return Ok(()); + } + }; + let bs = T::BlockSize::USIZE; + let blocks = if bytes % bs == 0 { + bytes / bs + } else { + bytes / bs + 1 + }; + if blocks > rem_blocks { + Err(StreamCipherError) + } else { + Ok(()) + } + } +} + +impl StreamCipher for StreamCipherCoreWrapper +where + T::BlockSize: IsLess, + Le: NonZero, +{ + #[inline] + fn try_apply_keystream_inout( + &mut self, + mut data: InOutBuf<'_, '_, u8>, + ) -> Result<(), StreamCipherError> { + self.check_remaining(data.len())?; + + let pos = self.get_pos(); + if pos != 0 { + let rem = &self.buffer[pos..]; + let n = data.len(); + if n < rem.len() { + data.xor_in2out(&rem[..n]); + self.set_pos_unchecked(pos + n); + return Ok(()); + } + let (mut left, right) = data.split_at(rem.len()); + data = right; + left.xor_in2out(rem); + } + + let (blocks, mut leftover) = data.into_chunks(); + self.core.apply_keystream_blocks_inout(blocks); + + let n = leftover.len(); + if n != 0 { + self.core.write_keystream_block(&mut self.buffer); + leftover.xor_in2out(&self.buffer[..n]); + } + self.set_pos_unchecked(n); + + Ok(()) + } +} + +impl StreamCipherSeek for StreamCipherCoreWrapper +where + T::BlockSize: IsLess, + Le: NonZero, +{ + fn try_current_pos(&self) -> Result { + let Self { core, pos, .. } = self; + SN::from_block_byte(core.get_block_pos(), *pos, T::BlockSize::U8) + } + + fn try_seek(&mut self, new_pos: SN) -> Result<(), StreamCipherError> { + let Self { core, buffer, pos } = self; + let (block_pos, byte_pos) = new_pos.into_block_byte(T::BlockSize::U8)?; + core.set_block_pos(block_pos); + if byte_pos != 0 { + self.core.write_keystream_block(buffer); + } + *pos = byte_pos; + Ok(()) + } +} + +// Note: ideally we would only implement the InitInner trait and everything +// else would be handled by blanket impls, but unfortunately it will +// not work properly without mutually exclusive traits, see: +// https://github.com/rust-lang/rfcs/issues/1053 + +impl KeySizeUser for StreamCipherCoreWrapper +where + T::BlockSize: IsLess, + Le: NonZero, +{ + type KeySize = T::KeySize; +} + +impl IvSizeUser for StreamCipherCoreWrapper +where + T::BlockSize: IsLess, + Le: NonZero, +{ + type IvSize = T::IvSize; +} + +impl KeyIvInit for StreamCipherCoreWrapper +where + T::BlockSize: IsLess, + Le: NonZero, +{ + #[inline] + fn new(key: &Key, iv: &Iv) -> Self { + Self { + core: T::new(key, iv), + buffer: Default::default(), + pos: 0, + } + } +} + +impl KeyInit for StreamCipherCoreWrapper +where + T::BlockSize: IsLess, + Le: NonZero, +{ + #[inline] + fn new(key: &Key) -> Self { + Self { + core: T::new(key), + buffer: Default::default(), + pos: 0, + } + } +} + +#[cfg(feature = "zeroize")] +impl Drop for StreamCipherCoreWrapper +where + T: BlockSizeUser, + T::BlockSize: IsLess, + Le: NonZero, +{ + fn drop(&mut self) { + self.buffer.zeroize(); + self.pos.zeroize(); + } +} + +#[cfg(feature = "zeroize")] +impl ZeroizeOnDrop for StreamCipherCoreWrapper +where + T: BlockSizeUser + ZeroizeOnDrop, + T::BlockSize: IsLess, + Le: NonZero, +{ +} diff --git a/crypto-common/CHANGELOG.md b/crypto-common/CHANGELOG.md index b5cf73540..98541eaad 100644 --- a/crypto-common/CHANGELOG.md +++ b/crypto-common/CHANGELOG.md @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.1.2 (2022-02-10) +### Added +- Re-export `generic-array` and `typenum`. Enable `more_lengths` feature on +`generic-array`. Add `key_size`, `iv_size`, `block_size`, and `output_size` +helper methods. ([#849]) + +[#849]: https://github.com/RustCrypto/traits/pull/849 + ## 0.1.1 (2021-12-14) ### Added - `rand_core` re-export and proper exposure of key/IV generation methods on docs.rs ([#847]) diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index 1b629b109..67249f0b0 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crypto-common" description = "Common cryptographic traits" -version = "0.1.1" # Also update html_root_url in lib.rs when bumping this +version = "0.1.2" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" @@ -12,7 +12,7 @@ keywords = ["crypto", "traits"] categories = ["cryptography", "no-std"] [dependencies] -generic-array = "0.14" +generic-array = { version = "0.14.4", features = ["more_lengths"] } rand_core = { version = "0.6", optional = true } [features] diff --git a/crypto-common/src/lib.rs b/crypto-common/src/lib.rs index f1e1570bc..62807bbb4 100644 --- a/crypto-common/src/lib.rs +++ b/crypto-common/src/lib.rs @@ -16,6 +16,9 @@ extern crate std; #[cfg(feature = "rand_core")] pub use rand_core; +pub use generic_array; +pub use generic_array::typenum; + use core::fmt; use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; #[cfg(feature = "rand_core")] @@ -34,6 +37,11 @@ pub type Iv = GenericArray::IvSize>; pub trait BlockSizeUser { /// Size of the block in bytes. type BlockSize: ArrayLength + 'static; + + /// Return block size in bytes. + fn block_size() -> usize { + Self::BlockSize::USIZE + } } impl BlockSizeUser for &T { @@ -48,6 +56,11 @@ impl BlockSizeUser for &mut T { pub trait OutputSizeUser { /// Size of the output in bytes. type OutputSize: ArrayLength + 'static; + + /// Return output size in bytes. + fn output_size() -> usize { + Self::OutputSize::USIZE + } } /// Types which use key for initialization. @@ -56,6 +69,11 @@ pub trait OutputSizeUser { pub trait KeySizeUser { /// Key size in bytes. type KeySize: ArrayLength + 'static; + + /// Return key size in bytes. + fn key_size() -> usize { + Self::KeySize::USIZE + } } /// Types which use initialization vector (nonce) for initialization. @@ -64,6 +82,11 @@ pub trait KeySizeUser { pub trait IvSizeUser { /// Initialization vector size in bytes. type IvSize: ArrayLength + 'static; + + /// Return IV size in bytes. + fn iv_size() -> usize { + Self::IvSize::USIZE + } } /// Types which use another type for initialization. diff --git a/digest/CHANGELOG.md b/digest/CHANGELOG.md index f72a9825c..5e18564c6 100644 --- a/digest/CHANGELOG.md +++ b/digest/CHANGELOG.md @@ -5,13 +5,19 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.10.2 (2022-02-10) +### Changed +- Relaxed bounds on the `Mac` trait ([#849]) + +[#849]: https://github.com/RustCrypto/traits/pull/849 + ## 0.10.1 (2021-12-14) ### Added - `Update::chain` and `Digest::new_with_prefix` methods. ([#846]) - `Mac::generate_key` method. ([#847]) ### Fixed -- Doc cfg attribute for CtOutput and MacError. ([#842]) +- Doc cfg attribute for `CtOutput` and `MacError`. ([#842]) - Expose `KeyInit::generate_key` method in docs. ([#847]) [#842]: https://github.com/RustCrypto/traits/pull/842 diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 037216dda..0b9020fa7 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "digest" description = "Traits for cryptographic hash functions" -version = "0.10.1" # Also update html_root_url in lib.rs when bumping this +version = "0.10.2" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" @@ -12,8 +12,7 @@ keywords = ["digest", "crypto", "hash"] categories = ["cryptography", "no-std"] [dependencies] -generic-array = "0.14.4" -crypto-common = { version = "0.1.1", path = "../crypto-common" } +crypto-common = { version = "0.1.2", path = "../crypto-common" } block-buffer = { version = "0.10", optional = true } subtle = { version = "=2.4", default-features = false, optional = true } diff --git a/digest/src/core_api.rs b/digest/src/core_api.rs index 6783e1985..2cf384efe 100644 --- a/digest/src/core_api.rs +++ b/digest/src/core_api.rs @@ -4,12 +4,14 @@ //! core algorithm wrapped by the wrapper types, which implement the //! higher-level traits. use crate::InvalidOutputSize; -use generic_array::typenum::{IsLess, Le, NonZero, U256}; pub use crypto_common::{AlgorithmName, Block, BlockSizeUser, OutputSizeUser, Reset}; use block_buffer::{BlockBuffer, BufferKind}; -use crypto_common::Output; +use crypto_common::{ + typenum::{IsLess, Le, NonZero, U256}, + Output, +}; mod ct_variable; mod rt_variable; diff --git a/digest/src/core_api/ct_variable.rs b/digest/src/core_api/ct_variable.rs index c69544912..40efff65c 100644 --- a/digest/src/core_api/ct_variable.rs +++ b/digest/src/core_api/ct_variable.rs @@ -6,10 +6,10 @@ use crate::HashMarker; #[cfg(feature = "mac")] use crate::MacMarker; use core::{fmt, marker::PhantomData}; -use crypto_common::{Block, BlockSizeUser, OutputSizeUser}; -use generic_array::{ +use crypto_common::{ + generic_array::{ArrayLength, GenericArray}, typenum::{IsLess, IsLessOrEqual, Le, LeEq, NonZero, U256}, - ArrayLength, GenericArray, + Block, BlockSizeUser, OutputSizeUser, }; /// Wrapper around [`VariableOutputCore`] which selects output size diff --git a/digest/src/core_api/rt_variable.rs b/digest/src/core_api/rt_variable.rs index 0c2233fe0..3dae748f5 100644 --- a/digest/src/core_api/rt_variable.rs +++ b/digest/src/core_api/rt_variable.rs @@ -5,7 +5,7 @@ use crate::{HashMarker, InvalidBufferSize}; use crate::{InvalidOutputSize, Reset, Update, VariableOutput, VariableOutputReset}; use block_buffer::BlockBuffer; use core::fmt; -use generic_array::typenum::{IsLess, Le, NonZero, Unsigned, U256}; +use crypto_common::typenum::{IsLess, Le, NonZero, Unsigned, U256}; /// Wrapper around [`VariableOutputCore`] which selects output size /// at run time. diff --git a/digest/src/core_api/wrapper.rs b/digest/src/core_api/wrapper.rs index f600642c2..4ad0f7eea 100644 --- a/digest/src/core_api/wrapper.rs +++ b/digest/src/core_api/wrapper.rs @@ -7,8 +7,10 @@ use crate::{ }; use block_buffer::BlockBuffer; use core::fmt; -use crypto_common::{BlockSizeUser, InvalidLength, Key, KeyInit, KeySizeUser, Output}; -use generic_array::typenum::{IsLess, Le, NonZero, U256}; +use crypto_common::{ + typenum::{IsLess, Le, NonZero, U256}, + BlockSizeUser, InvalidLength, Key, KeyInit, KeySizeUser, Output, +}; #[cfg(feature = "mac")] use crate::MacMarker; diff --git a/digest/src/core_api/xof_reader.rs b/digest/src/core_api/xof_reader.rs index 5b41479b0..e18ac133a 100644 --- a/digest/src/core_api/xof_reader.rs +++ b/digest/src/core_api/xof_reader.rs @@ -2,7 +2,7 @@ use super::{AlgorithmName, XofReaderCore}; use crate::XofReader; use block_buffer::EagerBuffer; use core::fmt; -use generic_array::typenum::{IsLess, Le, NonZero, U256}; +use crypto_common::typenum::{IsLess, Le, NonZero, U256}; /// Wrapper around [`XofReaderCore`] implementations. /// diff --git a/digest/src/digest.rs b/digest/src/digest.rs index 1ede72eb1..bd9fd62e4 100644 --- a/digest/src/digest.rs +++ b/digest/src/digest.rs @@ -1,6 +1,5 @@ use super::{FixedOutput, FixedOutputReset, InvalidBufferSize, Reset, Update}; -use crypto_common::{Output, OutputSizeUser}; -use generic_array::typenum::Unsigned; +use crypto_common::{typenum::Unsigned, Output, OutputSizeUser}; #[cfg(feature = "alloc")] use alloc::boxed::Box; @@ -24,6 +23,7 @@ pub trait Digest: OutputSizeUser { fn update(&mut self, data: impl AsRef<[u8]>); /// Process input data in a chained manner. + #[must_use] fn chain_update(self, data: impl AsRef<[u8]>) -> Self; /// Retrieve result and consume hasher instance. diff --git a/digest/src/lib.rs b/digest/src/lib.rs index b896bb910..0fc7ede42 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -28,7 +28,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", - html_root_url = "https://docs.rs/digest/0.10.1" + html_root_url = "https://docs.rs/digest/0.10.2" )] #![warn(missing_docs, rust_2018_idioms)] @@ -40,6 +40,7 @@ extern crate alloc; extern crate std; #[cfg(feature = "rand_core")] +#[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] pub use crypto_common::rand_core; #[cfg(feature = "alloc")] @@ -62,10 +63,9 @@ pub use block_buffer; pub use crypto_common; pub use crate::digest::{Digest, DynDigest, HashMarker}; +pub use crypto_common::{generic_array, typenum, typenum::consts, Output, OutputSizeUser, Reset}; #[cfg(feature = "mac")] pub use crypto_common::{InnerInit, InvalidLength, Key, KeyInit}; -pub use crypto_common::{Output, OutputSizeUser, Reset}; -pub use generic_array::{self, typenum::consts}; #[cfg(feature = "mac")] pub use mac::{CtOutput, Mac, MacError, MacMarker}; @@ -77,6 +77,7 @@ pub trait Update { fn update(&mut self, data: &[u8]); /// Digest input data in a chained manner. + #[must_use] fn chain(mut self, data: impl AsRef<[u8]>) -> Self where Self: Sized, diff --git a/digest/src/mac.rs b/digest/src/mac.rs index 672ce93e3..76f8df2c9 100644 --- a/digest/src/mac.rs +++ b/digest/src/mac.rs @@ -1,10 +1,10 @@ use crate::{FixedOutput, FixedOutputReset, Update}; -use crypto_common::{InvalidLength, Key, KeyInit, KeySizeUser, Output, OutputSizeUser, Reset}; +use crypto_common::{InvalidLength, Key, KeyInit, Output, OutputSizeUser, Reset}; #[cfg(feature = "rand_core")] use crate::rand_core::{CryptoRng, RngCore}; use core::fmt; -use generic_array::typenum::Unsigned; +use crypto_common::typenum::Unsigned; use subtle::{Choice, ConstantTimeEq}; /// Marker trait for Message Authentication algorithms. @@ -16,21 +16,31 @@ pub trait MacMarker {} /// This trait wraps [`KeyInit`], [`Update`], [`FixedOutput`], and [`MacMarker`] /// traits and provides additional convenience methods. #[cfg_attr(docsrs, doc(cfg(feature = "mac")))] -pub trait Mac: KeySizeUser + OutputSizeUser + Sized { +pub trait Mac: OutputSizeUser + Sized { /// Create new value from fixed size key. - fn new(key: &Key) -> Self; + fn new(key: &Key) -> Self + where + Self: KeyInit; /// Generate random key using the provided [`CryptoRng`]. #[cfg(feature = "rand_core")] #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] - fn generate_key(rng: impl CryptoRng + RngCore) -> Key; + fn generate_key(rng: impl CryptoRng + RngCore) -> Key + where + Self: KeyInit; /// Create new value from variable size key. - fn new_from_slice(key: &[u8]) -> Result; + fn new_from_slice(key: &[u8]) -> Result + where + Self: KeyInit; /// Update state using the provided data. fn update(&mut self, data: &[u8]); + /// Process input data in a chained manner. + #[must_use] + fn chain_update(self, data: impl AsRef<[u8]>) -> Self; + /// Obtain the result of a [`Mac`] computation as a [`CtOutput`] and consume /// [`Mac`] instance. fn finalize(self) -> CtOutput; @@ -69,14 +79,20 @@ pub trait Mac: KeySizeUser + OutputSizeUser + Sized { fn verify_truncated_right(self, tag: &[u8]) -> Result<(), MacError>; } -impl Mac for T { +impl Mac for T { #[inline(always)] - fn new(key: &Key) -> Self { + fn new(key: &Key) -> Self + where + Self: KeyInit, + { KeyInit::new(key) } #[inline(always)] - fn new_from_slice(key: &[u8]) -> Result { + fn new_from_slice(key: &[u8]) -> Result + where + Self: KeyInit, + { KeyInit::new_from_slice(key) } @@ -85,6 +101,12 @@ impl Mac for T { Update::update(self, data); } + #[inline] + fn chain_update(mut self, data: impl AsRef<[u8]>) -> Self { + Update::update(&mut self, data.as_ref()); + self + } + #[inline] fn finalize(self) -> CtOutput { CtOutput::new(self.finalize_fixed()) @@ -161,7 +183,10 @@ impl Mac for T { #[cfg(feature = "rand_core")] #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] #[inline] - fn generate_key(rng: impl CryptoRng + RngCore) -> Key { + fn generate_key(rng: impl CryptoRng + RngCore) -> Key + where + Self: KeyInit, + { ::generate_key(rng) } } From 2137b13bb6b9955b43c77e84c503a0275bc4088e Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Thu, 10 Feb 2022 23:05:31 +0000 Subject: [PATCH 0741/1461] Update lock files (#935) --- Cargo.lock | 27 +++++++++---------- cipher/Cargo.lock | 4 +-- crypto/Cargo.lock | 55 +++++++++++++++++++-------------------- elliptic-curve/Cargo.lock | 29 ++++++++++----------- 4 files changed, 56 insertions(+), 59 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 65efb3529..2495b4634 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -69,40 +69,39 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683d6b536309245c849479fba3da410962a43ed8e51c26b729208ec0ac2798d0" +version = "0.1.2" dependencies = [ "generic-array", + "rand_core", ] [[package]] name = "crypto-common" version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4600d695eb3f6ce1cd44e6e291adceb2cc3ab12f20a33777ecd0bf6eba34e06" dependencies = [ "generic-array", - "rand_core", ] [[package]] name = "digest" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b697d66081d42af4fba142d56918a3cb21dc8eb63372c6b85d14f44fb9c5979b" +version = "0.10.2" dependencies = [ + "blobby", "block-buffer", - "crypto-common 0.1.1", - "generic-array", + "crypto-common 0.1.2", + "subtle", ] [[package]] name = "digest" version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cb780dce4f9a8f5c087362b3a4595936b2019e7c8b30f2c3e9a7e94e6ae9837" dependencies = [ - "blobby", "block-buffer", - "crypto-common 0.1.2", - "subtle", + "crypto-common 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -227,14 +226,14 @@ checksum = "99c3bd8169c58782adad9290a9af5939994036b76187f7b4f0e6de91dbbfc0ec" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.1", + "digest 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "signature" version = "1.5.0" dependencies = [ - "digest 0.10.1", + "digest 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal", "rand_core", "sha2", diff --git a/cipher/Cargo.lock b/cipher/Cargo.lock index 2f5d35567..b86138fe7 100644 --- a/cipher/Cargo.lock +++ b/cipher/Cargo.lock @@ -47,9 +47,9 @@ dependencies = [ [[package]] name = "inout" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1d8734d7f28aaff861d726dc3bc8003e2987d2fc26add21f5dab0c35d5c348a" +checksum = "9e1f03d4ab4d5dc9ec2d219f86c15d2a15fc08239d1cd3b2d6a19717c0a2f443" dependencies = [ "block-padding", "generic-array", diff --git a/crypto/Cargo.lock b/crypto/Cargo.lock index cf9bc9780..aa4648872 100644 --- a/crypto/Cargo.lock +++ b/crypto/Cargo.lock @@ -18,15 +18,15 @@ checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" [[package]] name = "base64ct" -version = "1.0.1" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a32fd6af2b5827bce66c29053ba0e7c42b9dcab01835835058558c10851a46b" +checksum = "874f8444adcb4952a8bc51305c8be95c8ec8237bb0d2e78d2e039f771f8828a0" [[package]] name = "block-buffer" -version = "0.10.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1d36a02058e76b040de25a4464ba1c80935655595b661505c8b39b664828b95" +checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" dependencies = [ "generic-array", ] @@ -48,9 +48,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d355758f44afa81c21e66e1301d47cbffbbcde4b405cbe46b8b19f213abf9f60" +checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" [[package]] name = "crypto" @@ -68,9 +68,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.3.2" +version = "0.4.0-pre.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21" +checksum = "6a9df9647255ed398be26379810e02ed1d58263570b3bcd243ee2481f79c88b1" dependencies = [ "generic-array", "rand_core", @@ -80,9 +80,9 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683d6b536309245c849479fba3da410962a43ed8e51c26b729208ec0ac2798d0" +checksum = "a4600d695eb3f6ce1cd44e6e291adceb2cc3ab12f20a33777ecd0bf6eba34e06" dependencies = [ "generic-array", ] @@ -108,18 +108,17 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b697d66081d42af4fba142d56918a3cb21dc8eb63372c6b85d14f44fb9c5979b" +checksum = "8cb780dce4f9a8f5c087362b3a4595936b2019e7c8b30f2c3e9a7e94e6ae9837" dependencies = [ "block-buffer", "crypto-common", - "generic-array", ] [[package]] name = "elliptic-curve" -version = "0.12.0-pre" +version = "0.12.0-pre.1" dependencies = [ "base16ct", "crypto-bigint", @@ -145,9 +144,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.4" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" dependencies = [ "typenum", "version_check", @@ -155,9 +154,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c" dependencies = [ "cfg-if", "libc", @@ -177,9 +176,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.107" +version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbe5e23404da5b4f555ef85ebed98fb4083e55a00c317800bc2a50ede9f3d219" +checksum = "e74d72e0f9b65b5b4ca49a346af3976df0f9c61d550727f349ecd559f251a26c" [[package]] name = "password-hash" @@ -229,9 +228,9 @@ version = "1.5.0" [[package]] name = "spki" -version = "0.5.2" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8a277a21925310de1d31bb6b021da3550b00e9127096ef84ee38f44609925c4" +checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" dependencies = [ "base64ct", "der", @@ -245,9 +244,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "typenum" -version = "1.14.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" [[package]] name = "universal-hash" @@ -259,9 +258,9 @@ dependencies = [ [[package]] name = "version_check" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "wasi" @@ -271,6 +270,6 @@ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] name = "zeroize" -version = "1.5.0" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc222aec311c323c717f56060324f32b82da1ce1dd81d9a09aa6a9030bfe08db" +checksum = "7c88870063c39ee00ec285a2f8d6a966e5b6fb2becc4e8dac77ed0d370ed6006" diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index 90f53f403..f9858b5a8 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -28,9 +28,9 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.10.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1d36a02058e76b040de25a4464ba1c80935655595b661505c8b39b664828b95" +checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" dependencies = [ "generic-array", ] @@ -70,9 +70,9 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683d6b536309245c849479fba3da410962a43ed8e51c26b729208ec0ac2798d0" +checksum = "a4600d695eb3f6ce1cd44e6e291adceb2cc3ab12f20a33777ecd0bf6eba34e06" dependencies = [ "generic-array", ] @@ -89,13 +89,12 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b697d66081d42af4fba142d56918a3cb21dc8eb63372c6b85d14f44fb9c5979b" +checksum = "8cb780dce4f9a8f5c087362b3a4595936b2019e7c8b30f2c3e9a7e94e6ae9837" dependencies = [ "block-buffer", "crypto-common", - "generic-array", ] [[package]] @@ -191,9 +190,9 @@ checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" [[package]] name = "libc" -version = "0.2.112" +version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" +checksum = "e74d72e0f9b65b5b4ca49a346af3976df0f9c61d550727f349ecd559f251a26c" [[package]] name = "pem-rfc7468" @@ -251,15 +250,15 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.133" +version = "1.0.136" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97565067517b60e2d1ea8b268e59ce036de907ac523ad83a0475da04e818989a" +checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" [[package]] name = "serde_json" -version = "1.0.75" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c059c05b48c5c0067d4b4b2b4f0732dd65feb52daf7e0ea09cd87e7dadc1af79" +checksum = "d23c1ba4cf0efd44be32017709280b32d1cea5c3f1275c3b6d9e8bc54f758085" dependencies = [ "itoa", "ryu", @@ -323,9 +322,9 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "wasi" -version = "0.10.3+wasi-snapshot-preview1" +version = "0.10.2+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46a2e384a3f170b0c7543787a91411175b71afd56ba4d3a0ae5678d4e2243c0e" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] name = "wyz" From b4162de124df07d34063ead9225a487a9abefce7 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Perennou Date: Wed, 16 Feb 2022 05:07:56 +0100 Subject: [PATCH 0742/1461] cipher: restore allocating padded encrypt/decrypt (#936) --- .github/workflows/workspace.yml | 2 + cipher/CHANGELOG.md | 6 +++ cipher/Cargo.toml | 4 +- cipher/src/block.rs | 84 ++++++++++++++++++++++++++++++--- cipher/src/lib.rs | 3 ++ 5 files changed, 92 insertions(+), 7 deletions(-) diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index 5c8e83365..f3f7d4ac9 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -25,6 +25,8 @@ jobs: override: true profile: minimal - run: cargo clippy --all --all-features -- -D warnings + - run: cargo clippy --all --all-features -- -D warnings + working-directory: cipher - run: cargo clippy --all --all-features -- -D warnings working-directory: crypto - run: cargo clippy --all --all-features -- -D warnings diff --git a/cipher/CHANGELOG.md b/cipher/CHANGELOG.md index 7eee95adc..1ece484db 100644 --- a/cipher/CHANGELOG.md +++ b/cipher/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## UNRELEASED +### Added +- Allocating padded encrypt/decrypt ([#936]) + +[#936]: https://github.com/RustCrypto/traits/pull/936 + ## 0.3.0 (2022-02-10) ### Changed - Major rework of traits. Core functionality of block and stream ciphers diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index 4ef3d2a6e..572275234 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -25,7 +25,9 @@ blobby = { version = "0.3", optional = true } zeroize = { version = "1.5", optional = true, default-features = false } [features] -std = ["crypto-common/std", "inout/std"] +default = ["alloc"] +alloc = [] +std = ["alloc", "crypto-common/std", "inout/std"] block-padding = ["inout/block-padding"] rand_core = ["crypto-common/rand_core"] # Enable random key and IV generation methods dev = ["blobby"] diff --git a/cipher/src/block.rs b/cipher/src/block.rs index 9c22fe3e8..697e42e6f 100644 --- a/cipher/src/block.rs +++ b/cipher/src/block.rs @@ -11,6 +11,8 @@ //! [3]: https://en.wikipedia.org/wiki/Symmetric-key_algorithm use crate::{ParBlocks, ParBlocksSizeUser}; +#[cfg(all(feature = "block-padding", feature = "alloc"))] +use alloc::{vec, vec::Vec}; #[cfg(feature = "block-padding")] use inout::{ block_padding::{Padding, UnpadError}, @@ -173,6 +175,20 @@ pub trait BlockEncrypt: BlockSizeUser + Sized { let buf = InOutBufReserved::from_slices(msg, out_buf).map_err(|_| PadError)?; self.encrypt_padded_inout::

(buf) } + + /// Pad input and encrypt into a newly allocated Vec. Returns resulting ciphertext Vec. + #[cfg(all(feature = "block-padding", feature = "alloc"))] + #[cfg_attr(docsrs, doc(cfg(all(feature = "block-padding", feature = "alloc"))))] + #[inline] + fn encrypt_padded_vec>(&self, msg: &[u8]) -> Vec { + let mut out = allocate_out_vec::(msg.len()); + let len = self + .encrypt_padded_b2b::

(msg, &mut out) + .expect("enough space for encrypting is allocated") + .len(); + out.truncate(len); + out + } } /// Decrypt-only functionality for block ciphers. @@ -281,6 +297,24 @@ pub trait BlockDecrypt: BlockSizeUser { let buf = InOutBuf::new(in_buf, &mut out_buf[..n]).map_err(|_| UnpadError)?; self.decrypt_padded_inout::

(buf) } + + /// Decrypt input and unpad it in a newly allocated Vec. Returns resulting + /// ciphertext Vec. + /// + /// Returns [`UnpadError`] if padding is malformed or if input length is + /// not multiple of `Self::BlockSize`. + #[cfg(all(feature = "block-padding", feature = "alloc"))] + #[cfg_attr(docsrs, doc(cfg(all(feature = "block-padding", feature = "alloc"))))] + #[inline] + fn decrypt_padded_vec>( + &self, + buf: &[u8], + ) -> Result, UnpadError> { + let mut out = vec![0; buf.len()]; + let len = self.decrypt_padded_b2b::

(buf, &mut out)?.len(); + out.truncate(len); + Ok(out) + } } /// Encrypt-only functionality for block ciphers and modes with mutable access to `self`. @@ -363,11 +397,11 @@ pub trait BlockEncryptMut: BlockSizeUser + Sized { #[cfg(feature = "block-padding")] #[cfg_attr(docsrs, doc(cfg(feature = "block-padding")))] #[inline] - fn encrypt_padded_mut<'a, P: Padding>( + fn encrypt_padded_mut>( self, - buf: &'a mut [u8], + buf: &mut [u8], msg_len: usize, - ) -> Result<&'a [u8], PadError> { + ) -> Result<&[u8], PadError> { let buf = InOutBufReserved::from_mut_slice(buf, msg_len).map_err(|_| PadError)?; self.encrypt_padded_inout_mut::

(buf) } @@ -386,6 +420,20 @@ pub trait BlockEncryptMut: BlockSizeUser + Sized { let buf = InOutBufReserved::from_slices(msg, out_buf).map_err(|_| PadError)?; self.encrypt_padded_inout_mut::

(buf) } + + /// Pad input and encrypt into a newly allocated Vec. Returns resulting ciphertext Vec. + #[cfg(all(feature = "block-padding", feature = "alloc"))] + #[cfg_attr(docsrs, doc(cfg(all(feature = "block-padding", feature = "alloc"))))] + #[inline] + fn encrypt_padded_vec_mut>(self, msg: &[u8]) -> Vec { + let mut out = allocate_out_vec::(msg.len()); + let len = self + .encrypt_padded_b2b_mut::

(msg, &mut out) + .expect("enough space for encrypting is allocated") + .len(); + out.truncate(len); + out + } } /// Decrypt-only functionality for block ciphers and modes with mutable access to `self`. @@ -470,10 +518,10 @@ pub trait BlockDecryptMut: BlockSizeUser + Sized { #[cfg(feature = "block-padding")] #[cfg_attr(docsrs, doc(cfg(feature = "block-padding")))] #[inline] - fn decrypt_padded_mut<'a, P: Padding>( + fn decrypt_padded_mut>( self, - buf: &'a mut [u8], - ) -> Result<&'a [u8], UnpadError> { + buf: &mut [u8], + ) -> Result<&[u8], UnpadError> { self.decrypt_padded_inout_mut::

(buf.into()) } @@ -498,6 +546,24 @@ pub trait BlockDecryptMut: BlockSizeUser + Sized { let buf = InOutBuf::new(in_buf, &mut out_buf[..n]).map_err(|_| UnpadError)?; self.decrypt_padded_inout_mut::

(buf) } + + /// Decrypt input and unpad it in a newly allocated Vec. Returns resulting + /// ciphertext Vec. + /// + /// Returns [`UnpadError`] if padding is malformed or if input length is + /// not multiple of `Self::BlockSize`. + #[cfg(all(feature = "block-padding", feature = "alloc"))] + #[cfg_attr(docsrs, doc(cfg(all(feature = "block-padding", feature = "alloc"))))] + #[inline] + fn decrypt_padded_vec>( + self, + buf: &[u8], + ) -> Result, UnpadError> { + let mut out = vec![0; buf.len()]; + let len = self.decrypt_padded_b2b_mut::

(buf, &mut out)?.len(); + out.truncate(len); + Ok(out) + } } impl BlockEncryptMut for Alg { @@ -568,6 +634,12 @@ impl<'inp, 'out, BS: ArrayLength> BlockClosure for BlocksCtx<'inp, 'out, BS> } } +#[cfg(all(feature = "block-padding", feature = "alloc"))] +fn allocate_out_vec(len: usize) -> Vec { + let bs = BS::BlockSize::USIZE; + vec![0; bs * (len / bs + 1)] +} + /// Implement simple block backend #[macro_export] macro_rules! impl_simple_block_encdec { diff --git a/cipher/src/lib.rs b/cipher/src/lib.rs index fff7fd98e..102fa35a7 100644 --- a/cipher/src/lib.rs +++ b/cipher/src/lib.rs @@ -17,6 +17,9 @@ pub use crypto_common; pub use inout; +#[cfg(all(feature = "block-padding", feature = "alloc"))] +extern crate alloc; + #[cfg(feature = "std")] extern crate std; From 1f55b70e2587562e45d43c134663f8ffc4dc63fa Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Wed, 16 Feb 2022 04:49:10 +0000 Subject: [PATCH 0743/1461] Fix minimal versions build by using typenum 1.14 or higher (#940) --- Cargo.lock | 29 ++++++++++++------------ cipher/CHANGELOG.md | 8 +++++-- cipher/Cargo.lock | 3 ++- cipher/Cargo.toml | 4 ++-- cipher/src/lib.rs | 2 +- crypto-common/CHANGELOG.md | 6 +++++ crypto-common/Cargo.toml | 4 +++- crypto-common/src/lib.rs | 2 +- digest/CHANGELOG.md | 8 ++++++- digest/Cargo.toml | 4 ++-- digest/src/lib.rs | 2 +- elliptic-curve/Cargo.lock | 8 +++---- kem/Cargo.lock | 46 +++++++++++++++----------------------- 13 files changed, 68 insertions(+), 58 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2495b4634..193505b88 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -70,38 +70,39 @@ dependencies = [ [[package]] name = "crypto-common" version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4600d695eb3f6ce1cd44e6e291adceb2cc3ab12f20a33777ecd0bf6eba34e06" dependencies = [ "generic-array", - "rand_core", ] [[package]] name = "crypto-common" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4600d695eb3f6ce1cd44e6e291adceb2cc3ab12f20a33777ecd0bf6eba34e06" +version = "0.1.3" dependencies = [ "generic-array", + "rand_core", + "typenum", ] [[package]] name = "digest" version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cb780dce4f9a8f5c087362b3a4595936b2019e7c8b30f2c3e9a7e94e6ae9837" dependencies = [ - "blobby", "block-buffer", "crypto-common 0.1.2", - "subtle", ] [[package]] name = "digest" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cb780dce4f9a8f5c087362b3a4595936b2019e7c8b30f2c3e9a7e94e6ae9837" +version = "0.10.3" dependencies = [ + "blobby", "block-buffer", - "crypto-common 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.1.3", + "subtle", ] [[package]] @@ -166,9 +167,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.117" +version = "0.2.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e74d72e0f9b65b5b4ca49a346af3976df0f9c61d550727f349ecd559f251a26c" +checksum = "06e509672465a0504304aa87f9f176f2b2b716ed8fb105ebe5c02dc6dce96a94" [[package]] name = "lock_api" @@ -226,14 +227,14 @@ checksum = "99c3bd8169c58782adad9290a9af5939994036b76187f7b4f0e6de91dbbfc0ec" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.10.2", ] [[package]] name = "signature" version = "1.5.0" dependencies = [ - "digest 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.10.2", "hex-literal", "rand_core", "sha2", diff --git a/cipher/CHANGELOG.md b/cipher/CHANGELOG.md index 1ece484db..bd22a24e8 100644 --- a/cipher/CHANGELOG.md +++ b/cipher/CHANGELOG.md @@ -5,13 +5,17 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## UNRELEASED +## 0.4.1 (2022-02-16) ### Added - Allocating padded encrypt/decrypt ([#936]) +### Fixed +- Minimal versions build ([#940]) + +[#940]: https://github.com/RustCrypto/traits/pull/940 [#936]: https://github.com/RustCrypto/traits/pull/936 -## 0.3.0 (2022-02-10) +## 0.4.0 (2022-02-10) ### Changed - Major rework of traits. Core functionality of block and stream ciphers is defined using rank-2 closures with convinience methods built on top of diff --git a/cipher/Cargo.lock b/cipher/Cargo.lock index b86138fe7..1f374a7ad 100644 --- a/cipher/Cargo.lock +++ b/cipher/Cargo.lock @@ -29,10 +29,11 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.1.2" +version = "0.1.3" dependencies = [ "generic-array", "rand_core", + "typenum", ] [[package]] diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index 572275234..dc8c86b71 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "cipher" description = "Traits for describing block ciphers and stream ciphers" -version = "0.4.0" # Also update html_root_url in lib.rs when bumping this +version = "0.4.1" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" @@ -17,7 +17,7 @@ categories = ["cryptography", "no-std"] members = ["."] [dependencies] -crypto-common = { version = "0.1.2", path = "../crypto-common" } +crypto-common = { version = "0.1.3", path = "../crypto-common" } inout = "0.1" # optional dependencies diff --git a/cipher/src/lib.rs b/cipher/src/lib.rs index 102fa35a7..e54aab52b 100644 --- a/cipher/src/lib.rs +++ b/cipher/src/lib.rs @@ -10,7 +10,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", - html_root_url = "https://docs.rs/cipher/0.4.0" + html_root_url = "https://docs.rs/cipher/0.4.1" )] #![warn(missing_docs, rust_2018_idioms)] diff --git a/crypto-common/CHANGELOG.md b/crypto-common/CHANGELOG.md index 98541eaad..ebd278695 100644 --- a/crypto-common/CHANGELOG.md +++ b/crypto-common/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.1.3 (2022-02-16) +### Fixed +- Minimal versions build ([#940]) + +[#940]: https://github.com/RustCrypto/traits/pull/940 + ## 0.1.2 (2022-02-10) ### Added - Re-export `generic-array` and `typenum`. Enable `more_lengths` feature on diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index 67249f0b0..9e07b31b2 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crypto-common" description = "Common cryptographic traits" -version = "0.1.2" # Also update html_root_url in lib.rs when bumping this +version = "0.1.3" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" @@ -14,6 +14,8 @@ categories = ["cryptography", "no-std"] [dependencies] generic-array = { version = "0.14.4", features = ["more_lengths"] } rand_core = { version = "0.6", optional = true } +# earlier versions of typenum don't satisfy the 'static bound on U* types +typenum = "1.14" [features] std = [] diff --git a/crypto-common/src/lib.rs b/crypto-common/src/lib.rs index 62807bbb4..187b1ac42 100644 --- a/crypto-common/src/lib.rs +++ b/crypto-common/src/lib.rs @@ -5,7 +5,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", - html_root_url = "https://docs.rs/crypto-common/0.1.1" + html_root_url = "https://docs.rs/crypto-common/0.1.3" )] #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] diff --git a/digest/CHANGELOG.md b/digest/CHANGELOG.md index 5e18564c6..65d68311c 100644 --- a/digest/CHANGELOG.md +++ b/digest/CHANGELOG.md @@ -5,9 +5,15 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.10.3 (2022-02-16) +### Fixed +- Minimal versions build ([#940]) + +[#940]: https://github.com/RustCrypto/traits/pull/940 + ## 0.10.2 (2022-02-10) ### Changed -- Relaxed bounds on the `Mac` trait ([#849]) +- Relax bounds on the `Mac` trait ([#849]) [#849]: https://github.com/RustCrypto/traits/pull/849 diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 0b9020fa7..65e00c582 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "digest" description = "Traits for cryptographic hash functions" -version = "0.10.2" # Also update html_root_url in lib.rs when bumping this +version = "0.10.3" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" @@ -12,7 +12,7 @@ keywords = ["digest", "crypto", "hash"] categories = ["cryptography", "no-std"] [dependencies] -crypto-common = { version = "0.1.2", path = "../crypto-common" } +crypto-common = { version = "0.1.3", path = "../crypto-common" } block-buffer = { version = "0.10", optional = true } subtle = { version = "=2.4", default-features = false, optional = true } diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 0fc7ede42..c2edb40ee 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -28,7 +28,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", - html_root_url = "https://docs.rs/digest/0.10.2" + html_root_url = "https://docs.rs/digest/0.10.3" )] #![warn(missing_docs, rust_2018_idioms)] diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index f9858b5a8..68d529e81 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -190,9 +190,9 @@ checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" [[package]] name = "libc" -version = "0.2.117" +version = "0.2.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e74d72e0f9b65b5b4ca49a346af3976df0f9c61d550727f349ecd559f251a26c" +checksum = "06e509672465a0504304aa87f9f176f2b2b716ed8fb105ebe5c02dc6dce96a94" [[package]] name = "pem-rfc7468" @@ -256,9 +256,9 @@ checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" [[package]] name = "serde_json" -version = "1.0.78" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d23c1ba4cf0efd44be32017709280b32d1cea5c3f1275c3b6d9e8bc54f758085" +checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" dependencies = [ "itoa", "ryu", diff --git a/kem/Cargo.lock b/kem/Cargo.lock index e5ca3ac5c..437c7c25d 100644 --- a/kem/Cargo.lock +++ b/kem/Cargo.lock @@ -243,9 +243,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c" dependencies = [ "cfg-if", "libc", @@ -344,9 +344,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.112" +version = "0.2.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" +checksum = "06e509672465a0504304aa87f9f176f2b2b716ed8fb105ebe5c02dc6dce96a94" [[package]] name = "opaque-debug" @@ -472,23 +472,22 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47aa80447ce4daf1717500037052af176af5d38cc3e571d9ec1c7353fc10c87d" +checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" dependencies = [ "proc-macro2", ] [[package]] name = "rand" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha", "rand_core 0.6.3", - "rand_hc", ] [[package]] @@ -516,20 +515,11 @@ dependencies = [ "getrandom", ] -[[package]] -name = "rand_hc" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" -dependencies = [ - "rand_core 0.6.3", -] - [[package]] name = "serde" -version = "1.0.132" +version = "1.0.136" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9875c23cf305cd1fd7eb77234cbb705f21ea6a72c637a5c6db5fe4b8e7f008" +checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" dependencies = [ "serde_derive", ] @@ -545,9 +535,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.132" +version = "1.0.136" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc0db5cb2556c0e558887d9bbdcf6ac4471e83ff66cf696e5419024d1606276" +checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" dependencies = [ "proc-macro2", "quote", @@ -556,9 +546,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b69f9a4c9740d74c5baa3fd2e547f9525fa8088a8a958e0ca2409a514e33f5fa" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" dependencies = [ "block-buffer", "cfg-if", @@ -594,9 +584,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.84" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecb2e6da8ee5eb9a61068762a32fa9619cc591ceb055b3687f4cd4051ec2e06b" +checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b" dependencies = [ "proc-macro2", "quote", @@ -689,9 +679,9 @@ dependencies = [ [[package]] name = "zeroize_derive" -version = "1.2.2" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65f1a51723ec88c66d5d1fe80c841f17f63587d6691901d66be9bec6c3b51f73" +checksum = "81e8f13fef10b63c06356d65d416b070798ddabcadc10d3ece0c5be9b3c7eddb" dependencies = [ "proc-macro2", "quote", From 7c24337b154b96e1bc6d7cd60ac6c00e7ce804ef Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Wed, 16 Feb 2022 15:31:29 +0000 Subject: [PATCH 0744/1461] cipher: rename BlockDecryptMut::decrypt_padded_vec to decrypt_padded_vec_mut (#941) --- cipher/CHANGELOG.md | 8 +++++++- cipher/Cargo.lock | 2 +- cipher/Cargo.toml | 2 +- cipher/src/block.rs | 2 +- cipher/src/lib.rs | 2 +- 5 files changed, 11 insertions(+), 5 deletions(-) diff --git a/cipher/CHANGELOG.md b/cipher/CHANGELOG.md index bd22a24e8..9467a7afa 100644 --- a/cipher/CHANGELOG.md +++ b/cipher/CHANGELOG.md @@ -5,7 +5,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 0.4.1 (2022-02-16) +## 0.4.2 (2022-02-16) +### Fixed +- Rename `BlockDecryptMut::decrypt_padded_vec` to `decrypt_padded_vec_mut` for consistency with other methods ([#941]) + +[#941]: https://github.com/RustCrypto/traits/pull/941 + +## 0.4.1 (2022-02-16) [YANKED] ### Added - Allocating padded encrypt/decrypt ([#936]) diff --git a/cipher/Cargo.lock b/cipher/Cargo.lock index 1f374a7ad..6cece1623 100644 --- a/cipher/Cargo.lock +++ b/cipher/Cargo.lock @@ -19,7 +19,7 @@ dependencies = [ [[package]] name = "cipher" -version = "0.4.0" +version = "0.4.2" dependencies = [ "blobby", "crypto-common", diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index dc8c86b71..fb4c1bbe1 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "cipher" description = "Traits for describing block ciphers and stream ciphers" -version = "0.4.1" # Also update html_root_url in lib.rs when bumping this +version = "0.4.2" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/cipher/src/block.rs b/cipher/src/block.rs index 697e42e6f..0742ced14 100644 --- a/cipher/src/block.rs +++ b/cipher/src/block.rs @@ -555,7 +555,7 @@ pub trait BlockDecryptMut: BlockSizeUser + Sized { #[cfg(all(feature = "block-padding", feature = "alloc"))] #[cfg_attr(docsrs, doc(cfg(all(feature = "block-padding", feature = "alloc"))))] #[inline] - fn decrypt_padded_vec>( + fn decrypt_padded_vec_mut>( self, buf: &[u8], ) -> Result, UnpadError> { diff --git a/cipher/src/lib.rs b/cipher/src/lib.rs index e54aab52b..2f84ca2ea 100644 --- a/cipher/src/lib.rs +++ b/cipher/src/lib.rs @@ -10,7 +10,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", - html_root_url = "https://docs.rs/cipher/0.4.1" + html_root_url = "https://docs.rs/cipher/0.4.2" )] #![warn(missing_docs, rust_2018_idioms)] From 98d33669560a6a8b0b7f6b28bb302e2798b39e2f Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Thu, 17 Feb 2022 12:35:01 +0000 Subject: [PATCH 0745/1461] Add doc cfg to zeroize re-export (#944) --- cipher/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/cipher/src/lib.rs b/cipher/src/lib.rs index 2f84ca2ea..afa68f9e9 100644 --- a/cipher/src/lib.rs +++ b/cipher/src/lib.rs @@ -32,6 +32,7 @@ pub use crypto_common::rand_core; pub use inout::block_padding; #[cfg(feature = "zeroize")] +#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] pub use zeroize; #[cfg(feature = "dev")] From 3e3ef1fe6fac7b680ad81e5d198a7e8d6b8d9f20 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Fri, 18 Feb 2022 21:26:06 +0000 Subject: [PATCH 0746/1461] Test min versions build (#948) --- .github/workflows/aead.yml | 5 ++++ .github/workflows/async-signature.yml | 14 ++++++++++ .github/workflows/cipher.yml | 15 +++++++++++ .github/workflows/crypto-common.yml | 6 +++++ .github/workflows/crypto.yml | 16 +++++++++++ .github/workflows/digest.yml | 6 +++++ .github/workflows/elliptic-curve.yml | 15 +++++++++++ .github/workflows/kem.yml | 15 +++++++++++ .github/workflows/password-hash.yml | 15 +++++++++++ .github/workflows/signature.yml | 5 ++++ .github/workflows/universal-hash.yml | 6 +++++ Cargo.lock | 39 ++++++++++++++------------- crypto/Cargo.lock | 13 ++++----- elliptic-curve/Cargo.lock | 17 ++++++------ kem/Cargo.lock | 12 ++++----- password-hash/Cargo.lock | 4 +-- 16 files changed, 162 insertions(+), 41 deletions(-) diff --git a/.github/workflows/aead.yml b/.github/workflows/aead.yml index d16b5b75d..0f394ad27 100644 --- a/.github/workflows/aead.yml +++ b/.github/workflows/aead.yml @@ -40,6 +40,11 @@ jobs: - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features rand_core - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features stream + minimal-versions: + uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master + with: + working-directory: ${{ github.workflow }} + heapless: runs-on: ubuntu-latest strategy: diff --git a/.github/workflows/async-signature.yml b/.github/workflows/async-signature.yml index 940bb1fb5..d025f78f2 100644 --- a/.github/workflows/async-signature.yml +++ b/.github/workflows/async-signature.yml @@ -34,3 +34,17 @@ jobs: - run: cargo check --all-features - run: cargo test --release - run: cargo test --all-features --release + + # minimal-versions: + # runs-on: ubuntu-latest + # steps: + # - uses: actions/checkout@v1 + # - uses: actions-rs/toolchain@v1 + # with: + # toolchain: nightly + # override: true + # profile: minimal + # - uses: RustCrypto/actions/cargo-hack-install@master + # - run: rm ../../Cargo.toml + # - run: cargo update -Z minimal-versions + # - run: cargo hack test --release --feature-powerset diff --git a/.github/workflows/cipher.yml b/.github/workflows/cipher.yml index 6389b9858..244120e0b 100644 --- a/.github/workflows/cipher.yml +++ b/.github/workflows/cipher.yml @@ -39,6 +39,21 @@ jobs: - run: cargo build --target ${{ matrix.target }} --features rand_core - run: cargo build --target ${{ matrix.target }} --features block-padding + # TODO: use the reusable workflow after this crate will be part of the + # toot workspace + minimal-versions: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + toolchain: nightly + override: true + profile: minimal + - uses: RustCrypto/actions/cargo-hack-install@master + - run: cargo update -Z minimal-versions + - run: cargo hack test --release --feature-powerset + test: runs-on: ubuntu-latest strategy: diff --git a/.github/workflows/crypto-common.yml b/.github/workflows/crypto-common.yml index 1155de5c3..29cb3c0fb 100644 --- a/.github/workflows/crypto-common.yml +++ b/.github/workflows/crypto-common.yml @@ -36,6 +36,12 @@ jobs: override: true profile: minimal - run: cargo build --target ${{ matrix.target }} + + minimal-versions: + uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master + with: + working-directory: ${{ github.workflow }} + test: runs-on: ubuntu-latest strategy: diff --git a/.github/workflows/crypto.yml b/.github/workflows/crypto.yml index c93bb5095..60f8f1187 100644 --- a/.github/workflows/crypto.yml +++ b/.github/workflows/crypto.yml @@ -38,6 +38,22 @@ jobs: - run: cargo build --no-default-features --release --target ${{ matrix.target }} - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features aead,cipher,mac,digest,elliptic-curve,signature,universal-hash + + # TODO: use the reusable workflow after this crate will be part of the + # toot workspace + # minimal-versions: + # runs-on: ubuntu-latest + # steps: + # - uses: actions/checkout@v1 + # - uses: actions-rs/toolchain@v1 + # with: + # toolchain: nightly + # override: true + # profile: minimal + # - uses: RustCrypto/actions/cargo-hack-install@master + # - run: cargo update -Z minimal-versions + # - run: cargo hack test --release --feature-powerset + test: runs-on: ubuntu-latest strategy: diff --git a/.github/workflows/digest.yml b/.github/workflows/digest.yml index 18b7a1bdd..d3653ae0a 100644 --- a/.github/workflows/digest.yml +++ b/.github/workflows/digest.yml @@ -36,6 +36,12 @@ jobs: override: true profile: minimal - run: cargo build --target ${{ matrix.target }} + + minimal-versions: + uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master + with: + working-directory: ${{ github.workflow }} + test: runs-on: ubuntu-latest strategy: diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index 7accaf507..6c063f412 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -54,6 +54,21 @@ jobs: - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features pem,pkcs8,sec1 - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,digest,ecdh,hazmat,hash2curve,jwk,pem,pkcs8,sec1,serde,voprf + # TODO: use the reusable workflow after this crate will be part of the + # toot workspace + # minimal-versions: + # runs-on: ubuntu-latest + # steps: + # - uses: actions/checkout@v1 + # - uses: actions-rs/toolchain@v1 + # with: + # toolchain: nightly + # override: true + # profile: minimal + # - uses: RustCrypto/actions/cargo-hack-install@master + # - run: cargo update -Z minimal-versions + # - run: cargo hack test --release --feature-powerset + test: runs-on: ubuntu-latest strategy: diff --git a/.github/workflows/kem.yml b/.github/workflows/kem.yml index 2ee3c00af..c372d96de 100644 --- a/.github/workflows/kem.yml +++ b/.github/workflows/kem.yml @@ -37,6 +37,21 @@ jobs: profile: minimal - run: cargo build --no-default-features --release --target ${{ matrix.target }} + # TODO: use the reusable workflow after this crate will be part of the + # toot workspace + # minimal-versions: + # runs-on: ubuntu-latest + # steps: + # - uses: actions/checkout@v1 + # - uses: actions-rs/toolchain@v1 + # with: + # toolchain: nightly + # override: true + # profile: minimal + # - uses: RustCrypto/actions/cargo-hack-install@master + # - run: cargo update -Z minimal-versions + # - run: cargo hack test --release --feature-powerset + test: runs-on: ubuntu-latest strategy: diff --git a/.github/workflows/password-hash.yml b/.github/workflows/password-hash.yml index eb68d8f78..b92f0d74e 100644 --- a/.github/workflows/password-hash.yml +++ b/.github/workflows/password-hash.yml @@ -39,6 +39,21 @@ jobs: - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features rand_core + # TODO: use the reusable workflow after this crate will be part of the + # toot workspace + minimal-versions: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + toolchain: nightly + override: true + profile: minimal + - uses: RustCrypto/actions/cargo-hack-install@master + - run: cargo update -Z minimal-versions + - run: cargo hack test --release --feature-powerset + test: runs-on: ubuntu-latest strategy: diff --git a/.github/workflows/signature.yml b/.github/workflows/signature.yml index dc40bf54e..408dfeda4 100644 --- a/.github/workflows/signature.yml +++ b/.github/workflows/signature.yml @@ -37,6 +37,11 @@ jobs: profile: minimal - run: cargo build --no-default-features --release --target ${{ matrix.target }} + # minimal-versions: + # uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master + # with: + # working-directory: ${{ github.workflow }} + test: runs-on: ubuntu-latest strategy: diff --git a/.github/workflows/universal-hash.yml b/.github/workflows/universal-hash.yml index 50035c0e2..aeeaec468 100644 --- a/.github/workflows/universal-hash.yml +++ b/.github/workflows/universal-hash.yml @@ -36,6 +36,12 @@ jobs: override: true profile: minimal - run: cargo build --no-default-features --release --target ${{ matrix.target }} + + minimal-versions: + uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master + with: + working-directory: ${{ github.workflow }} + test: runs-on: ubuntu-latest strategy: diff --git a/Cargo.lock b/Cargo.lock index 193505b88..026303f18 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -69,40 +69,41 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4600d695eb3f6ce1cd44e6e291adceb2cc3ab12f20a33777ecd0bf6eba34e06" +version = "0.1.3" dependencies = [ "generic-array", + "rand_core", + "typenum", ] [[package]] name = "crypto-common" version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8" dependencies = [ "generic-array", - "rand_core", "typenum", ] [[package]] name = "digest" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cb780dce4f9a8f5c087362b3a4595936b2019e7c8b30f2c3e9a7e94e6ae9837" +version = "0.10.3" dependencies = [ + "blobby", "block-buffer", - "crypto-common 0.1.2", + "crypto-common 0.1.3", + "subtle", ] [[package]] name = "digest" version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" dependencies = [ - "blobby", "block-buffer", - "crypto-common 0.1.3", - "subtle", + "crypto-common 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -148,9 +149,9 @@ dependencies = [ [[package]] name = "hex-literal" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "961de220ec9a91af2e1e5bd80d02109155695e516771762381ef8581317066e0" +checksum = "d70693199b3cf4552f3fa720b54163927a3ebed2aef240efaf556033ab336a11" dependencies = [ "hex-literal-impl", "proc-macro-hack", @@ -158,9 +159,9 @@ dependencies = [ [[package]] name = "hex-literal-impl" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "853f769599eb31de176303197b7ba4973299c38c7a7604a6bc88c3eef05b9b46" +checksum = "59448fc2f82a5fb6907f78c3d69d843e82ff5b051923313cc4438cb0c7b745a8" dependencies = [ "proc-macro-hack", ] @@ -221,20 +222,20 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "sha2" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99c3bd8169c58782adad9290a9af5939994036b76187f7b4f0e6de91dbbfc0ec" +checksum = "55deaec60f81eefe3cce0dc50bda92d6d8e88f2a27df7c5033b42afeb1ed2676" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.2", + "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "signature" version = "1.5.0" dependencies = [ - "digest 0.10.2", + "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal", "rand_core", "sha2", diff --git a/crypto/Cargo.lock b/crypto/Cargo.lock index aa4648872..2d789fd57 100644 --- a/crypto/Cargo.lock +++ b/crypto/Cargo.lock @@ -80,11 +80,12 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4600d695eb3f6ce1cd44e6e291adceb2cc3ab12f20a33777ecd0bf6eba34e06" +checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8" dependencies = [ "generic-array", + "typenum", ] [[package]] @@ -108,9 +109,9 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cb780dce4f9a8f5c087362b3a4595936b2019e7c8b30f2c3e9a7e94e6ae9837" +checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" dependencies = [ "block-buffer", "crypto-common", @@ -176,9 +177,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.117" +version = "0.2.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e74d72e0f9b65b5b4ca49a346af3976df0f9c61d550727f349ecd559f251a26c" +checksum = "06e509672465a0504304aa87f9f176f2b2b716ed8fb105ebe5c02dc6dce96a94" [[package]] name = "password-hash" diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index 68d529e81..bfb4e7e4f 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -70,11 +70,12 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4600d695eb3f6ce1cd44e6e291adceb2cc3ab12f20a33777ecd0bf6eba34e06" +checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8" dependencies = [ "generic-array", + "typenum", ] [[package]] @@ -89,9 +90,9 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cb780dce4f9a8f5c087362b3a4595936b2019e7c8b30f2c3e9a7e94e6ae9837" +checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" dependencies = [ "block-buffer", "crypto-common", @@ -267,9 +268,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99c3bd8169c58782adad9290a9af5939994036b76187f7b4f0e6de91dbbfc0ec" +checksum = "55deaec60f81eefe3cce0dc50bda92d6d8e88f2a27df7c5033b42afeb1ed2676" dependencies = [ "cfg-if", "cpufeatures", @@ -278,9 +279,9 @@ dependencies = [ [[package]] name = "sha3" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31f935e31cf406e8c0e96c2815a5516181b7004ae8c5f296293221e9b1e356bd" +checksum = "881bf8156c87b6301fc5ca6b27f11eeb2761224c7081e69b409d5a1951a70c86" dependencies = [ "digest", "keccak", diff --git a/kem/Cargo.lock b/kem/Cargo.lock index 437c7c25d..4af6cb6ba 100644 --- a/kem/Cargo.lock +++ b/kem/Cargo.lock @@ -69,9 +69,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "cc" -version = "1.0.72" +version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" +checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" dependencies = [ "jobserver", ] @@ -164,9 +164,9 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "3.2.0" +version = "3.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +checksum = "90f9d052967f590a76e62eb387bd0bbb1b000182c3cefe5364db6b7211651bc0" dependencies = [ "byteorder", "digest", @@ -679,9 +679,9 @@ dependencies = [ [[package]] name = "zeroize_derive" -version = "1.3.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81e8f13fef10b63c06356d65d416b070798ddabcadc10d3ece0c5be9b3c7eddb" +checksum = "3f8f187641dad4f680d25c4bfc4225b418165984179f26ca76ec4fb6441d3a17" dependencies = [ "proc-macro2", "quote", diff --git a/password-hash/Cargo.lock b/password-hash/Cargo.lock index fe63ec2c0..d0e568674 100644 --- a/password-hash/Cargo.lock +++ b/password-hash/Cargo.lock @@ -27,9 +27,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.112" +version = "0.2.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" +checksum = "06e509672465a0504304aa87f9f176f2b2b716ed8fb105ebe5c02dc6dce96a94" [[package]] name = "password-hash" From 3d49954defec8525b62ae974f5652410bb2a4051 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Fri, 18 Feb 2022 21:42:07 +0000 Subject: [PATCH 0747/1461] signature: fix min versions build (#950) --- .github/workflows/async-signature.yml | 26 +++++++++++++------------- .github/workflows/signature.yml | 8 ++++---- signature/Cargo.toml | 6 +++--- signature/async/Cargo.toml | 2 +- signature/derive/Cargo.toml | 4 ++-- 5 files changed, 23 insertions(+), 23 deletions(-) diff --git a/.github/workflows/async-signature.yml b/.github/workflows/async-signature.yml index d025f78f2..bda70d7de 100644 --- a/.github/workflows/async-signature.yml +++ b/.github/workflows/async-signature.yml @@ -35,16 +35,16 @@ jobs: - run: cargo test --release - run: cargo test --all-features --release - # minimal-versions: - # runs-on: ubuntu-latest - # steps: - # - uses: actions/checkout@v1 - # - uses: actions-rs/toolchain@v1 - # with: - # toolchain: nightly - # override: true - # profile: minimal - # - uses: RustCrypto/actions/cargo-hack-install@master - # - run: rm ../../Cargo.toml - # - run: cargo update -Z minimal-versions - # - run: cargo hack test --release --feature-powerset + minimal-versions: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + toolchain: nightly + override: true + profile: minimal + - uses: RustCrypto/actions/cargo-hack-install@master + - run: rm ../../Cargo.toml + - run: cargo update -Z minimal-versions + - run: cargo hack test --release --feature-powerset diff --git a/.github/workflows/signature.yml b/.github/workflows/signature.yml index 408dfeda4..57df87c66 100644 --- a/.github/workflows/signature.yml +++ b/.github/workflows/signature.yml @@ -37,10 +37,10 @@ jobs: profile: minimal - run: cargo build --no-default-features --release --target ${{ matrix.target }} - # minimal-versions: - # uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master - # with: - # working-directory: ${{ github.workflow }} + minimal-versions: + uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master + with: + working-directory: ${{ github.workflow }} test: runs-on: ubuntu-latest diff --git a/signature/Cargo.toml b/signature/Cargo.toml index d59349135..5159521aa 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -12,12 +12,12 @@ keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"] categories = ["cryptography", "no-std"] [dependencies] -digest = { version = "0.10.1", optional = true, default-features = false } +digest = { version = "0.10.3", optional = true, default-features = false } rand_core = { version = "0.6", optional = true, default-features = false } -signature_derive = { version = "=1.0.0-pre.4", optional = true, path = "derive" } +signature_derive = { version = "=1.0.0-pre.5", optional = true, path = "derive" } [dev-dependencies] -hex-literal = "0.2" +hex-literal = "0.2.2" sha2 = { version = "0.10", default-features = false } [features] diff --git a/signature/async/Cargo.toml b/signature/async/Cargo.toml index a3fc81480..1119fb00c 100644 --- a/signature/async/Cargo.toml +++ b/signature/async/Cargo.toml @@ -12,7 +12,7 @@ keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"] categories = ["cryptography", "no-std"] [dependencies] -async-trait = "0.1" +async-trait = "0.1.9" signature = { version = "1.5", path = ".." } [features] diff --git a/signature/derive/Cargo.toml b/signature/derive/Cargo.toml index 0aa15c9d6..c9eb09668 100644 --- a/signature/derive/Cargo.toml +++ b/signature/derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "signature_derive" -version = "1.0.0-pre.4" +version = "1.0.0-pre.5" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" description = "Custom derive support for the 'signature' crate" @@ -18,4 +18,4 @@ proc-macro = true proc-macro2 = "1" quote = "1" syn = "1" -synstructure = "0.12" +synstructure = "0.12.2" From 7177db3cbf508e034cbd81ed3fa1a37ca56a713f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 19 Feb 2022 21:54:13 +0000 Subject: [PATCH 0748/1461] build(deps): bump cipher from 0.3.0 to 0.4.2 in /crypto (#951) --- crypto/Cargo.lock | 26 +++++++++++++++++++++++--- crypto/Cargo.toml | 2 +- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/crypto/Cargo.lock b/crypto/Cargo.lock index 2d789fd57..e2ec53c3e 100644 --- a/crypto/Cargo.lock +++ b/crypto/Cargo.lock @@ -31,6 +31,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-padding" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5808df4b2412175c4db3afb115c83d8d0cd26ca4f30a042026cddef8580e526a" +dependencies = [ + "generic-array", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -39,11 +48,12 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cipher" -version = "0.3.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" +checksum = "035bd298db1557b73a277e9c599c5a50e0d2e6ee9dcac78f3f951cb2f7d88d8c" dependencies = [ - "generic-array", + "crypto-common", + "inout", ] [[package]] @@ -175,6 +185,16 @@ dependencies = [ "subtle", ] +[[package]] +name = "inout" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1f03d4ab4d5dc9ec2d219f86c15d2a15fc08239d1cd3b2d6a19717c0a2f443" +dependencies = [ + "block-padding", + "generic-array", +] + [[package]] name = "libc" version = "0.2.118" diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 7ef2d9d27..d67341e36 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -20,7 +20,7 @@ members = ["."] [dependencies] aead = { version = "0.4", optional = true, path = "../aead" } -cipher = { version = "0.3", optional = true } +cipher = { version = "0.4", optional = true } digest = { version = "0.10", optional = true } elliptic-curve = { version = "0.12.0-pre", optional = true, path = "../elliptic-curve" } mac = { version = "0.11", package = "crypto-mac", optional = true } From dbbab409335188c5ebd6cd88f1f7a54f66e62316 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Mon, 21 Feb 2022 16:18:47 +0000 Subject: [PATCH 0749/1461] Cache cargo index (#952) --- .github/workflows/aead.yml | 25 ++++++++++++--------- .github/workflows/async-signature.yml | 22 +++++++++--------- .github/workflows/cipher.yml | 29 +++++++++++++----------- .github/workflows/crypto-common.yml | 24 +++++++++++--------- .github/workflows/crypto.yml | 32 +++++++++++++++------------ .github/workflows/digest.yml | 30 +++++++++++++------------ .github/workflows/elliptic-curve.yml | 26 +++++++++++++--------- .github/workflows/kem.yml | 28 +++++++++++++---------- .github/workflows/password-hash.yml | 27 ++++++++++++---------- .github/workflows/security-audit.yml | 10 ++++----- .github/workflows/signature.yml | 24 +++++++++++--------- .github/workflows/universal-hash.yml | 24 +++++++++++--------- .github/workflows/workspace.yml | 13 ++++++----- Cargo.lock | 6 ++--- 14 files changed, 176 insertions(+), 144 deletions(-) diff --git a/.github/workflows/aead.yml b/.github/workflows/aead.yml index 0f394ad27..6164a0bf1 100644 --- a/.github/workflows/aead.yml +++ b/.github/workflows/aead.yml @@ -28,7 +28,8 @@ jobs: - thumbv7em-none-eabi - wasm32-unknown-unknown steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 + - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: profile: minimal @@ -56,7 +57,8 @@ jobs: - thumbv7em-none-eabi - wasm32-unknown-unknown steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 + - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: profile: minimal @@ -74,12 +76,13 @@ jobs: - 1.41.0 # MSRV - stable steps: - - uses: actions/checkout@v1 - - uses: actions-rs/toolchain@v1 - with: - toolchain: ${{ matrix.rust }} - override: true - profile: minimal - - run: cargo test --release --no-default-features - - run: cargo test --release - - run: cargo test --release --features dev,rand_core,stream,std + - uses: actions/checkout@v2 + - uses: RustCrypto/actions/cargo-cache@master + - uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ matrix.rust }} + override: true + profile: minimal + - run: cargo test --release --no-default-features + - run: cargo test --release + - run: cargo test --release --features dev,rand_core,stream,std diff --git a/.github/workflows/async-signature.yml b/.github/workflows/async-signature.yml index bda70d7de..e77166ac6 100644 --- a/.github/workflows/async-signature.yml +++ b/.github/workflows/async-signature.yml @@ -25,20 +25,22 @@ jobs: - 1.41.0 # MSRV - stable steps: - - uses: actions/checkout@v1 - - uses: actions-rs/toolchain@v1 - with: - toolchain: ${{ matrix.rust }} - override: true - profile: minimal - - run: cargo check --all-features - - run: cargo test --release - - run: cargo test --all-features --release + - uses: actions/checkout@v2 + - uses: RustCrypto/actions/cargo-cache@master + - uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ matrix.rust }} + override: true + profile: minimal + - run: cargo check --all-features + - run: cargo test --release + - run: cargo test --all-features --release minimal-versions: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 + - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: toolchain: nightly diff --git a/.github/workflows/cipher.yml b/.github/workflows/cipher.yml index 244120e0b..9f2497d65 100644 --- a/.github/workflows/cipher.yml +++ b/.github/workflows/cipher.yml @@ -28,7 +28,8 @@ jobs: - thumbv7em-none-eabi - wasm32-unknown-unknown steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 + - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: toolchain: ${{ matrix.rust }} @@ -44,7 +45,8 @@ jobs: minimal-versions: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 + - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: toolchain: nightly @@ -62,14 +64,15 @@ jobs: - 1.56.0 # MSRV - stable steps: - - uses: actions/checkout@v1 - - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: ${{ matrix.rust }} - - run: cargo check --all-features - - run: cargo test - - run: cargo test --features block-padding - - run: cargo test --features dev - - run: cargo test --features std - - run: cargo test --all-features + - uses: actions/checkout@v2 + - uses: RustCrypto/actions/cargo-cache@master + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.rust }} + - run: cargo check --all-features + - run: cargo test + - run: cargo test --features block-padding + - run: cargo test --features dev + - run: cargo test --features std + - run: cargo test --all-features diff --git a/.github/workflows/crypto-common.yml b/.github/workflows/crypto-common.yml index 29cb3c0fb..b569f926b 100644 --- a/.github/workflows/crypto-common.yml +++ b/.github/workflows/crypto-common.yml @@ -28,7 +28,8 @@ jobs: - thumbv7em-none-eabi - wasm32-unknown-unknown steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 + - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: toolchain: ${{ matrix.rust }} @@ -50,13 +51,14 @@ jobs: - 1.41.0 # MSRV - stable steps: - - uses: actions/checkout@v1 - - uses: actions-rs/toolchain@v1 - with: - toolchain: ${{ matrix.rust }} - override: true - profile: minimal - - run: cargo check --all-features - - run: cargo test - - run: cargo test --features std - - run: cargo test --all-features + - uses: actions/checkout@v2 + - uses: RustCrypto/actions/cargo-cache@master + - uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ matrix.rust }} + override: true + profile: minimal + - run: cargo check --all-features + - run: cargo test + - run: cargo test --features std + - run: cargo test --all-features diff --git a/.github/workflows/crypto.yml b/.github/workflows/crypto.yml index 60f8f1187..bd020750d 100644 --- a/.github/workflows/crypto.yml +++ b/.github/workflows/crypto.yml @@ -28,7 +28,8 @@ jobs: - thumbv7em-none-eabi - wasm32-unknown-unknown steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 + - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: toolchain: ${{ matrix.rust }} @@ -44,7 +45,8 @@ jobs: # minimal-versions: # runs-on: ubuntu-latest # steps: - # - uses: actions/checkout@v1 + # - uses: actions/checkout@v2 + # - uses: RustCrypto/actions/cargo-cache@master # - uses: actions-rs/toolchain@v1 # with: # toolchain: nightly @@ -62,21 +64,23 @@ jobs: - 1.57.0 # MSRV - stable steps: - - uses: actions/checkout@v1 - - uses: actions-rs/toolchain@v1 - with: - toolchain: ${{ matrix.rust }} - override: true - profile: minimal - - run: cargo check --all-features - - run: cargo test --no-default-features --release - - run: cargo test --release - - run: cargo test --all-features --release + - uses: actions/checkout@v2 + - uses: RustCrypto/actions/cargo-cache@master + - uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ matrix.rust }} + override: true + profile: minimal + - run: cargo check --all-features + - run: cargo test --no-default-features --release + - run: cargo test --release + - run: cargo test --all-features --release clippy: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 + - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: toolchain: 1.57.0 @@ -89,7 +93,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout sources - uses: actions/checkout@v1 + uses: actions/checkout@v2 - name: Install stable toolchain uses: actions-rs/toolchain@v1 diff --git a/.github/workflows/digest.yml b/.github/workflows/digest.yml index d3653ae0a..e12da129b 100644 --- a/.github/workflows/digest.yml +++ b/.github/workflows/digest.yml @@ -28,7 +28,8 @@ jobs: - thumbv7em-none-eabi - wasm32-unknown-unknown steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 + - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: toolchain: ${{ matrix.rust }} @@ -50,16 +51,17 @@ jobs: - 1.41.0 # MSRV - stable steps: - - uses: actions/checkout@v1 - - uses: actions-rs/toolchain@v1 - with: - toolchain: ${{ matrix.rust }} - override: true - profile: minimal - - run: cargo check --all-features - - run: cargo test --no-default-features - - run: cargo test - - run: cargo test --features dev - - run: cargo test --features alloc - - run: cargo test --features std - - run: cargo test --all-features + - uses: actions/checkout@v2 + - uses: RustCrypto/actions/cargo-cache@master + - uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ matrix.rust }} + override: true + profile: minimal + - run: cargo check --all-features + - run: cargo test --no-default-features + - run: cargo test + - run: cargo test --features dev + - run: cargo test --features alloc + - run: cargo test --features std + - run: cargo test --all-features diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index 6c063f412..38fc86e24 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -29,6 +29,7 @@ jobs: - wasm32-unknown-unknown steps: - uses: actions/checkout@v2 + - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: profile: minimal @@ -59,7 +60,8 @@ jobs: # minimal-versions: # runs-on: ubuntu-latest # steps: - # - uses: actions/checkout@v1 + # - uses: actions/checkout@v2 + # - uses: RustCrypto/actions/cargo-cache@master # - uses: actions-rs/toolchain@v1 # with: # toolchain: nightly @@ -78,21 +80,23 @@ jobs: - stable - nightly steps: - - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 - with: - toolchain: ${{ matrix.rust }} - override: true - profile: minimal - - run: cargo check --all-features - - run: cargo test --no-default-features - - run: cargo test - - run: cargo test --all-features + - uses: actions/checkout@v2 + - uses: RustCrypto/actions/cargo-cache@master + - uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ matrix.rust }} + override: true + profile: minimal + - run: cargo check --all-features + - run: cargo test --no-default-features + - run: cargo test + - run: cargo test --all-features clippy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: toolchain: 1.57.0 diff --git a/.github/workflows/kem.yml b/.github/workflows/kem.yml index c372d96de..04b5d5db6 100644 --- a/.github/workflows/kem.yml +++ b/.github/workflows/kem.yml @@ -28,7 +28,8 @@ jobs: - thumbv7em-none-eabi - wasm32-unknown-unknown steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 + - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: toolchain: ${{ matrix.rust }} @@ -42,7 +43,8 @@ jobs: # minimal-versions: # runs-on: ubuntu-latest # steps: - # - uses: actions/checkout@v1 + # - uses: actions/checkout@v2 + # - uses: RustCrypto/actions/cargo-cache@master # - uses: actions-rs/toolchain@v1 # with: # toolchain: nightly @@ -60,21 +62,23 @@ jobs: - 1.56.0 # MSRV - stable steps: - - uses: actions/checkout@v1 - - uses: actions-rs/toolchain@v1 - with: - toolchain: ${{ matrix.rust }} - override: true - profile: minimal - - run: cargo check --all-features - - run: cargo test --no-default-features --release - - run: cargo test --release - - run: cargo test --all-features --release + - uses: actions/checkout@v2 + - uses: RustCrypto/actions/cargo-cache@master + - uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ matrix.rust }} + override: true + profile: minimal + - run: cargo check --all-features + - run: cargo test --no-default-features --release + - run: cargo test --release + - run: cargo test --all-features --release clippy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: toolchain: 1.56.0 diff --git a/.github/workflows/password-hash.yml b/.github/workflows/password-hash.yml index b92f0d74e..942319eba 100644 --- a/.github/workflows/password-hash.yml +++ b/.github/workflows/password-hash.yml @@ -28,7 +28,8 @@ jobs: - thumbv7em-none-eabi - wasm32-unknown-unknown steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 + - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: toolchain: ${{ matrix.rust }} @@ -44,7 +45,8 @@ jobs: minimal-versions: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 + - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: toolchain: nightly @@ -62,13 +64,14 @@ jobs: - 1.57.0 # MSRV - stable steps: - - uses: actions/checkout@v1 - - uses: actions-rs/toolchain@v1 - with: - toolchain: ${{ matrix.rust }} - override: true - profile: minimal - - run: cargo check --all-features - - run: cargo test --release --no-default-features - - run: cargo test --release - - run: cargo test --release --all-features + - uses: actions/checkout@v2 + - uses: RustCrypto/actions/cargo-cache@master + - uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ matrix.rust }} + override: true + profile: minimal + - run: cargo check --all-features + - run: cargo test --release --no-default-features + - run: cargo test --release + - run: cargo test --release --all-features diff --git a/.github/workflows/security-audit.yml b/.github/workflows/security-audit.yml index b1091a4c2..e5372b5d3 100644 --- a/.github/workflows/security-audit.yml +++ b/.github/workflows/security-audit.yml @@ -13,7 +13,7 @@ jobs: name: Security Audit Workspace runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 - name: Cache cargo bin uses: actions/cache@v1 with: @@ -30,7 +30,7 @@ jobs: run: working-directory: crypto steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 - name: Cache cargo bin uses: actions/cache@v1 with: @@ -47,7 +47,7 @@ jobs: run: working-directory: elliptic-curve steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 - name: Cache cargo bin uses: actions/cache@v1 with: @@ -64,7 +64,7 @@ jobs: run: working-directory: kem steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 - name: Cache cargo bin uses: actions/cache@v1 with: @@ -81,7 +81,7 @@ jobs: run: working-directory: password-hash steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 - name: Cache cargo bin uses: actions/cache@v1 with: diff --git a/.github/workflows/signature.yml b/.github/workflows/signature.yml index 57df87c66..a314d9382 100644 --- a/.github/workflows/signature.yml +++ b/.github/workflows/signature.yml @@ -28,7 +28,8 @@ jobs: - thumbv7em-none-eabi - wasm32-unknown-unknown steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 + - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: toolchain: ${{ matrix.rust }} @@ -50,13 +51,14 @@ jobs: - 1.41.0 # MSRV - stable steps: - - uses: actions/checkout@v1 - - uses: actions-rs/toolchain@v1 - with: - toolchain: ${{ matrix.rust }} - override: true - profile: minimal - - run: cargo check --all-features - - run: cargo test --no-default-features --release - - run: cargo test --release - - run: cargo test --all-features --release + - uses: actions/checkout@v2 + - uses: RustCrypto/actions/cargo-cache@master + - uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ matrix.rust }} + override: true + profile: minimal + - run: cargo check --all-features + - run: cargo test --no-default-features --release + - run: cargo test --release + - run: cargo test --all-features --release diff --git a/.github/workflows/universal-hash.yml b/.github/workflows/universal-hash.yml index aeeaec468..723e0783c 100644 --- a/.github/workflows/universal-hash.yml +++ b/.github/workflows/universal-hash.yml @@ -28,7 +28,8 @@ jobs: - thumbv7em-none-eabi - wasm32-unknown-unknown steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 + - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: toolchain: ${{ matrix.rust }} @@ -50,13 +51,14 @@ jobs: - 1.41.0 # MSRV - stable steps: - - uses: actions/checkout@v1 - - uses: actions-rs/toolchain@v1 - with: - toolchain: ${{ matrix.rust }} - override: true - profile: minimal - - run: cargo check --all-features - - run: cargo test --no-default-features --release - - run: cargo test --release - - run: cargo test --all-features --release + - uses: actions/checkout@v2 + - uses: RustCrypto/actions/cargo-cache@master + - uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ matrix.rust }} + override: true + profile: minimal + - run: cargo check --all-features + - run: cargo test --no-default-features --release + - run: cargo test --release + - run: cargo test --all-features --release diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index f3f7d4ac9..6b013b0ae 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -17,7 +17,8 @@ jobs: clippy: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 + - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: toolchain: 1.57.0 @@ -39,7 +40,7 @@ jobs: rustfmt_workspace: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: toolchain: stable @@ -57,7 +58,7 @@ jobs: run: working-directory: crypto steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: toolchain: stable @@ -75,7 +76,7 @@ jobs: run: working-directory: elliptic-curve steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: toolchain: stable @@ -93,7 +94,7 @@ jobs: run: working-directory: kem steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: toolchain: stable @@ -111,7 +112,7 @@ jobs: run: working-directory: password-hash steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: toolchain: stable diff --git a/Cargo.lock b/Cargo.lock index 026303f18..7c7be5c06 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -168,9 +168,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.118" +version = "0.2.119" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06e509672465a0504304aa87f9f176f2b2b716ed8fb105ebe5c02dc6dce96a94" +checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4" [[package]] name = "lock_api" @@ -244,7 +244,7 @@ dependencies = [ [[package]] name = "signature_derive" -version = "1.0.0-pre.4" +version = "1.0.0-pre.5" dependencies = [ "proc-macro2", "quote", From 3d6003a488135df2460aa730d0ecc4bee6dece9e Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Tue, 22 Feb 2022 16:56:31 +0000 Subject: [PATCH 0750/1461] cipher: do not enable the alloc feature by default (#953) --- cipher/CHANGELOG.md | 8 +++++++- cipher/Cargo.lock | 2 +- cipher/Cargo.toml | 3 +-- cipher/src/lib.rs | 2 +- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/cipher/CHANGELOG.md b/cipher/CHANGELOG.md index 9467a7afa..7db2add74 100644 --- a/cipher/CHANGELOG.md +++ b/cipher/CHANGELOG.md @@ -5,7 +5,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 0.4.2 (2022-02-16) +## 0.4.3 (2022-02-22) +### Fixed +- Do not enable the `alloc` feature by default ([#953]) + +[#953]: https://github.com/RustCrypto/traits/pull/953 + +## 0.4.2 (2022-02-16) [YANKED] ### Fixed - Rename `BlockDecryptMut::decrypt_padded_vec` to `decrypt_padded_vec_mut` for consistency with other methods ([#941]) diff --git a/cipher/Cargo.lock b/cipher/Cargo.lock index 6cece1623..c03b6ac1e 100644 --- a/cipher/Cargo.lock +++ b/cipher/Cargo.lock @@ -19,7 +19,7 @@ dependencies = [ [[package]] name = "cipher" -version = "0.4.2" +version = "0.4.3" dependencies = [ "blobby", "crypto-common", diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index fb4c1bbe1..47a846dab 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "cipher" description = "Traits for describing block ciphers and stream ciphers" -version = "0.4.2" # Also update html_root_url in lib.rs when bumping this +version = "0.4.3" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" @@ -25,7 +25,6 @@ blobby = { version = "0.3", optional = true } zeroize = { version = "1.5", optional = true, default-features = false } [features] -default = ["alloc"] alloc = [] std = ["alloc", "crypto-common/std", "inout/std"] block-padding = ["inout/block-padding"] diff --git a/cipher/src/lib.rs b/cipher/src/lib.rs index afa68f9e9..c97ae4368 100644 --- a/cipher/src/lib.rs +++ b/cipher/src/lib.rs @@ -10,7 +10,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", - html_root_url = "https://docs.rs/cipher/0.4.2" + html_root_url = "https://docs.rs/cipher/0.4.3" )] #![warn(missing_docs, rust_2018_idioms)] From 6bd041ee8e20b400d7b74883a7dd11f4b74f50f9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 25 Feb 2022 15:29:25 -0700 Subject: [PATCH 0751/1461] build(deps): bump zeroize from 1.5.2 to 1.5.3 in /elliptic-curve (#955) Bumps [zeroize](https://github.com/RustCrypto/utils) from 1.5.2 to 1.5.3. - [Release notes](https://github.com/RustCrypto/utils/releases) - [Commits](https://github.com/RustCrypto/utils/compare/zeroize-v1.5.2...zeroize-v1.5.3) --- updated-dependencies: - dependency-name: zeroize dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- elliptic-curve/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index bfb4e7e4f..8dcfd36af 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -338,6 +338,6 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.5.2" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c88870063c39ee00ec285a2f8d6a966e5b6fb2becc4e8dac77ed0d370ed6006" +checksum = "50344758e2f40e3a1fcfc8f6f91aa57b5f8ebd8d27919fe6451f15aaaf9ee608" From 3041bfaf98bd7f44882bdad7300d4d45634ff807 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 27 Feb 2022 19:25:10 -0700 Subject: [PATCH 0752/1461] aead: add optional support for `BytesMut` as a `Buffer` (#956) Continuation of #837. Allows using `bytes::BytesMut` as an `aead::Buffer`. --- .github/workflows/aead.yml | 1 + Cargo.lock | 7 +++++++ aead/Cargo.toml | 1 + aead/src/lib.rs | 27 +++++++++++++++++++++++++++ 4 files changed, 36 insertions(+) diff --git a/.github/workflows/aead.yml b/.github/workflows/aead.yml index 6164a0bf1..e28aaea7a 100644 --- a/.github/workflows/aead.yml +++ b/.github/workflows/aead.yml @@ -38,6 +38,7 @@ jobs: override: true - run: cargo build --target ${{ matrix.target }} --release --no-default-features - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features bytes - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features rand_core - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features stream diff --git a/Cargo.lock b/Cargo.lock index 7c7be5c06..aa9a6e794 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7,6 +7,7 @@ name = "aead" version = "0.4.3" dependencies = [ "blobby", + "bytes", "generic-array", "heapless", "rand_core", @@ -52,6 +53,12 @@ version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +[[package]] +name = "bytes" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" + [[package]] name = "cfg-if" version = "1.0.0" diff --git a/aead/Cargo.toml b/aead/Cargo.toml index f5c7d00c4..fda7f826b 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -19,6 +19,7 @@ generic-array = { version = "0.14", default-features = false } # optional dependencies blobby = { version = "0.3", optional = true } +bytes = { version = "1", optional = true, default-features = false } heapless = { version = "0.7", optional = true, default-features = false } rand_core = { version = "0.6", optional = true } diff --git a/aead/src/lib.rs b/aead/src/lib.rs index fb67f6899..404259ce9 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -39,6 +39,10 @@ pub mod stream; pub use generic_array::{self, typenum::consts}; +#[cfg(feature = "bytes")] +#[cfg_attr(docsrs, doc(cfg(feature = "bytes")))] +pub use bytes; + #[cfg(feature = "heapless")] #[cfg_attr(docsrs, doc(cfg(feature = "heapless")))] pub use heapless; @@ -53,6 +57,9 @@ use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; #[cfg(feature = "alloc")] use alloc::vec::Vec; +#[cfg(feature = "bytes")] +use bytes::BytesMut; + #[cfg(feature = "rand_core")] use rand_core::{CryptoRng, RngCore}; @@ -506,6 +513,26 @@ impl Buffer for Vec { } } +#[cfg(feature = "bytes")] +impl Buffer for BytesMut { + fn len(&self) -> usize { + BytesMut::len(self) + } + + fn is_empty(&self) -> bool { + BytesMut::is_empty(self) + } + + fn extend_from_slice(&mut self, other: &[u8]) -> Result<()> { + BytesMut::extend_from_slice(self, other); + Ok(()) + } + + fn truncate(&mut self, len: usize) { + BytesMut::truncate(self, len); + } +} + #[cfg(feature = "heapless")] impl Buffer for heapless::Vec { fn extend_from_slice(&mut self, other: &[u8]) -> Result<()> { From 107530fdee0cc85cc4c99587285f255581c57651 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 7 Mar 2022 10:32:59 -0700 Subject: [PATCH 0753/1461] password-hash: add docs for `Salt::RECOMMENDED_LENGTH` (#957) Incorporates documentation from the PHC string format specification as to why the given length was chosen --- password-hash/src/salt.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/password-hash/src/salt.rs b/password-hash/src/salt.rs index b5f09f84d..9702f742c 100644 --- a/password-hash/src/salt.rs +++ b/password-hash/src/salt.rs @@ -37,7 +37,7 @@ const INVARIANT_VIOLATED_MSG: &str = "salt string invariant violated"; /// # Recommended length /// The recommended default length for a salt string is **16-bytes** (128-bits). /// -/// See below for rationale. +/// See [`Salt::RECOMMENDED_LENGTH`] for more information. /// /// # Constraints /// Salt strings are constrained to the following set of characters per the @@ -89,6 +89,15 @@ impl<'a> Salt<'a> { pub const MAX_LENGTH: usize = 64; /// Recommended length of a salt: 16-bytes. + /// + /// This recommendation comes from the [PHC string format specification]: + /// + /// > The role of salts is to achieve uniqueness. A *random* salt is fine + /// > for that as long as its length is sufficient; a 16-byte salt would + /// > work well (by definition, UUID are very good salts, and they encode + /// > over exactly 16 bytes). 16 bytes encode as 22 characters in B64. + /// + /// [PHC string format specification]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#function-duties pub const RECOMMENDED_LENGTH: usize = 16; /// Create a [`Salt`] from the given `str`, validating it according to From 09f46890bac26054b950afc2f8f2f074255e1c02 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 9 Mar 2022 10:31:48 -0700 Subject: [PATCH 0754/1461] Reunify Cargo workspace (#958) Places all crates into a single Cargo workspace again. Removing the toplevel Cargo.toml when running CI on legacy pre-2021 edition crates should suffice to let them retain their current MSRV. --- .github/dependabot.yml | 20 - .github/workflows/aead.yml | 4 + .github/workflows/async-signature.yml | 2 +- .github/workflows/crypto-common.yml | 4 + .github/workflows/digest.yml | 4 + .github/workflows/elliptic-curve.yml | 28 -- .github/workflows/kem.yml | 28 -- .github/workflows/signature.yml | 4 + .github/workflows/universal-hash.yml | 4 + Cargo.lock | 647 +++++++++++++++++++++++- Cargo.toml | 5 + cipher/Cargo.lock | 81 --- cipher/Cargo.toml | 4 - crypto/Cargo.lock | 296 ----------- crypto/Cargo.toml | 4 - elliptic-curve/Cargo.lock | 343 ------------- elliptic-curve/Cargo.toml | 4 - kem/Cargo.lock | 690 -------------------------- kem/Cargo.toml | 15 +- kem/tests/hpke.rs | 3 + password-hash/Cargo.lock | 62 --- password-hash/Cargo.toml | 6 +- signature/async/Cargo.toml | 5 +- signature/async/README.md | 4 +- signature/async/src/lib.rs | 2 +- 25 files changed, 683 insertions(+), 1586 deletions(-) delete mode 100644 cipher/Cargo.lock delete mode 100644 crypto/Cargo.lock delete mode 100644 elliptic-curve/Cargo.lock delete mode 100644 kem/Cargo.lock delete mode 100644 password-hash/Cargo.lock diff --git a/.github/dependabot.yml b/.github/dependabot.yml index ce2b35da8..5cde1657c 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,23 +5,3 @@ updates: schedule: interval: daily open-pull-requests-limit: 10 -- package-ecosystem: cargo - directory: "/crypto" - schedule: - interval: daily - open-pull-requests-limit: 10 -- package-ecosystem: cargo - directory: "/elliptic-curve" - schedule: - interval: daily - open-pull-requests-limit: 10 -- package-ecosystem: cargo - directory: "/kem" - schedule: - interval: daily - open-pull-requests-limit: 10 -- package-ecosystem: cargo - directory: "/password-hash" - schedule: - interval: daily - open-pull-requests-limit: 10 diff --git a/.github/workflows/aead.yml b/.github/workflows/aead.yml index e28aaea7a..b9d068325 100644 --- a/.github/workflows/aead.yml +++ b/.github/workflows/aead.yml @@ -36,6 +36,8 @@ jobs: toolchain: ${{ matrix.rust }} target: ${{ matrix.target }} override: true + # Isolate this crate from workspace which is otherwise MSRV 1.56 due to 2021 edition crates + - run: rm ../Cargo.toml - run: cargo build --target ${{ matrix.target }} --release --no-default-features - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features bytes @@ -84,6 +86,8 @@ jobs: toolchain: ${{ matrix.rust }} override: true profile: minimal + # Isolate this crate from workspace which is otherwise MSRV 1.56 due to 2021 edition crates + - run: rm ../Cargo.toml - run: cargo test --release --no-default-features - run: cargo test --release - run: cargo test --release --features dev,rand_core,stream,std diff --git a/.github/workflows/async-signature.yml b/.github/workflows/async-signature.yml index e77166ac6..11872c07c 100644 --- a/.github/workflows/async-signature.yml +++ b/.github/workflows/async-signature.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.41.0 # MSRV + - 1.56.0 # MSRV - stable steps: - uses: actions/checkout@v2 diff --git a/.github/workflows/crypto-common.yml b/.github/workflows/crypto-common.yml index b569f926b..5947c6a16 100644 --- a/.github/workflows/crypto-common.yml +++ b/.github/workflows/crypto-common.yml @@ -36,6 +36,8 @@ jobs: target: ${{ matrix.target }} override: true profile: minimal + # Isolate this crate from workspace which is otherwise MSRV 1.56 due to 2021 edition crates + - run: rm ../Cargo.toml - run: cargo build --target ${{ matrix.target }} minimal-versions: @@ -58,6 +60,8 @@ jobs: toolchain: ${{ matrix.rust }} override: true profile: minimal + # Isolate this crate from workspace which is otherwise MSRV 1.56 due to 2021 edition crates + - run: rm ../Cargo.toml - run: cargo check --all-features - run: cargo test - run: cargo test --features std diff --git a/.github/workflows/digest.yml b/.github/workflows/digest.yml index e12da129b..585de6cb7 100644 --- a/.github/workflows/digest.yml +++ b/.github/workflows/digest.yml @@ -36,6 +36,8 @@ jobs: target: ${{ matrix.target }} override: true profile: minimal + # Isolate this crate from workspace which is otherwise MSRV 1.56 due to 2021 edition crates + - run: rm ../Cargo.toml - run: cargo build --target ${{ matrix.target }} minimal-versions: @@ -58,6 +60,8 @@ jobs: toolchain: ${{ matrix.rust }} override: true profile: minimal + # Isolate this crate from workspace which is otherwise MSRV 1.56 due to 2021 edition crates + - run: rm ../Cargo.toml - run: cargo check --all-features - run: cargo test --no-default-features - run: cargo test diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index 38fc86e24..2cf7a1d1b 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -91,31 +91,3 @@ jobs: - run: cargo test --no-default-features - run: cargo test - run: cargo test --all-features - - clippy: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: RustCrypto/actions/cargo-cache@master - - uses: actions-rs/toolchain@v1 - with: - toolchain: 1.57.0 - components: clippy - override: true - profile: minimal - - run: cargo clippy --all --all-features -- -D warnings - - rustfmt: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - components: rustfmt - override: true - profile: minimal - - uses: actions-rs/cargo@v1 - with: - command: fmt - args: --all -- --check diff --git a/.github/workflows/kem.yml b/.github/workflows/kem.yml index 04b5d5db6..c25891862 100644 --- a/.github/workflows/kem.yml +++ b/.github/workflows/kem.yml @@ -73,31 +73,3 @@ jobs: - run: cargo test --no-default-features --release - run: cargo test --release - run: cargo test --all-features --release - - clippy: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: RustCrypto/actions/cargo-cache@master - - uses: actions-rs/toolchain@v1 - with: - toolchain: 1.56.0 - components: clippy - override: true - profile: minimal - - run: cargo clippy --all --all-features -- -D warnings - - rustfmt: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - components: rustfmt - override: true - profile: minimal - - uses: actions-rs/cargo@v1 - with: - command: fmt - args: --all -- --check diff --git a/.github/workflows/signature.yml b/.github/workflows/signature.yml index a314d9382..5ff5efd01 100644 --- a/.github/workflows/signature.yml +++ b/.github/workflows/signature.yml @@ -36,6 +36,8 @@ jobs: target: ${{ matrix.target }} override: true profile: minimal + # Isolate this crate from workspace which is otherwise MSRV 1.56 due to 2021 edition crates + - run: rm ../Cargo.toml - run: cargo build --no-default-features --release --target ${{ matrix.target }} minimal-versions: @@ -58,6 +60,8 @@ jobs: toolchain: ${{ matrix.rust }} override: true profile: minimal + # Isolate this crate from workspace which is otherwise MSRV 1.56 due to 2021 edition crates + - run: rm ../Cargo.toml - run: cargo check --all-features - run: cargo test --no-default-features --release - run: cargo test --release diff --git a/.github/workflows/universal-hash.yml b/.github/workflows/universal-hash.yml index 723e0783c..a72fb941e 100644 --- a/.github/workflows/universal-hash.yml +++ b/.github/workflows/universal-hash.yml @@ -36,6 +36,8 @@ jobs: target: ${{ matrix.target }} override: true profile: minimal + # Isolate this crate from workspace which is otherwise MSRV 1.56 due to 2021 edition crates + - run: rm ../Cargo.toml - run: cargo build --no-default-features --release --target ${{ matrix.target }} minimal-versions: @@ -58,6 +60,8 @@ jobs: toolchain: ${{ matrix.rust }} override: true profile: minimal + # Isolate this crate from workspace which is otherwise MSRV 1.56 due to 2021 edition crates + - run: rm ../Cargo.toml - run: cargo check --all-features - run: cargo test --no-default-features --release - run: cargo test --release diff --git a/Cargo.lock b/Cargo.lock index aa9a6e794..0f65983f6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15,10 +15,10 @@ dependencies = [ [[package]] name = "async-signature" -version = "0.1.0" +version = "0.2.0-pre" dependencies = [ "async-trait", - "signature", + "signature 1.5.0", ] [[package]] @@ -32,12 +32,54 @@ dependencies = [ "syn", ] +[[package]] +name = "base16ct" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" + +[[package]] +name = "base64ct" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "874f8444adcb4952a8bc51305c8be95c8ec8237bb0d2e78d2e039f771f8828a0" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bitvec" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5237f00a8c86130a0cc317830e558b966dd7850d48a953d998c813f01a41b527" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + [[package]] name = "blobby" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "847495c209977a90e8aad588b959d0ca9f5dc228096d29a6bd3defd53f35eaec" +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + [[package]] name = "block-buffer" version = "0.10.2" @@ -47,6 +89,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-padding" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5808df4b2412175c4db3afb115c83d8d0cd26ca4f30a042026cddef8580e526a" +dependencies = [ + "generic-array", +] + [[package]] name = "byteorder" version = "1.4.3" @@ -59,12 +110,53 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" +[[package]] +name = "cc" +version = "1.0.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" +dependencies = [ + "jobserver", +] + [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cipher" +version = "0.4.3" +dependencies = [ + "blobby", + "crypto-common 0.1.3", + "inout", + "zeroize", +] + +[[package]] +name = "cipher" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1873270f8f7942c191139cb8a40fd228da6c3fd2fc376d7e92d47aa14aeb59e" +dependencies = [ + "crypto-common 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "inout", +] + +[[package]] +name = "const-oid" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d6f2aa4d0537bcc1c74df8755072bd31c1ef1a3a1b85a68e8404a8c353b7b8b" + +[[package]] +name = "const-oid" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" + [[package]] name = "cpufeatures" version = "0.2.1" @@ -74,6 +166,44 @@ dependencies = [ "libc", ] +[[package]] +name = "crypto" +version = "0.4.0-pre" +dependencies = [ + "aead", + "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-mac", + "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", + "elliptic-curve 0.12.0-pre.1", + "password-hash", + "signature 1.5.0", + "universal-hash", +] + +[[package]] +name = "crypto-bigint" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8658c15c5d921ddf980f7fe25b1e82f4b7a4083b2c4985fea4922edb8e43e07d" +dependencies = [ + "generic-array", + "rand_core", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-bigint" +version = "0.4.0-pre.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a9df9647255ed398be26379810e02ed1d58263570b3bcd243ee2481f79c88b1" +dependencies = [ + "generic-array", + "rand_core", + "subtle", + "zeroize", +] + [[package]] name = "crypto-common" version = "0.1.3" @@ -93,12 +223,50 @@ dependencies = [ "typenum", ] +[[package]] +name = "crypto-mac" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "der" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79b71cca7d95d7681a4b3b9cdf63c8dbc3730d0584c2c74e31416d64a90493f4" +dependencies = [ + "const-oid 0.6.2", +] + +[[package]] +name = "der" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" +dependencies = [ + "const-oid 0.7.1", + "pem-rfc7468 0.3.1", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + [[package]] name = "digest" version = "0.10.3" dependencies = [ "blobby", - "block-buffer", + "block-buffer 0.10.2", "crypto-common 0.1.3", "subtle", ] @@ -109,10 +277,89 @@ version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" dependencies = [ - "block-buffer", + "block-buffer 0.10.2", "crypto-common 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ecdsa" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43ee23aa5b4f68c7a092b5c3beb25f50c406adc75e2363634f242f28ab255372" +dependencies = [ + "der 0.4.5", + "elliptic-curve 0.10.4", + "hmac", + "signature 1.3.2", +] + +[[package]] +name = "elliptic-curve" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83e5c176479da93a0983f0a6fdc3c1b8e7d5be0d7fe3fe05a99f15b96582b9a8" +dependencies = [ + "crypto-bigint 0.2.5", + "ff 0.10.1", + "generic-array", + "group 0.10.0", + "pkcs8 0.7.6", + "rand_core", + "subtle", + "zeroize", +] + +[[package]] +name = "elliptic-curve" +version = "0.12.0-pre.1" +dependencies = [ + "base16ct", + "base64ct", + "crypto-bigint 0.4.0-pre.0", + "der 0.5.1", + "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", + "ff 0.11.0", + "generic-array", + "group 0.11.0", + "hex-literal 0.3.4", + "pem-rfc7468 0.3.1", + "rand_core", + "sec1", + "serde", + "serde_json", + "sha2 0.10.2", + "sha3", + "subtle", + "zeroize", +] + +[[package]] +name = "ff" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0f40b2dcd8bc322217a5f6559ae5f9e9d1de202a2ecee2e9eafcbece7562a4f" +dependencies = [ + "rand_core", + "subtle", +] + +[[package]] +name = "ff" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2958d04124b9f27f175eaeb9a9f383d026098aa837eadd8ba22c11f13a05b9e" +dependencies = [ + "bitvec", + "rand_core", + "subtle", +] + +[[package]] +name = "funty" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1847abb9cb65d566acd5942e94aea9c8f547ad02c98e1649326fc0e8910b8b1e" + [[package]] name = "generic-array" version = "0.14.5" @@ -134,6 +381,34 @@ dependencies = [ "wasi", ] +[[package]] +name = "glob" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" + +[[package]] +name = "group" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c363a5301b8f153d80747126a04b3c82073b9fe3130571a9d170cacdeaf7912" +dependencies = [ + "ff 0.10.1", + "rand_core", + "subtle", +] + +[[package]] +name = "group" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5ac374b108929de78460075f3dc439fa66df9d8fc77e8f12caa5165fcf0c89" +dependencies = [ + "ff 0.11.0", + "rand_core", + "subtle", +] + [[package]] name = "hash32" version = "0.2.1" @@ -164,6 +439,12 @@ dependencies = [ "proc-macro-hack", ] +[[package]] +name = "hex-literal" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" + [[package]] name = "hex-literal-impl" version = "0.2.3" @@ -173,6 +454,70 @@ dependencies = [ "proc-macro-hack", ] +[[package]] +name = "hkdf" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01706d578d5c281058480e673ae4086a9f4710d8df1ad80a5b03e39ece5f886b" +dependencies = [ + "digest 0.9.0", + "hmac", +] + +[[package]] +name = "hmac" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" +dependencies = [ + "crypto-mac", + "digest 0.9.0", +] + +[[package]] +name = "inout" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1f03d4ab4d5dc9ec2d219f86c15d2a15fc08239d1cd3b2d6a19717c0a2f443" +dependencies = [ + "block-padding", + "generic-array", +] + +[[package]] +name = "itoa" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" + +[[package]] +name = "jobserver" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa" +dependencies = [ + "libc", +] + +[[package]] +name = "keccak" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" + +[[package]] +name = "kem" +version = "0.1.0" +dependencies = [ + "generic-array", + "p256", + "pqcrypto", + "pqcrypto-traits", + "rand", + "rand_core", + "x3dh-ke", +] + [[package]] name = "libc" version = "0.2.119" @@ -188,6 +533,119 @@ dependencies = [ "scopeguard", ] +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "p256" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d053368e1bae4c8a672953397bd1bd7183dde1c72b0b7612a15719173148d186" +dependencies = [ + "ecdsa", + "elliptic-curve 0.10.4", + "sha2 0.9.9", +] + +[[package]] +name = "password-hash" +version = "0.4.0-pre" +dependencies = [ + "base64ct", + "rand_core", + "subtle", +] + +[[package]] +name = "pem-rfc7468" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f22eb0e3c593294a99e9ff4b24cf6b752d43f193aa4415fe5077c159996d497" +dependencies = [ + "base64ct", +] + +[[package]] +name = "pem-rfc7468" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01de5d978f34aa4b2296576379fcc416034702fd94117c56ffd8a1a767cefb30" +dependencies = [ + "base64ct", +] + +[[package]] +name = "pkcs8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee3ef9b64d26bad0536099c816c6734379e45bbd5f14798def6809e5cc350447" +dependencies = [ + "der 0.4.5", + "pem-rfc7468 0.2.3", + "spki 0.4.1", + "zeroize", +] + +[[package]] +name = "pkcs8" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" +dependencies = [ + "der 0.5.1", + "spki 0.5.4", + "zeroize", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" + +[[package]] +name = "pqcrypto" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9da39bd0587bff4189521766c34f3203263926f7527906578a96d22a81a700d5" +dependencies = [ + "pqcrypto-saber", + "pqcrypto-traits", +] + +[[package]] +name = "pqcrypto-internals" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64b13e34e3758451a74aee45db434cc258b7794225bcbef3274b981545058645" +dependencies = [ + "cc", + "getrandom", + "libc", +] + +[[package]] +name = "pqcrypto-saber" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57ba16b59d256e2cae57bcdbd013f73b32496ebc66db3db6ccb79a10f0d4b275" +dependencies = [ + "cc", + "glob", + "libc", + "pqcrypto-internals", + "pqcrypto-traits", +] + +[[package]] +name = "pqcrypto-traits" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97e91cb6af081c6daad5fa705f8adb0634c027662052cb3174bdf2957bf07e25" + [[package]] name = "proc-macro-hack" version = "0.5.19" @@ -212,6 +670,33 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "radium" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "643f8f41a8ebc4c5dc4515c82bb8abd397b527fc20fd681b7c011c2aee5d44fb" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + [[package]] name = "rand_core" version = "0.6.3" @@ -221,12 +706,84 @@ dependencies = [ "getrandom", ] +[[package]] +name = "ryu" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" + [[package]] name = "scopeguard" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "sec1" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08da66b8b0965a5555b6bd6639e68ccba85e1e2506f5fbb089e93f8a04e1a2d1" +dependencies = [ + "der 0.5.1", + "generic-array", + "pkcs8 0.8.0", + "subtle", + "zeroize", +] + +[[package]] +name = "serde" +version = "1.0.136" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_bytes" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16ae07dd2f88a366f15bd0632ba725227018c69a1c8550a927324f8eb8368bb9" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.136" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + [[package]] name = "sha2" version = "0.10.2" @@ -238,14 +795,34 @@ dependencies = [ "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "sha3" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "881bf8156c87b6301fc5ca6b27f11eeb2761224c7081e69b409d5a1951a70c86" +dependencies = [ + "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", + "keccak", +] + +[[package]] +name = "signature" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2807892cfa58e081aa1f1111391c7a0649d4fa127a4ffbe34bcbfb35a1171a4" +dependencies = [ + "digest 0.9.0", + "rand_core", +] + [[package]] name = "signature" version = "1.5.0" dependencies = [ "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", - "hex-literal", + "hex-literal 0.2.2", "rand_core", - "sha2", + "sha2 0.10.2", "signature_derive", ] @@ -268,6 +845,25 @@ dependencies = [ "lock_api", ] +[[package]] +name = "spki" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c01a0c15da1b0b0e1494112e7af814a678fec9bd157881b49beac661e9b6f32" +dependencies = [ + "der 0.4.5", +] + +[[package]] +name = "spki" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" +dependencies = [ + "base64ct", + "der 0.5.1", +] + [[package]] name = "stable_deref_trait" version = "1.2.0" @@ -303,6 +899,12 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + [[package]] name = "typenum" version = "1.15.0" @@ -334,3 +936,36 @@ name = "wasi" version = "0.10.2+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + +[[package]] +name = "wyz" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "129e027ad65ce1453680623c3fb5163cbf7107bfe1aa32257e7d0e63f9ced188" +dependencies = [ + "tap", +] + +[[package]] +name = "x3dh-ke" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ee8f59e7095cfd040618f328897c4b07925933de33b517949a64bc97b9fcde3" +dependencies = [ + "base64ct", + "bincode", + "const-oid 0.6.2", + "getrandom", + "hkdf", + "p256", + "rand_core", + "serde", + "serde_bytes", + "sha2 0.9.9", +] + +[[package]] +name = "zeroize" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50344758e2f40e3a1fcfc8f6f91aa57b5f8ebd8d27919fe6451f15aaaf9ee608" diff --git a/Cargo.toml b/Cargo.toml index 2c1cb7dc6..dc7d95785 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,13 @@ [workspace] +resolver = "2" members = [ "aead", + "cipher", + "crypto", "crypto-common", "digest", + "elliptic-curve", + "kem", "signature", "signature/async", "universal-hash", diff --git a/cipher/Cargo.lock b/cipher/Cargo.lock deleted file mode 100644 index c03b6ac1e..000000000 --- a/cipher/Cargo.lock +++ /dev/null @@ -1,81 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "blobby" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "847495c209977a90e8aad588b959d0ca9f5dc228096d29a6bd3defd53f35eaec" - -[[package]] -name = "block-padding" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5808df4b2412175c4db3afb115c83d8d0cd26ca4f30a042026cddef8580e526a" -dependencies = [ - "generic-array", -] - -[[package]] -name = "cipher" -version = "0.4.3" -dependencies = [ - "blobby", - "crypto-common", - "inout", - "zeroize", -] - -[[package]] -name = "crypto-common" -version = "0.1.3" -dependencies = [ - "generic-array", - "rand_core", - "typenum", -] - -[[package]] -name = "generic-array" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "inout" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1f03d4ab4d5dc9ec2d219f86c15d2a15fc08239d1cd3b2d6a19717c0a2f443" -dependencies = [ - "block-padding", - "generic-array", -] - -[[package]] -name = "rand_core" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" - -[[package]] -name = "typenum" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zeroize" -version = "1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c88870063c39ee00ec285a2f8d6a966e5b6fb2becc4e8dac77ed0d370ed6006" diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index 47a846dab..9bf6f4ac7 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -12,10 +12,6 @@ repository = "https://github.com/RustCrypto/traits" keywords = ["crypto", "block-cipher", "stream-cipher", "trait"] categories = ["cryptography", "no-std"] -# Hack to allow this crate to coexist with pre-2021 edition crates -[workspace] -members = ["."] - [dependencies] crypto-common = { version = "0.1.3", path = "../crypto-common" } inout = "0.1" diff --git a/crypto/Cargo.lock b/crypto/Cargo.lock deleted file mode 100644 index e2ec53c3e..000000000 --- a/crypto/Cargo.lock +++ /dev/null @@ -1,296 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "aead" -version = "0.4.3" -dependencies = [ - "generic-array", - "rand_core", -] - -[[package]] -name = "base16ct" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" - -[[package]] -name = "base64ct" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "874f8444adcb4952a8bc51305c8be95c8ec8237bb0d2e78d2e039f771f8828a0" - -[[package]] -name = "block-buffer" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" -dependencies = [ - "generic-array", -] - -[[package]] -name = "block-padding" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5808df4b2412175c4db3afb115c83d8d0cd26ca4f30a042026cddef8580e526a" -dependencies = [ - "generic-array", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "cipher" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "035bd298db1557b73a277e9c599c5a50e0d2e6ee9dcac78f3f951cb2f7d88d8c" -dependencies = [ - "crypto-common", - "inout", -] - -[[package]] -name = "const-oid" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" - -[[package]] -name = "crypto" -version = "0.4.0-pre" -dependencies = [ - "aead", - "cipher", - "crypto-mac", - "digest", - "elliptic-curve", - "password-hash", - "signature", - "universal-hash", -] - -[[package]] -name = "crypto-bigint" -version = "0.4.0-pre.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a9df9647255ed398be26379810e02ed1d58263570b3bcd243ee2481f79c88b1" -dependencies = [ - "generic-array", - "rand_core", - "subtle", - "zeroize", -] - -[[package]] -name = "crypto-common" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "crypto-mac" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" -dependencies = [ - "generic-array", - "subtle", -] - -[[package]] -name = "der" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" -dependencies = [ - "const-oid", -] - -[[package]] -name = "digest" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" -dependencies = [ - "block-buffer", - "crypto-common", -] - -[[package]] -name = "elliptic-curve" -version = "0.12.0-pre.1" -dependencies = [ - "base16ct", - "crypto-bigint", - "der", - "ff", - "generic-array", - "group", - "rand_core", - "sec1", - "subtle", - "zeroize", -] - -[[package]] -name = "ff" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2958d04124b9f27f175eaeb9a9f383d026098aa837eadd8ba22c11f13a05b9e" -dependencies = [ - "rand_core", - "subtle", -] - -[[package]] -name = "generic-array" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "group" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5ac374b108929de78460075f3dc439fa66df9d8fc77e8f12caa5165fcf0c89" -dependencies = [ - "ff", - "rand_core", - "subtle", -] - -[[package]] -name = "inout" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1f03d4ab4d5dc9ec2d219f86c15d2a15fc08239d1cd3b2d6a19717c0a2f443" -dependencies = [ - "block-padding", - "generic-array", -] - -[[package]] -name = "libc" -version = "0.2.118" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06e509672465a0504304aa87f9f176f2b2b716ed8fb105ebe5c02dc6dce96a94" - -[[package]] -name = "password-hash" -version = "0.4.0-pre" -dependencies = [ - "base64ct", - "rand_core", - "subtle", -] - -[[package]] -name = "pkcs8" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" -dependencies = [ - "der", - "spki", - "zeroize", -] - -[[package]] -name = "rand_core" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" -dependencies = [ - "getrandom", -] - -[[package]] -name = "sec1" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08da66b8b0965a5555b6bd6639e68ccba85e1e2506f5fbb089e93f8a04e1a2d1" -dependencies = [ - "der", - "generic-array", - "pkcs8", - "subtle", - "zeroize", -] - -[[package]] -name = "signature" -version = "1.5.0" - -[[package]] -name = "spki" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" -dependencies = [ - "base64ct", - "der", -] - -[[package]] -name = "subtle" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" - -[[package]] -name = "typenum" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" - -[[package]] -name = "universal-hash" -version = "0.4.1" -dependencies = [ - "generic-array", - "subtle", -] - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" - -[[package]] -name = "zeroize" -version = "1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c88870063c39ee00ec285a2f8d6a966e5b6fb2becc4e8dac77ed0d370ed6006" diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index d67341e36..69068517b 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -14,10 +14,6 @@ readme = "README.md" edition = "2021" rust-version = "1.57" -# Hack to allow this crate to coexist with pre-2021 edition crates -[workspace] -members = ["."] - [dependencies] aead = { version = "0.4", optional = true, path = "../aead" } cipher = { version = "0.4", optional = true } diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock deleted file mode 100644 index 8dcfd36af..000000000 --- a/elliptic-curve/Cargo.lock +++ /dev/null @@ -1,343 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "base16ct" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" - -[[package]] -name = "base64ct" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "874f8444adcb4952a8bc51305c8be95c8ec8237bb0d2e78d2e039f771f8828a0" - -[[package]] -name = "bitvec" -version = "0.22.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5237f00a8c86130a0cc317830e558b966dd7850d48a953d998c813f01a41b527" -dependencies = [ - "funty", - "radium", - "tap", - "wyz", -] - -[[package]] -name = "block-buffer" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" -dependencies = [ - "generic-array", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "const-oid" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" - -[[package]] -name = "cpufeatures" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" -dependencies = [ - "libc", -] - -[[package]] -name = "crypto-bigint" -version = "0.4.0-pre.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a9df9647255ed398be26379810e02ed1d58263570b3bcd243ee2481f79c88b1" -dependencies = [ - "generic-array", - "rand_core", - "subtle", - "zeroize", -] - -[[package]] -name = "crypto-common" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "der" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" -dependencies = [ - "const-oid", - "pem-rfc7468", -] - -[[package]] -name = "digest" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" -dependencies = [ - "block-buffer", - "crypto-common", -] - -[[package]] -name = "elliptic-curve" -version = "0.12.0-pre.1" -dependencies = [ - "base16ct", - "base64ct", - "crypto-bigint", - "der", - "digest", - "ff", - "generic-array", - "group", - "hex-literal", - "pem-rfc7468", - "rand_core", - "sec1", - "serde", - "serde_json", - "sha2", - "sha3", - "subtle", - "zeroize", -] - -[[package]] -name = "ff" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2958d04124b9f27f175eaeb9a9f383d026098aa837eadd8ba22c11f13a05b9e" -dependencies = [ - "bitvec", - "rand_core", - "subtle", -] - -[[package]] -name = "funty" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1847abb9cb65d566acd5942e94aea9c8f547ad02c98e1649326fc0e8910b8b1e" - -[[package]] -name = "generic-array" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "group" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5ac374b108929de78460075f3dc439fa66df9d8fc77e8f12caa5165fcf0c89" -dependencies = [ - "ff", - "rand_core", - "subtle", -] - -[[package]] -name = "hex-literal" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" - -[[package]] -name = "itoa" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" - -[[package]] -name = "keccak" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" - -[[package]] -name = "libc" -version = "0.2.118" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06e509672465a0504304aa87f9f176f2b2b716ed8fb105ebe5c02dc6dce96a94" - -[[package]] -name = "pem-rfc7468" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01de5d978f34aa4b2296576379fcc416034702fd94117c56ffd8a1a767cefb30" -dependencies = [ - "base64ct", -] - -[[package]] -name = "pkcs8" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" -dependencies = [ - "der", - "spki", - "zeroize", -] - -[[package]] -name = "radium" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "643f8f41a8ebc4c5dc4515c82bb8abd397b527fc20fd681b7c011c2aee5d44fb" - -[[package]] -name = "rand_core" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" -dependencies = [ - "getrandom", -] - -[[package]] -name = "ryu" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" - -[[package]] -name = "sec1" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08da66b8b0965a5555b6bd6639e68ccba85e1e2506f5fbb089e93f8a04e1a2d1" -dependencies = [ - "der", - "generic-array", - "pkcs8", - "subtle", - "zeroize", -] - -[[package]] -name = "serde" -version = "1.0.136" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" - -[[package]] -name = "serde_json" -version = "1.0.79" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "sha2" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55deaec60f81eefe3cce0dc50bda92d6d8e88f2a27df7c5033b42afeb1ed2676" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "sha3" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "881bf8156c87b6301fc5ca6b27f11eeb2761224c7081e69b409d5a1951a70c86" -dependencies = [ - "digest", - "keccak", -] - -[[package]] -name = "spki" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" -dependencies = [ - "base64ct", - "der", -] - -[[package]] -name = "subtle" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" - -[[package]] -name = "tap" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" - -[[package]] -name = "typenum" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" - -[[package]] -name = "wyz" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "129e027ad65ce1453680623c3fb5163cbf7107bfe1aa32257e7d0e63f9ced188" -dependencies = [ - "tap", -] - -[[package]] -name = "zeroize" -version = "1.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50344758e2f40e3a1fcfc8f6f91aa57b5f8ebd8d27919fe6451f15aaaf9ee608" diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 8187f4654..59897d4bb 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -15,10 +15,6 @@ keywords = ["crypto", "ecc", "elliptic", "weierstrass"] edition = "2021" rust-version = "1.57" -# Hack to allow this crate to coexist with pre-2021 edition crates -[workspace] -members = ["."] - [dependencies] base16ct = "0.1.1" crypto-bigint = { version = "=0.4.0-pre.0", default-features = false, features = ["rand_core", "generic-array", "zeroize"] } diff --git a/kem/Cargo.lock b/kem/Cargo.lock deleted file mode 100644 index 4af6cb6ba..000000000 --- a/kem/Cargo.lock +++ /dev/null @@ -1,690 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "aead" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" -dependencies = [ - "generic-array", -] - -[[package]] -name = "aes" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" -dependencies = [ - "cfg-if", - "cipher", - "cpufeatures", - "opaque-debug", -] - -[[package]] -name = "aes-gcm" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df5f85a83a7d8b0442b6aa7b504b8212c1733da07b98aae43d4bc21b2cb3cdf6" -dependencies = [ - "aead", - "aes", - "cipher", - "ctr", - "ghash", - "subtle", -] - -[[package]] -name = "base64ct" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "874f8444adcb4952a8bc51305c8be95c8ec8237bb0d2e78d2e039f771f8828a0" - -[[package]] -name = "bincode" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" -dependencies = [ - "serde", -] - -[[package]] -name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "generic-array", -] - -[[package]] -name = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - -[[package]] -name = "cc" -version = "1.0.73" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" -dependencies = [ - "jobserver", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "chacha20" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01b72a433d0cf2aef113ba70f62634c56fddb0f244e6377185c56a7cadbd8f91" -dependencies = [ - "cfg-if", - "cipher", - "cpufeatures", - "zeroize", -] - -[[package]] -name = "chacha20poly1305" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b84ed6d1d5f7aa9bdde921a5090e0ca4d934d250ea3b402a5fab3a994e28a2a" -dependencies = [ - "aead", - "chacha20", - "cipher", - "poly1305", - "zeroize", -] - -[[package]] -name = "cipher" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" -dependencies = [ - "generic-array", -] - -[[package]] -name = "const-oid" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d6f2aa4d0537bcc1c74df8755072bd31c1ef1a3a1b85a68e8404a8c353b7b8b" - -[[package]] -name = "cpufeatures" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" -dependencies = [ - "libc", -] - -[[package]] -name = "crypto-bigint" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f83bd3bb4314701c568e340cd8cf78c975aa0ca79e03d3f6d1677d5b0c9c0c03" -dependencies = [ - "generic-array", - "rand_core 0.6.3", - "subtle", - "zeroize", -] - -[[package]] -name = "crypto-mac" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" -dependencies = [ - "generic-array", - "subtle", -] - -[[package]] -name = "ctr" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea" -dependencies = [ - "cipher", -] - -[[package]] -name = "curve25519-dalek" -version = "3.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90f9d052967f590a76e62eb387bd0bbb1b000182c3cefe5364db6b7211651bc0" -dependencies = [ - "byteorder", - "digest", - "rand_core 0.5.1", - "subtle", - "zeroize", -] - -[[package]] -name = "der" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79b71cca7d95d7681a4b3b9cdf63c8dbc3730d0584c2c74e31416d64a90493f4" -dependencies = [ - "const-oid", -] - -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array", -] - -[[package]] -name = "ecdsa" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43ee23aa5b4f68c7a092b5c3beb25f50c406adc75e2363634f242f28ab255372" -dependencies = [ - "der", - "elliptic-curve", - "hmac", - "signature", -] - -[[package]] -name = "elliptic-curve" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "beca177dcb8eb540133e7680baff45e7cc4d93bf22002676cec549f82343721b" -dependencies = [ - "crypto-bigint", - "ff", - "generic-array", - "group", - "pkcs8", - "rand_core 0.6.3", - "subtle", - "zeroize", -] - -[[package]] -name = "ff" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0f40b2dcd8bc322217a5f6559ae5f9e9d1de202a2ecee2e9eafcbece7562a4f" -dependencies = [ - "rand_core 0.6.3", - "subtle", -] - -[[package]] -name = "generic-array" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "ghash" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1583cc1656d7839fd3732b80cf4f38850336cdb9b8ded1cd399ca62958de3c99" -dependencies = [ - "opaque-debug", - "polyval", -] - -[[package]] -name = "glob" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" - -[[package]] -name = "group" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c363a5301b8f153d80747126a04b3c82073b9fe3130571a9d170cacdeaf7912" -dependencies = [ - "ff", - "rand_core 0.6.3", - "subtle", -] - -[[package]] -name = "hkdf" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01706d578d5c281058480e673ae4086a9f4710d8df1ad80a5b03e39ece5f886b" -dependencies = [ - "digest", - "hmac", -] - -[[package]] -name = "hmac" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" -dependencies = [ - "crypto-mac", - "digest", -] - -[[package]] -name = "hpke" -version = "0.8.0" -source = "git+https://github.com/rozbb/rust-hpke?rev=3c795445f38317d6a0868259caf3e87916548356#3c795445f38317d6a0868259caf3e87916548356" -dependencies = [ - "aead", - "aes-gcm", - "byteorder", - "chacha20poly1305", - "digest", - "generic-array", - "hkdf", - "paste", - "rand_core 0.6.3", - "sha2", - "subtle", - "x25519-dalek", - "zeroize", -] - -[[package]] -name = "jobserver" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa" -dependencies = [ - "libc", -] - -[[package]] -name = "kem" -version = "0.1.0" -dependencies = [ - "generic-array", - "hpke", - "p256", - "pqcrypto", - "pqcrypto-traits", - "rand", - "rand_core 0.6.3", - "x3dh-ke", -] - -[[package]] -name = "libc" -version = "0.2.118" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06e509672465a0504304aa87f9f176f2b2b716ed8fb105ebe5c02dc6dce96a94" - -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - -[[package]] -name = "p256" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d053368e1bae4c8a672953397bd1bd7183dde1c72b0b7612a15719173148d186" -dependencies = [ - "ecdsa", - "elliptic-curve", - "sha2", -] - -[[package]] -name = "paste" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0744126afe1a6dd7f394cb50a716dbe086cb06e255e53d8d0185d82828358fb5" - -[[package]] -name = "pem-rfc7468" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f22eb0e3c593294a99e9ff4b24cf6b752d43f193aa4415fe5077c159996d497" -dependencies = [ - "base64ct", -] - -[[package]] -name = "pkcs8" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee3ef9b64d26bad0536099c816c6734379e45bbd5f14798def6809e5cc350447" -dependencies = [ - "der", - "pem-rfc7468", - "spki", - "zeroize", -] - -[[package]] -name = "poly1305" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "048aeb476be11a4b6ca432ca569e375810de9294ae78f4774e78ea98a9246ede" -dependencies = [ - "cpufeatures", - "opaque-debug", - "universal-hash", -] - -[[package]] -name = "polyval" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8419d2b623c7c0896ff2d5d96e2cb4ede590fed28fcc34934f4c33c036e620a1" -dependencies = [ - "cfg-if", - "cpufeatures", - "opaque-debug", - "universal-hash", -] - -[[package]] -name = "ppv-lite86" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" - -[[package]] -name = "pqcrypto" -version = "0.14.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9da39bd0587bff4189521766c34f3203263926f7527906578a96d22a81a700d5" -dependencies = [ - "pqcrypto-saber", - "pqcrypto-traits", -] - -[[package]] -name = "pqcrypto-internals" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64b13e34e3758451a74aee45db434cc258b7794225bcbef3274b981545058645" -dependencies = [ - "cc", - "getrandom", - "libc", -] - -[[package]] -name = "pqcrypto-saber" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57ba16b59d256e2cae57bcdbd013f73b32496ebc66db3db6ccb79a10f0d4b275" -dependencies = [ - "cc", - "glob", - "libc", - "pqcrypto-internals", - "pqcrypto-traits", -] - -[[package]] -name = "pqcrypto-traits" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97e91cb6af081c6daad5fa705f8adb0634c027662052cb3174bdf2957bf07e25" - -[[package]] -name = "proc-macro2" -version = "1.0.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" -dependencies = [ - "unicode-xid", -] - -[[package]] -name = "quote" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core 0.6.3", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.3", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" - -[[package]] -name = "rand_core" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" -dependencies = [ - "getrandom", -] - -[[package]] -name = "serde" -version = "1.0.136" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_bytes" -version = "0.11.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16ae07dd2f88a366f15bd0632ba725227018c69a1c8550a927324f8eb8368bb9" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_derive" -version = "1.0.136" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "sha2" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" -dependencies = [ - "block-buffer", - "cfg-if", - "cpufeatures", - "digest", - "opaque-debug", -] - -[[package]] -name = "signature" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2807892cfa58e081aa1f1111391c7a0649d4fa127a4ffbe34bcbfb35a1171a4" -dependencies = [ - "digest", - "rand_core 0.6.3", -] - -[[package]] -name = "spki" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c01a0c15da1b0b0e1494112e7af814a678fec9bd157881b49beac661e9b6f32" -dependencies = [ - "der", -] - -[[package]] -name = "subtle" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" - -[[package]] -name = "syn" -version = "1.0.86" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b" -dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] - -[[package]] -name = "synstructure" -version = "0.12.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "unicode-xid", -] - -[[package]] -name = "typenum" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" - -[[package]] -name = "unicode-xid" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" - -[[package]] -name = "universal-hash" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05" -dependencies = [ - "generic-array", - "subtle", -] - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" - -[[package]] -name = "x25519-dalek" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2392b6b94a576b4e2bf3c5b2757d63f10ada8020a2e4d08ac849ebcf6ea8e077" -dependencies = [ - "curve25519-dalek", - "rand_core 0.5.1", - "zeroize", -] - -[[package]] -name = "x3dh-ke" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ee8f59e7095cfd040618f328897c4b07925933de33b517949a64bc97b9fcde3" -dependencies = [ - "base64ct", - "bincode", - "const-oid", - "getrandom", - "hkdf", - "p256", - "rand_core 0.6.3", - "serde", - "serde_bytes", - "sha2", -] - -[[package]] -name = "zeroize" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f8f187641dad4f680d25c4bfc4225b418165984179f26ca76ec4fb6441d3a17" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] diff --git a/kem/Cargo.toml b/kem/Cargo.toml index 50d87a483..fce312b49 100644 --- a/kem/Cargo.toml +++ b/kem/Cargo.toml @@ -12,10 +12,6 @@ keywords = ["crypto"] categories = ["cryptography", "no-std"] rust-version = "1.56" -# Hack to allow this crate to coexist with pre-2021 edition crates -[workspace] -members = ["."] - [dependencies] rand_core = "0.6" generic-array = "0.14" @@ -27,11 +23,12 @@ p256 = { version = "0.9", features = [ "ecdsa" ] } pqcrypto = { version = "0.14", default-features = false, features = [ "pqcrypto-saber" ] } pqcrypto-traits = "0.3" -[dev-dependencies.hpke] -git = "https://github.com/rozbb/rust-hpke" -rev = "3c795445f38317d6a0868259caf3e87916548356" -default-features = false -features = [ "x25519" ] +# TODO(tarcieri): re-enable when `zeroize` compatibility can be resolved +#[dev-dependencies.hpke] +#git = "https://github.com/rozbb/rust-hpke" +#rev = "3c795445f38317d6a0868259caf3e87916548356" +#default-features = false +#features = [ "x25519" ] [features] default = [] diff --git a/kem/tests/hpke.rs b/kem/tests/hpke.rs index e287038ec..36ca6b3d5 100644 --- a/kem/tests/hpke.rs +++ b/kem/tests/hpke.rs @@ -1,3 +1,6 @@ +// TODO(tarcieri): re-enable when `zeroize` dependency issues are resolved +#![cfg(disabled)] + use generic_array::GenericArray; use hpke::{ kem::{Kem as KemTrait, X25519HkdfSha256}, diff --git a/password-hash/Cargo.lock b/password-hash/Cargo.lock deleted file mode 100644 index d0e568674..000000000 --- a/password-hash/Cargo.lock +++ /dev/null @@ -1,62 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "base64ct" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "874f8444adcb4952a8bc51305c8be95c8ec8237bb0d2e78d2e039f771f8828a0" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "getrandom" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "libc" -version = "0.2.118" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06e509672465a0504304aa87f9f176f2b2b716ed8fb105ebe5c02dc6dce96a94" - -[[package]] -name = "password-hash" -version = "0.4.0-pre" -dependencies = [ - "base64ct", - "rand_core", - "subtle", -] - -[[package]] -name = "rand_core" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" -dependencies = [ - "getrandom", -] - -[[package]] -name = "subtle" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" - -[[package]] -name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index 9a0c3dc2e..c0a8c1486 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -16,13 +16,9 @@ keywords = ["crypt", "mcf", "password", "pbkdf", "phc"] edition = "2021" rust-version = "1.57" -# Hack to allow this crate to coexist with pre-2021 edition crates -[workspace] -members = ["."] - [dependencies] base64ct = "1" -subtle = { version = ">=2, <2.5", default-features = false } +subtle = { version = "2", default-features = false } # optional features rand_core = { version = "0.6", optional = true, default-features = false } diff --git a/signature/async/Cargo.toml b/signature/async/Cargo.toml index 1119fb00c..208d8656b 100644 --- a/signature/async/Cargo.toml +++ b/signature/async/Cargo.toml @@ -1,15 +1,16 @@ [package] name = "async-signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "0.1.0" # Also update html_root_url in lib.rs when bumping this +version = "0.2.0-pre" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/async-signature" repository = "https://github.com/RustCrypto/traits/tree/master/signature/async" readme = "README.md" -edition = "2018" keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"] categories = ["cryptography", "no-std"] +edition = "2021" +rust-version = "1.56" [dependencies] async-trait = "0.1.9" diff --git a/signature/async/README.md b/signature/async/README.md index 1ec573ab3..135e6241a 100644 --- a/signature/async/README.md +++ b/signature/async/README.md @@ -9,7 +9,7 @@ ## Minimum Supported Rust Version -Rust **1.41** or higher. +Rust **1.56** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -36,7 +36,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/async-signature/badge.svg [docs-link]: https://docs.rs/async-signature/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.56+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260048-signatures [build-image]: https://github.com/RustCrypto/traits/workflows/async-signature/badge.svg?branch=master&event=push diff --git a/signature/async/src/lib.rs b/signature/async/src/lib.rs index 02a0f6609..c7a3f6365 100644 --- a/signature/async/src/lib.rs +++ b/signature/async/src/lib.rs @@ -21,7 +21,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/async-signature/0.1.0" + html_root_url = "https://docs.rs/async-signature/0.2.0-pre" )] #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms, unused_qualifications)] From d728dda991b355d3afc7422a6fd4c88a77b37a52 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 9 Mar 2022 11:18:09 -0700 Subject: [PATCH 0755/1461] password-hash: make `Ident::new` fallible; add `Ident::new_unwrap` (#960) Unifies the `const fn` implementation of `Ident::new` and `TryFrom`, with the former now able to return a result thanks to const panic. Since `Debug` isn't const-friendly yet and therefore `Result::unwrap` cannot be used in const contexts, adds a `::new_unwrap` function as a stopgap. It performs some pattern matching and uses const panic to handle the `Err` case. --- password-hash/src/ident.rs | 137 +++++++++------------------ password-hash/src/params.rs | 21 ++-- password-hash/tests/hashing.rs | 2 +- password-hash/tests/password_hash.rs | 2 +- password-hash/tests/test_vectors.rs | 6 +- 5 files changed, 63 insertions(+), 105 deletions(-) diff --git a/password-hash/src/ident.rs b/password-hash/src/ident.rs index 8283385ce..02e326916 100644 --- a/password-hash/src/ident.rs +++ b/password-hash/src/ident.rs @@ -47,41 +47,42 @@ impl<'a> Ident<'a> { /// Parse an [`Ident`] from a string. /// - /// # Panics - /// - /// Must conform to the contraints given in the type-level documentation, - /// or else it will panic. - /// - /// This method is intended for use in a `const` context where instead of - /// panicking it will cause a compile error. - /// - /// For fallible non-panicking parsing of an [`Ident`], use the [`TryFrom`] - /// impl on this type instead. - pub const fn new(s: &'a str) -> Self { + /// String must conform to the constraints given in the type-level + /// documentation. + pub const fn new(s: &'a str) -> Result { let input = s.as_bytes(); - assert!(!input.is_empty(), "PHC ident string can't be empty"); - assert!(input.len() <= Self::MAX_LENGTH, "PHC ident string too long"); - - macro_rules! validate_chars { - ($($pos:expr),+) => { - $( - if $pos < input.len() { - assert!( - is_char_valid(input[$pos]), - "invalid character in PHC string ident" - ); + match input.len() { + 1..=Self::MAX_LENGTH => { + let mut i = 0; + + while i < input.len() { + if !matches!(input[i], b'a'..=b'z' | b'0'..=b'9' | b'-') { + return Err(Error::ParamNameInvalid); } - )+ - }; - } - validate_chars!( - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31 - ); + i += 1; + } + + Ok(Self(s)) + } + _ => Err(Error::ParamNameInvalid), + } + } - Self(s) + /// Parse an [`Ident`] from a string, panicking on parse errors. + /// + /// This function exists as a workaround for `unwrap` not yet being + /// stable in `const fn` contexts, and is intended to allow the result to + /// be bound to a constant value. + pub const fn new_unwrap(s: &'a str) -> Self { + assert!(!s.is_empty(), "PHC ident string can't be empty"); + assert!(s.len() <= Self::MAX_LENGTH, "PHC ident string too long"); + + match Self::new(s) { + Ok(ident) => ident, + Err(_) => panic!("invalid PHC string format identifier"), + } } /// Borrow this ident as a `str` @@ -110,24 +111,7 @@ impl<'a> TryFrom<&'a str> for Ident<'a> { type Error = Error; fn try_from(s: &'a str) -> Result { - if s.is_empty() { - return Err(Error::ParamNameInvalid); - } - - let bytes = s.as_bytes(); - let too_long = bytes.len() > Self::MAX_LENGTH; - - if too_long { - return Err(Error::ParamNameInvalid); - } - - for &c in bytes { - if !is_char_valid(c) { - return Err(Error::ParamNameInvalid); - } - } - - Ok(Self::new(s)) + Self::new(s) } } @@ -143,11 +127,6 @@ impl<'a> fmt::Debug for Ident<'a> { } } -/// Ensure the given ASCII character (i.e. byte) is allowed in an [`Ident`]. -const fn is_char_valid(c: u8) -> bool { - matches!(c, b'a'..=b'z' | b'0'..=b'9' | b'-') -} - #[cfg(test)] mod tests { use super::{Error, Ident}; @@ -163,58 +142,30 @@ mod tests { let valid_examples = ["6", "x", "argon2d", "01234567891123456789212345678931"]; for &example in &valid_examples { - let const_val = Ident::new(example); - let try_from_val = Ident::try_from(example).unwrap(); - assert_eq!(example, &*const_val); - assert_eq!(example, &*try_from_val); + assert_eq!(example, &*Ident::new(example).unwrap()); } } #[test] - #[should_panic] - fn reject_empty_const() { - Ident::new(INVALID_EMPTY); + fn reject_empty() { + assert_eq!(Ident::new(INVALID_EMPTY), Err(Error::ParamNameInvalid)); } #[test] - fn reject_empty_fallible() { - let err = Ident::try_from(INVALID_EMPTY).err().unwrap(); - assert_eq!(err, Error::ParamNameInvalid); + fn reject_invalid() { + assert_eq!(Ident::new(INVALID_CHAR), Err(Error::ParamNameInvalid)); } #[test] - #[should_panic] - fn reject_invalid_char_const() { - Ident::new(INVALID_CHAR); + fn reject_too_long() { + assert_eq!(Ident::new(INVALID_TOO_LONG), Err(Error::ParamNameInvalid)); } #[test] - fn reject_invalid_char_fallible() { - let err = Ident::try_from(INVALID_CHAR).err().unwrap(); - assert_eq!(err, Error::ParamNameInvalid); - } - - #[test] - #[should_panic] - fn reject_too_long_const() { - Ident::new(INVALID_TOO_LONG); - } - - #[test] - fn reject_too_long_fallible() { - let err = Ident::try_from(INVALID_TOO_LONG).err().unwrap(); - assert_eq!(err, Error::ParamNameInvalid); - } - - #[test] - #[should_panic] - fn reject_invalid_char_and_too_long_const() { - Ident::new(INVALID_CHAR_AND_TOO_LONG); - } - - #[test] - fn reject_invalid_char_and_too_long_fallible() { - let err = Ident::try_from(INVALID_CHAR_AND_TOO_LONG).err().unwrap(); - assert_eq!(err, Error::ParamNameInvalid); + fn reject_invalid_char_and_too_long() { + assert_eq!( + Ident::new(INVALID_CHAR_AND_TOO_LONG), + Err(Error::ParamNameInvalid) + ); } } diff --git a/password-hash/src/params.rs b/password-hash/src/params.rs index 913a55f49..d0524e9f5 100644 --- a/password-hash/src/params.rs +++ b/password-hash/src/params.rs @@ -261,8 +261,15 @@ impl<'a> Iterator for Iter<'a> { fn next(&mut self) -> Option> { let mut param = self.inner.as_mut()?.next()?.split(PAIR_DELIMITER); - let name = Ident::new(param.next().expect(INVARIANT_VIOLATED_MSG)); - let value = Value::try_from(param.next().expect(INVARIANT_VIOLATED_MSG)) + + let name = param + .next() + .and_then(|id| Ident::try_from(id).ok()) + .expect(INVARIANT_VIOLATED_MSG); + + let value = param + .next() + .and_then(|value| Value::try_from(value).ok()) .expect(INVARIANT_VIOLATED_MSG); debug_assert_eq!(param.next(), None); @@ -351,7 +358,7 @@ mod tests { #[test] fn duplicate_names() { - let name = Ident::new("a"); + let name = Ident::new("a").unwrap(); let mut params = ParamsString::new(); params.add_decimal(name, 1).unwrap(); @@ -363,9 +370,9 @@ mod tests { fn from_iter() { let params = ParamsString::from_iter( [ - (Ident::new("a"), Value::try_from("1").unwrap()), - (Ident::new("b"), Value::try_from("2").unwrap()), - (Ident::new("c"), Value::try_from("3").unwrap()), + (Ident::new("a").unwrap(), Value::try_from("1").unwrap()), + (Ident::new("b").unwrap(), Value::try_from("2").unwrap()), + (Ident::new("c").unwrap(), Value::try_from("3").unwrap()), ] .iter() .cloned(), @@ -387,7 +394,7 @@ mod tests { let mut i = params.iter(); for (name, value) in &[("a", "1"), ("b", "2"), ("c", "3")] { - let name = Ident::new(name); + let name = Ident::new(name).unwrap(); let value = Value::try_from(*value).unwrap(); assert_eq!(i.next(), Some((name, value))); } diff --git a/password-hash/tests/hashing.rs b/password-hash/tests/hashing.rs index b88bff86a..ef30c71ac 100644 --- a/password-hash/tests/hashing.rs +++ b/password-hash/tests/hashing.rs @@ -4,7 +4,7 @@ pub use password_hash::{ Decimal, Error, Ident, Output, ParamsString, PasswordHash, PasswordHasher, Result, Salt, }; -const ALG: Ident = Ident::new("example"); +const ALG: Ident = Ident::new_unwrap("example"); /// Stub password hashing function for testing. pub struct StubPasswordHasher; diff --git a/password-hash/tests/password_hash.rs b/password-hash/tests/password_hash.rs index 30e4357ed..6b391f6b1 100644 --- a/password-hash/tests/password_hash.rs +++ b/password-hash/tests/password_hash.rs @@ -6,7 +6,7 @@ use password_hash::{Ident, ParamsString, PasswordHash, Salt}; -const EXAMPLE_ALGORITHM: Ident = Ident::new("argon2d"); +const EXAMPLE_ALGORITHM: Ident = Ident::new_unwrap("argon2d"); const EXAMPLE_SALT: &str = "saltsaltsaltsaltsalt"; const EXAMPLE_HASH: &[u8] = &[ 0x85, 0xab, 0x21, 0x85, 0xab, 0x21, 0x85, 0xab, 0x21, 0x85, 0xab, 0x21, 0x85, 0xab, 0x21, 0x85, diff --git a/password-hash/tests/test_vectors.rs b/password-hash/tests/test_vectors.rs index 95d097379..d1c20a2b4 100644 --- a/password-hash/tests/test_vectors.rs +++ b/password-hash/tests/test_vectors.rs @@ -11,7 +11,7 @@ const SCRYPT_HASH: &str = #[test] fn argon2id() { let ph = PasswordHash::new(ARGON2D_HASH).unwrap(); - assert_eq!(ph.algorithm, Ident::new("argon2d")); + assert_eq!(ph.algorithm, Ident::new("argon2d").unwrap()); assert_eq!(ph.version, Some(19)); assert_eq!(ph.params.iter().count(), 3); assert_eq!(ph.params.get_decimal("m").unwrap(), 512); @@ -25,7 +25,7 @@ fn argon2id() { #[test] fn bcrypt() { let ph = PasswordHash::new(BCRYPT_HASH).unwrap(); - assert_eq!(ph.algorithm, Ident::new("2b")); + assert_eq!(ph.algorithm, Ident::new("2b").unwrap()); assert_eq!(ph.version, None); assert_eq!(ph.params.len(), 0); assert_eq!(ph.salt.unwrap().to_string(), "MTIzNA"); @@ -39,7 +39,7 @@ fn bcrypt() { #[test] fn scrypt() { let ph = PasswordHash::new(SCRYPT_HASH).unwrap(); - assert_eq!(ph.algorithm, Ident::new("scrypt")); + assert_eq!(ph.algorithm, Ident::new("scrypt").unwrap()); assert_eq!(ph.version, None); assert_eq!(ph.params.len(), 0); assert_eq!(ph.salt.unwrap().to_string(), "epIxT/h6HbbwHaehFnh/bw"); From cfb132a906b99baf6324c16cf233170642df7b9f Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 9 Mar 2022 12:17:48 -0700 Subject: [PATCH 0756/1461] password-hash v0.4.0 (#961) --- Cargo.lock | 2 +- crypto/Cargo.toml | 2 +- password-hash/CHANGELOG.md | 19 +++++++++++++++++++ password-hash/Cargo.toml | 2 +- password-hash/src/lib.rs | 2 +- 5 files changed, 23 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0f65983f6..35e5d5121 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -552,7 +552,7 @@ dependencies = [ [[package]] name = "password-hash" -version = "0.4.0-pre" +version = "0.4.0" dependencies = [ "base64ct", "rand_core", diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 69068517b..0e4500afd 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -20,7 +20,7 @@ cipher = { version = "0.4", optional = true } digest = { version = "0.10", optional = true } elliptic-curve = { version = "0.12.0-pre", optional = true, path = "../elliptic-curve" } mac = { version = "0.11", package = "crypto-mac", optional = true } -password-hash = { version = "=0.4.0-pre", optional = true, path = "../password-hash" } +password-hash = { version = "0.4", optional = true, path = "../password-hash" } signature = { version = "1.5", optional = true, default-features = false, path = "../signature" } universal-hash = { version = "0.4", optional = true, path = "../universal-hash" } diff --git a/password-hash/CHANGELOG.md b/password-hash/CHANGELOG.md index b4be72b68..e0bbbf1d1 100644 --- a/password-hash/CHANGELOG.md +++ b/password-hash/CHANGELOG.md @@ -5,6 +5,25 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.4.0 (2022-03-09) +### Changed +- Leverage `const_panic`; MSRV 1.57 ([#896]) +- Rust 2021 edition upgrade ([#897]) +- Make `Ident::new` fallible; add `Ident::new_unwrap` ([#896], [#960]) + +### Fixed +- Better `Debug`/`Display` impls for `SaltString` ([#804]) + +### Removed +- `base64ct` version restrictions ([#914]) + +[#804]: https://github.com/RustCrypto/traits/pull/804 +[#896]: https://github.com/RustCrypto/traits/pull/896 +[#897]: https://github.com/RustCrypto/traits/pull/897 +[#897]: https://github.com/RustCrypto/traits/pull/897 +[#914]: https://github.com/RustCrypto/traits/pull/914 +[#960]: https://github.com/RustCrypto/traits/pull/960 + ## 0.3.2 (2021-09-15) ### Fixed - Remove unused lifetimes ([#760]) diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index c0a8c1486..3ea1275d4 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -5,7 +5,7 @@ Traits which describe the functionality of password hashing algorithms, as well as a `no_std`-friendly implementation of the PHC string format (a well-defined subset of the Modular Crypt Format a.k.a. MCF) """ -version = "0.4.0-pre" # Also update html_root_url in lib.rs when bumping this +version = "0.4.0" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index c59fa2b1f..7048e6927 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -4,7 +4,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/password-hash/0.4.0-pre" + html_root_url = "https://docs.rs/password-hash/0.4.0" )] #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms, unused_lifetimes)] From 1af673bb9c24776ecada3776f3105808382292b9 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Wed, 9 Mar 2022 19:38:11 +0000 Subject: [PATCH 0757/1461] Update MSRV badges (#962) --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ca83276cb..e4a345014 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Collection of traits which describe functionality of cryptographic primitives. | [`digest`] | [Cryptographic hash function] | [![crates.io](https://img.shields.io/crates/v/digest.svg)](https://crates.io/crates/digest) | [![Documentation](https://docs.rs/digest/badge.svg)](https://docs.rs/digest) | ![MSRV 1.41][msrv-1.41] | | [`elliptic‑curve`] | [Elliptic curve cryptography] | [![crates.io](https://img.shields.io/crates/v/elliptic-curve.svg)](https://crates.io/crates/elliptic-curve) | [![Documentation](https://docs.rs/elliptic-curve/badge.svg)](https://docs.rs/elliptic-curve) | ![MSRV 1.56][msrv-1.56] | | [`kem`] | [Key encapsulation mechanism] | [![crates.io](https://img.shields.io/crates/v/kem.svg)](https://crates.io/crates/kem) | [![Documentation](https://docs.rs/kem/badge.svg)](https://docs.rs/kem) | ![MSRV 1.56][msrv-1.56] | -| [`password-hash`] | [Password hashing] | [![crates.io](https://img.shields.io/crates/v/password-hash.svg)](https://crates.io/crates/password-hash) | [![Documentation](https://docs.rs/password-hash/badge.svg)](https://docs.rs/password-hash) | ![MSRV 1.47][msrv-1.47] | +| [`password-hash`] | [Password hashing] | [![crates.io](https://img.shields.io/crates/v/password-hash.svg)](https://crates.io/crates/password-hash) | [![Documentation](https://docs.rs/password-hash/badge.svg)](https://docs.rs/password-hash) | ![MSRV 1.57][msrv-1.57] | | [`signature`] | [Digital signature] | [![crates.io](https://img.shields.io/crates/v/signature.svg)](https://crates.io/crates/signature) | [![Documentation](https://docs.rs/signature/badge.svg)](https://docs.rs/signature) | ![MSRV 1.41][msrv-1.41] | | [`universal‑hash`] | [Universal hash function] | [![crates.io](https://img.shields.io/crates/v/universal-hash.svg)](https://crates.io/crates/universal-hash) | [![Documentation](https://docs.rs/universal-hash/badge.svg)](https://docs.rs/universal-hash) | ![MSRV 1.41][msrv-1.41] | @@ -23,7 +23,7 @@ Collection of traits which describe functionality of cryptographic primitives. | Crate name | Description | Crates.io | Docs | MSRV | |------------|-------------------------|:---------:|:-----:|:----:| -| [`crypto`] | Facade for trait crates | [![crates.io](https://img.shields.io/crates/v/crypto.svg)](https://crates.io/crates/crypto) | [![Documentation](https://docs.rs/crypto/badge.svg)](https://docs.rs/crypto) | ![MSRV 1.56][msrv-1.56] | +| [`crypto`] | Facade for trait crates | [![crates.io](https://img.shields.io/crates/v/crypto.svg)](https://crates.io/crates/crypto) | [![Documentation](https://docs.rs/crypto/badge.svg)](https://docs.rs/crypto) | ![MSRV 1.57][msrv-1.57] | ### Minimum Supported Rust Version (MSRV) Policy @@ -50,8 +50,8 @@ Unless you explicitly state otherwise, any contribution intentionally submitted [deps-image]: https://deps.rs/repo/github/RustCrypto/traits/status.svg [deps-link]: https://deps.rs/repo/github/RustCrypto/traits [msrv-1.41]: https://img.shields.io/badge/rustc-1.41.0+-blue.svg -[msrv-1.47]: https://img.shields.io/badge/rustc-1.47.0+-blue.svg [msrv-1.56]: https://img.shields.io/badge/rustc-1.56.0+-blue.svg +[msrv-1.57]: https://img.shields.io/badge/rustc-1.57.0+-blue.svg [//]: # (crates) From c385ff2cc045fb5d098e6318e6daab9c826eb05a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 11 Mar 2022 15:10:34 -0700 Subject: [PATCH 0758/1461] build(deps): bump base64ct from 1.3.3 to 1.4.1 (#963) Bumps [base64ct](https://github.com/RustCrypto/formats) from 1.3.3 to 1.4.1. - [Release notes](https://github.com/RustCrypto/formats/releases) - [Commits](https://github.com/RustCrypto/formats/commits) --- updated-dependencies: - dependency-name: base64ct dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 35e5d5121..5df396ef6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -40,9 +40,9 @@ checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" [[package]] name = "base64ct" -version = "1.3.3" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "874f8444adcb4952a8bc51305c8be95c8ec8237bb0d2e78d2e039f771f8828a0" +checksum = "71acf5509fc522cce1b100ac0121c635129bfd4d91cdf036bcc9b9935f97ccf5" [[package]] name = "bincode" From ad0572f49fb5924de078cb5233e025562ebfd4b2 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 16 Mar 2022 22:09:47 -0600 Subject: [PATCH 0759/1461] elliptic-curve: add hex `serde` (de)serializer for `PublicKey` (#967) This commit changes the `Serializer` and `Deserializer` impls on the `PublicKey` type to work more like the ones on other types in this crate and its downstream dependencies: - Use binary DER serialization with binary formats (what it does today) - Use an upper-case hex serialization of the DER in conjunction with "human readable" formats Though richer formats exist for this use case (such as `JwkEcKey` which is an existing implementation of JWK), hex-serialized DER is relatively easy to work with, and can be decoded easily with online tools such as https://lapo.it/asn1js/ Note that the `Deserialize` impl for `PublicKey` never worked with human-readable formats as it was attempting to deserialize to `&[u8]`, which doesn't work with formats like JSON or TOML because they need an intermediate decoding step and therefore require deserialization to `Vec`. So this isn't a breaking change from the `Deserialize` side. Fixes RustCrypto/elliptic-curves#536 --- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/public_key.rs | 31 ++++++++++++++++++++----------- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 59897d4bb..684a258f9 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -42,7 +42,7 @@ sha3 = "0.10" [features] default = ["arithmetic"] -alloc = ["der/alloc", "sec1/alloc", "zeroize/alloc"] # todo: use weak activation for `group`/`sec1` alloc when available +alloc = ["base16ct/alloc", "der/alloc", "sec1/alloc", "zeroize/alloc"] # todo: use weak activation for `group`/`sec1` alloc when available arithmetic = ["ff", "group"] bits = ["arithmetic", "ff/bits"] dev = ["arithmetic", "hex-literal", "pem", "pkcs8"] diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index edc6e6aa6..b00bc2a26 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -32,7 +32,6 @@ use { use alloc::string::{String, ToString}; #[cfg(all(feature = "pem", feature = "serde"))] -#[cfg_attr(docsrs, doc(cfg(all(feature = "pem", feature = "serde"))))] use serde::{de, ser, Deserialize, Serialize}; /// Elliptic curve public keys. @@ -353,8 +352,8 @@ where } } -#[cfg(all(feature = "pem", feature = "serde"))] -#[cfg_attr(docsrs, doc(cfg(all(feature = "pem", feature = "serde"))))] +#[cfg(all(feature = "alloc", feature = "serde"))] +#[cfg_attr(docsrs, doc(cfg(all(feature = "alloc", feature = "serde"))))] impl Serialize for PublicKey where C: Curve + AlgorithmParameters + ProjectiveArithmetic, @@ -365,15 +364,18 @@ where where S: ser::Serializer, { - self.to_public_key_der() - .map_err(ser::Error::custom)? - .as_ref() - .serialize(serializer) + let der = self.to_public_key_der().map_err(ser::Error::custom)?; + + if serializer.is_human_readable() { + base16ct::upper::encode_string(der.as_ref()).serialize(serializer) + } else { + der.as_ref().serialize(serializer) + } } } -#[cfg(all(feature = "pem", feature = "serde"))] -#[cfg_attr(docsrs, doc(cfg(all(feature = "pem", feature = "serde"))))] +#[cfg(all(feature = "alloc", feature = "serde"))] +#[cfg_attr(docsrs, doc(cfg(all(feature = "alloc", feature = "serde"))))] impl<'de, C> Deserialize<'de> for PublicKey where C: Curve + AlgorithmParameters + ProjectiveArithmetic, @@ -386,8 +388,15 @@ where { use de::Error; - <&[u8]>::deserialize(deserializer) - .and_then(|bytes| Self::from_public_key_der(bytes).map_err(D::Error::custom)) + if deserializer.is_human_readable() { + let der_bytes = base16ct::mixed::decode_vec(<&str>::deserialize(deserializer)?) + .map_err(D::Error::custom)?; + Self::from_public_key_der(&der_bytes) + } else { + let der_bytes = <&[u8]>::deserialize(deserializer)?; + Self::from_public_key_der(der_bytes) + } + .map_err(D::Error::custom) } } From 479185e7dbdb030b2f3f6728351e2bcfbdca40e8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 18 Mar 2022 09:20:25 -0600 Subject: [PATCH 0760/1461] build(deps): bump zeroize from 1.5.3 to 1.5.4 (#968) Bumps [zeroize](https://github.com/RustCrypto/utils) from 1.5.3 to 1.5.4. - [Release notes](https://github.com/RustCrypto/utils/releases) - [Commits](https://github.com/RustCrypto/utils/compare/zeroize-v1.5.3...zeroize-v1.5.4) --- updated-dependencies: - dependency-name: zeroize dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5df396ef6..57ea1b717 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -966,6 +966,6 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.5.3" +version = "1.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50344758e2f40e3a1fcfc8f6f91aa57b5f8ebd8d27919fe6451f15aaaf9ee608" +checksum = "7eb5728b8afd3f280a869ce1d4c554ffaed35f45c231fc41bfbd0381bef50317" From 38ce12602c48684b9f993e53a3fed3145e70f0f9 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Fri, 25 Mar 2022 19:36:45 +0100 Subject: [PATCH 0761/1461] Fix compilation with `serde` without `pem` (#969) --- .github/workflows/elliptic-curve.yml | 1 + elliptic-curve/src/public_key.rs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index 2cf7a1d1b..8b6ff369e 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -50,6 +50,7 @@ jobs: - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features pkcs8 - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features sec1 - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features serde + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,serde - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features voprf - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features pkcs8,sec1 - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features pem,pkcs8,sec1 diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index b00bc2a26..4edc60568 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -31,7 +31,7 @@ use { #[cfg(any(feature = "jwk", feature = "pem"))] use alloc::string::{String, ToString}; -#[cfg(all(feature = "pem", feature = "serde"))] +#[cfg(all(feature = "alloc", feature = "serde"))] use serde::{de, ser, Deserialize, Serialize}; /// Elliptic curve public keys. From 65ddd0c0742b933e3175aeb698df73b29ea218d6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 30 Mar 2022 16:31:48 -0600 Subject: [PATCH 0762/1461] build(deps): bump base64ct from 1.4.1 to 1.5.0 (#972) Bumps [base64ct](https://github.com/RustCrypto/formats) from 1.4.1 to 1.5.0. - [Release notes](https://github.com/RustCrypto/formats/releases) - [Commits](https://github.com/RustCrypto/formats/compare/base64ct/v1.4.1...base64ct/v1.5.0) --- updated-dependencies: - dependency-name: base64ct dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 57ea1b717..34dc15179 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -40,9 +40,9 @@ checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" [[package]] name = "base64ct" -version = "1.4.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71acf5509fc522cce1b100ac0121c635129bfd4d91cdf036bcc9b9935f97ccf5" +checksum = "dea908e7347a8c64e378c17e30ef880ad73e3b4498346b055c2c00ea342f3179" [[package]] name = "bincode" From bf02fb043bd9b98d418003c618b1efe0711685a9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Apr 2022 10:22:25 -0600 Subject: [PATCH 0763/1461] build(deps): bump pem-rfc7468 from 0.3.1 to 0.5.1 (#973) Bumps [pem-rfc7468](https://github.com/RustCrypto/formats) from 0.3.1 to 0.5.1. - [Release notes](https://github.com/RustCrypto/formats/releases) - [Commits](https://github.com/RustCrypto/formats/compare/pem-rfc7468/v0.3.1...pem-rfc7468/v0.5.1) --- updated-dependencies: - dependency-name: pem-rfc7468 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 11 ++++++++++- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 34dc15179..02a6ce7f9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -322,7 +322,7 @@ dependencies = [ "generic-array", "group 0.11.0", "hex-literal 0.3.4", - "pem-rfc7468 0.3.1", + "pem-rfc7468 0.5.1", "rand_core", "sec1", "serde", @@ -577,6 +577,15 @@ dependencies = [ "base64ct", ] +[[package]] +name = "pem-rfc7468" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "973e070439aaacda48e5effad187f36d670b7635f7dcb75fa3c6f482d1b5b932" +dependencies = [ + "base64ct", +] + [[package]] name = "pkcs8" version = "0.7.6" diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 684a258f9..8b4af70d2 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -30,7 +30,7 @@ digest = { version = "0.10", optional = true } ff = { version = "0.11", optional = true, default-features = false } group = { version = "0.11", optional = true, default-features = false } hex-literal = { version = "0.3", optional = true } -pem-rfc7468 = { version = "0.3", optional = true } +pem-rfc7468 = { version = "0.5", optional = true } sec1 = { version = "0.2", optional = true, features = ["subtle", "zeroize"] } serde = { version = "1", optional = true, default-features = false } serde_json = { version = "1", optional = true, default-features = false, features = ["alloc"] } From e9e0f1cb32bdc52a5666c4ecd1219d37d29b1402 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 6 Apr 2022 10:36:48 -0600 Subject: [PATCH 0764/1461] password-hash: add `authentication` category to Cargo.toml (#976) --- password-hash/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index 3ea1275d4..37e1a131e 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -11,7 +11,7 @@ license = "MIT OR Apache-2.0" readme = "README.md" documentation = "https://docs.rs/password-hash" repository = "https://github.com/RustCrypto/traits/tree/master/password-hash" -categories = ["cryptography", "no-std"] +categories = ["authentication", "cryptography", "no-std"] keywords = ["crypt", "mcf", "password", "pbkdf", "phc"] edition = "2021" rust-version = "1.57" From c5ab0d6233a690fb34cc4a95c4bc828ec31a83f2 Mon Sep 17 00:00:00 2001 From: Agost Biro <5764438+agostbiro@users.noreply.github.com> Date: Wed, 6 Apr 2022 18:42:07 +0200 Subject: [PATCH 0765/1461] Fix typo in comment (#977) --- cipher/src/stream.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cipher/src/stream.rs b/cipher/src/stream.rs index 6f0fa67ee..735f2c867 100644 --- a/cipher/src/stream.rs +++ b/cipher/src/stream.rs @@ -168,7 +168,7 @@ pub trait StreamCipherSeek { /// Seek to the given position /// /// # Panics - /// If provided position value is bigger than keystream leangth + /// If provided position value is bigger than keystream length fn seek(&mut self, pos: T) { self.try_seek(pos).unwrap() } From 34540dcd05e3f7337a9cf322999520f5aea6f759 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 8 Apr 2022 09:28:15 -0600 Subject: [PATCH 0766/1461] elliptic-curve: remove `Zeroize` impl from `ecdh::SharedSecret` (#978) The purpose of zeroization is to clear the bytes of the shared secret on drop. However, before this commit `SharedSecret` also had a `Zeroize` impl which could be called before `Drop`. Used incorrectly, this could potentially erase the shared secret data, which could potentially lead to bugs where that data is used to derive e.g. encryption keys after being zeroed. This commit removes the `Zeroize` impl to prevent this. Data is still zeroed on drop and it still impls the `ZeroizeOnDrop` trait. --- elliptic-curve/src/ecdh.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/elliptic-curve/src/ecdh.rs b/elliptic-curve/src/ecdh.rs index 40307ea44..7b6540d0e 100644 --- a/elliptic-curve/src/ecdh.rs +++ b/elliptic-curve/src/ecdh.rs @@ -204,16 +204,10 @@ impl From> for SharedSecret { } } -impl Zeroize for SharedSecret { - fn zeroize(&mut self) { - self.secret_bytes.zeroize() - } -} - impl ZeroizeOnDrop for SharedSecret {} impl Drop for SharedSecret { fn drop(&mut self) { - self.zeroize(); + self.secret_bytes.zeroize() } } From 2365eeb53d6d9bf7ed5253784fea9fb6fe7820ec Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 22 Apr 2022 12:00:37 -0600 Subject: [PATCH 0767/1461] password-hash v0.4.1 (#985) --- Cargo.lock | 2 +- password-hash/CHANGELOG.md | 6 ++++++ password-hash/Cargo.toml | 2 +- password-hash/README.md | 8 ++++---- password-hash/src/lib.rs | 3 +-- 5 files changed, 13 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 02a6ce7f9..758791753 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -552,7 +552,7 @@ dependencies = [ [[package]] name = "password-hash" -version = "0.4.0" +version = "0.4.1" dependencies = [ "base64ct", "rand_core", diff --git a/password-hash/CHANGELOG.md b/password-hash/CHANGELOG.md index e0bbbf1d1..449c653b8 100644 --- a/password-hash/CHANGELOG.md +++ b/password-hash/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.4.1 (2022-04-22) +### Added +- `authentication` category to Cargo.toml ([#976]) + +[#976]: https://github.com/RustCrypto/traits/pull/976 + ## 0.4.0 (2022-03-09) ### Changed - Leverage `const_panic`; MSRV 1.57 ([#896]) diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index 37e1a131e..2a1277f3d 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -5,7 +5,7 @@ Traits which describe the functionality of password hashing algorithms, as well as a `no_std`-friendly implementation of the PHC string format (a well-defined subset of the Modular Crypt Format a.k.a. MCF) """ -version = "0.4.0" # Also update html_root_url in lib.rs when bumping this +version = "0.4.1" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/password-hash/README.md b/password-hash/README.md index 05ba77239..adde996aa 100644 --- a/password-hash/README.md +++ b/password-hash/README.md @@ -2,10 +2,10 @@ [![crate][crate-image]][crate-link] [![Docs][docs-image]][docs-link] +[![Build Status][build-image]][build-link] ![Apache2/MIT licensed][license-image] ![Rust Version][rustc-image] [![Project Chat][chat-image]][chat-link] -[![Build Status][build-image]][build-link] Traits which describe the functionality of [password hashing algorithms]. @@ -56,16 +56,16 @@ dual licensed as above, without any additional terms or conditions. [//]: # (badges) -[crate-image]: https://img.shields.io/crates/v/password-hash.svg +[crate-image]: https://img.shields.io/crates/v/password-hash.svg?logo=rust [crate-link]: https://crates.io/crates/password-hash [docs-image]: https://docs.rs/password-hash/badge.svg [docs-link]: https://docs.rs/password-hash/ +[build-image]: https://github.com/RustCrypto/traits/workflows/password-hash/badge.svg?branch=master&event=push +[build-link]: https://github.com/RustCrypto/traits/actions?query=workflow:password-hash [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg [rustc-image]: https://img.shields.io/badge/rustc-1.57+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260046-password-hashes -[build-image]: https://github.com/RustCrypto/traits/workflows/password-hash/badge.svg?branch=master&event=push -[build-link]: https://github.com/RustCrypto/traits/actions?query=workflow:password-hash [//]: # (general links) diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index 7048e6927..f451fb0a8 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -3,8 +3,7 @@ #![doc = include_str!("../README.md")] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/password-hash/0.4.0" + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg" )] #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms, unused_lifetimes)] From 7d822df905300ed0f051753a70a506ac26c25aaf Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 22 Apr 2022 12:21:01 -0600 Subject: [PATCH 0768/1461] password-hash: add downloads badge to README.md --- password-hash/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/password-hash/README.md b/password-hash/README.md index adde996aa..1367aed95 100644 --- a/password-hash/README.md +++ b/password-hash/README.md @@ -2,6 +2,7 @@ [![crate][crate-image]][crate-link] [![Docs][docs-image]][docs-link] +[![Downloads][downloads-image]][crate-link] [![Build Status][build-image]][build-link] ![Apache2/MIT licensed][license-image] ![Rust Version][rustc-image] @@ -60,6 +61,7 @@ dual licensed as above, without any additional terms or conditions. [crate-link]: https://crates.io/crates/password-hash [docs-image]: https://docs.rs/password-hash/badge.svg [docs-link]: https://docs.rs/password-hash/ +[downloads-image]: https://img.shields.io/crates/d/password-hash.svg [build-image]: https://github.com/RustCrypto/traits/workflows/password-hash/badge.svg?branch=master&event=push [build-link]: https://github.com/RustCrypto/traits/actions?query=workflow:password-hash [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg From f7b487e4f161951103793c4e3875cda85704a1cc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 May 2022 21:04:01 -0600 Subject: [PATCH 0769/1461] build(deps): bump zeroize from 1.5.4 to 1.5.5 (#989) Bumps [zeroize](https://github.com/RustCrypto/utils) from 1.5.4 to 1.5.5. - [Release notes](https://github.com/RustCrypto/utils/releases) - [Commits](https://github.com/RustCrypto/utils/compare/zeroize-v1.5.4...zeroize-v1.5.5) --- updated-dependencies: - dependency-name: zeroize dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 758791753..c0c70f092 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -975,6 +975,6 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.5.4" +version = "1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb5728b8afd3f280a869ce1d4c554ffaed35f45c231fc41bfbd0381bef50317" +checksum = "94693807d016b2f2d2e14420eb3bfcca689311ff775dcf113d74ea624b7cdf07" From 8f61b3ab696e699f2eda8fbd0781ff89e7208684 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 4 May 2022 21:55:49 -0600 Subject: [PATCH 0770/1461] elliptic-curve: bump `ff` + `group` to v0.12 (#994) Release notes: - `ff` v0.12: https://github.com/zkcrypto/ff/blob/main/CHANGELOG.md#0120---2022-05-04 - `group` v0.12: https://github.com/zkcrypto/group/blob/main/CHANGELOG.md#0120---2022-05-04 --- Cargo.lock | 30 +++++++++++++++--------------- elliptic-curve/Cargo.toml | 4 ++-- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c0c70f092..ccafb4e9f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -55,9 +55,9 @@ dependencies = [ [[package]] name = "bitvec" -version = "0.22.3" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5237f00a8c86130a0cc317830e558b966dd7850d48a953d998c813f01a41b527" +checksum = "1489fcb93a5bb47da0462ca93ad252ad6af2145cce58d10d46a83931ba9f016b" dependencies = [ "funty", "radium", @@ -318,9 +318,9 @@ dependencies = [ "crypto-bigint 0.4.0-pre.0", "der 0.5.1", "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", - "ff 0.11.0", + "ff 0.12.0", "generic-array", - "group 0.11.0", + "group 0.12.0", "hex-literal 0.3.4", "pem-rfc7468 0.5.1", "rand_core", @@ -345,9 +345,9 @@ dependencies = [ [[package]] name = "ff" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2958d04124b9f27f175eaeb9a9f383d026098aa837eadd8ba22c11f13a05b9e" +checksum = "df689201f395c6b90dfe87127685f8dbfc083a5e779e613575d8bd7314300c3e" dependencies = [ "bitvec", "rand_core", @@ -356,9 +356,9 @@ dependencies = [ [[package]] name = "funty" -version = "1.2.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1847abb9cb65d566acd5942e94aea9c8f547ad02c98e1649326fc0e8910b8b1e" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "generic-array" @@ -400,11 +400,11 @@ dependencies = [ [[package]] name = "group" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5ac374b108929de78460075f3dc439fa66df9d8fc77e8f12caa5165fcf0c89" +checksum = "7391856def869c1c81063a03457c676fbcd419709c3dfb33d8d319de484b154d" dependencies = [ - "ff 0.11.0", + "ff 0.12.0", "rand_core", "subtle", ] @@ -681,9 +681,9 @@ dependencies = [ [[package]] name = "radium" -version = "0.6.2" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "643f8f41a8ebc4c5dc4515c82bb8abd397b527fc20fd681b7c011c2aee5d44fb" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" [[package]] name = "rand" @@ -948,9 +948,9 @@ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] name = "wyz" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "129e027ad65ce1453680623c3fb5163cbf7107bfe1aa32257e7d0e63f9ced188" +checksum = "30b31594f29d27036c383b53b59ed3476874d518f0efb151b27a4c275141390e" dependencies = [ "tap", ] diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 8b4af70d2..3bf8bb0d8 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -27,8 +27,8 @@ zeroize = { version = "1.5", default-features = false } # optional dependencies base64ct = { version = "1", optional = true, default-features = false } digest = { version = "0.10", optional = true } -ff = { version = "0.11", optional = true, default-features = false } -group = { version = "0.11", optional = true, default-features = false } +ff = { version = "0.12", optional = true, default-features = false } +group = { version = "0.12", optional = true, default-features = false } hex-literal = { version = "0.3", optional = true } pem-rfc7468 = { version = "0.5", optional = true } sec1 = { version = "0.2", optional = true, features = ["subtle", "zeroize"] } From 86c4dd72ca701056823687adb3823245306137ca Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 6 May 2022 07:14:08 -0600 Subject: [PATCH 0771/1461] elliptic-curve: bump `der` to v0.6.0-pre.4 (#995) Also bumps `pkcs8` to v0.9.0-pre.2. This should hopefully be the last prerelease before a final release. --- Cargo.lock | 46 +++++++++++++------------- elliptic-curve/Cargo.toml | 4 +-- elliptic-curve/src/dev.rs | 2 +- elliptic-curve/src/lib.rs | 2 +- elliptic-curve/src/public_key.rs | 2 +- elliptic-curve/src/secret_key.rs | 2 +- elliptic-curve/src/secret_key/pkcs8.rs | 7 ++-- elliptic-curve/tests/pkcs8.rs | 6 ++-- 8 files changed, 36 insertions(+), 35 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ccafb4e9f..16e5bd574 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -153,9 +153,9 @@ checksum = "9d6f2aa4d0537bcc1c74df8755072bd31c1ef1a3a1b85a68e8404a8c353b7b8b" [[package]] name = "const-oid" -version = "0.7.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" +checksum = "722e23542a15cea1f65d4a1419c4cfd7a26706c70871a13a04238ca3f40f1661" [[package]] name = "cpufeatures" @@ -244,12 +244,13 @@ dependencies = [ [[package]] name = "der" -version = "0.5.1" +version = "0.6.0-pre.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" +checksum = "0daf09ee3ea2f7e4f5761deb921bd4c4e46861ee4b218349a40eccfa9d7fa6a5" dependencies = [ - "const-oid 0.7.1", - "pem-rfc7468 0.3.1", + "const-oid 0.9.0", + "pem-rfc7468 0.6.0", + "zeroize", ] [[package]] @@ -316,7 +317,7 @@ dependencies = [ "base16ct", "base64ct", "crypto-bigint 0.4.0-pre.0", - "der 0.5.1", + "der 0.6.0-pre.4", "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "ff 0.12.0", "generic-array", @@ -570,18 +571,18 @@ dependencies = [ [[package]] name = "pem-rfc7468" -version = "0.3.1" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01de5d978f34aa4b2296576379fcc416034702fd94117c56ffd8a1a767cefb30" +checksum = "973e070439aaacda48e5effad187f36d670b7635f7dcb75fa3c6f482d1b5b932" dependencies = [ "base64ct", ] [[package]] name = "pem-rfc7468" -version = "0.5.1" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "973e070439aaacda48e5effad187f36d670b7635f7dcb75fa3c6f482d1b5b932" +checksum = "24d159833a9105500e0398934e205e0773f0b27529557134ecfc51c27646adac" dependencies = [ "base64ct", ] @@ -600,13 +601,12 @@ dependencies = [ [[package]] name = "pkcs8" -version = "0.8.0" +version = "0.9.0-pre.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" +checksum = "648850a9b1320771c90c141a7497552f887081f4d63117c038621222eceb511b" dependencies = [ - "der 0.5.1", - "spki 0.5.4", - "zeroize", + "der 0.6.0-pre.4", + "spki 0.6.0-pre.3", ] [[package]] @@ -729,13 +729,13 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "sec1" -version = "0.2.1" +version = "0.3.0-pre.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08da66b8b0965a5555b6bd6639e68ccba85e1e2506f5fbb089e93f8a04e1a2d1" +checksum = "a064c53858053f909bdc5a83b6a471df77114d97a6c17c48b091905cdbf1f913" dependencies = [ - "der 0.5.1", + "der 0.6.0-pre.4", "generic-array", - "pkcs8 0.8.0", + "pkcs8 0.9.0-pre.2", "subtle", "zeroize", ] @@ -865,12 +865,12 @@ dependencies = [ [[package]] name = "spki" -version = "0.5.4" +version = "0.6.0-pre.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" +checksum = "dc54500466d9dad8716bc2b0bbb8e72cf2559759efa6c535fb40dcdf249716b3" dependencies = [ "base64ct", - "der 0.5.1", + "der 0.6.0-pre.4", ] [[package]] diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 3bf8bb0d8..a13351303 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -18,7 +18,7 @@ rust-version = "1.57" [dependencies] base16ct = "0.1.1" crypto-bigint = { version = "=0.4.0-pre.0", default-features = false, features = ["rand_core", "generic-array", "zeroize"] } -der = { version = "0.5", default-features = false, features = ["oid"] } +der = { version = "=0.6.0-pre.4", default-features = false, features = ["oid"] } generic-array = { version = "0.14", default-features = false } rand_core = { version = "0.6", default-features = false } subtle = { version = "2", default-features = false } @@ -31,7 +31,7 @@ ff = { version = "0.12", optional = true, default-features = false } group = { version = "0.12", optional = true, default-features = false } hex-literal = { version = "0.3", optional = true } pem-rfc7468 = { version = "0.5", optional = true } -sec1 = { version = "0.2", optional = true, features = ["subtle", "zeroize"] } +sec1 = { version = "=0.3.0-pre.2", optional = true, features = ["subtle", "zeroize"] } serde = { version = "1", optional = true, default-features = false } serde_json = { version = "1", optional = true, default-features = false, features = ["alloc"] } diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 5b9ca3781..3d4884471 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -87,7 +87,7 @@ impl ScalarArithmetic for MockCurve { impl AlgorithmParameters for MockCurve { /// OID for NIST P-256 - const OID: pkcs8::ObjectIdentifier = pkcs8::ObjectIdentifier::new("1.2.840.10045.3.1.7"); + const OID: pkcs8::ObjectIdentifier = pkcs8::ObjectIdentifier::new_unwrap("1.2.840.10045.3.1.7"); } #[cfg(feature = "jwk")] diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 63b99c5ef..1723771f8 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -146,7 +146,7 @@ use generic_array::GenericArray; #[cfg(feature = "pkcs8")] #[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))] pub const ALGORITHM_OID: pkcs8::ObjectIdentifier = - pkcs8::ObjectIdentifier::new("1.2.840.10045.2.1"); + pkcs8::ObjectIdentifier::new_unwrap("1.2.840.10045.2.1"); /// Elliptic curve. /// diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index 4edc60568..6225c21db 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -312,7 +312,7 @@ where AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { - fn to_public_key_der(&self) -> pkcs8::spki::Result { + fn to_public_key_der(&self) -> pkcs8::spki::Result { let public_key_bytes = self.to_encoded_point(false); pkcs8::SubjectPublicKeyInfo { diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 1f90ea1c7..15e3d8e58 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -24,7 +24,7 @@ use { AffinePoint, }, alloc::vec::Vec, - der::Encodable, + der::Encode, zeroize::Zeroizing, }; diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs index 2786b61bd..9bec94827 100644 --- a/elliptic-curve/src/secret_key/pkcs8.rs +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -6,7 +6,7 @@ use crate::{ sec1::{ModulusSize, ValidatePublicKey}, AlgorithmParameters, Curve, FieldSize, ALGORITHM_OID, }; -use der::Decodable; +use der::Decode; use sec1::EcPrivateKey; // Imports for the `EncodePrivateKey` impl @@ -65,9 +65,10 @@ where AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { - fn to_pkcs8_der(&self) -> pkcs8::Result { + fn to_pkcs8_der(&self) -> pkcs8::Result { let ec_private_key = self.to_sec1_der()?; - pkcs8::PrivateKeyInfo::new(C::algorithm_identifier(), &ec_private_key).to_der() + let pkcs8_key = pkcs8::PrivateKeyInfo::new(C::algorithm_identifier(), &ec_private_key); + Ok(der::SecretDocument::encode_msg(&pkcs8_key)?) } } diff --git a/elliptic-curve/tests/pkcs8.rs b/elliptic-curve/tests/pkcs8.rs index c88b416a9..cffb06802 100644 --- a/elliptic-curve/tests/pkcs8.rs +++ b/elliptic-curve/tests/pkcs8.rs @@ -4,7 +4,7 @@ use elliptic_curve::{ dev::{PublicKey, SecretKey}, - pkcs8::{DecodePrivateKey, DecodePublicKey, EncodePrivateKey, PrivateKeyDocument}, + pkcs8::{DecodePrivateKey, DecodePublicKey, EncodePrivateKey}, sec1::ToEncodedPoint, }; use hex_literal::hex; @@ -21,7 +21,7 @@ const EXAMPLE_SCALAR: [u8; 32] = hex!("AABBCCDDEEFF0000000000000000000000000000000000000000000000000001"); /// Example PKCS#8 private key -fn example_private_key() -> PrivateKeyDocument { +fn example_private_key() -> der::SecretDocument { SecretKey::from_be_bytes(&EXAMPLE_SCALAR) .unwrap() .to_pkcs8_der() @@ -30,7 +30,7 @@ fn example_private_key() -> PrivateKeyDocument { #[test] fn decode_pkcs8_private_key_from_der() { - let secret_key = SecretKey::from_pkcs8_der(example_private_key().as_ref()).unwrap(); + let secret_key = SecretKey::from_pkcs8_der(example_private_key().as_bytes()).unwrap(); assert_eq!(secret_key.to_be_bytes().as_slice(), &EXAMPLE_SCALAR); } From a874af7f57a0ae57f3b1df554048e3c37b35a118 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 6 May 2022 08:16:21 -0600 Subject: [PATCH 0772/1461] elliptic-curve: use `serdect` crate (#996) Uses the `serdect` crate, which provides constant time-ish serde serializers/deserializers, for impl'ing the `serde::{Deserialize, Serialize}` traits. --- Cargo.lock | 12 ++++++++- elliptic-curve/Cargo.toml | 3 ++- elliptic-curve/src/jwk.rs | 2 +- elliptic-curve/src/lib.rs | 3 --- elliptic-curve/src/public_key.rs | 32 +++++++---------------- elliptic-curve/src/scalar/core.rs | 42 +++++-------------------------- 6 files changed, 29 insertions(+), 65 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 16e5bd574..df2f045ad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -326,8 +326,8 @@ dependencies = [ "pem-rfc7468 0.5.1", "rand_core", "sec1", - "serde", "serde_json", + "serdect", "sha2 0.10.2", "sha3", "subtle", @@ -780,6 +780,16 @@ dependencies = [ "serde", ] +[[package]] +name = "serdect" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "038fce1bf4d74b9b30ea7dcd59df75ba8ec669a5dcb3cc64fbfcef7334ced32c" +dependencies = [ + "base16ct", + "serde", +] + [[package]] name = "sha2" version = "0.9.9" diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index a13351303..73fda2107 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -32,7 +32,7 @@ group = { version = "0.12", optional = true, default-features = false } hex-literal = { version = "0.3", optional = true } pem-rfc7468 = { version = "0.5", optional = true } sec1 = { version = "=0.3.0-pre.2", optional = true, features = ["subtle", "zeroize"] } -serde = { version = "1", optional = true, default-features = false } +serdect = { version = "0.1", optional = true, default-features = false, features = ["alloc"] } serde_json = { version = "1", optional = true, default-features = false, features = ["alloc"] } [dev-dependencies] @@ -52,6 +52,7 @@ hazmat = [] jwk = ["alloc", "base64ct/alloc", "serde", "serde_json", "zeroize/alloc"] pem = ["alloc", "arithmetic", "pem-rfc7468/alloc", "pkcs8", "sec1/pem"] pkcs8 = ["sec1/pkcs8"] +serde = ["alloc", "serdect"] std = ["alloc", "rand_core/std"] voprf = ["digest"] diff --git a/elliptic-curve/src/jwk.rs b/elliptic-curve/src/jwk.rs index 85dbfe2cd..ff5e6e638 100644 --- a/elliptic-curve/src/jwk.rs +++ b/elliptic-curve/src/jwk.rs @@ -19,7 +19,7 @@ use core::{ marker::PhantomData, str::{self, FromStr}, }; -use serde::{de, ser, Deserialize, Serialize}; +use serdect::serde::{de, ser, Deserialize, Serialize}; use zeroize::{Zeroize, ZeroizeOnDrop}; #[cfg(feature = "arithmetic")] diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 1723771f8..edcfe2a00 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -133,9 +133,6 @@ pub use crate::jwk::{JwkEcKey, JwkParameters}; #[cfg(feature = "pkcs8")] pub use ::sec1::pkcs8; -#[cfg(feature = "serde")] -pub use serde; - use core::fmt::Debug; use generic_array::GenericArray; diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index 6225c21db..d0388c659 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -31,8 +31,8 @@ use { #[cfg(any(feature = "jwk", feature = "pem"))] use alloc::string::{String, ToString}; -#[cfg(all(feature = "alloc", feature = "serde"))] -use serde::{de, ser, Deserialize, Serialize}; +#[cfg(feature = "serde")] +use serdect::serde::{de, ser, Deserialize, Serialize}; /// Elliptic curve public keys. /// @@ -352,8 +352,8 @@ where } } -#[cfg(all(feature = "alloc", feature = "serde"))] -#[cfg_attr(docsrs, doc(cfg(all(feature = "alloc", feature = "serde"))))] +#[cfg(feature = "serde")] +#[cfg_attr(docsrs, doc(cfg(feature = "serde")))] impl Serialize for PublicKey where C: Curve + AlgorithmParameters + ProjectiveArithmetic, @@ -365,17 +365,12 @@ where S: ser::Serializer, { let der = self.to_public_key_der().map_err(ser::Error::custom)?; - - if serializer.is_human_readable() { - base16ct::upper::encode_string(der.as_ref()).serialize(serializer) - } else { - der.as_ref().serialize(serializer) - } + serdect::slice::serialize_hex_upper_or_bin(&der, serializer) } } -#[cfg(all(feature = "alloc", feature = "serde"))] -#[cfg_attr(docsrs, doc(cfg(all(feature = "alloc", feature = "serde"))))] +#[cfg(feature = "serde")] +#[cfg_attr(docsrs, doc(cfg(feature = "serde")))] impl<'de, C> Deserialize<'de> for PublicKey where C: Curve + AlgorithmParameters + ProjectiveArithmetic, @@ -386,17 +381,8 @@ where where D: de::Deserializer<'de>, { - use de::Error; - - if deserializer.is_human_readable() { - let der_bytes = base16ct::mixed::decode_vec(<&str>::deserialize(deserializer)?) - .map_err(D::Error::custom)?; - Self::from_public_key_der(&der_bytes) - } else { - let der_bytes = <&[u8]>::deserialize(deserializer)?; - Self::from_public_key_der(der_bytes) - } - .map_err(D::Error::custom) + let der_bytes = serdect::slice::deserialize_hex_or_bin_vec(deserializer)?; + Self::from_public_key_der(&der_bytes).map_err(de::Error::custom) } } diff --git a/elliptic-curve/src/scalar/core.rs b/elliptic-curve/src/scalar/core.rs index ff806f0aa..6a088ca55 100644 --- a/elliptic-curve/src/scalar/core.rs +++ b/elliptic-curve/src/scalar/core.rs @@ -26,7 +26,7 @@ use { }; #[cfg(feature = "serde")] -use serde::{de, ser, Deserialize, Serialize}; +use serdect::serde::{de, ser, Deserialize, Serialize}; /// Generic scalar type with core functionality. /// @@ -408,25 +408,11 @@ impl Serialize for ScalarCore where C: Curve, { - #[cfg(not(feature = "alloc"))] fn serialize(&self, serializer: S) -> core::result::Result where S: ser::Serializer, { - self.to_be_bytes().as_slice().serialize(serializer) - } - - #[cfg(feature = "alloc")] - fn serialize(&self, serializer: S) -> core::result::Result - where - S: ser::Serializer, - { - use alloc::string::ToString; - if serializer.is_human_readable() { - self.to_string().serialize(serializer) - } else { - self.to_be_bytes().as_slice().serialize(serializer) - } + serdect::array::serialize_hex_upper_or_bin(&self.to_be_bytes(), serializer) } } @@ -436,29 +422,13 @@ impl<'de, C> Deserialize<'de> for ScalarCore where C: Curve, { - #[cfg(not(feature = "alloc"))] fn deserialize(deserializer: D) -> core::result::Result where D: de::Deserializer<'de>, { - use de::Error; - <&[u8]>::deserialize(deserializer) - .and_then(|slice| Self::from_be_slice(slice).map_err(D::Error::custom)) - } - - #[cfg(feature = "alloc")] - fn deserialize(deserializer: D) -> core::result::Result - where - D: de::Deserializer<'de>, - { - use de::Error; - if deserializer.is_human_readable() { - <&str>::deserialize(deserializer)? - .parse() - .map_err(D::Error::custom) - } else { - <&[u8]>::deserialize(deserializer) - .and_then(|slice| Self::from_be_slice(slice).map_err(D::Error::custom)) - } + let mut bytes = FieldBytes::::default(); + serdect::array::deserialize_hex_or_bin(&mut bytes, deserializer)?; + Option::from(Self::from_be_bytes(bytes)) + .ok_or_else(|| de::Error::custom("scalar out of range")) } } From 4880e230fa8b0aaed2f1b9469b06458ed8499056 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 6 May 2022 09:35:03 -0600 Subject: [PATCH 0773/1461] elliptic-curve v0.12.0-pre.2 (#997) --- Cargo.lock | 4 ++-- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index df2f045ad..bb3719ed9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -174,7 +174,7 @@ dependencies = [ "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "crypto-mac", "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", - "elliptic-curve 0.12.0-pre.1", + "elliptic-curve 0.12.0-pre.2", "password-hash", "signature 1.5.0", "universal-hash", @@ -312,7 +312,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.12.0-pre.1" +version = "0.12.0-pre.2" dependencies = [ "base16ct", "base64ct", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 73fda2107..270f3b1ed 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.12.0-pre.1" # Also update html_root_url in lib.rs when bumping this +version = "0.12.0-pre.2" # Also update html_root_url in lib.rs when bumping this description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, From 24d84b137a43d6205ade0fef1c2f765bd030bff8 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 6 May 2022 17:24:58 -0600 Subject: [PATCH 0774/1461] elliptic-curve: fix broken rustdoc links (#998) --- elliptic-curve/src/hash2curve/group_digest.rs | 12 ++++++------ elliptic-curve/src/secret_key.rs | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/elliptic-curve/src/hash2curve/group_digest.rs b/elliptic-curve/src/hash2curve/group_digest.rs index a7330058b..dbcb1512b 100644 --- a/elliptic-curve/src/hash2curve/group_digest.rs +++ b/elliptic-curve/src/hash2curve/group_digest.rs @@ -44,8 +44,8 @@ where /// /// `len_in_bytes = ::Length * 2` /// - /// [`ExpandMsgXmd`]: crate::hash2field::ExpandMsgXmd - /// [`ExpandMsgXof`]: crate::hash2field::ExpandMsgXof + /// [`ExpandMsgXmd`]: crate::hash2curve::ExpandMsgXmd + /// [`ExpandMsgXof`]: crate::hash2curve::ExpandMsgXof fn hash_from_bytes<'a, X: ExpandMsg<'a>>( msgs: &[&[u8]], dst: &'a [u8], @@ -84,8 +84,8 @@ where /// /// `len_in_bytes = ::Length` /// - /// [`ExpandMsgXmd`]: crate::hash2field::ExpandMsgXmd - /// [`ExpandMsgXof`]: crate::hash2field::ExpandMsgXof + /// [`ExpandMsgXmd`]: crate::hash2curve::ExpandMsgXmd + /// [`ExpandMsgXof`]: crate::hash2curve::ExpandMsgXof fn encode_from_bytes<'a, X: ExpandMsg<'a>>( msgs: &[&[u8]], dst: &'a [u8], @@ -107,8 +107,8 @@ where /// /// `len_in_bytes = ::Length` /// - /// [`ExpandMsgXmd`]: crate::hash2field::ExpandMsgXmd - /// [`ExpandMsgXof`]: crate::hash2field::ExpandMsgXof + /// [`ExpandMsgXmd`]: crate::hash2curve::ExpandMsgXmd + /// [`ExpandMsgXof`]: crate::hash2curve::ExpandMsgXof fn hash_to_scalar<'a, X: ExpandMsg<'a>>(msgs: &[&[u8]], dst: &'a [u8]) -> Result where Self::Scalar: FromOkm, diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 15e3d8e58..531719783 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -79,7 +79,7 @@ pub(crate) const SEC1_PEM_TYPE_LABEL: &str = "EC PRIVATE KEY"; /// To decode an elliptic curve private key from PKCS#8, enable the `pkcs8` /// feature of this crate (or the `pkcs8` feature of a specific RustCrypto /// elliptic curve crate) and use the -/// [`elliptic_curve::pkcs8::DecodePrivateKey`][`DecodePrivateKey`] +/// [`DecodePrivateKey`][`elliptic_curve::pkcs8::DecodePrivateKey`] /// trait to parse it. /// /// When the `pem` feature of this crate (or a specific RustCrypto elliptic From a394ad8a2f5ef375150df1b419115660e1076d52 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 6 May 2022 18:02:40 -0600 Subject: [PATCH 0775/1461] CI: re-unify workspace jobs (#999) Now that #958 has recombined all of the crates into a single workspace, these jobs can be recombined too. --- .github/workflows/workspace.yml | 89 +++------------------------------ Cargo.lock | 1 + 2 files changed, 7 insertions(+), 83 deletions(-) diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index 6b013b0ae..ba8f5b0ca 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -13,6 +13,11 @@ on: - '**/CHANGELOG.md' - .github/** +env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" + RUSTDOCFLAGS: "-Dwarnings" + jobs: clippy: runs-on: ubuntu-latest @@ -26,99 +31,17 @@ jobs: override: true profile: minimal - run: cargo clippy --all --all-features -- -D warnings - - run: cargo clippy --all --all-features -- -D warnings - working-directory: cipher - - run: cargo clippy --all --all-features -- -D warnings - working-directory: crypto - - run: cargo clippy --all --all-features -- -D warnings - working-directory: elliptic-curve - - run: cargo clippy --all --all-features -- -D warnings - working-directory: kem - - run: cargo clippy --all --all-features -- -D warnings - working-directory: password-hash - - rustfmt_workspace: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - components: rustfmt - override: true - profile: minimal - - uses: actions-rs/cargo@v1 - with: - command: fmt - args: --all -- --check - - rustfmt_crypto: - runs-on: ubuntu-latest - defaults: - run: - working-directory: crypto - steps: - - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - components: rustfmt - override: true - profile: minimal - - uses: actions-rs/cargo@v1 - with: - command: fmt - args: --all -- --check - rustfmt_elliptic-curve: + rustfmt: runs-on: ubuntu-latest - defaults: - run: - working-directory: elliptic-curve steps: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: toolchain: stable components: rustfmt - override: true profile: minimal - - uses: actions-rs/cargo@v1 - with: - command: fmt - args: --all -- --check - - rustfmt_kem: - runs-on: ubuntu-latest - defaults: - run: - working-directory: kem - steps: - - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - components: rustfmt override: true - profile: minimal - - uses: actions-rs/cargo@v1 - with: - command: fmt - args: --all -- --check - - rustfmt_password-hash: - runs-on: ubuntu-latest - defaults: - run: - working-directory: password-hash - steps: - - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - components: rustfmt - override: true - profile: minimal - uses: actions-rs/cargo@v1 with: command: fmt diff --git a/Cargo.lock b/Cargo.lock index bb3719ed9..34dbbf728 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +# version = 3 [[package]] From 63ced8d97188fd1ec468f9e253fcb6744c3af300 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 7 May 2022 08:26:25 -0600 Subject: [PATCH 0776/1461] elliptic-curve: replace `AlgorithmParamters` with `AssociatedOid` (#1001) Uses the `AssociatedOid` trait from `const-oid` to replace the similarly shaped `AlgorithmParameters` trait. --- Cargo.lock | 12 ++++++------ elliptic-curve/Cargo.toml | 4 ++-- elliptic-curve/src/dev.rs | 7 ++++--- elliptic-curve/src/lib.rs | 23 +---------------------- elliptic-curve/src/public_key.rs | 25 +++++++++++++++---------- elliptic-curve/src/secret_key/pkcs8.rs | 19 ++++++++++++------- 6 files changed, 40 insertions(+), 50 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 34dbbf728..464c0b262 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,5 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -# version = 3 [[package]] @@ -325,6 +324,7 @@ dependencies = [ "group 0.12.0", "hex-literal 0.3.4", "pem-rfc7468 0.5.1", + "pkcs8 0.9.0-pre.3", "rand_core", "sec1", "serde_json", @@ -602,9 +602,9 @@ dependencies = [ [[package]] name = "pkcs8" -version = "0.9.0-pre.2" +version = "0.9.0-pre.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "648850a9b1320771c90c141a7497552f887081f4d63117c038621222eceb511b" +checksum = "c1799b3d2dcb77fb12fd3cada7897c333d3f62c6eec50af2461b3cd8081a2599" dependencies = [ "der 0.6.0-pre.4", "spki 0.6.0-pre.3", @@ -730,13 +730,13 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "sec1" -version = "0.3.0-pre.2" +version = "0.3.0-pre.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a064c53858053f909bdc5a83b6a471df77114d97a6c17c48b091905cdbf1f913" +checksum = "437ee1920f19c74e2b92630ba247f0716b52249464d97e76bf22ecb8ee75bbee" dependencies = [ "der 0.6.0-pre.4", "generic-array", - "pkcs8 0.9.0-pre.2", + "pkcs8 0.9.0-pre.3", "subtle", "zeroize", ] diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 270f3b1ed..e2ae167dc 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -31,7 +31,8 @@ ff = { version = "0.12", optional = true, default-features = false } group = { version = "0.12", optional = true, default-features = false } hex-literal = { version = "0.3", optional = true } pem-rfc7468 = { version = "0.5", optional = true } -sec1 = { version = "=0.3.0-pre.2", optional = true, features = ["subtle", "zeroize"] } +pkcs8 = { version = "=0.9.0-pre.3", optional = true, default-features = false } +sec1 = { version = "=0.3.0-pre.3", optional = true, features = ["subtle", "zeroize"] } serdect = { version = "0.1", optional = true, default-features = false, features = ["alloc"] } serde_json = { version = "1", optional = true, default-features = false, features = ["alloc"] } @@ -51,7 +52,6 @@ ecdh = ["arithmetic"] hazmat = [] jwk = ["alloc", "base64ct/alloc", "serde", "serde_json", "zeroize/alloc"] pem = ["alloc", "arithmetic", "pem-rfc7468/alloc", "pkcs8", "sec1/pem"] -pkcs8 = ["sec1/pkcs8"] serde = ["alloc", "serdect"] std = ["alloc", "rand_core/std"] voprf = ["digest"] diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 3d4884471..4e424716d 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -12,8 +12,8 @@ use crate::{ sec1::{FromEncodedPoint, ToEncodedPoint}, subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}, zeroize::DefaultIsZeroes, - AffineArithmetic, AffineXCoordinate, AlgorithmParameters, Curve, IsHigh, PrimeCurve, - ProjectiveArithmetic, ScalarArithmetic, + AffineArithmetic, AffineXCoordinate, Curve, IsHigh, PrimeCurve, ProjectiveArithmetic, + ScalarArithmetic, }; use core::{ iter::Sum, @@ -22,6 +22,7 @@ use core::{ use ff::{Field, PrimeField}; use generic_array::arr; use hex_literal::hex; +use pkcs8::AssociatedOid; #[cfg(feature = "bits")] use crate::group::ff::PrimeFieldBits; @@ -85,7 +86,7 @@ impl ScalarArithmetic for MockCurve { type Scalar = Scalar; } -impl AlgorithmParameters for MockCurve { +impl AssociatedOid for MockCurve { /// OID for NIST P-256 const OID: pkcs8::ObjectIdentifier = pkcs8::ObjectIdentifier::new_unwrap("1.2.840.10045.3.1.7"); } diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index edcfe2a00..65ac83561 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -131,7 +131,7 @@ pub use crate::scalar::ScalarBits; pub use crate::jwk::{JwkEcKey, JwkParameters}; #[cfg(feature = "pkcs8")] -pub use ::sec1::pkcs8; +pub use pkcs8; use core::fmt::Debug; use generic_array::GenericArray; @@ -195,27 +195,6 @@ pub type AffinePoint = ::AffinePoint; #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub type ProjectivePoint = ::ProjectivePoint; -/// Associate an [`ObjectIdentifier`][`pkcs8::ObjectIdentifier`] (OID) with an -/// elliptic curve algorithm implementation. -/// -/// This is used as as the `parameters` of an `AlgorithmIdentifier` as -/// described in RFC 5280 Section 4.1.1.2: -/// -#[cfg(feature = "pkcs8")] -#[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))] -pub trait AlgorithmParameters: Curve { - /// Object Identifier (OID) for this curve - const OID: pkcs8::ObjectIdentifier; - - /// Get the [`pkcs8::AlgorithmIdentifier`] for this curve - fn algorithm_identifier() -> pkcs8::AlgorithmIdentifier<'static> { - pkcs8::AlgorithmIdentifier { - oid: ALGORITHM_OID, - parameters: Some((&Self::OID).into()), - } - } -} - /// Elliptic curve parameters used by VOPRF. #[cfg(feature = "voprf")] #[cfg_attr(docsrs, doc(cfg(feature = "voprf")))] diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index d0388c659..8a3e4b00d 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -11,8 +11,8 @@ use crate::{JwkEcKey, JwkParameters}; #[cfg(all(feature = "sec1", feature = "pkcs8"))] use crate::{ - pkcs8::{self, DecodePublicKey}, - AlgorithmParameters, ALGORITHM_OID, + pkcs8::{self, AssociatedOid, DecodePublicKey}, + ALGORITHM_OID, }; #[cfg(feature = "pem")] @@ -281,7 +281,7 @@ where #[cfg_attr(docsrs, doc(cfg(all(feature = "pkcs8", feature = "sec1"))))] impl TryFrom> for PublicKey where - C: Curve + AlgorithmParameters + ProjectiveArithmetic, + C: Curve + AssociatedOid + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -298,7 +298,7 @@ where #[cfg_attr(docsrs, doc(cfg(all(feature = "pkcs8", feature = "sec1"))))] impl DecodePublicKey for PublicKey where - C: Curve + AlgorithmParameters + ProjectiveArithmetic, + C: Curve + AssociatedOid + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -308,15 +308,20 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "pem")))] impl EncodePublicKey for PublicKey where - C: Curve + AlgorithmParameters + ProjectiveArithmetic, + C: Curve + AssociatedOid + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { fn to_public_key_der(&self) -> pkcs8::spki::Result { + let algorithm = pkcs8::AlgorithmIdentifier { + oid: ALGORITHM_OID, + parameters: Some((&C::OID).into()), + }; + let public_key_bytes = self.to_encoded_point(false); pkcs8::SubjectPublicKeyInfo { - algorithm: C::algorithm_identifier(), + algorithm, subject_public_key: public_key_bytes.as_ref(), } .try_into() @@ -327,7 +332,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "pem")))] impl FromStr for PublicKey where - C: Curve + AlgorithmParameters + ProjectiveArithmetic, + C: Curve + AssociatedOid + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -342,7 +347,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "pem")))] impl ToString for PublicKey where - C: Curve + AlgorithmParameters + ProjectiveArithmetic, + C: Curve + AssociatedOid + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -356,7 +361,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "serde")))] impl Serialize for PublicKey where - C: Curve + AlgorithmParameters + ProjectiveArithmetic, + C: Curve + AssociatedOid + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -373,7 +378,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "serde")))] impl<'de, C> Deserialize<'de> for PublicKey where - C: Curve + AlgorithmParameters + ProjectiveArithmetic, + C: Curve + AssociatedOid + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs index 9bec94827..3c1a509bf 100644 --- a/elliptic-curve/src/secret_key/pkcs8.rs +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -2,9 +2,9 @@ use super::SecretKey; use crate::{ - pkcs8::{self, DecodePrivateKey}, + pkcs8::{self, AssociatedOid, DecodePrivateKey}, sec1::{ModulusSize, ValidatePublicKey}, - AlgorithmParameters, Curve, FieldSize, ALGORITHM_OID, + Curve, FieldSize, ALGORITHM_OID, }; use der::Decode; use sec1::EcPrivateKey; @@ -30,7 +30,7 @@ use { #[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))] impl TryFrom> for SecretKey where - C: Curve + AlgorithmParameters + ValidatePublicKey, + C: Curve + AssociatedOid + ValidatePublicKey, FieldSize: ModulusSize, { type Error = pkcs8::Error; @@ -48,7 +48,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))] impl DecodePrivateKey for SecretKey where - C: Curve + AlgorithmParameters + ValidatePublicKey, + C: Curve + AssociatedOid + ValidatePublicKey, FieldSize: ModulusSize, { } @@ -61,13 +61,18 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "pem")))] impl EncodePrivateKey for SecretKey where - C: Curve + AlgorithmParameters + ProjectiveArithmetic, + C: Curve + AssociatedOid + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { fn to_pkcs8_der(&self) -> pkcs8::Result { + let algorithm_identifier = pkcs8::AlgorithmIdentifier { + oid: ALGORITHM_OID, + parameters: Some((&C::OID).into()), + }; + let ec_private_key = self.to_sec1_der()?; - let pkcs8_key = pkcs8::PrivateKeyInfo::new(C::algorithm_identifier(), &ec_private_key); + let pkcs8_key = pkcs8::PrivateKeyInfo::new(algorithm_identifier, &ec_private_key); Ok(der::SecretDocument::encode_msg(&pkcs8_key)?) } } @@ -76,7 +81,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "pem")))] impl FromStr for SecretKey where - C: Curve + AlgorithmParameters + ValidatePublicKey, + C: Curve + AssociatedOid + ValidatePublicKey, FieldSize: ModulusSize, { type Err = Error; From 6d70420aa10fea3161fc0e7f1379189797619bb2 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 7 May 2022 10:16:12 -0600 Subject: [PATCH 0777/1461] elliptic-curve: bump `crypto-bigint` to v0.4.0-pre.1 (#1002) --- Cargo.lock | 6 +++--- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 464c0b262..aa82aea6d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -194,9 +194,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.4.0-pre.0" +version = "0.4.0-pre.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a9df9647255ed398be26379810e02ed1d58263570b3bcd243ee2481f79c88b1" +checksum = "ae6297ed3c636678b7495cd10625980d8242f49af92307162adde9db0cb65fc4" dependencies = [ "generic-array", "rand_core", @@ -316,7 +316,7 @@ version = "0.12.0-pre.2" dependencies = [ "base16ct", "base64ct", - "crypto-bigint 0.4.0-pre.0", + "crypto-bigint 0.4.0-pre.1", "der 0.6.0-pre.4", "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "ff 0.12.0", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index e2ae167dc..5b30a5714 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -17,7 +17,7 @@ rust-version = "1.57" [dependencies] base16ct = "0.1.1" -crypto-bigint = { version = "=0.4.0-pre.0", default-features = false, features = ["rand_core", "generic-array", "zeroize"] } +crypto-bigint = { version = "=0.4.0-pre.1", default-features = false, features = ["rand_core", "generic-array", "zeroize"] } der = { version = "=0.6.0-pre.4", default-features = false, features = ["oid"] } generic-array = { version = "0.14", default-features = false } rand_core = { version = "0.6", default-features = false } From 916ae38e588ecd90daf975b57b3390565d98e5e1 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 7 May 2022 10:53:11 -0600 Subject: [PATCH 0778/1461] elliptic-curve v0.12.0-pre.3 (#1003) --- Cargo.lock | 4 ++-- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aa82aea6d..cb32d84df 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -174,7 +174,7 @@ dependencies = [ "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "crypto-mac", "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", - "elliptic-curve 0.12.0-pre.2", + "elliptic-curve 0.12.0-pre.3", "password-hash", "signature 1.5.0", "universal-hash", @@ -312,7 +312,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.12.0-pre.2" +version = "0.12.0-pre.3" dependencies = [ "base16ct", "base64ct", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 5b30a5714..c93a791ba 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.12.0-pre.2" # Also update html_root_url in lib.rs when bumping this +version = "0.12.0-pre.3" # Also update html_root_url in lib.rs when bumping this description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, From 196bee3f82b97d093cb0f5466003e068658fe591 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 7 May 2022 20:53:05 -0600 Subject: [PATCH 0779/1461] elliptic-curve: bump `sec1` dependency to v0.3.0-pre.4 (#1004) --- Cargo.lock | 10 ++++++---- elliptic-curve/Cargo.toml | 6 +++--- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cb32d84df..5ae9b1c56 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -174,7 +174,7 @@ dependencies = [ "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "crypto-mac", "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", - "elliptic-curve 0.12.0-pre.3", + "elliptic-curve 0.12.0-pre.4", "password-hash", "signature 1.5.0", "universal-hash", @@ -312,7 +312,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.12.0-pre.3" +version = "0.12.0-pre.4" dependencies = [ "base16ct", "base64ct", @@ -730,13 +730,15 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "sec1" -version = "0.3.0-pre.3" +version = "0.3.0-pre.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "437ee1920f19c74e2b92630ba247f0716b52249464d97e76bf22ecb8ee75bbee" +checksum = "0d00c76f7d9f461f9a12a1b67775709f4e1b214272923167195aeb6fc76e8a7a" dependencies = [ + "base16ct", "der 0.6.0-pre.4", "generic-array", "pkcs8 0.9.0-pre.3", + "serdect", "subtle", "zeroize", ] diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index c93a791ba..339ebdf81 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.12.0-pre.3" # Also update html_root_url in lib.rs when bumping this +version = "0.12.0-pre.4" # Also update html_root_url in lib.rs when bumping this description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, @@ -32,7 +32,7 @@ group = { version = "0.12", optional = true, default-features = false } hex-literal = { version = "0.3", optional = true } pem-rfc7468 = { version = "0.5", optional = true } pkcs8 = { version = "=0.9.0-pre.3", optional = true, default-features = false } -sec1 = { version = "=0.3.0-pre.3", optional = true, features = ["subtle", "zeroize"] } +sec1 = { version = "=0.3.0-pre.4", optional = true, features = ["subtle", "zeroize"] } serdect = { version = "0.1", optional = true, default-features = false, features = ["alloc"] } serde_json = { version = "1", optional = true, default-features = false, features = ["alloc"] } @@ -52,7 +52,7 @@ ecdh = ["arithmetic"] hazmat = [] jwk = ["alloc", "base64ct/alloc", "serde", "serde_json", "zeroize/alloc"] pem = ["alloc", "arithmetic", "pem-rfc7468/alloc", "pkcs8", "sec1/pem"] -serde = ["alloc", "serdect"] +serde = ["alloc", "sec1/serde", "serdect"] std = ["alloc", "rand_core/std"] voprf = ["digest"] From 7ed813dd3bde17e009b255a2c487e8108d7e4d1f Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 8 May 2022 12:52:54 -0600 Subject: [PATCH 0780/1461] elliptic-curve: bump `crypto-bigint` to v0.4 (#1005) --- Cargo.lock | 6 +++--- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5ae9b1c56..d31c04e0a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -194,9 +194,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.4.0-pre.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae6297ed3c636678b7495cd10625980d8242f49af92307162adde9db0cb65fc4" +checksum = "f322d21b9f3edc2a5d5e2237e78d7b72f4da0b979df0da94cae705df1edd0181" dependencies = [ "generic-array", "rand_core", @@ -316,7 +316,7 @@ version = "0.12.0-pre.4" dependencies = [ "base16ct", "base64ct", - "crypto-bigint 0.4.0-pre.1", + "crypto-bigint 0.4.0", "der 0.6.0-pre.4", "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "ff 0.12.0", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 339ebdf81..fd4be9697 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -17,7 +17,7 @@ rust-version = "1.57" [dependencies] base16ct = "0.1.1" -crypto-bigint = { version = "=0.4.0-pre.1", default-features = false, features = ["rand_core", "generic-array", "zeroize"] } +crypto-bigint = { version = "0.4", default-features = false, features = ["rand_core", "generic-array", "zeroize"] } der = { version = "=0.6.0-pre.4", default-features = false, features = ["oid"] } generic-array = { version = "0.14", default-features = false } rand_core = { version = "0.6", default-features = false } From f864dd077af12aae42fce5f417d16a908b9de957 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 8 May 2022 18:06:09 -0600 Subject: [PATCH 0781/1461] elliptic-curve: bump `der`, `pkcs8`, and `sec1` (#1006) Bumps the following to final release versions: - `der` v0.6 - `pkcs8` v0.9 - `sec1` v0.3 --- Cargo.lock | 30 +++++++++++++++--------------- elliptic-curve/Cargo.toml | 6 +++--- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d31c04e0a..bc514cef7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -244,9 +244,9 @@ dependencies = [ [[package]] name = "der" -version = "0.6.0-pre.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0daf09ee3ea2f7e4f5761deb921bd4c4e46861ee4b218349a40eccfa9d7fa6a5" +checksum = "13dd2ae565c0a381dde7fade45fce95984c568bdcb4700a4fdbe3175e0380b2f" dependencies = [ "const-oid 0.9.0", "pem-rfc7468 0.6.0", @@ -317,14 +317,14 @@ dependencies = [ "base16ct", "base64ct", "crypto-bigint 0.4.0", - "der 0.6.0-pre.4", + "der 0.6.0", "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "ff 0.12.0", "generic-array", "group 0.12.0", "hex-literal 0.3.4", "pem-rfc7468 0.5.1", - "pkcs8 0.9.0-pre.3", + "pkcs8 0.9.0", "rand_core", "sec1", "serde_json", @@ -602,12 +602,12 @@ dependencies = [ [[package]] name = "pkcs8" -version = "0.9.0-pre.3" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1799b3d2dcb77fb12fd3cada7897c333d3f62c6eec50af2461b3cd8081a2599" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" dependencies = [ - "der 0.6.0-pre.4", - "spki 0.6.0-pre.3", + "der 0.6.0", + "spki 0.6.0", ] [[package]] @@ -730,14 +730,14 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "sec1" -version = "0.3.0-pre.4" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d00c76f7d9f461f9a12a1b67775709f4e1b214272923167195aeb6fc76e8a7a" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" dependencies = [ "base16ct", - "der 0.6.0-pre.4", + "der 0.6.0", "generic-array", - "pkcs8 0.9.0-pre.3", + "pkcs8 0.9.0", "serdect", "subtle", "zeroize", @@ -878,12 +878,12 @@ dependencies = [ [[package]] name = "spki" -version = "0.6.0-pre.3" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc54500466d9dad8716bc2b0bbb8e72cf2559759efa6c535fb40dcdf249716b3" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" dependencies = [ "base64ct", - "der 0.6.0-pre.4", + "der 0.6.0", ] [[package]] diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index fd4be9697..92e5c7b7a 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -18,7 +18,7 @@ rust-version = "1.57" [dependencies] base16ct = "0.1.1" crypto-bigint = { version = "0.4", default-features = false, features = ["rand_core", "generic-array", "zeroize"] } -der = { version = "=0.6.0-pre.4", default-features = false, features = ["oid"] } +der = { version = "0.6", default-features = false, features = ["oid"] } generic-array = { version = "0.14", default-features = false } rand_core = { version = "0.6", default-features = false } subtle = { version = "2", default-features = false } @@ -31,8 +31,8 @@ ff = { version = "0.12", optional = true, default-features = false } group = { version = "0.12", optional = true, default-features = false } hex-literal = { version = "0.3", optional = true } pem-rfc7468 = { version = "0.5", optional = true } -pkcs8 = { version = "=0.9.0-pre.3", optional = true, default-features = false } -sec1 = { version = "=0.3.0-pre.4", optional = true, features = ["subtle", "zeroize"] } +pkcs8 = { version = "0.9", optional = true, default-features = false } +sec1 = { version = "0.3", optional = true, features = ["subtle", "zeroize"] } serdect = { version = "0.1", optional = true, default-features = false, features = ["alloc"] } serde_json = { version = "1", optional = true, default-features = false, features = ["alloc"] } From 72bdd1b91b2ca8a5ab1074f332112532fc2de589 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 8 May 2022 20:04:54 -0600 Subject: [PATCH 0782/1461] build(deps): bump pqcrypto from 0.14.2 to 0.15.0 (#981) Bumps [pqcrypto](https://github.com/rustpq/pqcrypto) from 0.14.2 to 0.15.0. - [Release notes](https://github.com/rustpq/pqcrypto/releases) - [Changelog](https://github.com/rustpq/pqcrypto/blob/main/CHANGELOG.md) - [Commits](https://github.com/rustpq/pqcrypto/commits) --- updated-dependencies: - dependency-name: pqcrypto dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- kem/Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bc514cef7..159122eb9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -618,9 +618,9 @@ checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" [[package]] name = "pqcrypto" -version = "0.14.2" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9da39bd0587bff4189521766c34f3203263926f7527906578a96d22a81a700d5" +checksum = "e10caefecccc56b78d30a6b46effa2360048104d668fb7cea944c0761f9c1f11" dependencies = [ "pqcrypto-saber", "pqcrypto-traits", @@ -639,9 +639,9 @@ dependencies = [ [[package]] name = "pqcrypto-saber" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57ba16b59d256e2cae57bcdbd013f73b32496ebc66db3db6ccb79a10f0d4b275" +checksum = "7453b631d7bd268fffadf70514cdf05c9e9fd9574e26eafb85b5b86402e34c5b" dependencies = [ "cc", "glob", diff --git a/kem/Cargo.toml b/kem/Cargo.toml index fce312b49..cf8f0a405 100644 --- a/kem/Cargo.toml +++ b/kem/Cargo.toml @@ -20,7 +20,7 @@ generic-array = "0.14" rand = { version = "0.8", features = [ "getrandom" ] } x3dh-ke = "0.1" p256 = { version = "0.9", features = [ "ecdsa" ] } -pqcrypto = { version = "0.14", default-features = false, features = [ "pqcrypto-saber" ] } +pqcrypto = { version = "0.15", default-features = false, features = [ "pqcrypto-saber" ] } pqcrypto-traits = "0.3" # TODO(tarcieri): re-enable when `zeroize` compatibility can be resolved From 007b0770bb74f873ca2c255b12275285fa336c33 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 8 May 2022 20:05:04 -0600 Subject: [PATCH 0783/1461] build(deps): bump inout from 0.1.2 to 0.1.3 (#974) Bumps [inout](https://github.com/RustCrypto/utils) from 0.1.2 to 0.1.3. - [Release notes](https://github.com/RustCrypto/utils/releases) - [Commits](https://github.com/RustCrypto/utils/compare/inout-v0.1.2...inout-v0.1.3) --- updated-dependencies: - dependency-name: inout dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 159122eb9..b3f327181 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -478,9 +478,9 @@ dependencies = [ [[package]] name = "inout" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1f03d4ab4d5dc9ec2d219f86c15d2a15fc08239d1cd3b2d6a19717c0a2f443" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" dependencies = [ "block-padding", "generic-array", From 4e4e69ac1127984d214a631d39e021b15c48990e Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 8 May 2022 20:47:40 -0600 Subject: [PATCH 0784/1461] Cargo.lock: bump dependencies (#1008) --- Cargo.lock | 78 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 46 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b3f327181..8c3bc5dc0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -23,15 +23,21 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.52" +version = "0.1.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "061a7acccaa286c011ddc30970520b98fa40e00c9d644633fb26b5fc63a265e3" +checksum = "ed6aa3524a2dfcf9fe180c51eae2b58738348d819517ceadf95789c51fff7600" dependencies = [ "proc-macro2", "quote", "syn", ] +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + [[package]] name = "base16ct" version = "0.1.1" @@ -91,9 +97,9 @@ dependencies = [ [[package]] name = "block-padding" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5808df4b2412175c4db3afb115c83d8d0cd26ca4f30a042026cddef8580e526a" +checksum = "0a90ec2df9600c28a01c56c4784c9207a96d2451833aeceb8cc97e4c9548bb78" dependencies = [ "generic-array", ] @@ -159,9 +165,9 @@ checksum = "722e23542a15cea1f65d4a1419c4cfd7a26706c70871a13a04238ca3f40f1661" [[package]] name = "cpufeatures" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" +checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" dependencies = [ "libc", ] @@ -282,6 +288,12 @@ dependencies = [ "crypto-common 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "dunce" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "453440c271cf5577fd2a40e4942540cb7d0d2f85e27c8d07dd0023c925a67541" + [[package]] name = "ecdsa" version = "0.12.4" @@ -374,9 +386,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c" +checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" dependencies = [ "cfg-if", "libc", @@ -522,16 +534,17 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.119" +version = "0.2.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4" +checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b" [[package]] name = "lock_api" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88943dd7ef4a2e5a4bfa2753aaab3013e34ce2533d1996fb18ef591e315e2b3b" +checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" dependencies = [ + "autocfg", "scopeguard", ] @@ -628,11 +641,12 @@ dependencies = [ [[package]] name = "pqcrypto-internals" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64b13e34e3758451a74aee45db434cc258b7794225bcbef3274b981545058645" +checksum = "0127cbc0239f585139a56effd7867921eae3425a000a72dde2b0a156062346b2" dependencies = [ "cc", + "dunce", "getrandom", "libc", ] @@ -664,18 +678,18 @@ checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" [[package]] name = "proc-macro2" -version = "1.0.36" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" +checksum = "9027b48e9d4c9175fa2218adf3557f91c1137021739951d4932f5f8268ac48aa" dependencies = [ "unicode-xid", ] [[package]] name = "quote" -version = "1.0.15" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" +checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" dependencies = [ "proc-macro2", ] @@ -745,27 +759,27 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.136" +version = "1.0.137" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" +checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" dependencies = [ "serde_derive", ] [[package]] name = "serde_bytes" -version = "0.11.5" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16ae07dd2f88a366f15bd0632ba725227018c69a1c8550a927324f8eb8368bb9" +checksum = "212e73464ebcde48d723aa02eb270ba62eff38a9b732df31f33f1b4e145f3a54" dependencies = [ "serde", ] [[package]] name = "serde_derive" -version = "1.0.136" +version = "1.0.137" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" +checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" dependencies = [ "proc-macro2", "quote", @@ -774,9 +788,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.79" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" +checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" dependencies = [ "itoa", "ryu", @@ -860,9 +874,9 @@ dependencies = [ [[package]] name = "spin" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "511254be0c5bcf062b019a6c89c01a664aa359ded62f78aa72c6fc137c0590e5" +checksum = "c530c2b0d0bf8b69304b39fe2001993e267461948b890cd037d8ad4293fa1a0d" dependencies = [ "lock_api", ] @@ -900,9 +914,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.86" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b" +checksum = "7ff7c592601f11445996a06f8ad0c27f094a58857c2f89e97974ab9235b92c52" dependencies = [ "proc-macro2", "quote", @@ -935,9 +949,9 @@ checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" [[package]] name = "unicode-xid" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" +checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04" [[package]] name = "universal-hash" From 30a048761b38fbec6942355f7eed146fd9f72832 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 8 May 2022 21:25:40 -0600 Subject: [PATCH 0785/1461] elliptic-curve: `ecdh::SharedSecret::extract` HKDF helper (#1007) Adds support for using HKDF to generate key material from an ECDH shared secret using the `hkdf` crate. Renames the previous `as_bytes` method to `raw_secret_bytes` with a warning that the `extract` method should be preferred instead. --- Cargo.lock | 26 +++++++++++-- elliptic-curve/Cargo.toml | 3 +- elliptic-curve/src/ecdh.rs | 63 ++++++++++++++++++++++---------- elliptic-curve/src/secret_key.rs | 4 +- 4 files changed, 69 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8c3bc5dc0..6eec93364 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -286,6 +286,7 @@ checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" dependencies = [ "block-buffer 0.10.2", "crypto-common 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "subtle", ] [[package]] @@ -302,7 +303,7 @@ checksum = "43ee23aa5b4f68c7a092b5c3beb25f50c406adc75e2363634f242f28ab255372" dependencies = [ "der 0.4.5", "elliptic-curve 0.10.4", - "hmac", + "hmac 0.11.0", "signature 1.3.2", ] @@ -335,6 +336,7 @@ dependencies = [ "generic-array", "group 0.12.0", "hex-literal 0.3.4", + "hkdf 0.12.3", "pem-rfc7468 0.5.1", "pkcs8 0.9.0", "rand_core", @@ -475,7 +477,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01706d578d5c281058480e673ae4086a9f4710d8df1ad80a5b03e39ece5f886b" dependencies = [ "digest 0.9.0", - "hmac", + "hmac 0.11.0", +] + +[[package]] +name = "hkdf" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" +dependencies = [ + "hmac 0.12.1", ] [[package]] @@ -488,6 +499,15 @@ dependencies = [ "digest 0.9.0", ] +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "inout" version = "0.1.3" @@ -992,7 +1012,7 @@ dependencies = [ "bincode", "const-oid 0.6.2", "getrandom", - "hkdf", + "hkdf 0.11.0", "p256", "rand_core", "serde", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 92e5c7b7a..4f3dd3283 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -29,6 +29,7 @@ base64ct = { version = "1", optional = true, default-features = false } digest = { version = "0.10", optional = true } ff = { version = "0.12", optional = true, default-features = false } group = { version = "0.12", optional = true, default-features = false } +hkdf = { version = "0.12", optional = true, default-features = false } hex-literal = { version = "0.3", optional = true } pem-rfc7468 = { version = "0.5", optional = true } pkcs8 = { version = "0.9", optional = true, default-features = false } @@ -48,7 +49,7 @@ arithmetic = ["ff", "group"] bits = ["arithmetic", "ff/bits"] dev = ["arithmetic", "hex-literal", "pem", "pkcs8"] hash2curve = ["arithmetic", "digest"] -ecdh = ["arithmetic"] +ecdh = ["arithmetic", "digest", "hkdf"] hazmat = [] jwk = ["alloc", "base64ct/alloc", "serde", "serde_json", "zeroize/alloc"] pem = ["alloc", "arithmetic", "pem-rfc7468/alloc", "pkcs8", "sec1/pem"] diff --git a/elliptic-curve/src/ecdh.rs b/elliptic-curve/src/ecdh.rs index 7b6540d0e..1e9f7bc31 100644 --- a/elliptic-curve/src/ecdh.rs +++ b/elliptic-curve/src/ecdh.rs @@ -31,7 +31,9 @@ use crate::{ ProjectiveArithmetic, ProjectivePoint, PublicKey, }; use core::borrow::Borrow; +use digest::{crypto_common::BlockSizeUser, Digest}; use group::Curve as _; +use hkdf::{hmac::SimpleHmac, Hkdf}; use rand_core::{CryptoRng, RngCore}; use zeroize::{Zeroize, ZeroizeOnDrop}; @@ -150,20 +152,6 @@ where } /// Shared secret value computed via ECDH key agreement. -/// -/// This value contains the raw serialized x-coordinate of the elliptic curve -/// point computed from a Diffie-Hellman exchange. -/// -/// # ⚠️ WARNING: NOT UNIFORMLY RANDOM! ⚠️ -/// -/// This value is not uniformly random and should not be used directly -/// as a cryptographic key for anything which requires that property -/// (e.g. symmetric ciphers). -/// -/// Instead, the resulting value should be used as input to a Key Derivation -/// Function (KDF) or cryptographic hash function to produce a symmetric key. -// TODO(tarcieri): KDF traits and support for deriving uniform keys -// See: https://github.com/RustCrypto/traits/issues/5 pub struct SharedSecret { /// Computed secret value secret_bytes: FieldBytes, @@ -181,13 +169,48 @@ impl SharedSecret { } } - /// Shared secret value, serialized as bytes. + /// Use [HKDF] (HMAC-based Extract-and-Expand Key Derivation Function) to + /// extract entropy from this shared secret. + /// + /// This method can be used to transform the shared secret into uniformly + /// random values which are suitable as key material. + /// + /// The `D` type parameter is a cryptographic digest function. + /// `sha2::Sha256` is a common choice for use with HKDF. + /// + /// The `salt` parameter can be used to supply additional randomness. + /// Some examples include: + /// + /// - randomly generated (but authenticated) string + /// - fixed application-specific value + /// - previous shared secret used for rekeying (as in TLS 1.3 and Noise) + /// + /// After initializing HKDF, use [`Hkdf::expand`] to obtain output key + /// material. + /// + /// [HKDF]: https://en.wikipedia.org/wiki/HKDF + pub fn extract(&self, salt: Option<&[u8]>) -> Hkdf> + where + D: BlockSizeUser + Clone + Digest, + { + Hkdf::new(salt, &self.secret_bytes) + } + + /// This value contains the raw serialized x-coordinate of the elliptic curve + /// point computed from a Diffie-Hellman exchange, serialized as bytes. + /// + /// When in doubt, use [`SharedSecret::extract`] instead. + /// + /// # ⚠️ WARNING: NOT UNIFORMLY RANDOM! ⚠️ + /// + /// This value is not uniformly random and should not be used directly + /// as a cryptographic key for anything which requires that property + /// (e.g. symmetric ciphers). /// - /// As noted in the comments for this struct, this value is non-uniform and - /// should not be used directly as a symmetric encryption key, but instead - /// as input to a KDF (or failing that, a hash function) used to produce - /// a symmetric key. - pub fn as_bytes(&self) -> &FieldBytes { + /// Instead, the resulting value should be used as input to a Key Derivation + /// Function (KDF) or cryptographic hash function to produce a symmetric key. + /// The [`SharedSecret::extract`] function will do this for you. + pub fn raw_secret_bytes(&self) -> &FieldBytes { &self.secret_bytes } } diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 531719783..f6fd70774 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -78,9 +78,7 @@ pub(crate) const SEC1_PEM_TYPE_LABEL: &str = "EC PRIVATE KEY"; /// /// To decode an elliptic curve private key from PKCS#8, enable the `pkcs8` /// feature of this crate (or the `pkcs8` feature of a specific RustCrypto -/// elliptic curve crate) and use the -/// [`DecodePrivateKey`][`elliptic_curve::pkcs8::DecodePrivateKey`] -/// trait to parse it. +/// elliptic curve crate) and use the [`DecodePrivateKey`] trait to parse it. /// /// When the `pem` feature of this crate (or a specific RustCrypto elliptic /// curve crate) is enabled, a [`FromStr`] impl is also available. From 8cb0072d69256c9510322951f23d845594bb9b48 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 8 May 2022 22:29:41 -0600 Subject: [PATCH 0786/1461] elliptic-curve v0.12.0 (#1009) --- Cargo.lock | 15 +++------------ crypto/Cargo.toml | 2 +- elliptic-curve/CHANGELOG.md | 35 +++++++++++++++++++++++++++++++++++ elliptic-curve/Cargo.toml | 6 +++--- elliptic-curve/README.md | 8 ++++---- elliptic-curve/src/lib.rs | 3 +-- 6 files changed, 47 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6eec93364..5f755be67 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -180,7 +180,7 @@ dependencies = [ "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "crypto-mac", "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", - "elliptic-curve 0.12.0-pre.4", + "elliptic-curve 0.12.0", "password-hash", "signature 1.5.0", "universal-hash", @@ -325,7 +325,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.12.0-pre.4" +version = "0.12.0" dependencies = [ "base16ct", "base64ct", @@ -337,7 +337,7 @@ dependencies = [ "group 0.12.0", "hex-literal 0.3.4", "hkdf 0.12.3", - "pem-rfc7468 0.5.1", + "pem-rfc7468 0.6.0", "pkcs8 0.9.0", "rand_core", "sec1", @@ -603,15 +603,6 @@ dependencies = [ "base64ct", ] -[[package]] -name = "pem-rfc7468" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "973e070439aaacda48e5effad187f36d670b7635f7dcb75fa3c6f482d1b5b932" -dependencies = [ - "base64ct", -] - [[package]] name = "pem-rfc7468" version = "0.6.0" diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 0e4500afd..61a94e840 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -18,7 +18,7 @@ rust-version = "1.57" aead = { version = "0.4", optional = true, path = "../aead" } cipher = { version = "0.4", optional = true } digest = { version = "0.10", optional = true } -elliptic-curve = { version = "0.12.0-pre", optional = true, path = "../elliptic-curve" } +elliptic-curve = { version = "0.12", optional = true, path = "../elliptic-curve" } mac = { version = "0.11", package = "crypto-mac", optional = true } password-hash = { version = "0.4", optional = true, path = "../password-hash" } signature = { version = "1.5", optional = true, default-features = false, path = "../signature" } diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index 71f33e949..450de8b4c 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,41 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.12.0 (2022-05-08) +### Added +- `ecdh::SharedSecret::extract` HKDF helper ([#1007]) + +### Changed +- Bump `digest` dependency to v0.10 ([#883], [#904]) +- Make `NonZeroScalar::invert` infallible ([#894]) +- `ToCompactEncodedPoint` now returns `CtOption` ([#895]) +- Move `hash2field` into `hash2curve` module ([#903]) +- Bump `ff` and `group` dependencies to v0.12 ([#994]) +- Use `serdect` crate ([#996]) +- Replace `AlgorithmParamters` with `AssociatedOid` ([#1001]) +- Bump `crypto-bigint` dependency to v0.4 ([#1005]) +- Bump `der` dependency to v0.6 ([#1006]) +- Bump `pkcs8` dependency to v0.9 ([#1006]) +- Bump `sec1` dependency to v0.3 ([#1006]) +- Bump `pem-rfc7468` dependency to v0.6 ([#1009]) + +### Removed +- `Zeroize` impl from `ecdh::SharedSecret` ([#978]) + +[#883]: https://github.com/RustCrypto/formats/pull/883 +[#894]: https://github.com/RustCrypto/formats/pull/894 +[#895]: https://github.com/RustCrypto/formats/pull/895 +[#903]: https://github.com/RustCrypto/formats/pull/903 +[#904]: https://github.com/RustCrypto/formats/pull/904 +[#978]: https://github.com/RustCrypto/formats/pull/978 +[#994]: https://github.com/RustCrypto/formats/pull/994 +[#996]: https://github.com/RustCrypto/formats/pull/996 +[#1001]: https://github.com/RustCrypto/formats/pull/1001 +[#1005]: https://github.com/RustCrypto/formats/pull/1005 +[#1006]: https://github.com/RustCrypto/formats/pull/1006 +[#1007]: https://github.com/RustCrypto/formats/pull/1007 +[#1009]: https://github.com/RustCrypto/formats/pull/1009 + ## 0.11.12 (2022-01-30) ### Changed - Disable `bits` feature on docs.rs due to nightly breakage ([#927]) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 4f3dd3283..1c0e7cfe7 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.12.0-pre.4" # Also update html_root_url in lib.rs when bumping this +version = "0.12.0" description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, @@ -31,7 +31,7 @@ ff = { version = "0.12", optional = true, default-features = false } group = { version = "0.12", optional = true, default-features = false } hkdf = { version = "0.12", optional = true, default-features = false } hex-literal = { version = "0.3", optional = true } -pem-rfc7468 = { version = "0.5", optional = true } +pem-rfc7468 = { version = "0.6", optional = true } pkcs8 = { version = "0.9", optional = true, default-features = false } sec1 = { version = "0.3", optional = true, features = ["subtle", "zeroize"] } serdect = { version = "0.1", optional = true, default-features = false, features = ["alloc"] } @@ -52,7 +52,7 @@ hash2curve = ["arithmetic", "digest"] ecdh = ["arithmetic", "digest", "hkdf"] hazmat = [] jwk = ["alloc", "base64ct/alloc", "serde", "serde_json", "zeroize/alloc"] -pem = ["alloc", "arithmetic", "pem-rfc7468/alloc", "pkcs8", "sec1/pem"] +pem = ["alloc", "arithmetic", "der/pem", "pem-rfc7468/alloc", "pkcs8", "sec1/pem"] serde = ["alloc", "sec1/serde", "serdect"] std = ["alloc", "rand_core/std"] voprf = ["digest"] diff --git a/elliptic-curve/README.md b/elliptic-curve/README.md index 0fa524d34..254a99433 100644 --- a/elliptic-curve/README.md +++ b/elliptic-curve/README.md @@ -2,10 +2,10 @@ [![crate][crate-image]][crate-link] [![Docs][docs-image]][docs-link] +[![Build Status][build-image]][build-link] ![Apache2/MIT licensed][license-image] ![Rust Version][rustc-image] [![Project Chat][chat-image]][chat-link] -[![Build Status][build-image]][build-link] General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, @@ -42,13 +42,13 @@ dual licensed as above, without any additional terms or conditions. [//]: # (badges) -[crate-image]: https://img.shields.io/crates/v/elliptic-curve.svg +[crate-image]: https://buildstats.info/crate/elliptic-curve [crate-link]: https://crates.io/crates/elliptic-curve [docs-image]: https://docs.rs/elliptic-curve/badge.svg [docs-link]: https://docs.rs/elliptic-curve/ +[build-image]: https://github.com/RustCrypto/traits/actions/workflows/elliptic-curve.yml/badge.svg +[build-link]: https://github.com/RustCrypto/traits/actions/workflows/elliptic-curve.yml [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg [rustc-image]: https://img.shields.io/badge/rustc-1.57+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260040-elliptic-curves -[build-image]: https://github.com/RustCrypto/elliptic-curves/workflows/elliptic-curve%20crate/badge.svg?branch=master&event=push -[build-link]: https://github.com/RustCrypto/elliptic-curves/actions?query=workflow%3A%22elliptic-curve+crate%22 diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 65ac83561..4dbafbd13 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -3,8 +3,7 @@ #![doc = include_str!("../README.md")] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.12.0-pre.1" + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg" )] #![forbid(unsafe_code, clippy::unwrap_used)] #![warn(missing_docs, rust_2018_idioms, unused_qualifications)] From 7b97322cbeaecf6505781b5ad58743a4bbc9ad50 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 May 2022 16:26:25 -0600 Subject: [PATCH 0787/1461] build(deps): bump crypto-bigint from 0.4.0 to 0.4.1 (#1010) Bumps [crypto-bigint](https://github.com/RustCrypto/crypto-bigint) from 0.4.0 to 0.4.1. - [Release notes](https://github.com/RustCrypto/crypto-bigint/releases) - [Changelog](https://github.com/RustCrypto/crypto-bigint/blob/master/CHANGELOG.md) - [Commits](https://github.com/RustCrypto/crypto-bigint/compare/v0.4.0...v0.4.1) --- updated-dependencies: - dependency-name: crypto-bigint dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5f755be67..6e05e10eb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -200,9 +200,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f322d21b9f3edc2a5d5e2237e78d7b72f4da0b979df0da94cae705df1edd0181" +checksum = "3c65a74f1a0c03043720dd2b2746b9466727d5af63da6379af98ac9012384ee2" dependencies = [ "generic-array", "rand_core", @@ -329,7 +329,7 @@ version = "0.12.0" dependencies = [ "base16ct", "base64ct", - "crypto-bigint 0.4.0", + "crypto-bigint 0.4.1", "der 0.6.0", "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "ff 0.12.0", From fb5cd116d33c23ff8b0ac04fd84288e6ffbc2d46 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 12 May 2022 08:51:46 -0600 Subject: [PATCH 0788/1461] digest: yank v0.10.0 and v0.10.1 (#1012) Closes #979 --- digest/CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/digest/CHANGELOG.md b/digest/CHANGELOG.md index 65d68311c..c9f52c64e 100644 --- a/digest/CHANGELOG.md +++ b/digest/CHANGELOG.md @@ -17,7 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [#849]: https://github.com/RustCrypto/traits/pull/849 -## 0.10.1 (2021-12-14) +## 0.10.1 (2021-12-14) [YANKED] ### Added - `Update::chain` and `Digest::new_with_prefix` methods. ([#846]) - `Mac::generate_key` method. ([#847]) @@ -30,7 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [#846]: https://github.com/RustCrypto/traits/pull/846 [#847]: https://github.com/RustCrypto/traits/pull/847 -## 0.10.0 (2021-12-07) +## 0.10.0 (2021-12-07) [YANKED] ### Changed - Dirty traits are removed and instead block-level traits are introduced. Variable output traits reworked and now support both run and compile time selection of output size. ([#380], [#819]) From 44921b3fcc9c9a795c023049c07b62cb328d020f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 19 May 2022 19:23:11 -0600 Subject: [PATCH 0789/1461] build(deps): bump crypto-bigint from 0.4.1 to 0.4.2 (#1013) Bumps [crypto-bigint](https://github.com/RustCrypto/crypto-bigint) from 0.4.1 to 0.4.2. - [Release notes](https://github.com/RustCrypto/crypto-bigint/releases) - [Changelog](https://github.com/RustCrypto/crypto-bigint/blob/master/CHANGELOG.md) - [Commits](https://github.com/RustCrypto/crypto-bigint/compare/v0.4.1...v0.4.2) --- updated-dependencies: - dependency-name: crypto-bigint dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6e05e10eb..4f6181296 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -200,9 +200,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c65a74f1a0c03043720dd2b2746b9466727d5af63da6379af98ac9012384ee2" +checksum = "de3e45371ac6a1370324b085acb466f24b07d4d66da6999a42c8ce655bd14e0e" dependencies = [ "generic-array", "rand_core", @@ -329,7 +329,7 @@ version = "0.12.0" dependencies = [ "base16ct", "base64ct", - "crypto-bigint 0.4.1", + "crypto-bigint 0.4.2", "der 0.6.0", "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "ff 0.12.0", From 283e3b1360d471cd2b7228dcc7ad3c09f5dc6d74 Mon Sep 17 00:00:00 2001 From: Michael Rosenberg Date: Thu, 26 May 2022 05:43:45 -0700 Subject: [PATCH 0790/1461] KEM v2 (#982) I made a few changes to the KEM API ## Deserialization As discussed over Zulip earlier this year, there should probably be a way to deserialize an encapsulated key sent over the wire. This breaks a bit with the rest of RustCrypto because it uses `&GenericArray` rather than `&[u8]` for bitstrings. I'm not married to this, but the pros are: 1. It fits the existing API, which already uses a `GenericArray` to describe shared secrets 2. Fixed size arrays make function preconditions clear a first glance, which is good. ## Shared Secrets Separately, I've also switched the API off of directly returning `GenericArray`s for a shared secret and made it its own `SharedSecret` type. The con is that the values are just a little more opaque. The pros are: 1. Shared secrets are now zeroize-on-drop 2. The type signatures are more concise --- Cargo.lock | 16 ++++++++++++ kem/Cargo.toml | 12 ++++----- kem/src/kem.rs | 61 +++++++++++++++++++++++++++++++++++++--------- kem/tests/hpke.rs | 51 ++++++++++++++++++++++++-------------- kem/tests/saber.rs | 35 ++++++++++++++++++++------ kem/tests/x3dh.rs | 44 +++++++++++++++++++-------------- 6 files changed, 159 insertions(+), 60 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4f6181296..f1c054a2e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -550,6 +550,7 @@ dependencies = [ "rand", "rand_core", "x3dh-ke", + "zeroize", ] [[package]] @@ -1016,3 +1017,18 @@ name = "zeroize" version = "1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94693807d016b2f2d2e14420eb3bfcca689311ff775dcf113d74ea624b7cdf07" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f8f187641dad4f680d25c4bfc4225b418165984179f26ca76ec4fb6441d3a17" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] diff --git a/kem/Cargo.toml b/kem/Cargo.toml index cf8f0a405..9c397970f 100644 --- a/kem/Cargo.toml +++ b/kem/Cargo.toml @@ -15,6 +15,7 @@ rust-version = "1.56" [dependencies] rand_core = "0.6" generic-array = "0.14" +zeroize = { version = "1.5", default-features = false } [dev-dependencies] rand = { version = "0.8", features = [ "getrandom" ] } @@ -23,12 +24,11 @@ p256 = { version = "0.9", features = [ "ecdsa" ] } pqcrypto = { version = "0.15", default-features = false, features = [ "pqcrypto-saber" ] } pqcrypto-traits = "0.3" -# TODO(tarcieri): re-enable when `zeroize` compatibility can be resolved -#[dev-dependencies.hpke] -#git = "https://github.com/rozbb/rust-hpke" -#rev = "3c795445f38317d6a0868259caf3e87916548356" -#default-features = false -#features = [ "x25519" ] +[dev-dependencies.hpke] +git = "https://github.com/rozbb/rust-hpke" +rev = "9230db267819f5795a47510139f4f1a60688ce82" +default-features = false +features = [ "x25519" ] [features] default = [] diff --git a/kem/src/kem.rs b/kem/src/kem.rs index 193eaadf3..4e7853672 100644 --- a/kem/src/kem.rs +++ b/kem/src/kem.rs @@ -1,16 +1,21 @@ //! KEM Traits use crate::errors::Error; + use core::fmt::Debug; -use generic_array::{ArrayLength, GenericArray}; +use generic_array::{ArrayLength, GenericArray}; use rand_core::{CryptoRng, RngCore}; +use zeroize::{Zeroize, ZeroizeOnDrop}; /// Trait impl'd by concrete types that represent an encapsulated key. This is intended to be, in /// essence, a bag of bytes. pub trait EncappedKey: AsRef<[u8]> + Debug + Sized { - /// The size of the shared secret that this KEM produces - type NSecret: ArrayLength; + /// The size, in bytes, of an encapsulated key. + type EncappedKeySize: ArrayLength; + + /// The size, in bytes, of the shared secret that this KEM produces. + type SharedSecretSize: ArrayLength; /// Represents the identity key of an encapsulator. This is used in authenticated /// decapsulation. @@ -18,31 +23,65 @@ pub trait EncappedKey: AsRef<[u8]> + Debug + Sized { /// The public key of a decapsulator. This is used in encapsulation. type RecipientPublicKey; + + /// Parses an encapsulated key from its byte representation. + fn from_bytes(bytes: &GenericArray) -> Result; + + /// Borrows a byte slice representing the serialized form of this encapsulated key. + fn as_bytes(&self) -> &GenericArray { + // EncappedKey is already AsRef<[u8]>, so we don't need to do any work. This will panic iff + // the underlying bytestring is not precisely NEnc bytes long. + self.as_ref().into() + } +} + +/// The shared secret that results from key exchange. +pub struct SharedSecret(GenericArray); + +// Zero the secret on drop +impl Drop for SharedSecret { + fn drop(&mut self) { + self.0.as_mut_slice().zeroize(); + } +} + +impl ZeroizeOnDrop for SharedSecret {} + +impl SharedSecret { + /// Constructs a new `SharedSecret` by wrapping the given bytes + pub fn new(bytes: GenericArray) -> Self { + SharedSecret(bytes) + } + + /// Returns borrowed bytes representing the shared secret of the key exchange + pub fn as_bytes(&self) -> &[u8] { + &self.0 + } } /// Represents the functionality of a key encapsulator. For unauthenticated encapsulation, `Self` /// can be an empty struct. For authenticated encapsulation, `Self` is a private key. pub trait Encapsulator { - /// Attempt to encapsulate a fresh shared secret with the given recipient. The resulting shared - /// secret is bound to the identity encoded in `Self` (i.e., authenticated wrt `Self`). If - /// `Self` is empty, then this is equivalent to unauthenticated encapsulation. Returns the + /// Attempts to encapsulate a fresh shared secret with the given recipient. The resulting + /// shared secret is bound to the identity encoded in `Self` (i.e., authenticated wrt `Self`). + /// If `Self` is empty, then this is equivalent to unauthenticated encapsulation. Returns the /// shared secret and encapsulated key on success, or an error if something went wrong. fn try_encap( &self, csprng: &mut R, recip_pubkey: &EK::RecipientPublicKey, - ) -> Result<(EK, GenericArray), Error>; + ) -> Result<(EK, SharedSecret), Error>; } -/// Represents the functionality of a key decapsulator, where `Self` is a cryptographic key +/// Represents the functionality of a key decapsulator, where `Self` is a cryptographic key. pub trait Decapsulator { /// Attempt to decapsulate the given encapsulated key. Returns the shared secret on success, or /// an error if something went wrong. - fn try_decap(&self, encapped_key: &EK) -> Result, Error>; + fn try_decap(&self, encapped_key: &EK) -> Result, Error>; } /// Represents the functionality of a authenticated-key decapsulator, where `Self` is a -/// cryptographic key +/// cryptographic key. pub trait AuthDecapsulator { /// Attempt to decapsulate the given encapsulated key. The resulting shared secret is bound to /// the provided sender identity, thus providing authenticity. Returns the shared secret @@ -51,5 +90,5 @@ pub trait AuthDecapsulator { &self, encapped_key: &EK, sender_pubkey: &EK::SenderPublicKey, - ) -> Result, Error>; + ) -> Result, Error>; } diff --git a/kem/tests/hpke.rs b/kem/tests/hpke.rs index 36ca6b3d5..0b5d07b3f 100644 --- a/kem/tests/hpke.rs +++ b/kem/tests/hpke.rs @@ -1,12 +1,11 @@ -// TODO(tarcieri): re-enable when `zeroize` dependency issues are resolved -#![cfg(disabled)] - -use generic_array::GenericArray; use hpke::{ kem::{Kem as KemTrait, X25519HkdfSha256}, Deserializable as HpkeDeserializable, Serializable as HpkeSerializable, }; -use kem::{AuthDecapsulator, Decapsulator, EncappedKey, Encapsulator, Error}; +use kem::{ + generic_array::GenericArray, AuthDecapsulator, Decapsulator, EncappedKey, Encapsulator, Error, + SharedSecret, +}; use rand::rngs::OsRng; use rand_core::{CryptoRng, RngCore}; @@ -24,11 +23,17 @@ struct X25519EncappedKey( GenericArray::EncappedKey as HpkeSerializable>::OutputSize>, ); impl EncappedKey for X25519EncappedKey { - type NSecret = ::NSecret; + type SharedSecretSize = ::NSecret; + type EncappedKeySize = + <::PublicKey as HpkeSerializable>::OutputSize; // In HPKE the only recipient public key is the identity key type RecipientPublicKey = X25519PublicKey; // The sender's pubkey is the identity too type SenderPublicKey = X25519PublicKey; + + fn from_bytes(bytes: &GenericArray) -> Result { + Ok(X25519EncappedKey(bytes.clone())) + } } impl AsRef<[u8]> for X25519EncappedKey { fn as_ref(&self) -> &[u8] { @@ -38,7 +43,7 @@ impl AsRef<[u8]> for X25519EncappedKey { // Define some convenience types type X25519PrivateKey = ::PrivateKey; -type SharedSecret = GenericArray::NSecret>; +type X25519SharedSecret = SharedSecret; // Define an authenticated encapsulator. To authenticate, we need a full sender keypair. struct X25519AuthEncap(X25519PrivateKey, X25519PublicKey); @@ -47,9 +52,14 @@ impl Encapsulator for X25519AuthEncap { &self, csprng: &mut R, recip_pubkey: &X25519PublicKey, - ) -> Result<(X25519EncappedKey, SharedSecret), Error> { + ) -> Result<(X25519EncappedKey, X25519SharedSecret), Error> { ::encap(&recip_pubkey.0, Some((&self.0, &(self.1).0)), csprng) - .map(|(ss, ek)| (X25519EncappedKey(ek.to_bytes()), ss.0)) + .map(|(ss, ek)| { + ( + X25519EncappedKey(ek.to_bytes()), + X25519SharedSecret::new(ss.0), + ) + }) .map_err(|_| Error) } } @@ -61,9 +71,14 @@ impl Encapsulator for X25519Encap { &self, csprng: &mut R, recip_pubkey: &X25519PublicKey, - ) -> Result<(X25519EncappedKey, SharedSecret), Error> { + ) -> Result<(X25519EncappedKey, X25519SharedSecret), Error> { ::encap(&recip_pubkey.0, None, csprng) - .map(|(ss, ek)| (X25519EncappedKey(ek.to_bytes()), ss.0)) + .map(|(ss, ek)| { + ( + X25519EncappedKey(ek.to_bytes()), + X25519SharedSecret::new(ss.0), + ) + }) .map_err(|_| Error) } } @@ -72,7 +87,7 @@ impl Encapsulator for X25519Encap { // the same type (which, outside of testing, should not be the case), this can do both auth'd and // unauth'd decapsulation. impl Decapsulator for X25519PrivateKey { - fn try_decap(&self, encapped_key: &X25519EncappedKey) -> Result { + fn try_decap(&self, encapped_key: &X25519EncappedKey) -> Result { // First parse the encapped key, since it's just bytes right now let deserialized_encapped_key = <::EncappedKey as HpkeDeserializable>::from_bytes( @@ -82,7 +97,7 @@ impl Decapsulator for X25519PrivateKey { // Now decapsulate ::decap(self, None, &deserialized_encapped_key) - .map(|ss| ss.0) + .map(|ss| SharedSecret::new(ss.0)) .map_err(|_| Error) } } @@ -91,7 +106,7 @@ impl AuthDecapsulator for X25519PrivateKey { &self, encapped_key: &X25519EncappedKey, sender_pubkey: &X25519PublicKey, - ) -> Result { + ) -> Result { // First parse the encapped key, since it's just bytes right now let deserialized_encapped_key = <::EncappedKey as HpkeDeserializable>::from_bytes( @@ -105,7 +120,7 @@ impl AuthDecapsulator for X25519PrivateKey { Some(&sender_pubkey.0), &deserialized_encapped_key, ) - .map(|ss| ss.0) + .map(|ss| X25519SharedSecret::new(ss.0)) .map_err(|_| Error) } } @@ -130,13 +145,13 @@ fn test_hpke() { let encapper = X25519Encap; let (ek, ss1) = encapper.try_encap(&mut rng, &pk_recip).unwrap(); let ss2 = sk_recip.try_decap(&ek).unwrap(); - assert_eq!(ss1, ss2); + assert_eq!(ss1.as_bytes(), ss2.as_bytes()); // Now do an authenticated encap let encapper = X25519AuthEncap(sk_sender, pk_sender.clone()); let (ek, ss1) = encapper.try_encap(&mut rng, &pk_recip).unwrap(); let ss2 = sk_recip.try_auth_decap(&ek, &pk_sender).unwrap(); - assert_eq!(ss1, ss2); + assert_eq!(ss1.as_bytes(), ss2.as_bytes()); // Now do an invalid authenticated encap, where the sender uses the wrong private key. This // should produce unequal shared secrets. @@ -144,5 +159,5 @@ fn test_hpke() { let encapper = X25519AuthEncap(rand_sk, pk_sender.clone()); let (ek, ss1) = encapper.try_encap(&mut rng, &pk_recip).unwrap(); let ss2 = sk_recip.try_auth_decap(&ek, &pk_sender).unwrap(); - assert_ne!(ss1, ss2); + assert_ne!(ss1.as_bytes(), ss2.as_bytes()); } diff --git a/kem/tests/saber.rs b/kem/tests/saber.rs index b4229e912..ce70c47d1 100644 --- a/kem/tests/saber.rs +++ b/kem/tests/saber.rs @@ -1,5 +1,10 @@ -use generic_array::{typenum::U32, GenericArray}; -use kem::{Decapsulator, EncappedKey, Encapsulator, Error}; +use kem::{ + generic_array::{ + typenum::{self, U1000, U32, U472}, + GenericArray, + }, + Decapsulator, EncappedKey, Encapsulator, Error, SharedSecret, +}; use pqcrypto::kem::firesaber::{ decapsulate, encapsulate, keypair, Ciphertext, PublicKey, SecretKey, }; @@ -13,11 +18,20 @@ type SaberPublicKey = PublicKey; // The encapped key type is called "Ciphertext" in Rust's pqcrypto. Impl the necessary traits. struct SaberEncappedKey(Ciphertext); impl EncappedKey for SaberEncappedKey { - type NSecret = U32; + type SharedSecretSize = U32; + // FireSaber encapped keys are 1472 bytes; + type EncappedKeySize = typenum::op!(U1000 + U472); + // In HPKE the only recipient public key is the identity key type RecipientPublicKey = SaberPublicKey; // The sender's pubkey is the identity too type SenderPublicKey = SaberPrivateKey; + + fn from_bytes(bytes: &GenericArray) -> Result { + Ciphertext::from_bytes(bytes.as_slice()) + .map(SaberEncappedKey) + .map_err(|_| Error) + } } impl AsRef<[u8]> for SaberEncappedKey { fn as_ref(&self) -> &[u8] { @@ -31,7 +45,7 @@ impl core::fmt::Debug for SaberEncappedKey { } // Define some convenience types -type SaberSharedSecret = GenericArray::NSecret>; +type SaberSharedSecret = SharedSecret; type SaberPrivateKey = SecretKey; // Define an unauthenticated encapsulator. It holds nothing at all @@ -43,7 +57,7 @@ impl Encapsulator for SaberEncapper { recip_pubkey: &SaberPublicKey, ) -> Result<(SaberEncappedKey, SaberSharedSecret), Error> { let (ss, ek) = encapsulate(recip_pubkey); - let ss_bytes = SaberSharedSecret::clone_from_slice(ss.as_bytes()); + let ss_bytes = SaberSharedSecret::new(GenericArray::clone_from_slice(ss.as_bytes())); Ok((SaberEncappedKey(ek), ss_bytes)) } @@ -53,7 +67,9 @@ impl Encapsulator for SaberEncapper { impl Decapsulator for SaberPrivateKey { fn try_decap(&self, encapped_key: &SaberEncappedKey) -> Result { let ss = decapsulate(&encapped_key.0, self); - Ok(SaberSharedSecret::clone_from_slice(ss.as_bytes())) + Ok(SaberSharedSecret::new(GenericArray::clone_from_slice( + ss.as_bytes(), + ))) } } @@ -68,5 +84,10 @@ fn test_saber() { let encapper = SaberEncapper; let (ek, ss1) = encapper.try_encap(&mut rng, &pk_recip).unwrap(); let ss2 = sk_recip.try_decap(&ek).unwrap(); - assert_eq!(ss1, ss2); + assert_eq!(ss1.as_bytes(), ss2.as_bytes()); + + // Test serialization/deserialization + let ek_bytes = ek.as_bytes(); + let ek2 = SaberEncappedKey::from_bytes(ek_bytes).unwrap(); + assert_eq!(ek.as_bytes(), ek2.as_bytes()); } diff --git a/kem/tests/x3dh.rs b/kem/tests/x3dh.rs index 23af60c29..0081a7197 100644 --- a/kem/tests/x3dh.rs +++ b/kem/tests/x3dh.rs @@ -1,12 +1,17 @@ -use generic_array::{typenum::U32, GenericArray}; -use kem::{AuthDecapsulator, EncappedKey, Encapsulator, Error}; +use kem::{ + generic_array::{ + typenum::{self, Unsigned}, + GenericArray, + }, + AuthDecapsulator, EncappedKey, Encapsulator, Error, SharedSecret, +}; use p256::ecdsa::Signature; use rand::rngs::OsRng; use rand_core::{CryptoRng, RngCore}; use x3dh_ke::{x3dh_a, x3dh_b, EphemeralKey, IdentityKey, Key, OneTimePreKey, SignedPreKey}; -// The size of an encapped key -const P256_POINT_SIZE: usize = 231; +// The size of an encapped key. This is the number of bytes in an uncompressed P256 point +type NEnc = typenum::U231; // Define the sender pubkey type. This is an identity key; type X3DhSenderPublicKey = IdentityKey; @@ -40,11 +45,18 @@ type X3DhPubkeyBundle = X3DhPrivkeyBundle; // The encapped key is just the byte repr of an ephemeral key. Impl the appropriate traits #[derive(Debug)] -struct X3DhEncappedKey([u8; P256_POINT_SIZE]); +struct X3DhEncappedKey([u8; NEnc::USIZE]); impl EncappedKey for X3DhEncappedKey { - type NSecret = U32; + type SharedSecretSize = typenum::U32; + type EncappedKeySize = NEnc; type SenderPublicKey = X3DhSenderPublicKey; type RecipientPublicKey = X3DhPubkeyBundle; + + fn from_bytes(bytes: &GenericArray) -> Result { + let mut buf = [0u8; NEnc::USIZE]; + buf.copy_from_slice(bytes); + Ok(X3DhEncappedKey(buf)) + } } impl AsRef<[u8]> for X3DhEncappedKey { fn as_ref(&self) -> &[u8] { @@ -55,7 +67,7 @@ impl AsRef<[u8]> for X3DhEncappedKey { // The private key of an authenticated sender is just their identity key. Again, this is the same // type as the pubkey. type X3DhSenderPrivateKey = IdentityKey; -type SharedSecret = GenericArray::NSecret>; +type X3DhSharedSecret = SharedSecret; // Define an authenticated encapsulator. To authenticate, we need a full sender keypair. impl Encapsulator for X3DhSenderPrivateKey { @@ -63,7 +75,7 @@ impl Encapsulator for X3DhSenderPrivateKey { &self, _csprng: &mut R, recip_pubkey: &X3DhPubkeyBundle, - ) -> Result<(X3DhEncappedKey, SharedSecret), Error> { + ) -> Result<(X3DhEncappedKey, X3DhSharedSecret), Error> { // Make a new ephemeral key. This will be the encapped key let ek = EphemeralKey::default(); // Deconstruct the recipient's pubkey bundle @@ -71,17 +83,13 @@ impl Encapsulator for X3DhSenderPrivateKey { // Do the X3DH operation to get the shared secret let shared_secret = x3dh_a(sig, self, spk, &ek, ik, opk) - .map(|ss| SharedSecret::clone_from_slice(&ss)) + .map(|ss| X3DhSharedSecret::new(ss.into())) .map_err(|e| { println!("err {:?}", e); Error })?; // Serialize the ephemeral key - let encapped_key = { - let mut buf = [0u8; P256_POINT_SIZE]; - buf.copy_from_slice(&ek.to_bytes()); - X3DhEncappedKey(buf) - }; + let encapped_key = X3DhEncappedKey::from_bytes(ek.to_bytes().as_slice().into())?; Ok((encapped_key, shared_secret)) } @@ -95,7 +103,7 @@ impl AuthDecapsulator for X3DhPrivkeyBundle { &self, encapped_key: &X3DhEncappedKey, sender_pubkey: &X3DhSenderPublicKey, - ) -> Result { + ) -> Result { // First parse the encapped key, since it's just bytes right now let deserialized_ek = EphemeralKey::from_bytes(&encapped_key.0).map_err(|_| Error)?; // Deconstruct our private keys bundle @@ -108,7 +116,7 @@ impl AuthDecapsulator for X3DhPrivkeyBundle { // Now decapsulate let buf = x3dh_b(sender_pubkey, spk, &deserialized_ek, ik, opk); - Ok(SharedSecret::clone_from_slice(&buf)) + Ok(X3DhSharedSecret::new(buf.into())) } } @@ -128,7 +136,7 @@ fn test_x3dh() { let ss2 = sk_bundle_b .try_auth_decap(&encapped_key, &pk_ident_a) .unwrap(); - assert_eq!(ss1, ss2); + assert_eq!(ss1.as_bytes(), ss2.as_bytes()); // Now do an invalid authenticated encap, where the sender uses the wrong private key. This // should produce unequal shared secrets. @@ -137,5 +145,5 @@ fn test_x3dh() { let ss2 = sk_bundle_b .try_auth_decap(&encapped_key, &pk_ident_a) .unwrap(); - assert_ne!(ss1, ss2); + assert_ne!(ss1.as_bytes(), ss2.as_bytes()); } From a89b4b3be3fa669e660932069640357c89f21173 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 26 May 2022 09:55:48 -0600 Subject: [PATCH 0791/1461] kem v0.2.0 (#1015) --- Cargo.lock | 202 ++++++++++++++++++++++++++++++++++++++++++----- kem/CHANGELOG.md | 11 +++ kem/Cargo.toml | 2 +- 3 files changed, 194 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f1c054a2e..f102512d9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,7 +10,41 @@ dependencies = [ "bytes", "generic-array", "heapless", - "rand_core", + "rand_core 0.6.3", +] + +[[package]] +name = "aead" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" +dependencies = [ + "generic-array", +] + +[[package]] +name = "aes" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfe0133578c0986e1fe3dfcd4af1cc5b2dd6c3dbf534d69916ce16a2701d40ba" +dependencies = [ + "cfg-if", + "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cpufeatures", +] + +[[package]] +name = "aes-gcm" +version = "0.10.0-pre" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8004e8b23ff2c65e28ff77bab0eccd36f4a6c2c8e0b55c46acba481425cc3a4f" +dependencies = [ + "aead 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "aes", + "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "ctr", + "ghash", + "subtle", ] [[package]] @@ -131,6 +165,30 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chacha20" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7fc89c7c5b9e7a02dfe45cd2367bae382f9ed31c61ca8debe5f827c420a2f08" +dependencies = [ + "cfg-if", + "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cpufeatures", +] + +[[package]] +name = "chacha20poly1305" +version = "0.10.0-pre" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "746c430f71e66469abcf493c11484b1a86b957c84fc2d0ba664cd12ac23679ea" +dependencies = [ + "aead 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "chacha20", + "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "poly1305", + "zeroize", +] + [[package]] name = "cipher" version = "0.4.3" @@ -149,6 +207,7 @@ checksum = "d1873270f8f7942c191139cb8a40fd228da6c3fd2fc376d7e92d47aa14aeb59e" dependencies = [ "crypto-common 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "inout", + "zeroize", ] [[package]] @@ -176,14 +235,14 @@ dependencies = [ name = "crypto" version = "0.4.0-pre" dependencies = [ - "aead", + "aead 0.4.3", "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "crypto-mac", "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "elliptic-curve 0.12.0", "password-hash", "signature 1.5.0", - "universal-hash", + "universal-hash 0.4.1", ] [[package]] @@ -193,7 +252,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8658c15c5d921ddf980f7fe25b1e82f4b7a4083b2c4985fea4922edb8e43e07d" dependencies = [ "generic-array", - "rand_core", + "rand_core 0.6.3", "subtle", "zeroize", ] @@ -205,7 +264,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de3e45371ac6a1370324b085acb466f24b07d4d66da6999a42c8ce655bd14e0e" dependencies = [ "generic-array", - "rand_core", + "rand_core 0.6.3", "subtle", "zeroize", ] @@ -215,7 +274,7 @@ name = "crypto-common" version = "0.1.3" dependencies = [ "generic-array", - "rand_core", + "rand_core 0.6.3", "typenum", ] @@ -239,6 +298,28 @@ dependencies = [ "subtle", ] +[[package]] +name = "ctr" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d14f329cfbaf5d0e06b5e87fff7e265d2673c5ea7d2c27691a2c107db1442a0" +dependencies = [ + "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "curve25519-dalek" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "subtle", + "zeroize", +] + [[package]] name = "der" version = "0.4.5" @@ -318,7 +399,7 @@ dependencies = [ "generic-array", "group 0.10.0", "pkcs8 0.7.6", - "rand_core", + "rand_core 0.6.3", "subtle", "zeroize", ] @@ -339,7 +420,7 @@ dependencies = [ "hkdf 0.12.3", "pem-rfc7468 0.6.0", "pkcs8 0.9.0", - "rand_core", + "rand_core 0.6.3", "sec1", "serde_json", "serdect", @@ -355,7 +436,7 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0f40b2dcd8bc322217a5f6559ae5f9e9d1de202a2ecee2e9eafcbece7562a4f" dependencies = [ - "rand_core", + "rand_core 0.6.3", "subtle", ] @@ -366,7 +447,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df689201f395c6b90dfe87127685f8dbfc083a5e779e613575d8bd7314300c3e" dependencies = [ "bitvec", - "rand_core", + "rand_core 0.6.3", "subtle", ] @@ -397,6 +478,16 @@ dependencies = [ "wasi", ] +[[package]] +name = "ghash" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1583cc1656d7839fd3732b80cf4f38850336cdb9b8ded1cd399ca62958de3c99" +dependencies = [ + "opaque-debug", + "polyval", +] + [[package]] name = "glob" version = "0.3.0" @@ -410,7 +501,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c363a5301b8f153d80747126a04b3c82073b9fe3130571a9d170cacdeaf7912" dependencies = [ "ff 0.10.1", - "rand_core", + "rand_core 0.6.3", "subtle", ] @@ -421,7 +512,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7391856def869c1c81063a03457c676fbcd419709c3dfb33d8d319de484b154d" dependencies = [ "ff 0.12.0", - "rand_core", + "rand_core 0.6.3", "subtle", ] @@ -508,6 +599,26 @@ dependencies = [ "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "hpke" +version = "0.9.0" +source = "git+https://github.com/rozbb/rust-hpke?rev=9230db267819f5795a47510139f4f1a60688ce82#9230db267819f5795a47510139f4f1a60688ce82" +dependencies = [ + "aead 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "aes-gcm", + "byteorder", + "chacha20poly1305", + "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", + "generic-array", + "hkdf 0.12.3", + "hmac 0.12.1", + "rand_core 0.6.3", + "sha2 0.10.2", + "subtle", + "x25519-dalek", + "zeroize", +] + [[package]] name = "inout" version = "0.1.3" @@ -541,14 +652,15 @@ checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" [[package]] name = "kem" -version = "0.1.0" +version = "0.2.0" dependencies = [ "generic-array", + "hpke", "p256", "pqcrypto", "pqcrypto-traits", "rand", - "rand_core", + "rand_core 0.6.3", "x3dh-ke", "zeroize", ] @@ -591,7 +703,7 @@ name = "password-hash" version = "0.4.1" dependencies = [ "base64ct", - "rand_core", + "rand_core 0.6.3", "subtle", ] @@ -635,6 +747,29 @@ dependencies = [ "spki 0.6.0", ] +[[package]] +name = "poly1305" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "048aeb476be11a4b6ca432ca569e375810de9294ae78f4774e78ea98a9246ede" +dependencies = [ + "cpufeatures", + "opaque-debug", + "universal-hash 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "polyval" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8419d2b623c7c0896ff2d5d96e2cb4ede590fed28fcc34934f4c33c036e620a1" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "ppv-lite86" version = "0.2.16" @@ -720,7 +855,7 @@ checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha", - "rand_core", + "rand_core 0.6.3", ] [[package]] @@ -730,9 +865,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.3", ] +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" + [[package]] name = "rand_core" version = "0.6.3" @@ -860,7 +1001,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2807892cfa58e081aa1f1111391c7a0649d4fa127a4ffbe34bcbfb35a1171a4" dependencies = [ "digest 0.9.0", - "rand_core", + "rand_core 0.6.3", ] [[package]] @@ -869,7 +1010,7 @@ version = "1.5.0" dependencies = [ "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal 0.2.2", - "rand_core", + "rand_core 0.6.3", "sha2 0.10.2", "signature_derive", ] @@ -973,6 +1114,16 @@ dependencies = [ "subtle", ] +[[package]] +name = "universal-hash" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05" +dependencies = [ + "generic-array", + "subtle", +] + [[package]] name = "version_check" version = "0.9.4" @@ -994,6 +1145,17 @@ dependencies = [ "tap", ] +[[package]] +name = "x25519-dalek" +version = "2.0.0-pre.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5da623d8af10a62342bcbbb230e33e58a63255a58012f8653c578e54bab48df" +dependencies = [ + "curve25519-dalek", + "rand_core 0.6.3", + "zeroize", +] + [[package]] name = "x3dh-ke" version = "0.1.5" @@ -1006,7 +1168,7 @@ dependencies = [ "getrandom", "hkdf 0.11.0", "p256", - "rand_core", + "rand_core 0.6.3", "serde", "serde_bytes", "sha2 0.9.9", diff --git a/kem/CHANGELOG.md b/kem/CHANGELOG.md index 07beeed89..103b251f0 100644 --- a/kem/CHANGELOG.md +++ b/kem/CHANGELOG.md @@ -4,5 +4,16 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.2.0 (2022-05-26) +### Added +- Generic `SharedSecret` type ([#982]) +- `EncappedKey::EncappedKeySize` associated constant ([#982]) + +### Changed +- Rename `EncappedKey::NSecret` => `EncappedKey::SharedSecretSize` ([#982]) +- Add `EncappedKey::{from_bytes, as_bytes}` methods ([#982]) + +[#982]: https://github.com/RustCrypto/traits/pull/982 + ## 0.1.0 (2022-01-03) - Initial release diff --git a/kem/Cargo.toml b/kem/Cargo.toml index 9c397970f..b7e246c57 100644 --- a/kem/Cargo.toml +++ b/kem/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "kem" description = "Traits for key encapsulation mechanisms" -version = "0.1.0" +version = "0.2.0" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/kem" From 2b3633b8d2979828c826804e5825e6899a00eac8 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 26 May 2022 09:58:17 -0600 Subject: [PATCH 0792/1461] README.md: put dependencies badge on the end Makes the colors: [ blue ] [ blue ] [ green] ...instead of the previous: [ blue ] [ green ] [ blue ] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e4a345014..768f1fc44 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # RustCrypto: Traits -[![Project Chat][chat-image]][chat-link] [![dependency status][deps-image]][deps-link] ![Apache2/MIT licensed][license-image] +[![Project Chat][chat-image]][chat-link] ![Apache2/MIT licensed][license-image] [![dependency status][deps-image]][deps-link] Collection of traits which describe functionality of cryptographic primitives. From 950692b754f3afc17efe1076cb0616ebd2702b39 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 26 May 2022 09:59:39 -0600 Subject: [PATCH 0793/1461] README.md: have chat badge link to traits channel --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 768f1fc44..c06744b05 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ Unless you explicitly state otherwise, any contribution intentionally submitted [//]: # (badges) [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg -[chat-link]: https://rustcrypto.zulipchat.com/ +[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260050-traits [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg [deps-image]: https://deps.rs/repo/github/RustCrypto/traits/status.svg [deps-link]: https://deps.rs/repo/github/RustCrypto/traits From f1e3868fce59d0d157bae4994ee27fac6dec7c73 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 31 May 2022 09:11:51 -0600 Subject: [PATCH 0794/1461] elliptic-curve: bump `crypto-bigint` to v0.4.3 (#1018) An explicit requirement for the full version ensures that the `AsRef`/`AsMut` impls are available: https://github.com/RustCrypto/crypto-bigint/pull/89 --- Cargo.lock | 6 +++--- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f102512d9..d604c73b3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -259,9 +259,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3e45371ac6a1370324b085acb466f24b07d4d66da6999a42c8ce655bd14e0e" +checksum = "78a4e0fb04deabeb711eb20bd1179f1524c06f7e6975ebccc495f678a635887b" dependencies = [ "generic-array", "rand_core 0.6.3", @@ -410,7 +410,7 @@ version = "0.12.0" dependencies = [ "base16ct", "base64ct", - "crypto-bigint 0.4.2", + "crypto-bigint 0.4.3", "der 0.6.0", "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "ff 0.12.0", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 1c0e7cfe7..008c2c109 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -17,7 +17,7 @@ rust-version = "1.57" [dependencies] base16ct = "0.1.1" -crypto-bigint = { version = "0.4", default-features = false, features = ["rand_core", "generic-array", "zeroize"] } +crypto-bigint = { version = "0.4.3", default-features = false, features = ["rand_core", "generic-array", "zeroize"] } der = { version = "0.6", default-features = false, features = ["oid"] } generic-array = { version = "0.14", default-features = false } rand_core = { version = "0.6", default-features = false } From 2bdca99dbbc7af28fd5032aa2da48f7c658140fd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 Jun 2022 11:05:57 -0600 Subject: [PATCH 0795/1461] build(deps): bump crypto-bigint from 0.4.3 to 0.4.4 (#1020) Bumps [crypto-bigint](https://github.com/RustCrypto/crypto-bigint) from 0.4.3 to 0.4.4. - [Release notes](https://github.com/RustCrypto/crypto-bigint/releases) - [Changelog](https://github.com/RustCrypto/crypto-bigint/blob/master/CHANGELOG.md) - [Commits](https://github.com/RustCrypto/crypto-bigint/compare/v0.4.3...v0.4.4) --- updated-dependencies: - dependency-name: crypto-bigint dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 6 +++--- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d604c73b3..20c8fb8ca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -259,9 +259,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78a4e0fb04deabeb711eb20bd1179f1524c06f7e6975ebccc495f678a635887b" +checksum = "40997c4145fd5570180f579db9fcea452c91a2b72411da899efb1fb041136eae" dependencies = [ "generic-array", "rand_core 0.6.3", @@ -410,7 +410,7 @@ version = "0.12.0" dependencies = [ "base16ct", "base64ct", - "crypto-bigint 0.4.3", + "crypto-bigint 0.4.4", "der 0.6.0", "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "ff 0.12.0", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 008c2c109..3420ecd35 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -17,7 +17,7 @@ rust-version = "1.57" [dependencies] base16ct = "0.1.1" -crypto-bigint = { version = "0.4.3", default-features = false, features = ["rand_core", "generic-array", "zeroize"] } +crypto-bigint = { version = "0.4.4", default-features = false, features = ["rand_core", "generic-array", "zeroize"] } der = { version = "0.6", default-features = false, features = ["oid"] } generic-array = { version = "0.14", default-features = false } rand_core = { version = "0.6", default-features = false } From 6937f5d2fbf9454c0fc2d48c1fb1bb7591ef1d4b Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 9 Jun 2022 18:45:11 -0600 Subject: [PATCH 0796/1461] elliptic-curve: add `impl_field_element!` macro (#1021) Extracts the macro of the same name from the `p384` crate so it can be used with other elliptic curve crates. Closes #1017. --- elliptic-curve/src/dev.rs | 72 ++++++ elliptic-curve/src/lib.rs | 3 + elliptic-curve/src/macros.rs | 440 +++++++++++++++++++++++++++++++++++ 3 files changed, 515 insertions(+) create mode 100644 elliptic-curve/src/macros.rs diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 4e424716d..305508a6f 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -707,6 +707,78 @@ impl Neg for ProjectivePoint { } } +/// Constant representing the base field modulus +/// p = 2^{224}(2^{32} − 1) + 2^{192} + 2^{96} − 1 +pub const MODULUS: U256 = + U256::from_be_hex("ffffffff00000001000000000000000000000000ffffffffffffffffffffffff"); + +/// Example base field element. +#[derive(Clone, Copy, Debug)] +pub struct FieldElement(pub(crate) U256); + +/// Internal field element representation. +#[cfg(target_pointer_width = "32")] +type FeWords = [u32; 8]; + +/// Internal field element representation. +#[cfg(target_pointer_width = "64")] +type FeWords = [u64; 4]; + +impl_field_element!( + FieldElement, + FieldBytes, + U256, + MODULUS, + FeWords, + p256_from_montgomery, + p256_to_montgomery, + p256_add, + p256_sub, + p256_mul, + p256_opp, + p256_square +); + +impl FieldElement { + /// Returns the multiplicative inverse of self, if self is non-zero. + pub fn invert(&self) -> CtOption { + unimplemented!() + } + + /// Returns the square root of self mod p, or `None` if no square root exists. + pub fn sqrt(&self) -> CtOption { + unimplemented!() + } +} + +const fn p256_from_montgomery(_: &FeWords) -> FeWords { + unimplemented!() +} + +const fn p256_to_montgomery(w: &FeWords) -> FeWords { + *w +} + +const fn p256_add(_: &FeWords, _: &FeWords) -> FeWords { + unimplemented!() +} + +const fn p256_sub(_: &FeWords, _: &FeWords) -> FeWords { + unimplemented!() +} + +const fn p256_mul(_: &FeWords, _: &FeWords) -> FeWords { + unimplemented!() +} + +const fn p256_opp(_: &FeWords) -> FeWords { + unimplemented!() +} + +const fn p256_square(_: &FeWords) -> FeWords { + unimplemented!() +} + #[cfg(test)] mod tests { use super::Scalar; diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 4dbafbd13..93aafc9fd 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -71,6 +71,9 @@ pub mod ops; #[cfg(feature = "sec1")] pub mod sec1; +#[macro_use] +mod macros; + mod error; mod point; mod scalar; diff --git a/elliptic-curve/src/macros.rs b/elliptic-curve/src/macros.rs new file mode 100644 index 000000000..6a0c8bbca --- /dev/null +++ b/elliptic-curve/src/macros.rs @@ -0,0 +1,440 @@ +/// Provides both inherent and trait impls for a field element type which are +/// backed by a core set of arithmetic functions specified as macro arguments. +/// +/// # Inherent impls +/// - `const ZERO: Self` +/// - `const ONE: Self` (multiplicative identity) +/// - `pub fn from_be_bytes` +/// - `pub fn from_be_slice` +/// - `pub fn from_le_bytes` +/// - `pub fn from_le_slice` +/// - `pub fn from_uint` +/// - `fn from_uint_unchecked` +/// - `pub fn to_be_bytes` +/// - `pub fn to_le_bytes` +/// - `pub fn to_canonical` +/// - `pub fn is_odd` +/// - `pub fn is_zero` +/// - `pub fn double` +/// +/// NOTE: field implementations must provide their own inherent impls of +/// the following methods in order for the code generated by this macro to +/// compile: +/// +/// - `pub fn invert` +/// - `pub fn sqrt` +/// +/// # Trait impls +/// - `AsRef<$arr>` +/// - `ConditionallySelectable` +/// - `ConstantTimeEq` +/// - `ConstantTimeGreater` +/// - `ConstantTimeLess` +/// - `Default` +/// - `DefaultIsZeroes` +/// - `Eq` +/// - `Field` +/// - `PartialEq` +/// +/// ## Ops +/// - `Add` +/// - `AddAssign` +/// - `Sub` +/// - `SubAssign` +/// - `Mul` +/// - `MulAssign` +/// - `Neg` +#[macro_export] +macro_rules! impl_field_element { + ( + $fe:tt, + $bytes:ty, + $uint:ty, + $modulus:expr, + $arr:ty, + $from_mont:ident, + $to_mont:ident, + $add:ident, + $sub:ident, + $mul:ident, + $neg:ident, + $square:ident + ) => { + impl $fe { + /// Zero element. + pub const ZERO: Self = Self(<$uint>::ZERO); + + /// Multiplicative identity. + pub const ONE: Self = Self::from_uint_unchecked(<$uint>::ONE); + + /// Create a [` + #[doc = stringify!($fe)] + /// `] from a canonical big-endian representation. + pub fn from_be_bytes(repr: $bytes) -> $crate::subtle::CtOption { + use $crate::bigint::ArrayEncoding as _; + Self::from_uint(<$uint>::from_be_byte_array(repr)) + } + + /// Decode [` + #[doc = stringify!($fe)] + /// `] from a big endian byte slice. + pub fn from_be_slice(slice: &[u8]) -> $crate::Result { + <$uint as $crate::bigint::Encoding>::Repr::try_from(slice) + .ok() + .and_then(|array| Self::from_be_bytes(array.into()).into()) + .ok_or($crate::Error) + } + + /// Create a [` + #[doc = stringify!($fe)] + /// `] from a canonical little-endian representation. + pub fn from_le_bytes(repr: $bytes) -> $crate::subtle::CtOption { + use $crate::bigint::ArrayEncoding as _; + Self::from_uint(<$uint>::from_le_byte_array(repr)) + } + + /// Decode [` + #[doc = stringify!($fe)] + /// `] from a little endian byte slice. + pub fn from_le_slice(slice: &[u8]) -> $crate::Result { + <$uint as $crate::bigint::Encoding>::Repr::try_from(slice) + .ok() + .and_then(|array| Self::from_le_bytes(array.into()).into()) + .ok_or($crate::Error) + } + + /// Decode [` + #[doc = stringify!($fe)] + /// `] + /// from [` + #[doc = stringify!($uint)] + /// `] converting it into Montgomery form: + /// + /// ```text + /// w * R^2 * R^-1 mod p = wR mod p + /// ``` + pub fn from_uint(uint: $uint) -> $crate::subtle::CtOption { + use $crate::subtle::ConstantTimeLess as _; + let is_some = uint.ct_lt(&$modulus); + $crate::subtle::CtOption::new(Self::from_uint_unchecked(uint), is_some) + } + + /// Parse a [` + #[doc = stringify!($fe)] + /// `] from big endian hex-encoded bytes. + /// + /// Does *not* perform a check that the field element does not overflow the order. + /// + /// This method is primarily intended for defining internal constants. + #[allow(dead_code)] + pub(crate) const fn from_be_hex(hex: &str) -> Self { + Self::from_uint_unchecked(<$uint>::from_be_hex(hex)) + } + + /// Parse a [` + #[doc = stringify!($fe)] + /// `] from little endian hex-encoded bytes. + /// + /// Does *not* perform a check that the field element does not overflow the order. + /// + /// This method is primarily intended for defining internal constants. + #[allow(dead_code)] + pub(crate) const fn from_le_hex(hex: &str) -> Self { + Self::from_uint_unchecked(<$uint>::from_le_hex(hex)) + } + + /// Decode [` + #[doc = stringify!($fe)] + /// `] from [` + #[doc = stringify!($uint)] + /// `] converting it into Montgomery form. + /// + /// Does *not* perform a check that the field element does not overflow the order. + /// + /// Used incorrectly this can lead to invalid results! + pub(crate) const fn from_uint_unchecked(w: $uint) -> Self { + Self(<$uint>::from_uint_array($to_mont(w.as_uint_array()))) + } + + /// Returns the big-endian encoding of this [` + #[doc = stringify!($fe)] + /// `]. + pub fn to_be_bytes(self) -> $bytes { + use $crate::bigint::ArrayEncoding as _; + self.to_canonical().to_be_byte_array() + } + + /// Returns the little-endian encoding of this [` + #[doc = stringify!($fe)] + /// `]. + pub fn to_le_bytes(self) -> $bytes { + use $crate::bigint::ArrayEncoding as _; + self.to_canonical().to_le_byte_array() + } + + /// Translate [` + #[doc = stringify!($fe)] + /// `] out of the Montgomery domain, returning a [` + #[doc = stringify!($uint)] + /// `] in canonical form. + #[inline] + pub const fn to_canonical(self) -> $uint { + <$uint>::from_uint_array($from_mont(self.0.as_uint_array())) + } + + /// Determine if this [` + #[doc = stringify!($fe)] + /// `] is odd in the SEC1 sense: `self mod 2 == 1`. + /// + /// # Returns + /// + /// If odd, return `Choice(1)`. Otherwise, return `Choice(0)`. + pub fn is_odd(&self) -> Choice { + use $crate::bigint::Integer; + self.to_canonical().is_odd() + } + + /// Determine if this [` + #[doc = stringify!($fe)] + /// `] is even in the SEC1 sense: `self mod 2 == 0`. + /// + /// # Returns + /// + /// If even, return `Choice(1)`. Otherwise, return `Choice(0)`. + pub fn is_even(&self) -> Choice { + !self.is_odd() + } + + /// Determine if this [` + #[doc = stringify!($fe)] + /// `] is zero. + /// + /// # Returns + /// + /// If zero, return `Choice(1)`. Otherwise, return `Choice(0)`. + pub fn is_zero(&self) -> Choice { + self.ct_eq(&Self::ZERO) + } + + /// Add elements. + pub const fn add(&self, rhs: &Self) -> Self { + Self(<$uint>::from_uint_array($add( + self.0.as_uint_array(), + rhs.0.as_uint_array(), + ))) + } + + /// Double element (add it to itself). + #[must_use] + pub const fn double(&self) -> Self { + self.add(self) + } + + /// Subtract elements. + pub const fn sub(&self, rhs: &Self) -> Self { + Self(<$uint>::from_uint_array($sub( + self.0.as_uint_array(), + rhs.0.as_uint_array(), + ))) + } + + /// Multiply elements. + pub const fn mul(&self, rhs: &Self) -> Self { + Self(<$uint>::from_uint_array($mul( + self.0.as_uint_array(), + rhs.0.as_uint_array(), + ))) + } + + /// Negate element. + pub const fn neg(&self) -> Self { + Self(<$uint>::from_uint_array($neg(self.0.as_uint_array()))) + } + + /// Compute modular square. + #[must_use] + pub const fn square(&self) -> Self { + Self(<$uint>::from_uint_array($square(self.0.as_uint_array()))) + } + } + + impl AsRef<$arr> for $fe { + fn as_ref(&self) -> &$arr { + self.0.as_ref() + } + } + + impl Default for $fe { + fn default() -> Self { + Self::ZERO + } + } + + impl Eq for $fe {} + + impl PartialEq for $fe { + fn eq(&self, rhs: &Self) -> bool { + self.0.ct_eq(&(rhs.0)).into() + } + } + + impl $crate::subtle::ConditionallySelectable for $fe { + fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { + Self(<$uint>::conditional_select(&a.0, &b.0, choice)) + } + } + + impl $crate::subtle::ConstantTimeEq for $fe { + fn ct_eq(&self, other: &Self) -> $crate::subtle::Choice { + self.0.ct_eq(&other.0) + } + } + + impl $crate::subtle::ConstantTimeGreater for $fe { + fn ct_gt(&self, other: &Self) -> $crate::subtle::Choice { + self.0.ct_gt(&other.0) + } + } + + impl $crate::subtle::ConstantTimeLess for $fe { + fn ct_lt(&self, other: &Self) -> $crate::subtle::Choice { + self.0.ct_lt(&other.0) + } + } + + impl $crate::zeroize::DefaultIsZeroes for $fe {} + + impl $crate::ff::Field for $fe { + fn random(mut rng: impl $crate::rand_core::RngCore) -> Self { + // NOTE: can't use ScalarCore::random due to CryptoRng bound + let mut bytes = <$bytes>::default(); + + loop { + rng.fill_bytes(&mut bytes); + if let Some(fe) = Self::from_be_bytes(bytes).into() { + return fe; + } + } + } + + fn zero() -> Self { + Self::ZERO + } + + fn one() -> Self { + Self::ONE + } + + fn is_zero(&self) -> Choice { + Self::ZERO.ct_eq(self) + } + + #[must_use] + fn square(&self) -> Self { + self.square() + } + + #[must_use] + fn double(&self) -> Self { + self.double() + } + + fn invert(&self) -> CtOption { + self.invert() + } + + fn sqrt(&self) -> CtOption { + self.sqrt() + } + } + + $crate::impl_field_op!($fe, $uint, Add, add, $add); + $crate::impl_field_op!($fe, $uint, Sub, sub, $sub); + $crate::impl_field_op!($fe, $uint, Mul, mul, $mul); + + impl AddAssign<$fe> for $fe { + #[inline] + fn add_assign(&mut self, other: $fe) { + *self = *self + other; + } + } + + impl AddAssign<&$fe> for $fe { + #[inline] + fn add_assign(&mut self, other: &$fe) { + *self = *self + other; + } + } + + impl SubAssign<$fe> for $fe { + #[inline] + fn sub_assign(&mut self, other: $fe) { + *self = *self - other; + } + } + + impl SubAssign<&$fe> for $fe { + #[inline] + fn sub_assign(&mut self, other: &$fe) { + *self = *self - other; + } + } + + impl MulAssign<&$fe> for $fe { + #[inline] + fn mul_assign(&mut self, other: &$fe) { + *self = *self * other; + } + } + + impl MulAssign for $fe { + #[inline] + fn mul_assign(&mut self, other: $fe) { + *self = *self * other; + } + } + + impl Neg for $fe { + type Output = $fe; + + #[inline] + fn neg(self) -> $fe { + Self($neg(self.as_ref()).into()) + } + } + }; +} + +/// Emit impls for a `core::ops` trait for all combinations of reference types, +/// which thunk to the given function. +#[macro_export] +macro_rules! impl_field_op { + ($fe:tt, $uint:ty, $op:tt, $op_fn:ident, $func:ident) => { + impl ::core::ops::$op for $fe { + type Output = $fe; + + #[inline] + fn $op_fn(self, rhs: $fe) -> $fe { + $fe($func(self.as_ref(), rhs.as_ref()).into()) + } + } + + impl ::core::ops::$op<&$fe> for $fe { + type Output = $fe; + + #[inline] + fn $op_fn(self, rhs: &$fe) -> $fe { + $fe($func(self.as_ref(), rhs.as_ref()).into()) + } + } + + impl ::core::ops::$op<&$fe> for &$fe { + type Output = $fe; + + #[inline] + fn $op_fn(self, rhs: &$fe) -> $fe { + $fe($func(self.as_ref(), rhs.as_ref()).into()) + } + } + }; +} From ccdae97547507b18881ab3ff6d669bce8ec226af Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 12 Jun 2022 07:24:30 -0600 Subject: [PATCH 0797/1461] elliptic-curve: generic impl of complete prime order formulas (#1022) Adds a generic implementation of the complete addition formulas from Renes-Costello-Batina 2015[1] adapted from @str4d's original implementation for the `p256` crate: https://github.com/RustCrypto/elliptic-curves/pull/15 This implementation has been copied-and-pasted into the `p384` crate, hence the motivation to make it generic and extract it somewhere that it can be reused. The API exposed is fairly low-level, however it's difficult to better encapsulate it without making breaking changes to the `elliptic-curve` crate. Thus this PR opts to provide an initial low-level generic implementation with the goal of exploring removing more duplication with a higher-level API as followup work to be done at a time when breaking changes are permitted. [1]: https://eprint.iacr.org/2015/1060 --- elliptic-curve/src/lib.rs | 33 ++++---- elliptic-curve/src/weierstrass.rs | 128 ++++++++++++++++++++++++++++++ 2 files changed, 147 insertions(+), 14 deletions(-) create mode 100644 elliptic-curve/src/weierstrass.rs diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 93aafc9fd..62ac7856b 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -66,13 +66,30 @@ extern crate std; #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] pub use rand_core; +#[macro_use] +mod macros; + pub mod ops; +#[cfg(feature = "dev")] +#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] +pub mod dev; + +#[cfg(feature = "ecdh")] +#[cfg_attr(docsrs, doc(cfg(feature = "ecdh")))] +pub mod ecdh; + +#[cfg(feature = "hash2curve")] +#[cfg_attr(docsrs, doc(cfg(feature = "hash2curve")))] +pub mod hash2curve; + #[cfg(feature = "sec1")] +#[cfg_attr(docsrs, doc(cfg(feature = "sec1")))] pub mod sec1; -#[macro_use] -mod macros; +#[cfg(feature = "arithmetic")] +#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] +pub mod weierstrass; mod error; mod point; @@ -84,21 +101,9 @@ mod arithmetic; #[cfg(feature = "arithmetic")] mod public_key; -#[cfg(feature = "dev")] -#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] -pub mod dev; - -#[cfg(feature = "ecdh")] -#[cfg_attr(docsrs, doc(cfg(feature = "ecdh")))] -pub mod ecdh; - #[cfg(feature = "jwk")] mod jwk; -#[cfg(feature = "hash2curve")] -#[cfg_attr(docsrs, doc(cfg(feature = "hash2curve")))] -pub mod hash2curve; - pub use crate::{ error::{Error, Result}, point::{ diff --git a/elliptic-curve/src/weierstrass.rs b/elliptic-curve/src/weierstrass.rs new file mode 100644 index 000000000..1782d95e1 --- /dev/null +++ b/elliptic-curve/src/weierstrass.rs @@ -0,0 +1,128 @@ +//! Complete projective formulas for prime order elliptic curves as described +//! in [Renes-Costello-Batina 2015]. +//! +//! [Renes-Costello-Batina 2015]: https://eprint.iacr.org/2015/1060 + +#![allow(clippy::op_ref)] + +use ff::Field; + +/// Affine point whose coordinates are represented by the given field element. +pub type AffinePoint = (Fe, Fe); + +/// Projective point whose coordinates are represented by the given field element. +pub type ProjectivePoint = (Fe, Fe, Fe); + +/// Implements the complete addition formula from [Renes-Costello-Batina 2015] +/// (Algorithm 4). +/// +/// [Renes-Costello-Batina 2015]: https://eprint.iacr.org/2015/1060 +#[inline(always)] +pub fn add( + (ax, ay, az): ProjectivePoint, + (bx, by, bz): ProjectivePoint, + curve_equation_b: Fe, +) -> ProjectivePoint +where + Fe: Field, +{ + // The comments after each line indicate which algorithm steps are being + // performed. + let xx = ax * bx; // 1 + let yy = ay * by; // 2 + let zz = az * bz; // 3 + let xy_pairs = ((ax + ay) * &(bx + by)) - &(xx + &yy); // 4, 5, 6, 7, 8 + let yz_pairs = ((ay + az) * &(by + bz)) - &(yy + &zz); // 9, 10, 11, 12, 13 + let xz_pairs = ((ax + az) * &(bx + bz)) - &(xx + &zz); // 14, 15, 16, 17, 18 + + let bzz_part = xz_pairs - &(curve_equation_b * &zz); // 19, 20 + let bzz3_part = bzz_part.double() + &bzz_part; // 21, 22 + let yy_m_bzz3 = yy - &bzz3_part; // 23 + let yy_p_bzz3 = yy + &bzz3_part; // 24 + + let zz3 = zz.double() + &zz; // 26, 27 + let bxz_part = (curve_equation_b * &xz_pairs) - &(zz3 + &xx); // 25, 28, 29 + let bxz3_part = bxz_part.double() + &bxz_part; // 30, 31 + let xx3_m_zz3 = xx.double() + &xx - &zz3; // 32, 33, 34 + + ( + (yy_p_bzz3 * &xy_pairs) - &(yz_pairs * &bxz3_part), // 35, 39, 40 + (yy_p_bzz3 * &yy_m_bzz3) + &(xx3_m_zz3 * &bxz3_part), // 36, 37, 38 + (yy_m_bzz3 * &yz_pairs) + &(xy_pairs * &xx3_m_zz3), // 41, 42, 43 + ) +} + +/// Implements the complete mixed addition formula from +/// [Renes-Costello-Batina 2015] (Algorithm 5). +/// +/// [Renes-Costello-Batina 2015]: https://eprint.iacr.org/2015/1060 +#[inline(always)] +pub fn add_mixed( + (ax, ay, az): ProjectivePoint, + (bx, by): AffinePoint, + curve_equation_b: Fe, +) -> ProjectivePoint +where + Fe: Field, +{ + // The comments after each line indicate which algorithm steps are being + // performed. + let xx = ax * &bx; // 1 + let yy = ay * &by; // 2 + let xy_pairs = ((ax + &ay) * &(bx + &by)) - &(xx + &yy); // 3, 4, 5, 6, 7 + let yz_pairs = (by * &az) + &ay; // 8, 9 (t4) + let xz_pairs = (bx * &az) + &ax; // 10, 11 (y3) + + let bz_part = xz_pairs - &(curve_equation_b * &az); // 12, 13 + let bz3_part = bz_part.double() + &bz_part; // 14, 15 + let yy_m_bzz3 = yy - &bz3_part; // 16 + let yy_p_bzz3 = yy + &bz3_part; // 17 + + let z3 = az.double() + &az; // 19, 20 + let bxz_part = (curve_equation_b * &xz_pairs) - &(z3 + &xx); // 18, 21, 22 + let bxz3_part = bxz_part.double() + &bxz_part; // 23, 24 + let xx3_m_zz3 = xx.double() + &xx - &z3; // 25, 26, 27 + + ( + (yy_p_bzz3 * &xy_pairs) - &(yz_pairs * &bxz3_part), // 28, 32, 33 + (yy_p_bzz3 * &yy_m_bzz3) + &(xx3_m_zz3 * &bxz3_part), // 29, 30, 31 + (yy_m_bzz3 * &yz_pairs) + &(xy_pairs * &xx3_m_zz3), // 34, 35, 36 + ) +} + +/// Implements the exception-free point doubling formula from +/// [Renes-Costello-Batina 2015] (Algorithm 6). +/// +/// [Renes-Costello-Batina 2015]: https://eprint.iacr.org/2015/1060 +#[inline(always)] +pub fn double((x, y, z): ProjectivePoint, curve_equation_b: Fe) -> ProjectivePoint +where + Fe: Field, +{ + // The comments after each line indicate which algorithm steps are being + // performed. + let xx = x.square(); // 1 + let yy = y.square(); // 2 + let zz = z.square(); // 3 + let xy2 = (x * &y).double(); // 4, 5 + let xz2 = (x * &z).double(); // 6, 7 + + let bzz_part = (curve_equation_b * &zz) - &xz2; // 8, 9 + let bzz3_part = bzz_part.double() + &bzz_part; // 10, 11 + let yy_m_bzz3 = yy - &bzz3_part; // 12 + let yy_p_bzz3 = yy + &bzz3_part; // 13 + let y_frag = yy_p_bzz3 * &yy_m_bzz3; // 14 + let x_frag = yy_m_bzz3 * &xy2; // 15 + + let zz3 = zz.double() + &zz; // 16, 17 + let bxz2_part = (curve_equation_b * &xz2) - &(zz3 + &xx); // 18, 19, 20 + let bxz6_part = bxz2_part.double() + &bxz2_part; // 21, 22 + let xx3_m_zz3 = xx.double() + &xx - &zz3; // 23, 24, 25 + + let dy = y_frag + &(xx3_m_zz3 * &bxz6_part); // 26, 27 + let yz2 = (y * &z).double(); // 28, 29 + let dx = x_frag - &(bxz6_part * &yz2); // 30, 31 + let dz = (yz2 * &yy).double().double(); // 32, 33, 34 + + (dx, dy, dz) +} From c953409e7ce43c38d992fc5bf79a67e79adf6707 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 12 Jun 2022 08:46:33 -0600 Subject: [PATCH 0798/1461] elliptic-curve v0.12.1 (#1023) --- Cargo.lock | 4 ++-- elliptic-curve/CHANGELOG.md | 13 +++++++++++++ elliptic-curve/Cargo.toml | 2 +- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 20c8fb8ca..08334549b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -239,7 +239,7 @@ dependencies = [ "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "crypto-mac", "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", - "elliptic-curve 0.12.0", + "elliptic-curve 0.12.1", "password-hash", "signature 1.5.0", "universal-hash 0.4.1", @@ -406,7 +406,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.12.0" +version = "0.12.1" dependencies = [ "base16ct", "base64ct", diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index 450de8b4c..3bdbcf438 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,19 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.12.1 (2022-06-12) +### Added +- `impl_field_element!` macro ([#1021]) +- Generic impl of complete prime order formulas ([#1022]) + +### Changed +- Bump `crypto-bigint` to v0.4.4 ([#1018], [#1020]) + +[#1018]: https://github.com/RustCrypto/formats/pull/1018 +[#1020]: https://github.com/RustCrypto/formats/pull/1020 +[#1021]: https://github.com/RustCrypto/formats/pull/1021 +[#1022]: https://github.com/RustCrypto/formats/pull/1022 + ## 0.12.0 (2022-05-08) ### Added - `ecdh::SharedSecret::extract` HKDF helper ([#1007]) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 3420ecd35..a41d7df86 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.12.0" +version = "0.12.1" description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, From ca32a1131be11025bab9f3bbc0870c44642c7201 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Jun 2022 16:38:46 -0600 Subject: [PATCH 0799/1461] build(deps): bump crypto-bigint from 0.4.4 to 0.4.7 (#1025) Bumps [crypto-bigint](https://github.com/RustCrypto/crypto-bigint) from 0.4.4 to 0.4.7. - [Release notes](https://github.com/RustCrypto/crypto-bigint/releases) - [Changelog](https://github.com/RustCrypto/crypto-bigint/blob/master/CHANGELOG.md) - [Commits](https://github.com/RustCrypto/crypto-bigint/compare/v0.4.4...v0.4.7) --- updated-dependencies: - dependency-name: crypto-bigint dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 6 +++--- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 08334549b..5a4a32917 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -259,9 +259,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.4.4" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40997c4145fd5570180f579db9fcea452c91a2b72411da899efb1fb041136eae" +checksum = "ac961631d66e80ac7ac2ac01320628ce214ad2b5ef0a88ceb86eae459069e2b4" dependencies = [ "generic-array", "rand_core 0.6.3", @@ -410,7 +410,7 @@ version = "0.12.1" dependencies = [ "base16ct", "base64ct", - "crypto-bigint 0.4.4", + "crypto-bigint 0.4.7", "der 0.6.0", "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "ff 0.12.0", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index a41d7df86..8a2164b31 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -17,7 +17,7 @@ rust-version = "1.57" [dependencies] base16ct = "0.1.1" -crypto-bigint = { version = "0.4.4", default-features = false, features = ["rand_core", "generic-array", "zeroize"] } +crypto-bigint = { version = "0.4.7", default-features = false, features = ["rand_core", "generic-array", "zeroize"] } der = { version = "0.6", default-features = false, features = ["oid"] } generic-array = { version = "0.14", default-features = false } rand_core = { version = "0.6", default-features = false } From 831b5778893445145275429b83a860660a0eaff8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Jun 2022 16:17:48 -0600 Subject: [PATCH 0800/1461] build(deps): bump base64ct from 1.5.0 to 1.5.1 (#1030) Bumps [base64ct](https://github.com/RustCrypto/formats) from 1.5.0 to 1.5.1. - [Release notes](https://github.com/RustCrypto/formats/releases) - [Commits](https://github.com/RustCrypto/formats/compare/base64ct/v1.5.0...base64ct/v1.5.1) --- updated-dependencies: - dependency-name: base64ct dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5a4a32917..78d87944c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -80,9 +80,9 @@ checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" [[package]] name = "base64ct" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dea908e7347a8c64e378c17e30ef880ad73e3b4498346b055c2c00ea342f3179" +checksum = "3bdca834647821e0b13d9539a8634eb62d3501b6b6c2cec1722786ee6671b851" [[package]] name = "bincode" From a60e3dc04c8ffafb1ed4dcf4085a6494d87f7103 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 27 Jun 2022 18:07:31 -0600 Subject: [PATCH 0801/1461] password-hash: fix docs.rs metadata (#1031) --- password-hash/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index 2a1277f3d..423082802 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -29,5 +29,5 @@ alloc = ["base64ct/alloc"] std = ["alloc", "base64ct/std", "rand_core/std"] [package.metadata.docs.rs] -rustc-args = ["--cfg", "docsrs"] all-features = true +rustdoc-args = ["--cfg", "docsrs"] From fbd8291c624ae92211cb3866651fa3e5a83d46af Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 27 Jun 2022 18:34:51 -0600 Subject: [PATCH 0802/1461] password-hash v0.4.2 (#1032) --- Cargo.lock | 2 +- password-hash/CHANGELOG.md | 6 ++++++ password-hash/Cargo.toml | 2 +- password-hash/README.md | 4 +--- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 78d87944c..75c3a50ec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -700,7 +700,7 @@ dependencies = [ [[package]] name = "password-hash" -version = "0.4.1" +version = "0.4.2" dependencies = [ "base64ct", "rand_core 0.6.3", diff --git a/password-hash/CHANGELOG.md b/password-hash/CHANGELOG.md index 449c653b8..9328fce19 100644 --- a/password-hash/CHANGELOG.md +++ b/password-hash/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.4.2 (2022-06-27) +### Fixed +- docs.rs metadata ([#1031]) + +[#1031]: https://github.com/RustCrypto/traits/pull/1031 + ## 0.4.1 (2022-04-22) ### Added - `authentication` category to Cargo.toml ([#976]) diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index 423082802..0848f8be6 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -5,7 +5,7 @@ Traits which describe the functionality of password hashing algorithms, as well as a `no_std`-friendly implementation of the PHC string format (a well-defined subset of the Modular Crypt Format a.k.a. MCF) """ -version = "0.4.1" +version = "0.4.2" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/password-hash/README.md b/password-hash/README.md index 1367aed95..499cb44f4 100644 --- a/password-hash/README.md +++ b/password-hash/README.md @@ -2,7 +2,6 @@ [![crate][crate-image]][crate-link] [![Docs][docs-image]][docs-link] -[![Downloads][downloads-image]][crate-link] [![Build Status][build-image]][build-link] ![Apache2/MIT licensed][license-image] ![Rust Version][rustc-image] @@ -57,11 +56,10 @@ dual licensed as above, without any additional terms or conditions. [//]: # (badges) -[crate-image]: https://img.shields.io/crates/v/password-hash.svg?logo=rust +[crate-image]: https://buildstats.info/crate/password-hash [crate-link]: https://crates.io/crates/password-hash [docs-image]: https://docs.rs/password-hash/badge.svg [docs-link]: https://docs.rs/password-hash/ -[downloads-image]: https://img.shields.io/crates/d/password-hash.svg [build-image]: https://github.com/RustCrypto/traits/workflows/password-hash/badge.svg?branch=master&event=push [build-link]: https://github.com/RustCrypto/traits/actions?query=workflow:password-hash [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg From 6b0b6bd295c92a250844a4b54d9e836959af2f80 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 29 Jun 2022 13:28:28 -0600 Subject: [PATCH 0803/1461] crypto-common: add `getrandom` feature (#1034) Transitively enables `rand_core/getrandom`, making it possible to access `crypto_common::rand_core::OsRng`. --- crypto-common/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index 9e07b31b2..dd9be5bfe 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -19,6 +19,7 @@ typenum = "1.14" [features] std = [] +getrandom = ["rand_core/getrandom"] [package.metadata.docs.rs] all-features = true From ad1d6f96269e956f4d0d1928922bb06b1cc502f5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 29 Jun 2022 16:44:02 -0600 Subject: [PATCH 0804/1461] build(deps): bump zeroize from 1.5.5 to 1.5.6 (#1036) Bumps [zeroize](https://github.com/RustCrypto/utils) from 1.5.5 to 1.5.6. - [Release notes](https://github.com/RustCrypto/utils/releases) - [Commits](https://github.com/RustCrypto/utils/compare/zeroize-v1.5.5...zeroize-v1.5.6) --- updated-dependencies: - dependency-name: zeroize dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 75c3a50ec..c6f2890c8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1176,9 +1176,9 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.5.5" +version = "1.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94693807d016b2f2d2e14420eb3bfcca689311ff775dcf113d74ea624b7cdf07" +checksum = "20b578acffd8516a6c3f2a1bdefc1ec37e547bb4e0fb8b6b01a4cafc886b4442" dependencies = [ "zeroize_derive", ] From 5e1f26074efff8d81042bc798db0cf873a0c98f2 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 29 Jun 2022 18:39:32 -0600 Subject: [PATCH 0805/1461] Make Cargo.toml comments on optional dependencies consistent (#1035) This style is consistent with other crates in this repo (and elsewhere in the project), for example `cipher`. --- crypto-common/Cargo.toml | 5 +++-- digest/Cargo.toml | 1 + password-hash/Cargo.toml | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index dd9be5bfe..1f85b00c5 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -13,9 +13,10 @@ categories = ["cryptography", "no-std"] [dependencies] generic-array = { version = "0.14.4", features = ["more_lengths"] } +typenum = "1.14" # earlier versions of typenum don't satisfy the 'static bound on U* types + +# optional dependencies rand_core = { version = "0.6", optional = true } -# earlier versions of typenum don't satisfy the 'static bound on U* types -typenum = "1.14" [features] std = [] diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 65e00c582..94ff540e3 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -14,6 +14,7 @@ categories = ["cryptography", "no-std"] [dependencies] crypto-common = { version = "0.1.3", path = "../crypto-common" } +# optional dependencies block-buffer = { version = "0.10", optional = true } subtle = { version = "=2.4", default-features = false, optional = true } blobby = { version = "0.3", optional = true } diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index 0848f8be6..9a0cc299d 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -20,7 +20,7 @@ rust-version = "1.57" base64ct = "1" subtle = { version = "2", default-features = false } -# optional features +# optional dependencies rand_core = { version = "0.6", optional = true, default-features = false } [features] From 4c0821c236d029341f3304820c396dc63662f1d7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 29 Jun 2022 18:39:46 -0600 Subject: [PATCH 0806/1461] build(deps): bump serde_json from 1.0.81 to 1.0.82 (#1037) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.81 to 1.0.82. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.81...v1.0.82) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c6f2890c8..59b6ec8d5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -941,9 +941,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.81" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" +checksum = "82c2c1fdcd807d1098552c5b9a36e425e42e9fbd7c6a37a8425f390f781f7fa7" dependencies = [ "itoa", "ryu", From 8675be60763fad7bd841c6ca12cd0c596dcf1b25 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 1 Jul 2022 08:42:07 -0600 Subject: [PATCH 0807/1461] elliptic-curve: bump `crypto-bigint` to v0.4.8 (#1039) Fixes deprecation warnings --- Cargo.lock | 6 +++--- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/dev.rs | 4 ++-- elliptic-curve/src/macros.rs | 26 +++++++++++++------------- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 59b6ec8d5..6f0a091bd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -259,9 +259,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac961631d66e80ac7ac2ac01320628ce214ad2b5ef0a88ceb86eae459069e2b4" +checksum = "9f2b443d17d49dad5ef0ede301c3179cc923b8822f3393b4d2c28c269dd4a122" dependencies = [ "generic-array", "rand_core 0.6.3", @@ -410,7 +410,7 @@ version = "0.12.1" dependencies = [ "base16ct", "base64ct", - "crypto-bigint 0.4.7", + "crypto-bigint 0.4.8", "der 0.6.0", "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "ff 0.12.0", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 8a2164b31..a31d26fca 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -17,7 +17,7 @@ rust-version = "1.57" [dependencies] base16ct = "0.1.1" -crypto-bigint = { version = "0.4.7", default-features = false, features = ["rand_core", "generic-array", "zeroize"] } +crypto-bigint = { version = "0.4.8", default-features = false, features = ["rand_core", "generic-array", "zeroize"] } der = { version = "0.6", default-features = false, features = ["oid"] } generic-array = { version = "0.14", default-features = false } rand_core = { version = "0.6", default-features = false } diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 305508a6f..be0c156e5 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -186,11 +186,11 @@ impl PrimeFieldBits for Scalar { type ReprBits = [u64; 4]; fn to_le_bits(&self) -> ScalarBits { - self.0.as_uint().to_uint_array().into() + self.0.as_uint().to_words().into() } fn char_le_bits() -> ScalarBits { - MockCurve::ORDER.to_uint_array().into() + MockCurve::ORDER.to_words().into() } } diff --git a/elliptic-curve/src/macros.rs b/elliptic-curve/src/macros.rs index 6a0c8bbca..6ceadc833 100644 --- a/elliptic-curve/src/macros.rs +++ b/elliptic-curve/src/macros.rs @@ -153,7 +153,7 @@ macro_rules! impl_field_element { /// /// Used incorrectly this can lead to invalid results! pub(crate) const fn from_uint_unchecked(w: $uint) -> Self { - Self(<$uint>::from_uint_array($to_mont(w.as_uint_array()))) + Self(<$uint>::from_words($to_mont(w.as_words()))) } /// Returns the big-endian encoding of this [` @@ -179,7 +179,7 @@ macro_rules! impl_field_element { /// `] in canonical form. #[inline] pub const fn to_canonical(self) -> $uint { - <$uint>::from_uint_array($from_mont(self.0.as_uint_array())) + <$uint>::from_words($from_mont(self.0.as_words())) } /// Determine if this [` @@ -218,9 +218,9 @@ macro_rules! impl_field_element { /// Add elements. pub const fn add(&self, rhs: &Self) -> Self { - Self(<$uint>::from_uint_array($add( - self.0.as_uint_array(), - rhs.0.as_uint_array(), + Self(<$uint>::from_words($add( + self.0.as_words(), + rhs.0.as_words(), ))) } @@ -232,29 +232,29 @@ macro_rules! impl_field_element { /// Subtract elements. pub const fn sub(&self, rhs: &Self) -> Self { - Self(<$uint>::from_uint_array($sub( - self.0.as_uint_array(), - rhs.0.as_uint_array(), + Self(<$uint>::from_words($sub( + self.0.as_words(), + rhs.0.as_words(), ))) } /// Multiply elements. pub const fn mul(&self, rhs: &Self) -> Self { - Self(<$uint>::from_uint_array($mul( - self.0.as_uint_array(), - rhs.0.as_uint_array(), + Self(<$uint>::from_words($mul( + self.0.as_words(), + rhs.0.as_words(), ))) } /// Negate element. pub const fn neg(&self) -> Self { - Self(<$uint>::from_uint_array($neg(self.0.as_uint_array()))) + Self(<$uint>::from_words($neg(self.0.as_words()))) } /// Compute modular square. #[must_use] pub const fn square(&self) -> Self { - Self(<$uint>::from_uint_array($square(self.0.as_uint_array()))) + Self(<$uint>::from_words($square(self.0.as_words()))) } } From e51e94c4c52833a5e8a6758e28c18995e3f7bf9e Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 1 Jul 2022 09:05:44 -0600 Subject: [PATCH 0808/1461] elliptic-curve v0.12.2 (#1040) --- Cargo.lock | 4 ++-- elliptic-curve/CHANGELOG.md | 40 +++++++++++++++++++++---------------- elliptic-curve/Cargo.toml | 2 +- 3 files changed, 26 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6f0a091bd..2ac425808 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -239,7 +239,7 @@ dependencies = [ "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "crypto-mac", "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", - "elliptic-curve 0.12.1", + "elliptic-curve 0.12.2", "password-hash", "signature 1.5.0", "universal-hash 0.4.1", @@ -406,7 +406,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.12.1" +version = "0.12.2" dependencies = [ "base16ct", "base64ct", diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index 3bdbcf438..4e55c0927 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.12.2 (2022-07-01) +### Changed +- Bump `crypto-bigint` to v0.4.8 ([#1039]) + +[#1039]: https://github.com/RustCrypto/traits/pull/1039 + ## 0.12.1 (2022-06-12) ### Added - `impl_field_element!` macro ([#1021]) @@ -12,10 +18,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Bump `crypto-bigint` to v0.4.4 ([#1018], [#1020]) -[#1018]: https://github.com/RustCrypto/formats/pull/1018 -[#1020]: https://github.com/RustCrypto/formats/pull/1020 -[#1021]: https://github.com/RustCrypto/formats/pull/1021 -[#1022]: https://github.com/RustCrypto/formats/pull/1022 +[#1018]: https://github.com/RustCrypto/traits/pull/1018 +[#1020]: https://github.com/RustCrypto/traits/pull/1020 +[#1021]: https://github.com/RustCrypto/traits/pull/1021 +[#1022]: https://github.com/RustCrypto/traits/pull/1022 ## 0.12.0 (2022-05-08) ### Added @@ -38,19 +44,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Removed - `Zeroize` impl from `ecdh::SharedSecret` ([#978]) -[#883]: https://github.com/RustCrypto/formats/pull/883 -[#894]: https://github.com/RustCrypto/formats/pull/894 -[#895]: https://github.com/RustCrypto/formats/pull/895 -[#903]: https://github.com/RustCrypto/formats/pull/903 -[#904]: https://github.com/RustCrypto/formats/pull/904 -[#978]: https://github.com/RustCrypto/formats/pull/978 -[#994]: https://github.com/RustCrypto/formats/pull/994 -[#996]: https://github.com/RustCrypto/formats/pull/996 -[#1001]: https://github.com/RustCrypto/formats/pull/1001 -[#1005]: https://github.com/RustCrypto/formats/pull/1005 -[#1006]: https://github.com/RustCrypto/formats/pull/1006 -[#1007]: https://github.com/RustCrypto/formats/pull/1007 -[#1009]: https://github.com/RustCrypto/formats/pull/1009 +[#883]: https://github.com/RustCrypto/traits/pull/883 +[#894]: https://github.com/RustCrypto/traits/pull/894 +[#895]: https://github.com/RustCrypto/traits/pull/895 +[#903]: https://github.com/RustCrypto/traits/pull/903 +[#904]: https://github.com/RustCrypto/traits/pull/904 +[#978]: https://github.com/RustCrypto/traits/pull/978 +[#994]: https://github.com/RustCrypto/traits/pull/994 +[#996]: https://github.com/RustCrypto/traits/pull/996 +[#1001]: https://github.com/RustCrypto/traits/pull/1001 +[#1005]: https://github.com/RustCrypto/traits/pull/1005 +[#1006]: https://github.com/RustCrypto/traits/pull/1006 +[#1007]: https://github.com/RustCrypto/traits/pull/1007 +[#1009]: https://github.com/RustCrypto/traits/pull/1009 ## 0.11.12 (2022-01-30) ### Changed diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index a31d26fca..dca4b3bba 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.12.1" +version = "0.12.2" description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, From 106df27c3cbf9524dffbb0be58ac050d49fc6084 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 1 Jul 2022 17:15:17 -0600 Subject: [PATCH 0809/1461] aead: use `crypto-common` (#1033) Replaces the `NewAead` trait with the same-shaped `KeyInit` trait. --- Cargo.lock | 22 +++++++++++----------- aead/Cargo.toml | 8 +++++--- aead/src/lib.rs | 45 +++------------------------------------------ aead/src/stream.rs | 8 ++++---- crypto/Cargo.toml | 2 +- 5 files changed, 24 insertions(+), 61 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2ac425808..63aa6add7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5,21 +5,21 @@ version = 3 [[package]] name = "aead" version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" dependencies = [ - "blobby", - "bytes", "generic-array", - "heapless", - "rand_core 0.6.3", ] [[package]] name = "aead" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" +version = "0.5.0-pre" dependencies = [ + "blobby", + "bytes", + "crypto-common 0.1.3", "generic-array", + "heapless", ] [[package]] @@ -39,7 +39,7 @@ version = "0.10.0-pre" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8004e8b23ff2c65e28ff77bab0eccd36f4a6c2c8e0b55c46acba481425cc3a4f" dependencies = [ - "aead 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "aead 0.4.3", "aes", "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "ctr", @@ -182,7 +182,7 @@ version = "0.10.0-pre" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "746c430f71e66469abcf493c11484b1a86b957c84fc2d0ba664cd12ac23679ea" dependencies = [ - "aead 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "aead 0.4.3", "chacha20", "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "poly1305", @@ -235,7 +235,7 @@ dependencies = [ name = "crypto" version = "0.4.0-pre" dependencies = [ - "aead 0.4.3", + "aead 0.5.0-pre", "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "crypto-mac", "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -604,7 +604,7 @@ name = "hpke" version = "0.9.0" source = "git+https://github.com/rozbb/rust-hpke?rev=9230db267819f5795a47510139f4f1a60688ce82#9230db267819f5795a47510139f4f1a60688ce82" dependencies = [ - "aead 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "aead 0.4.3", "aes-gcm", "byteorder", "chacha20poly1305", diff --git a/aead/Cargo.toml b/aead/Cargo.toml index fda7f826b..da10b1506 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aead" -version = "0.4.3" # Also update html_root_url in lib.rs when bumping this +version = "0.5.0-pre" # Also update html_root_url in lib.rs when bumping this description = """ Traits for Authenticated Encryption with Associated Data (AEAD) algorithms, such as AES-GCM as ChaCha20Poly1305, which provide a high-level API @@ -15,18 +15,20 @@ keywords = ["crypto", "encryption"] categories = ["cryptography", "no-std"] [dependencies] +crypto-common = { version = "0.1", path = "../crypto-common" } generic-array = { version = "0.14", default-features = false } # optional dependencies blobby = { version = "0.3", optional = true } bytes = { version = "1", optional = true, default-features = false } heapless = { version = "0.7", optional = true, default-features = false } -rand_core = { version = "0.6", optional = true } [features] +default = ["rand_core"] alloc = [] -std = ["alloc", "rand_core/std"] +std = ["alloc", "crypto-common/std"] dev = ["blobby"] +rand_core = ["crypto-common/rand_core"] stream = [] [package.metadata.docs.rs] diff --git a/aead/src/lib.rs b/aead/src/lib.rs index 404259ce9..f0148f9c4 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -18,8 +18,7 @@ #![forbid(unsafe_code, clippy::unwrap_used)] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/aead/0.4.3" + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg" )] #![warn(missing_docs, rust_2018_idioms)] @@ -37,6 +36,7 @@ pub mod dev; #[cfg_attr(docsrs, doc(cfg(feature = "stream")))] pub mod stream; +pub use crypto_common::{Key, KeyInit, KeySizeUser}; pub use generic_array::{self, typenum::consts}; #[cfg(feature = "bytes")] @@ -49,7 +49,7 @@ pub use heapless; #[cfg(feature = "rand_core")] #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] -pub use rand_core; +pub use crypto_common::rand_core; use core::fmt; use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; @@ -60,9 +60,6 @@ use alloc::vec::Vec; #[cfg(feature = "bytes")] use bytes::BytesMut; -#[cfg(feature = "rand_core")] -use rand_core::{CryptoRng, RngCore}; - /// Error type. /// /// This type is deliberately opaque as to avoid potential side-channel @@ -82,48 +79,12 @@ impl fmt::Display for Error { #[cfg(feature = "std")] impl std::error::Error for Error {} -/// Key for a [`NewAead`] algorithm -// TODO(tarcieri): make this a struct and zeroize on drop? -pub type Key = GenericArray::KeySize>; - /// Nonce: single-use value for ensuring ciphertexts are unique pub type Nonce = GenericArray::NonceSize>; /// Tag: authentication code which ensures ciphertexts are authentic pub type Tag = GenericArray::TagSize>; -/// Instantiate either a stateless [`Aead`] or stateful [`AeadMut`] algorithm. -pub trait NewAead { - /// The size of the key array required by this algorithm. - type KeySize: ArrayLength; - - /// Create a new AEAD instance with the given key. - fn new(key: &Key) -> Self; - - /// Create new AEAD instance from key given as a byte slice.. - /// - /// Default implementation will accept only keys with length equal to `KeySize`. - fn new_from_slice(key: &[u8]) -> Result - where - Self: Sized, - { - if key.len() != Self::KeySize::to_usize() { - Err(Error) - } else { - Ok(Self::new(GenericArray::from_slice(key))) - } - } - - /// Generate a random key for this AEAD using the provided [`CryptoRng`]. - #[cfg(feature = "rand_core")] - #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] - fn generate_key(mut rng: impl CryptoRng + RngCore) -> Key { - let mut key = Key::::default(); - rng.fill_bytes(&mut key); - key - } -} - /// Authenticated Encryption with Associated Data (AEAD) algorithm core trait. /// /// Defines nonce, tag, and overhead sizes that are consumed by various other diff --git a/aead/src/stream.rs b/aead/src/stream.rs index d3ccf113a..6b38d43fd 100644 --- a/aead/src/stream.rs +++ b/aead/src/stream.rs @@ -32,7 +32,7 @@ #![allow(clippy::upper_case_acronyms)] -use crate::{AeadCore, AeadInPlace, Buffer, Error, Key, NewAead, Result}; +use crate::{AeadCore, AeadInPlace, Buffer, Error, Key, KeyInit, Result}; use core::ops::{AddAssign, Sub}; use generic_array::{ typenum::{Unsigned, U4, U5}, @@ -76,7 +76,7 @@ where /// Create a new STREAM with the given key and nonce. fn new(key: &Key, nonce: &Nonce) -> Self where - A: NewAead, + A: KeyInit, Self: Sized, { Self::from_aead(A::new(key), nonce) @@ -227,7 +227,7 @@ macro_rules! impl_stream_object { #[doc = "object from the given AEAD key and nonce."] pub fn new(key: &Key, nonce: &Nonce) -> Self where - A: NewAead, + A: KeyInit, S: NewStream, { Self::from_stream_primitive(S::new(key, nonce)) @@ -238,7 +238,7 @@ macro_rules! impl_stream_object { #[doc = "object from the given AEAD primitive."] pub fn from_aead(aead: A, nonce: &Nonce) -> Self where - A: NewAead, + A: KeyInit, S: NewStream, { Self::from_stream_primitive(S::from_aead(aead, nonce)) diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 61a94e840..fb17f9b10 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -15,7 +15,7 @@ edition = "2021" rust-version = "1.57" [dependencies] -aead = { version = "0.4", optional = true, path = "../aead" } +aead = { version = "=0.5.0-pre", optional = true, path = "../aead" } cipher = { version = "0.4", optional = true } digest = { version = "0.10", optional = true } elliptic-curve = { version = "0.12", optional = true, path = "../elliptic-curve" } From 45e827d0bedbc58d027921d3b4ec935b9d536658 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 2 Jul 2022 13:11:40 -0600 Subject: [PATCH 0810/1461] crypto-common v0.1.4 (#1041) --- Cargo.lock | 18 +++++++++--------- crypto-common/CHANGELOG.md | 6 ++++++ crypto-common/Cargo.toml | 2 +- crypto-common/src/lib.rs | 3 +-- 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 63aa6add7..f3396a4f1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,7 +17,7 @@ version = "0.5.0-pre" dependencies = [ "blobby", "bytes", - "crypto-common 0.1.3", + "crypto-common 0.1.4", "generic-array", "heapless", ] @@ -194,7 +194,7 @@ name = "cipher" version = "0.4.3" dependencies = [ "blobby", - "crypto-common 0.1.3", + "crypto-common 0.1.4", "inout", "zeroize", ] @@ -205,7 +205,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d1873270f8f7942c191139cb8a40fd228da6c3fd2fc376d7e92d47aa14aeb59e" dependencies = [ - "crypto-common 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.1.3", "inout", "zeroize", ] @@ -272,19 +272,19 @@ dependencies = [ [[package]] name = "crypto-common" version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8" dependencies = [ "generic-array", - "rand_core 0.6.3", "typenum", ] [[package]] name = "crypto-common" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8" +version = "0.1.4" dependencies = [ "generic-array", + "rand_core 0.6.3", "typenum", ] @@ -355,7 +355,7 @@ version = "0.10.3" dependencies = [ "blobby", "block-buffer 0.10.2", - "crypto-common 0.1.3", + "crypto-common 0.1.4", "subtle", ] @@ -366,7 +366,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" dependencies = [ "block-buffer 0.10.2", - "crypto-common 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.1.3", "subtle", ] diff --git a/crypto-common/CHANGELOG.md b/crypto-common/CHANGELOG.md index ebd278695..6650c9d4f 100644 --- a/crypto-common/CHANGELOG.md +++ b/crypto-common/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.1.4 (2022-07-02) +### Added +- `getrandom` feature ([#1034]) + +[#1034]: https://github.com/RustCrypto/traits/pull/1034 + ## 0.1.3 (2022-02-16) ### Fixed - Minimal versions build ([#940]) diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index 1f85b00c5..9a716ef44 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crypto-common" description = "Common cryptographic traits" -version = "0.1.3" # Also update html_root_url in lib.rs when bumping this +version = "0.1.4" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/crypto-common/src/lib.rs b/crypto-common/src/lib.rs index 187b1ac42..15c01c2dd 100644 --- a/crypto-common/src/lib.rs +++ b/crypto-common/src/lib.rs @@ -4,8 +4,7 @@ #![cfg_attr(docsrs, feature(doc_cfg))] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", - html_root_url = "https://docs.rs/crypto-common/0.1.3" + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg" )] #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] From 8aa52b109a82060076f506db7e15fdc7e8c154c7 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 2 Jul 2022 13:26:13 -0600 Subject: [PATCH 0811/1461] aead: `getrandom` eature (#1042) Adds a `getrandom` feature which activates `crypto-common/getrandom` and makes it simple to access `OsRng` without importing an additional dependency. --- aead/Cargo.toml | 3 ++- aead/src/lib.rs | 10 ++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/aead/Cargo.toml b/aead/Cargo.toml index da10b1506..cadd524c4 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -15,7 +15,7 @@ keywords = ["crypto", "encryption"] categories = ["cryptography", "no-std"] [dependencies] -crypto-common = { version = "0.1", path = "../crypto-common" } +crypto-common = { version = "0.1.4", path = "../crypto-common" } generic-array = { version = "0.14", default-features = false } # optional dependencies @@ -28,6 +28,7 @@ default = ["rand_core"] alloc = [] std = ["alloc", "crypto-common/std"] dev = ["blobby"] +getrandom = ["crypto-common/getrandom", "rand_core"] rand_core = ["crypto-common/rand_core"] stream = [] diff --git a/aead/src/lib.rs b/aead/src/lib.rs index f0148f9c4..ba5d67329 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -43,6 +43,10 @@ pub use generic_array::{self, typenum::consts}; #[cfg_attr(docsrs, doc(cfg(feature = "bytes")))] pub use bytes; +#[cfg(feature = "getrandom")] +#[cfg_attr(docsrs, doc(cfg(feature = "getrandom")))] +pub use crypto_common::rand_core::OsRng; + #[cfg(feature = "heapless")] #[cfg_attr(docsrs, doc(cfg(feature = "heapless")))] pub use heapless; @@ -414,8 +418,10 @@ impl AeadMutInPlace for Alg { } } -/// AEAD payloads are a combination of a message (plaintext or ciphertext) -/// and "additional associated data" (AAD) to be authenticated (in cleartext) +/// AEAD payloads (message + AAD). +/// +/// Combination of a message (plaintext or ciphertext) and +/// "additional associated data" (AAD) to be authenticated (in cleartext) /// along with the message. /// /// If you don't care about AAD, you can pass a `&[u8]` as the payload to From 7ffdfa7a0d4546d2806aca159a51a083dc15b915 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 2 Jul 2022 13:37:24 -0600 Subject: [PATCH 0812/1461] aead v0.5.0-pre.1 (#1043) --- Cargo.lock | 4 ++-- aead/Cargo.toml | 2 +- crypto/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f3396a4f1..e36a2bdf2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,7 +13,7 @@ dependencies = [ [[package]] name = "aead" -version = "0.5.0-pre" +version = "0.5.0-pre.1" dependencies = [ "blobby", "bytes", @@ -235,7 +235,7 @@ dependencies = [ name = "crypto" version = "0.4.0-pre" dependencies = [ - "aead 0.5.0-pre", + "aead 0.5.0-pre.1", "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "crypto-mac", "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/aead/Cargo.toml b/aead/Cargo.toml index cadd524c4..8b721ad32 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aead" -version = "0.5.0-pre" # Also update html_root_url in lib.rs when bumping this +version = "0.5.0-pre.1" # Also update html_root_url in lib.rs when bumping this description = """ Traits for Authenticated Encryption with Associated Data (AEAD) algorithms, such as AES-GCM as ChaCha20Poly1305, which provide a high-level API diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index fb17f9b10..89babe818 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -15,7 +15,7 @@ edition = "2021" rust-version = "1.57" [dependencies] -aead = { version = "=0.5.0-pre", optional = true, path = "../aead" } +aead = { version = "=0.5.0-pre.1", optional = true, path = "../aead" } cipher = { version = "0.4", optional = true } digest = { version = "0.10", optional = true } elliptic-curve = { version = "0.12", optional = true, path = "../elliptic-curve" } From e37ad0172cfdc1d17344a4cdd7ace616294e1dd9 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 2 Jul 2022 14:22:06 -0600 Subject: [PATCH 0813/1461] aead: Rust 2021 edition upgrade; MSRV 1.56+ (#1044) --- .github/workflows/aead.yml | 34 +++++----------------------------- aead/Cargo.toml | 3 ++- aead/README.md | 4 ++-- aead/src/dev.rs | 9 +++++---- 4 files changed, 14 insertions(+), 36 deletions(-) diff --git a/.github/workflows/aead.yml b/.github/workflows/aead.yml index b9d068325..45c8b0076 100644 --- a/.github/workflows/aead.yml +++ b/.github/workflows/aead.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.41.0 # MSRV + - 1.56.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -36,11 +36,11 @@ jobs: toolchain: ${{ matrix.rust }} target: ${{ matrix.target }} override: true - # Isolate this crate from workspace which is otherwise MSRV 1.56 due to 2021 edition crates - - run: rm ../Cargo.toml + - run: cargo check --all-features - run: cargo build --target ${{ matrix.target }} --release --no-default-features - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features bytes + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features heapless - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features rand_core - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features stream @@ -49,34 +49,12 @@ jobs: with: working-directory: ${{ github.workflow }} - heapless: - runs-on: ubuntu-latest - strategy: - matrix: - rust: - - 1.51.0 # MSRV for `heapless` - - stable - target: - - thumbv7em-none-eabi - - wasm32-unknown-unknown - steps: - - uses: actions/checkout@v2 - - uses: RustCrypto/actions/cargo-cache@master - - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: ${{ matrix.rust }} - target: ${{ matrix.target }} - override: true - - run: cargo check --all-features - - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features heapless - test: runs-on: ubuntu-latest strategy: matrix: rust: - - 1.41.0 # MSRV + - 1.56.0 # MSRV - stable steps: - uses: actions/checkout@v2 @@ -86,8 +64,6 @@ jobs: toolchain: ${{ matrix.rust }} override: true profile: minimal - # Isolate this crate from workspace which is otherwise MSRV 1.56 due to 2021 edition crates - - run: rm ../Cargo.toml - run: cargo test --release --no-default-features - run: cargo test --release - - run: cargo test --release --features dev,rand_core,stream,std + - run: cargo test --release --all-features diff --git a/aead/Cargo.toml b/aead/Cargo.toml index 8b721ad32..0842a78aa 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -6,13 +6,14 @@ Traits for Authenticated Encryption with Associated Data (AEAD) algorithms, such as AES-GCM as ChaCha20Poly1305, which provide a high-level API """ authors = ["RustCrypto Developers"] -edition = "2018" +edition = "2021" license = "MIT OR Apache-2.0" readme = "README.md" documentation = "https://docs.rs/aead" repository = "https://github.com/RustCrypto/traits" keywords = ["crypto", "encryption"] categories = ["cryptography", "no-std"] +rust-version = "1.56" [dependencies] crypto-common = { version = "0.1.4", path = "../crypto-common" } diff --git a/aead/README.md b/aead/README.md index 8bc2a7a12..ff1a580a2 100644 --- a/aead/README.md +++ b/aead/README.md @@ -19,7 +19,7 @@ See [RustCrypto/AEADs] for cipher implementations which use this trait. ## Minimum Supported Rust Version -Rust **1.41** or higher. +Rust **1.56** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -51,7 +51,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/aead/badge.svg [docs-link]: https://docs.rs/aead/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.56+-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/traits/workflows/aead/badge.svg?branch=master&event=push diff --git a/aead/src/dev.rs b/aead/src/dev.rs index cfd531267..a5795c9be 100644 --- a/aead/src/dev.rs +++ b/aead/src/dev.rs @@ -8,10 +8,11 @@ macro_rules! new_test { ($name:ident, $test_name:expr, $cipher:ty $(,)?) => { #[test] fn $name() { - use aead::dev::blobby::Blob6Iterator; - use aead::generic_array::typenum::Unsigned; - use aead::{generic_array::GenericArray, Aead, NewAead, Payload}; - use core::convert::TryInto; + use aead::{ + dev::blobby::Blob6Iterator, + generic_array::{typenum::Unsigned, GenericArray}, + Aead, NewAead, Payload, + }; fn run_test( key: &[u8], From d34c61d10b513b48072042901e427526d925e721 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 2 Jul 2022 14:41:07 -0600 Subject: [PATCH 0814/1461] aead: fix `new_test!` macro (#1045) It was referencing the now-removed `NewAead` trait --- aead/src/dev.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aead/src/dev.rs b/aead/src/dev.rs index a5795c9be..a0fc7db2f 100644 --- a/aead/src/dev.rs +++ b/aead/src/dev.rs @@ -11,7 +11,7 @@ macro_rules! new_test { use aead::{ dev::blobby::Blob6Iterator, generic_array::{typenum::Unsigned, GenericArray}, - Aead, NewAead, Payload, + Aead, KeyInit, Payload, }; fn run_test( From cbaec6013837f488eab56d24661b6efc006238d5 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 2 Jul 2022 15:13:49 -0600 Subject: [PATCH 0815/1461] aead v0.5.0-pre.2 (#1046) --- Cargo.lock | 4 ++-- aead/Cargo.toml | 2 +- crypto/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e36a2bdf2..8759615cf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,7 +13,7 @@ dependencies = [ [[package]] name = "aead" -version = "0.5.0-pre.1" +version = "0.5.0-pre.2" dependencies = [ "blobby", "bytes", @@ -235,7 +235,7 @@ dependencies = [ name = "crypto" version = "0.4.0-pre" dependencies = [ - "aead 0.5.0-pre.1", + "aead 0.5.0-pre.2", "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "crypto-mac", "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/aead/Cargo.toml b/aead/Cargo.toml index 0842a78aa..574c8a144 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aead" -version = "0.5.0-pre.1" # Also update html_root_url in lib.rs when bumping this +version = "0.5.0-pre.2" # Also update html_root_url in lib.rs when bumping this description = """ Traits for Authenticated Encryption with Associated Data (AEAD) algorithms, such as AES-GCM as ChaCha20Poly1305, which provide a high-level API diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 89babe818..ec4fbd3ba 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -15,7 +15,7 @@ edition = "2021" rust-version = "1.57" [dependencies] -aead = { version = "=0.5.0-pre.1", optional = true, path = "../aead" } +aead = { version = "=0.5.0-pre.2", optional = true, path = "../aead" } cipher = { version = "0.4", optional = true } digest = { version = "0.10", optional = true } elliptic-curve = { version = "0.12", optional = true, path = "../elliptic-curve" } From ea33e3206ba9b71d741f75f03a94ec09aae32693 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 9 Jul 2022 10:26:21 -0600 Subject: [PATCH 0816/1461] crypto-common v0.1.5 (#1049) --- Cargo.lock | 8 ++++---- crypto-common/CHANGELOG.md | 6 ++++++ crypto-common/Cargo.toml | 2 +- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8759615cf..23554168e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,7 +17,7 @@ version = "0.5.0-pre.2" dependencies = [ "blobby", "bytes", - "crypto-common 0.1.4", + "crypto-common 0.1.5", "generic-array", "heapless", ] @@ -194,7 +194,7 @@ name = "cipher" version = "0.4.3" dependencies = [ "blobby", - "crypto-common 0.1.4", + "crypto-common 0.1.5", "inout", "zeroize", ] @@ -281,7 +281,7 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.1.4" +version = "0.1.5" dependencies = [ "generic-array", "rand_core 0.6.3", @@ -355,7 +355,7 @@ version = "0.10.3" dependencies = [ "blobby", "block-buffer 0.10.2", - "crypto-common 0.1.4", + "crypto-common 0.1.5", "subtle", ] diff --git a/crypto-common/CHANGELOG.md b/crypto-common/CHANGELOG.md index 6650c9d4f..7a052c5fb 100644 --- a/crypto-common/CHANGELOG.md +++ b/crypto-common/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.1.5 (2022-07-09) +### Fixed +- Support on-label MSRV ([#1049]) + +[#1049]: https://github.com/RustCrypto/traits/pull/1049 + ## 0.1.4 (2022-07-02) ### Added - `getrandom` feature ([#1034]) diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index 9a716ef44..c27d8e253 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crypto-common" description = "Common cryptographic traits" -version = "0.1.4" +version = "0.1.5" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" From 74db58175466681f005834403ba543c1db7cc127 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 16 Jul 2022 15:48:09 -0600 Subject: [PATCH 0817/1461] crypto-common: move `ParBlocks*` from `cipher` crate (#1052) Moves `ParBlocks`/`ParBlocksSizeUser` from the `cipher` crate so it can be reused in the `universal-hash` crate (see #965, #1051). The `cipher` crate re-exports them in an API-compatible way, so this is not a breaking change. --- cipher/src/lib.rs | 12 +----------- crypto-common/src/lib.rs | 12 ++++++++++++ 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/cipher/src/lib.rs b/cipher/src/lib.rs index c97ae4368..59b0d75d2 100644 --- a/cipher/src/lib.rs +++ b/cipher/src/lib.rs @@ -51,21 +51,11 @@ pub use crypto_common::{ generic_array, typenum::{self, consts}, AlgorithmName, Block, InnerIvInit, InvalidLength, Iv, IvSizeUser, Key, KeyInit, KeyIvInit, - KeySizeUser, + KeySizeUser, ParBlocks, ParBlocksSizeUser, }; -use generic_array::{ArrayLength, GenericArray}; /// Trait for loading current IV state. pub trait IvState: IvSizeUser { /// Returns current IV state. fn iv_state(&self) -> Iv; } - -/// Types which process blocks in parallel. -pub trait ParBlocksSizeUser: BlockSizeUser { - /// Number of blocks which can be processed in parallel. - type ParBlocksSize: ArrayLength>; -} - -/// Parallel blocks on which [`ParBlocksSizeUser`] implementors operate. -pub type ParBlocks = GenericArray, ::ParBlocksSize>; diff --git a/crypto-common/src/lib.rs b/crypto-common/src/lib.rs index 15c01c2dd..c49984cd2 100644 --- a/crypto-common/src/lib.rs +++ b/crypto-common/src/lib.rs @@ -25,10 +25,16 @@ use rand_core::{CryptoRng, RngCore}; /// Block on which [`BlockSizeUser`] implementors operate. pub type Block = GenericArray::BlockSize>; + +/// Parallel blocks on which [`ParBlocksSizeUser`] implementors operate. +pub type ParBlocks = GenericArray, ::ParBlocksSize>; + /// Output array of [`OutputSizeUser`] implementors. pub type Output = GenericArray::OutputSize>; + /// Key used by [`KeySizeUser`] implementors. pub type Key = GenericArray::KeySize>; + /// Initialization vector (nonce) used by [`IvSizeUser`] implementors. pub type Iv = GenericArray::IvSize>; @@ -51,6 +57,12 @@ impl BlockSizeUser for &mut T { type BlockSize = T::BlockSize; } +/// Types which can process blocks in parallel. +pub trait ParBlocksSizeUser: BlockSizeUser { + /// Number of blocks which can be processed in parallel. + type ParBlocksSize: ArrayLength>; +} + /// Types which return data with the given size. pub trait OutputSizeUser { /// Size of the output in bytes. From 25614e2d5a4ccbb0cfde23367a93c8bcdbfe421a Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 16 Jul 2022 15:59:31 -0600 Subject: [PATCH 0818/1461] crypto-common v0.1.6 (#1053) --- Cargo.lock | 8 ++++---- cipher/CHANGELOG.md | 6 ++++++ cipher/Cargo.toml | 2 +- crypto-common/CHANGELOG.md | 6 ++++++ crypto-common/Cargo.toml | 2 +- 5 files changed, 18 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 23554168e..7b6fa4663 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,7 +17,7 @@ version = "0.5.0-pre.2" dependencies = [ "blobby", "bytes", - "crypto-common 0.1.5", + "crypto-common 0.1.6", "generic-array", "heapless", ] @@ -194,7 +194,7 @@ name = "cipher" version = "0.4.3" dependencies = [ "blobby", - "crypto-common 0.1.5", + "crypto-common 0.1.6", "inout", "zeroize", ] @@ -281,7 +281,7 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.1.5" +version = "0.1.6" dependencies = [ "generic-array", "rand_core 0.6.3", @@ -355,7 +355,7 @@ version = "0.10.3" dependencies = [ "blobby", "block-buffer 0.10.2", - "crypto-common 0.1.5", + "crypto-common 0.1.6", "subtle", ] diff --git a/cipher/CHANGELOG.md b/cipher/CHANGELOG.md index 7db2add74..002a44566 100644 --- a/cipher/CHANGELOG.md +++ b/cipher/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.4.4 [UNRELEASED] +### Changed +- Move `ParBlocks`/`ParBlocksSizeUser` to the `crypto-common` crate ([#1052]) + +[#1052]: https://github.com/RustCrypto/traits/pull/1052 + ## 0.4.3 (2022-02-22) ### Fixed - Do not enable the `alloc` feature by default ([#953]) diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index 9bf6f4ac7..c04cc0577 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -13,7 +13,7 @@ keywords = ["crypto", "block-cipher", "stream-cipher", "trait"] categories = ["cryptography", "no-std"] [dependencies] -crypto-common = { version = "0.1.3", path = "../crypto-common" } +crypto-common = { version = "0.1.6", path = "../crypto-common" } inout = "0.1" # optional dependencies diff --git a/crypto-common/CHANGELOG.md b/crypto-common/CHANGELOG.md index 7a052c5fb..9fa793693 100644 --- a/crypto-common/CHANGELOG.md +++ b/crypto-common/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.1.6 (2022-07-16) +### Added +- Move `ParBlocks`/`ParBlocksSizeUser` from `cipher` crate ([#1052]) + +[#1052]: https://github.com/RustCrypto/traits/pull/1052 + ## 0.1.5 (2022-07-09) ### Fixed - Support on-label MSRV ([#1049]) diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index c27d8e253..1a5e579c8 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crypto-common" description = "Common cryptographic traits" -version = "0.1.5" +version = "0.1.6" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" From 7eb501d53e0acb552ae16d75572bf659871e14b2 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 17 Jul 2022 08:26:09 -0600 Subject: [PATCH 0819/1461] universal-hash v0.5.0-pre (#1051) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Артём Павлов [Artyom Pavlov] --- .github/workflows/universal-hash.yml | 4 +- Cargo.lock | 14 +- README.md | 4 +- crypto/Cargo.toml | 2 +- universal-hash/Cargo.toml | 14 +- universal-hash/README.md | 6 +- universal-hash/src/lib.rs | 213 +++++++++++++-------------- 7 files changed, 123 insertions(+), 134 deletions(-) diff --git a/.github/workflows/universal-hash.yml b/.github/workflows/universal-hash.yml index a72fb941e..2df8b8f31 100644 --- a/.github/workflows/universal-hash.yml +++ b/.github/workflows/universal-hash.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.41.0 # MSRV + - 1.56.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -50,7 +50,7 @@ jobs: strategy: matrix: rust: - - 1.41.0 # MSRV + - 1.56.0 # MSRV - stable steps: - uses: actions/checkout@v2 diff --git a/Cargo.lock b/Cargo.lock index 7b6fa4663..9e6e4136f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -242,7 +242,7 @@ dependencies = [ "elliptic-curve 0.12.2", "password-hash", "signature 1.5.0", - "universal-hash 0.4.1", + "universal-hash 0.5.0-pre", ] [[package]] @@ -755,7 +755,7 @@ checksum = "048aeb476be11a4b6ca432ca569e375810de9294ae78f4774e78ea98a9246ede" dependencies = [ "cpufeatures", "opaque-debug", - "universal-hash 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "universal-hash 0.4.1", ] [[package]] @@ -767,7 +767,7 @@ dependencies = [ "cfg-if", "cpufeatures", "opaque-debug", - "universal-hash 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "universal-hash 0.4.1", ] [[package]] @@ -1109,6 +1109,8 @@ checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04" [[package]] name = "universal-hash" version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05" dependencies = [ "generic-array", "subtle", @@ -1116,11 +1118,9 @@ dependencies = [ [[package]] name = "universal-hash" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05" +version = "0.5.0-pre" dependencies = [ - "generic-array", + "crypto-common 0.1.6", "subtle", ] diff --git a/README.md b/README.md index c06744b05..4f17baea3 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # RustCrypto: Traits -[![Project Chat][chat-image]][chat-link] ![Apache2/MIT licensed][license-image] [![dependency status][deps-image]][deps-link] +[![Project Chat][chat-image]][chat-link] ![Apache2/MIT licensed][license-image] [![dependency status][deps-image]][deps-link] Collection of traits which describe functionality of cryptographic primitives. @@ -17,7 +17,7 @@ Collection of traits which describe functionality of cryptographic primitives. | [`kem`] | [Key encapsulation mechanism] | [![crates.io](https://img.shields.io/crates/v/kem.svg)](https://crates.io/crates/kem) | [![Documentation](https://docs.rs/kem/badge.svg)](https://docs.rs/kem) | ![MSRV 1.56][msrv-1.56] | | [`password-hash`] | [Password hashing] | [![crates.io](https://img.shields.io/crates/v/password-hash.svg)](https://crates.io/crates/password-hash) | [![Documentation](https://docs.rs/password-hash/badge.svg)](https://docs.rs/password-hash) | ![MSRV 1.57][msrv-1.57] | | [`signature`] | [Digital signature] | [![crates.io](https://img.shields.io/crates/v/signature.svg)](https://crates.io/crates/signature) | [![Documentation](https://docs.rs/signature/badge.svg)](https://docs.rs/signature) | ![MSRV 1.41][msrv-1.41] | -| [`universal‑hash`] | [Universal hash function] | [![crates.io](https://img.shields.io/crates/v/universal-hash.svg)](https://crates.io/crates/universal-hash) | [![Documentation](https://docs.rs/universal-hash/badge.svg)](https://docs.rs/universal-hash) | ![MSRV 1.41][msrv-1.41] | +| [`universal‑hash`] | [Universal hash function] | [![crates.io](https://img.shields.io/crates/v/universal-hash.svg)](https://crates.io/crates/universal-hash) | [![Documentation](https://docs.rs/universal-hash/badge.svg)](https://docs.rs/universal-hash) | ![MSRV 1.56][msrv-1.56] | ### Additional Crates diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index ec4fbd3ba..234b80ca8 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -22,7 +22,7 @@ elliptic-curve = { version = "0.12", optional = true, path = "../elliptic-curve" mac = { version = "0.11", package = "crypto-mac", optional = true } password-hash = { version = "0.4", optional = true, path = "../password-hash" } signature = { version = "1.5", optional = true, default-features = false, path = "../signature" } -universal-hash = { version = "0.4", optional = true, path = "../universal-hash" } +universal-hash = { version = "=0.5.0-pre", optional = true, path = "../universal-hash" } [features] std = [ diff --git a/universal-hash/Cargo.toml b/universal-hash/Cargo.toml index 2c15823ef..1ed6bd4a1 100644 --- a/universal-hash/Cargo.toml +++ b/universal-hash/Cargo.toml @@ -1,22 +1,24 @@ [package] name = "universal-hash" -version = "0.4.1" # Also update html_root_url in lib.rs when bumping this +version = "0.5.0-pre" +description = "Traits which describe the functionality of universal hash functions (UHFs)" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" -description = "Trait for universal hash functions" +edition = "2021" +rust-version = "1.56" +readme = "README.md" documentation = "https://docs.rs/universal-hash" repository = "https://github.com/RustCrypto/traits" keywords = ["crypto", "mac"] categories = ["cryptography", "no-std"] -readme = "README.md" -edition = "2018" [dependencies] -generic-array = "0.14" +crypto-common = { version = "0.1.6", path = "../crypto-common" } subtle = { version = "=2.4", default-features = false } [features] -std = [] +std = ["crypto-common/std"] [package.metadata.docs.rs] all-features = true +rustdoc-args = ["--cfg", "docsrs"] diff --git a/universal-hash/README.md b/universal-hash/README.md index 20fd50a82..9fd55a0cf 100644 --- a/universal-hash/README.md +++ b/universal-hash/README.md @@ -7,7 +7,7 @@ [![Project Chat][chat-image]][chat-link] [![Build Status][build-image]][build-link] -Traits which define functionality of [universal hash functions]. +Traits which describe functionality of [universal hash functions] (UHFs). See [RustCrypto/universal-hashes] for implementations which use this trait. @@ -15,7 +15,7 @@ See [RustCrypto/universal-hashes] for implementations which use this trait. ## Minimum Supported Rust Version -Rust **1.41** or higher. +Rust **1.56** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -47,7 +47,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/universal-hash/badge.svg [docs-link]: https://docs.rs/universal-hash/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.56+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260051-universal-hashes [build-image]: https://github.com/RustCrypto/traits/workflows/universal-hash/badge.svg?branch=master&event=push diff --git a/universal-hash/src/lib.rs b/universal-hash/src/lib.rs index dc802c815..91d4b13a9 100644 --- a/universal-hash/src/lib.rs +++ b/universal-hash/src/lib.rs @@ -18,46 +18,90 @@ //! [Universal Hash Functions]: https://en.wikipedia.org/wiki/Universal_hashing #![no_std] -#![forbid(unsafe_code)] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/universal-hash/0.4.1" + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg" )] +#![cfg_attr(docsrs, feature(doc_cfg))] +#![deny(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] #[cfg(feature = "std")] extern crate std; -pub use generic_array::{self, typenum::consts}; +pub use crypto_common::{ + self, generic_array, + typenum::{self, consts}, + Block, Key, KeyInit, ParBlocks, +}; -use generic_array::typenum::Unsigned; +use core::slice; +use crypto_common::{BlockSizeUser, ParBlocksSizeUser}; use generic_array::{ArrayLength, GenericArray}; -use subtle::{Choice, ConstantTimeEq}; - -/// Keys to a [`UniversalHash`]. -pub type Key = GenericArray::KeySize>; - -/// Blocks are inputs to a [`UniversalHash`]. -pub type Block = GenericArray::BlockSize>; - -/// Instantiate a [`UniversalHash`] algorithm. -pub trait NewUniversalHash: Sized { - /// Size of the key for the universal hash function. - type KeySize: ArrayLength; +use subtle::ConstantTimeEq; +use typenum::Unsigned; + +/// Trait implemented by UHF backends. +pub trait UhfBackend: ParBlocksSizeUser { + /// Process single block. + fn proc_block(&mut self, block: &Block); + + /// Process several blocks in parallel. + #[inline(always)] + fn proc_par_blocks(&mut self, blocks: &ParBlocks) { + for block in blocks { + self.proc_block(block); + } + } +} - /// Instantiate a universal hash function with the given key. - fn new(key: &Key) -> Self; +/// Trait for [`UhfBackend`] users. +/// +/// This trait is used to define rank-2 closures. +pub trait UhfClosure: BlockSizeUser { + /// Execute closure with the provided UHF backend. + fn call>(self, backend: &mut B); } /// The [`UniversalHash`] trait defines a generic interface for universal hash /// functions. -pub trait UniversalHash: Clone { - /// Size of the inputs to and outputs from the universal hash function - type BlockSize: ArrayLength; +pub trait UniversalHash: BlockSizeUser + Sized { + /// Update hash function state using the provided rank-2 closure. + fn update_with_backend(&mut self, f: impl UhfClosure); + + /// Update hash function state with the provided block. + #[inline] + fn update(&mut self, blocks: &[Block]) { + struct Ctx<'a, BS: ArrayLength> { + blocks: &'a [Block], + } + + impl<'a, BS: ArrayLength> BlockSizeUser for Ctx<'a, BS> { + type BlockSize = BS; + } + + impl<'a, BS: ArrayLength> UhfClosure for Ctx<'a, BS> { + #[inline(always)] + fn call>(self, backend: &mut B) { + let pb = B::ParBlocksSize::USIZE; + if pb > 1 { + let (par_blocks, tail) = to_blocks(self.blocks); + for par_block in par_blocks { + backend.proc_par_blocks(par_block); + } + for block in tail { + backend.proc_block(block); + } + } else { + for block in self.blocks { + backend.proc_block(block); + } + } + } + } - /// Input a block into the universal hash function - fn update(&mut self, block: &Block); + self.update_with_backend(Ctx { blocks }); + } /// Input data into the universal hash function. If the length of the /// data is not a multiple of the block size, the remaining data is @@ -65,41 +109,30 @@ pub trait UniversalHash: Clone { /// /// This approach is frequently used by AEAD modes which use /// Message Authentication Codes (MACs) based on universal hashing. + #[inline] fn update_padded(&mut self, data: &[u8]) { - let mut chunks = data.chunks_exact(Self::BlockSize::to_usize()); + let (blocks, tail) = to_blocks(data); - for chunk in &mut chunks { - self.update(GenericArray::from_slice(chunk)); - } + self.update(blocks); - let rem = chunks.remainder(); - - if !rem.is_empty() { + if !tail.is_empty() { let mut padded_block = GenericArray::default(); - padded_block[..rem.len()].copy_from_slice(rem); - self.update(&padded_block); + padded_block[..tail.len()].copy_from_slice(tail); + self.update(slice::from_ref(&padded_block)); } } - /// Reset [`UniversalHash`] instance. - fn reset(&mut self); - - /// Obtain the [`Output`] of a [`UniversalHash`] function and consume it. - fn finalize(self) -> Output; + /// Retrieve result and consume hasher instance. + fn finalize(self) -> Block; - /// Obtain the [`Output`] of a [`UniversalHash`] computation and reset it back - /// to its initial state. - fn finalize_reset(&mut self) -> Output { - let res = self.clone().finalize(); - self.reset(); - res - } - - /// Verify the [`UniversalHash`] of the processed input matches a given [`Output`]. + /// Verify the [`UniversalHash`] of the processed input matches + /// a given `expected` value. + /// /// This is useful when constructing Message Authentication Codes (MACs) /// from universal hash functions. - fn verify(self, other: &Block) -> Result<(), Error> { - if self.finalize() == other.into() { + #[inline] + fn verify(self, expected: &Block) -> Result<(), Error> { + if self.finalize().ct_eq(expected).unwrap_u8() == 1 { Ok(()) } else { Err(Error) @@ -107,78 +140,32 @@ pub trait UniversalHash: Clone { } } -/// Outputs of universal hash functions which are a thin wrapper around a -/// byte array. Provides a safe [`Eq`] implementation that runs in constant time, -/// which is useful for implementing Message Authentication Codes (MACs) based -/// on universal hashing. -#[derive(Clone)] -pub struct Output { - bytes: GenericArray, -} - -impl Output -where - U: UniversalHash, -{ - /// Create a new [`Output`] block. - pub fn new(bytes: Block) -> Output { - Output { bytes } - } - - /// Get the inner [`GenericArray`] this type wraps - pub fn into_bytes(self) -> Block { - self.bytes - } -} - -impl From> for Output -where - U: UniversalHash, -{ - fn from(bytes: Block) -> Self { - Output { bytes } - } -} - -impl<'a, U> From<&'a Block> for Output -where - U: UniversalHash, -{ - fn from(bytes: &'a Block) -> Self { - bytes.clone().into() - } -} - -impl ConstantTimeEq for Output -where - U: UniversalHash, -{ - fn ct_eq(&self, other: &Self) -> Choice { - self.bytes.ct_eq(&other.bytes) - } -} - -impl PartialEq for Output -where - U: UniversalHash, -{ - fn eq(&self, x: &Output) -> bool { - self.ct_eq(x).unwrap_u8() == 1 - } -} - -impl Eq for Output {} - -/// Error type for when the [`Output`] of a [`UniversalHash`] -/// is not equal to the expected value. +/// Error type used by the [`UniversalHash::verify`] method +/// to indicate that UHF output is not equal the expected value. #[derive(Default, Debug, Copy, Clone, Eq, PartialEq)] pub struct Error; impl core::fmt::Display for Error { + #[inline] fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.write_str("UHF output mismatch") } } #[cfg(feature = "std")] +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] impl std::error::Error for Error {} + +/// Split message into slice of blocks and leftover tail. +// TODO: replace with `slice::as_chunks` on migration to const generics +#[inline(always)] +fn to_blocks>(data: &[T]) -> (&[GenericArray], &[T]) { + let nb = data.len() / N::USIZE; + let (left, right) = data.split_at(nb * N::USIZE); + let p = left.as_ptr() as *const GenericArray; + // SAFETY: we guarantee that `blocks` does not point outside of `data` + // and `p` is valid for reads + #[allow(unsafe_code)] + let blocks = unsafe { slice::from_raw_parts(p, nb) }; + (blocks, right) +} From ccd718279f406e1ebee088fb4cdc6b578ec23740 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 19 Jul 2022 11:57:16 -0600 Subject: [PATCH 0820/1461] universal-hash: add back `finalize_reset` (#1054) This method was used by the `aes-gcm-siv` crate to handle a case where consuming `self` is problematic and borrowing `&mut self` is much more straightforward. It seems we've had several cases like this pop up with similar methods that were removed in other crates like `block-modes` and `digest`. The method is provided but bounded on `Clone + Reset`, with the latter sourced from `crypto-common`. --- universal-hash/src/lib.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/universal-hash/src/lib.rs b/universal-hash/src/lib.rs index 91d4b13a9..a8b6b79e9 100644 --- a/universal-hash/src/lib.rs +++ b/universal-hash/src/lib.rs @@ -32,7 +32,7 @@ extern crate std; pub use crypto_common::{ self, generic_array, typenum::{self, consts}, - Block, Key, KeyInit, ParBlocks, + Block, Key, KeyInit, ParBlocks, Reset, }; use core::slice; @@ -125,6 +125,18 @@ pub trait UniversalHash: BlockSizeUser + Sized { /// Retrieve result and consume hasher instance. fn finalize(self) -> Block; + /// Obtain the [`Output`] of a [`UniversalHash`] computation and reset it back + /// to its initial state. + #[inline] + fn finalize_reset(&mut self) -> Block + where + Self: Clone + Reset, + { + let ret = self.clone().finalize(); + self.reset(); + ret + } + /// Verify the [`UniversalHash`] of the processed input matches /// a given `expected` value. /// From 53c47220e1316f68629336284277d34277e4aaa8 Mon Sep 17 00:00:00 2001 From: Agost Biro <5764438+agostbiro@users.noreply.github.com> Date: Tue, 19 Jul 2022 21:04:02 +0200 Subject: [PATCH 0821/1461] elliptic-curve: fix outdated doc (#1048) The `zeroize` feature flag has been removed, zeroization on drop is now done by default. --- elliptic-curve/src/secret_key.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index f6fd70774..0fc3dafb1 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -2,10 +2,8 @@ //! //! The [`SecretKey`] type is a wrapper around a secret scalar value which is //! designed to prevent unintentional exposure (e.g. via `Debug` or other -//! logging). -//! -//! When the `zeroize` feature of this crate is enabled, it also handles -//! zeroing it out of memory securely on drop. +//! logging). It also handles zeroing the secret value out of memory securely +//! on drop. #[cfg(all(feature = "pkcs8", feature = "sec1"))] mod pkcs8; From 0904bed0e85f798bea4f1a61437ec55e4f089865 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 20 Jul 2022 07:57:55 -0600 Subject: [PATCH 0822/1461] universal-hash v0.5.0-pre.1 (#1056) --- Cargo.lock | 4 ++-- crypto/Cargo.toml | 2 +- universal-hash/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9e6e4136f..f80935d24 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -242,7 +242,7 @@ dependencies = [ "elliptic-curve 0.12.2", "password-hash", "signature 1.5.0", - "universal-hash 0.5.0-pre", + "universal-hash 0.5.0-pre.1", ] [[package]] @@ -1118,7 +1118,7 @@ dependencies = [ [[package]] name = "universal-hash" -version = "0.5.0-pre" +version = "0.5.0-pre.1" dependencies = [ "crypto-common 0.1.6", "subtle", diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 234b80ca8..ed81ca1c5 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -22,7 +22,7 @@ elliptic-curve = { version = "0.12", optional = true, path = "../elliptic-curve" mac = { version = "0.11", package = "crypto-mac", optional = true } password-hash = { version = "0.4", optional = true, path = "../password-hash" } signature = { version = "1.5", optional = true, default-features = false, path = "../signature" } -universal-hash = { version = "=0.5.0-pre", optional = true, path = "../universal-hash" } +universal-hash = { version = "=0.5.0-pre.1", optional = true, path = "../universal-hash" } [features] std = [ diff --git a/universal-hash/Cargo.toml b/universal-hash/Cargo.toml index 1ed6bd4a1..25b4cd1b5 100644 --- a/universal-hash/Cargo.toml +++ b/universal-hash/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "universal-hash" -version = "0.5.0-pre" +version = "0.5.0-pre.1" description = "Traits which describe the functionality of universal hash functions (UHFs)" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" From c98363e2521599f3984dc8a7f29d141cb405e443 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Jul 2022 16:23:54 -0600 Subject: [PATCH 0823/1461] build(deps): bump zeroize from 1.5.6 to 1.5.7 (#1057) Bumps [zeroize](https://github.com/RustCrypto/utils) from 1.5.6 to 1.5.7. - [Release notes](https://github.com/RustCrypto/utils/releases) - [Commits](https://github.com/RustCrypto/utils/compare/zeroize-v1.5.6...zeroize-v1.5.7) --- updated-dependencies: - dependency-name: zeroize dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f80935d24..6ff8531d1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1176,9 +1176,9 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.5.6" +version = "1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20b578acffd8516a6c3f2a1bdefc1ec37e547bb4e0fb8b6b01a4cafc886b4442" +checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f" dependencies = [ "zeroize_derive", ] From 05d54a2ad9c5dba96495d67ed2197847c3d727e1 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 24 Jul 2022 07:46:03 -0600 Subject: [PATCH 0824/1461] aead v0.5.0 (#1058) --- Cargo.lock | 4 ++-- aead/CHANGELOG.md | 14 ++++++++++++++ aead/Cargo.toml | 2 +- crypto/Cargo.toml | 2 +- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6ff8531d1..06ef971bc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,7 +13,7 @@ dependencies = [ [[package]] name = "aead" -version = "0.5.0-pre.2" +version = "0.5.0" dependencies = [ "blobby", "bytes", @@ -235,7 +235,7 @@ dependencies = [ name = "crypto" version = "0.4.0-pre" dependencies = [ - "aead 0.5.0-pre.2", + "aead 0.5.0", "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "crypto-mac", "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/aead/CHANGELOG.md b/aead/CHANGELOG.md index 90e7874da..6efdd317e 100644 --- a/aead/CHANGELOG.md +++ b/aead/CHANGELOG.md @@ -5,6 +5,20 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.5.0 (2022-07-23) +### Added +- Optional support for `BytesMut` as a `Buffer` ([#956]) +- `getrandom` feature ([#1042]) + +### Changed +- Replace `NewAead` trait with `KeyInit` trait from `crypto-common` ([#1033]) +- Rust 2021 edition upgrade; MSRV 1.56+ ([#1044]) + +[#956]: https://github.com/RustCrypto/traits/pull/956 +[#1033]: https://github.com/RustCrypto/traits/pull/1033 +[#1042]: https://github.com/RustCrypto/traits/pull/1042 +[#1044]: https://github.com/RustCrypto/traits/pull/1044 + ## 0.4.3 (2021-08-29) ### Added - `Result` type alias ([#725]) diff --git a/aead/Cargo.toml b/aead/Cargo.toml index 574c8a144..d3fca49b7 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aead" -version = "0.5.0-pre.2" # Also update html_root_url in lib.rs when bumping this +version = "0.5.0" # Also update html_root_url in lib.rs when bumping this description = """ Traits for Authenticated Encryption with Associated Data (AEAD) algorithms, such as AES-GCM as ChaCha20Poly1305, which provide a high-level API diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index ed81ca1c5..991f0f5ee 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -15,7 +15,7 @@ edition = "2021" rust-version = "1.57" [dependencies] -aead = { version = "=0.5.0-pre.2", optional = true, path = "../aead" } +aead = { version = "0.5", optional = true, path = "../aead" } cipher = { version = "0.4", optional = true } digest = { version = "0.10", optional = true } elliptic-curve = { version = "0.12", optional = true, path = "../elliptic-curve" } From 0b2a4a28277c5931d2683e4fe1722c417b9814f3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 24 Jul 2022 08:01:28 -0600 Subject: [PATCH 0825/1461] build(deps): bump bytes from 1.1.0 to 1.2.0 (#1055) Bumps [bytes](https://github.com/tokio-rs/bytes) from 1.1.0 to 1.2.0. - [Release notes](https://github.com/tokio-rs/bytes/releases) - [Changelog](https://github.com/tokio-rs/bytes/blob/master/CHANGELOG.md) - [Commits](https://github.com/tokio-rs/bytes/compare/v1.1.0...v1.2.0) --- updated-dependencies: - dependency-name: bytes dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 06ef971bc..10cfdf5a5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -146,9 +146,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" +checksum = "f0b3de4a0c5e67e16066a0715723abd91edc2f9001d09c46e1dca929351e130e" [[package]] name = "cc" From ec0757d03b594aeef1c37c30f6b106dc3833dc98 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 24 Jul 2022 11:36:38 -0600 Subject: [PATCH 0826/1461] universal-hash: add `UhfBackend::blocks_needed_to_align` (#1059) Originally suggested by @str4d here: https://github.com/RustCrypto/traits/pull/965#discussion_r857126434 The use case is ensuring unbuffered processing of the input AEAD message body when the AAD does not line up with the number of blocks it's processing in parallel. This number of blocks can be input from the start of the message body to finish completely filling the buffer, ensuring all subsequent processing occurs at the start of the buffer. --- universal-hash/src/lib.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/universal-hash/src/lib.rs b/universal-hash/src/lib.rs index a8b6b79e9..c64589977 100644 --- a/universal-hash/src/lib.rs +++ b/universal-hash/src/lib.rs @@ -53,6 +53,13 @@ pub trait UhfBackend: ParBlocksSizeUser { self.proc_block(block); } } + + /// Returns the number of blocks that should be passed to `Self::proc_block` before + /// `Self::proc_par_blocks` can be used efficiently. This is always less than + /// `Self::ParBlocksSize`. + fn blocks_needed_to_align(&self) -> usize { + 0 + } } /// Trait for [`UhfBackend`] users. From e1959bd709e994f02b74700f095dff42bae4b047 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 24 Jul 2022 12:00:19 -0600 Subject: [PATCH 0827/1461] universal-hash v0.5.0-pre.2 (#1060) --- Cargo.lock | 4 ++-- crypto/Cargo.toml | 2 +- universal-hash/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 10cfdf5a5..f0b0d6593 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -242,7 +242,7 @@ dependencies = [ "elliptic-curve 0.12.2", "password-hash", "signature 1.5.0", - "universal-hash 0.5.0-pre.1", + "universal-hash 0.5.0-pre.2", ] [[package]] @@ -1118,7 +1118,7 @@ dependencies = [ [[package]] name = "universal-hash" -version = "0.5.0-pre.1" +version = "0.5.0-pre.2" dependencies = [ "crypto-common 0.1.6", "subtle", diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 991f0f5ee..e775cd1b4 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -22,7 +22,7 @@ elliptic-curve = { version = "0.12", optional = true, path = "../elliptic-curve" mac = { version = "0.11", package = "crypto-mac", optional = true } password-hash = { version = "0.4", optional = true, path = "../password-hash" } signature = { version = "1.5", optional = true, default-features = false, path = "../signature" } -universal-hash = { version = "=0.5.0-pre.1", optional = true, path = "../universal-hash" } +universal-hash = { version = "=0.5.0-pre.2", optional = true, path = "../universal-hash" } [features] std = [ diff --git a/universal-hash/Cargo.toml b/universal-hash/Cargo.toml index 25b4cd1b5..651222c76 100644 --- a/universal-hash/Cargo.toml +++ b/universal-hash/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "universal-hash" -version = "0.5.0-pre.1" +version = "0.5.0-pre.2" description = "Traits which describe the functionality of universal hash functions (UHFs)" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" From 398d6d258ba6175d41785482e0f693b2fa56248b Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 31 Jul 2022 11:06:59 -0600 Subject: [PATCH 0828/1461] universal-hash v0.5.0 (#1061) --- Cargo.lock | 4 ++-- crypto/Cargo.toml | 2 +- universal-hash/CHANGELOG.md | 20 ++++++++++++++++++++ universal-hash/Cargo.toml | 2 +- 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f0b0d6593..963668982 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -242,7 +242,7 @@ dependencies = [ "elliptic-curve 0.12.2", "password-hash", "signature 1.5.0", - "universal-hash 0.5.0-pre.2", + "universal-hash 0.5.0", ] [[package]] @@ -1118,7 +1118,7 @@ dependencies = [ [[package]] name = "universal-hash" -version = "0.5.0-pre.2" +version = "0.5.0" dependencies = [ "crypto-common 0.1.6", "subtle", diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index e775cd1b4..703064780 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -22,7 +22,7 @@ elliptic-curve = { version = "0.12", optional = true, path = "../elliptic-curve" mac = { version = "0.11", package = "crypto-mac", optional = true } password-hash = { version = "0.4", optional = true, path = "../password-hash" } signature = { version = "1.5", optional = true, default-features = false, path = "../signature" } -universal-hash = { version = "=0.5.0-pre.2", optional = true, path = "../universal-hash" } +universal-hash = { version = "0.5", optional = true, path = "../universal-hash" } [features] std = [ diff --git a/universal-hash/CHANGELOG.md b/universal-hash/CHANGELOG.md index 7959f756e..bb9f52879 100644 --- a/universal-hash/CHANGELOG.md +++ b/universal-hash/CHANGELOG.md @@ -5,6 +5,26 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.5.0 (2021-07-30) +### Added +- `UhfBackend` trait ([#1051], [#1059]) +- `UhfClosure` trait ([#1051]) +- `UniversalHash::update_with_backend` method ([#1051]) + +### Changed +- Replace `NewUniversalHash` trait with `KeyInit` from `crypto-common` ([#1051]) +- Source `Block` and `Key` types from `crypto-common` ([#1051]) +- `UniversalHash::update` is now provided takes a slice of blocks ([#1051]) +- `UniversalHash::finalize` now returns a `Block` ([#1051]) +- Rust 2021 edition; MSRV 1.56 ([#1051]) + +### Removed +- `Ouput` replaced by `Block` ([#1051]) +- `UniversalHash::reset` replaced with `Reset` trait from `crypto-common` ([#1051]) + +[#1051]: https://github.com/RustCrypto/traits/pull/1051 +[#1059]: https://github.com/RustCrypto/traits/pull/1059 + ## 0.4.1 (2021-07-20) ### Changed - Pin `subtle` dependency to v2.4 ([#689]) diff --git a/universal-hash/Cargo.toml b/universal-hash/Cargo.toml index 651222c76..74bbd115b 100644 --- a/universal-hash/Cargo.toml +++ b/universal-hash/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "universal-hash" -version = "0.5.0-pre.2" +version = "0.5.0" description = "Traits which describe the functionality of universal hash functions (UHFs)" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" From 3876e63dbbcbf6620a99291368011db69ec72120 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Aug 2022 16:42:20 -0600 Subject: [PATCH 0829/1461] build(deps): bump sha3 from 0.10.1 to 0.10.2 (#1065) Bumps [sha3](https://github.com/RustCrypto/hashes) from 0.10.1 to 0.10.2. - [Release notes](https://github.com/RustCrypto/hashes/releases) - [Commits](https://github.com/RustCrypto/hashes/compare/sha3-v0.10.1...sha3-v0.10.2) --- updated-dependencies: - dependency-name: sha3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 963668982..f97718410 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -986,9 +986,9 @@ dependencies = [ [[package]] name = "sha3" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "881bf8156c87b6301fc5ca6b27f11eeb2761224c7081e69b409d5a1951a70c86" +checksum = "0a31480366ec990f395a61b7c08122d99bd40544fdb5abcfc1b06bb29994312c" dependencies = [ "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "keccak", From 2030e4c560d7a3e1fbf7b917f60d00261664b56a Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 1 Aug 2022 20:55:54 -0600 Subject: [PATCH 0830/1461] elliptic-curve: add aliases for SEC1 compressed/uncompressed points (#1067) Adds `GenericArray` type aliases for representing compressed/uncompressed SEC1 points, along with type aliases for calculating their sizes. --- elliptic-curve/src/sec1.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index fd6d2c156..3e1635941 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -5,14 +5,27 @@ pub use sec1::point::{Coordinates, ModulusSize, Tag}; use crate::{Curve, FieldSize, Result, SecretKey}; +use generic_array::GenericArray; use subtle::CtOption; #[cfg(feature = "arithmetic")] use crate::{AffinePoint, Error, ProjectiveArithmetic}; +/// Encoded elliptic curve point with point compression. +pub type CompressedPoint = GenericArray>; + +/// Size of a compressed elliptic curve point. +pub type CompressedPointSize = as ModulusSize>::CompressedPointSize; + /// Encoded elliptic curve point sized appropriately for a given curve. pub type EncodedPoint = sec1::point::EncodedPoint>; +/// Encoded elliptic curve point *without* point compression. +pub type UncompressedPoint = GenericArray>; + +/// Size of an uncompressed elliptic curve point. +pub type UncompressedPointSize = as ModulusSize>::UncompressedPointSize; + /// Trait for deserializing a value from a SEC1 encoded curve point. /// /// This is intended for use with the `AffinePoint` type for a given elliptic curve. From 32bca30c7af80004b43f22fcfd7d9b764872035b Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 1 Aug 2022 21:07:13 -0600 Subject: [PATCH 0831/1461] elliptic-curve: fix `arithmetic` + `serde` feature combo (#1066) It previously resulted in a compile error --- .github/workflows/elliptic-curve.yml | 4 +++- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/public_key.rs | 15 +++++++++------ 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index 8b6ff369e..88b0ffaf6 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -3,6 +3,7 @@ name: elliptic-curve on: pull_request: paths: + - ".github/workflows/elliptic-curve.yml" - "elliptic-curve/**" - "Cargo.*" push: @@ -50,8 +51,9 @@ jobs: - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features pkcs8 - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features sec1 - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features serde - - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,serde - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features voprf + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,serde + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features arithmetic,serde - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features pkcs8,sec1 - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features pem,pkcs8,sec1 - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,digest,ecdh,hazmat,hash2curve,jwk,pem,pkcs8,sec1,serde,voprf diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index dca4b3bba..9baccd056 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -53,7 +53,7 @@ ecdh = ["arithmetic", "digest", "hkdf"] hazmat = [] jwk = ["alloc", "base64ct/alloc", "serde", "serde_json", "zeroize/alloc"] pem = ["alloc", "arithmetic", "der/pem", "pem-rfc7468/alloc", "pkcs8", "sec1/pem"] -serde = ["alloc", "sec1/serde", "serdect"] +serde = ["alloc", "pkcs8", "sec1/serde", "serdect"] std = ["alloc", "rand_core/std"] voprf = ["digest"] diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index 8a3e4b00d..1dc858581 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -16,7 +16,7 @@ use crate::{ }; #[cfg(feature = "pem")] -use {core::str::FromStr, pkcs8::EncodePublicKey}; +use core::str::FromStr; #[cfg(feature = "sec1")] use { @@ -28,12 +28,15 @@ use { subtle::CtOption, }; -#[cfg(any(feature = "jwk", feature = "pem"))] -use alloc::string::{String, ToString}; - #[cfg(feature = "serde")] use serdect::serde::{de, ser, Deserialize, Serialize}; +#[cfg(all(feature = "alloc", feature = "pkcs8"))] +use pkcs8::EncodePublicKey; + +#[cfg(any(feature = "jwk", feature = "pem"))] +use alloc::string::{String, ToString}; + /// Elliptic curve public keys. /// /// This is a wrapper type for [`AffinePoint`] which ensures an inner @@ -304,8 +307,8 @@ where { } -#[cfg(feature = "pem")] -#[cfg_attr(docsrs, doc(cfg(feature = "pem")))] +#[cfg(all(feature = "alloc", feature = "pkcs8"))] +#[cfg_attr(docsrs, doc(cfg(all(feature = "alloc", feature = "pkcs8"))))] impl EncodePublicKey for PublicKey where C: Curve + AssociatedOid + ProjectiveArithmetic, From 147a4e8460433bdb4632c941df3d9306e6ce6099 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 1 Aug 2022 21:20:15 -0600 Subject: [PATCH 0832/1461] elliptic-curve v0.12.3 (#1068) --- Cargo.lock | 4 ++-- elliptic-curve/CHANGELOG.md | 10 ++++++++++ elliptic-curve/Cargo.toml | 2 +- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f97718410..189b0af1f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -239,7 +239,7 @@ dependencies = [ "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "crypto-mac", "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", - "elliptic-curve 0.12.2", + "elliptic-curve 0.12.3", "password-hash", "signature 1.5.0", "universal-hash 0.5.0", @@ -406,7 +406,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.12.2" +version = "0.12.3" dependencies = [ "base16ct", "base64ct", diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index 4e55c0927..975e749d4 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.12.3 (2022-08-01) +### Added +- Aliases for SEC1 compressed/uncompressed points ([#1067]) + +### Fixed +- `arithmetic` + `serde` feature combo ([#1066]) + +[#1066]: https://github.com/RustCrypto/traits/pull/1066 +[#1067]: https://github.com/RustCrypto/traits/pull/1067 + ## 0.12.2 (2022-07-01) ### Changed - Bump `crypto-bigint` to v0.4.8 ([#1039]) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 9baccd056..8a3a098ba 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.12.2" +version = "0.12.3" description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, From 78a2af8a50179904e27473a65ec94398f5a534a1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 Aug 2022 16:10:13 -0600 Subject: [PATCH 0833/1461] build(deps): bump serde_json from 1.0.82 to 1.0.83 (#1071) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.82 to 1.0.83. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.82...v1.0.83) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 189b0af1f..a57f141e2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -941,9 +941,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.82" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82c2c1fdcd807d1098552c5b9a36e425e42e9fbd7c6a37a8425f390f781f7fa7" +checksum = "38dd04e3c8279e75b31ef29dbdceebfe5ad89f4d0937213c53f7d49d01b3d5a7" dependencies = [ "itoa", "ryu", From 7475fb13903a72515e470d3bf9fcbbc94df8e67c Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 9 Aug 2022 19:44:48 -0600 Subject: [PATCH 0834/1461] aead: add `AeadCore::generate_nonce` (#1073) Adds a provided trait method to `AeadCore` for random nonce genreation, gated on the `rand_core` feature. Includes documentation with guidance from NIST SP 800-38D regarding the safety of random nonces, noting their suggested limit of 2^32 encryption operations per key for any nonce size. --- aead/src/lib.rs | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/aead/src/lib.rs b/aead/src/lib.rs index ba5d67329..41191cf32 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -64,6 +64,9 @@ use alloc::vec::Vec; #[cfg(feature = "bytes")] use bytes::BytesMut; +#[cfg(feature = "rand_core")] +use rand_core::{CryptoRng, RngCore}; + /// Error type. /// /// This type is deliberately opaque as to avoid potential side-channel @@ -103,6 +106,52 @@ pub trait AeadCore { /// The upper bound amount of additional space required to support a /// ciphertext vs. a plaintext. type CiphertextOverhead: ArrayLength + Unsigned; + + /// Generate a random nonce for this AEAD algorithm. + /// + /// AEAD algorithms accept a parameter to encryption/decryption called + /// a "nonce" which must be unique every time encryption is performed and + /// never repeated for the same key. The nonce is often prepended to the + /// ciphertext. The nonce used to produce a given ciphertext must be passed + /// to the decryption function in order for it to decrypt correctly. + /// + /// Nonces don't necessarily have to be random, but it is one strategy + /// which is implemented by this function. + /// + /// # ⚠️Security Warning + /// + /// AEAD algorithms often fail catastrophically if nonces are ever repeated + /// (with SIV modes being an exception). + /// + /// Using random nonces runs the risk of repeating them unless the nonce + /// size is particularly large (e.g. 192-bit extended nonces used by the + /// `XChaCha20Poly1305` and `XSalsa20Poly1305` constructions. + /// + /// [NIST SP 800-38D] recommends the following: + /// + /// > The total number of invocations of the authenticated encryption + /// > function shall not exceed 2^32, including all IV lengths and all + /// > instances of the authenticated encryption function with the given key. + /// + /// Following this guideline, only 4,294,967,296 messages with random + /// nonces can be encrypted under a given key. While this bound is high, + /// it's possible to encounter in practice, and systems which might + /// reach it should consider alternatives to purely random nonces, like + /// a counter or a combination of a random nonce + counter. + /// + /// See the [`stream`] module for a ready-made implementation of the latter. + /// + /// [NIST SP 800-38D]: https://csrc.nist.gov/publications/detail/sp/800-38d/final + #[cfg(feature = "rand_core")] + #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] + fn generate_nonce(mut rng: impl CryptoRng + RngCore) -> Nonce + where + Nonce: Default, + { + let mut nonce = Nonce::::default(); + rng.fill_bytes(&mut nonce); + nonce + } } /// Authenticated Encryption with Associated Data (AEAD) algorithm. From add50a3ab3439650d74a614972819c92e60e4410 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 9 Aug 2022 20:15:12 -0600 Subject: [PATCH 0835/1461] aead v0.5.1 (#1074) --- Cargo.lock | 4 ++-- aead/CHANGELOG.md | 6 ++++++ aead/Cargo.toml | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a57f141e2..5bc5cd9e7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,7 +13,7 @@ dependencies = [ [[package]] name = "aead" -version = "0.5.0" +version = "0.5.1" dependencies = [ "blobby", "bytes", @@ -235,7 +235,7 @@ dependencies = [ name = "crypto" version = "0.4.0-pre" dependencies = [ - "aead 0.5.0", + "aead 0.5.1", "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "crypto-mac", "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/aead/CHANGELOG.md b/aead/CHANGELOG.md index 6efdd317e..e4834b239 100644 --- a/aead/CHANGELOG.md +++ b/aead/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.5.1 (2022-08-09) +### Added +- `AeadCore::generate_nonce` ([#1073]) + +[#1073]: https://github.com/RustCrypto/traits/pull/1073 + ## 0.5.0 (2022-07-23) ### Added - Optional support for `BytesMut` as a `Buffer` ([#956]) diff --git a/aead/Cargo.toml b/aead/Cargo.toml index d3fca49b7..06859209d 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aead" -version = "0.5.0" # Also update html_root_url in lib.rs when bumping this +version = "0.5.1" # Also update html_root_url in lib.rs when bumping this description = """ Traits for Authenticated Encryption with Associated Data (AEAD) algorithms, such as AES-GCM as ChaCha20Poly1305, which provide a high-level API From 2084a30677df7b161a88aed021a0ed383e32d697 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Aug 2022 20:20:34 -0600 Subject: [PATCH 0836/1461] build(deps): bump generic-array from 0.14.5 to 0.14.6 (#1070) Bumps [generic-array](https://github.com/fizyk20/generic-array) from 0.14.5 to 0.14.6. - [Release notes](https://github.com/fizyk20/generic-array/releases) - [Changelog](https://github.com/fizyk20/generic-array/blob/master/CHANGELOG.md) - [Commits](https://github.com/fizyk20/generic-array/commits) --- updated-dependencies: - dependency-name: generic-array dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- crypto-common/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5bc5cd9e7..72eed45d9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -459,9 +459,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "generic-array" -version = "0.14.5" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" +checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" dependencies = [ "typenum", "version_check", diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index 1a5e579c8..374e80f52 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -12,7 +12,7 @@ keywords = ["crypto", "traits"] categories = ["cryptography", "no-std"] [dependencies] -generic-array = { version = "0.14.4", features = ["more_lengths"] } +generic-array = { version = "0.14.6", features = ["more_lengths"] } typenum = "1.14" # earlier versions of typenum don't satisfy the 'static bound on U* types # optional dependencies From 57e68a6e216c64db2082613ea73b16500d0decb6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Aug 2022 20:20:45 -0600 Subject: [PATCH 0837/1461] build(deps): bump bytes from 1.2.0 to 1.2.1 (#1064) Bumps [bytes](https://github.com/tokio-rs/bytes) from 1.2.0 to 1.2.1. - [Release notes](https://github.com/tokio-rs/bytes/releases) - [Changelog](https://github.com/tokio-rs/bytes/blob/master/CHANGELOG.md) - [Commits](https://github.com/tokio-rs/bytes/commits) --- updated-dependencies: - dependency-name: bytes dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 72eed45d9..510a2310f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -146,9 +146,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0b3de4a0c5e67e16066a0715723abd91edc2f9001d09c46e1dca929351e130e" +checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" [[package]] name = "cc" From 41d7b5c9b31e1efd983f007ab75063c3beabd3b0 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 9 Aug 2022 20:59:38 -0600 Subject: [PATCH 0838/1461] crypto: remove `crypto-mac` crate dependency (#1075) It's been merged into `digest` --- .github/workflows/crypto.yml | 2 +- Cargo.lock | 1 - crypto/Cargo.toml | 4 +--- crypto/src/lib.rs | 4 ---- 4 files changed, 2 insertions(+), 9 deletions(-) diff --git a/.github/workflows/crypto.yml b/.github/workflows/crypto.yml index bd020750d..a692d82c8 100644 --- a/.github/workflows/crypto.yml +++ b/.github/workflows/crypto.yml @@ -38,7 +38,7 @@ jobs: profile: minimal - run: cargo build --no-default-features --release --target ${{ matrix.target }} - run: cargo build --no-default-features --release --target ${{ matrix.target }} - --features aead,cipher,mac,digest,elliptic-curve,signature,universal-hash + --features aead,cipher,digest,elliptic-curve,signature,universal-hash # TODO: use the reusable workflow after this crate will be part of the # toot workspace diff --git a/Cargo.lock b/Cargo.lock index 510a2310f..9de80d548 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -237,7 +237,6 @@ version = "0.4.0-pre" dependencies = [ "aead 0.5.1", "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "crypto-mac", "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "elliptic-curve 0.12.3", "password-hash", diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 703064780..dfa3d394a 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -17,9 +17,8 @@ rust-version = "1.57" [dependencies] aead = { version = "0.5", optional = true, path = "../aead" } cipher = { version = "0.4", optional = true } -digest = { version = "0.10", optional = true } +digest = { version = "0.10", optional = true, features = ["mac"] } elliptic-curve = { version = "0.12", optional = true, path = "../elliptic-curve" } -mac = { version = "0.11", package = "crypto-mac", optional = true } password-hash = { version = "0.4", optional = true, path = "../password-hash" } signature = { version = "1.5", optional = true, default-features = false, path = "../signature" } universal-hash = { version = "0.5", optional = true, path = "../universal-hash" } @@ -30,7 +29,6 @@ std = [ "cipher/std", "digest/std", "elliptic-curve/std", - "mac/std", "password-hash/std", "signature/std", "universal-hash/std" diff --git a/crypto/src/lib.rs b/crypto/src/lib.rs index e5730641e..5b47ccebc 100644 --- a/crypto/src/lib.rs +++ b/crypto/src/lib.rs @@ -36,7 +36,6 @@ //! | [`cipher`](https://docs.rs/cipher) | `cipher` | Block and stream ciphers (i.e. low-level symmetric encryption) | //! | [`digest`](https://docs.rs/digest) | `digest` | Cryptographic hash functions | //! | [`elliptic_curve`](https://docs.rs/elliptic-curve) | `elliptic-curve` | Elliptic curve cryptography | -//! | [`mac`](https://docs.rs/crypto-mac) | `mac` | Message Authentication Codes (i.e. symmetric message authentication) | //! | [`password_hash`](https://docs.rs/password-hash) | `password-hash` | Password hashing functions | //! | [`signature`](https://docs.rs/signature) | `signature` | Digital signatures (i.e. public key-based message authentication) | //! | [`universal_hash`](https://docs.rs/universal-hash) | `universal‑hash` | Universal Hash Functions (used to build MACs) | @@ -56,9 +55,6 @@ pub use digest; #[cfg(feature = "elliptic-curve")] pub use elliptic_curve; -#[cfg(feature = "mac")] -pub use mac; - #[cfg(feature = "password-hash")] pub use password_hash; From c53bf5b591f7ff485d8ec12a998117d2ac5519da Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 9 Aug 2022 21:21:03 -0600 Subject: [PATCH 0839/1461] crypto: re-export `crypto-common` (#1076) --- Cargo.lock | 1 + crypto/Cargo.toml | 5 +++++ crypto/src/lib.rs | 2 ++ 3 files changed, 8 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 9de80d548..169341a37 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -237,6 +237,7 @@ version = "0.4.0-pre" dependencies = [ "aead 0.5.1", "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.1.6", "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "elliptic-curve 0.12.3", "password-hash", diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index dfa3d394a..19d9d4612 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -15,6 +15,9 @@ edition = "2021" rust-version = "1.57" [dependencies] +crypto-common = { version = "0.1", default-features = false, path = "../crypto-common" } + +# optional dependencies aead = { version = "0.5", optional = true, path = "../aead" } cipher = { version = "0.4", optional = true } digest = { version = "0.10", optional = true, features = ["mac"] } @@ -33,6 +36,8 @@ std = [ "signature/std", "universal-hash/std" ] +getrandom = ["crypto-common/getrandom"] +rand_core = ["crypto-common/rand_core"] [package.metadata.docs.rs] all-features = true diff --git a/crypto/src/lib.rs b/crypto/src/lib.rs index 5b47ccebc..9a5f397eb 100644 --- a/crypto/src/lib.rs +++ b/crypto/src/lib.rs @@ -43,6 +43,8 @@ //! [1]: https://github.com/RustCrypto/traits //! [2]: https://github.com/RustCrypto +pub use crypto_common as common; + #[cfg(feature = "aead")] pub use aead; From 6af57061268eb9defe111baadc6ae144ac210c5d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 9 Aug 2022 21:49:23 -0600 Subject: [PATCH 0840/1461] crypto v0.4.0 (#1077) --- Cargo.lock | 2 +- crypto/CHANGELOG.md | 26 ++++++++++++++++++++++++++ crypto/Cargo.toml | 2 +- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 169341a37..a009aa05d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -233,7 +233,7 @@ dependencies = [ [[package]] name = "crypto" -version = "0.4.0-pre" +version = "0.4.0" dependencies = [ "aead 0.5.1", "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/crypto/CHANGELOG.md b/crypto/CHANGELOG.md index e004b7865..a63d4dca6 100644 --- a/crypto/CHANGELOG.md +++ b/crypto/CHANGELOG.md @@ -5,6 +5,32 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.4.0 (2022-08-09) +### Added +- Re-export `crypto-common` as `common` ([#1076]) + +### Changed +- Bump `aead` to v0.5 ([#1058]) +- Bump `cipher` to 0.4 ([#951]) +- Bump `digest` dependency to v0.10 ([#850]) +- Bump `elliptic-curve` to v0.12 ([#1009]) +- Bump `password-hash` to v0.4 ([#961]) +- Bump `signature` to v1.5 ([#867]) +- Bump `universal-hash` to v0.5 ([#1061]) + +### Removed +- `mac` feature: merged into `digest` ([#1075]) + +[#850]: https://github.com/RustCrypto/traits/pull/850 +[#867]: https://github.com/RustCrypto/traits/pull/867 +[#951]: https://github.com/RustCrypto/traits/pull/951 +[#961]: https://github.com/RustCrypto/traits/pull/961 +[#1009]: https://github.com/RustCrypto/traits/pull/1009 +[#1058]: https://github.com/RustCrypto/traits/pull/1058 +[#1061]: https://github.com/RustCrypto/traits/pull/1061 +[#1075]: https://github.com/RustCrypto/traits/pull/1075 +[#1076]: https://github.com/RustCrypto/traits/pull/1076 + ## 0.3.0 (2021-06-08) ### Changed - Bump `elliptic-curve` crate dependency to v0.10 ([#663]) diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 19d9d4612..3f26148de 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "crypto" -version = "0.4.0-pre" # Also update html_root_url in lib.rs when bumping this +version = "0.4.0" # Also update html_root_url in lib.rs when bumping this description = """ Resources for building cryptosystems in Rust using the RustCrypto project's ecosystem. """ From 54d32dc4eaf353a53cc46d97f3efca6e9b2c6c4d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 13 Aug 2022 12:07:34 -0600 Subject: [PATCH 0841/1461] signature: Rust 2021 edition upgrade; MSRV 1.56 (#1081) Since we have PRs that demand an MSRV bump (#1080), bumps the crate's edition to the latest, which requires MSRV 1.56. --- .github/workflows/signature.yml | 8 ++----- Cargo.lock | 6 ++--- crypto/Cargo.toml | 2 +- signature/Cargo.toml | 5 ++-- signature/README.md | 14 +++++------ signature/async/Cargo.toml | 4 ++-- signature/async/src/lib.rs | 25 +++----------------- signature/derive/Cargo.toml | 3 ++- signature/derive/src/lib.rs | 6 +---- signature/src/lib.rs | 42 ++++++++------------------------- 10 files changed, 34 insertions(+), 81 deletions(-) diff --git a/.github/workflows/signature.yml b/.github/workflows/signature.yml index 5ff5efd01..f96dbea0c 100644 --- a/.github/workflows/signature.yml +++ b/.github/workflows/signature.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.41.0 # MSRV + - 1.56.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -36,8 +36,6 @@ jobs: target: ${{ matrix.target }} override: true profile: minimal - # Isolate this crate from workspace which is otherwise MSRV 1.56 due to 2021 edition crates - - run: rm ../Cargo.toml - run: cargo build --no-default-features --release --target ${{ matrix.target }} minimal-versions: @@ -50,7 +48,7 @@ jobs: strategy: matrix: rust: - - 1.41.0 # MSRV + - 1.56.0 # MSRV - stable steps: - uses: actions/checkout@v2 @@ -60,8 +58,6 @@ jobs: toolchain: ${{ matrix.rust }} override: true profile: minimal - # Isolate this crate from workspace which is otherwise MSRV 1.56 due to 2021 edition crates - - run: rm ../Cargo.toml - run: cargo check --all-features - run: cargo test --no-default-features --release - run: cargo test --release diff --git a/Cargo.lock b/Cargo.lock index a009aa05d..987f9712d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -52,7 +52,7 @@ name = "async-signature" version = "0.2.0-pre" dependencies = [ "async-trait", - "signature 1.5.0", + "signature 1.6.0-pre", ] [[package]] @@ -241,7 +241,7 @@ dependencies = [ "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "elliptic-curve 0.12.3", "password-hash", - "signature 1.5.0", + "signature 1.6.0-pre", "universal-hash 0.5.0", ] @@ -1006,7 +1006,7 @@ dependencies = [ [[package]] name = "signature" -version = "1.5.0" +version = "1.6.0-pre" dependencies = [ "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal 0.2.2", diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 3f26148de..e7106f2e2 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -23,7 +23,7 @@ cipher = { version = "0.4", optional = true } digest = { version = "0.10", optional = true, features = ["mac"] } elliptic-curve = { version = "0.12", optional = true, path = "../elliptic-curve" } password-hash = { version = "0.4", optional = true, path = "../password-hash" } -signature = { version = "1.5", optional = true, default-features = false, path = "../signature" } +signature = { version = "=1.6.0-pre", optional = true, default-features = false, path = "../signature" } universal-hash = { version = "0.5", optional = true, path = "../universal-hash" } [features] diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 5159521aa..d3c805274 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,13 +1,14 @@ [package] name = "signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "1.5.0" # Also update html_root_url in lib.rs when bumping this +version = "1.6.0-pre" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/signature" repository = "https://github.com/RustCrypto/traits/tree/master/signature" readme = "README.md" -edition = "2018" +edition = "2021" +rust-version = "1.56" keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"] categories = ["cryptography", "no-std"] diff --git a/signature/README.md b/signature/README.md index 72db8bd3d..a1a6fa4ae 100644 --- a/signature/README.md +++ b/signature/README.md @@ -2,10 +2,10 @@ [![crate][crate-image]][crate-link] [![Docs][docs-image]][docs-link] +[![Build Status][build-image]][build-link] ![Apache2/MIT licensed][license-image] ![Rust Version][rustc-image] [![Project Chat][chat-image]][chat-link] -[![Build Status][build-image]][build-link] This crate contains traits which provide generic, object-safe APIs for generating and verifying [digital signatures][1]. @@ -13,7 +13,7 @@ generating and verifying [digital signatures][1]. Used by the [`ecdsa`][2] and [`ed25519`][3] crates, with forthcoming support in the [`rsa`][4] crate. -See also the [Signatory][5] project for trait wrappers for using these traits +See also the [Signatory][5] crate for trait wrappers for using these traits with many popular Rust cryptography crates, including `ed25519-dalek`, *ring*, `secp256k1-rs`, and `sodiumoxide`. @@ -21,7 +21,7 @@ with many popular Rust cryptography crates, including `ed25519-dalek`, *ring*, ## Minimum Supported Rust Version -Rust **1.41** or higher. +Rust **1.56** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -52,16 +52,16 @@ dual licensed as above, without any additional terms or conditions. [//]: # (badges) -[crate-image]: https://img.shields.io/crates/v/signature.svg +[crate-image]: https://buildstats.info/crate/signature [crate-link]: https://crates.io/crates/signature [docs-image]: https://docs.rs/signature/badge.svg [docs-link]: https://docs.rs/signature/ +[build-image]: https://github.com/RustCrypto/traits/actions/workflows/signature.yml/badge.svg +[build-link]: https://github.com/RustCrypto/traits/actions/workflows/signature.yml [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.56+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260048-signatures -[build-image]: https://github.com/RustCrypto/traits/workflows/signature/badge.svg?branch=master&event=push -[build-link]: https://github.com/RustCrypto/traits/actions?query=workflow%3Asignature [//]: # (general links) diff --git a/signature/async/Cargo.toml b/signature/async/Cargo.toml index 208d8656b..c6287aee7 100644 --- a/signature/async/Cargo.toml +++ b/signature/async/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "async-signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "0.2.0-pre" # Also update html_root_url in lib.rs when bumping this +version = "0.2.0-pre" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/async-signature" @@ -14,7 +14,7 @@ rust-version = "1.56" [dependencies] async-trait = "0.1.9" -signature = { version = "1.5", path = ".." } +signature = { version = "=1.6.0-pre", path = ".." } [features] digest = ["signature/digest-preview"] diff --git a/signature/async/src/lib.rs b/signature/async/src/lib.rs index c7a3f6365..4592c50e3 100644 --- a/signature/async/src/lib.rs +++ b/signature/async/src/lib.rs @@ -1,28 +1,9 @@ -//! RustCrypto: `async-signature` crate. -//! -//! This is an experimental crate containing `async` versions of select traits -//! from the [`signature`] crate, namely [`AsyncSigner`] and when the `digest` -//! feature is enabled, [`AsyncDigestSigner`]. -//! -//! Traits are implemented using [`async-trait`], which rewrites the traits to -//! use `Box`-ed futures. -//! -//! The longer-term goal is to move these traits into the [`signature`] crate -//! itself, however before doing so we'd like to remove the [`async-trait`] -//! dependency in order to enable use in `no_std` environments. This crate -//! is a stopgap until that happens. -//! -//! For more information, see: -//! -//! -//! [`async-trait`]: https://docs.rs/async-trait - -#![cfg_attr(docsrs, feature(doc_cfg))] +#![doc = include_str!("../README.md")] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/async-signature/0.2.0-pre" + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg" )] +#![cfg_attr(docsrs, feature(doc_cfg))] #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms, unused_qualifications)] diff --git a/signature/derive/Cargo.toml b/signature/derive/Cargo.toml index c9eb09668..12e82ea4d 100644 --- a/signature/derive/Cargo.toml +++ b/signature/derive/Cargo.toml @@ -7,7 +7,8 @@ description = "Custom derive support for the 'signature' crate" documentation = "https://docs.rs/signature" repository = "https://github.com/RustCrypto/traits/tree/master/signature/derive" readme = "README.md" -edition = "2018" +edition = "2021" +rust-version = "1.56" keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"] categories = ["cryptography", "no-std"] diff --git a/signature/derive/src/lib.rs b/signature/derive/src/lib.rs index a6c6e7234..e54227302 100644 --- a/signature/derive/src/lib.rs +++ b/signature/derive/src/lib.rs @@ -1,9 +1,5 @@ -//! Custom derive support for the `signature` crate. -//! -//! This crate can be used to derive `Signer` and `Verifier` impls for -//! types that impl `DigestSigner` or `DigestVerifier` respectively. - #![crate_type = "proc-macro"] +#![doc = include_str!("../README.md")] #![deny(warnings, unused_import_braces, unused_qualifications)] #![forbid(unsafe_code)] diff --git a/signature/src/lib.rs b/signature/src/lib.rs index 432aa8d6d..dca03c1d7 100644 --- a/signature/src/lib.rs +++ b/signature/src/lib.rs @@ -1,25 +1,13 @@ -//! RustCrypto: `signature` crate. -//! -//! Traits which provide generic, object-safe APIs for generating and verifying -//! digital signatures, i.e. message authentication using public-key cryptography. -//! -//! ## Minimum Supported Rust Version -//! -//! Rust **1.41** or higher. -//! -//! Minimum supported Rust version may be changed in the future, but such -//! changes will be accompanied with a minor version bump. -//! -//! ## SemVer policy -//! -//! - MSRV is considered exempt from SemVer as noted above -//! - All on-by-default features of this library are covered by SemVer -//! - Off-by-default features ending in `*-preview` (e.g. `derive-preview`, -//! `digest-preview`) are unstable "preview" features which are also -//! considered exempt from SemVer (typically because they rely on pre-1.0 -//! crates as dependencies). However, breaking changes to these features -//! will, like MSRV, also be accompanied by a minor version bump. -//! +#![no_std] +#![doc = include_str!("../README.md")] +#![doc( + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg" +)] +#![cfg_attr(docsrs, feature(doc_cfg))] +#![forbid(unsafe_code)] +#![warn(missing_docs, rust_2018_idioms, unused_qualifications)] + //! # Design //! //! This crate provides a common set of traits for signing and verifying @@ -155,16 +143,6 @@ //! [`Digest`]: https://docs.rs/digest/latest/digest/trait.Digest.html //! [Fiat-Shamir heuristic]: https://en.wikipedia.org/wiki/Fiat%E2%80%93Shamir_heuristic -#![no_std] -#![cfg_attr(docsrs, feature(doc_cfg))] -#![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/signature/1.5.0" -)] -#![forbid(unsafe_code)] -#![warn(missing_docs, rust_2018_idioms, unused_qualifications)] - #[cfg(feature = "std")] extern crate std; From 55da859b6f820f9b5ce9773e4f5461533db28960 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 14 Aug 2022 06:37:12 -0600 Subject: [PATCH 0842/1461] signature: add `Keypair` trait (#1080) Adds a trait for types which represent a combination of both a signing key and verifying key as is common in many digital signature systems. The `Keypair` name follows Rust standard capitalization rules for the closed compound word "keypair" as commonly used in cryptography. --- signature/src/keypair.rs | 17 +++++++++++++++++ signature/src/lib.rs | 3 ++- 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 signature/src/keypair.rs diff --git a/signature/src/keypair.rs b/signature/src/keypair.rs new file mode 100644 index 000000000..c5a55de6e --- /dev/null +++ b/signature/src/keypair.rs @@ -0,0 +1,17 @@ +//! Signing keypairs. + +use crate::{Signature, Signer, Verifier}; + +/// Signing keypair with an associated verifying key. +/// +/// This represents a type which holds both a signing key and a verifying key. +pub trait Keypair: AsRef + Signer { + /// Verifying key type for this keypair. + type VerifyingKey: Verifier; + + /// Get the verifying key which can verify signatures produced by the + /// signing key portion of this keypair. + fn verifying_key(&self) -> &Self::VerifyingKey { + self.as_ref() + } +} diff --git a/signature/src/lib.rs b/signature/src/lib.rs index dca03c1d7..022f22188 100644 --- a/signature/src/lib.rs +++ b/signature/src/lib.rs @@ -176,8 +176,9 @@ pub use digest; pub use rand_core; mod error; +mod keypair; mod signature; mod signer; mod verifier; -pub use crate::{error::*, signature::*, signer::*, verifier::*}; +pub use crate::{error::*, keypair::*, signature::*, signer::*, verifier::*}; From 17f2b5a62863fe6b82ee4c87a5dc54c90c033365 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 14 Aug 2022 10:25:18 -0600 Subject: [PATCH 0843/1461] signature_derive v1.0.0-pre.5 (#1082) --- signature/derive/CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/signature/derive/CHANGELOG.md b/signature/derive/CHANGELOG.md index b7f29fa97..6b21c134d 100644 --- a/signature/derive/CHANGELOG.md +++ b/signature/derive/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 1.0.0-pre.5 (2022-08-14) +### Changed +- Rust 2021 edition upgrade; MSRV 1.56 ([#1081]) + +[#1081]: https://github.com/RustCrypto/traits/pull/1081 + ## 1.0.0-pre.4 (2022-01-04) ### Changed - Support for new `digest` v0.10 API ([#850]) From e7f2abae0dcb476f10fc84289c407a6be86275fc Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 14 Aug 2022 10:45:59 -0600 Subject: [PATCH 0844/1461] signature: bump `hex-literal` dependency to v0.3 (#1083) --- Cargo.lock | 29 ++--------------------------- signature/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 987f9712d..7a05581dd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -416,7 +416,7 @@ dependencies = [ "ff 0.12.0", "generic-array", "group 0.12.0", - "hex-literal 0.3.4", + "hex-literal", "hkdf 0.12.3", "pem-rfc7468 0.6.0", "pkcs8 0.9.0", @@ -536,31 +536,12 @@ dependencies = [ "stable_deref_trait", ] -[[package]] -name = "hex-literal" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d70693199b3cf4552f3fa720b54163927a3ebed2aef240efaf556033ab336a11" -dependencies = [ - "hex-literal-impl", - "proc-macro-hack", -] - [[package]] name = "hex-literal" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" -[[package]] -name = "hex-literal-impl" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59448fc2f82a5fb6907f78c3d69d843e82ff5b051923313cc4438cb0c7b745a8" -dependencies = [ - "proc-macro-hack", -] - [[package]] name = "hkdf" version = "0.11.0" @@ -817,12 +798,6 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97e91cb6af081c6daad5fa705f8adb0634c027662052cb3174bdf2957bf07e25" -[[package]] -name = "proc-macro-hack" -version = "0.5.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" - [[package]] name = "proc-macro2" version = "1.0.38" @@ -1009,7 +984,7 @@ name = "signature" version = "1.6.0-pre" dependencies = [ "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", - "hex-literal 0.2.2", + "hex-literal", "rand_core 0.6.3", "sha2 0.10.2", "signature_derive", diff --git a/signature/Cargo.toml b/signature/Cargo.toml index d3c805274..8895dce0e 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -18,7 +18,7 @@ rand_core = { version = "0.6", optional = true, default-features = false } signature_derive = { version = "=1.0.0-pre.5", optional = true, path = "derive" } [dev-dependencies] -hex-literal = "0.2.2" +hex-literal = "0.3" sha2 = { version = "0.10", default-features = false } [features] From fb8a1f5d9e9f7d5cb5abe6e3581962f5ac25c9b6 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 14 Aug 2022 11:03:06 -0600 Subject: [PATCH 0845/1461] signature v1.6.0 (#1084) --- Cargo.lock | 6 +++--- crypto/Cargo.toml | 2 +- signature/CHANGELOG.md | 14 ++++++++++++++ signature/Cargo.toml | 2 +- signature/async/Cargo.toml | 2 +- 5 files changed, 20 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7a05581dd..8ef1874a8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -52,7 +52,7 @@ name = "async-signature" version = "0.2.0-pre" dependencies = [ "async-trait", - "signature 1.6.0-pre", + "signature 1.6.0", ] [[package]] @@ -241,7 +241,7 @@ dependencies = [ "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "elliptic-curve 0.12.3", "password-hash", - "signature 1.6.0-pre", + "signature 1.6.0", "universal-hash 0.5.0", ] @@ -981,7 +981,7 @@ dependencies = [ [[package]] name = "signature" -version = "1.6.0-pre" +version = "1.6.0" dependencies = [ "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal", diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index e7106f2e2..3f26148de 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -23,7 +23,7 @@ cipher = { version = "0.4", optional = true } digest = { version = "0.10", optional = true, features = ["mac"] } elliptic-curve = { version = "0.12", optional = true, path = "../elliptic-curve" } password-hash = { version = "0.4", optional = true, path = "../password-hash" } -signature = { version = "=1.6.0-pre", optional = true, default-features = false, path = "../signature" } +signature = { version = "1.5", optional = true, default-features = false, path = "../signature" } universal-hash = { version = "0.5", optional = true, path = "../universal-hash" } [features] diff --git a/signature/CHANGELOG.md b/signature/CHANGELOG.md index bec83106f..f49c1e3d7 100644 --- a/signature/CHANGELOG.md +++ b/signature/CHANGELOG.md @@ -4,6 +4,20 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 1.6.0 (2022-08-14) +### Added +- `Keypair` trait ([#1080]) + +### Changed +- Rust 2021 edition upgrade; MSRV 1.56 ([#1081]) +- Bump `signature_derive` dependency to v1.0.0-pre.5 ([#1082]) +- Bump `hex-literal` dependency to v0.3 ([#1083]) + +[#1080]: https://github.com/RustCrypto/traits/pull/1080 +[#1081]: https://github.com/RustCrypto/traits/pull/1081 +[#1082]: https://github.com/RustCrypto/traits/pull/1082 +[#1083]: https://github.com/RustCrypto/traits/pull/1083 + ## 1.5.0 (2022-01-04) ### Changed - Bump `digest` dependency to v0.10 ([#850]) diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 8895dce0e..6c593523a 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "1.6.0-pre" +version = "1.6.0" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/signature" diff --git a/signature/async/Cargo.toml b/signature/async/Cargo.toml index c6287aee7..4b8d764e6 100644 --- a/signature/async/Cargo.toml +++ b/signature/async/Cargo.toml @@ -14,7 +14,7 @@ rust-version = "1.56" [dependencies] async-trait = "0.1.9" -signature = { version = "=1.6.0-pre", path = ".." } +signature = { version = "1.6", path = ".." } [features] digest = ["signature/digest-preview"] From 610a26f8997052ede9013a952b84c1b44826efc3 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 14 Aug 2022 11:07:09 -0600 Subject: [PATCH 0846/1461] README.md: update MSRVs --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 4f17baea3..99f3d96fb 100644 --- a/README.md +++ b/README.md @@ -8,15 +8,15 @@ Collection of traits which describe functionality of cryptographic primitives. | Name | Algorithm | Crates.io | Docs | MSRV | |---------------------|-----------|:---------:|:-----:|:----:| -| [`aead`] | [Authenticated encryption] | [![crates.io](https://img.shields.io/crates/v/aead.svg)](https://crates.io/crates/aead) | [![Documentation](https://docs.rs/aead/badge.svg)](https://docs.rs/aead) | ![MSRV 1.41][msrv-1.41] | -| [`async‑signature`] | [Digital signature] | [![crates.io](https://img.shields.io/crates/v/async-signature.svg)](https://crates.io/crates/async-signature) | [![Documentation](https://docs.rs/async-signature/badge.svg)](https://docs.rs/async-signature) | ![MSRV 1.41][msrv-1.41] | +| [`aead`] | [Authenticated encryption] | [![crates.io](https://img.shields.io/crates/v/aead.svg)](https://crates.io/crates/aead) | [![Documentation](https://docs.rs/aead/badge.svg)](https://docs.rs/aead) | ![MSRV 1.56][msrv-1.56] | +| [`async‑signature`] | [Digital signature] | [![crates.io](https://img.shields.io/crates/v/async-signature.svg)](https://crates.io/crates/async-signature) | [![Documentation](https://docs.rs/async-signature/badge.svg)](https://docs.rs/async-signature) | ![MSRV 1.56][msrv-1.56] | | [`cipher`] | [Block] and [stream cipher] | [![crates.io](https://img.shields.io/crates/v/cipher.svg)](https://crates.io/crates/cipher) | [![Documentation](https://docs.rs/cipher/badge.svg)](https://docs.rs/cipher) | ![MSRV 1.56][msrv-1.56] | | [`crypto‑common`] | Common cryptographic traits | [![crates.io](https://img.shields.io/crates/v/crypto-common.svg)](https://crates.io/crates/crypto-common) | [![Documentation](https://docs.rs/crypto-common/badge.svg)](https://docs.rs/crypto-common) | ![MSRV 1.41][msrv-1.41] | | [`digest`] | [Cryptographic hash function] | [![crates.io](https://img.shields.io/crates/v/digest.svg)](https://crates.io/crates/digest) | [![Documentation](https://docs.rs/digest/badge.svg)](https://docs.rs/digest) | ![MSRV 1.41][msrv-1.41] | -| [`elliptic‑curve`] | [Elliptic curve cryptography] | [![crates.io](https://img.shields.io/crates/v/elliptic-curve.svg)](https://crates.io/crates/elliptic-curve) | [![Documentation](https://docs.rs/elliptic-curve/badge.svg)](https://docs.rs/elliptic-curve) | ![MSRV 1.56][msrv-1.56] | +| [`elliptic‑curve`] | [Elliptic curve cryptography] | [![crates.io](https://img.shields.io/crates/v/elliptic-curve.svg)](https://crates.io/crates/elliptic-curve) | [![Documentation](https://docs.rs/elliptic-curve/badge.svg)](https://docs.rs/elliptic-curve) | ![MSRV 1.57][msrv-1.57] | | [`kem`] | [Key encapsulation mechanism] | [![crates.io](https://img.shields.io/crates/v/kem.svg)](https://crates.io/crates/kem) | [![Documentation](https://docs.rs/kem/badge.svg)](https://docs.rs/kem) | ![MSRV 1.56][msrv-1.56] | | [`password-hash`] | [Password hashing] | [![crates.io](https://img.shields.io/crates/v/password-hash.svg)](https://crates.io/crates/password-hash) | [![Documentation](https://docs.rs/password-hash/badge.svg)](https://docs.rs/password-hash) | ![MSRV 1.57][msrv-1.57] | -| [`signature`] | [Digital signature] | [![crates.io](https://img.shields.io/crates/v/signature.svg)](https://crates.io/crates/signature) | [![Documentation](https://docs.rs/signature/badge.svg)](https://docs.rs/signature) | ![MSRV 1.41][msrv-1.41] | +| [`signature`] | [Digital signature] | [![crates.io](https://img.shields.io/crates/v/signature.svg)](https://crates.io/crates/signature) | [![Documentation](https://docs.rs/signature/badge.svg)](https://docs.rs/signature) | ![MSRV 1.56][msrv-1.56] | | [`universal‑hash`] | [Universal hash function] | [![crates.io](https://img.shields.io/crates/v/universal-hash.svg)](https://crates.io/crates/universal-hash) | [![Documentation](https://docs.rs/universal-hash/badge.svg)](https://docs.rs/universal-hash) | ![MSRV 1.56][msrv-1.56] | ### Additional Crates From b1a538c18c8b45b3eac99bc760a3ef7ab7fb023f Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 14 Aug 2022 12:49:07 -0600 Subject: [PATCH 0847/1461] async-signature: add `AsyncKeypair` (#1085) Adds a trait which provides an async equivalent of `Keypair` with requests to the signer sent async. Like `Signer`/`AsyncSigner`, also provides a blanket impl for the non-async `Keypair` trait. --- signature/async/src/lib.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/signature/async/src/lib.rs b/signature/async/src/lib.rs index 4592c50e3..50de8853b 100644 --- a/signature/async/src/lib.rs +++ b/signature/async/src/lib.rs @@ -13,6 +13,7 @@ pub use signature::{self, Error, Signature}; pub use signature::digest::{self, Digest}; use async_trait::async_trait; +use signature::Verifier; /// Asynchronously sign the provided message bytestring using `Self` /// (e.g. client for a Cloud KMS or HSM), returning a digital signature. @@ -72,3 +73,28 @@ where self.try_sign_digest(digest) } } + +/// Keypair with async signer component and an associated verifying key. +/// +/// This represents a type which holds both an async signing key and a verifying key. +pub trait AsyncKeypair: AsRef + AsyncSigner +where + S: Signature + Send + 'static, +{ + /// Verifying key type for this keypair. + type VerifyingKey: Verifier; + + /// Get the verifying key which can verify signatures produced by the + /// signing key portion of this keypair. + fn verifying_key(&self) -> &Self::VerifyingKey { + self.as_ref() + } +} + +impl AsyncKeypair for T +where + S: Signature + Send + 'static, + T: signature::Keypair + Send + Sync, +{ + type VerifyingKey = >::VerifyingKey; +} From 08c248f8068dc13564e7a0afb2270a061fb5b020 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 14 Aug 2022 13:18:54 -0600 Subject: [PATCH 0848/1461] async-signature v0.2.0 (#1086) --- Cargo.lock | 2 +- signature/async/CHANGELOG.md | 10 ++++++++++ signature/async/Cargo.toml | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8ef1874a8..3bac1582d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -49,7 +49,7 @@ dependencies = [ [[package]] name = "async-signature" -version = "0.2.0-pre" +version = "0.2.0" dependencies = [ "async-trait", "signature 1.6.0", diff --git a/signature/async/CHANGELOG.md b/signature/async/CHANGELOG.md index 3e9762a85..77f2c6b9b 100644 --- a/signature/async/CHANGELOG.md +++ b/signature/async/CHANGELOG.md @@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.2.0 (2022-08-14) +### Added +- `AsyncKeypair` trait ([#1085]) + +### Changed +- Bump minimum `signature` requirement to v1.6 ([#1084]) + +[#1084]: https://github.com/RustCrypto/traits/pull/1084 +[#1085]: https://github.com/RustCrypto/traits/pull/1085 + ## 0.1.0 (2022-01-04) ### Changed - Bump `signature` crate dependency to v1.5 ([#850], [#867]) diff --git a/signature/async/Cargo.toml b/signature/async/Cargo.toml index 4b8d764e6..f0779c619 100644 --- a/signature/async/Cargo.toml +++ b/signature/async/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "async-signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "0.2.0-pre" +version = "0.2.0" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/async-signature" From 826b0f048182cfc6d2e579e494dec8429747a493 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Mon, 22 Aug 2022 17:49:43 +0000 Subject: [PATCH 0849/1461] Replace Choice::unwrap_u8() == 1 with Choice::into() (#1088) --- digest/src/mac.rs | 8 ++++---- universal-hash/src/lib.rs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/digest/src/mac.rs b/digest/src/mac.rs index 76f8df2c9..ccbd95ba1 100644 --- a/digest/src/mac.rs +++ b/digest/src/mac.rs @@ -144,7 +144,7 @@ impl Mac for T { return Err(MacError); } let choice = self.finalize_fixed().ct_eq(tag); - if choice.unwrap_u8() == 1 { + if choice.into() { Ok(()) } else { Err(MacError) @@ -158,7 +158,7 @@ impl Mac for T { } let choice = self.finalize_fixed()[..n].ct_eq(tag); - if choice.unwrap_u8() == 1 { + if choice.into() { Ok(()) } else { Err(MacError) @@ -173,7 +173,7 @@ impl Mac for T { let m = Self::OutputSize::USIZE - n; let choice = self.finalize_fixed()[m..].ct_eq(tag); - if choice.unwrap_u8() == 1 { + if choice.into() { Ok(()) } else { Err(MacError) @@ -239,7 +239,7 @@ impl ConstantTimeEq for CtOutput { impl PartialEq for CtOutput { #[inline(always)] fn eq(&self, x: &CtOutput) -> bool { - self.ct_eq(x).unwrap_u8() == 1 + self.ct_eq(x).into() } } diff --git a/universal-hash/src/lib.rs b/universal-hash/src/lib.rs index c64589977..f11e48fb1 100644 --- a/universal-hash/src/lib.rs +++ b/universal-hash/src/lib.rs @@ -151,7 +151,7 @@ pub trait UniversalHash: BlockSizeUser + Sized { /// from universal hash functions. #[inline] fn verify(self, expected: &Block) -> Result<(), Error> { - if self.finalize().ct_eq(expected).unwrap_u8() == 1 { + if self.finalize().ct_eq(expected).into() { Ok(()) } else { Err(Error) From 48bd97000b062a21fe2b22b1bde1967ab84dd9e9 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Mon, 22 Aug 2022 17:58:59 +0000 Subject: [PATCH 0850/1461] Update Cargo.toml and desable HPKE tests in kem (#1089) --- Cargo.lock | 501 +++++++++++++++++++++++++--------------------- kem/Cargo.toml | 12 +- kem/tests/hpke.rs | 2 + 3 files changed, 277 insertions(+), 238 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3bac1582d..0e67e0cf4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,15 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "aead" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" -dependencies = [ - "generic-array", -] - [[package]] name = "aead" version = "0.5.1" @@ -23,28 +14,12 @@ dependencies = [ ] [[package]] -name = "aes" -version = "0.8.1" +name = "aho-corasick" +version = "0.7.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfe0133578c0986e1fe3dfcd4af1cc5b2dd6c3dbf534d69916ce16a2701d40ba" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" dependencies = [ - "cfg-if", - "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "cpufeatures", -] - -[[package]] -name = "aes-gcm" -version = "0.10.0-pre" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8004e8b23ff2c65e28ff77bab0eccd36f4a6c2c8e0b55c46acba481425cc3a4f" -dependencies = [ - "aead 0.4.3", - "aes", - "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "ctr", - "ghash", - "subtle", + "memchr", ] [[package]] @@ -57,21 +32,45 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.53" +version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed6aa3524a2dfcf9fe180c51eae2b58738348d819517ceadf95789c51fff7600" +checksum = "76464446b8bc32758d7e88ee1a804d9914cd9b1cb264c029899680b0be29826f" dependencies = [ "proc-macro2", "quote", "syn", ] +[[package]] +name = "atomic-polyfill" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c041a8d9751a520ee19656232a18971f18946a7900f1520ee4400002244dd89" +dependencies = [ + "critical-section", +] + [[package]] name = "autocfg" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "bare-metal" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3" +dependencies = [ + "rustc_version 0.2.3", +] + +[[package]] +name = "bare-metal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fe8f5a8a398345e52358e18ff07cc17a568fbca5c6f73873d3a62056309603" + [[package]] name = "base16ct" version = "0.1.1" @@ -93,11 +92,23 @@ dependencies = [ "serde", ] +[[package]] +name = "bit_field" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4" + +[[package]] +name = "bitfield" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719" + [[package]] name = "bitvec" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1489fcb93a5bb47da0462ca93ad252ad6af2145cce58d10d46a83931ba9f016b" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" dependencies = [ "funty", "radium", @@ -165,30 +176,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "chacha20" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7fc89c7c5b9e7a02dfe45cd2367bae382f9ed31c61ca8debe5f827c420a2f08" -dependencies = [ - "cfg-if", - "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "cpufeatures", -] - -[[package]] -name = "chacha20poly1305" -version = "0.10.0-pre" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "746c430f71e66469abcf493c11484b1a86b957c84fc2d0ba664cd12ac23679ea" -dependencies = [ - "aead 0.4.3", - "chacha20", - "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "poly1305", - "zeroize", -] - [[package]] name = "cipher" version = "0.4.3" @@ -205,9 +192,8 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d1873270f8f7942c191139cb8a40fd228da6c3fd2fc376d7e92d47aa14aeb59e" dependencies = [ - "crypto-common 0.1.3", + "crypto-common 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "inout", - "zeroize", ] [[package]] @@ -222,27 +208,51 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "722e23542a15cea1f65d4a1419c4cfd7a26706c70871a13a04238ca3f40f1661" +[[package]] +name = "cortex-m" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70858629a458fdfd39f9675c4dc309411f2a3f83bede76988d81bf1a0ecee9e0" +dependencies = [ + "bare-metal 0.2.5", + "bitfield", + "embedded-hal", + "volatile-register", +] + [[package]] name = "cpufeatures" -version = "0.2.2" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" +checksum = "dc948ebb96241bb40ab73effeb80d9f93afaad49359d159a5e61be51619fe813" dependencies = [ "libc", ] +[[package]] +name = "critical-section" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95da181745b56d4bd339530ec393508910c909c784e8962d15d722bacf0bcbcd" +dependencies = [ + "bare-metal 1.0.0", + "cfg-if", + "cortex-m", + "riscv", +] + [[package]] name = "crypto" version = "0.4.0" dependencies = [ - "aead 0.5.1", + "aead", "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "crypto-common 0.1.6", "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "elliptic-curve 0.12.3", "password-hash", "signature 1.6.0", - "universal-hash 0.5.0", + "universal-hash", ] [[package]] @@ -252,7 +262,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8658c15c5d921ddf980f7fe25b1e82f4b7a4083b2c4985fea4922edb8e43e07d" dependencies = [ "generic-array", - "rand_core 0.6.3", + "rand_core", "subtle", "zeroize", ] @@ -264,27 +274,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f2b443d17d49dad5ef0ede301c3179cc923b8822f3393b4d2c28c269dd4a122" dependencies = [ "generic-array", - "rand_core 0.6.3", + "rand_core", "subtle", "zeroize", ] [[package]] name = "crypto-common" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8" +version = "0.1.6" dependencies = [ "generic-array", + "rand_core", "typenum", ] [[package]] name = "crypto-common" version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", - "rand_core 0.6.3", "typenum", ] @@ -298,28 +308,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "ctr" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d14f329cfbaf5d0e06b5e87fff7e265d2673c5ea7d2c27691a2c107db1442a0" -dependencies = [ - "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "curve25519-dalek" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" -dependencies = [ - "byteorder", - "digest 0.9.0", - "rand_core 0.5.1", - "subtle", - "zeroize", -] - [[package]] name = "der" version = "0.4.5" @@ -366,7 +354,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" dependencies = [ "block-buffer 0.10.2", - "crypto-common 0.1.3", + "crypto-common 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "subtle", ] @@ -399,7 +387,7 @@ dependencies = [ "generic-array", "group 0.10.0", "pkcs8 0.7.6", - "rand_core 0.6.3", + "rand_core", "subtle", "zeroize", ] @@ -420,7 +408,7 @@ dependencies = [ "hkdf 0.12.3", "pem-rfc7468 0.6.0", "pkcs8 0.9.0", - "rand_core 0.6.3", + "rand_core", "sec1", "serde_json", "serdect", @@ -430,13 +418,23 @@ dependencies = [ "zeroize", ] +[[package]] +name = "embedded-hal" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff" +dependencies = [ + "nb 0.1.3", + "void", +] + [[package]] name = "ff" version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0f40b2dcd8bc322217a5f6559ae5f9e9d1de202a2ecee2e9eafcbece7562a4f" dependencies = [ - "rand_core 0.6.3", + "rand_core", "subtle", ] @@ -447,7 +445,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df689201f395c6b90dfe87127685f8dbfc083a5e779e613575d8bd7314300c3e" dependencies = [ "bitvec", - "rand_core 0.6.3", + "rand_core", "subtle", ] @@ -469,25 +467,15 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" +checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" dependencies = [ "cfg-if", "libc", "wasi", ] -[[package]] -name = "ghash" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1583cc1656d7839fd3732b80cf4f38850336cdb9b8ded1cd399ca62958de3c99" -dependencies = [ - "opaque-debug", - "polyval", -] - [[package]] name = "glob" version = "0.3.0" @@ -501,7 +489,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c363a5301b8f153d80747126a04b3c82073b9fe3130571a9d170cacdeaf7912" dependencies = [ "ff 0.10.1", - "rand_core 0.6.3", + "rand_core", "subtle", ] @@ -512,7 +500,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7391856def869c1c81063a03457c676fbcd419709c3dfb33d8d319de484b154d" dependencies = [ "ff 0.12.0", - "rand_core 0.6.3", + "rand_core", "subtle", ] @@ -527,11 +515,13 @@ dependencies = [ [[package]] name = "heapless" -version = "0.7.10" +version = "0.7.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d076121838e03f862871315477528debffdb7462fb229216ecef91b1a3eb31eb" +checksum = "db04bc24a18b9ea980628ecf00e6c0264f3c1426dac36c00cb49b6fbad8b0743" dependencies = [ + "atomic-polyfill", "hash32", + "rustc_version 0.4.0", "spin", "stable_deref_trait", ] @@ -580,26 +570,6 @@ dependencies = [ "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "hpke" -version = "0.9.0" -source = "git+https://github.com/rozbb/rust-hpke?rev=9230db267819f5795a47510139f4f1a60688ce82#9230db267819f5795a47510139f4f1a60688ce82" -dependencies = [ - "aead 0.4.3", - "aes-gcm", - "byteorder", - "chacha20poly1305", - "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", - "generic-array", - "hkdf 0.12.3", - "hmac 0.12.1", - "rand_core 0.6.3", - "sha2 0.10.2", - "subtle", - "x25519-dalek", - "zeroize", -] - [[package]] name = "inout" version = "0.1.3" @@ -612,9 +582,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.1" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" +checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" [[package]] name = "jobserver" @@ -627,30 +597,35 @@ dependencies = [ [[package]] name = "keccak" -version = "0.1.0" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" +checksum = "f9b7d56ba4a8344d6be9729995e6b06f928af29998cdf79fe390cbf6b1fee838" [[package]] name = "kem" version = "0.2.0" dependencies = [ "generic-array", - "hpke", "p256", "pqcrypto", "pqcrypto-traits", "rand", - "rand_core 0.6.3", + "rand_core", "x3dh-ke", "zeroize", ] +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + [[package]] name = "libc" -version = "0.2.125" +version = "0.2.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b" +checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5" [[package]] name = "lock_api" @@ -662,6 +637,27 @@ dependencies = [ "scopeguard", ] +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "nb" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f" +dependencies = [ + "nb 1.0.0", +] + +[[package]] +name = "nb" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "546c37ac5d9e56f55e73b677106873d9d9f5190605e41a856503623648488cae" + [[package]] name = "opaque-debug" version = "0.3.0" @@ -684,7 +680,7 @@ name = "password-hash" version = "0.4.2" dependencies = [ "base64ct", - "rand_core 0.6.3", + "rand_core", "subtle", ] @@ -728,29 +724,6 @@ dependencies = [ "spki 0.6.0", ] -[[package]] -name = "poly1305" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "048aeb476be11a4b6ca432ca569e375810de9294ae78f4774e78ea98a9246ede" -dependencies = [ - "cpufeatures", - "opaque-debug", - "universal-hash 0.4.1", -] - -[[package]] -name = "polyval" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8419d2b623c7c0896ff2d5d96e2cb4ede590fed28fcc34934f4c33c036e620a1" -dependencies = [ - "cfg-if", - "cpufeatures", - "opaque-debug", - "universal-hash 0.4.1", -] - [[package]] name = "ppv-lite86" version = "0.2.16" @@ -800,18 +773,18 @@ checksum = "97e91cb6af081c6daad5fa705f8adb0634c027662052cb3174bdf2957bf07e25" [[package]] name = "proc-macro2" -version = "1.0.38" +version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9027b48e9d4c9175fa2218adf3557f91c1137021739951d4932f5f8268ac48aa" +checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab" dependencies = [ - "unicode-xid", + "unicode-ident", ] [[package]] name = "quote" -version = "1.0.18" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" +checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" dependencies = [ "proc-macro2", ] @@ -830,7 +803,7 @@ checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha", - "rand_core 0.6.3", + "rand_core", ] [[package]] @@ -840,15 +813,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core 0.6.3", + "rand_core", ] -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" - [[package]] name = "rand_core" version = "0.6.3" @@ -858,11 +825,67 @@ dependencies = [ "getrandom", ] +[[package]] +name = "regex" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" + +[[package]] +name = "riscv" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6907ccdd7a31012b70faf2af85cd9e5ba97657cc3987c4f13f8e4d2c2a088aba" +dependencies = [ + "bare-metal 1.0.0", + "bit_field", + "riscv-target", +] + +[[package]] +name = "riscv-target" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88aa938cda42a0cf62a20cfe8d139ff1af20c2e681212b5b34adb5a58333f222" +dependencies = [ + "lazy_static", + "regex", +] + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver 0.9.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver 1.0.13", +] + [[package]] name = "ryu" -version = "1.0.9" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" +checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" [[package]] name = "scopeguard" @@ -885,29 +908,50 @@ dependencies = [ "zeroize", ] +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93f6841e709003d68bb2deee8c343572bf446003ec20a583e76f7b15cebf3711" + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + [[package]] name = "serde" -version = "1.0.137" +version = "1.0.144" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" +checksum = "0f747710de3dcd43b88c9168773254e809d8ddbdf9653b84e2554ab219f17860" dependencies = [ "serde_derive", ] [[package]] name = "serde_bytes" -version = "0.11.6" +version = "0.11.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "212e73464ebcde48d723aa02eb270ba62eff38a9b732df31f33f1b4e145f3a54" +checksum = "cfc50e8183eeeb6178dcb167ae34a8051d63535023ae38b5d8d12beae193d37b" dependencies = [ "serde", ] [[package]] name = "serde_derive" -version = "1.0.137" +version = "1.0.144" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" +checksum = "94ed3a816fb1d101812f83e789f888322c34e291f894f19590dc310963e87a00" dependencies = [ "proc-macro2", "quote", @@ -916,9 +960,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.83" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38dd04e3c8279e75b31ef29dbdceebfe5ad89f4d0937213c53f7d49d01b3d5a7" +checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44" dependencies = [ "itoa", "ryu", @@ -976,7 +1020,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2807892cfa58e081aa1f1111391c7a0649d4fa127a4ffbe34bcbfb35a1171a4" dependencies = [ "digest 0.9.0", - "rand_core 0.6.3", + "rand_core", ] [[package]] @@ -985,7 +1029,7 @@ version = "1.6.0" dependencies = [ "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal", - "rand_core 0.6.3", + "rand_core", "sha2 0.10.2", "signature_derive", ] @@ -1002,9 +1046,9 @@ dependencies = [ [[package]] name = "spin" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c530c2b0d0bf8b69304b39fe2001993e267461948b890cd037d8ad4293fa1a0d" +checksum = "7f6002a767bff9e83f8eeecf883ecb8011875a21ae8da43bffb817a57e78cc09" dependencies = [ "lock_api", ] @@ -1042,13 +1086,13 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.92" +version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ff7c592601f11445996a06f8ad0c27f094a58857c2f89e97974ab9235b92c52" +checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13" dependencies = [ "proc-macro2", "quote", - "unicode-xid", + "unicode-ident", ] [[package]] @@ -1076,20 +1120,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" [[package]] -name = "unicode-xid" -version = "0.2.3" +name = "unicode-ident" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04" +checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf" [[package]] -name = "universal-hash" -version = "0.4.1" +name = "unicode-xid" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05" -dependencies = [ - "generic-array", - "subtle", -] +checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04" [[package]] name = "universal-hash" @@ -1099,6 +1139,12 @@ dependencies = [ "subtle", ] +[[package]] +name = "vcell" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002" + [[package]] name = "version_check" version = "0.9.4" @@ -1106,29 +1152,33 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] -name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" +name = "void" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" [[package]] -name = "wyz" -version = "0.5.0" +name = "volatile-register" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30b31594f29d27036c383b53b59ed3476874d518f0efb151b27a4c275141390e" +checksum = "9ee8f19f9d74293faf70901bc20ad067dc1ad390d2cbf1e3f75f721ffee908b6" dependencies = [ - "tap", + "vcell", ] [[package]] -name = "x25519-dalek" -version = "2.0.0-pre.1" +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wyz" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5da623d8af10a62342bcbbb230e33e58a63255a58012f8653c578e54bab48df" +checksum = "30b31594f29d27036c383b53b59ed3476874d518f0efb151b27a4c275141390e" dependencies = [ - "curve25519-dalek", - "rand_core 0.6.3", - "zeroize", + "tap", ] [[package]] @@ -1143,7 +1193,7 @@ dependencies = [ "getrandom", "hkdf 0.11.0", "p256", - "rand_core 0.6.3", + "rand_core", "serde", "serde_bytes", "sha2 0.9.9", @@ -1154,18 +1204,3 @@ name = "zeroize" version = "1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f8f187641dad4f680d25c4bfc4225b418165984179f26ca76ec4fb6441d3a17" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] diff --git a/kem/Cargo.toml b/kem/Cargo.toml index b7e246c57..326865c96 100644 --- a/kem/Cargo.toml +++ b/kem/Cargo.toml @@ -24,11 +24,13 @@ p256 = { version = "0.9", features = [ "ecdsa" ] } pqcrypto = { version = "0.15", default-features = false, features = [ "pqcrypto-saber" ] } pqcrypto-traits = "0.3" -[dev-dependencies.hpke] -git = "https://github.com/rozbb/rust-hpke" -rev = "9230db267819f5795a47510139f4f1a60688ce82" -default-features = false -features = [ "x25519" ] +# rust-hpke causes compilation issues, so it's temporarily disabled, see: +# https://github.com/RustCrypto/traits/pull/1088 +# [dev-dependencies.hpke] +# git = "https://github.com/rozbb/rust-hpke" +# rev = "9230db267819f5795a47510139f4f1a60688ce82" +# default-features = false +# features = [ "x25519" ] [features] default = [] diff --git a/kem/tests/hpke.rs b/kem/tests/hpke.rs index 0b5d07b3f..680e03a18 100644 --- a/kem/tests/hpke.rs +++ b/kem/tests/hpke.rs @@ -1,3 +1,5 @@ +#![cfg(disable_hpke)] + use hpke::{ kem::{Kem as KemTrait, X25519HkdfSha256}, Deserializable as HpkeDeserializable, Serializable as HpkeSerializable, From 652088f22d0245270cc5622a4495dd80009e4cf4 Mon Sep 17 00:00:00 2001 From: Michael Rosenberg Date: Mon, 22 Aug 2022 14:47:46 -0400 Subject: [PATCH 0851/1461] KEM: Updated HPKE deps for testing (#1090) --- kem/Cargo.toml | 16 +++++++++------- kem/tests/hpke.rs | 2 -- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/kem/Cargo.toml b/kem/Cargo.toml index 326865c96..60cc0e567 100644 --- a/kem/Cargo.toml +++ b/kem/Cargo.toml @@ -24,13 +24,15 @@ p256 = { version = "0.9", features = [ "ecdsa" ] } pqcrypto = { version = "0.15", default-features = false, features = [ "pqcrypto-saber" ] } pqcrypto-traits = "0.3" -# rust-hpke causes compilation issues, so it's temporarily disabled, see: -# https://github.com/RustCrypto/traits/pull/1088 -# [dev-dependencies.hpke] -# git = "https://github.com/rozbb/rust-hpke" -# rev = "9230db267819f5795a47510139f4f1a60688ce82" -# default-features = false -# features = [ "x25519" ] +# We use an hpke commit that pulls in x25519-dalek v2.0.0-pre.1. This is necessary because all the +# modern crates (including this one) use zeroize >1.3, which is incompatible with the previous +# x25519-dalek version. Once the next x25519-dalek version is cut, the next hpke version will be +# cut, and this commit-based dependency can go away. +[dev-dependencies.hpke] +git = "https://github.com/rozbb/rust-hpke" +rev = "18eda000f27a871f360c283b30407a95169d7d58" +default-features = false +features = [ "x25519" ] [features] default = [] diff --git a/kem/tests/hpke.rs b/kem/tests/hpke.rs index 680e03a18..0b5d07b3f 100644 --- a/kem/tests/hpke.rs +++ b/kem/tests/hpke.rs @@ -1,5 +1,3 @@ -#![cfg(disable_hpke)] - use hpke::{ kem::{Kem as KemTrait, X25519HkdfSha256}, Deserializable as HpkeDeserializable, Serializable as HpkeSerializable, From 3c64565884661479ed760730fa193d38dac39200 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Aug 2022 09:24:43 -0600 Subject: [PATCH 0852/1461] build(deps): bump base64ct from 1.5.1 to 1.5.2 (#1092) Bumps [base64ct](https://github.com/RustCrypto/formats) from 1.5.1 to 1.5.2. - [Release notes](https://github.com/RustCrypto/formats/releases) - [Commits](https://github.com/RustCrypto/formats/compare/base64ct/v1.5.1...base64ct-v1.5.2) --- updated-dependencies: - dependency-name: base64ct dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 219 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 199 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0e67e0cf4..9db1e85ef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,6 +13,41 @@ dependencies = [ "heapless", ] +[[package]] +name = "aead" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c192eb8f11fc081b0fe4259ba5af04217d4e0faddd02417310a927911abd7c8" +dependencies = [ + "crypto-common 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "generic-array", +] + +[[package]] +name = "aes" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfe0133578c0986e1fe3dfcd4af1cc5b2dd6c3dbf534d69916ce16a2701d40ba" +dependencies = [ + "cfg-if", + "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cpufeatures", +] + +[[package]] +name = "aes-gcm" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82e1366e0c69c9f927b1fa5ce2c7bf9eafc8f9268c0b9800729e8b267612447c" +dependencies = [ + "aead 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "aes", + "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "ctr", + "ghash", + "subtle", +] + [[package]] name = "aho-corasick" version = "0.7.18" @@ -79,9 +114,9 @@ checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" [[package]] name = "base64ct" -version = "1.5.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bdca834647821e0b13d9539a8634eb62d3501b6b6c2cec1722786ee6671b851" +checksum = "ea2b2456fd614d856680dcd9fcc660a51a820fa09daef2e49772b56a193c8474" [[package]] name = "bincode" @@ -176,6 +211,30 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chacha20" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7fc89c7c5b9e7a02dfe45cd2367bae382f9ed31c61ca8debe5f827c420a2f08" +dependencies = [ + "cfg-if", + "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cpufeatures", +] + +[[package]] +name = "chacha20poly1305" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" +dependencies = [ + "aead 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "chacha20", + "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "poly1305", + "zeroize", +] + [[package]] name = "cipher" version = "0.4.3" @@ -194,6 +253,7 @@ checksum = "d1873270f8f7942c191139cb8a40fd228da6c3fd2fc376d7e92d47aa14aeb59e" dependencies = [ "crypto-common 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "inout", + "zeroize", ] [[package]] @@ -245,14 +305,14 @@ dependencies = [ name = "crypto" version = "0.4.0" dependencies = [ - "aead", + "aead 0.5.1", "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "crypto-common 0.1.6", "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "elliptic-curve 0.12.3", "password-hash", "signature 1.6.0", - "universal-hash", + "universal-hash 0.5.0", ] [[package]] @@ -262,7 +322,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8658c15c5d921ddf980f7fe25b1e82f4b7a4083b2c4985fea4922edb8e43e07d" dependencies = [ "generic-array", - "rand_core", + "rand_core 0.6.3", "subtle", "zeroize", ] @@ -274,7 +334,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f2b443d17d49dad5ef0ede301c3179cc923b8822f3393b4d2c28c269dd4a122" dependencies = [ "generic-array", - "rand_core", + "rand_core 0.6.3", "subtle", "zeroize", ] @@ -284,7 +344,7 @@ name = "crypto-common" version = "0.1.6" dependencies = [ "generic-array", - "rand_core", + "rand_core 0.6.3", "typenum", ] @@ -295,6 +355,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", + "rand_core 0.6.3", "typenum", ] @@ -308,6 +369,28 @@ dependencies = [ "subtle", ] +[[package]] +name = "ctr" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d14f329cfbaf5d0e06b5e87fff7e265d2673c5ea7d2c27691a2c107db1442a0" +dependencies = [ + "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "curve25519-dalek" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "subtle", + "zeroize", +] + [[package]] name = "der" version = "0.4.5" @@ -387,7 +470,7 @@ dependencies = [ "generic-array", "group 0.10.0", "pkcs8 0.7.6", - "rand_core", + "rand_core 0.6.3", "subtle", "zeroize", ] @@ -408,7 +491,7 @@ dependencies = [ "hkdf 0.12.3", "pem-rfc7468 0.6.0", "pkcs8 0.9.0", - "rand_core", + "rand_core 0.6.3", "sec1", "serde_json", "serdect", @@ -434,7 +517,7 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0f40b2dcd8bc322217a5f6559ae5f9e9d1de202a2ecee2e9eafcbece7562a4f" dependencies = [ - "rand_core", + "rand_core 0.6.3", "subtle", ] @@ -445,7 +528,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df689201f395c6b90dfe87127685f8dbfc083a5e779e613575d8bd7314300c3e" dependencies = [ "bitvec", - "rand_core", + "rand_core 0.6.3", "subtle", ] @@ -476,6 +559,16 @@ dependencies = [ "wasi", ] +[[package]] +name = "ghash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d930750de5717d2dd0b8c0d42c076c0e884c81a73e6cab859bbd2339c71e3e40" +dependencies = [ + "opaque-debug", + "polyval", +] + [[package]] name = "glob" version = "0.3.0" @@ -489,7 +582,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c363a5301b8f153d80747126a04b3c82073b9fe3130571a9d170cacdeaf7912" dependencies = [ "ff 0.10.1", - "rand_core", + "rand_core 0.6.3", "subtle", ] @@ -500,7 +593,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7391856def869c1c81063a03457c676fbcd419709c3dfb33d8d319de484b154d" dependencies = [ "ff 0.12.0", - "rand_core", + "rand_core 0.6.3", "subtle", ] @@ -570,6 +663,26 @@ dependencies = [ "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "hpke" +version = "0.9.0" +source = "git+https://github.com/rozbb/rust-hpke?rev=18eda000f27a871f360c283b30407a95169d7d58#18eda000f27a871f360c283b30407a95169d7d58" +dependencies = [ + "aead 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "aes-gcm", + "byteorder", + "chacha20poly1305", + "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", + "generic-array", + "hkdf 0.12.3", + "hmac 0.12.1", + "rand_core 0.6.3", + "sha2 0.10.2", + "subtle", + "x25519-dalek", + "zeroize", +] + [[package]] name = "inout" version = "0.1.3" @@ -606,11 +719,12 @@ name = "kem" version = "0.2.0" dependencies = [ "generic-array", + "hpke", "p256", "pqcrypto", "pqcrypto-traits", "rand", - "rand_core", + "rand_core 0.6.3", "x3dh-ke", "zeroize", ] @@ -680,7 +794,7 @@ name = "password-hash" version = "0.4.2" dependencies = [ "base64ct", - "rand_core", + "rand_core 0.6.3", "subtle", ] @@ -724,6 +838,29 @@ dependencies = [ "spki 0.6.0", ] +[[package]] +name = "poly1305" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" +dependencies = [ + "cpufeatures", + "opaque-debug", + "universal-hash 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "polyval" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef234e08c11dfcb2e56f79fd70f6f2eb7f025c0ce2333e82f4f0518ecad30c6" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "ppv-lite86" version = "0.2.16" @@ -803,7 +940,7 @@ checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha", - "rand_core", + "rand_core 0.6.3", ] [[package]] @@ -813,9 +950,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.3", ] +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" + [[package]] name = "rand_core" version = "0.6.3" @@ -1020,7 +1163,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2807892cfa58e081aa1f1111391c7a0649d4fa127a4ffbe34bcbfb35a1171a4" dependencies = [ "digest 0.9.0", - "rand_core", + "rand_core 0.6.3", ] [[package]] @@ -1029,7 +1172,7 @@ version = "1.6.0" dependencies = [ "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal", - "rand_core", + "rand_core 0.6.3", "sha2 0.10.2", "signature_derive", ] @@ -1139,6 +1282,16 @@ dependencies = [ "subtle", ] +[[package]] +name = "universal-hash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d3160b73c9a19f7e2939a2fdad446c57c1bbbbf4d919d3213ff1267a580d8b5" +dependencies = [ + "crypto-common 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "subtle", +] + [[package]] name = "vcell" version = "0.1.3" @@ -1181,6 +1334,17 @@ dependencies = [ "tap", ] +[[package]] +name = "x25519-dalek" +version = "2.0.0-pre.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5da623d8af10a62342bcbbb230e33e58a63255a58012f8653c578e54bab48df" +dependencies = [ + "curve25519-dalek", + "rand_core 0.6.3", + "zeroize", +] + [[package]] name = "x3dh-ke" version = "0.1.5" @@ -1193,7 +1357,7 @@ dependencies = [ "getrandom", "hkdf 0.11.0", "p256", - "rand_core", + "rand_core 0.6.3", "serde", "serde_bytes", "sha2 0.9.9", @@ -1204,3 +1368,18 @@ name = "zeroize" version = "1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f8f187641dad4f680d25c4bfc4225b418165984179f26ca76ec4fb6441d3a17" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] From 73e46b1fd053bffaf8b320a843fd5a7ec0c5a7a9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Aug 2022 17:48:53 -0600 Subject: [PATCH 0853/1461] build(deps): bump sha2 from 0.10.2 to 0.10.3 (#1093) Bumps [sha2](https://github.com/RustCrypto/hashes) from 0.10.2 to 0.10.3. - [Release notes](https://github.com/RustCrypto/hashes/releases) - [Commits](https://github.com/RustCrypto/hashes/compare/sha2-v0.10.2...sha2-v0.10.3) --- updated-dependencies: - dependency-name: sha2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9db1e85ef..0ea15491c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -495,7 +495,7 @@ dependencies = [ "sec1", "serde_json", "serdect", - "sha2 0.10.2", + "sha2 0.10.3", "sha3", "subtle", "zeroize", @@ -677,7 +677,7 @@ dependencies = [ "hkdf 0.12.3", "hmac 0.12.1", "rand_core 0.6.3", - "sha2 0.10.2", + "sha2 0.10.3", "subtle", "x25519-dalek", "zeroize", @@ -1137,9 +1137,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55deaec60f81eefe3cce0dc50bda92d6d8e88f2a27df7c5033b42afeb1ed2676" +checksum = "899bf02746a2c92bf1053d9327dadb252b01af1f81f90cdb902411f518bc7215" dependencies = [ "cfg-if", "cpufeatures", @@ -1173,7 +1173,7 @@ dependencies = [ "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal", "rand_core 0.6.3", - "sha2 0.10.2", + "sha2 0.10.3", "signature_derive", ] From fae070d27c2b8e0ab46c7cbbe8d5378dd9d4c998 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Sat, 3 Sep 2022 02:01:51 +0300 Subject: [PATCH 0854/1461] Update Cargo.lock --- Cargo.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0ea15491c..77f459530 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -495,7 +495,7 @@ dependencies = [ "sec1", "serde_json", "serdect", - "sha2 0.10.3", + "sha2 0.10.5", "sha3", "subtle", "zeroize", @@ -677,7 +677,7 @@ dependencies = [ "hkdf 0.12.3", "hmac 0.12.1", "rand_core 0.6.3", - "sha2 0.10.3", + "sha2 0.10.5", "subtle", "x25519-dalek", "zeroize", @@ -743,9 +743,9 @@ checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5" [[package]] name = "lock_api" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" +checksum = "9f80bf5aacaf25cbfc8210d1cfb718f2bf3b11c4c54e5afe36c236853a8ec390" dependencies = [ "autocfg", "scopeguard", @@ -1137,9 +1137,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.3" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "899bf02746a2c92bf1053d9327dadb252b01af1f81f90cdb902411f518bc7215" +checksum = "cf9db03534dff993187064c4e0c05a5708d2a9728ace9a8959b77bedf415dac5" dependencies = [ "cfg-if", "cpufeatures", @@ -1148,9 +1148,9 @@ dependencies = [ [[package]] name = "sha3" -version = "0.10.2" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a31480366ec990f395a61b7c08122d99bd40544fdb5abcfc1b06bb29994312c" +checksum = "eaedf34ed289ea47c2b741bb72e5357a209512d67bcd4bda44359e5bf0470f56" dependencies = [ "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "keccak", @@ -1173,7 +1173,7 @@ dependencies = [ "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal", "rand_core 0.6.3", - "sha2 0.10.3", + "sha2 0.10.5", "signature_derive", ] From 9d1b5b3c7e1877cf298d8272a7f6b582c0e1ab1d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 8 Sep 2022 20:45:52 -0600 Subject: [PATCH 0855/1461] signature_derive: remove `synstructure` dependency (#1100) It wasn't actually being used for anything structural, but rather for its higher-level proc macro API and testing facilities. However, both of those aren't too hard to replace, using `syn` for testing (via `parse_quote!`) --- Cargo.lock | 1 - signature/derive/Cargo.toml | 1 - signature/derive/src/lib.rs | 225 ++++++++++++++++++++---------------- 3 files changed, 123 insertions(+), 104 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 77f459530..a6c149806 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1184,7 +1184,6 @@ dependencies = [ "proc-macro2", "quote", "syn", - "synstructure", ] [[package]] diff --git a/signature/derive/Cargo.toml b/signature/derive/Cargo.toml index 12e82ea4d..9fe117929 100644 --- a/signature/derive/Cargo.toml +++ b/signature/derive/Cargo.toml @@ -19,4 +19,3 @@ proc-macro = true proc-macro2 = "1" quote = "1" syn = "1" -synstructure = "0.12.2" diff --git a/signature/derive/src/lib.rs b/signature/derive/src/lib.rs index e54227302..59fdfaf7b 100644 --- a/signature/derive/src/lib.rs +++ b/signature/derive/src/lib.rs @@ -1,142 +1,163 @@ #![crate_type = "proc-macro"] #![doc = include_str!("../README.md")] -#![deny(warnings, unused_import_braces, unused_qualifications)] #![forbid(unsafe_code)] +#![warn( + clippy::unwrap_used, + rust_2018_idioms, + trivial_casts, + unused_import_braces, + unused_qualifications +)] -extern crate proc_macro; - -use proc_macro2::TokenStream; +use proc_macro::TokenStream; +use proc_macro2::TokenStream as TokenStream2; use quote::quote; -use synstructure::{decl_derive, AddBounds}; +use syn::{parse_macro_input, DeriveInput}; + +/// Derive the [`Signer`] trait for a type which impls [`DigestSigner`]. +/// +/// When implementing the [`DigestSigner`] trait for a signature type which +/// itself impl's the [`PrehashSignature`] trait (which marks signature +/// algorithms which are computed using a [`Digest`]), signature providers +/// can automatically derive the [`Signer`] trait when the digest algorithm +/// is [`PrehashSignature::Digest`] (i.e. the "standard" digest algorithm +/// for a given signature type) +/// +/// This automates all of the digest computation otherwise needed for a +/// complete signature algorithm implementation. +/// +/// [`Digest`]: https://docs.rs/digest/latest/digest/trait.Digest.html +/// [`DigestSigner`]: https://docs.rs/signature/latest/signature/trait.DigestSigner.html +/// [`PrehashSignature`]: https://docs.rs/signature/latest/signature/trait.PrehashSignature.html +/// [`PrehashSignature::Digest`]: https://docs.rs/signature/latest/signature/trait.PrehashSignature.html#associated-types +#[proc_macro_derive(Signer)] +pub fn derive_signer(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as DeriveInput); + emit_signer_impl(input).into() +} -/// Derive the `Signer` trait for `DigestSigner` types -fn derive_signer(mut s: synstructure::Structure) -> TokenStream { - s.add_bounds(AddBounds::None); - s.gen_impl(quote! { - gen impl signature::Signer for @Self +fn emit_signer_impl(input: DeriveInput) -> TokenStream2 { + let ident = input.ident; + let type_params = input.generics.type_params().collect::>(); + let type_idents = type_params + .iter() + .map(|bound| bound.ident.clone()) + .collect::>(); + + quote! { + impl ::signature::Signer for #ident<#(#type_idents),*> where - S: signature::PrehashSignature, - Self: signature::DigestSigner + S: ::signature::PrehashSignature, + Self: ::signature::DigestSigner { - fn try_sign(&self, msg: &[u8]) -> Result { + fn try_sign(&self, msg: &[u8]) -> Result { self.try_sign_digest(S::Digest::new_with_prefix(msg)) } } - }) + } } -decl_derive! { - [Signer] => - /// Derive the [`Signer`] trait for a type which impls [`DigestSigner`]. - /// - /// When implementing the [`DigestSigner`] trait for a signature type which - /// itself impl's the [`PrehashSignature`] trait (which marks signature - /// algorithms which are computed using a [`Digest`]), signature providers - /// can automatically derive the [`Signer`] trait when the digest algorithm - /// is [`PrehashSignature::Digest`] (i.e. the "standard" digest algorithm - /// for a given signature type) - /// - /// This automates all of the digest computation otherwise needed for a - /// complete signature algorithm implementation. - /// - /// [`Digest`]: https://docs.rs/digest/latest/digest/trait.Digest.html - /// [`DigestSigner`]: https://docs.rs/signature/latest/signature/trait.DigestSigner.html - /// [`PrehashSignature`]: https://docs.rs/signature/latest/signature/trait.PrehashSignature.html - /// [`PrehashSignature::Digest`]: https://docs.rs/signature/latest/signature/trait.PrehashSignature.html#associated-types - derive_signer +/// Derive the [`Verifier`] trait for a type which impls [`DigestVerifier`]. +/// +/// When implementing the [`DigestVerifier`] trait for a signature type which +/// itself impl's the [`PrehashSignature`] trait (which marks signature +/// algorithms which are computed using a [`Digest`]), signature providers +/// can automatically derive the [`Verifier`] trait when the digest algorithm +/// is [`PrehashSignature::Digest`] (i.e. the "standard" digest algorithm +/// for a given signature type) +/// +/// This automates all of the digest computation otherwise needed for a +/// complete signature algorithm implementation. +/// +/// [`Digest`]: https://docs.rs/digest/latest/digest/trait.Digest.html +/// [`DigestVerifier`]: https://docs.rs/signature/latest/signature/trait.DigestVerifier.html +/// [`PrehashSignature`]: https://docs.rs/signature/latest/signature/trait.PrehashSignature.html +/// [`PrehashSignature::Digest`]: https://docs.rs/signature/latest/signature/trait.PrehashSignature.html#associated-types +#[proc_macro_derive(Verifier)] +pub fn derive_verifier(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as DeriveInput); + emit_verifier_impl(input).into() } -/// Derive the `Verifier` trait for `DigestVerifier` types -fn derive_verifier(mut s: synstructure::Structure) -> TokenStream { - s.add_bounds(AddBounds::None); - s.gen_impl(quote! { - gen impl signature::Verifier for @Self +fn emit_verifier_impl(input: DeriveInput) -> TokenStream2 { + let ident = input.ident; + let type_params = input.generics.type_params().collect::>(); + let type_idents = type_params + .iter() + .map(|bound| bound.ident.clone()) + .collect::>(); + + quote! { + impl ::signature::Verifier for #ident<#(#type_idents),*> where - S: signature::PrehashSignature, - Self: signature::DigestVerifier + S: ::signature::PrehashSignature, + Self: ::signature::DigestVerifier { - fn verify(&self, msg: &[u8], signature: &S) -> Result<(), signature::Error> { + fn verify(&self, msg: &[u8], signature: &S) -> Result<(), ::signature::Error> { self.verify_digest(S::Digest::new_with_prefix(msg), signature) } } - }) -} - -decl_derive! { - [Verifier] => - /// Derive the [`Verifier`] trait for a type which impls [`DigestVerifier`]. - /// - /// When implementing the [`DigestVerifier`] trait for a signature type which - /// itself impl's the [`PrehashSignature`] trait (which marks signature - /// algorithms which are computed using a [`Digest`]), signature providers - /// can automatically derive the [`Verifier`] trait when the digest algorithm - /// is [`PrehashSignature::Digest`] (i.e. the "standard" digest algorithm - /// for a given signature type) - /// - /// This automates all of the digest computation otherwise needed for a - /// complete signature algorithm implementation. - /// - /// [`Digest`]: https://docs.rs/digest/latest/digest/trait.Digest.html - /// [`DigestVerifier`]: https://docs.rs/signature/latest/signature/trait.DigestVerifier.html - /// [`PrehashSignature`]: https://docs.rs/signature/latest/signature/trait.PrehashSignature.html - /// [`PrehashSignature::Digest`]: https://docs.rs/signature/latest/signature/trait.PrehashSignature.html#associated-types - derive_verifier + } } #[cfg(test)] mod tests { use super::*; - use synstructure::test_derive; + use syn::parse_quote; #[test] fn signer() { - test_derive! { - derive_signer { - struct MySigner { - scalar: Scalar - } + let input = parse_quote! { + #[derive(Signer)] + struct MySigner { + scalar: Scalar } - expands to { - #[allow(non_upper_case_globals)] - const _DERIVE_signature_Signer_S_FOR_MySigner: () = { - impl signature::Signer for MySigner - where - S: signature::PrehashSignature, - Self: signature::DigestSigner - { - fn try_sign(&self, msg: &[u8]) -> Result { - self.try_sign_digest(S::Digest::new_with_prefix(msg)) - } + }; + + let output = emit_signer_impl(input); + + assert_eq!( + output.to_string(), + quote! { + impl ::signature::Signer for MySigner + where + S: ::signature::PrehashSignature, + Self: ::signature::DigestSigner + { + fn try_sign(&self, msg: &[u8]) -> Result { + self.try_sign_digest(S::Digest::new_with_prefix(msg)) } - }; + } } - no_build // tests in `signature-crate/tests` - } + .to_string() + ); } #[test] fn verifier() { - test_derive! { - derive_verifier { - struct MyVerifier { - point: UncompressedPoint - } + let input = parse_quote! { + #[derive(Verifier)] + struct MyVerifier { + point: UncompressedPoint } - expands to { - #[allow(non_upper_case_globals)] - const _DERIVE_signature_Verifier_S_FOR_MyVerifier: () = { - impl signature::Verifier for MyVerifier - where - S: signature::PrehashSignature, - Self: signature::DigestVerifier - { - fn verify(&self, msg: &[u8], signature: &S) -> Result<(), signature::Error> { - self.verify_digest(S::Digest::new_with_prefix(msg), signature) - } + }; + + let output = emit_verifier_impl(input); + + assert_eq!( + output.to_string(), + quote! { + impl ::signature::Verifier for MyVerifier + where + S: ::signature::PrehashSignature, + Self: ::signature::DigestVerifier + { + fn verify(&self, msg: &[u8], signature: &S) -> Result<(), ::signature::Error> { + self.verify_digest(S::Digest::new_with_prefix(msg), signature) } - }; + } } - no_build // tests in `signature-crate/tests` - } + .to_string() + ); } } From 726e5cd96e75099185e7fc6870525010e044bee2 Mon Sep 17 00:00:00 2001 From: KizzyCode Date: Fri, 9 Sep 2022 15:57:29 +0200 Subject: [PATCH 0856/1461] elliptic-curve: add to_sec1_bytes (#1102) --- elliptic-curve/src/public_key.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index 1dc858581..f5ca8887b 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -37,6 +37,9 @@ use pkcs8::EncodePublicKey; #[cfg(any(feature = "jwk", feature = "pem"))] use alloc::string::{String, ToString}; +#[cfg(feature = "alloc")] +use alloc::boxed::Box; + /// Elliptic curve public keys. /// /// This is a wrapper type for [`AffinePoint`] which ensures an inner @@ -121,6 +124,23 @@ where Option::from(Self::from_encoded_point(&point)).ok_or(Error) } + /// Convert this [`PublicKey`] into the + /// `Elliptic-Curve-Point-to-Octet-String` encoding described in + /// SEC 1: Elliptic Curve Cryptography (Version 2.0) section 2.3.3 + /// (page 10). + /// + /// + #[cfg(feature = "alloc")] + pub fn to_sec1_bytes(&self) -> Box<[u8]> + where + C: Curve + ProjectiveArithmetic + PointCompression, + AffinePoint: FromEncodedPoint + ToEncodedPoint, + FieldSize: ModulusSize, + { + let point = EncodedPoint::::from(self); + point.to_bytes() + } + /// Borrow the inner [`AffinePoint`] from this [`PublicKey`]. /// /// In ECC, public keys are elliptic curve points. From db853f17c7103698ca61cf8e3e3845eb4fce885b Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 9 Sep 2022 08:07:54 -0600 Subject: [PATCH 0857/1461] signature: add `hazmat-preview` feature (#1099) Adds a `hazmat` module gated under a newly added `hazmat-preview` feature which calls out the relevant functionality as subject to change with minor versions. It adds the following traits: - `PrehashSigner` - `PrehashVerifier` These APIs accept the digest to be signed/verified as a raw byte slice. This comes with potential misuses like failing to use a cryptographically secure hash function as the `prehash`, which could enable existential forgeries of signatures, hence gating it under a `hazmat-preview` feature and placing it in a `hazmat` module. Note that we previously explored APIs like this for `DigestSigner`. They were removed in RustCrypto/signatures#17 due to the afforementioned misuse potential. However, these APIs are occasionally needed for implementing protocols that use special rules for computing hashes (e.g. EIP-712 structured hashes), or for implementing things like network signing services which want to accept a prehash of a message to be signed rather than the full message (to cut down on network bandwidth). The traits accept a byte slice `prehash`, which permits multiple lengths and allows the implementation to decide which lengths are valid. This makes it possible for e.g. ECDSA implementations to automatically truncate message prehashes which are larger than the field size. --- .github/workflows/signature.yml | 6 +++- signature/Cargo.toml | 1 + signature/src/hazmat.rs | 49 +++++++++++++++++++++++++++++++++ signature/src/lib.rs | 16 +++++++---- 4 files changed, 65 insertions(+), 7 deletions(-) create mode 100644 signature/src/hazmat.rs diff --git a/.github/workflows/signature.yml b/.github/workflows/signature.yml index f96dbea0c..922f032e9 100644 --- a/.github/workflows/signature.yml +++ b/.github/workflows/signature.yml @@ -36,7 +36,11 @@ jobs: target: ${{ matrix.target }} override: true profile: minimal - - run: cargo build --no-default-features --release --target ${{ matrix.target }} + - run: cargo build --target ${{ matrix.target }} --release --no-default-features + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features derive-preview + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features digest-preview + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features hazmat-preview + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features rand-preview minimal-versions: uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 6c593523a..0c24eda49 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -29,6 +29,7 @@ std = [] # See https://docs.rs/signature/latest/signature/#unstable-features for more information. derive-preview = ["digest-preview", "signature_derive"] digest-preview = ["digest"] +hazmat-preview = [] rand-preview = ["rand_core"] [package.metadata.docs.rs] diff --git a/signature/src/hazmat.rs b/signature/src/hazmat.rs new file mode 100644 index 000000000..348cb20c8 --- /dev/null +++ b/signature/src/hazmat.rs @@ -0,0 +1,49 @@ +//! Hazardous Materials: low-level APIs which can be insecure if misused. +//! +//! The traits in this module are not generally recommended, and should only be +//! used in special cases where they are specifically needed. +//! +//! Using them incorrectly can introduce security vulnerabilities. Please +//! carefully read the documentation before attempting to use them. +//! +//! To use them, enable the `hazmat-preview` crate feature. Note that this +//! feature is semi-unstable and not subject to regular 1.x SemVer guarantees. +//! However, any breaking changes will be accompanied with a minor version bump. + +use crate::{Error, Signature}; + +/// Sign the provided message prehash, returning a digital signature. +pub trait PrehashSigner { + /// Attempt to sign the given message digest, returning a digital signature + /// on success, or an error if something went wrong. + /// + /// The `prehash` parameter should be the output of a secure cryptographic + /// hash function. + /// + /// This API takes a `prehash` byte slice as there can potentially be many + /// compatible lengths for the message digest for a given concrete signature + /// algorithm. + /// + /// Allowed lengths are algorithm-dependent and up to a particular + /// implementation to decide. + fn try_sign_prehash(&self, prehash: &[u8]) -> Result; +} + +/// Verify the provided message prehash using `Self` (e.g. a public key) +pub trait PrehashVerifier { + /// Use `Self` to verify that the provided signature for a given message + /// `prehash` is authentic. + /// + /// The `prehash` parameter should be the output of a secure cryptographic + /// hash function. + /// + /// Returns `Error` if it is inauthentic or some other error occurred, or + /// otherwise returns `Ok(())`. + /// + /// # ⚠️ Security Warning + /// + /// If `prehash` is something other than the output of a cryptographically + /// secure hash function, an attacker can potentially forge signatures by + /// solving a system of linear equations. + fn verify_prehash(&self, prehash: &[u8], signature: &S) -> Result<(), Error>; +} diff --git a/signature/src/lib.rs b/signature/src/lib.rs index 022f22188..6f7cc7899 100644 --- a/signature/src/lib.rs +++ b/signature/src/lib.rs @@ -164,6 +164,16 @@ compile_error!( Use the `rand-preview` feature instead." ); +#[cfg(feature = "hazmat-preview")] +#[cfg_attr(docsrs, doc(cfg(feature = "hazmat-preview")))] +pub mod hazmat; + +mod error; +mod keypair; +mod signature; +mod signer; +mod verifier; + #[cfg(feature = "derive-preview")] #[cfg_attr(docsrs, doc(cfg(feature = "derive-preview")))] pub use signature_derive::{Signer, Verifier}; @@ -175,10 +185,4 @@ pub use digest; #[cfg_attr(docsrs, doc(cfg(feature = "rand-preview")))] pub use rand_core; -mod error; -mod keypair; -mod signature; -mod signer; -mod verifier; - pub use crate::{error::*, keypair::*, signature::*, signer::*, verifier::*}; From 2711ff5ad0719dacc588dcad3d0f5b835e347598 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 9 Sep 2022 11:25:19 -0600 Subject: [PATCH 0858/1461] signature_derive: `DigestSigner`/`DigestVerifier` support (#1103) Adds support for deriving `DigestSigner`/`DigestVerifier` for types which impl `hazmat::{PrehashSigner, PrehashVerifier}`. Custom derive is used instead of a blanket impl in case implementations wish to specialize the `Digest*` impls. For example, they may want to use the `Digest` parameter elsewhere, for example as the hash function HMAC-DRBG is instantiated with for RFC6979. --- signature/derive/src/lib.rs | 173 ++++++++++++++++-- signature/src/hazmat.rs | 2 +- signature/src/lib.rs | 7 + .../tests/{signature_derive.rs => derive.rs} | 20 +- 4 files changed, 174 insertions(+), 28 deletions(-) rename signature/tests/{signature_derive.rs => derive.rs} (74%) diff --git a/signature/derive/src/lib.rs b/signature/derive/src/lib.rs index 59fdfaf7b..f4f3fdfc4 100644 --- a/signature/derive/src/lib.rs +++ b/signature/derive/src/lib.rs @@ -12,7 +12,7 @@ use proc_macro::TokenStream; use proc_macro2::TokenStream as TokenStream2; use quote::quote; -use syn::{parse_macro_input, DeriveInput}; +use syn::{parse_macro_input, DeriveInput, Ident, TypeParam}; /// Derive the [`Signer`] trait for a type which impls [`DigestSigner`]. /// @@ -37,12 +37,10 @@ pub fn derive_signer(input: TokenStream) -> TokenStream { } fn emit_signer_impl(input: DeriveInput) -> TokenStream2 { - let ident = input.ident; - let type_params = input.generics.type_params().collect::>(); - let type_idents = type_params - .iter() - .map(|bound| bound.ident.clone()) - .collect::>(); + let params = DeriveParams::new(input); + let ident = ¶ms.ident; + let type_params = ¶ms.type_params; + let type_idents = params.type_idents(); quote! { impl ::signature::Signer for #ident<#(#type_idents),*> @@ -50,7 +48,7 @@ fn emit_signer_impl(input: DeriveInput) -> TokenStream2 { S: ::signature::PrehashSignature, Self: ::signature::DigestSigner { - fn try_sign(&self, msg: &[u8]) -> Result { + fn try_sign(&self, msg: &[u8]) -> ::signature::Result { self.try_sign_digest(S::Digest::new_with_prefix(msg)) } } @@ -80,12 +78,10 @@ pub fn derive_verifier(input: TokenStream) -> TokenStream { } fn emit_verifier_impl(input: DeriveInput) -> TokenStream2 { - let ident = input.ident; - let type_params = input.generics.type_params().collect::>(); - let type_idents = type_params - .iter() - .map(|bound| bound.ident.clone()) - .collect::>(); + let params = DeriveParams::new(input); + let ident = ¶ms.ident; + let type_params = ¶ms.type_params; + let type_idents = params.type_idents(); quote! { impl ::signature::Verifier for #ident<#(#type_idents),*> @@ -93,13 +89,100 @@ fn emit_verifier_impl(input: DeriveInput) -> TokenStream2 { S: ::signature::PrehashSignature, Self: ::signature::DigestVerifier { - fn verify(&self, msg: &[u8], signature: &S) -> Result<(), ::signature::Error> { + fn verify(&self, msg: &[u8], signature: &S) -> ::signature::Result<()> { self.verify_digest(S::Digest::new_with_prefix(msg), signature) } } } } +/// Derive the [`DigestSigner`] trait for a type which impls [`PrehashSigner`]. +/// +/// [`DigestSigner`]: https://docs.rs/signature/latest/signature/trait.DigestSigner.html +/// [`PrehashSigner`]: https://docs.rs/signature/latest/signature/hazmat/trait.PrehashSigner.html +#[proc_macro_derive(DigestSigner)] +pub fn derive_digest_signer(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as DeriveInput); + emit_digest_signer_impl(input).into() +} + +fn emit_digest_signer_impl(input: DeriveInput) -> TokenStream2 { + let params = DeriveParams::new(input); + let ident = ¶ms.ident; + let type_params = ¶ms.type_params; + let type_idents = params.type_idents(); + + quote! { + impl ::signature::DigestSigner for #ident<#(#type_idents),*> + where + D: ::signature::digest::Digest, + S: ::signature::Signature, + Self: ::signature::hazmat::PrehashSigner + { + fn try_sign_digest(&self, digest: D) -> ::signature::Result { + self.sign_prehash(&digest.finalize()) + } + } + } +} + +/// Derive the [`DigestVerifier`] trait for a type which impls [`PrehashVerifier`]. +/// +/// [`DigestVerifier`]: https://docs.rs/signature/latest/signature/trait.DigestVerifier.html +/// [`PrehashVerifier`]: https://docs.rs/signature/latest/signature/hazmat/trait.PrehashVerifier.html +#[proc_macro_derive(DigestVerifier)] +pub fn derive_digest_verifier(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as DeriveInput); + emit_digest_verifier_impl(input).into() +} + +fn emit_digest_verifier_impl(input: DeriveInput) -> TokenStream2 { + let params = DeriveParams::new(input); + let ident = ¶ms.ident; + let type_params = ¶ms.type_params; + let type_idents = params.type_idents(); + + quote! { + impl ::signature::DigestVerifier for #ident<#(#type_idents),*> + where + D: ::signature::digest::Digest, + S: ::signature::Signature, + Self: ::signature::hazmat::PrehashVerifier + { + fn verify_digest(&self, digest: D, signature: &S) -> ::signature::Result<()> { + self.verify_prehash(&digest.finalize(), signature) + } + } + } +} + +/// Derivation parameters parsed from `DeriveInput`. +struct DeriveParams { + /// `Ident` for the struct the trait impls are being added to. + ident: Ident, + + /// Generic type parameters. + type_params: Vec, +} + +impl DeriveParams { + /// Parse parameters from `DeriveInput`. + fn new(input: DeriveInput) -> Self { + Self { + ident: input.ident, + type_params: input.generics.type_params().cloned().collect(), + } + } + + /// Get the `Ident`s which correspond to each of the `type_params`. + fn type_idents(&self) -> Vec { + self.type_params + .iter() + .map(|bound| bound.ident.clone()) + .collect() + } +} + #[cfg(test)] mod tests { use super::*; @@ -124,7 +207,7 @@ mod tests { S: ::signature::PrehashSignature, Self: ::signature::DigestSigner { - fn try_sign(&self, msg: &[u8]) -> Result { + fn try_sign(&self, msg: &[u8]) -> ::signature::Result { self.try_sign_digest(S::Digest::new_with_prefix(msg)) } } @@ -152,7 +235,7 @@ mod tests { S: ::signature::PrehashSignature, Self: ::signature::DigestVerifier { - fn verify(&self, msg: &[u8], signature: &S) -> Result<(), ::signature::Error> { + fn verify(&self, msg: &[u8], signature: &S) -> ::signature::Result<()> { self.verify_digest(S::Digest::new_with_prefix(msg), signature) } } @@ -160,4 +243,60 @@ mod tests { .to_string() ); } + + #[test] + fn digest_signer() { + let input = parse_quote! { + #[derive(DigestSigner)] + struct MySigner { + scalar: Scalar + } + }; + + let output = emit_digest_signer_impl(input); + + assert_eq!( + output.to_string(), + quote! { + impl ::signature::DigestSigner for MySigner + where + S: ::signature::Signature, + Self: ::signature::hazmat::PrehashSigner + { + fn try_sign_digest(&self, digest: D) -> ::signature::Result { + self.sign_prehash(&digest.finalize()) + } + } + } + .to_string() + ); + } + + #[test] + fn digest_verifier() { + let input = parse_quote! { + #[derive(DigestVerifier)] + struct MyVerifier { + point: UncompressedPoint + } + }; + + let output = emit_digest_verifier_impl(input); + + assert_eq!( + output.to_string(), + quote! { + impl ::signature::DigestVerifier for MyVerifier + where + S: ::signature::Signature, + Self: ::signature::hazmat::PrehashVerifier + { + fn verify_digest(&self, digest: D) -> ::signature::Result { + self.verify_prehash(&digest.finalize()) + } + } + } + .to_string() + ); + } } diff --git a/signature/src/hazmat.rs b/signature/src/hazmat.rs index 348cb20c8..4a117fcdb 100644 --- a/signature/src/hazmat.rs +++ b/signature/src/hazmat.rs @@ -26,7 +26,7 @@ pub trait PrehashSigner { /// /// Allowed lengths are algorithm-dependent and up to a particular /// implementation to decide. - fn try_sign_prehash(&self, prehash: &[u8]) -> Result; + fn sign_prehash(&self, prehash: &[u8]) -> Result; } /// Verify the provided message prehash using `Self` (e.g. a public key) diff --git a/signature/src/lib.rs b/signature/src/lib.rs index 6f7cc7899..ab504c2ac 100644 --- a/signature/src/lib.rs +++ b/signature/src/lib.rs @@ -178,6 +178,13 @@ mod verifier; #[cfg_attr(docsrs, doc(cfg(feature = "derive-preview")))] pub use signature_derive::{Signer, Verifier}; +#[cfg(all(feature = "derive-preview", feature = "digest-preview"))] +#[cfg_attr( + docsrs, + doc(cfg(all(feature = "derive-preview", feature = "digest-preview"))) +)] +pub use signature_derive::{DigestSigner, DigestVerifier}; + #[cfg(feature = "digest-preview")] pub use digest; diff --git a/signature/tests/signature_derive.rs b/signature/tests/derive.rs similarity index 74% rename from signature/tests/signature_derive.rs rename to signature/tests/derive.rs index bda95d6f9..5048dc682 100644 --- a/signature/tests/signature_derive.rs +++ b/signature/tests/derive.rs @@ -1,11 +1,12 @@ //! Tests for code generated by `signature_derive` -#![cfg(all(test, feature = "derive-preview"))] +#![cfg(all(feature = "derive-preview", feature = "hazmat-preview"))] use digest::{generic_array::GenericArray, Digest, OutputSizeUser}; use hex_literal::hex; use sha2::Sha256; use signature::{ + hazmat::{PrehashSigner, PrehashVerifier}, DigestSigner, DigestVerifier, Error, PrehashSignature, Signature, Signer, Verifier, }; @@ -39,12 +40,12 @@ impl PrehashSignature for DummySignature { } /// Dummy signer which just returns the message digest as a `DummySignature` -#[derive(Signer, Default)] +#[derive(Signer, DigestSigner, Default)] struct DummySigner {} -impl DigestSigner for DummySigner { - fn try_sign_digest(&self, digest: Sha256) -> Result { - DummySignature::from_bytes(&digest.finalize()) +impl PrehashSigner for DummySigner { + fn sign_prehash(&self, prehash: &[u8]) -> signature::Result { + DummySignature::from_bytes(prehash) } } @@ -52,13 +53,12 @@ impl DigestSigner for DummySigner { /// expected value. /// /// Panics (via `assert_eq!`) if the value is not what is expected. -#[derive(Verifier, Default)] +#[derive(Verifier, DigestVerifier, Default)] struct DummyVerifier {} -impl DigestVerifier for DummyVerifier { - fn verify_digest(&self, digest: Sha256, signature: &DummySignature) -> Result<(), Error> { - let actual_digest = digest.finalize(); - assert_eq!(signature.as_ref(), actual_digest.as_slice()); +impl PrehashVerifier for DummyVerifier { + fn verify_prehash(&self, prehash: &[u8], signature: &DummySignature) -> signature::Result<()> { + assert_eq!(signature.as_ref(), prehash); Ok(()) } } From 5d8051595e5efe322f436fec769806f8ea58f180 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 12 Sep 2022 12:41:05 -0600 Subject: [PATCH 0859/1461] signature_derive v1.0.0-pre.6 (#1104) --- Cargo.lock | 2 +- signature/Cargo.toml | 2 +- signature/derive/CHANGELOG.md | 10 ++++++++++ signature/derive/Cargo.toml | 2 +- 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a6c149806..71e6c4f26 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1179,7 +1179,7 @@ dependencies = [ [[package]] name = "signature_derive" -version = "1.0.0-pre.5" +version = "1.0.0-pre.6" dependencies = [ "proc-macro2", "quote", diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 0c24eda49..ea66c5634 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -15,7 +15,7 @@ categories = ["cryptography", "no-std"] [dependencies] digest = { version = "0.10.3", optional = true, default-features = false } rand_core = { version = "0.6", optional = true, default-features = false } -signature_derive = { version = "=1.0.0-pre.5", optional = true, path = "derive" } +signature_derive = { version = "=1.0.0-pre.6", optional = true, path = "derive" } [dev-dependencies] hex-literal = "0.3" diff --git a/signature/derive/CHANGELOG.md b/signature/derive/CHANGELOG.md index 6b21c134d..91be5cf9b 100644 --- a/signature/derive/CHANGELOG.md +++ b/signature/derive/CHANGELOG.md @@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 1.0.0-pre.6 (2022-09-12) +### Added +- `DigestSigner`/`DigestVerifier` support ([#1103]) + +### Removed +- `synstructure` dependency ([#1100]) + +[#1100]: https://github.com/RustCrypto/traits/pull/1100 +[#1103]: https://github.com/RustCrypto/traits/pull/1103 + ## 1.0.0-pre.5 (2022-08-14) ### Changed - Rust 2021 edition upgrade; MSRV 1.56 ([#1081]) diff --git a/signature/derive/Cargo.toml b/signature/derive/Cargo.toml index 9fe117929..d0ab77771 100644 --- a/signature/derive/Cargo.toml +++ b/signature/derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "signature_derive" -version = "1.0.0-pre.5" +version = "1.0.0-pre.6" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" description = "Custom derive support for the 'signature' crate" From 805d43233faff778c2cac0305c89cbf2ba06070d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 12 Sep 2022 13:21:45 -0600 Subject: [PATCH 0860/1461] signature v1.6.1 (#1105) --- Cargo.lock | 6 +++--- signature/CHANGELOG.md | 12 +++++++++++- signature/Cargo.toml | 2 +- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 71e6c4f26..9a48049cb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -62,7 +62,7 @@ name = "async-signature" version = "0.2.0" dependencies = [ "async-trait", - "signature 1.6.0", + "signature 1.6.1", ] [[package]] @@ -311,7 +311,7 @@ dependencies = [ "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "elliptic-curve 0.12.3", "password-hash", - "signature 1.6.0", + "signature 1.6.1", "universal-hash 0.5.0", ] @@ -1168,7 +1168,7 @@ dependencies = [ [[package]] name = "signature" -version = "1.6.0" +version = "1.6.1" dependencies = [ "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal", diff --git a/signature/CHANGELOG.md b/signature/CHANGELOG.md index f49c1e3d7..17aa2f378 100644 --- a/signature/CHANGELOG.md +++ b/signature/CHANGELOG.md @@ -4,7 +4,17 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 1.6.0 (2022-08-14) +## 1.6.1 (2022-09-12) +### Added +- `hazmat-preview` feature with `PrehashSigner`/`PrehashVerifier` traits ([#1099]) + +### Changed +- Bump `signature_derive` to v1.0.0-pre.6 ([#1104]) + +[#1099]: https://github.com/RustCrypto/traits/pull/1099 +[#1104]: https://github.com/RustCrypto/traits/pull/1104 + +## 1.6.0 (2022-08-14) [YANKED] ### Added - `Keypair` trait ([#1080]) diff --git a/signature/Cargo.toml b/signature/Cargo.toml index ea66c5634..6b6041d08 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "1.6.0" +version = "1.6.1" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/signature" From 72ab34d720d263533bbed3fa2c05ecb9ff047273 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Thu, 15 Sep 2022 17:14:11 +0000 Subject: [PATCH 0861/1461] digest: update examples in readme (#1109) --- digest/README.md | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/digest/README.md b/digest/README.md index 0a43d4751..c71a8d144 100644 --- a/digest/README.md +++ b/digest/README.md @@ -35,22 +35,22 @@ First add `blake2` crate to your `Cargo.toml`: ```toml [dependencies] -blake2 = "0.8" +sha2 = "0.10" ``` -`blake2` and other crates re-export `digest` crate and `Digest` trait for +`sha2` and other crates re-export `digest` crate and `Digest` trait for convenience, so you don't have to add `digest` crate as an explicit dependency. Now you can write the following code: ```rust -use blake2::{Blake2b, Digest}; +use sha2::{Sha256, Digest}; -let mut hasher = Blake2b::new(); +let mut hasher = Sha256::new(); let data = b"Hello world!"; -hasher.input(data); +hasher.update(data); // `input` can be called repeatedly and is generic over `AsRef<[u8]>` -hasher.input("String data"); +hasher.update("String data"); // Note that calling `finalize()` consumes hasher let hash = hasher.finalize(); println!("Result: {:x}", hash); @@ -63,9 +63,9 @@ Alternatively you can use chained approach, which is equivalent to the previous example: ```rust -let hash = Blake2b::new() - .chain(b"Hello world!") - .chain("String data") +let hash = Sha256::new() + .chain_update(b"Hello world!") + .chain_update("String data") .finalize(); println!("Result: {:x}", hash); @@ -74,7 +74,7 @@ println!("Result: {:x}", hash); If the whole message is available you also can use convinience `digest` method: ```rust -let hash = Blake2b::digest(b"my message"); +let hash = Sha256::digest(b"my message"); println!("Result: {:x}", hash); ``` @@ -84,11 +84,11 @@ If you want to hash data from [`Read`][3] trait (e.g. from file) you can rely on implementation of [`Write`][4] trait (requires enabled-by-default `std` feature): ```rust -use blake2::{Blake2b, Digest}; +use sha2::{Sha256, Digest}; use std::{fs, io}; let mut file = fs::File::open(&path)?; -let mut hasher = Blake2b::new(); +let mut hasher = Sha256::new(); let n = io::copy(&mut file, &mut hasher)?; let hash = hasher.finalize(); @@ -109,17 +109,17 @@ use digest::Digest; // Instead use crates from: https://github.com/RustCrypto/password-hashing fn hash_password(password: &str, salt: &str, output: &mut [u8]) { let mut hasher = D::new(); - hasher.input(password.as_bytes()); - hasher.input(b"$"); - hasher.input(salt.as_bytes()); + hasher.update(password.as_bytes()); + hasher.update(b"$"); + hasher.update(salt.as_bytes()); output.copy_from_slice(hasher.finalize().as_slice()) } -use blake2::Blake2b; -use sha2::Sha256; +let mut buf1 = [0u8; 32]; +let mut buf2 = [0u8; 64]; -hash_password::("my_password", "abcd", &mut buf); -hash_password::("my_password", "abcd", &mut buf); +hash_password::("my_password", "abcd", &mut buf1); +hash_password::("my_password", "abcd", &mut buf2); ``` If you want to use hash functions with trait objects, use `digest::DynDigest` From c593aa1e8f01667b5472524f04598915e7a46fe5 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Thu, 15 Sep 2022 21:06:55 +0300 Subject: [PATCH 0862/1461] signature: relax `Keypair` type bounds (#1107) * signature: relax Keypair boundaries The Keypair trait might be useful for representing relationship between DigestSigner and DigestVerifier, RandomizedSigner and RandomizedVerifier, etc. in addition to just Signer/Verfifier pair. Relax type boundaries for the Keypair trait. * async-signature: relax AsyncKeypair boundaries The AsyncKeypair trait might be useful for representing relationship between DigestSigner and DigestVerifier, RandomizedSigner and RandomizedVerifier, etc. in addition to just Signer/Verfifier pair. Relax type boundaries for the AsyncKeypair trait. Signed-off-by: Dmitry Baryshkov --- signature/async/src/lib.rs | 5 ++--- signature/src/keypair.rs | 6 +++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/signature/async/src/lib.rs b/signature/async/src/lib.rs index 50de8853b..0d77574ee 100644 --- a/signature/async/src/lib.rs +++ b/signature/async/src/lib.rs @@ -13,7 +13,6 @@ pub use signature::{self, Error, Signature}; pub use signature::digest::{self, Digest}; use async_trait::async_trait; -use signature::Verifier; /// Asynchronously sign the provided message bytestring using `Self` /// (e.g. client for a Cloud KMS or HSM), returning a digital signature. @@ -77,12 +76,12 @@ where /// Keypair with async signer component and an associated verifying key. /// /// This represents a type which holds both an async signing key and a verifying key. -pub trait AsyncKeypair: AsRef + AsyncSigner +pub trait AsyncKeypair: AsRef where S: Signature + Send + 'static, { /// Verifying key type for this keypair. - type VerifyingKey: Verifier; + type VerifyingKey; /// Get the verifying key which can verify signatures produced by the /// signing key portion of this keypair. diff --git a/signature/src/keypair.rs b/signature/src/keypair.rs index c5a55de6e..6d9f947c6 100644 --- a/signature/src/keypair.rs +++ b/signature/src/keypair.rs @@ -1,13 +1,13 @@ //! Signing keypairs. -use crate::{Signature, Signer, Verifier}; +use crate::Signature; /// Signing keypair with an associated verifying key. /// /// This represents a type which holds both a signing key and a verifying key. -pub trait Keypair: AsRef + Signer { +pub trait Keypair: AsRef { /// Verifying key type for this keypair. - type VerifyingKey: Verifier; + type VerifyingKey; /// Get the verifying key which can verify signatures produced by the /// signing key portion of this keypair. From 03e7beef5188b58b1730ea0532fe3ba01846cd44 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 15 Sep 2022 13:35:13 -0600 Subject: [PATCH 0863/1461] signature v1.6.2 (#1111) --- Cargo.lock | 6 +++--- signature/CHANGELOG.md | 8 +++++++- signature/Cargo.toml | 2 +- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9a48049cb..280ae5514 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -62,7 +62,7 @@ name = "async-signature" version = "0.2.0" dependencies = [ "async-trait", - "signature 1.6.1", + "signature 1.6.2", ] [[package]] @@ -311,7 +311,7 @@ dependencies = [ "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "elliptic-curve 0.12.3", "password-hash", - "signature 1.6.1", + "signature 1.6.2", "universal-hash 0.5.0", ] @@ -1168,7 +1168,7 @@ dependencies = [ [[package]] name = "signature" -version = "1.6.1" +version = "1.6.2" dependencies = [ "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal", diff --git a/signature/CHANGELOG.md b/signature/CHANGELOG.md index 17aa2f378..3959765f5 100644 --- a/signature/CHANGELOG.md +++ b/signature/CHANGELOG.md @@ -4,7 +4,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 1.6.1 (2022-09-12) +## 1.6.2 (2022-09-15) +### Changed +- Relax `Keypair` type bounds ([#1107]) + +[#1107]: https://github.com/RustCrypto/traits/pull/1107 + +## 1.6.1 (2022-09-12) [YANKED] ### Added - `hazmat-preview` feature with `PrehashSigner`/`PrehashVerifier` traits ([#1099]) diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 6b6041d08..9069213a9 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "1.6.1" +version = "1.6.2" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/signature" From efae60b6ab40631e52ad1346dd2dd1437ca45110 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 15 Sep 2022 14:05:30 -0600 Subject: [PATCH 0864/1461] async-signature: deprecate `AsyncKeypair` (#1112) As of #1107 this trait is shaped the same as `Keypair`, so there's no need for it to continue to exist. It will be removed in the next breaking release. --- signature/async/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/signature/async/src/lib.rs b/signature/async/src/lib.rs index 0d77574ee..fe12a3ca4 100644 --- a/signature/async/src/lib.rs +++ b/signature/async/src/lib.rs @@ -76,6 +76,7 @@ where /// Keypair with async signer component and an associated verifying key. /// /// This represents a type which holds both an async signing key and a verifying key. +#[deprecated(since = "0.2.1", note = "use signature::Keypair instead")] pub trait AsyncKeypair: AsRef where S: Signature + Send + 'static, @@ -90,6 +91,7 @@ where } } +#[allow(deprecated)] impl AsyncKeypair for T where S: Signature + Send + 'static, From 1b3f0c784029ef1d344c5c56c7a768e3772c6fef Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 15 Sep 2022 14:22:06 -0600 Subject: [PATCH 0865/1461] async-keypair v0.2.1 (#1113) --- Cargo.lock | 2 +- signature/async/CHANGELOG.md | 10 +++++++++- signature/async/Cargo.toml | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 280ae5514..56f417318 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -59,7 +59,7 @@ dependencies = [ [[package]] name = "async-signature" -version = "0.2.0" +version = "0.2.1" dependencies = [ "async-trait", "signature 1.6.2", diff --git a/signature/async/CHANGELOG.md b/signature/async/CHANGELOG.md index 77f2c6b9b..754c8d55a 100644 --- a/signature/async/CHANGELOG.md +++ b/signature/async/CHANGELOG.md @@ -4,7 +4,15 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 0.2.0 (2022-08-14) +## 0.2.1 (2022-09-15) +### Changed +- Relax `AsyncKeypair` bounds ([#1107]) +- Deprecate `AsyncKeypair` ([#1112]) + +[#1107]: https://github.com/RustCrypto/traits/pull/1107 +[#1112]: https://github.com/RustCrypto/traits/pull/1112 + +## 0.2.0 (2022-08-14) [YANKED] ### Added - `AsyncKeypair` trait ([#1085]) diff --git a/signature/async/Cargo.toml b/signature/async/Cargo.toml index f0779c619..c81957044 100644 --- a/signature/async/Cargo.toml +++ b/signature/async/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "async-signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "0.2.0" +version = "0.2.1" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/async-signature" From c9a8d738270675a3c1f401c546aa8d9560308c8b Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 15 Sep 2022 17:09:28 -0600 Subject: [PATCH 0866/1461] signature_derive: fix `Digest*` trait derivation (#1115) The derived code in the test fixtures is incorrect. Likewise, it seems there wasn't a proper CI job for this crate. This commit also includes fixes which ensure `signature_derive`'s tests are run in CI. --- .github/workflows/signature.yml | 18 ++++++++++++++++++ signature/derive/src/lib.rs | 6 ++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/.github/workflows/signature.yml b/.github/workflows/signature.yml index 922f032e9..dbe841f9b 100644 --- a/.github/workflows/signature.yml +++ b/.github/workflows/signature.yml @@ -66,3 +66,21 @@ jobs: - run: cargo test --no-default-features --release - run: cargo test --release - run: cargo test --all-features --release + + derive: + runs-on: ubuntu-latest + strategy: + matrix: + rust: + - 1.56.0 # MSRV + - stable + steps: + - uses: actions/checkout@v2 + - uses: RustCrypto/actions/cargo-cache@master + - uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ matrix.rust }} + override: true + profile: minimal + - run: cargo test --release + working-directory: signature/derive \ No newline at end of file diff --git a/signature/derive/src/lib.rs b/signature/derive/src/lib.rs index f4f3fdfc4..d47216cce 100644 --- a/signature/derive/src/lib.rs +++ b/signature/derive/src/lib.rs @@ -260,6 +260,7 @@ mod tests { quote! { impl ::signature::DigestSigner for MySigner where + D: ::signature::digest::Digest, S: ::signature::Signature, Self: ::signature::hazmat::PrehashSigner { @@ -288,11 +289,12 @@ mod tests { quote! { impl ::signature::DigestVerifier for MyVerifier where + D: ::signature::digest::Digest, S: ::signature::Signature, Self: ::signature::hazmat::PrehashVerifier { - fn verify_digest(&self, digest: D) -> ::signature::Result { - self.verify_prehash(&digest.finalize()) + fn verify_digest(&self, digest: D, signature: &S) -> ::signature::Result<()> { + self.verify_prehash(&digest.finalize(), signature) } } } From f7968a1141cf1765a01c2a404e3960b6ffdcab9d Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Fri, 16 Sep 2022 00:51:19 +0000 Subject: [PATCH 0867/1461] digest: add implementations of the AssociatedOid trait (#1098) --- .github/workflows/digest.yml | 27 +++++++++++-- Cargo.lock | 43 +++++++++++---------- digest/CHANGELOG.md | 7 ++++ digest/Cargo.toml | 4 +- digest/src/core_api/ct_variable.rs | 61 ++++++++++++++++++++++++------ digest/src/core_api/wrapper.rs | 13 +++++++ digest/src/lib.rs | 6 ++- 7 files changed, 122 insertions(+), 39 deletions(-) diff --git a/.github/workflows/digest.yml b/.github/workflows/digest.yml index 585de6cb7..51ee473b8 100644 --- a/.github/workflows/digest.yml +++ b/.github/workflows/digest.yml @@ -50,7 +50,7 @@ jobs: strategy: matrix: rust: - - 1.41.0 # MSRV + # - 1.41.0 # MSRV - stable steps: - uses: actions/checkout@v2 @@ -60,8 +60,6 @@ jobs: toolchain: ${{ matrix.rust }} override: true profile: minimal - # Isolate this crate from workspace which is otherwise MSRV 1.56 due to 2021 edition crates - - run: rm ../Cargo.toml - run: cargo check --all-features - run: cargo test --no-default-features - run: cargo test @@ -69,3 +67,26 @@ jobs: - run: cargo test --features alloc - run: cargo test --features std - run: cargo test --all-features + + # The `oid` feature bumps MSRV to 1.57, so we temporarily split this job. + test-msrv: + runs-on: ubuntu-latest + strategy: + matrix: + rust: + - 1.41.0 # MSRV + steps: + - uses: actions/checkout@v2 + - uses: RustCrypto/actions/cargo-cache@master + - uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ matrix.rust }} + override: true + profile: minimal + # Isolate this crate from workspace which is otherwise MSRV 1.56 due to 2021 edition crates + - run: rm ../Cargo.toml + - run: cargo test --no-default-features + - run: cargo test + - run: cargo test --features dev + - run: cargo test --features alloc + - run: cargo test --features std diff --git a/Cargo.lock b/Cargo.lock index 56f417318..b119b584b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -50,9 +50,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "0.7.18" +version = "0.7.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e" dependencies = [ "memchr", ] @@ -168,9 +168,9 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" +checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" dependencies = [ "generic-array", ] @@ -282,9 +282,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc948ebb96241bb40ab73effeb80d9f93afaad49359d159a5e61be51619fe813" +checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" dependencies = [ "libc", ] @@ -308,7 +308,7 @@ dependencies = [ "aead 0.5.1", "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "crypto-common 0.1.6", - "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.10.3", "elliptic-curve 0.12.3", "password-hash", "signature 1.6.2", @@ -423,21 +423,22 @@ dependencies = [ [[package]] name = "digest" version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" dependencies = [ - "blobby", - "block-buffer 0.10.2", - "crypto-common 0.1.6", + "block-buffer 0.10.3", + "crypto-common 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "subtle", ] [[package]] name = "digest" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" +version = "0.10.4" dependencies = [ - "block-buffer 0.10.2", - "crypto-common 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "blobby", + "block-buffer 0.10.3", + "const-oid 0.9.0", + "crypto-common 0.1.6", "subtle", ] @@ -483,7 +484,7 @@ dependencies = [ "base64ct", "crypto-bigint 0.4.8", "der 0.6.0", - "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.10.3", "ff 0.12.0", "generic-array", "group 0.12.0", @@ -660,7 +661,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.10.3", ] [[package]] @@ -672,7 +673,7 @@ dependencies = [ "aes-gcm", "byteorder", "chacha20poly1305", - "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.10.3", "generic-array", "hkdf 0.12.3", "hmac 0.12.1", @@ -1143,7 +1144,7 @@ checksum = "cf9db03534dff993187064c4e0c05a5708d2a9728ace9a8959b77bedf415dac5" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.10.3", ] [[package]] @@ -1152,7 +1153,7 @@ version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eaedf34ed289ea47c2b741bb72e5357a209512d67bcd4bda44359e5bf0470f56" dependencies = [ - "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.10.3", "keccak", ] @@ -1170,7 +1171,7 @@ dependencies = [ name = "signature" version = "1.6.2" dependencies = [ - "digest 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.10.3", "hex-literal", "rand_core 0.6.3", "sha2 0.10.5", diff --git a/digest/CHANGELOG.md b/digest/CHANGELOG.md index c9f52c64e..2553f5e74 100644 --- a/digest/CHANGELOG.md +++ b/digest/CHANGELOG.md @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.10.4 (2022-09-16) +### Added +- Feature-gated implementation of the `const_oid::AssociatedOid` trait +for the core wrappers. ([#1098]) + +[#1098]: https://github.com/RustCrypto/traits/pull/1098 + ## 0.10.3 (2022-02-16) ### Fixed - Minimal versions build ([#940]) diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 94ff540e3..253da27ba 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "digest" description = "Traits for cryptographic hash functions" -version = "0.10.3" # Also update html_root_url in lib.rs when bumping this +version = "0.10.4" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" @@ -18,12 +18,14 @@ crypto-common = { version = "0.1.3", path = "../crypto-common" } block-buffer = { version = "0.10", optional = true } subtle = { version = "=2.4", default-features = false, optional = true } blobby = { version = "0.3", optional = true } +const-oid = { version = "0.9", optional = true } [features] default = ["core-api"] core-api = ["block-buffer"] # Enable Core API traits mac = ["subtle"] # Enable MAC traits rand_core = ["crypto-common/rand_core"] # Enable random key generation methods +oid = ["const-oid"] # OID support. WARNING: Bumps MSRV to 1.57 alloc = [] std = ["alloc", "crypto-common/std"] dev = ["blobby"] diff --git a/digest/src/core_api/ct_variable.rs b/digest/src/core_api/ct_variable.rs index 40efff65c..7ee1bed0a 100644 --- a/digest/src/core_api/ct_variable.rs +++ b/digest/src/core_api/ct_variable.rs @@ -5,6 +5,8 @@ use super::{ use crate::HashMarker; #[cfg(feature = "mac")] use crate::MacMarker; +#[cfg(feature = "oid")] +use const_oid::{AssociatedOid, ObjectIdentifier}; use core::{fmt, marker::PhantomData}; use crypto_common::{ generic_array::{ArrayLength, GenericArray}, @@ -12,10 +14,15 @@ use crypto_common::{ Block, BlockSizeUser, OutputSizeUser, }; +/// Dummy type used with [`CtVariableCoreWrapper`] in cases when +/// resulting hash does not have a known OID. +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +pub struct NoOid; + /// Wrapper around [`VariableOutputCore`] which selects output size /// at compile time. #[derive(Clone)] -pub struct CtVariableCoreWrapper +pub struct CtVariableCoreWrapper where T: VariableOutputCore, OutSize: ArrayLength + IsLessOrEqual, @@ -24,10 +31,10 @@ where Le: NonZero, { inner: T, - _out: PhantomData, + _out: PhantomData<(OutSize, O)>, } -impl HashMarker for CtVariableCoreWrapper +impl HashMarker for CtVariableCoreWrapper where T: VariableOutputCore + HashMarker, OutSize: ArrayLength + IsLessOrEqual, @@ -38,7 +45,7 @@ where } #[cfg(feature = "mac")] -impl MacMarker for CtVariableCoreWrapper +impl MacMarker for CtVariableCoreWrapper where T: VariableOutputCore + MacMarker, OutSize: ArrayLength + IsLessOrEqual, @@ -48,7 +55,7 @@ where { } -impl BlockSizeUser for CtVariableCoreWrapper +impl BlockSizeUser for CtVariableCoreWrapper where T: VariableOutputCore, OutSize: ArrayLength + IsLessOrEqual, @@ -59,7 +66,7 @@ where type BlockSize = T::BlockSize; } -impl UpdateCore for CtVariableCoreWrapper +impl UpdateCore for CtVariableCoreWrapper where T: VariableOutputCore, OutSize: ArrayLength + IsLessOrEqual, @@ -73,7 +80,7 @@ where } } -impl OutputSizeUser for CtVariableCoreWrapper +impl OutputSizeUser for CtVariableCoreWrapper where T: VariableOutputCore, OutSize: ArrayLength + IsLessOrEqual + 'static, @@ -84,7 +91,7 @@ where type OutputSize = OutSize; } -impl BufferKindUser for CtVariableCoreWrapper +impl BufferKindUser for CtVariableCoreWrapper where T: VariableOutputCore, OutSize: ArrayLength + IsLessOrEqual, @@ -95,7 +102,7 @@ where type BufferKind = T::BufferKind; } -impl FixedOutputCore for CtVariableCoreWrapper +impl FixedOutputCore for CtVariableCoreWrapper where T: VariableOutputCore, OutSize: ArrayLength + IsLessOrEqual + 'static, @@ -120,7 +127,7 @@ where } } -impl Default for CtVariableCoreWrapper +impl Default for CtVariableCoreWrapper where T: VariableOutputCore, OutSize: ArrayLength + IsLessOrEqual, @@ -137,7 +144,7 @@ where } } -impl Reset for CtVariableCoreWrapper +impl Reset for CtVariableCoreWrapper where T: VariableOutputCore, OutSize: ArrayLength + IsLessOrEqual, @@ -151,7 +158,7 @@ where } } -impl AlgorithmName for CtVariableCoreWrapper +impl AlgorithmName for CtVariableCoreWrapper where T: VariableOutputCore + AlgorithmName, OutSize: ArrayLength + IsLessOrEqual, @@ -165,3 +172,33 @@ where write!(f, "{}", OutSize::USIZE) } } + +#[cfg(feature = "oid")] +#[cfg_attr(docsrs, doc(cfg(feature = "oid")))] +impl AssociatedOid for CtVariableCoreWrapper +where + T: VariableOutputCore, + O: AssociatedOid, + OutSize: ArrayLength + IsLessOrEqual, + LeEq: NonZero, + T::BlockSize: IsLess, + Le: NonZero, +{ + const OID: ObjectIdentifier = O::OID; +} + +/// Implement dummy type with hidden docs which is used to "carry" hasher +/// OID for [`CtVariableCoreWrapper`]. +#[macro_export] +macro_rules! impl_oid_carrier { + ($name:ident, $oid:literal) => { + #[doc(hidden)] + #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] + pub struct $name; + + #[cfg(feature = "oid")] + impl AssociatedOid for $name { + const OID: ObjectIdentifier = ObjectIdentifier::new_unwrap($oid); + } + }; +} diff --git a/digest/src/core_api/wrapper.rs b/digest/src/core_api/wrapper.rs index 4ad0f7eea..ca977381e 100644 --- a/digest/src/core_api/wrapper.rs +++ b/digest/src/core_api/wrapper.rs @@ -14,6 +14,8 @@ use crypto_common::{ #[cfg(feature = "mac")] use crate::MacMarker; +#[cfg(feature = "oid")] +use const_oid::{AssociatedOid, ObjectIdentifier}; /// Wrapper around [`BufferKindUser`]. /// @@ -227,6 +229,17 @@ where } } +#[cfg(feature = "oid")] +#[cfg_attr(docsrs, doc(cfg(feature = "oid")))] +impl AssociatedOid for CoreWrapper +where + T: BufferKindUser + AssociatedOid, + T::BlockSize: IsLess, + Le: NonZero, +{ + const OID: ObjectIdentifier = T::OID; +} + #[cfg(feature = "std")] #[cfg_attr(docsrs, doc(cfg(feature = "std")))] impl std::io::Write for CoreWrapper diff --git a/digest/src/lib.rs b/digest/src/lib.rs index c2edb40ee..fc82e2e3a 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -27,8 +27,7 @@ #![forbid(unsafe_code)] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", - html_root_url = "https://docs.rs/digest/0.10.3" + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg" )] #![warn(missing_docs, rust_2018_idioms)] @@ -60,6 +59,9 @@ mod mac; #[cfg(feature = "core-api")] #[cfg_attr(docsrs, doc(cfg(feature = "core-api")))] pub use block_buffer; +#[cfg(feature = "oid")] +#[cfg_attr(docsrs, doc(cfg(feature = "oid")))] +pub use const_oid; pub use crypto_common; pub use crate::digest::{Digest, DynDigest, HashMarker}; From 4c89bc9c8381707c4dcf7faaab7a8155c3d20074 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Fri, 16 Sep 2022 01:41:06 +0000 Subject: [PATCH 0868/1461] digest: MSRV fix release (#1117) --- Cargo.lock | 85 ++++++++++++++++++++------------------------- Cargo.toml | 6 ++-- digest/CHANGELOG.md | 6 ++++ digest/Cargo.toml | 2 +- 4 files changed, 48 insertions(+), 51 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b119b584b..be40fe72d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -308,7 +308,7 @@ dependencies = [ "aead 0.5.1", "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "crypto-common 0.1.6", - "digest 0.10.3", + "digest 0.10.4", "elliptic-curve 0.12.3", "password-hash", "signature 1.6.2", @@ -322,7 +322,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8658c15c5d921ddf980f7fe25b1e82f4b7a4083b2c4985fea4922edb8e43e07d" dependencies = [ "generic-array", - "rand_core 0.6.3", + "rand_core 0.6.4", "subtle", "zeroize", ] @@ -334,7 +334,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f2b443d17d49dad5ef0ede301c3179cc923b8822f3393b4d2c28c269dd4a122" dependencies = [ "generic-array", - "rand_core 0.6.3", + "rand_core 0.6.4", "subtle", "zeroize", ] @@ -344,7 +344,7 @@ name = "crypto-common" version = "0.1.6" dependencies = [ "generic-array", - "rand_core 0.6.3", + "rand_core 0.6.4", "typenum", ] @@ -355,7 +355,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", - "rand_core 0.6.3", + "rand_core 0.6.4", "typenum", ] @@ -422,26 +422,15 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" +checksum = "2e287ab672bc35c3dfc456f9da59473d8f60450cc57dc4dc350d5dccd000167a" dependencies = [ "block-buffer 0.10.3", "crypto-common 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "subtle", ] -[[package]] -name = "digest" -version = "0.10.4" -dependencies = [ - "blobby", - "block-buffer 0.10.3", - "const-oid 0.9.0", - "crypto-common 0.1.6", - "subtle", -] - [[package]] name = "dunce" version = "1.0.2" @@ -471,7 +460,7 @@ dependencies = [ "generic-array", "group 0.10.0", "pkcs8 0.7.6", - "rand_core 0.6.3", + "rand_core 0.6.4", "subtle", "zeroize", ] @@ -484,7 +473,7 @@ dependencies = [ "base64ct", "crypto-bigint 0.4.8", "der 0.6.0", - "digest 0.10.3", + "digest 0.10.4", "ff 0.12.0", "generic-array", "group 0.12.0", @@ -492,7 +481,7 @@ dependencies = [ "hkdf 0.12.3", "pem-rfc7468 0.6.0", "pkcs8 0.9.0", - "rand_core 0.6.3", + "rand_core 0.6.4", "sec1", "serde_json", "serdect", @@ -518,7 +507,7 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0f40b2dcd8bc322217a5f6559ae5f9e9d1de202a2ecee2e9eafcbece7562a4f" dependencies = [ - "rand_core 0.6.3", + "rand_core 0.6.4", "subtle", ] @@ -529,7 +518,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df689201f395c6b90dfe87127685f8dbfc083a5e779e613575d8bd7314300c3e" dependencies = [ "bitvec", - "rand_core 0.6.3", + "rand_core 0.6.4", "subtle", ] @@ -583,7 +572,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c363a5301b8f153d80747126a04b3c82073b9fe3130571a9d170cacdeaf7912" dependencies = [ "ff 0.10.1", - "rand_core 0.6.3", + "rand_core 0.6.4", "subtle", ] @@ -594,7 +583,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7391856def869c1c81063a03457c676fbcd419709c3dfb33d8d319de484b154d" dependencies = [ "ff 0.12.0", - "rand_core 0.6.3", + "rand_core 0.6.4", "subtle", ] @@ -661,7 +650,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.3", + "digest 0.10.4", ] [[package]] @@ -673,11 +662,11 @@ dependencies = [ "aes-gcm", "byteorder", "chacha20poly1305", - "digest 0.10.3", + "digest 0.10.4", "generic-array", "hkdf 0.12.3", "hmac 0.12.1", - "rand_core 0.6.3", + "rand_core 0.6.4", "sha2 0.10.5", "subtle", "x25519-dalek", @@ -725,7 +714,7 @@ dependencies = [ "pqcrypto", "pqcrypto-traits", "rand", - "rand_core 0.6.3", + "rand_core 0.6.4", "x3dh-ke", "zeroize", ] @@ -795,7 +784,7 @@ name = "password-hash" version = "0.4.2" dependencies = [ "base64ct", - "rand_core 0.6.3", + "rand_core 0.6.4", "subtle", ] @@ -941,7 +930,7 @@ checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha", - "rand_core 0.6.3", + "rand_core 0.6.4", ] [[package]] @@ -951,7 +940,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core 0.6.3", + "rand_core 0.6.4", ] [[package]] @@ -962,9 +951,9 @@ checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" [[package]] name = "rand_core" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ "getrandom", ] @@ -1022,7 +1011,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.13", + "semver 1.0.14", ] [[package]] @@ -1063,9 +1052,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f6841e709003d68bb2deee8c343572bf446003ec20a583e76f7b15cebf3711" +checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4" [[package]] name = "semver-parser" @@ -1144,7 +1133,7 @@ checksum = "cf9db03534dff993187064c4e0c05a5708d2a9728ace9a8959b77bedf415dac5" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.3", + "digest 0.10.4", ] [[package]] @@ -1153,7 +1142,7 @@ version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eaedf34ed289ea47c2b741bb72e5357a209512d67bcd4bda44359e5bf0470f56" dependencies = [ - "digest 0.10.3", + "digest 0.10.4", "keccak", ] @@ -1164,16 +1153,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2807892cfa58e081aa1f1111391c7a0649d4fa127a4ffbe34bcbfb35a1171a4" dependencies = [ "digest 0.9.0", - "rand_core 0.6.3", + "rand_core 0.6.4", ] [[package]] name = "signature" version = "1.6.2" dependencies = [ - "digest 0.10.3", + "digest 0.10.4", "hex-literal", - "rand_core 0.6.3", + "rand_core 0.6.4", "sha2 0.10.5", "signature_derive", ] @@ -1264,15 +1253,15 @@ checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" [[package]] name = "unicode-ident" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf" +checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd" [[package]] name = "unicode-xid" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" [[package]] name = "universal-hash" @@ -1341,7 +1330,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5da623d8af10a62342bcbbb230e33e58a63255a58012f8653c578e54bab48df" dependencies = [ "curve25519-dalek", - "rand_core 0.6.3", + "rand_core 0.6.4", "zeroize", ] @@ -1357,7 +1346,7 @@ dependencies = [ "getrandom", "hkdf 0.11.0", "p256", - "rand_core 0.6.3", + "rand_core 0.6.4", "serde", "serde_bytes", "sha2 0.9.9", diff --git a/Cargo.toml b/Cargo.toml index dc7d95785..b8363c66c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,11 +4,13 @@ members = [ "aead", "cipher", "crypto", - "crypto-common", - "digest", "elliptic-curve", "kem", "signature", "signature/async", "universal-hash", ] +exclude = [ + "crypto-common", + "digest", +] diff --git a/digest/CHANGELOG.md b/digest/CHANGELOG.md index 2553f5e74..fe7488e0e 100644 --- a/digest/CHANGELOG.md +++ b/digest/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.10.5 (2022-09-16) +### Fixed +- MSRV build. ([#1117]) + +[#1117]: https://github.com/RustCrypto/traits/pull/1117 + ## 0.10.4 (2022-09-16) ### Added - Feature-gated implementation of the `const_oid::AssociatedOid` trait diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 253da27ba..42ab88f77 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "digest" description = "Traits for cryptographic hash functions" -version = "0.10.4" +version = "0.10.5" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" From ba24f60e30749877906a4494be5991502a400d48 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 16 Sep 2022 07:29:56 -0600 Subject: [PATCH 0869/1461] signature_derive: fix support for `where` bounds (#1118) Retains the original where bounds provided in a type declaration. Additionally this adds `__` to the names of the type parameters used by the `impl` to avoid clashes with ones that might be specified for a given type. --- signature/derive/src/lib.rs | 234 ++++++++++++++++++++++++------------ 1 file changed, 159 insertions(+), 75 deletions(-) diff --git a/signature/derive/src/lib.rs b/signature/derive/src/lib.rs index d47216cce..8de761813 100644 --- a/signature/derive/src/lib.rs +++ b/signature/derive/src/lib.rs @@ -10,9 +10,12 @@ )] use proc_macro::TokenStream; -use proc_macro2::TokenStream as TokenStream2; +use proc_macro2::{Span, TokenStream as TokenStream2}; use quote::quote; -use syn::{parse_macro_input, DeriveInput, Ident, TypeParam}; +use syn::{ + parse_macro_input, parse_quote, punctuated::Punctuated, DeriveInput, Ident, PredicateType, + Token, TraitBound, Type, TypeParam, TypeParamBound, WhereClause, WherePredicate, +}; /// Derive the [`Signer`] trait for a type which impls [`DigestSigner`]. /// @@ -37,19 +40,26 @@ pub fn derive_signer(input: TokenStream) -> TokenStream { } fn emit_signer_impl(input: DeriveInput) -> TokenStream2 { - let params = DeriveParams::new(input); - let ident = ¶ms.ident; - let type_params = ¶ms.type_params; - let type_idents = params.type_idents(); + let s_ident = Ident::new("__S", Span::call_site()); + + let mut params = DeriveParams::new(input); + params.add_bound(&s_ident, parse_quote!(::signature::PrehashSignature)); + params.add_bound( + &Ident::new("Self", Span::call_site()), + parse_quote!(::signature::DigestSigner<#s_ident::Digest, #s_ident>), + ); + + let name = params.name; + let impl_generics = params.impl_generics; + let ty_generics = params.ty_generics; + let where_clause = params.where_clause; quote! { - impl ::signature::Signer for #ident<#(#type_idents),*> - where - S: ::signature::PrehashSignature, - Self: ::signature::DigestSigner + impl<#(#impl_generics),*> ::signature::Signer<#s_ident> for #name<#(#ty_generics),*> + #where_clause { - fn try_sign(&self, msg: &[u8]) -> ::signature::Result { - self.try_sign_digest(S::Digest::new_with_prefix(msg)) + fn try_sign(&self, msg: &[u8]) -> ::signature::Result<#s_ident> { + self.try_sign_digest(#s_ident::Digest::new_with_prefix(msg)) } } } @@ -78,19 +88,26 @@ pub fn derive_verifier(input: TokenStream) -> TokenStream { } fn emit_verifier_impl(input: DeriveInput) -> TokenStream2 { - let params = DeriveParams::new(input); - let ident = ¶ms.ident; - let type_params = ¶ms.type_params; - let type_idents = params.type_idents(); + let s_ident = Ident::new("__S", Span::call_site()); + + let mut params = DeriveParams::new(input); + params.add_bound(&s_ident, parse_quote!(::signature::PrehashSignature)); + params.add_bound( + &Ident::new("Self", Span::call_site()), + parse_quote!(::signature::DigestVerifier<#s_ident::Digest, #s_ident>), + ); + + let name = params.name; + let impl_generics = params.impl_generics; + let ty_generics = params.ty_generics; + let where_clause = params.where_clause; quote! { - impl ::signature::Verifier for #ident<#(#type_idents),*> - where - S: ::signature::PrehashSignature, - Self: ::signature::DigestVerifier + impl<#(#impl_generics),*> ::signature::Verifier<#s_ident> for #name<#(#ty_generics),*> + #where_clause { - fn verify(&self, msg: &[u8], signature: &S) -> ::signature::Result<()> { - self.verify_digest(S::Digest::new_with_prefix(msg), signature) + fn verify(&self, msg: &[u8], signature: &#s_ident) -> ::signature::Result<()> { + self.verify_digest(#s_ident::Digest::new_with_prefix(msg), signature) } } } @@ -107,19 +124,27 @@ pub fn derive_digest_signer(input: TokenStream) -> TokenStream { } fn emit_digest_signer_impl(input: DeriveInput) -> TokenStream2 { - let params = DeriveParams::new(input); - let ident = ¶ms.ident; - let type_params = ¶ms.type_params; - let type_idents = params.type_idents(); + let d_ident = Ident::new("__D", Span::call_site()); + let s_ident = Ident::new("__S", Span::call_site()); + + let mut params = DeriveParams::new(input); + params.add_bound(&d_ident, parse_quote!(::signature::digest::Digest)); + params.add_bound(&s_ident, parse_quote!(::signature::Signature)); + params.add_bound( + &Ident::new("Self", Span::call_site()), + parse_quote!(::signature::hazmat::PrehashSigner<#s_ident>), + ); + + let name = params.name; + let impl_generics = params.impl_generics; + let ty_generics = params.ty_generics; + let where_clause = params.where_clause; quote! { - impl ::signature::DigestSigner for #ident<#(#type_idents),*> - where - D: ::signature::digest::Digest, - S: ::signature::Signature, - Self: ::signature::hazmat::PrehashSigner + impl<#(#impl_generics),*> ::signature::DigestSigner<#d_ident, #s_ident> for #name<#(#ty_generics),*> + #where_clause { - fn try_sign_digest(&self, digest: D) -> ::signature::Result { + fn try_sign_digest(&self, digest: #d_ident) -> ::signature::Result<#s_ident> { self.sign_prehash(&digest.finalize()) } } @@ -137,19 +162,27 @@ pub fn derive_digest_verifier(input: TokenStream) -> TokenStream { } fn emit_digest_verifier_impl(input: DeriveInput) -> TokenStream2 { - let params = DeriveParams::new(input); - let ident = ¶ms.ident; - let type_params = ¶ms.type_params; - let type_idents = params.type_idents(); + let d_ident = Ident::new("__D", Span::call_site()); + let s_ident = Ident::new("__S", Span::call_site()); + + let mut params = DeriveParams::new(input); + params.add_bound(&d_ident, parse_quote!(::signature::digest::Digest)); + params.add_bound(&s_ident, parse_quote!(::signature::Signature)); + params.add_bound( + &Ident::new("Self", Span::call_site()), + parse_quote!(::signature::hazmat::PrehashVerifier<#s_ident>), + ); + + let name = params.name; + let impl_generics = params.impl_generics; + let ty_generics = params.ty_generics; + let where_clause = params.where_clause; quote! { - impl ::signature::DigestVerifier for #ident<#(#type_idents),*> - where - D: ::signature::digest::Digest, - S: ::signature::Signature, - Self: ::signature::hazmat::PrehashVerifier + impl<#(#impl_generics),*> ::signature::DigestVerifier<#d_ident, #s_ident> for #name<#(#ty_generics),*> + #where_clause { - fn verify_digest(&self, digest: D, signature: &S) -> ::signature::Result<()> { + fn verify_digest(&self, digest: #d_ident, signature: &#s_ident) -> ::signature::Result<()> { self.verify_prehash(&digest.finalize(), signature) } } @@ -158,28 +191,75 @@ fn emit_digest_verifier_impl(input: DeriveInput) -> TokenStream2 { /// Derivation parameters parsed from `DeriveInput`. struct DeriveParams { - /// `Ident` for the struct the trait impls are being added to. - ident: Ident, + /// Name of the struct the trait impls are being added to. + name: Ident, + + /// Generic parameters of `impl`. + impl_generics: Vec, - /// Generic type parameters. - type_params: Vec, + /// Generic parameters of the type. + ty_generics: Vec, + + /// Where clause in-progress. + where_clause: WhereClause, } impl DeriveParams { /// Parse parameters from `DeriveInput`. fn new(input: DeriveInput) -> Self { + let impl_generics = input.generics.type_params().cloned().collect(); + + let ty_generics = input + .generics + .type_params() + .map(|bound| bound.ident.clone()) + .collect(); + + let where_clause = input + .generics + .where_clause + .clone() + .unwrap_or_else(|| WhereClause { + where_token: ::default(), + predicates: Punctuated::new(), + }); + Self { - ident: input.ident, - type_params: input.generics.type_params().cloned().collect(), + name: input.ident, + impl_generics, + ty_generics, + where_clause, } } - /// Get the `Ident`s which correspond to each of the `type_params`. - fn type_idents(&self) -> Vec { - self.type_params - .iter() - .map(|bound| bound.ident.clone()) - .collect() + /// Add a generic parameter with the given bound. + fn add_bound(&mut self, name: &Ident, bound: TraitBound) { + if name != "Self" { + self.impl_generics.push(TypeParam { + attrs: vec![], + ident: name.clone(), + colon_token: None, + bounds: Default::default(), + eq_token: None, + default: None, + }); + } + + let type_path = parse_quote!(#name); + + let mut bounds = Punctuated::new(); + bounds.push(TypeParamBound::Trait(bound)); + + let predicate_type = PredicateType { + lifetimes: None, + bounded_ty: Type::Path(type_path), + colon_token: ::default(), + bounds, + }; + + self.where_clause + .predicates + .push(WherePredicate::Type(predicate_type)) } } @@ -192,7 +272,10 @@ mod tests { fn signer() { let input = parse_quote! { #[derive(Signer)] - struct MySigner { + struct MySigner + where + C: EllipticCurve + { scalar: Scalar } }; @@ -202,13 +285,14 @@ mod tests { assert_eq!( output.to_string(), quote! { - impl ::signature::Signer for MySigner + impl ::signature::Signer<__S> for MySigner where - S: ::signature::PrehashSignature, - Self: ::signature::DigestSigner + C: EllipticCurve, + __S: ::signature::PrehashSignature, + Self: ::signature::DigestSigner<__S::Digest, __S> { - fn try_sign(&self, msg: &[u8]) -> ::signature::Result { - self.try_sign_digest(S::Digest::new_with_prefix(msg)) + fn try_sign(&self, msg: &[u8]) -> ::signature::Result<__S> { + self.try_sign_digest(__S::Digest::new_with_prefix(msg)) } } } @@ -230,13 +314,13 @@ mod tests { assert_eq!( output.to_string(), quote! { - impl ::signature::Verifier for MyVerifier + impl ::signature::Verifier<__S> for MyVerifier where - S: ::signature::PrehashSignature, - Self: ::signature::DigestVerifier + __S: ::signature::PrehashSignature, + Self: ::signature::DigestVerifier<__S::Digest, __S> { - fn verify(&self, msg: &[u8], signature: &S) -> ::signature::Result<()> { - self.verify_digest(S::Digest::new_with_prefix(msg), signature) + fn verify(&self, msg: &[u8], signature: &__S) -> ::signature::Result<()> { + self.verify_digest(__S::Digest::new_with_prefix(msg), signature) } } } @@ -258,13 +342,13 @@ mod tests { assert_eq!( output.to_string(), quote! { - impl ::signature::DigestSigner for MySigner + impl ::signature::DigestSigner<__D, __S> for MySigner where - D: ::signature::digest::Digest, - S: ::signature::Signature, - Self: ::signature::hazmat::PrehashSigner + __D: ::signature::digest::Digest, + __S: ::signature::Signature, + Self: ::signature::hazmat::PrehashSigner<__S> { - fn try_sign_digest(&self, digest: D) -> ::signature::Result { + fn try_sign_digest(&self, digest: __D) -> ::signature::Result<__S> { self.sign_prehash(&digest.finalize()) } } @@ -287,13 +371,13 @@ mod tests { assert_eq!( output.to_string(), quote! { - impl ::signature::DigestVerifier for MyVerifier + impl ::signature::DigestVerifier<__D, __S> for MyVerifier where - D: ::signature::digest::Digest, - S: ::signature::Signature, - Self: ::signature::hazmat::PrehashVerifier + __D: ::signature::digest::Digest, + __S: ::signature::Signature, + Self: ::signature::hazmat::PrehashVerifier<__S> { - fn verify_digest(&self, digest: D, signature: &S) -> ::signature::Result<()> { + fn verify_digest(&self, digest: __D, signature: &__S) -> ::signature::Result<()> { self.verify_prehash(&digest.finalize(), signature) } } From c7eb99fc75b9d230a6696b3a290f64b83dbc8856 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 16 Sep 2022 08:00:52 -0600 Subject: [PATCH 0870/1461] signature_derive v1.0.0-pre.7 (#1119) --- Cargo.lock | 2 +- signature/Cargo.toml | 2 +- signature/derive/CHANGELOG.md | 6 ++++++ signature/derive/Cargo.toml | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index be40fe72d..fc392b8c9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1169,7 +1169,7 @@ dependencies = [ [[package]] name = "signature_derive" -version = "1.0.0-pre.6" +version = "1.0.0-pre.7" dependencies = [ "proc-macro2", "quote", diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 9069213a9..a6e525e16 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -15,7 +15,7 @@ categories = ["cryptography", "no-std"] [dependencies] digest = { version = "0.10.3", optional = true, default-features = false } rand_core = { version = "0.6", optional = true, default-features = false } -signature_derive = { version = "=1.0.0-pre.6", optional = true, path = "derive" } +signature_derive = { version = "=1.0.0-pre.7", optional = true, path = "derive" } [dev-dependencies] hex-literal = "0.3" diff --git a/signature/derive/CHANGELOG.md b/signature/derive/CHANGELOG.md index 91be5cf9b..65caa4655 100644 --- a/signature/derive/CHANGELOG.md +++ b/signature/derive/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 1.0.0-pre.7 (2022-09-16) +### Fixed +- Support for `where` bounds ([#1118]) + +[#1118]: https://github.com/RustCrypto/traits/pull/1118 + ## 1.0.0-pre.6 (2022-09-12) ### Added - `DigestSigner`/`DigestVerifier` support ([#1103]) diff --git a/signature/derive/Cargo.toml b/signature/derive/Cargo.toml index d0ab77771..c21334ed4 100644 --- a/signature/derive/Cargo.toml +++ b/signature/derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "signature_derive" -version = "1.0.0-pre.6" +version = "1.0.0-pre.7" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" description = "Custom derive support for the 'signature' crate" From b38115e3a123219648ac682e0c0aabab36238c89 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 16 Sep 2022 08:24:57 -0600 Subject: [PATCH 0871/1461] signature v1.6.3 (#1120) --- Cargo.lock | 6 +++--- signature/CHANGELOG.md | 6 ++++++ signature/Cargo.toml | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fc392b8c9..485bb6a1d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -62,7 +62,7 @@ name = "async-signature" version = "0.2.1" dependencies = [ "async-trait", - "signature 1.6.2", + "signature 1.6.3", ] [[package]] @@ -311,7 +311,7 @@ dependencies = [ "digest 0.10.4", "elliptic-curve 0.12.3", "password-hash", - "signature 1.6.2", + "signature 1.6.3", "universal-hash 0.5.0", ] @@ -1158,7 +1158,7 @@ dependencies = [ [[package]] name = "signature" -version = "1.6.2" +version = "1.6.3" dependencies = [ "digest 0.10.4", "hex-literal", diff --git a/signature/CHANGELOG.md b/signature/CHANGELOG.md index 3959765f5..ad7c81946 100644 --- a/signature/CHANGELOG.md +++ b/signature/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 1.6.2 (2022-09-16) +### Changed +- Bump `signature_derive` to v1.0.0-pre.7 ([#1119]) + +[#1119]: https://github.com/RustCrypto/traits/pull/1119 + ## 1.6.2 (2022-09-15) ### Changed - Relax `Keypair` type bounds ([#1107]) diff --git a/signature/Cargo.toml b/signature/Cargo.toml index a6e525e16..26b463b28 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "1.6.2" +version = "1.6.3" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/signature" From 66009dd2d6d7cb02f181d40eab96aa994c558b08 Mon Sep 17 00:00:00 2001 From: Dirk Stolle Date: Wed, 21 Sep 2022 23:57:47 +0200 Subject: [PATCH 0872/1461] Fix some typos (#1126) --- cipher/CHANGELOG.md | 2 +- cipher/src/stream_core.rs | 2 +- cipher/src/stream_wrapper.rs | 4 ++-- digest/README.md | 2 +- digest/src/dev.rs | 2 +- digest/src/dev/rng.rs | 2 +- digest/src/digest.rs | 2 +- digest/src/mac.rs | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/cipher/CHANGELOG.md b/cipher/CHANGELOG.md index 002a44566..d48764969 100644 --- a/cipher/CHANGELOG.md +++ b/cipher/CHANGELOG.md @@ -36,7 +36,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## 0.4.0 (2022-02-10) ### Changed - Major rework of traits. Core functionality of block and stream ciphers -is defined using rank-2 closures with convinience methods built on top of +is defined using rank-2 closures with convenience methods built on top of it. Expose block-level trait for stream ciphers and add generic wrapper around it. The async stream cipher trait is defined as sub-trait of mutable block cipher traits. ([#849]) diff --git a/cipher/src/stream_core.rs b/cipher/src/stream_core.rs index bb4d9a43a..1e4b302ea 100644 --- a/cipher/src/stream_core.rs +++ b/cipher/src/stream_core.rs @@ -148,7 +148,7 @@ pub trait StreamCipherCore: BlockSizeUser + Sized { // note: unfortunately, currently we can not write blanket impls of // `BlockEncryptMut` and `BlockDecryptMut` for `T: StreamCipherCore` -// since it requires mutually exlusive traits, see: +// since it requires mutually exclusive traits, see: // https://github.com/rust-lang/rfcs/issues/1053 /// Counter type usable with [`StreamCipherCore`]. diff --git a/cipher/src/stream_wrapper.rs b/cipher/src/stream_wrapper.rs index 21f861638..1d0d3155c 100644 --- a/cipher/src/stream_wrapper.rs +++ b/cipher/src/stream_wrapper.rs @@ -55,7 +55,7 @@ where self.pos as usize } - /// Return size of the internall buffer in bytes. + /// Return size of the internal buffer in bytes. #[inline] fn size(&self) -> usize { T::BlockSize::USIZE @@ -67,7 +67,7 @@ where self.pos = pos as u8; } - /// Return number of remaining bytes in the internall buffer. + /// Return number of remaining bytes in the internal buffer. #[inline] fn remaining(&self) -> usize { self.size() - self.get_pos() diff --git a/digest/README.md b/digest/README.md index c71a8d144..a3fbd9c48 100644 --- a/digest/README.md +++ b/digest/README.md @@ -71,7 +71,7 @@ let hash = Sha256::new() println!("Result: {:x}", hash); ``` -If the whole message is available you also can use convinience `digest` method: +If the whole message is available you also can use convenience `digest` method: ```rust let hash = Sha256::digest(b"my message"); diff --git a/digest/src/dev.rs b/digest/src/dev.rs index 2b68bdd4d..438089574 100644 --- a/digest/src/dev.rs +++ b/digest/src/dev.rs @@ -71,7 +71,7 @@ pub fn feed_rand_16mib(d: &mut D) { for _ in 0..n { rng.fill(buf); d.update(buf); - // additional byte, so size of feeded data + // additional byte, so size of fed data // will not be multiple of block size d.update(&[42]); } diff --git a/digest/src/dev/rng.rs b/digest/src/dev/rng.rs index 8b233aafb..d34a1cf31 100644 --- a/digest/src/dev/rng.rs +++ b/digest/src/dev/rng.rs @@ -2,7 +2,7 @@ use core::num::Wrapping; /// Initial RNG state used in tests. -// choosen by fair dice roll. guaranteed to be random. +// chosen by fair dice roll. guaranteed to be random. pub(crate) const RNG: XorShiftRng = XorShiftRng { x: Wrapping(0x0787_3B4A), y: Wrapping(0xFAAB_8FFE), diff --git a/digest/src/digest.rs b/digest/src/digest.rs index bd9fd62e4..9373550ca 100644 --- a/digest/src/digest.rs +++ b/digest/src/digest.rs @@ -7,7 +7,7 @@ use alloc::boxed::Box; /// Marker trait for cryptographic hash functions. pub trait HashMarker {} -/// Convinience wrapper trait covering functionality of cryptographic hash +/// Convenience wrapper trait covering functionality of cryptographic hash /// functions with fixed output size. /// /// This trait wraps [`Update`], [`FixedOutput`], [`Default`], and diff --git a/digest/src/mac.rs b/digest/src/mac.rs index ccbd95ba1..f7fd31d07 100644 --- a/digest/src/mac.rs +++ b/digest/src/mac.rs @@ -11,7 +11,7 @@ use subtle::{Choice, ConstantTimeEq}; #[cfg_attr(docsrs, doc(cfg(feature = "mac")))] pub trait MacMarker {} -/// Convinience wrapper trait covering functionality of Message Authentication algorithms. +/// Convenience wrapper trait covering functionality of Message Authentication algorithms. /// /// This trait wraps [`KeyInit`], [`Update`], [`FixedOutput`], and [`MacMarker`] /// traits and provides additional convenience methods. From 1f0f2f3ba683955778f271eb2206b5da5f4e26e0 Mon Sep 17 00:00:00 2001 From: Dirk Stolle Date: Wed, 21 Sep 2022 23:59:36 +0200 Subject: [PATCH 0873/1461] Extend Dependabot configuration to keep GitHub Actions up to date (#1125) --- .github/dependabot.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 5cde1657c..397bdaa4f 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,3 +5,8 @@ updates: schedule: interval: daily open-pull-requests-limit: 10 +- package-ecosystem: github-actions + directory: "/" + schedule: + interval: weekly + open-pull-requests-limit: 10 From 1b1f0d9dd7024f8463b441102fe3f7a84af0898d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 21 Sep 2022 22:19:24 +0000 Subject: [PATCH 0874/1461] build(deps): bump actions/checkout from 2 to 3 (#1128) --- .github/workflows/aead.yml | 4 ++-- .github/workflows/async-signature.yml | 4 ++-- .github/workflows/cipher.yml | 6 +++--- .github/workflows/crypto-common.yml | 4 ++-- .github/workflows/crypto.yml | 10 +++++----- .github/workflows/digest.yml | 6 +++--- .github/workflows/elliptic-curve.yml | 6 +++--- .github/workflows/kem.yml | 6 +++--- .github/workflows/password-hash.yml | 6 +++--- .github/workflows/security-audit.yml | 10 +++++----- .github/workflows/signature.yml | 6 +++--- .github/workflows/universal-hash.yml | 4 ++-- .github/workflows/workspace.yml | 4 ++-- 13 files changed, 38 insertions(+), 38 deletions(-) diff --git a/.github/workflows/aead.yml b/.github/workflows/aead.yml index 45c8b0076..308d562b3 100644 --- a/.github/workflows/aead.yml +++ b/.github/workflows/aead.yml @@ -28,7 +28,7 @@ jobs: - thumbv7em-none-eabi - wasm32-unknown-unknown steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: @@ -57,7 +57,7 @@ jobs: - 1.56.0 # MSRV - stable steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: diff --git a/.github/workflows/async-signature.yml b/.github/workflows/async-signature.yml index 11872c07c..75bcf327a 100644 --- a/.github/workflows/async-signature.yml +++ b/.github/workflows/async-signature.yml @@ -25,7 +25,7 @@ jobs: - 1.56.0 # MSRV - stable steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: @@ -39,7 +39,7 @@ jobs: minimal-versions: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: diff --git a/.github/workflows/cipher.yml b/.github/workflows/cipher.yml index 9f2497d65..575bba883 100644 --- a/.github/workflows/cipher.yml +++ b/.github/workflows/cipher.yml @@ -28,7 +28,7 @@ jobs: - thumbv7em-none-eabi - wasm32-unknown-unknown steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: @@ -45,7 +45,7 @@ jobs: minimal-versions: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: @@ -64,7 +64,7 @@ jobs: - 1.56.0 # MSRV - stable steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: diff --git a/.github/workflows/crypto-common.yml b/.github/workflows/crypto-common.yml index 5947c6a16..333c608ef 100644 --- a/.github/workflows/crypto-common.yml +++ b/.github/workflows/crypto-common.yml @@ -28,7 +28,7 @@ jobs: - thumbv7em-none-eabi - wasm32-unknown-unknown steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: @@ -53,7 +53,7 @@ jobs: - 1.41.0 # MSRV - stable steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: diff --git a/.github/workflows/crypto.yml b/.github/workflows/crypto.yml index a692d82c8..8687448cc 100644 --- a/.github/workflows/crypto.yml +++ b/.github/workflows/crypto.yml @@ -28,7 +28,7 @@ jobs: - thumbv7em-none-eabi - wasm32-unknown-unknown steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: @@ -45,7 +45,7 @@ jobs: # minimal-versions: # runs-on: ubuntu-latest # steps: - # - uses: actions/checkout@v2 + # - uses: actions/checkout@v3 # - uses: RustCrypto/actions/cargo-cache@master # - uses: actions-rs/toolchain@v1 # with: @@ -64,7 +64,7 @@ jobs: - 1.57.0 # MSRV - stable steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: @@ -79,7 +79,7 @@ jobs: clippy: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: @@ -93,7 +93,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout sources - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Install stable toolchain uses: actions-rs/toolchain@v1 diff --git a/.github/workflows/digest.yml b/.github/workflows/digest.yml index 51ee473b8..ee77a7116 100644 --- a/.github/workflows/digest.yml +++ b/.github/workflows/digest.yml @@ -28,7 +28,7 @@ jobs: - thumbv7em-none-eabi - wasm32-unknown-unknown steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: @@ -53,7 +53,7 @@ jobs: # - 1.41.0 # MSRV - stable steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: @@ -76,7 +76,7 @@ jobs: rust: - 1.41.0 # MSRV steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index 88b0ffaf6..b8991acb3 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -29,7 +29,7 @@ jobs: - thumbv7em-none-eabi - wasm32-unknown-unknown steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: @@ -63,7 +63,7 @@ jobs: # minimal-versions: # runs-on: ubuntu-latest # steps: - # - uses: actions/checkout@v2 + # - uses: actions/checkout@v3 # - uses: RustCrypto/actions/cargo-cache@master # - uses: actions-rs/toolchain@v1 # with: @@ -83,7 +83,7 @@ jobs: - stable - nightly steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: diff --git a/.github/workflows/kem.yml b/.github/workflows/kem.yml index c25891862..7bf9bcdbd 100644 --- a/.github/workflows/kem.yml +++ b/.github/workflows/kem.yml @@ -28,7 +28,7 @@ jobs: - thumbv7em-none-eabi - wasm32-unknown-unknown steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: @@ -43,7 +43,7 @@ jobs: # minimal-versions: # runs-on: ubuntu-latest # steps: - # - uses: actions/checkout@v2 + # - uses: actions/checkout@v3 # - uses: RustCrypto/actions/cargo-cache@master # - uses: actions-rs/toolchain@v1 # with: @@ -62,7 +62,7 @@ jobs: - 1.56.0 # MSRV - stable steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: diff --git a/.github/workflows/password-hash.yml b/.github/workflows/password-hash.yml index 942319eba..2914e66e5 100644 --- a/.github/workflows/password-hash.yml +++ b/.github/workflows/password-hash.yml @@ -28,7 +28,7 @@ jobs: - thumbv7em-none-eabi - wasm32-unknown-unknown steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: @@ -45,7 +45,7 @@ jobs: minimal-versions: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: @@ -64,7 +64,7 @@ jobs: - 1.57.0 # MSRV - stable steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: diff --git a/.github/workflows/security-audit.yml b/.github/workflows/security-audit.yml index e5372b5d3..8ab53bfb3 100644 --- a/.github/workflows/security-audit.yml +++ b/.github/workflows/security-audit.yml @@ -13,7 +13,7 @@ jobs: name: Security Audit Workspace runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Cache cargo bin uses: actions/cache@v1 with: @@ -30,7 +30,7 @@ jobs: run: working-directory: crypto steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Cache cargo bin uses: actions/cache@v1 with: @@ -47,7 +47,7 @@ jobs: run: working-directory: elliptic-curve steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Cache cargo bin uses: actions/cache@v1 with: @@ -64,7 +64,7 @@ jobs: run: working-directory: kem steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Cache cargo bin uses: actions/cache@v1 with: @@ -81,7 +81,7 @@ jobs: run: working-directory: password-hash steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Cache cargo bin uses: actions/cache@v1 with: diff --git a/.github/workflows/signature.yml b/.github/workflows/signature.yml index dbe841f9b..1e87d18c8 100644 --- a/.github/workflows/signature.yml +++ b/.github/workflows/signature.yml @@ -28,7 +28,7 @@ jobs: - thumbv7em-none-eabi - wasm32-unknown-unknown steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: @@ -55,7 +55,7 @@ jobs: - 1.56.0 # MSRV - stable steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: @@ -75,7 +75,7 @@ jobs: - 1.56.0 # MSRV - stable steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: diff --git a/.github/workflows/universal-hash.yml b/.github/workflows/universal-hash.yml index 2df8b8f31..cb82170c2 100644 --- a/.github/workflows/universal-hash.yml +++ b/.github/workflows/universal-hash.yml @@ -28,7 +28,7 @@ jobs: - thumbv7em-none-eabi - wasm32-unknown-unknown steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: @@ -53,7 +53,7 @@ jobs: - 1.56.0 # MSRV - stable steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index ba8f5b0ca..7b506044d 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -22,7 +22,7 @@ jobs: clippy: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: @@ -35,7 +35,7 @@ jobs: rustfmt: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: actions-rs/toolchain@v1 with: toolchain: stable From d024d2db6f5de378e9bccf1ab1cb773dec37a023 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 21 Sep 2022 22:19:43 +0000 Subject: [PATCH 0875/1461] build(deps): bump actions/cache from 1 to 3 (#1127) --- .github/workflows/security-audit.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/security-audit.yml b/.github/workflows/security-audit.yml index 8ab53bfb3..64ce9c73a 100644 --- a/.github/workflows/security-audit.yml +++ b/.github/workflows/security-audit.yml @@ -15,7 +15,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: Cache cargo bin - uses: actions/cache@v1 + uses: actions/cache@v3 with: path: ~/.cargo/bin key: ${{ runner.os }}-cargo-audit-v0.12.0 @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: Cache cargo bin - uses: actions/cache@v1 + uses: actions/cache@v3 with: path: ~/.cargo/bin key: ${{ runner.os }}-cargo-audit-v0.12.0 @@ -49,7 +49,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: Cache cargo bin - uses: actions/cache@v1 + uses: actions/cache@v3 with: path: ~/.cargo/bin key: ${{ runner.os }}-cargo-audit-v0.12.0 @@ -66,7 +66,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: Cache cargo bin - uses: actions/cache@v1 + uses: actions/cache@v3 with: path: ~/.cargo/bin key: ${{ runner.os }}-cargo-audit-v0.12.0 @@ -83,7 +83,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: Cache cargo bin - uses: actions/cache@v1 + uses: actions/cache@v3 with: path: ~/.cargo/bin key: ${{ runner.os }}-cargo-audit-v0.12.0 From f5199d07025375da035d5ec82739cbad3fea8f8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2?= Date: Fri, 23 Sep 2022 20:19:16 +0300 Subject: [PATCH 0876/1461] Update Cargo.lock --- Cargo.lock | 56 +++++++++++++++++++++++++++--------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 485bb6a1d..d6119b459 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -308,7 +308,7 @@ dependencies = [ "aead 0.5.1", "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "crypto-common 0.1.6", - "digest 0.10.4", + "digest 0.10.5", "elliptic-curve 0.12.3", "password-hash", "signature 1.6.3", @@ -422,9 +422,9 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.4" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e287ab672bc35c3dfc456f9da59473d8f60450cc57dc4dc350d5dccd000167a" +checksum = "adfbc57365a37acbd2ebf2b64d7e69bb766e2fea813521ed536f5d0520dcf86c" dependencies = [ "block-buffer 0.10.3", "crypto-common 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -473,7 +473,7 @@ dependencies = [ "base64ct", "crypto-bigint 0.4.8", "der 0.6.0", - "digest 0.10.4", + "digest 0.10.5", "ff 0.12.0", "generic-array", "group 0.12.0", @@ -485,7 +485,7 @@ dependencies = [ "sec1", "serde_json", "serdect", - "sha2 0.10.5", + "sha2 0.10.6", "sha3", "subtle", "zeroize", @@ -650,7 +650,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.4", + "digest 0.10.5", ] [[package]] @@ -662,12 +662,12 @@ dependencies = [ "aes-gcm", "byteorder", "chacha20poly1305", - "digest 0.10.4", + "digest 0.10.5", "generic-array", "hkdf 0.12.3", "hmac 0.12.1", "rand_core 0.6.4", - "sha2 0.10.5", + "sha2 0.10.6", "subtle", "x25519-dalek", "zeroize", @@ -691,9 +691,9 @@ checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" [[package]] name = "jobserver" -version = "0.1.24" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa" +checksum = "068b1ee6743e4d11fb9c6a1e6064b3693a1b600e7f5f5988047d98b3dc9fb90b" dependencies = [ "libc", ] @@ -727,15 +727,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.132" +version = "0.2.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5" +checksum = "c0f80d65747a3e43d1596c7c5492d95d5edddaabd45a7fcdb02b95f644164966" [[package]] name = "lock_api" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f80bf5aacaf25cbfc8210d1cfb718f2bf3b11c4c54e5afe36c236853a8ec390" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" dependencies = [ "autocfg", "scopeguard", @@ -1064,9 +1064,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.144" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f747710de3dcd43b88c9168773254e809d8ddbdf9653b84e2554ab219f17860" +checksum = "728eb6351430bccb993660dfffc5a72f91ccc1295abaa8ce19b27ebe4f75568b" dependencies = [ "serde_derive", ] @@ -1082,9 +1082,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.144" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94ed3a816fb1d101812f83e789f888322c34e291f894f19590dc310963e87a00" +checksum = "81fa1584d3d1bcacd84c277a0dfe21f5b0f6accf4a23d04d4c6d61f1af522b4c" dependencies = [ "proc-macro2", "quote", @@ -1127,22 +1127,22 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.5" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9db03534dff993187064c4e0c05a5708d2a9728ace9a8959b77bedf415dac5" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.4", + "digest 0.10.5", ] [[package]] name = "sha3" -version = "0.10.4" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaedf34ed289ea47c2b741bb72e5357a209512d67bcd4bda44359e5bf0470f56" +checksum = "e2904bea16a1ae962b483322a1c7b81d976029203aea1f461e51cd7705db7ba9" dependencies = [ - "digest 0.10.4", + "digest 0.10.5", "keccak", ] @@ -1160,10 +1160,10 @@ dependencies = [ name = "signature" version = "1.6.3" dependencies = [ - "digest 0.10.4", + "digest 0.10.5", "hex-literal", "rand_core 0.6.4", - "sha2 0.10.5", + "sha2 0.10.6", "signature_derive", ] @@ -1218,9 +1218,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.99" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13" +checksum = "52205623b1b0f064a4e71182c3b18ae902267282930c6d5462c91b859668426e" dependencies = [ "proc-macro2", "quote", From 460f14e9a5b0b53eb749cf9d30aa92bf4fb5bd34 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Thu, 6 Oct 2022 02:38:29 +0300 Subject: [PATCH 0877/1461] signature: expand hazmat to cover sign-with-rng case (#1130) Expand hazmat with the RandomizedPrehashSigner trait, declaring fn sign_prehash_with_rng(). This is necessary for hazmat implementation for the RSA PSS keys. Signed-off-by: Dmitry Baryshkov Signed-off-by: Dmitry Baryshkov --- signature/src/hazmat.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/signature/src/hazmat.rs b/signature/src/hazmat.rs index 4a117fcdb..8119225c6 100644 --- a/signature/src/hazmat.rs +++ b/signature/src/hazmat.rs @@ -12,6 +12,9 @@ use crate::{Error, Signature}; +#[cfg(feature = "rand-preview")] +use crate::rand_core::{CryptoRng, RngCore}; + /// Sign the provided message prehash, returning a digital signature. pub trait PrehashSigner { /// Attempt to sign the given message digest, returning a digital signature @@ -29,6 +32,29 @@ pub trait PrehashSigner { fn sign_prehash(&self, prehash: &[u8]) -> Result; } +/// Sign the provided message prehash using the provided external randomness source, returning a digital signature. +#[cfg(feature = "rand-preview")] +#[cfg_attr(docsrs, doc(cfg(feature = "rand-preview")))] +pub trait RandomizedPrehashSigner { + /// Attempt to sign the given message digest, returning a digital signature + /// on success, or an error if something went wrong. + /// + /// The `prehash` parameter should be the output of a secure cryptographic + /// hash function. + /// + /// This API takes a `prehash` byte slice as there can potentially be many + /// compatible lengths for the message digest for a given concrete signature + /// algorithm. + /// + /// Allowed lengths are algorithm-dependent and up to a particular + /// implementation to decide. + fn sign_prehash_with_rng( + &self, + rng: impl CryptoRng + RngCore, + prehash: &[u8], + ) -> Result; +} + /// Verify the provided message prehash using `Self` (e.g. a public key) pub trait PrehashVerifier { /// Use `Self` to verify that the provided signature for a given message From 58ab549f94ef8c236fde298bc52ca1fbc3111e46 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Thu, 6 Oct 2022 10:47:39 +1100 Subject: [PATCH 0878/1461] sec1: forward `std` feature (#1131) --- elliptic-curve/CHANGELOG.md | 6 ++++++ elliptic-curve/Cargo.toml | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index 975e749d4..619c175cd 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +- Forward `std` feature to `sec1` dependency ([#1131]) + +[#1131]: https://github.com/RustCrypto/traits/pull/1131 + ## 0.12.3 (2022-08-01) ### Added - Aliases for SEC1 compressed/uncompressed points ([#1067]) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 8a3a098ba..96ba1c1eb 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -54,7 +54,7 @@ hazmat = [] jwk = ["alloc", "base64ct/alloc", "serde", "serde_json", "zeroize/alloc"] pem = ["alloc", "arithmetic", "der/pem", "pem-rfc7468/alloc", "pkcs8", "sec1/pem"] serde = ["alloc", "pkcs8", "sec1/serde", "serdect"] -std = ["alloc", "rand_core/std"] +std = ["alloc", "rand_core/std", "sec1/std"] voprf = ["digest"] [package.metadata.docs.rs] From 51c29407c2d6037fafe675492e352ac4334f3ccf Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 6 Oct 2022 09:19:05 -0600 Subject: [PATCH 0879/1461] signature v1.6.4 (#1132) --- Cargo.lock | 6 +++--- signature/CHANGELOG.md | 8 +++++++- signature/Cargo.toml | 2 +- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d6119b459..e99ad89bb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -62,7 +62,7 @@ name = "async-signature" version = "0.2.1" dependencies = [ "async-trait", - "signature 1.6.3", + "signature 1.6.4", ] [[package]] @@ -311,7 +311,7 @@ dependencies = [ "digest 0.10.5", "elliptic-curve 0.12.3", "password-hash", - "signature 1.6.3", + "signature 1.6.4", "universal-hash 0.5.0", ] @@ -1158,7 +1158,7 @@ dependencies = [ [[package]] name = "signature" -version = "1.6.3" +version = "1.6.4" dependencies = [ "digest 0.10.5", "hex-literal", diff --git a/signature/CHANGELOG.md b/signature/CHANGELOG.md index ad7c81946..86198d54c 100644 --- a/signature/CHANGELOG.md +++ b/signature/CHANGELOG.md @@ -4,7 +4,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 1.6.2 (2022-09-16) +## 1.6.4 (2022-10-06) +### Added +- `RandomizedPrehashSigner` trait in `hazmat` module ([#1130]) + +[#1130]: https://github.com/RustCrypto/traits/pull/1130 + +## 1.6.3 (2022-09-16) ### Changed - Bump `signature_derive` to v1.0.0-pre.7 ([#1119]) diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 26b463b28..9235fac31 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "1.6.3" +version = "1.6.4" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/signature" From 45f3869f9fc30742804b607911f72562ba88cf77 Mon Sep 17 00:00:00 2001 From: Michael Rosenberg Date: Fri, 7 Oct 2022 13:22:38 -0400 Subject: [PATCH 0880/1461] KEM: Updated HPKE deps for testing (#1133) --- .github/workflows/kem.yml | 4 ++-- kem/Cargo.toml | 15 +++------------ 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/.github/workflows/kem.yml b/.github/workflows/kem.yml index 7bf9bcdbd..4ece828aa 100644 --- a/.github/workflows/kem.yml +++ b/.github/workflows/kem.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.57.0 # Next MSRV candidate - stable target: - thumbv7em-none-eabi @@ -59,7 +59,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.57.0 # Next MSRV candidate - stable steps: - uses: actions/checkout@v3 diff --git a/kem/Cargo.toml b/kem/Cargo.toml index 60cc0e567..b81be916f 100644 --- a/kem/Cargo.toml +++ b/kem/Cargo.toml @@ -18,21 +18,12 @@ generic-array = "0.14" zeroize = { version = "1.5", default-features = false } [dev-dependencies] -rand = { version = "0.8", features = [ "getrandom" ] } -x3dh-ke = "0.1" +hpke = "0.10" p256 = { version = "0.9", features = [ "ecdsa" ] } pqcrypto = { version = "0.15", default-features = false, features = [ "pqcrypto-saber" ] } pqcrypto-traits = "0.3" - -# We use an hpke commit that pulls in x25519-dalek v2.0.0-pre.1. This is necessary because all the -# modern crates (including this one) use zeroize >1.3, which is incompatible with the previous -# x25519-dalek version. Once the next x25519-dalek version is cut, the next hpke version will be -# cut, and this commit-based dependency can go away. -[dev-dependencies.hpke] -git = "https://github.com/rozbb/rust-hpke" -rev = "18eda000f27a871f360c283b30407a95169d7d58" -default-features = false -features = [ "x25519" ] +rand = { version = "0.8", features = [ "getrandom" ] } +x3dh-ke = "0.1" [features] default = [] From d3793270eb3b28d4fb7f8d2eb953cc6f4c059715 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Oct 2022 16:14:35 -0600 Subject: [PATCH 0881/1461] build(deps): bump serde_json from 1.0.85 to 1.0.86 (#1134) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.85 to 1.0.86. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.85...v1.0.86) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 43 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e99ad89bb..2bdfc409a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -491,6 +491,26 @@ dependencies = [ "zeroize", ] +[[package]] +name = "elliptic-curve" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +dependencies = [ + "base16ct", + "crypto-bigint 0.4.8", + "der 0.6.0", + "digest 0.10.5", + "ff 0.12.0", + "generic-array", + "group 0.12.0", + "hkdf 0.12.3", + "rand_core 0.6.4", + "sec1", + "subtle", + "zeroize", +] + [[package]] name = "embedded-hal" version = "0.2.7" @@ -655,8 +675,9 @@ dependencies = [ [[package]] name = "hpke" -version = "0.9.0" -source = "git+https://github.com/rozbb/rust-hpke?rev=18eda000f27a871f360c283b30407a95169d7d58#18eda000f27a871f360c283b30407a95169d7d58" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf39e5461bfdc6ad0fbc97067519fcaf96a7a2e67f24cc0eb8a1e7c0c45af792" dependencies = [ "aead 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "aes-gcm", @@ -666,6 +687,7 @@ dependencies = [ "generic-array", "hkdf 0.12.3", "hmac 0.12.1", + "p256 0.11.1", "rand_core 0.6.4", "sha2 0.10.6", "subtle", @@ -710,7 +732,7 @@ version = "0.2.0" dependencies = [ "generic-array", "hpke", - "p256", + "p256 0.9.0", "pqcrypto", "pqcrypto-traits", "rand", @@ -779,6 +801,15 @@ dependencies = [ "sha2 0.9.9", ] +[[package]] +name = "p256" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51f44edd08f51e2ade572f141051021c5af22677e42b7dd28a88155151c33594" +dependencies = [ + "elliptic-curve 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "password-hash" version = "0.4.2" @@ -1093,9 +1124,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.85" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44" +checksum = "41feea4228a6f1cd09ec7a3593a682276702cd67b5273544757dae23c096f074" dependencies = [ "itoa", "ryu", @@ -1345,7 +1376,7 @@ dependencies = [ "const-oid 0.6.2", "getrandom", "hkdf 0.11.0", - "p256", + "p256 0.9.0", "rand_core 0.6.4", "serde", "serde_bytes", From bc099c68f865e47772c370e97f22134aa23b8763 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 13 Oct 2022 16:21:20 -0600 Subject: [PATCH 0882/1461] build(deps): bump group from 0.12.0 to 0.12.1 (#1137) Bumps [group](https://github.com/zkcrypto/group) from 0.12.0 to 0.12.1. - [Release notes](https://github.com/zkcrypto/group/releases) - [Changelog](https://github.com/zkcrypto/group/blob/main/CHANGELOG.md) - [Commits](https://github.com/zkcrypto/group/commits) --- updated-dependencies: - dependency-name: group dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2bdfc409a..981eb7a25 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -476,7 +476,7 @@ dependencies = [ "digest 0.10.5", "ff 0.12.0", "generic-array", - "group 0.12.0", + "group 0.12.1", "hex-literal", "hkdf 0.12.3", "pem-rfc7468 0.6.0", @@ -503,7 +503,7 @@ dependencies = [ "digest 0.10.5", "ff 0.12.0", "generic-array", - "group 0.12.0", + "group 0.12.1", "hkdf 0.12.3", "rand_core 0.6.4", "sec1", @@ -598,9 +598,9 @@ dependencies = [ [[package]] name = "group" -version = "0.12.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7391856def869c1c81063a03457c676fbcd419709c3dfb33d8d319de484b154d" +checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" dependencies = [ "ff 0.12.0", "rand_core 0.6.4", From c0c0849003c72cebbb7ff0d0b8f197ede62a57a4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Oct 2022 16:24:29 -0600 Subject: [PATCH 0883/1461] build(deps): bump sha3 from 0.10.5 to 0.10.6 (#1138) Bumps [sha3](https://github.com/RustCrypto/hashes) from 0.10.5 to 0.10.6. - [Release notes](https://github.com/RustCrypto/hashes/releases) - [Commits](https://github.com/RustCrypto/hashes/compare/sha3-v0.10.5...sha3-v0.10.6) --- updated-dependencies: - dependency-name: sha3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 981eb7a25..525686b71 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1169,9 +1169,9 @@ dependencies = [ [[package]] name = "sha3" -version = "0.10.5" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2904bea16a1ae962b483322a1c7b81d976029203aea1f461e51cd7705db7ba9" +checksum = "bdf0c33fae925bdc080598b84bc15c55e7b9a4a43b3c704da051f977469691c9" dependencies = [ "digest 0.10.5", "keccak", From 73876ed601a72f6cbf63dd69467108943817010d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Oct 2022 17:50:21 -0600 Subject: [PATCH 0884/1461] build(deps): bump serde_json from 1.0.86 to 1.0.87 (#1139) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.86 to 1.0.87. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.86...v1.0.87) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 525686b71..79330f9ae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1124,9 +1124,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.86" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41feea4228a6f1cd09ec7a3593a682276702cd67b5273544757dae23c096f074" +checksum = "6ce777b7b150d76b9cf60d28b55f5847135a003f7d7350c6be7a773508ce7d45" dependencies = [ "itoa", "ryu", From 507349e28ee8175b13f30e9a71bdde49ba548d18 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Oct 2022 19:02:25 -0600 Subject: [PATCH 0885/1461] build(deps): bump base64ct from 1.5.2 to 1.5.3 (#1140) Bumps [base64ct](https://github.com/RustCrypto/formats) from 1.5.2 to 1.5.3. - [Release notes](https://github.com/RustCrypto/formats/releases) - [Commits](https://github.com/RustCrypto/formats/compare/base64ct-v1.5.2...base64ct/v1.5.3) --- updated-dependencies: - dependency-name: base64ct dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 79330f9ae..46cc60015 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -114,9 +114,9 @@ checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" [[package]] name = "base64ct" -version = "1.5.2" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea2b2456fd614d856680dcd9fcc660a51a820fa09daef2e49772b56a193c8474" +checksum = "b645a089122eccb6111b4f81cbc1a49f5900ac4666bb93ac027feaecf15607bf" [[package]] name = "bincode" From 5c9307253ff3dd82d07ea6513e4a38519daceaa3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Oct 2022 13:28:24 -0600 Subject: [PATCH 0886/1461] build(deps): bump crypto-bigint from 0.4.8 to 0.4.9 (#1135) Bumps [crypto-bigint](https://github.com/RustCrypto/crypto-bigint) from 0.4.8 to 0.4.9. - [Release notes](https://github.com/RustCrypto/crypto-bigint/releases) - [Changelog](https://github.com/RustCrypto/crypto-bigint/blob/master/CHANGELOG.md) - [Commits](https://github.com/RustCrypto/crypto-bigint/compare/v0.4.8...v0.4.9) --- updated-dependencies: - dependency-name: crypto-bigint dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 46cc60015..948a7172a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -329,9 +329,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f2b443d17d49dad5ef0ede301c3179cc923b8822f3393b4d2c28c269dd4a122" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" dependencies = [ "generic-array", "rand_core 0.6.4", @@ -471,7 +471,7 @@ version = "0.12.3" dependencies = [ "base16ct", "base64ct", - "crypto-bigint 0.4.8", + "crypto-bigint 0.4.9", "der 0.6.0", "digest 0.10.5", "ff 0.12.0", @@ -498,7 +498,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" dependencies = [ "base16ct", - "crypto-bigint 0.4.8", + "crypto-bigint 0.4.9", "der 0.6.0", "digest 0.10.5", "ff 0.12.0", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 96ba1c1eb..73310f588 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -17,7 +17,7 @@ rust-version = "1.57" [dependencies] base16ct = "0.1.1" -crypto-bigint = { version = "0.4.8", default-features = false, features = ["rand_core", "generic-array", "zeroize"] } +crypto-bigint = { version = "0.4.9", default-features = false, features = ["rand_core", "generic-array", "zeroize"] } der = { version = "0.6", default-features = false, features = ["oid"] } generic-array = { version = "0.14", default-features = false } rand_core = { version = "0.6", default-features = false } From f8c2ff2f9913a707471fd60f24650cee4366e772 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 29 Oct 2022 14:45:47 -0600 Subject: [PATCH 0887/1461] build(deps): bump ff from 0.12.0 to 0.12.1 (#1142) Bumps [ff](https://github.com/zkcrypto/ff) from 0.12.0 to 0.12.1. - [Release notes](https://github.com/zkcrypto/ff/releases) - [Changelog](https://github.com/zkcrypto/ff/blob/main/CHANGELOG.md) - [Commits](https://github.com/zkcrypto/ff/commits) --- updated-dependencies: - dependency-name: ff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 948a7172a..344e2059c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -474,7 +474,7 @@ dependencies = [ "crypto-bigint 0.4.9", "der 0.6.0", "digest 0.10.5", - "ff 0.12.0", + "ff 0.12.1", "generic-array", "group 0.12.1", "hex-literal", @@ -501,7 +501,7 @@ dependencies = [ "crypto-bigint 0.4.9", "der 0.6.0", "digest 0.10.5", - "ff 0.12.0", + "ff 0.12.1", "generic-array", "group 0.12.1", "hkdf 0.12.3", @@ -533,9 +533,9 @@ dependencies = [ [[package]] name = "ff" -version = "0.12.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df689201f395c6b90dfe87127685f8dbfc083a5e779e613575d8bd7314300c3e" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" dependencies = [ "bitvec", "rand_core 0.6.4", @@ -602,7 +602,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" dependencies = [ - "ff 0.12.0", + "ff 0.12.1", "rand_core 0.6.4", "subtle", ] From 36aa416eb2973c1019b0c1f668e9058ea4ed3611 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 29 Oct 2022 14:47:17 -0600 Subject: [PATCH 0888/1461] signature v2.0.0-pre (#1141) This commit contains the first breaking changes to the `signature` crate made since its initial 1.0 stabilization. Planning for these changes occurred in #237. The following changes have been made: - The `Signature` trait has been renamed to `SignatureEncoding`. The `Signature` bound on `*Signer` and `*Verifier` traits has been removed, meaning there are no longer any mandatory trait bounds on the signature parameters at all. - The `AsRef<[u8]>` bound formerly found on the `Signature` crate has been replaced with an associated `Repr` type, inspired by the `group::GroupEncoding` trait. This means signature types no longer need to retain a serialized form, and can parse the bag-of-bytes representation to something more convenient, which is useful for e.g. batch verification. - The `std` feature is no longer enabled by default, which matches the other RustCrypto/traits crates. - The `derive-preview` and `hazmat-preview` features have been stabilized. - The former `Keypair` trait has been renamed to `KeypairRef`, and the signature generic parameter removed. A new `Keypair` trait has been added which returns an owned instance of the associated `VerifyingKey`, and a blanket impl of `Keypair` for `KeypairRef` has been added. This addresses the issues described in #1124. --- .github/workflows/signature.yml | 6 +-- Cargo.lock | 8 ++-- crypto/Cargo.toml | 4 +- signature/Cargo.toml | 10 ++--- signature/README.md | 25 +++++------ signature/async/Cargo.toml | 2 +- signature/async/src/lib.rs | 37 +++------------- signature/derive/src/lib.rs | 27 ++++++------ signature/src/encoding.rs | 38 +++++++++++++++++ signature/src/error.rs | 6 +-- signature/src/hazmat.rs | 8 ++-- signature/src/keypair.rs | 24 ++++++++--- signature/src/lib.rs | 64 ++++++++++------------------ signature/src/prehash_signature.rs | 32 ++++++++++++++ signature/src/signature.rs | 68 ------------------------------ signature/src/signer.rs | 28 ++++-------- signature/src/verifier.rs | 10 ++--- signature/tests/derive.rs | 38 ++++++++++------- 18 files changed, 195 insertions(+), 240 deletions(-) create mode 100644 signature/src/encoding.rs create mode 100644 signature/src/prehash_signature.rs delete mode 100644 signature/src/signature.rs diff --git a/.github/workflows/signature.yml b/.github/workflows/signature.yml index 1e87d18c8..592915ecf 100644 --- a/.github/workflows/signature.yml +++ b/.github/workflows/signature.yml @@ -37,10 +37,10 @@ jobs: override: true profile: minimal - run: cargo build --target ${{ matrix.target }} --release --no-default-features - - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features derive-preview + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features derive - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features digest-preview - - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features hazmat-preview - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features rand-preview + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features derive,digest-preview,rand-preview minimal-versions: uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master @@ -83,4 +83,4 @@ jobs: override: true profile: minimal - run: cargo test --release - working-directory: signature/derive \ No newline at end of file + working-directory: signature/derive diff --git a/Cargo.lock b/Cargo.lock index 344e2059c..b24400783 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -62,7 +62,7 @@ name = "async-signature" version = "0.2.1" dependencies = [ "async-trait", - "signature 1.6.4", + "signature 2.0.0-pre", ] [[package]] @@ -303,7 +303,7 @@ dependencies = [ [[package]] name = "crypto" -version = "0.4.0" +version = "0.5.0-pre" dependencies = [ "aead 0.5.1", "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -311,7 +311,7 @@ dependencies = [ "digest 0.10.5", "elliptic-curve 0.12.3", "password-hash", - "signature 1.6.4", + "signature 2.0.0-pre", "universal-hash 0.5.0", ] @@ -1189,7 +1189,7 @@ dependencies = [ [[package]] name = "signature" -version = "1.6.4" +version = "2.0.0-pre" dependencies = [ "digest 0.10.5", "hex-literal", diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 3f26148de..1f73bd7aa 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "crypto" -version = "0.4.0" # Also update html_root_url in lib.rs when bumping this +version = "0.5.0-pre" # Also update html_root_url in lib.rs when bumping this description = """ Resources for building cryptosystems in Rust using the RustCrypto project's ecosystem. """ @@ -23,7 +23,7 @@ cipher = { version = "0.4", optional = true } digest = { version = "0.10", optional = true, features = ["mac"] } elliptic-curve = { version = "0.12", optional = true, path = "../elliptic-curve" } password-hash = { version = "0.4", optional = true, path = "../password-hash" } -signature = { version = "1.5", optional = true, default-features = false, path = "../signature" } +signature = { version = "=2.0.0-pre", optional = true, default-features = false, path = "../signature" } universal-hash = { version = "0.5", optional = true, path = "../universal-hash" } [features] diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 9235fac31..c55628df7 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "1.6.4" +version = "2.0.0-pre" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/signature" @@ -15,21 +15,19 @@ categories = ["cryptography", "no-std"] [dependencies] digest = { version = "0.10.3", optional = true, default-features = false } rand_core = { version = "0.6", optional = true, default-features = false } -signature_derive = { version = "=1.0.0-pre.7", optional = true, path = "derive" } +derive = { package = "signature_derive", version = "=1.0.0-pre.7", optional = true, path = "derive" } [dev-dependencies] hex-literal = "0.3" sha2 = { version = "0.10", default-features = false } [features] -default = ["std"] -std = [] +alloc = [] +std = ["alloc"] # Preview features are unstable and exempt from semver. # See https://docs.rs/signature/latest/signature/#unstable-features for more information. -derive-preview = ["digest-preview", "signature_derive"] digest-preview = ["digest"] -hazmat-preview = [] rand-preview = ["rand_core"] [package.metadata.docs.rs] diff --git a/signature/README.md b/signature/README.md index a1a6fa4ae..52ae899de 100644 --- a/signature/README.md +++ b/signature/README.md @@ -1,4 +1,4 @@ -# RustCrypto: Digital Signature Algorithms +# [RustCrypto]: Digital Signature Algorithms [![crate][crate-image]][crate-link] [![Docs][docs-image]][docs-link] @@ -8,14 +8,10 @@ [![Project Chat][chat-image]][chat-link] This crate contains traits which provide generic, object-safe APIs for -generating and verifying [digital signatures][1]. +generating and verifying [digital signatures]. -Used by the [`ecdsa`][2] and [`ed25519`][3] crates, with forthcoming support -in the [`rsa`][4] crate. - -See also the [Signatory][5] crate for trait wrappers for using these traits -with many popular Rust cryptography crates, including `ed25519-dalek`, *ring*, -`secp256k1-rs`, and `sodiumoxide`. +Used by the [`dsa`], [`ecdsa`], [`ed25519`], and [`rsa`] crates maintained by +the [RustCrypto] organization, as well as [`ed25519-dalek`]. [Documentation][docs-link] @@ -63,10 +59,11 @@ dual licensed as above, without any additional terms or conditions. [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260048-signatures -[//]: # (general links) +[//]: # (links) -[1]: https://en.wikipedia.org/wiki/Digital_signature -[2]: https://github.com/RustCrypto/signatures/tree/master/ecdsa -[3]: https://github.com/RustCrypto/signatures/tree/master/ed25519 -[4]: https://github.com/RustCrypto/RSA -[5]: https://docs.rs/signatory +[digital signatures]: https://en.wikipedia.org/wiki/Digital_signature +[`dsa`]: https://github.com/RustCrypto/signatures/tree/master/dsa +[`ecdsa`]: https://github.com/RustCrypto/signatures/tree/master/ecdsa +[`ed25519`]: https://github.com/RustCrypto/signatures/tree/master/ed25519 +[`ed25519-dalek`]: https://github.com/dalek-cryptography/ed25519-dalek +[`rsa`]: https://github.com/RustCrypto/RSA diff --git a/signature/async/Cargo.toml b/signature/async/Cargo.toml index c81957044..13c964df8 100644 --- a/signature/async/Cargo.toml +++ b/signature/async/Cargo.toml @@ -14,7 +14,7 @@ rust-version = "1.56" [dependencies] async-trait = "0.1.9" -signature = { version = "1.6", path = ".." } +signature = { version = "=2.0.0-pre", path = ".." } [features] digest = ["signature/digest-preview"] diff --git a/signature/async/src/lib.rs b/signature/async/src/lib.rs index fe12a3ca4..2e8bb09f0 100644 --- a/signature/async/src/lib.rs +++ b/signature/async/src/lib.rs @@ -7,7 +7,7 @@ #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms, unused_qualifications)] -pub use signature::{self, Error, Signature}; +pub use signature::{self, Error}; #[cfg(feature = "digest")] pub use signature::digest::{self, Digest}; @@ -22,7 +22,7 @@ use async_trait::async_trait; pub trait AsyncSigner where Self: Send + Sync, - S: Signature + Send + 'static, + S: Send + 'static, { /// Attempt to sign the given message, returning a digital signature on /// success, or an error if something went wrong. @@ -35,7 +35,7 @@ where #[async_trait] impl AsyncSigner for T where - S: Signature + Send + 'static, + S: Send + 'static, T: signature::Signer + Send + Sync, { async fn sign_async(&self, msg: &[u8]) -> Result { @@ -53,7 +53,7 @@ pub trait AsyncDigestSigner where Self: Send + Sync, D: Digest + Send + 'static, - S: Signature + 'static, + S: 'static, { /// Attempt to sign the given prehashed message [`Digest`], returning a /// digital signature on success, or an error if something went wrong. @@ -65,37 +65,10 @@ where impl AsyncDigestSigner for T where D: Digest + Send + 'static, - S: Signature + Send + 'static, + S: Send + 'static, T: signature::DigestSigner + Send + Sync, { async fn sign_digest_async(&self, digest: D) -> Result { self.try_sign_digest(digest) } } - -/// Keypair with async signer component and an associated verifying key. -/// -/// This represents a type which holds both an async signing key and a verifying key. -#[deprecated(since = "0.2.1", note = "use signature::Keypair instead")] -pub trait AsyncKeypair: AsRef -where - S: Signature + Send + 'static, -{ - /// Verifying key type for this keypair. - type VerifyingKey; - - /// Get the verifying key which can verify signatures produced by the - /// signing key portion of this keypair. - fn verifying_key(&self) -> &Self::VerifyingKey { - self.as_ref() - } -} - -#[allow(deprecated)] -impl AsyncKeypair for T -where - S: Signature + Send + 'static, - T: signature::Keypair + Send + Sync, -{ - type VerifyingKey = >::VerifyingKey; -} diff --git a/signature/derive/src/lib.rs b/signature/derive/src/lib.rs index 8de761813..1afb0aaa2 100644 --- a/signature/derive/src/lib.rs +++ b/signature/derive/src/lib.rs @@ -129,7 +129,7 @@ fn emit_digest_signer_impl(input: DeriveInput) -> TokenStream2 { let mut params = DeriveParams::new(input); params.add_bound(&d_ident, parse_quote!(::signature::digest::Digest)); - params.add_bound(&s_ident, parse_quote!(::signature::Signature)); + params.add_param(&s_ident); params.add_bound( &Ident::new("Self", Span::call_site()), parse_quote!(::signature::hazmat::PrehashSigner<#s_ident>), @@ -167,7 +167,7 @@ fn emit_digest_verifier_impl(input: DeriveInput) -> TokenStream2 { let mut params = DeriveParams::new(input); params.add_bound(&d_ident, parse_quote!(::signature::digest::Digest)); - params.add_bound(&s_ident, parse_quote!(::signature::Signature)); + params.add_param(&s_ident); params.add_bound( &Ident::new("Self", Span::call_site()), parse_quote!(::signature::hazmat::PrehashVerifier<#s_ident>), @@ -235,14 +235,7 @@ impl DeriveParams { /// Add a generic parameter with the given bound. fn add_bound(&mut self, name: &Ident, bound: TraitBound) { if name != "Self" { - self.impl_generics.push(TypeParam { - attrs: vec![], - ident: name.clone(), - colon_token: None, - bounds: Default::default(), - eq_token: None, - default: None, - }); + self.add_param(name); } let type_path = parse_quote!(#name); @@ -261,6 +254,18 @@ impl DeriveParams { .predicates .push(WherePredicate::Type(predicate_type)) } + + /// Add a generic parameter without a bound. + fn add_param(&mut self, name: &Ident) { + self.impl_generics.push(TypeParam { + attrs: vec![], + ident: name.clone(), + colon_token: None, + bounds: Default::default(), + eq_token: None, + default: None, + }); + } } #[cfg(test)] @@ -345,7 +350,6 @@ mod tests { impl ::signature::DigestSigner<__D, __S> for MySigner where __D: ::signature::digest::Digest, - __S: ::signature::Signature, Self: ::signature::hazmat::PrehashSigner<__S> { fn try_sign_digest(&self, digest: __D) -> ::signature::Result<__S> { @@ -374,7 +378,6 @@ mod tests { impl ::signature::DigestVerifier<__D, __S> for MyVerifier where __D: ::signature::digest::Digest, - __S: ::signature::Signature, Self: ::signature::hazmat::PrehashVerifier<__S> { fn verify_digest(&self, digest: __D, signature: &__S) -> ::signature::Result<()> { diff --git a/signature/src/encoding.rs b/signature/src/encoding.rs new file mode 100644 index 000000000..f4d281c2a --- /dev/null +++ b/signature/src/encoding.rs @@ -0,0 +1,38 @@ +//! Encoding support. + +use crate::{Error, Result}; + +#[cfg(feature = "alloc")] +use alloc::{boxed::Box, vec::Vec}; + +/// Support for decoding/encoding signatures as bytes. +pub trait SignatureEncoding: + Clone + Sized + for<'a> TryFrom<&'a [u8], Error = Error> + Into +{ + /// Byte representation of a signature. + type Repr: 'static + AsRef<[u8]> + AsMut<[u8]> + Clone + Default + Send + Sync; + + /// Decode signature from its byte representation. + fn from_bytes(bytes: &Self::Repr) -> Result { + Self::try_from(bytes.as_ref()) + } + + /// Encode signature as its byte representation. + fn to_bytes(&self) -> Self::Repr { + self.clone().into() + } + + /// Encode signature as a byte vector. + #[cfg(feature = "alloc")] + #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] + fn to_vec(&self) -> Vec { + self.to_bytes().as_ref().to_vec() + } + + /// Encode the signature as a boxed byte slice. + #[cfg(feature = "alloc")] + #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] + fn to_boxed_slice(&self) -> Box<[u8]> { + self.to_vec().into_boxed_slice() + } +} diff --git a/signature/src/error.rs b/signature/src/error.rs index 06e22d527..831dbc89d 100644 --- a/signature/src/error.rs +++ b/signature/src/error.rs @@ -22,11 +22,8 @@ pub type Result = core::result::Result; /// /// [BB'06]: https://en.wikipedia.org/wiki/Daniel_Bleichenbacher #[derive(Default)] +#[non_exhaustive] pub struct Error { - /// Prevent from being instantiated as `Error {}` when the `std` feature - /// is disabled - _private: (), - /// Source of the error (if applicable). #[cfg(feature = "std")] source: Option>, @@ -50,7 +47,6 @@ impl Error { source: impl Into>, ) -> Self { Self { - _private: (), source: Some(source.into()), } } diff --git a/signature/src/hazmat.rs b/signature/src/hazmat.rs index 8119225c6..1b2e702ae 100644 --- a/signature/src/hazmat.rs +++ b/signature/src/hazmat.rs @@ -10,13 +10,13 @@ //! feature is semi-unstable and not subject to regular 1.x SemVer guarantees. //! However, any breaking changes will be accompanied with a minor version bump. -use crate::{Error, Signature}; +use crate::Error; #[cfg(feature = "rand-preview")] use crate::rand_core::{CryptoRng, RngCore}; /// Sign the provided message prehash, returning a digital signature. -pub trait PrehashSigner { +pub trait PrehashSigner { /// Attempt to sign the given message digest, returning a digital signature /// on success, or an error if something went wrong. /// @@ -35,7 +35,7 @@ pub trait PrehashSigner { /// Sign the provided message prehash using the provided external randomness source, returning a digital signature. #[cfg(feature = "rand-preview")] #[cfg_attr(docsrs, doc(cfg(feature = "rand-preview")))] -pub trait RandomizedPrehashSigner { +pub trait RandomizedPrehashSigner { /// Attempt to sign the given message digest, returning a digital signature /// on success, or an error if something went wrong. /// @@ -56,7 +56,7 @@ pub trait RandomizedPrehashSigner { } /// Verify the provided message prehash using `Self` (e.g. a public key) -pub trait PrehashVerifier { +pub trait PrehashVerifier { /// Use `Self` to verify that the provided signature for a given message /// `prehash` is authentic. /// diff --git a/signature/src/keypair.rs b/signature/src/keypair.rs index 6d9f947c6..d4795f2f9 100644 --- a/signature/src/keypair.rs +++ b/signature/src/keypair.rs @@ -1,17 +1,29 @@ //! Signing keypairs. -use crate::Signature; - /// Signing keypair with an associated verifying key. /// /// This represents a type which holds both a signing key and a verifying key. -pub trait Keypair: AsRef { +pub trait Keypair { /// Verifying key type for this keypair. - type VerifyingKey; + type VerifyingKey: Clone; /// Get the verifying key which can verify signatures produced by the /// signing key portion of this keypair. - fn verifying_key(&self) -> &Self::VerifyingKey { - self.as_ref() + fn verifying_key(&self) -> Self::VerifyingKey; +} + +/// Signing keypair with an associated verifying key. +/// +/// This represents a type which holds both a signing key and a verifying key. +pub trait KeypairRef: AsRef { + /// Verifying key type for this keypair. + type VerifyingKey: Clone; +} + +impl Keypair for K { + type VerifyingKey = ::VerifyingKey; + + fn verifying_key(&self) -> Self::VerifyingKey { + self.as_ref().clone() } } diff --git a/signature/src/lib.rs b/signature/src/lib.rs index ab504c2ac..d35ec5f9a 100644 --- a/signature/src/lib.rs +++ b/signature/src/lib.rs @@ -43,24 +43,14 @@ //! ## Implementation //! //! To accomplish the above goals, the [`Signer`] and [`Verifier`] traits -//! provided by this are generic over a [`Signature`] return value, and use -//! generic parameters rather than associated types. Notably, they use such -//! a parameter for the return value, allowing it to be inferred by the type -//! checker based on the desired signature type. -//! -//! The [`Signature`] trait is bounded on `AsRef<[u8]>`, enforcing that -//! signature types are thin wrappers around a "bag-of-bytes" -//! serialization. Inspiration for this approach comes from the Ed25519 -//! signature system, which was based on the observation that past -//! systems were not prescriptive about how signatures should be represented -//! on-the-wire, and that lead to a proliferation of different wire formats -//! and confusion about which ones should be used. This crate aims to provide -//! similar simplicity by minimizing the number of steps involved to obtain -//! a serializable signature. +//! provided by this are generic over a signature value, and use generic +//! parameters rather than associated types. Notably, they use such a parameter +//! for the return value, allowing it to be inferred by the type checker based +//! on the desired signature type. //! //! ## Alternatives considered //! -//! This crate is based on over two years of exploration of how to encapsulate +//! This crate is based on many years of exploration of how to encapsulate //! digital signature systems in the most flexible, developer-friendly way. //! During that time many design alternatives were explored, tradeoffs //! compared, and ultimately the provided API was selected. @@ -73,10 +63,7 @@ //! - "Bag-of-bytes" serialization precludes signature providers from using //! their own internal representation of a signature, which can be helpful //! for many reasons (e.g. advanced signature system features like batch -//! verification). Alternatively each provider could define its own signature -//! type, using a marker trait to identify the particular signature algorithm, -//! have `From` impls for converting to/from `[u8; N]`, and a marker trait -//! for identifying a specific signature algorithm. +//! verification). //! - Associated types, rather than generic parameters of traits, could allow //! more customization of the types used by a particular signature system, //! e.g. using custom error types. @@ -121,7 +108,7 @@ //! [`DigestSigner`] and [`DigestVerifier`], the `derive-preview` feature //! can be used to derive [`Signer`] and [`Verifier`] traits which prehash //! the input message using the [`PrehashSignature::Digest`] algorithm for -//! a given [`Signature`] type. When the `derive-preview` feature is enabled +//! a given signature type. When the `derive-preview` feature is enabled //! import the proc macros with `use signature::{Signer, Verifier}` and then //! add a `derive(Signer)` or `derive(Verifier)` attribute to the given //! digest signer/verifier type. Enabling this feature also enables `digest` @@ -143,15 +130,12 @@ //! [`Digest`]: https://docs.rs/digest/latest/digest/trait.Digest.html //! [Fiat-Shamir heuristic]: https://en.wikipedia.org/wiki/Fiat%E2%80%93Shamir_heuristic +#[cfg(feature = "alloc")] +extern crate alloc; + #[cfg(feature = "std")] extern crate std; -#[cfg(all(feature = "signature_derive", not(feature = "derive-preview")))] -compile_error!( - "The `signature_derive` feature should not be enabled directly. \ - Use the `derive-preview` feature instead." -); - #[cfg(all(feature = "digest", not(feature = "digest-preview")))] compile_error!( "The `digest` feature should not be enabled directly. \ @@ -164,32 +148,30 @@ compile_error!( Use the `rand-preview` feature instead." ); -#[cfg(feature = "hazmat-preview")] -#[cfg_attr(docsrs, doc(cfg(feature = "hazmat-preview")))] pub mod hazmat; +mod encoding; mod error; mod keypair; -mod signature; mod signer; mod verifier; -#[cfg(feature = "derive-preview")] -#[cfg_attr(docsrs, doc(cfg(feature = "derive-preview")))] -pub use signature_derive::{Signer, Verifier}; +#[cfg(feature = "digest-preview")] +mod prehash_signature; -#[cfg(all(feature = "derive-preview", feature = "digest-preview"))] -#[cfg_attr( - docsrs, - doc(cfg(all(feature = "derive-preview", feature = "digest-preview"))) -)] -pub use signature_derive::{DigestSigner, DigestVerifier}; +pub use crate::{encoding::*, error::*, keypair::*, signer::*, verifier::*}; + +#[cfg(feature = "derive")] +#[cfg_attr(docsrs, doc(cfg(feature = "derive")))] +pub use derive::{Signer, Verifier}; + +#[cfg(all(feature = "derive", feature = "digest-preview"))] +#[cfg_attr(docsrs, doc(cfg(all(feature = "derive", feature = "digest-preview"))))] +pub use derive::{DigestSigner, DigestVerifier}; #[cfg(feature = "digest-preview")] -pub use digest; +pub use {crate::prehash_signature::*, digest}; #[cfg(feature = "rand-preview")] #[cfg_attr(docsrs, doc(cfg(feature = "rand-preview")))] pub use rand_core; - -pub use crate::{error::*, keypair::*, signature::*, signer::*, verifier::*}; diff --git a/signature/src/prehash_signature.rs b/signature/src/prehash_signature.rs new file mode 100644 index 000000000..779b0dcdb --- /dev/null +++ b/signature/src/prehash_signature.rs @@ -0,0 +1,32 @@ +//! `PrehashSignature` trait. + +/// For intra-doc link resolution. +#[allow(unused_imports)] +use crate::{ + signer::{DigestSigner, Signer}, + verifier::{DigestVerifier, Verifier}, +}; + +/// Marker trait for `Signature` types computable as `𝐒(𝐇(𝒎))` +/// i.e. ones which prehash a message to be signed as `𝐇(𝒎)` +/// +/// Where: +/// +/// - `𝐒`: signature algorithm +/// - `𝐇`: hash (a.k.a. digest) function +/// - `𝒎`: message +/// +/// This approach is relatively common in signature schemes based on the +/// [Fiat-Shamir heuristic]. +/// +/// For signature types that implement this trait, when the `derive-preview` +/// Cargo feature is enabled a custom derive for [`Signer`] is available for any +/// types that impl [`DigestSigner`], and likewise for deriving [`Verifier`] for +/// types which impl [`DigestVerifier`]. +/// +/// [Fiat-Shamir heuristic]: https://en.wikipedia.org/wiki/Fiat%E2%80%93Shamir_heuristic +#[cfg_attr(docsrs, doc(cfg(feature = "digest")))] +pub trait PrehashSignature { + /// Preferred `Digest` algorithm to use when computing this signature type. + type Digest: digest::Digest; +} diff --git a/signature/src/signature.rs b/signature/src/signature.rs deleted file mode 100644 index 29aa0b845..000000000 --- a/signature/src/signature.rs +++ /dev/null @@ -1,68 +0,0 @@ -//! Signature traits - -use crate::error::Error; -use core::fmt::Debug; - -/// For intra-doc link resolution -#[cfg(feature = "digest-preview")] -#[allow(unused_imports)] -use crate::{ - signer::{DigestSigner, Signer}, - verifier::{DigestVerifier, Verifier}, -}; - -/// Trait impl'd by concrete types that represent digital signatures. -/// -/// Signature types *must* (as mandated by the `AsRef<[u8]>` bound) be a thin -/// wrapper around the "bag-of-bytes" serialized form of a signature which can -/// be directly parsed from or written to the "wire". -/// -/// Inspiration for this approach comes from the Ed25519 signature system, -/// which adopted it based on the observation that past signature systems -/// were not prescriptive about how signatures should be represented -/// on-the-wire, and that lead to a proliferation of different wire formats and -/// confusion about which ones should be used. -/// -/// The [`Signature`] trait aims to provide similar simplicity by minimizing -/// the number of steps involved to obtain a serializable signature and -/// ideally ensuring there is one signature type for any given signature system -/// shared by all "provider" crates. -/// -/// For signature systems which require a more advanced internal representation -/// (e.g. involving decoded scalars or decompressed elliptic curve points) it's -/// recommended that "provider" libraries maintain their own internal signature -/// type and use `From` bounds to provide automatic conversions. -pub trait Signature: AsRef<[u8]> + Debug + Sized { - /// Parse a signature from its byte representation - fn from_bytes(bytes: &[u8]) -> Result; - - /// Borrow a byte slice representing the serialized form of this signature - fn as_bytes(&self) -> &[u8] { - self.as_ref() - } -} - -/// Marker trait for `Signature` types computable as `𝐒(𝐇(𝒎))` -/// i.e. ones which prehash a message to be signed as `𝐇(𝒎)` -/// -/// Where: -/// -/// - `𝐒`: signature algorithm -/// - `𝐇`: hash (a.k.a. digest) function -/// - `𝒎`: message -/// -/// This approach is relatively common in signature schemes based on the -/// [Fiat-Shamir heuristic]. -/// -/// For signature types that implement this trait, when the `derive-preview` -/// Cargo feature is enabled a custom derive for [`Signer`] is available for any -/// types that impl [`DigestSigner`], and likewise for deriving [`Verifier`] for -/// types which impl [`DigestVerifier`]. -/// -/// [Fiat-Shamir heuristic]: https://en.wikipedia.org/wiki/Fiat%E2%80%93Shamir_heuristic -#[cfg(feature = "digest-preview")] -#[cfg_attr(docsrs, doc(cfg(feature = "digest-preview")))] -pub trait PrehashSignature: Signature { - /// Preferred `Digest` algorithm to use when computing this signature type. - type Digest: digest::Digest; -} diff --git a/signature/src/signer.rs b/signature/src/signer.rs index c025711fe..25c6614a2 100644 --- a/signature/src/signer.rs +++ b/signature/src/signer.rs @@ -1,6 +1,6 @@ //! Traits for generating digital signatures -use crate::{error::Error, Signature}; +use crate::error::Error; #[cfg(feature = "digest-preview")] use crate::digest::Digest; @@ -10,7 +10,7 @@ use crate::rand_core::{CryptoRng, RngCore}; /// Sign the provided message bytestring using `Self` (e.g. a cryptographic key /// or connection to an HSM), returning a digital signature. -pub trait Signer { +pub trait Signer { /// Sign the given message and return a digital signature fn sign(&self, msg: &[u8]) -> S { self.try_sign(msg).expect("signature operation failed") @@ -26,7 +26,7 @@ pub trait Signer { /// Sign the provided message bytestring using `&mut Self` (e.g., an evolving /// cryptographic key), returning a digital signature. -pub trait SignerMut { +pub trait SignerMut { /// Sign the given message, update the state, and return a digital signature fn sign(&mut self, msg: &[u8]) -> S { self.try_sign(msg).expect("signature operation failed") @@ -40,12 +40,8 @@ pub trait SignerMut { fn try_sign(&mut self, msg: &[u8]) -> Result; } -// Blanket impl of SignerMut for all Signer types -impl SignerMut for T -where - T: Signer, - S: Signature, -{ +/// Blanket impl of [`SignerMut`] for all [`Signer`] types. +impl> SignerMut for T { fn try_sign(&mut self, msg: &[u8]) -> Result { T::try_sign(self, msg) } @@ -72,11 +68,7 @@ where /// [Fiat-Shamir heuristic]: https://en.wikipedia.org/wiki/Fiat%E2%80%93Shamir_heuristic #[cfg(feature = "digest-preview")] #[cfg_attr(docsrs, doc(cfg(feature = "digest-preview")))] -pub trait DigestSigner -where - D: Digest, - S: Signature, -{ +pub trait DigestSigner { /// Sign the given prehashed message [`Digest`], returning a signature. /// /// Panics in the event of a signing error. @@ -93,7 +85,7 @@ where /// Sign the given message using the provided external randomness source. #[cfg(feature = "rand-preview")] #[cfg_attr(docsrs, doc(cfg(feature = "rand-preview")))] -pub trait RandomizedSigner { +pub trait RandomizedSigner { /// Sign the given message and return a digital signature fn sign_with_rng(&self, rng: impl CryptoRng + RngCore, msg: &[u8]) -> S { self.try_sign_with_rng(rng, msg) @@ -113,11 +105,7 @@ pub trait RandomizedSigner { #[cfg(all(feature = "digest-preview", feature = "rand-preview"))] #[cfg_attr(docsrs, doc(cfg(feature = "digest-preview")))] #[cfg_attr(docsrs, doc(cfg(feature = "rand-preview")))] -pub trait RandomizedDigestSigner -where - D: Digest, - S: Signature, -{ +pub trait RandomizedDigestSigner { /// Sign the given prehashed message `Digest`, returning a signature. /// /// Panics in the event of a signing error. diff --git a/signature/src/verifier.rs b/signature/src/verifier.rs index 4d6efbc2b..47bfef360 100644 --- a/signature/src/verifier.rs +++ b/signature/src/verifier.rs @@ -1,12 +1,12 @@ //! Trait for verifying digital signatures -use crate::{error::Error, Signature}; +use crate::error::Error; #[cfg(feature = "digest-preview")] use crate::digest::Digest; /// Verify the provided message bytestring using `Self` (e.g. a public key) -pub trait Verifier { +pub trait Verifier { /// Use `Self` to verify that the provided signature for a given message /// bytestring is authentic. /// @@ -36,11 +36,7 @@ pub trait Verifier { /// [Fiat-Shamir heuristic]: https://en.wikipedia.org/wiki/Fiat%E2%80%93Shamir_heuristic #[cfg(feature = "digest-preview")] #[cfg_attr(docsrs, doc(cfg(feature = "digest-preview")))] -pub trait DigestVerifier -where - D: Digest, - S: Signature, -{ +pub trait DigestVerifier { /// Verify the signature against the given [`Digest`] output. fn verify_digest(&self, digest: D, signature: &S) -> Result<(), Error>; } diff --git a/signature/tests/derive.rs b/signature/tests/derive.rs index 5048dc682..684aca66f 100644 --- a/signature/tests/derive.rs +++ b/signature/tests/derive.rs @@ -7,7 +7,7 @@ use hex_literal::hex; use sha2::Sha256; use signature::{ hazmat::{PrehashSigner, PrehashVerifier}, - DigestSigner, DigestVerifier, Error, PrehashSignature, Signature, Signer, Verifier, + DigestSigner, DigestVerifier, Error, PrehashSignature, SignatureEncoding, Signer, Verifier, }; /// Test vector to compute SHA-256 digest of @@ -17,35 +17,43 @@ const INPUT_STRING: &[u8] = b"abc"; const INPUT_STRING_DIGEST: [u8; 32] = hex!("ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad"); +type Repr = GenericArray::OutputSize>; + /// Dummy signature which just contains a digest output -#[derive(Debug)] -struct DummySignature(GenericArray::OutputSize>); +#[derive(Clone, Debug)] +struct DummySignature(Repr); + +impl PrehashSignature for DummySignature { + type Digest = Sha256; +} + +impl SignatureEncoding for DummySignature { + type Repr = Repr; +} + +impl TryFrom<&[u8]> for DummySignature { + type Error = Error; -impl Signature for DummySignature { - fn from_bytes(bytes: &[u8]) -> Result { + fn try_from(bytes: &[u8]) -> Result { Ok(DummySignature(GenericArray::clone_from_slice( bytes.as_ref(), ))) } } -impl AsRef<[u8]> for DummySignature { - fn as_ref(&self) -> &[u8] { - self.0.as_ref() +impl From for Repr { + fn from(sig: DummySignature) -> Repr { + sig.0 } } -impl PrehashSignature for DummySignature { - type Digest = Sha256; -} - /// Dummy signer which just returns the message digest as a `DummySignature` #[derive(Signer, DigestSigner, Default)] struct DummySigner {} impl PrehashSigner for DummySigner { fn sign_prehash(&self, prehash: &[u8]) -> signature::Result { - DummySignature::from_bytes(prehash) + DummySignature::try_from(prehash) } } @@ -58,7 +66,7 @@ struct DummyVerifier {} impl PrehashVerifier for DummyVerifier { fn verify_prehash(&self, prehash: &[u8], signature: &DummySignature) -> signature::Result<()> { - assert_eq!(signature.as_ref(), prehash); + assert_eq!(signature.to_bytes().as_slice(), prehash); Ok(()) } } @@ -66,7 +74,7 @@ impl PrehashVerifier for DummyVerifier { #[test] fn derived_signer_impl() { let sig: DummySignature = DummySigner::default().sign(INPUT_STRING); - assert_eq!(sig.as_ref(), INPUT_STRING_DIGEST.as_ref()) + assert_eq!(sig.to_bytes().as_slice(), INPUT_STRING_DIGEST.as_ref()) } #[test] From cdf6677ec2d9551e48c979bee32dfd83713ecec6 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 29 Oct 2022 20:51:50 -0600 Subject: [PATCH 0889/1461] signature: remove `Default` bound on `SignatureEncoding::Repr` (#1143) Unfortunately the `Default` impl on `core` array types is still problematic here: error[E0277]: the trait bound `[u8; 64]: Default` is not satisfied --> ed25519/src/lib.rs:339:17 | 339 | type Repr = SignatureBytes; | ^^^^^^^^^^^^^^ the trait `Default` is not implemented for `[u8; 64]` --- signature/src/encoding.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/signature/src/encoding.rs b/signature/src/encoding.rs index f4d281c2a..997f6617d 100644 --- a/signature/src/encoding.rs +++ b/signature/src/encoding.rs @@ -10,7 +10,7 @@ pub trait SignatureEncoding: Clone + Sized + for<'a> TryFrom<&'a [u8], Error = Error> + Into { /// Byte representation of a signature. - type Repr: 'static + AsRef<[u8]> + AsMut<[u8]> + Clone + Default + Send + Sync; + type Repr: 'static + AsRef<[u8]> + AsMut<[u8]> + Clone + Send + Sync; /// Decode signature from its byte representation. fn from_bytes(bytes: &Self::Repr) -> Result { From f7917303ae68980541863987a3649a1b87136966 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 29 Oct 2022 21:05:56 -0600 Subject: [PATCH 0890/1461] signature: remove `AsMut` bound on `Repr` (#1144) Without a `Default` bound (#1143) there's little purpose to having an `AsMut` bound on `Repr`, which would allow `Default` to construct an empty bytestring and `AsMut` used to write into it. Given there isn't an obvious use case, fewer bounds are better. --- signature/src/encoding.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/signature/src/encoding.rs b/signature/src/encoding.rs index 997f6617d..02bfbe497 100644 --- a/signature/src/encoding.rs +++ b/signature/src/encoding.rs @@ -10,7 +10,7 @@ pub trait SignatureEncoding: Clone + Sized + for<'a> TryFrom<&'a [u8], Error = Error> + Into { /// Byte representation of a signature. - type Repr: 'static + AsRef<[u8]> + AsMut<[u8]> + Clone + Send + Sync; + type Repr: 'static + AsRef<[u8]> + Clone + Send + Sync; /// Decode signature from its byte representation. fn from_bytes(bytes: &Self::Repr) -> Result { From 796894fd5485efaaad20eb1ecd01821b330c09e5 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 31 Oct 2022 10:46:46 -0600 Subject: [PATCH 0891/1461] signature v2.0.0-pre.0 (#1145) --- Cargo.lock | 10 +++++----- crypto/Cargo.toml | 2 +- signature/Cargo.toml | 4 ++-- signature/async/Cargo.toml | 4 ++-- signature/derive/Cargo.toml | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b24400783..55b78ce8f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -59,10 +59,10 @@ dependencies = [ [[package]] name = "async-signature" -version = "0.2.1" +version = "0.3.0-pre" dependencies = [ "async-trait", - "signature 2.0.0-pre", + "signature 2.0.0-pre.0", ] [[package]] @@ -311,7 +311,7 @@ dependencies = [ "digest 0.10.5", "elliptic-curve 0.12.3", "password-hash", - "signature 2.0.0-pre", + "signature 2.0.0-pre.0", "universal-hash 0.5.0", ] @@ -1189,7 +1189,7 @@ dependencies = [ [[package]] name = "signature" -version = "2.0.0-pre" +version = "2.0.0-pre.0" dependencies = [ "digest 0.10.5", "hex-literal", @@ -1200,7 +1200,7 @@ dependencies = [ [[package]] name = "signature_derive" -version = "1.0.0-pre.7" +version = "2.0.0-pre.0" dependencies = [ "proc-macro2", "quote", diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 1f73bd7aa..a1082034e 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -23,7 +23,7 @@ cipher = { version = "0.4", optional = true } digest = { version = "0.10", optional = true, features = ["mac"] } elliptic-curve = { version = "0.12", optional = true, path = "../elliptic-curve" } password-hash = { version = "0.4", optional = true, path = "../password-hash" } -signature = { version = "=2.0.0-pre", optional = true, default-features = false, path = "../signature" } +signature = { version = "=2.0.0-pre.0", optional = true, default-features = false, path = "../signature" } universal-hash = { version = "0.5", optional = true, path = "../universal-hash" } [features] diff --git a/signature/Cargo.toml b/signature/Cargo.toml index c55628df7..83d673b8a 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "2.0.0-pre" +version = "2.0.0-pre.0" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/signature" @@ -15,7 +15,7 @@ categories = ["cryptography", "no-std"] [dependencies] digest = { version = "0.10.3", optional = true, default-features = false } rand_core = { version = "0.6", optional = true, default-features = false } -derive = { package = "signature_derive", version = "=1.0.0-pre.7", optional = true, path = "derive" } +derive = { package = "signature_derive", version = "=2.0.0-pre.0", optional = true, path = "derive" } [dev-dependencies] hex-literal = "0.3" diff --git a/signature/async/Cargo.toml b/signature/async/Cargo.toml index 13c964df8..81da248eb 100644 --- a/signature/async/Cargo.toml +++ b/signature/async/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "async-signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "0.2.1" +version = "0.3.0-pre" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/async-signature" @@ -14,7 +14,7 @@ rust-version = "1.56" [dependencies] async-trait = "0.1.9" -signature = { version = "=2.0.0-pre", path = ".." } +signature = { version = "=2.0.0-pre.0", path = ".." } [features] digest = ["signature/digest-preview"] diff --git a/signature/derive/Cargo.toml b/signature/derive/Cargo.toml index c21334ed4..294a39474 100644 --- a/signature/derive/Cargo.toml +++ b/signature/derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "signature_derive" -version = "1.0.0-pre.7" +version = "2.0.0-pre.0" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" description = "Custom derive support for the 'signature' crate" From 45f1bab0ce45f432207009c4f4db66e46ca25ec4 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 1 Nov 2022 21:31:41 -0600 Subject: [PATCH 0892/1461] signature: use `&mut impl CryptoRngCore` RNG arguments (#1147) `rand_core` v0.6.4 added an auto-impl'd `CryptoRngCore` marker trait for types which impl `CryptoRng + RngCore` which is slightly more convenient and less verbose. This commit changes to using `&mut impl CryptoRngCore` as proposed in #1087. This hopefully strikes a balance between least surprise and minimal required syntax, namely &mut references are reusable and don't require knowledge of the blanket impl of `RngCore` for `&mut R: RngCore` --- signature/Cargo.toml | 2 +- signature/src/signer.rs | 15 ++++++--------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 83d673b8a..800207173 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -14,7 +14,7 @@ categories = ["cryptography", "no-std"] [dependencies] digest = { version = "0.10.3", optional = true, default-features = false } -rand_core = { version = "0.6", optional = true, default-features = false } +rand_core = { version = "0.6.4", optional = true, default-features = false } derive = { package = "signature_derive", version = "=2.0.0-pre.0", optional = true, path = "derive" } [dev-dependencies] diff --git a/signature/src/signer.rs b/signature/src/signer.rs index 25c6614a2..be3de2ec5 100644 --- a/signature/src/signer.rs +++ b/signature/src/signer.rs @@ -6,7 +6,7 @@ use crate::error::Error; use crate::digest::Digest; #[cfg(feature = "rand-preview")] -use crate::rand_core::{CryptoRng, RngCore}; +use crate::rand_core::CryptoRngCore; /// Sign the provided message bytestring using `Self` (e.g. a cryptographic key /// or connection to an HSM), returning a digital signature. @@ -87,7 +87,7 @@ pub trait DigestSigner { #[cfg_attr(docsrs, doc(cfg(feature = "rand-preview")))] pub trait RandomizedSigner { /// Sign the given message and return a digital signature - fn sign_with_rng(&self, rng: impl CryptoRng + RngCore, msg: &[u8]) -> S { + fn sign_with_rng(&self, rng: &mut impl CryptoRngCore, msg: &[u8]) -> S { self.try_sign_with_rng(rng, msg) .expect("signature operation failed") } @@ -97,7 +97,7 @@ pub trait RandomizedSigner { /// /// The main intended use case for signing errors is when communicating /// with external signers, e.g. cloud KMS, HSMs, or other hardware tokens. - fn try_sign_with_rng(&self, rng: impl CryptoRng + RngCore, msg: &[u8]) -> Result; + fn try_sign_with_rng(&self, rng: &mut impl CryptoRngCore, msg: &[u8]) -> Result; } /// Combination of [`DigestSigner`] and [`RandomizedSigner`] with support for @@ -109,16 +109,13 @@ pub trait RandomizedDigestSigner { /// Sign the given prehashed message `Digest`, returning a signature. /// /// Panics in the event of a signing error. - fn sign_digest_with_rng(&self, rng: impl CryptoRng + RngCore, digest: D) -> S { + fn sign_digest_with_rng(&self, rng: &mut impl CryptoRngCore, digest: D) -> S { self.try_sign_digest_with_rng(rng, digest) .expect("signature operation failed") } /// Attempt to sign the given prehashed message `Digest`, returning a /// digital signature on success, or an error if something went wrong. - fn try_sign_digest_with_rng( - &self, - rng: impl CryptoRng + RngCore, - digest: D, - ) -> Result; + fn try_sign_digest_with_rng(&self, rng: &mut impl CryptoRngCore, digest: D) + -> Result; } From 2fb70acf3bbae7b39cf446eda50a973335d55834 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 2 Nov 2022 07:45:39 -0600 Subject: [PATCH 0893/1461] signature: simplify encoding trait (#1149) Removes the `from_bytes` and `to_boxed_slice` methods, as `TryFrom` and `to_vec().into_boxed_slice()` provide equivalent functionality. --- signature/src/encoding.rs | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/signature/src/encoding.rs b/signature/src/encoding.rs index 02bfbe497..fafa3550c 100644 --- a/signature/src/encoding.rs +++ b/signature/src/encoding.rs @@ -1,9 +1,9 @@ //! Encoding support. -use crate::{Error, Result}; +use crate::Error; #[cfg(feature = "alloc")] -use alloc::{boxed::Box, vec::Vec}; +use alloc::vec::Vec; /// Support for decoding/encoding signatures as bytes. pub trait SignatureEncoding: @@ -12,11 +12,6 @@ pub trait SignatureEncoding: /// Byte representation of a signature. type Repr: 'static + AsRef<[u8]> + Clone + Send + Sync; - /// Decode signature from its byte representation. - fn from_bytes(bytes: &Self::Repr) -> Result { - Self::try_from(bytes.as_ref()) - } - /// Encode signature as its byte representation. fn to_bytes(&self) -> Self::Repr { self.clone().into() @@ -28,11 +23,4 @@ pub trait SignatureEncoding: fn to_vec(&self) -> Vec { self.to_bytes().as_ref().to_vec() } - - /// Encode the signature as a boxed byte slice. - #[cfg(feature = "alloc")] - #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] - fn to_boxed_slice(&self) -> Box<[u8]> { - self.to_vec().into_boxed_slice() - } } From 3d23e551722fe78de677bb54ffe95f508567db6c Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 3 Nov 2022 15:18:05 -0600 Subject: [PATCH 0894/1461] signature v2.0.0-pre.1 (#1150) --- Cargo.lock | 6 +++--- crypto/Cargo.toml | 2 +- signature/Cargo.toml | 2 +- signature/async/Cargo.toml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 55b78ce8f..94ffb37fe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -62,7 +62,7 @@ name = "async-signature" version = "0.3.0-pre" dependencies = [ "async-trait", - "signature 2.0.0-pre.0", + "signature 2.0.0-pre.1", ] [[package]] @@ -311,7 +311,7 @@ dependencies = [ "digest 0.10.5", "elliptic-curve 0.12.3", "password-hash", - "signature 2.0.0-pre.0", + "signature 2.0.0-pre.1", "universal-hash 0.5.0", ] @@ -1189,7 +1189,7 @@ dependencies = [ [[package]] name = "signature" -version = "2.0.0-pre.0" +version = "2.0.0-pre.1" dependencies = [ "digest 0.10.5", "hex-literal", diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index a1082034e..12e446715 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -23,7 +23,7 @@ cipher = { version = "0.4", optional = true } digest = { version = "0.10", optional = true, features = ["mac"] } elliptic-curve = { version = "0.12", optional = true, path = "../elliptic-curve" } password-hash = { version = "0.4", optional = true, path = "../password-hash" } -signature = { version = "=2.0.0-pre.0", optional = true, default-features = false, path = "../signature" } +signature = { version = "=2.0.0-pre.1", optional = true, default-features = false, path = "../signature" } universal-hash = { version = "0.5", optional = true, path = "../universal-hash" } [features] diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 800207173..4fca51dad 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "2.0.0-pre.0" +version = "2.0.0-pre.1" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/signature" diff --git a/signature/async/Cargo.toml b/signature/async/Cargo.toml index 81da248eb..59d85bb22 100644 --- a/signature/async/Cargo.toml +++ b/signature/async/Cargo.toml @@ -14,7 +14,7 @@ rust-version = "1.56" [dependencies] async-trait = "0.1.9" -signature = { version = "=2.0.0-pre.0", path = ".." } +signature = { version = "=2.0.0-pre.1", path = ".." } [features] digest = ["signature/digest-preview"] From b49cc053813446de06825fe905d456d51d1f09fb Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 4 Nov 2022 10:25:34 -0600 Subject: [PATCH 0895/1461] signature: update remaining use of `CryptoRng + RngCore` (#1151) In #1147, other usages of a CSRNG were changed to use `&mut impl CryptoRngCore`. However, `RandomizedPrehashSigner` was not updated accordingly. This commit updates it as well. --- signature/src/hazmat.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/signature/src/hazmat.rs b/signature/src/hazmat.rs index 1b2e702ae..3233033c0 100644 --- a/signature/src/hazmat.rs +++ b/signature/src/hazmat.rs @@ -13,7 +13,7 @@ use crate::Error; #[cfg(feature = "rand-preview")] -use crate::rand_core::{CryptoRng, RngCore}; +use crate::rand_core::CryptoRngCore; /// Sign the provided message prehash, returning a digital signature. pub trait PrehashSigner { @@ -50,7 +50,7 @@ pub trait RandomizedPrehashSigner { /// implementation to decide. fn sign_prehash_with_rng( &self, - rng: impl CryptoRng + RngCore, + rng: &mut impl CryptoRngCore, prehash: &[u8], ) -> Result; } From cb756ec2caef13319410355b8aec3371e8d68489 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 4 Nov 2022 10:54:43 -0600 Subject: [PATCH 0896/1461] signature v2.0.0-pre.2 (#1152) --- Cargo.lock | 6 +++--- crypto/Cargo.toml | 2 +- signature/Cargo.toml | 2 +- signature/async/Cargo.toml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 94ffb37fe..e1a341542 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -62,7 +62,7 @@ name = "async-signature" version = "0.3.0-pre" dependencies = [ "async-trait", - "signature 2.0.0-pre.1", + "signature 2.0.0-pre.2", ] [[package]] @@ -311,7 +311,7 @@ dependencies = [ "digest 0.10.5", "elliptic-curve 0.12.3", "password-hash", - "signature 2.0.0-pre.1", + "signature 2.0.0-pre.2", "universal-hash 0.5.0", ] @@ -1189,7 +1189,7 @@ dependencies = [ [[package]] name = "signature" -version = "2.0.0-pre.1" +version = "2.0.0-pre.2" dependencies = [ "digest 0.10.5", "hex-literal", diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 12e446715..f7f13b707 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -23,7 +23,7 @@ cipher = { version = "0.4", optional = true } digest = { version = "0.10", optional = true, features = ["mac"] } elliptic-curve = { version = "0.12", optional = true, path = "../elliptic-curve" } password-hash = { version = "0.4", optional = true, path = "../password-hash" } -signature = { version = "=2.0.0-pre.1", optional = true, default-features = false, path = "../signature" } +signature = { version = "=2.0.0-pre.2", optional = true, default-features = false, path = "../signature" } universal-hash = { version = "0.5", optional = true, path = "../universal-hash" } [features] diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 4fca51dad..88ccd65ba 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "2.0.0-pre.1" +version = "2.0.0-pre.2" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/signature" diff --git a/signature/async/Cargo.toml b/signature/async/Cargo.toml index 59d85bb22..621c0c3ab 100644 --- a/signature/async/Cargo.toml +++ b/signature/async/Cargo.toml @@ -14,7 +14,7 @@ rust-version = "1.56" [dependencies] async-trait = "0.1.9" -signature = { version = "=2.0.0-pre.1", path = ".." } +signature = { version = "=2.0.0-pre.2", path = ".." } [features] digest = ["signature/digest-preview"] From f6ebf832dccf43337c8791dca00c9905e61f99e1 Mon Sep 17 00:00:00 2001 From: guyru Date: Sat, 5 Nov 2022 18:12:57 +0200 Subject: [PATCH 0897/1461] Fix example to refer to Sha256 and not Blake (#1153) --- digest/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/digest/README.md b/digest/README.md index a3fbd9c48..9f68559cd 100644 --- a/digest/README.md +++ b/digest/README.md @@ -28,10 +28,10 @@ done with a minor version bump. ## Usage -Let us demonstrate how to use crates in this repository using BLAKE2b as an +Let us demonstrate how to use crates in this repository using Sha256 as an example. -First add `blake2` crate to your `Cargo.toml`: +First add the `sha2` crate to your `Cargo.toml`: ```toml [dependencies] From a9ef4f6d78455283a62987d6c163c55ed62330fc Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Thu, 17 Nov 2022 00:58:58 +0000 Subject: [PATCH 0898/1461] digest: add Mac::verify_reset and Mac::verify_slice_reset methods (#1154) --- Cargo.lock | 81 +++++++++++++++++++++++---------------------- digest/CHANGELOG.md | 8 ++++- digest/Cargo.toml | 4 +-- digest/src/mac.rs | 44 ++++++++++++++++++++++++ 4 files changed, 95 insertions(+), 42 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e1a341542..e0f27379a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -25,9 +25,9 @@ dependencies = [ [[package]] name = "aes" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfe0133578c0986e1fe3dfcd4af1cc5b2dd6c3dbf534d69916ce16a2701d40ba" +checksum = "433cfd6710c9986c576a25ca913c39d66a6474107b406f34f91d4a8923395241" dependencies = [ "cfg-if", "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -67,9 +67,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.57" +version = "0.1.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76464446b8bc32758d7e88ee1a804d9914cd9b1cb264c029899680b0be29826f" +checksum = "1e805d94e6b5001b651426cf4cd446b1ab5f319d27bab5c644f61de0a804360c" dependencies = [ "proc-macro2", "quote", @@ -198,9 +198,9 @@ checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" [[package]] name = "cc" -version = "1.0.73" +version = "1.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" +checksum = "76a284da2e6fe2092f2353e51713435363112dfd60030e22add80be333fb928f" dependencies = [ "jobserver", ] @@ -264,9 +264,9 @@ checksum = "9d6f2aa4d0537bcc1c74df8755072bd31c1ef1a3a1b85a68e8404a8c353b7b8b" [[package]] name = "const-oid" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "722e23542a15cea1f65d4a1419c4cfd7a26706c70871a13a04238ca3f40f1661" +checksum = "cec318a675afcb6a1ea1d4340e2d377e56e47c266f28043ceccbf4412ddfdd3b" [[package]] name = "cortex-m" @@ -371,9 +371,9 @@ dependencies = [ [[package]] name = "ctr" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d14f329cfbaf5d0e06b5e87fff7e265d2673c5ea7d2c27691a2c107db1442a0" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" dependencies = [ "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -406,7 +406,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13dd2ae565c0a381dde7fade45fce95984c568bdcb4700a4fdbe3175e0380b2f" dependencies = [ - "const-oid 0.9.0", + "const-oid 0.9.1", "pem-rfc7468 0.6.0", "zeroize", ] @@ -433,9 +433,9 @@ dependencies = [ [[package]] name = "dunce" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "453440c271cf5577fd2a40e4942540cb7d0d2f85e27c8d07dd0023c925a67541" +checksum = "0bd4b30a6560bbd9b4620f4de34c3f14f60848e58a9b7216801afcb4c7b31c3c" [[package]] name = "ecdsa" @@ -560,9 +560,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" +checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" dependencies = [ "cfg-if", "libc", @@ -707,9 +707,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" +checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" [[package]] name = "jobserver" @@ -722,9 +722,12 @@ dependencies = [ [[package]] name = "keccak" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9b7d56ba4a8344d6be9729995e6b06f928af29998cdf79fe390cbf6b1fee838" +checksum = "3afef3b6eff9ce9d8ff9b3601125eec7f0c8cbac7abd14f355d053fa56c98768" +dependencies = [ + "cpufeatures", +] [[package]] name = "kem" @@ -749,9 +752,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.133" +version = "0.2.137" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0f80d65747a3e43d1596c7c5492d95d5edddaabd45a7fcdb02b95f644164966" +checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" [[package]] name = "lock_api" @@ -884,9 +887,9 @@ dependencies = [ [[package]] name = "ppv-lite86" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "pqcrypto" @@ -931,9 +934,9 @@ checksum = "97e91cb6af081c6daad5fa705f8adb0634c027662052cb3174bdf2957bf07e25" [[package]] name = "proc-macro2" -version = "1.0.43" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab" +checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" dependencies = [ "unicode-ident", ] @@ -991,9 +994,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" +checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a" dependencies = [ "aho-corasick", "memchr", @@ -1002,9 +1005,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.27" +version = "0.6.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" +checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" [[package]] name = "riscv" @@ -1095,9 +1098,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.145" +version = "1.0.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728eb6351430bccb993660dfffc5a72f91ccc1295abaa8ce19b27ebe4f75568b" +checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965" dependencies = [ "serde_derive", ] @@ -1113,9 +1116,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.145" +version = "1.0.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fa1584d3d1bcacd84c277a0dfe21f5b0f6accf4a23d04d4c6d61f1af522b4c" +checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852" dependencies = [ "proc-macro2", "quote", @@ -1249,9 +1252,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.100" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52205623b1b0f064a4e71182c3b18ae902267282930c6d5462c91b859668426e" +checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d" dependencies = [ "proc-macro2", "quote", @@ -1284,9 +1287,9 @@ checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" [[package]] name = "unicode-ident" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd" +checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" [[package]] name = "unicode-xid" @@ -1347,9 +1350,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wyz" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30b31594f29d27036c383b53b59ed3476874d518f0efb151b27a4c275141390e" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" dependencies = [ "tap", ] diff --git a/digest/CHANGELOG.md b/digest/CHANGELOG.md index fe7488e0e..e03398bfc 100644 --- a/digest/CHANGELOG.md +++ b/digest/CHANGELOG.md @@ -5,9 +5,15 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.10.6 (2022-11-17) +### Added +- `Mac::verify_reset` and `Mac::verify_slice_reset` methods ([#1154]) + +[#1154]: https://github.com/RustCrypto/traits/pull/1154 + ## 0.10.5 (2022-09-16) ### Fixed -- MSRV build. ([#1117]) +- MSRV build ([#1117]) [#1117]: https://github.com/RustCrypto/traits/pull/1117 diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 42ab88f77..943378c13 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "digest" -description = "Traits for cryptographic hash functions" -version = "0.10.5" +description = "Traits for cryptographic hash functions and message authentication codes" +version = "0.10.6" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/digest/src/mac.rs b/digest/src/mac.rs index f7fd31d07..1c31359ea 100644 --- a/digest/src/mac.rs +++ b/digest/src/mac.rs @@ -59,6 +59,12 @@ pub trait Mac: OutputSizeUser + Sized { /// Check if tag/code value is correct for the processed input. fn verify(self, tag: &Output) -> Result<(), MacError>; + /// Check if tag/code value is correct for the processed input and reset + /// [`Mac`] instance. + fn verify_reset(&mut self, tag: &Output) -> Result<(), MacError> + where + Self: FixedOutputReset; + /// Check truncated tag correctness using all bytes /// of calculated tag. /// @@ -66,6 +72,15 @@ pub trait Mac: OutputSizeUser + Sized { /// to MAC's output. fn verify_slice(self, tag: &[u8]) -> Result<(), MacError>; + /// Check truncated tag correctness using all bytes + /// of calculated tag and reset [`Mac`] instance. + /// + /// Returns `Error` if `tag` is not valid or not equal in length + /// to MAC's output. + fn verify_slice_reset(&mut self, tag: &[u8]) -> Result<(), MacError> + where + Self: FixedOutputReset; + /// Check truncated tag correctness using left side bytes /// (i.e. `tag[..n]`) of calculated tag. /// @@ -137,6 +152,18 @@ impl Mac for T { } } + #[inline] + fn verify_reset(&mut self, tag: &Output) -> Result<(), MacError> + where + Self: FixedOutputReset, + { + if self.finalize_reset() == tag.into() { + Ok(()) + } else { + Err(MacError) + } + } + #[inline] fn verify_slice(self, tag: &[u8]) -> Result<(), MacError> { let n = tag.len(); @@ -151,6 +178,23 @@ impl Mac for T { } } + #[inline] + fn verify_slice_reset(&mut self, tag: &[u8]) -> Result<(), MacError> + where + Self: FixedOutputReset, + { + let n = tag.len(); + if n != Self::OutputSize::USIZE { + return Err(MacError); + } + let choice = self.finalize_fixed_reset().ct_eq(tag); + if choice.into() { + Ok(()) + } else { + Err(MacError) + } + } + fn verify_truncated_left(self, tag: &[u8]) -> Result<(), MacError> { let n = tag.len(); if n == 0 || n > Self::OutputSize::USIZE { From 567dba11c41ed9d24fb014b224f9d1305f6e968d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 17 Nov 2022 15:09:34 -0700 Subject: [PATCH 0899/1461] build(deps): bump digest from 0.10.5 to 0.10.6 (#1155) Bumps [digest](https://github.com/RustCrypto/traits) from 0.10.5 to 0.10.6. - [Release notes](https://github.com/RustCrypto/traits/releases) - [Commits](https://github.com/RustCrypto/traits/compare/digest-v0.10.5...digest-v0.10.6) --- updated-dependencies: - dependency-name: digest dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 20 ++++++++++---------- signature/Cargo.toml | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e0f27379a..7083c3300 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -308,7 +308,7 @@ dependencies = [ "aead 0.5.1", "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "crypto-common 0.1.6", - "digest 0.10.5", + "digest 0.10.6", "elliptic-curve 0.12.3", "password-hash", "signature 2.0.0-pre.2", @@ -422,9 +422,9 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.5" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adfbc57365a37acbd2ebf2b64d7e69bb766e2fea813521ed536f5d0520dcf86c" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" dependencies = [ "block-buffer 0.10.3", "crypto-common 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -473,7 +473,7 @@ dependencies = [ "base64ct", "crypto-bigint 0.4.9", "der 0.6.0", - "digest 0.10.5", + "digest 0.10.6", "ff 0.12.1", "generic-array", "group 0.12.1", @@ -500,7 +500,7 @@ dependencies = [ "base16ct", "crypto-bigint 0.4.9", "der 0.6.0", - "digest 0.10.5", + "digest 0.10.6", "ff 0.12.1", "generic-array", "group 0.12.1", @@ -670,7 +670,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.5", + "digest 0.10.6", ] [[package]] @@ -683,7 +683,7 @@ dependencies = [ "aes-gcm", "byteorder", "chacha20poly1305", - "digest 0.10.5", + "digest 0.10.6", "generic-array", "hkdf 0.12.3", "hmac 0.12.1", @@ -1167,7 +1167,7 @@ checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.5", + "digest 0.10.6", ] [[package]] @@ -1176,7 +1176,7 @@ version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bdf0c33fae925bdc080598b84bc15c55e7b9a4a43b3c704da051f977469691c9" dependencies = [ - "digest 0.10.5", + "digest 0.10.6", "keccak", ] @@ -1194,7 +1194,7 @@ dependencies = [ name = "signature" version = "2.0.0-pre.2" dependencies = [ - "digest 0.10.5", + "digest 0.10.6", "hex-literal", "rand_core 0.6.4", "sha2 0.10.6", diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 88ccd65ba..6d3f7e0f8 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -13,7 +13,7 @@ keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"] categories = ["cryptography", "no-std"] [dependencies] -digest = { version = "0.10.3", optional = true, default-features = false } +digest = { version = "0.10.6", optional = true, default-features = false } rand_core = { version = "0.6.4", optional = true, default-features = false } derive = { package = "signature_derive", version = "=2.0.0-pre.0", optional = true, path = "derive" } From df64695a11f5678828f586a53c81a74c81c75fec Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 18 Nov 2022 16:15:01 -0700 Subject: [PATCH 0900/1461] build(deps): bump serde_json from 1.0.87 to 1.0.88 (#1156) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.87 to 1.0.88. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.87...v1.0.88) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7083c3300..bc93991ca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1127,9 +1127,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.87" +version = "1.0.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce777b7b150d76b9cf60d28b55f5847135a003f7d7350c6be7a773508ce7d45" +checksum = "8e8b3801309262e8184d9687fb697586833e939767aea0dda89f5a8e650e8bd7" dependencies = [ "itoa", "ryu", From 44e9e1426b696306f7fe377afb852786f12ab5bc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Nov 2022 15:11:14 -0700 Subject: [PATCH 0901/1461] build(deps): bump bytes from 1.2.1 to 1.3.0 (#1158) Bumps [bytes](https://github.com/tokio-rs/bytes) from 1.2.1 to 1.3.0. - [Release notes](https://github.com/tokio-rs/bytes/releases) - [Changelog](https://github.com/tokio-rs/bytes/blob/master/CHANGELOG.md) - [Commits](https://github.com/tokio-rs/bytes/commits) --- updated-dependencies: - dependency-name: bytes dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bc93991ca..dc206f6a9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -192,9 +192,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.2.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" +checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c" [[package]] name = "cc" From 151d7d57e8bec453e0bb5bfd291a82cb45818455 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Tue, 6 Dec 2022 08:57:00 +0300 Subject: [PATCH 0902/1461] Update Cargo.lock --- Cargo.lock | 222 ++++++----------------------------------------------- 1 file changed, 24 insertions(+), 198 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dc206f6a9..8ed9118a5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -48,15 +48,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "aho-corasick" -version = "0.7.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e" -dependencies = [ - "memchr", -] - [[package]] name = "async-signature" version = "0.3.0-pre" @@ -67,9 +58,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.58" +version = "0.1.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e805d94e6b5001b651426cf4cd446b1ab5f319d27bab5c644f61de0a804360c" +checksum = "31e6e93155431f3931513b243d371981bb2770112b370c82745a1d19d2f99364" dependencies = [ "proc-macro2", "quote", @@ -78,9 +69,9 @@ dependencies = [ [[package]] name = "atomic-polyfill" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c041a8d9751a520ee19656232a18971f18946a7900f1520ee4400002244dd89" +checksum = "e3ff7eb3f316534d83a8a2c3d1674ace8a5a71198eba31e2e2b597833f699b28" dependencies = [ "critical-section", ] @@ -91,21 +82,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" -[[package]] -name = "bare-metal" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3" -dependencies = [ - "rustc_version 0.2.3", -] - -[[package]] -name = "bare-metal" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8fe8f5a8a398345e52358e18ff07cc17a568fbca5c6f73873d3a62056309603" - [[package]] name = "base16ct" version = "0.1.1" @@ -127,18 +103,6 @@ dependencies = [ "serde", ] -[[package]] -name = "bit_field" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4" - -[[package]] -name = "bitfield" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719" - [[package]] name = "bitvec" version = "1.0.1" @@ -198,9 +162,9 @@ checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c" [[package]] name = "cc" -version = "1.0.76" +version = "1.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76a284da2e6fe2092f2353e51713435363112dfd60030e22add80be333fb928f" +checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4" dependencies = [ "jobserver", ] @@ -268,18 +232,6 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cec318a675afcb6a1ea1d4340e2d377e56e47c266f28043ceccbf4412ddfdd3b" -[[package]] -name = "cortex-m" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70858629a458fdfd39f9675c4dc309411f2a3f83bede76988d81bf1a0ecee9e0" -dependencies = [ - "bare-metal 0.2.5", - "bitfield", - "embedded-hal", - "volatile-register", -] - [[package]] name = "cpufeatures" version = "0.2.5" @@ -291,15 +243,9 @@ dependencies = [ [[package]] name = "critical-section" -version = "0.2.7" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95da181745b56d4bd339530ec393508910c909c784e8962d15d722bacf0bcbcd" -dependencies = [ - "bare-metal 1.0.0", - "cfg-if", - "cortex-m", - "riscv", -] +checksum = "6548a0ad5d2549e111e1f6a11a6c2e2d00ce6a3dafe22948d67c2b443f775e52" [[package]] name = "crypto" @@ -511,16 +457,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "embedded-hal" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff" -dependencies = [ - "nb 0.1.3", - "void", -] - [[package]] name = "ff" version = "0.10.1" @@ -624,7 +560,7 @@ checksum = "db04bc24a18b9ea980628ecf00e6c0264f3c1426dac36c00cb49b6fbad8b0743" dependencies = [ "atomic-polyfill", "hash32", - "rustc_version 0.4.0", + "rustc_version", "spin", "stable_deref_trait", ] @@ -744,17 +680,11 @@ dependencies = [ "zeroize", ] -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - [[package]] name = "libc" -version = "0.2.137" +version = "0.2.138" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" +checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" [[package]] name = "lock_api" @@ -766,27 +696,6 @@ dependencies = [ "scopeguard", ] -[[package]] -name = "memchr" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" - -[[package]] -name = "nb" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f" -dependencies = [ - "nb 1.0.0", -] - -[[package]] -name = "nb" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "546c37ac5d9e56f55e73b677106873d9d9f5190605e41a856503623648488cae" - [[package]] name = "opaque-debug" version = "0.3.0" @@ -992,60 +901,13 @@ dependencies = [ "getrandom", ] -[[package]] -name = "regex" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.6.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" - -[[package]] -name = "riscv" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6907ccdd7a31012b70faf2af85cd9e5ba97657cc3987c4f13f8e4d2c2a088aba" -dependencies = [ - "bare-metal 1.0.0", - "bit_field", - "riscv-target", -] - -[[package]] -name = "riscv-target" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88aa938cda42a0cf62a20cfe8d139ff1af20c2e681212b5b34adb5a58333f222" -dependencies = [ - "lazy_static", - "regex", -] - -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -dependencies = [ - "semver 0.9.0", -] - [[package]] name = "rustc_version" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.14", + "semver", ] [[package]] @@ -1075,32 +937,17 @@ dependencies = [ "zeroize", ] -[[package]] -name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser", -] - [[package]] name = "semver" version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4" -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" - [[package]] name = "serde" -version = "1.0.147" +version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965" +checksum = "256b9932320c590e707b94576e3cc1f7c9024d0ee6612dfbcf1cb106cbe8e055" dependencies = [ "serde_derive", ] @@ -1116,9 +963,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.147" +version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852" +checksum = "b4eae9b04cbffdfd550eb462ed33bc6a1b68c935127d008b27444d08380f94e4" dependencies = [ "proc-macro2", "quote", @@ -1127,9 +974,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.88" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8b3801309262e8184d9687fb697586833e939767aea0dda89f5a8e650e8bd7" +checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db" dependencies = [ "itoa", "ryu", @@ -1252,9 +1099,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.103" +version = "1.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d" +checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" dependencies = [ "proc-macro2", "quote", @@ -1281,9 +1128,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "typenum" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "unicode-ident" @@ -1315,33 +1162,12 @@ dependencies = [ "subtle", ] -[[package]] -name = "vcell" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002" - [[package]] name = "version_check" version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" -[[package]] -name = "void" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" - -[[package]] -name = "volatile-register" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ee8f19f9d74293faf70901bc20ad067dc1ad390d2cbf1e3f75f721ffee908b6" -dependencies = [ - "vcell", -] - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -1397,9 +1223,9 @@ dependencies = [ [[package]] name = "zeroize_derive" -version = "1.3.2" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f8f187641dad4f680d25c4bfc4225b418165984179f26ca76ec4fb6441d3a17" +checksum = "44bf07cb3e50ea2003396695d58bf46bc9887a1f362260446fad6bc4e79bd36c" dependencies = [ "proc-macro2", "quote", From 9abd5784cc5e7cedec6705a415e471ee969fe566 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Dec 2022 15:07:34 -0700 Subject: [PATCH 0903/1461] build(deps): bump der from 0.6.0 to 0.6.1 (#1161) Bumps [der](https://github.com/RustCrypto/formats) from 0.6.0 to 0.6.1. - [Release notes](https://github.com/RustCrypto/formats/releases) - [Commits](https://github.com/RustCrypto/formats/compare/der/v0.6.0...der/v0.6.1) --- updated-dependencies: - dependency-name: der dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8ed9118a5..010c803c9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -348,9 +348,9 @@ dependencies = [ [[package]] name = "der" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dd2ae565c0a381dde7fade45fce95984c568bdcb4700a4fdbe3175e0380b2f" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" dependencies = [ "const-oid 0.9.1", "pem-rfc7468 0.6.0", @@ -418,7 +418,7 @@ dependencies = [ "base16ct", "base64ct", "crypto-bigint 0.4.9", - "der 0.6.0", + "der 0.6.1", "digest 0.10.6", "ff 0.12.1", "generic-array", @@ -445,7 +445,7 @@ checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" dependencies = [ "base16ct", "crypto-bigint 0.4.9", - "der 0.6.0", + "der 0.6.1", "digest 0.10.6", "ff 0.12.1", "generic-array", @@ -767,7 +767,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" dependencies = [ - "der 0.6.0", + "der 0.6.1", "spki 0.6.0", ] @@ -929,7 +929,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" dependencies = [ "base16ct", - "der 0.6.0", + "der 0.6.1", "generic-array", "pkcs8 0.9.0", "serdect", @@ -1082,7 +1082,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" dependencies = [ "base64ct", - "der 0.6.0", + "der 0.6.1", ] [[package]] From d28eb2408070b247ebc0fd243a39dedf52b594d4 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Tue, 6 Dec 2022 23:21:51 +0100 Subject: [PATCH 0904/1461] Allow bigger `c1` constant in `OsswuMapParams` (#1024) --- elliptic-curve/src/hash2curve/osswu.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elliptic-curve/src/hash2curve/osswu.rs b/elliptic-curve/src/hash2curve/osswu.rs index f803863b1..8b646f874 100644 --- a/elliptic-curve/src/hash2curve/osswu.rs +++ b/elliptic-curve/src/hash2curve/osswu.rs @@ -11,7 +11,7 @@ where F: Field, { /// The first constant term - pub c1: [u64; 4], + pub c1: &'static [u64], /// The second constant term pub c2: F, /// The ISO A variable or Curve A variable From bd7a8ac54d951c7dd3a3ff26fc228547a6ee1d4c Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 8 Dec 2022 20:32:36 -0700 Subject: [PATCH 0905/1461] Bump `elliptic-curve` to v0.13.0-pre (#1164) Breaking changes were introduced in #1024, so this bumps the crate version to v0.13.0-pre to note that happened. Note that there is no crate release associated with this version. When a crate release occurs, it will be bumped to `-pre.0`. --- Cargo.lock | 24 ++++++++++++------------ crypto/Cargo.toml | 2 +- elliptic-curve/Cargo.toml | 2 +- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 010c803c9..f6cfb2680 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -414,45 +414,45 @@ dependencies = [ [[package]] name = "elliptic-curve" version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" dependencies = [ "base16ct", - "base64ct", "crypto-bigint 0.4.9", "der 0.6.1", "digest 0.10.6", "ff 0.12.1", "generic-array", "group 0.12.1", - "hex-literal", "hkdf 0.12.3", - "pem-rfc7468 0.6.0", - "pkcs8 0.9.0", "rand_core 0.6.4", "sec1", - "serde_json", - "serdect", - "sha2 0.10.6", - "sha3", "subtle", "zeroize", ] [[package]] name = "elliptic-curve" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +version = "0.13.0-pre" dependencies = [ "base16ct", + "base64ct", "crypto-bigint 0.4.9", "der 0.6.1", "digest 0.10.6", "ff 0.12.1", "generic-array", "group 0.12.1", + "hex-literal", "hkdf 0.12.3", + "pem-rfc7468 0.6.0", + "pkcs8 0.9.0", "rand_core 0.6.4", "sec1", + "serde_json", + "serdect", + "sha2 0.10.6", + "sha3", "subtle", "zeroize", ] @@ -719,7 +719,7 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51f44edd08f51e2ade572f141051021c5af22677e42b7dd28a88155151c33594" dependencies = [ - "elliptic-curve 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", + "elliptic-curve 0.12.3", ] [[package]] diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index f7f13b707..12a5798a3 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -21,7 +21,7 @@ crypto-common = { version = "0.1", default-features = false, path = "../crypto-c aead = { version = "0.5", optional = true, path = "../aead" } cipher = { version = "0.4", optional = true } digest = { version = "0.10", optional = true, features = ["mac"] } -elliptic-curve = { version = "0.12", optional = true, path = "../elliptic-curve" } +elliptic-curve = { version = "0.12", optional = true } # TODO(tarcieri): path = "../elliptic-curve" password-hash = { version = "0.4", optional = true, path = "../password-hash" } signature = { version = "=2.0.0-pre.2", optional = true, default-features = false, path = "../signature" } universal-hash = { version = "0.5", optional = true, path = "../universal-hash" } diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 73310f588..c0e3fc0b3 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.12.3" +version = "0.13.0-pre" description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, From 44575866225e1d1634e1eba6f31411588ecbfe39 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 8 Dec 2022 20:52:24 -0700 Subject: [PATCH 0906/1461] elliptic-curve: remove `impl_field_element!` macro (#1165) Removes macro which was originally added in #1021 Going forward these macros are located in the `primeorder` crate: https://github.com/RustCrypto/elliptic-curves/blob/master/primeorder/src/field.rs --- elliptic-curve/src/dev.rs | 72 ------ elliptic-curve/src/lib.rs | 3 - elliptic-curve/src/macros.rs | 440 ----------------------------------- 3 files changed, 515 deletions(-) delete mode 100644 elliptic-curve/src/macros.rs diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index be0c156e5..8f1f0472b 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -707,78 +707,6 @@ impl Neg for ProjectivePoint { } } -/// Constant representing the base field modulus -/// p = 2^{224}(2^{32} − 1) + 2^{192} + 2^{96} − 1 -pub const MODULUS: U256 = - U256::from_be_hex("ffffffff00000001000000000000000000000000ffffffffffffffffffffffff"); - -/// Example base field element. -#[derive(Clone, Copy, Debug)] -pub struct FieldElement(pub(crate) U256); - -/// Internal field element representation. -#[cfg(target_pointer_width = "32")] -type FeWords = [u32; 8]; - -/// Internal field element representation. -#[cfg(target_pointer_width = "64")] -type FeWords = [u64; 4]; - -impl_field_element!( - FieldElement, - FieldBytes, - U256, - MODULUS, - FeWords, - p256_from_montgomery, - p256_to_montgomery, - p256_add, - p256_sub, - p256_mul, - p256_opp, - p256_square -); - -impl FieldElement { - /// Returns the multiplicative inverse of self, if self is non-zero. - pub fn invert(&self) -> CtOption { - unimplemented!() - } - - /// Returns the square root of self mod p, or `None` if no square root exists. - pub fn sqrt(&self) -> CtOption { - unimplemented!() - } -} - -const fn p256_from_montgomery(_: &FeWords) -> FeWords { - unimplemented!() -} - -const fn p256_to_montgomery(w: &FeWords) -> FeWords { - *w -} - -const fn p256_add(_: &FeWords, _: &FeWords) -> FeWords { - unimplemented!() -} - -const fn p256_sub(_: &FeWords, _: &FeWords) -> FeWords { - unimplemented!() -} - -const fn p256_mul(_: &FeWords, _: &FeWords) -> FeWords { - unimplemented!() -} - -const fn p256_opp(_: &FeWords) -> FeWords { - unimplemented!() -} - -const fn p256_square(_: &FeWords) -> FeWords { - unimplemented!() -} - #[cfg(test)] mod tests { use super::Scalar; diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 62ac7856b..2f9481206 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -66,9 +66,6 @@ extern crate std; #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] pub use rand_core; -#[macro_use] -mod macros; - pub mod ops; #[cfg(feature = "dev")] diff --git a/elliptic-curve/src/macros.rs b/elliptic-curve/src/macros.rs deleted file mode 100644 index 6ceadc833..000000000 --- a/elliptic-curve/src/macros.rs +++ /dev/null @@ -1,440 +0,0 @@ -/// Provides both inherent and trait impls for a field element type which are -/// backed by a core set of arithmetic functions specified as macro arguments. -/// -/// # Inherent impls -/// - `const ZERO: Self` -/// - `const ONE: Self` (multiplicative identity) -/// - `pub fn from_be_bytes` -/// - `pub fn from_be_slice` -/// - `pub fn from_le_bytes` -/// - `pub fn from_le_slice` -/// - `pub fn from_uint` -/// - `fn from_uint_unchecked` -/// - `pub fn to_be_bytes` -/// - `pub fn to_le_bytes` -/// - `pub fn to_canonical` -/// - `pub fn is_odd` -/// - `pub fn is_zero` -/// - `pub fn double` -/// -/// NOTE: field implementations must provide their own inherent impls of -/// the following methods in order for the code generated by this macro to -/// compile: -/// -/// - `pub fn invert` -/// - `pub fn sqrt` -/// -/// # Trait impls -/// - `AsRef<$arr>` -/// - `ConditionallySelectable` -/// - `ConstantTimeEq` -/// - `ConstantTimeGreater` -/// - `ConstantTimeLess` -/// - `Default` -/// - `DefaultIsZeroes` -/// - `Eq` -/// - `Field` -/// - `PartialEq` -/// -/// ## Ops -/// - `Add` -/// - `AddAssign` -/// - `Sub` -/// - `SubAssign` -/// - `Mul` -/// - `MulAssign` -/// - `Neg` -#[macro_export] -macro_rules! impl_field_element { - ( - $fe:tt, - $bytes:ty, - $uint:ty, - $modulus:expr, - $arr:ty, - $from_mont:ident, - $to_mont:ident, - $add:ident, - $sub:ident, - $mul:ident, - $neg:ident, - $square:ident - ) => { - impl $fe { - /// Zero element. - pub const ZERO: Self = Self(<$uint>::ZERO); - - /// Multiplicative identity. - pub const ONE: Self = Self::from_uint_unchecked(<$uint>::ONE); - - /// Create a [` - #[doc = stringify!($fe)] - /// `] from a canonical big-endian representation. - pub fn from_be_bytes(repr: $bytes) -> $crate::subtle::CtOption { - use $crate::bigint::ArrayEncoding as _; - Self::from_uint(<$uint>::from_be_byte_array(repr)) - } - - /// Decode [` - #[doc = stringify!($fe)] - /// `] from a big endian byte slice. - pub fn from_be_slice(slice: &[u8]) -> $crate::Result { - <$uint as $crate::bigint::Encoding>::Repr::try_from(slice) - .ok() - .and_then(|array| Self::from_be_bytes(array.into()).into()) - .ok_or($crate::Error) - } - - /// Create a [` - #[doc = stringify!($fe)] - /// `] from a canonical little-endian representation. - pub fn from_le_bytes(repr: $bytes) -> $crate::subtle::CtOption { - use $crate::bigint::ArrayEncoding as _; - Self::from_uint(<$uint>::from_le_byte_array(repr)) - } - - /// Decode [` - #[doc = stringify!($fe)] - /// `] from a little endian byte slice. - pub fn from_le_slice(slice: &[u8]) -> $crate::Result { - <$uint as $crate::bigint::Encoding>::Repr::try_from(slice) - .ok() - .and_then(|array| Self::from_le_bytes(array.into()).into()) - .ok_or($crate::Error) - } - - /// Decode [` - #[doc = stringify!($fe)] - /// `] - /// from [` - #[doc = stringify!($uint)] - /// `] converting it into Montgomery form: - /// - /// ```text - /// w * R^2 * R^-1 mod p = wR mod p - /// ``` - pub fn from_uint(uint: $uint) -> $crate::subtle::CtOption { - use $crate::subtle::ConstantTimeLess as _; - let is_some = uint.ct_lt(&$modulus); - $crate::subtle::CtOption::new(Self::from_uint_unchecked(uint), is_some) - } - - /// Parse a [` - #[doc = stringify!($fe)] - /// `] from big endian hex-encoded bytes. - /// - /// Does *not* perform a check that the field element does not overflow the order. - /// - /// This method is primarily intended for defining internal constants. - #[allow(dead_code)] - pub(crate) const fn from_be_hex(hex: &str) -> Self { - Self::from_uint_unchecked(<$uint>::from_be_hex(hex)) - } - - /// Parse a [` - #[doc = stringify!($fe)] - /// `] from little endian hex-encoded bytes. - /// - /// Does *not* perform a check that the field element does not overflow the order. - /// - /// This method is primarily intended for defining internal constants. - #[allow(dead_code)] - pub(crate) const fn from_le_hex(hex: &str) -> Self { - Self::from_uint_unchecked(<$uint>::from_le_hex(hex)) - } - - /// Decode [` - #[doc = stringify!($fe)] - /// `] from [` - #[doc = stringify!($uint)] - /// `] converting it into Montgomery form. - /// - /// Does *not* perform a check that the field element does not overflow the order. - /// - /// Used incorrectly this can lead to invalid results! - pub(crate) const fn from_uint_unchecked(w: $uint) -> Self { - Self(<$uint>::from_words($to_mont(w.as_words()))) - } - - /// Returns the big-endian encoding of this [` - #[doc = stringify!($fe)] - /// `]. - pub fn to_be_bytes(self) -> $bytes { - use $crate::bigint::ArrayEncoding as _; - self.to_canonical().to_be_byte_array() - } - - /// Returns the little-endian encoding of this [` - #[doc = stringify!($fe)] - /// `]. - pub fn to_le_bytes(self) -> $bytes { - use $crate::bigint::ArrayEncoding as _; - self.to_canonical().to_le_byte_array() - } - - /// Translate [` - #[doc = stringify!($fe)] - /// `] out of the Montgomery domain, returning a [` - #[doc = stringify!($uint)] - /// `] in canonical form. - #[inline] - pub const fn to_canonical(self) -> $uint { - <$uint>::from_words($from_mont(self.0.as_words())) - } - - /// Determine if this [` - #[doc = stringify!($fe)] - /// `] is odd in the SEC1 sense: `self mod 2 == 1`. - /// - /// # Returns - /// - /// If odd, return `Choice(1)`. Otherwise, return `Choice(0)`. - pub fn is_odd(&self) -> Choice { - use $crate::bigint::Integer; - self.to_canonical().is_odd() - } - - /// Determine if this [` - #[doc = stringify!($fe)] - /// `] is even in the SEC1 sense: `self mod 2 == 0`. - /// - /// # Returns - /// - /// If even, return `Choice(1)`. Otherwise, return `Choice(0)`. - pub fn is_even(&self) -> Choice { - !self.is_odd() - } - - /// Determine if this [` - #[doc = stringify!($fe)] - /// `] is zero. - /// - /// # Returns - /// - /// If zero, return `Choice(1)`. Otherwise, return `Choice(0)`. - pub fn is_zero(&self) -> Choice { - self.ct_eq(&Self::ZERO) - } - - /// Add elements. - pub const fn add(&self, rhs: &Self) -> Self { - Self(<$uint>::from_words($add( - self.0.as_words(), - rhs.0.as_words(), - ))) - } - - /// Double element (add it to itself). - #[must_use] - pub const fn double(&self) -> Self { - self.add(self) - } - - /// Subtract elements. - pub const fn sub(&self, rhs: &Self) -> Self { - Self(<$uint>::from_words($sub( - self.0.as_words(), - rhs.0.as_words(), - ))) - } - - /// Multiply elements. - pub const fn mul(&self, rhs: &Self) -> Self { - Self(<$uint>::from_words($mul( - self.0.as_words(), - rhs.0.as_words(), - ))) - } - - /// Negate element. - pub const fn neg(&self) -> Self { - Self(<$uint>::from_words($neg(self.0.as_words()))) - } - - /// Compute modular square. - #[must_use] - pub const fn square(&self) -> Self { - Self(<$uint>::from_words($square(self.0.as_words()))) - } - } - - impl AsRef<$arr> for $fe { - fn as_ref(&self) -> &$arr { - self.0.as_ref() - } - } - - impl Default for $fe { - fn default() -> Self { - Self::ZERO - } - } - - impl Eq for $fe {} - - impl PartialEq for $fe { - fn eq(&self, rhs: &Self) -> bool { - self.0.ct_eq(&(rhs.0)).into() - } - } - - impl $crate::subtle::ConditionallySelectable for $fe { - fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { - Self(<$uint>::conditional_select(&a.0, &b.0, choice)) - } - } - - impl $crate::subtle::ConstantTimeEq for $fe { - fn ct_eq(&self, other: &Self) -> $crate::subtle::Choice { - self.0.ct_eq(&other.0) - } - } - - impl $crate::subtle::ConstantTimeGreater for $fe { - fn ct_gt(&self, other: &Self) -> $crate::subtle::Choice { - self.0.ct_gt(&other.0) - } - } - - impl $crate::subtle::ConstantTimeLess for $fe { - fn ct_lt(&self, other: &Self) -> $crate::subtle::Choice { - self.0.ct_lt(&other.0) - } - } - - impl $crate::zeroize::DefaultIsZeroes for $fe {} - - impl $crate::ff::Field for $fe { - fn random(mut rng: impl $crate::rand_core::RngCore) -> Self { - // NOTE: can't use ScalarCore::random due to CryptoRng bound - let mut bytes = <$bytes>::default(); - - loop { - rng.fill_bytes(&mut bytes); - if let Some(fe) = Self::from_be_bytes(bytes).into() { - return fe; - } - } - } - - fn zero() -> Self { - Self::ZERO - } - - fn one() -> Self { - Self::ONE - } - - fn is_zero(&self) -> Choice { - Self::ZERO.ct_eq(self) - } - - #[must_use] - fn square(&self) -> Self { - self.square() - } - - #[must_use] - fn double(&self) -> Self { - self.double() - } - - fn invert(&self) -> CtOption { - self.invert() - } - - fn sqrt(&self) -> CtOption { - self.sqrt() - } - } - - $crate::impl_field_op!($fe, $uint, Add, add, $add); - $crate::impl_field_op!($fe, $uint, Sub, sub, $sub); - $crate::impl_field_op!($fe, $uint, Mul, mul, $mul); - - impl AddAssign<$fe> for $fe { - #[inline] - fn add_assign(&mut self, other: $fe) { - *self = *self + other; - } - } - - impl AddAssign<&$fe> for $fe { - #[inline] - fn add_assign(&mut self, other: &$fe) { - *self = *self + other; - } - } - - impl SubAssign<$fe> for $fe { - #[inline] - fn sub_assign(&mut self, other: $fe) { - *self = *self - other; - } - } - - impl SubAssign<&$fe> for $fe { - #[inline] - fn sub_assign(&mut self, other: &$fe) { - *self = *self - other; - } - } - - impl MulAssign<&$fe> for $fe { - #[inline] - fn mul_assign(&mut self, other: &$fe) { - *self = *self * other; - } - } - - impl MulAssign for $fe { - #[inline] - fn mul_assign(&mut self, other: $fe) { - *self = *self * other; - } - } - - impl Neg for $fe { - type Output = $fe; - - #[inline] - fn neg(self) -> $fe { - Self($neg(self.as_ref()).into()) - } - } - }; -} - -/// Emit impls for a `core::ops` trait for all combinations of reference types, -/// which thunk to the given function. -#[macro_export] -macro_rules! impl_field_op { - ($fe:tt, $uint:ty, $op:tt, $op_fn:ident, $func:ident) => { - impl ::core::ops::$op for $fe { - type Output = $fe; - - #[inline] - fn $op_fn(self, rhs: $fe) -> $fe { - $fe($func(self.as_ref(), rhs.as_ref()).into()) - } - } - - impl ::core::ops::$op<&$fe> for $fe { - type Output = $fe; - - #[inline] - fn $op_fn(self, rhs: &$fe) -> $fe { - $fe($func(self.as_ref(), rhs.as_ref()).into()) - } - } - - impl ::core::ops::$op<&$fe> for &$fe { - type Output = $fe; - - #[inline] - fn $op_fn(self, rhs: &$fe) -> $fe { - $fe($func(self.as_ref(), rhs.as_ref()).into()) - } - } - }; -} From 28ec035531ed028ba010a652980f78007c8f49ff Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 8 Dec 2022 21:10:22 -0700 Subject: [PATCH 0907/1461] elliptic-curve: bump `ff` and `group` to v0.13 (#1166) --- Cargo.lock | 25 +++++++++- elliptic-curve/Cargo.toml | 4 +- elliptic-curve/src/dev.rs | 62 +++++++++++++++--------- elliptic-curve/src/hash2curve/isogeny.rs | 4 +- elliptic-curve/src/hash2curve/osswu.rs | 2 +- elliptic-curve/src/scalar/nonzero.rs | 4 +- 6 files changed, 69 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f6cfb2680..03631107f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -440,9 +440,9 @@ dependencies = [ "crypto-bigint 0.4.9", "der 0.6.1", "digest 0.10.6", - "ff 0.12.1", + "ff 0.13.0", "generic-array", - "group 0.12.1", + "group 0.13.0", "hex-literal", "hkdf 0.12.3", "pem-rfc7468 0.6.0", @@ -472,6 +472,16 @@ name = "ff" version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ "bitvec", "rand_core 0.6.4", @@ -543,6 +553,17 @@ dependencies = [ "subtle", ] +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff 0.13.0", + "rand_core 0.6.4", + "subtle", +] + [[package]] name = "hash32" version = "0.2.1" diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index c0e3fc0b3..00378302f 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -27,8 +27,8 @@ zeroize = { version = "1.5", default-features = false } # optional dependencies base64ct = { version = "1", optional = true, default-features = false } digest = { version = "0.10", optional = true } -ff = { version = "0.12", optional = true, default-features = false } -group = { version = "0.12", optional = true, default-features = false } +ff = { version = "0.13", optional = true, default-features = false } +group = { version = "0.13", optional = true, default-features = false } hkdf = { version = "0.12", optional = true, default-features = false } hex-literal = { version = "0.3", optional = true } pem-rfc7468 = { version = "0.6", optional = true } diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 8f1f0472b..f7205e52c 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -16,11 +16,10 @@ use crate::{ ScalarArithmetic, }; use core::{ - iter::Sum, + iter::{Product, Sum}, ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign}, }; use ff::{Field, PrimeField}; -use generic_array::arr; use hex_literal::hex; use pkcs8::AssociatedOid; @@ -102,6 +101,9 @@ impl JwkParameters for MockCurve { pub struct Scalar(ScalarCore); impl Field for Scalar { + const ZERO: Self = Self(ScalarCore::ZERO); + const ONE: Self = Self(ScalarCore::ONE); + fn random(mut rng: impl RngCore) -> Self { let mut bytes = FieldBytes::default(); @@ -113,14 +115,6 @@ impl Field for Scalar { } } - fn zero() -> Self { - Self(ScalarCore::ZERO) - } - - fn one() -> Self { - Self(ScalarCore::ONE) - } - fn is_zero(&self) -> Choice { self.0.is_zero() } @@ -142,14 +136,25 @@ impl Field for Scalar { fn sqrt(&self) -> CtOption { unimplemented!(); } + + fn sqrt_ratio(_num: &Self, _div: &Self) -> (Choice, Self) { + unimplemented!(); + } } impl PrimeField for Scalar { type Repr = FieldBytes; + const MODULUS: &'static str = + "0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff"; const NUM_BITS: u32 = 256; const CAPACITY: u32 = 255; + const TWO_INV: Self = Self::ZERO; // BOGUS! + const MULTIPLICATIVE_GENERATOR: Self = Self::ZERO; // BOGUS! Should be 7 const S: u32 = 4; + const ROOT_OF_UNITY: Self = Self::ZERO; // BOGUS! Should be 0xffc97f062a770992ba807ace842a3dfc1546cad004378daf0592d7fbb41e6602 + const ROOT_OF_UNITY_INV: Self = Self::ZERO; // BOGUS! + const DELTA: Self = Self::ZERO; // BOGUS! fn from_repr(bytes: FieldBytes) -> CtOption { ScalarCore::from_be_bytes(bytes).map(Self) @@ -162,19 +167,6 @@ impl PrimeField for Scalar { fn is_odd(&self) -> Choice { self.0.is_odd() } - - fn multiplicative_generator() -> Self { - 7u64.into() - } - - fn root_of_unity() -> Self { - Self::from_repr(arr![u8; - 0xff, 0xc9, 0x7f, 0x06, 0x2a, 0x77, 0x09, 0x92, 0xba, 0x80, 0x7a, 0xce, 0x84, 0x2a, - 0x3d, 0xfc, 0x15, 0x46, 0xca, 0xd0, 0x04, 0x37, 0x8d, 0xaf, 0x05, 0x92, 0xd7, 0xfb, - 0xb4, 0x1e, 0x66, 0x02, - ]) - .unwrap() - } } #[cfg(feature = "bits")] @@ -314,6 +306,30 @@ impl Neg for Scalar { } } +impl Sum for Scalar { + fn sum>(_iter: I) -> Self { + unimplemented!(); + } +} + +impl<'a> Sum<&'a Scalar> for Scalar { + fn sum>(_iter: I) -> Self { + unimplemented!(); + } +} + +impl Product for Scalar { + fn product>(_iter: I) -> Self { + unimplemented!(); + } +} + +impl<'a> Product<&'a Scalar> for Scalar { + fn product>(_iter: I) -> Self { + unimplemented!(); + } +} + impl Reduce for Scalar { fn from_uint_reduced(w: U256) -> Self { let (r, underflow) = w.sbb(&MockCurve::ORDER, Limb::ZERO); diff --git a/elliptic-curve/src/hash2curve/isogeny.rs b/elliptic-curve/src/hash2curve/isogeny.rs index fc197246a..fc870d010 100644 --- a/elliptic-curve/src/hash2curve/isogeny.rs +++ b/elliptic-curve/src/hash2curve/isogeny.rs @@ -28,7 +28,7 @@ pub trait Isogeny: Field + AddAssign + Mul { /// Map from the isogeny points to the main curve fn isogeny(x: Self, y: Self) -> (Self, Self) { let mut xs = GenericArray::::default(); - xs[0] = Self::one(); + xs[0] = Self::ONE; xs[1] = x; xs[2] = x.square(); for i in 3..Self::Degree::to_usize() { @@ -48,7 +48,7 @@ pub trait Isogeny: Field + AddAssign + Mul { /// Compute the ISO transform fn compute_iso(xxs: &[Self], k: &[Self]) -> Self { - let mut xx = Self::zero(); + let mut xx = Self::ZERO; for (xi, ki) in xxs.iter().zip(k.iter()) { xx += *xi * ki; } diff --git a/elliptic-curve/src/hash2curve/osswu.rs b/elliptic-curve/src/hash2curve/osswu.rs index 8b646f874..ced69c7b9 100644 --- a/elliptic-curve/src/hash2curve/osswu.rs +++ b/elliptic-curve/src/hash2curve/osswu.rs @@ -46,7 +46,7 @@ pub trait OsswuMap: Field + Sgn0 { let tv3 = Self::PARAMS.z * tv1; // Z * u^2 let mut tv2 = tv3.square(); // tv3^2 let mut xd = tv2 + tv3; // tv3^2 + tv3 - let x1n = Self::PARAMS.map_b * (xd + Self::one()); // B * (xd + 1) + let x1n = Self::PARAMS.map_b * (xd + Self::ONE); // B * (xd + 1) xd *= -Self::PARAMS.map_a; // -A * xd let tv = Self::PARAMS.z * Self::PARAMS.map_a; diff --git a/elliptic-curve/src/scalar/nonzero.rs b/elliptic-curve/src/scalar/nonzero.rs index 7450537a9..5f901d581 100644 --- a/elliptic-curve/src/scalar/nonzero.rs +++ b/elliptic-curve/src/scalar/nonzero.rs @@ -282,7 +282,7 @@ where // Write a 1 instead of a 0 to ensure this type's non-zero invariant // is upheld. - self.scalar = Scalar::::one(); + self.scalar = Scalar::::ONE; } } @@ -348,6 +348,6 @@ mod tests { fn zeroize() { let mut scalar = NonZeroScalar::new(Scalar::from(42u64)).unwrap(); scalar.zeroize(); - assert_eq!(*scalar, Scalar::one()); + assert_eq!(*scalar, Scalar::ONE); } } From b12237e540df00cdd2949cf8f3d996fb1d766a1c Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 10 Dec 2022 16:07:29 -0700 Subject: [PATCH 0908/1461] signature: use `R: CryptoRngCore + ?Sized` for RNG params (#1167) As discussed in #1148, adopts a generic paramater `R` for RNGs, and also adds a `?Sized` bound which permits the use of trait objects. --- signature/src/hazmat.rs | 4 ++-- signature/src/signer.rs | 17 ++++++++++++----- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/signature/src/hazmat.rs b/signature/src/hazmat.rs index 3233033c0..c7b188efd 100644 --- a/signature/src/hazmat.rs +++ b/signature/src/hazmat.rs @@ -48,9 +48,9 @@ pub trait RandomizedPrehashSigner { /// /// Allowed lengths are algorithm-dependent and up to a particular /// implementation to decide. - fn sign_prehash_with_rng( + fn sign_prehash_with_rng( &self, - rng: &mut impl CryptoRngCore, + rng: &mut R, prehash: &[u8], ) -> Result; } diff --git a/signature/src/signer.rs b/signature/src/signer.rs index be3de2ec5..de77f08c0 100644 --- a/signature/src/signer.rs +++ b/signature/src/signer.rs @@ -87,7 +87,7 @@ pub trait DigestSigner { #[cfg_attr(docsrs, doc(cfg(feature = "rand-preview")))] pub trait RandomizedSigner { /// Sign the given message and return a digital signature - fn sign_with_rng(&self, rng: &mut impl CryptoRngCore, msg: &[u8]) -> S { + fn sign_with_rng(&self, rng: &mut R, msg: &[u8]) -> S { self.try_sign_with_rng(rng, msg) .expect("signature operation failed") } @@ -97,7 +97,11 @@ pub trait RandomizedSigner { /// /// The main intended use case for signing errors is when communicating /// with external signers, e.g. cloud KMS, HSMs, or other hardware tokens. - fn try_sign_with_rng(&self, rng: &mut impl CryptoRngCore, msg: &[u8]) -> Result; + fn try_sign_with_rng( + &self, + rng: &mut R, + msg: &[u8], + ) -> Result; } /// Combination of [`DigestSigner`] and [`RandomizedSigner`] with support for @@ -109,13 +113,16 @@ pub trait RandomizedDigestSigner { /// Sign the given prehashed message `Digest`, returning a signature. /// /// Panics in the event of a signing error. - fn sign_digest_with_rng(&self, rng: &mut impl CryptoRngCore, digest: D) -> S { + fn sign_digest_with_rng(&self, rng: &mut R, digest: D) -> S { self.try_sign_digest_with_rng(rng, digest) .expect("signature operation failed") } /// Attempt to sign the given prehashed message `Digest`, returning a /// digital signature on success, or an error if something went wrong. - fn try_sign_digest_with_rng(&self, rng: &mut impl CryptoRngCore, digest: D) - -> Result; + fn try_sign_digest_with_rng( + &self, + rng: &mut R, + digest: D, + ) -> Result; } From 44b7b5014d92392ecbd915e87019e73dd64c35b4 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 10 Dec 2022 16:21:32 -0700 Subject: [PATCH 0909/1461] signature: fallible encoding support (#1168) This is helpful for "no panic" profiles. The `Error` type is deliberately left opaque, which means that `From`/`Into` still work via blanket `TryFrom`/`TryInto` impls with `Error = Infallible`. The `SignatureEncoding::to_bytes` method still provides infallible serialization. --- signature/src/encoding.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/signature/src/encoding.rs b/signature/src/encoding.rs index fafa3550c..1d82c826b 100644 --- a/signature/src/encoding.rs +++ b/signature/src/encoding.rs @@ -7,14 +7,17 @@ use alloc::vec::Vec; /// Support for decoding/encoding signatures as bytes. pub trait SignatureEncoding: - Clone + Sized + for<'a> TryFrom<&'a [u8], Error = Error> + Into + Clone + Sized + for<'a> TryFrom<&'a [u8], Error = Error> + TryInto { /// Byte representation of a signature. type Repr: 'static + AsRef<[u8]> + Clone + Send + Sync; /// Encode signature as its byte representation. fn to_bytes(&self) -> Self::Repr { - self.clone().into() + self.clone() + .try_into() + .ok() + .expect("signature encoding error") } /// Encode signature as a byte vector. From dff18e2311578ae056b8c1901f55146c81413dcf Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 10 Dec 2022 16:35:11 -0700 Subject: [PATCH 0910/1461] signature v2.0.0-pre.3 (#1169) --- Cargo.lock | 6 +++--- crypto/Cargo.toml | 2 +- signature/Cargo.toml | 2 +- signature/async/Cargo.toml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 03631107f..2950a36db 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -53,7 +53,7 @@ name = "async-signature" version = "0.3.0-pre" dependencies = [ "async-trait", - "signature 2.0.0-pre.2", + "signature 2.0.0-pre.3", ] [[package]] @@ -257,7 +257,7 @@ dependencies = [ "digest 0.10.6", "elliptic-curve 0.12.3", "password-hash", - "signature 2.0.0-pre.2", + "signature 2.0.0-pre.3", "universal-hash 0.5.0", ] @@ -1060,7 +1060,7 @@ dependencies = [ [[package]] name = "signature" -version = "2.0.0-pre.2" +version = "2.0.0-pre.3" dependencies = [ "digest 0.10.6", "hex-literal", diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 12a5798a3..98cad644e 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -23,7 +23,7 @@ cipher = { version = "0.4", optional = true } digest = { version = "0.10", optional = true, features = ["mac"] } elliptic-curve = { version = "0.12", optional = true } # TODO(tarcieri): path = "../elliptic-curve" password-hash = { version = "0.4", optional = true, path = "../password-hash" } -signature = { version = "=2.0.0-pre.2", optional = true, default-features = false, path = "../signature" } +signature = { version = "=2.0.0-pre.3", optional = true, default-features = false, path = "../signature" } universal-hash = { version = "0.5", optional = true, path = "../universal-hash" } [features] diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 6d3f7e0f8..ba5765da6 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "2.0.0-pre.2" +version = "2.0.0-pre.3" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/signature" diff --git a/signature/async/Cargo.toml b/signature/async/Cargo.toml index 621c0c3ab..8783af2ae 100644 --- a/signature/async/Cargo.toml +++ b/signature/async/Cargo.toml @@ -14,7 +14,7 @@ rust-version = "1.56" [dependencies] async-trait = "0.1.9" -signature = { version = "=2.0.0-pre.2", path = ".." } +signature = { version = "=2.0.0-pre.3", path = ".." } [features] digest = ["signature/digest-preview"] From cf9a83cefe07dd5a8bdb6a166553d0ee4695ea4a Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Mon, 19 Dec 2022 20:11:17 +0300 Subject: [PATCH 0911/1461] crypto-common: add BlockSizes trait, bump MSRV to 1.56 (#1172) --- .github/workflows/crypto-common.yml | 8 +--- Cargo.lock | 66 ++++++++++++++--------------- Cargo.toml | 2 +- README.md | 2 +- aead/Cargo.toml | 2 +- cipher/Cargo.toml | 2 +- crypto-common/CHANGELOG.md | 8 ++++ crypto-common/Cargo.toml | 5 ++- crypto-common/README.md | 4 +- crypto-common/src/lib.rs | 28 +++++++++++- crypto/Cargo.toml | 2 +- digest/Cargo.toml | 2 +- universal-hash/Cargo.toml | 2 +- 13 files changed, 82 insertions(+), 51 deletions(-) diff --git a/.github/workflows/crypto-common.yml b/.github/workflows/crypto-common.yml index 333c608ef..b5fd9464d 100644 --- a/.github/workflows/crypto-common.yml +++ b/.github/workflows/crypto-common.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.41.0 # MSRV + - 1.56.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -36,8 +36,6 @@ jobs: target: ${{ matrix.target }} override: true profile: minimal - # Isolate this crate from workspace which is otherwise MSRV 1.56 due to 2021 edition crates - - run: rm ../Cargo.toml - run: cargo build --target ${{ matrix.target }} minimal-versions: @@ -50,7 +48,7 @@ jobs: strategy: matrix: rust: - - 1.41.0 # MSRV + - 1.56.0 # MSRV - stable steps: - uses: actions/checkout@v3 @@ -60,8 +58,6 @@ jobs: toolchain: ${{ matrix.rust }} override: true profile: minimal - # Isolate this crate from workspace which is otherwise MSRV 1.56 due to 2021 edition crates - - run: rm ../Cargo.toml - run: cargo check --all-features - run: cargo test - run: cargo test --features std diff --git a/Cargo.lock b/Cargo.lock index 2950a36db..b022e230b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,7 +19,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c192eb8f11fc081b0fe4259ba5af04217d4e0faddd02417310a927911abd7c8" dependencies = [ - "crypto-common 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.1.6", "generic-array", ] @@ -58,9 +58,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.59" +version = "0.1.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6e93155431f3931513b243d371981bb2770112b370c82745a1d19d2f99364" +checksum = "677d1d8ab452a3936018a687b20e6f7cf5363d713b732b8884001317b0e48aa3" dependencies = [ "proc-macro2", "quote", @@ -162,9 +162,9 @@ checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c" [[package]] name = "cc" -version = "1.0.77" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4" +checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" dependencies = [ "jobserver", ] @@ -215,7 +215,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d1873270f8f7942c191139cb8a40fd228da6c3fd2fc376d7e92d47aa14aeb59e" dependencies = [ - "crypto-common 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.1.6", "inout", "zeroize", ] @@ -288,6 +288,8 @@ dependencies = [ [[package]] name = "crypto-common" version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", "rand_core 0.6.4", @@ -296,9 +298,7 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +version = "0.2.0-pre" dependencies = [ "generic-array", "rand_core 0.6.4", @@ -373,7 +373,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" dependencies = [ "block-buffer 0.10.3", - "crypto-common 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.1.6", "subtle", ] @@ -664,9 +664,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" +checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440" [[package]] name = "jobserver" @@ -864,18 +864,18 @@ checksum = "97e91cb6af081c6daad5fa705f8adb0634c027662052cb3174bdf2957bf07e25" [[package]] name = "proc-macro2" -version = "1.0.47" +version = "1.0.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" dependencies = [ "proc-macro2", ] @@ -933,9 +933,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" +checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" [[package]] name = "scopeguard" @@ -960,33 +960,33 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.14" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4" +checksum = "58bc9567378fc7690d6b2addae4e60ac2eeea07becb2c64b9f218b53865cba2a" [[package]] name = "serde" -version = "1.0.149" +version = "1.0.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "256b9932320c590e707b94576e3cc1f7c9024d0ee6612dfbcf1cb106cbe8e055" +checksum = "97fed41fc1a24994d044e6db6935e69511a1153b52c15eb42493b26fa87feba0" dependencies = [ "serde_derive", ] [[package]] name = "serde_bytes" -version = "0.11.7" +version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfc50e8183eeeb6178dcb167ae34a8051d63535023ae38b5d8d12beae193d37b" +checksum = "718dc5fff5b36f99093fc49b280cfc96ce6fc824317783bff5a1fed0c7a64819" dependencies = [ "serde", ] [[package]] name = "serde_derive" -version = "1.0.149" +version = "1.0.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4eae9b04cbffdfd550eb462ed33bc6a1b68c935127d008b27444d08380f94e4" +checksum = "255abe9a125a985c05190d687b320c12f9b1f0b99445e608c21ba0782c719ad8" dependencies = [ "proc-macro2", "quote", @@ -995,9 +995,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.89" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db" +checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883" dependencies = [ "itoa", "ryu", @@ -1120,9 +1120,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.105" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" +checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" dependencies = [ "proc-macro2", "quote", @@ -1155,9 +1155,9 @@ checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "unicode-ident" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" [[package]] name = "unicode-xid" @@ -1179,7 +1179,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d3160b73c9a19f7e2939a2fdad446c57c1bbbbf4d919d3213ff1267a580d8b5" dependencies = [ - "crypto-common 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.1.6", "subtle", ] diff --git a/Cargo.toml b/Cargo.toml index b8363c66c..38e3e4117 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,7 @@ members = [ "aead", "cipher", "crypto", + "crypto-common", "elliptic-curve", "kem", "signature", @@ -11,6 +12,5 @@ members = [ "universal-hash", ] exclude = [ - "crypto-common", "digest", ] diff --git a/README.md b/README.md index 99f3d96fb..8d1821067 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Collection of traits which describe functionality of cryptographic primitives. | [`aead`] | [Authenticated encryption] | [![crates.io](https://img.shields.io/crates/v/aead.svg)](https://crates.io/crates/aead) | [![Documentation](https://docs.rs/aead/badge.svg)](https://docs.rs/aead) | ![MSRV 1.56][msrv-1.56] | | [`async‑signature`] | [Digital signature] | [![crates.io](https://img.shields.io/crates/v/async-signature.svg)](https://crates.io/crates/async-signature) | [![Documentation](https://docs.rs/async-signature/badge.svg)](https://docs.rs/async-signature) | ![MSRV 1.56][msrv-1.56] | | [`cipher`] | [Block] and [stream cipher] | [![crates.io](https://img.shields.io/crates/v/cipher.svg)](https://crates.io/crates/cipher) | [![Documentation](https://docs.rs/cipher/badge.svg)](https://docs.rs/cipher) | ![MSRV 1.56][msrv-1.56] | -| [`crypto‑common`] | Common cryptographic traits | [![crates.io](https://img.shields.io/crates/v/crypto-common.svg)](https://crates.io/crates/crypto-common) | [![Documentation](https://docs.rs/crypto-common/badge.svg)](https://docs.rs/crypto-common) | ![MSRV 1.41][msrv-1.41] | +| [`crypto‑common`] | Common cryptographic traits | [![crates.io](https://img.shields.io/crates/v/crypto-common.svg)](https://crates.io/crates/crypto-common) | [![Documentation](https://docs.rs/crypto-common/badge.svg)](https://docs.rs/crypto-common) | ![MSRV 1.56][msrv-1.56] | | [`digest`] | [Cryptographic hash function] | [![crates.io](https://img.shields.io/crates/v/digest.svg)](https://crates.io/crates/digest) | [![Documentation](https://docs.rs/digest/badge.svg)](https://docs.rs/digest) | ![MSRV 1.41][msrv-1.41] | | [`elliptic‑curve`] | [Elliptic curve cryptography] | [![crates.io](https://img.shields.io/crates/v/elliptic-curve.svg)](https://crates.io/crates/elliptic-curve) | [![Documentation](https://docs.rs/elliptic-curve/badge.svg)](https://docs.rs/elliptic-curve) | ![MSRV 1.57][msrv-1.57] | | [`kem`] | [Key encapsulation mechanism] | [![crates.io](https://img.shields.io/crates/v/kem.svg)](https://crates.io/crates/kem) | [![Documentation](https://docs.rs/kem/badge.svg)](https://docs.rs/kem) | ![MSRV 1.56][msrv-1.56] | diff --git a/aead/Cargo.toml b/aead/Cargo.toml index 06859209d..6837bf118 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -16,7 +16,7 @@ categories = ["cryptography", "no-std"] rust-version = "1.56" [dependencies] -crypto-common = { version = "0.1.4", path = "../crypto-common" } +crypto-common = "0.1.4" generic-array = { version = "0.14", default-features = false } # optional dependencies diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index c04cc0577..2242e1a27 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -13,7 +13,7 @@ keywords = ["crypto", "block-cipher", "stream-cipher", "trait"] categories = ["cryptography", "no-std"] [dependencies] -crypto-common = { version = "0.1.6", path = "../crypto-common" } +crypto-common = "0.1.6" inout = "0.1" # optional dependencies diff --git a/crypto-common/CHANGELOG.md b/crypto-common/CHANGELOG.md index 9fa793693..448cb106c 100644 --- a/crypto-common/CHANGELOG.md +++ b/crypto-common/CHANGELOG.md @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## UNRELEASED +### Added +- Sealed `BlockSizes` trait implemented for types from `U1` to `U255` + +### Changed +- `BlockUser::BlockSize` is now bounded by the `BlockSizes` trait +- Edition changed to 2021 and MSRV bumped to 1.56 + ## 0.1.6 (2022-07-16) ### Added - Move `ParBlocks`/`ParBlocksSizeUser` from `cipher` crate ([#1052]) diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index 374e80f52..03f4d2b9e 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -1,11 +1,12 @@ [package] name = "crypto-common" description = "Common cryptographic traits" -version = "0.1.6" +version = "0.2.0-pre" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" -edition = "2018" +edition = "2021" +rust-version = "1.56" documentation = "https://docs.rs/crypto-common" repository = "https://github.com/RustCrypto/traits" keywords = ["crypto", "traits"] diff --git a/crypto-common/README.md b/crypto-common/README.md index 70ca758cd..ba35578f8 100644 --- a/crypto-common/README.md +++ b/crypto-common/README.md @@ -14,7 +14,7 @@ higher-level trait crates instead of this one. ## Minimum Supported Rust Version -Rust **1.41** or higher. +Rust **1.56** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -46,7 +46,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/crypto-common/badge.svg [docs-link]: https://docs.rs/crypto-common/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.56+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260041-hashes [build-image]: https://github.com/RustCrypto/traits/workflows/crypto-common/badge.svg?branch=master&event=push diff --git a/crypto-common/src/lib.rs b/crypto-common/src/lib.rs index c49984cd2..53f0fa9cf 100644 --- a/crypto-common/src/lib.rs +++ b/crypto-common/src/lib.rs @@ -41,9 +41,10 @@ pub type Iv = GenericArray::IvSize>; /// Types which process data in blocks. pub trait BlockSizeUser { /// Size of the block in bytes. - type BlockSize: ArrayLength + 'static; + type BlockSize: BlockSizes; /// Return block size in bytes. + #[inline(always)] fn block_size() -> usize { Self::BlockSize::USIZE } @@ -57,6 +58,25 @@ impl BlockSizeUser for &mut T { type BlockSize = T::BlockSize; } +/// Trait implemented for supported block sizes, i.e. for types from `U1` to `U255`. +pub trait BlockSizes: ArrayLength + sealed::BlockSizes + 'static {} + +impl + sealed::BlockSizes> BlockSizes for T {} + +mod sealed { + use generic_array::typenum::{Gr, IsGreater, IsLess, Le, NonZero, Unsigned, U1, U256}; + + pub trait BlockSizes {} + + impl BlockSizes for T + where + Self: IsLess + IsGreater, + Le: NonZero, + Gr: NonZero, + { + } +} + /// Types which can process blocks in parallel. pub trait ParBlocksSizeUser: BlockSizeUser { /// Number of blocks which can be processed in parallel. @@ -69,6 +89,7 @@ pub trait OutputSizeUser { type OutputSize: ArrayLength + 'static; /// Return output size in bytes. + #[inline(always)] fn output_size() -> usize { Self::OutputSize::USIZE } @@ -82,6 +103,7 @@ pub trait KeySizeUser { type KeySize: ArrayLength + 'static; /// Return key size in bytes. + #[inline(always)] fn key_size() -> usize { Self::KeySize::USIZE } @@ -95,6 +117,7 @@ pub trait IvSizeUser { type IvSize: ArrayLength + 'static; /// Return IV size in bytes. + #[inline(always)] fn iv_size() -> usize { Self::IvSize::USIZE } @@ -126,6 +149,7 @@ pub trait KeyInit: KeySizeUser + Sized { fn new(key: &Key) -> Self; /// Create new value from variable size key. + #[inline] fn new_from_slice(key: &[u8]) -> Result { if key.len() != Self::KeySize::to_usize() { Err(InvalidLength) @@ -211,6 +235,7 @@ pub trait InnerIvInit: InnerUser + IvSizeUser + Sized { fn inner_iv_init(inner: Self::Inner, iv: &Iv) -> Self; /// Initialize value using `inner` and `iv` slice. + #[inline] fn inner_iv_slice_init(inner: Self::Inner, iv: &[u8]) -> Result { if iv.len() != Self::IvSize::to_usize() { Err(InvalidLength) @@ -302,6 +327,7 @@ where pub struct InvalidLength; impl fmt::Display for InvalidLength { + #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { f.write_str("Invalid Length") } diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 98cad644e..c533bc075 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -15,7 +15,7 @@ edition = "2021" rust-version = "1.57" [dependencies] -crypto-common = { version = "0.1", default-features = false, path = "../crypto-common" } +crypto-common = { version = "0.1", default-features = false } # optional dependencies aead = { version = "0.5", optional = true, path = "../aead" } diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 943378c13..0529b2b6e 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -12,7 +12,7 @@ keywords = ["digest", "crypto", "hash"] categories = ["cryptography", "no-std"] [dependencies] -crypto-common = { version = "0.1.3", path = "../crypto-common" } +crypto-common = "0.1.3" # optional dependencies block-buffer = { version = "0.10", optional = true } diff --git a/universal-hash/Cargo.toml b/universal-hash/Cargo.toml index 74bbd115b..cd954a971 100644 --- a/universal-hash/Cargo.toml +++ b/universal-hash/Cargo.toml @@ -13,7 +13,7 @@ keywords = ["crypto", "mac"] categories = ["cryptography", "no-std"] [dependencies] -crypto-common = { version = "0.1.6", path = "../crypto-common" } +crypto-common = "0.1.6" subtle = { version = "=2.4", default-features = false } [features] From 9bf4bf86562d8f16b472943ead5a16c3d8540133 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Mon, 19 Dec 2022 21:06:31 +0300 Subject: [PATCH 0912/1461] digest v0.11.0-pre (#1173) --- .github/workflows/crypto.yml | 48 ++++++---------------- .github/workflows/digest.yml | 27 +------------ Cargo.lock | 32 +++++++++++++++ Cargo.toml | 4 +- README.md | 3 +- digest/CHANGELOG.md | 10 +++++ digest/Cargo.toml | 11 ++--- digest/README.md | 6 +-- digest/src/core_api.rs | 23 ++--------- digest/src/core_api/ct_variable.rs | 26 +----------- digest/src/core_api/rt_variable.rs | 36 ++--------------- digest/src/core_api/wrapper.rs | 65 ++---------------------------- digest/src/core_api/xof_reader.rs | 19 ++------- digest/src/dev/mac.rs | 8 ++-- digest/src/mac.rs | 51 ++--------------------- 15 files changed, 91 insertions(+), 278 deletions(-) diff --git a/.github/workflows/crypto.yml b/.github/workflows/crypto.yml index 8687448cc..276594d36 100644 --- a/.github/workflows/crypto.yml +++ b/.github/workflows/crypto.yml @@ -40,21 +40,19 @@ jobs: - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features aead,cipher,digest,elliptic-curve,signature,universal-hash - # TODO: use the reusable workflow after this crate will be part of the - # toot workspace - # minimal-versions: - # runs-on: ubuntu-latest - # steps: - # - uses: actions/checkout@v3 - # - uses: RustCrypto/actions/cargo-cache@master - # - uses: actions-rs/toolchain@v1 - # with: - # toolchain: nightly - # override: true - # profile: minimal - # - uses: RustCrypto/actions/cargo-hack-install@master - # - run: cargo update -Z minimal-versions - # - run: cargo hack test --release --feature-powerset + minimal-versions: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: RustCrypto/actions/cargo-cache@master + - uses: actions-rs/toolchain@v1 + with: + toolchain: nightly + override: true + profile: minimal + - uses: RustCrypto/actions/cargo-hack-install@master + - run: cargo update -Z minimal-versions + - run: cargo hack test --release --feature-powerset test: runs-on: ubuntu-latest @@ -88,23 +86,3 @@ jobs: override: true profile: minimal - run: cargo clippy --all --all-features -- -D warnings - - rustfmt: - runs-on: ubuntu-latest - steps: - - name: Checkout sources - uses: actions/checkout@v3 - - - name: Install stable toolchain - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - components: rustfmt - override: true - profile: minimal - - - name: Run cargo fmt - uses: actions-rs/cargo@v1 - with: - command: fmt - args: --all -- --check diff --git a/.github/workflows/digest.yml b/.github/workflows/digest.yml index ee77a7116..625127772 100644 --- a/.github/workflows/digest.yml +++ b/.github/workflows/digest.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.41.0 # MSRV + - 1.57.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -50,7 +50,7 @@ jobs: strategy: matrix: rust: - # - 1.41.0 # MSRV + - 1.57.0 # MSRV - stable steps: - uses: actions/checkout@v3 @@ -67,26 +67,3 @@ jobs: - run: cargo test --features alloc - run: cargo test --features std - run: cargo test --all-features - - # The `oid` feature bumps MSRV to 1.57, so we temporarily split this job. - test-msrv: - runs-on: ubuntu-latest - strategy: - matrix: - rust: - - 1.41.0 # MSRV - steps: - - uses: actions/checkout@v3 - - uses: RustCrypto/actions/cargo-cache@master - - uses: actions-rs/toolchain@v1 - with: - toolchain: ${{ matrix.rust }} - override: true - profile: minimal - # Isolate this crate from workspace which is otherwise MSRV 1.56 due to 2021 edition crates - - run: rm ../Cargo.toml - - run: cargo test --no-default-features - - run: cargo test - - run: cargo test --features dev - - run: cargo test --features alloc - - run: cargo test --features std diff --git a/Cargo.lock b/Cargo.lock index b022e230b..3a3838ce0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -139,6 +139,16 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-buffer" +version = "0.11.0-pre" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b6a33d658e9ef24ba0c4566d3d023d7978ca2ea3efb65e4eacd4586695892b" +dependencies = [ + "crypto-common 0.2.0-pre (registry+https://github.com/rust-lang/crates.io-index)", + "generic-array", +] + [[package]] name = "block-padding" version = "0.3.2" @@ -305,6 +315,17 @@ dependencies = [ "typenum", ] +[[package]] +name = "crypto-common" +version = "0.2.0-pre" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6faaa83e7700e0832cbbf84854d4c356270526907d9b14fab927fc7a9b5befb8" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "typenum", +] + [[package]] name = "crypto-mac" version = "0.11.1" @@ -377,6 +398,17 @@ dependencies = [ "subtle", ] +[[package]] +name = "digest" +version = "0.11.0-pre" +dependencies = [ + "blobby", + "block-buffer 0.11.0-pre", + "const-oid 0.9.1", + "crypto-common 0.2.0-pre (registry+https://github.com/rust-lang/crates.io-index)", + "subtle", +] + [[package]] name = "dunce" version = "1.0.3" diff --git a/Cargo.toml b/Cargo.toml index 38e3e4117..dc7d95785 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,12 +5,10 @@ members = [ "cipher", "crypto", "crypto-common", + "digest", "elliptic-curve", "kem", "signature", "signature/async", "universal-hash", ] -exclude = [ - "digest", -] diff --git a/README.md b/README.md index 8d1821067..d907874ad 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Collection of traits which describe functionality of cryptographic primitives. | [`async‑signature`] | [Digital signature] | [![crates.io](https://img.shields.io/crates/v/async-signature.svg)](https://crates.io/crates/async-signature) | [![Documentation](https://docs.rs/async-signature/badge.svg)](https://docs.rs/async-signature) | ![MSRV 1.56][msrv-1.56] | | [`cipher`] | [Block] and [stream cipher] | [![crates.io](https://img.shields.io/crates/v/cipher.svg)](https://crates.io/crates/cipher) | [![Documentation](https://docs.rs/cipher/badge.svg)](https://docs.rs/cipher) | ![MSRV 1.56][msrv-1.56] | | [`crypto‑common`] | Common cryptographic traits | [![crates.io](https://img.shields.io/crates/v/crypto-common.svg)](https://crates.io/crates/crypto-common) | [![Documentation](https://docs.rs/crypto-common/badge.svg)](https://docs.rs/crypto-common) | ![MSRV 1.56][msrv-1.56] | -| [`digest`] | [Cryptographic hash function] | [![crates.io](https://img.shields.io/crates/v/digest.svg)](https://crates.io/crates/digest) | [![Documentation](https://docs.rs/digest/badge.svg)](https://docs.rs/digest) | ![MSRV 1.41][msrv-1.41] | +| [`digest`] | [Cryptographic hash function] | [![crates.io](https://img.shields.io/crates/v/digest.svg)](https://crates.io/crates/digest) | [![Documentation](https://docs.rs/digest/badge.svg)](https://docs.rs/digest) | ![MSRV 1.57][msrv-1.57] | | [`elliptic‑curve`] | [Elliptic curve cryptography] | [![crates.io](https://img.shields.io/crates/v/elliptic-curve.svg)](https://crates.io/crates/elliptic-curve) | [![Documentation](https://docs.rs/elliptic-curve/badge.svg)](https://docs.rs/elliptic-curve) | ![MSRV 1.57][msrv-1.57] | | [`kem`] | [Key encapsulation mechanism] | [![crates.io](https://img.shields.io/crates/v/kem.svg)](https://crates.io/crates/kem) | [![Documentation](https://docs.rs/kem/badge.svg)](https://docs.rs/kem) | ![MSRV 1.56][msrv-1.56] | | [`password-hash`] | [Password hashing] | [![crates.io](https://img.shields.io/crates/v/password-hash.svg)](https://crates.io/crates/password-hash) | [![Documentation](https://docs.rs/password-hash/badge.svg)](https://docs.rs/password-hash) | ![MSRV 1.57][msrv-1.57] | @@ -49,7 +49,6 @@ Unless you explicitly state otherwise, any contribution intentionally submitted [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg [deps-image]: https://deps.rs/repo/github/RustCrypto/traits/status.svg [deps-link]: https://deps.rs/repo/github/RustCrypto/traits -[msrv-1.41]: https://img.shields.io/badge/rustc-1.41.0+-blue.svg [msrv-1.56]: https://img.shields.io/badge/rustc-1.56.0+-blue.svg [msrv-1.57]: https://img.shields.io/badge/rustc-1.57.0+-blue.svg diff --git a/digest/CHANGELOG.md b/digest/CHANGELOG.md index e03398bfc..6713389fd 100644 --- a/digest/CHANGELOG.md +++ b/digest/CHANGELOG.md @@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## UNRELEASED +### Changed +- `crypto-common` dependency bumped to v0.2 ([#1173]) +- Edition changed to 2021 and MSRV bumped to 1.57 ([#1173]) + +### Removed +- `Mac::new`, `Mac::new_from_slice`, and `Mac::generate_key` methods ([#1173]) + +[#1173]: https://github.com/RustCrypto/traits/pull/1173 + ## 0.10.6 (2022-11-17) ### Added - `Mac::verify_reset` and `Mac::verify_slice_reset` methods ([#1154]) diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 0529b2b6e..61f468357 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -1,21 +1,22 @@ [package] name = "digest" description = "Traits for cryptographic hash functions and message authentication codes" -version = "0.10.6" +version = "0.11.0-pre" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" -edition = "2018" +edition = "2021" +rust-version = "1.57" documentation = "https://docs.rs/digest" repository = "https://github.com/RustCrypto/traits" keywords = ["digest", "crypto", "hash"] categories = ["cryptography", "no-std"] [dependencies] -crypto-common = "0.1.3" +crypto-common = "0.2.0-pre" # optional dependencies -block-buffer = { version = "0.10", optional = true } +block-buffer = { version = "0.11.0-pre", optional = true } subtle = { version = "=2.4", default-features = false, optional = true } blobby = { version = "0.3", optional = true } const-oid = { version = "0.9", optional = true } @@ -25,7 +26,7 @@ default = ["core-api"] core-api = ["block-buffer"] # Enable Core API traits mac = ["subtle"] # Enable MAC traits rand_core = ["crypto-common/rand_core"] # Enable random key generation methods -oid = ["const-oid"] # OID support. WARNING: Bumps MSRV to 1.57 +oid = ["const-oid"] alloc = [] std = ["alloc", "crypto-common/std"] dev = ["blobby"] diff --git a/digest/README.md b/digest/README.md index 9f68559cd..1d5f1f8fb 100644 --- a/digest/README.md +++ b/digest/README.md @@ -16,7 +16,7 @@ See [RustCrypto/hashes][1] for implementations which use this trait. ## Minimum Supported Rust Version -Rust **1.41** or higher. +Rust **1.57** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -35,7 +35,7 @@ First add the `sha2` crate to your `Cargo.toml`: ```toml [dependencies] -sha2 = "0.10" +sha2 = "0.11" ``` `sha2` and other crates re-export `digest` crate and `Digest` trait for @@ -147,7 +147,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/digest/badge.svg [docs-link]: https://docs.rs/digest/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.57+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260041-hashes [build-image]: https://github.com/RustCrypto/traits/workflows/digest/badge.svg?branch=master&event=push diff --git a/digest/src/core_api.rs b/digest/src/core_api.rs index 2cf384efe..6e8b8def7 100644 --- a/digest/src/core_api.rs +++ b/digest/src/core_api.rs @@ -8,10 +8,7 @@ use crate::InvalidOutputSize; pub use crypto_common::{AlgorithmName, Block, BlockSizeUser, OutputSizeUser, Reset}; use block_buffer::{BlockBuffer, BufferKind}; -use crypto_common::{ - typenum::{IsLess, Le, NonZero, U256}, - Output, -}; +use crypto_common::Output; mod ct_variable; mod rt_variable; @@ -40,22 +37,14 @@ pub trait BufferKindUser: BlockSizeUser { } /// Core trait for hash functions with fixed output size. -pub trait FixedOutputCore: UpdateCore + BufferKindUser + OutputSizeUser -where - Self::BlockSize: IsLess, - Le: NonZero, -{ +pub trait FixedOutputCore: UpdateCore + BufferKindUser + OutputSizeUser { /// Finalize state using remaining data stored in the provided block buffer, /// write result into provided array and leave `self` in a dirty state. fn finalize_fixed_core(&mut self, buffer: &mut Buffer, out: &mut Output); } /// Core trait for hash functions with extendable (XOF) output size. -pub trait ExtendableOutputCore: UpdateCore + BufferKindUser -where - Self::BlockSize: IsLess, - Le: NonZero, -{ +pub trait ExtendableOutputCore: UpdateCore + BufferKindUser { /// XOF reader core state. type ReaderCore: XofReaderCore; @@ -81,11 +70,7 @@ pub trait XofReaderCore: BlockSizeUser { /// [`finalize_variable_core`]: VariableOutputCore::finalize_variable_core /// [`new`]: VariableOutputCore::new /// [`TRUNC_SIDE`]: VariableOutputCore::TRUNC_SIDE -pub trait VariableOutputCore: UpdateCore + OutputSizeUser + BufferKindUser + Sized -where - Self::BlockSize: IsLess, - Le: NonZero, -{ +pub trait VariableOutputCore: UpdateCore + OutputSizeUser + BufferKindUser + Sized { /// Side which should be used in a truncated result. const TRUNC_SIDE: TruncSide; diff --git a/digest/src/core_api/ct_variable.rs b/digest/src/core_api/ct_variable.rs index 7ee1bed0a..0011a9262 100644 --- a/digest/src/core_api/ct_variable.rs +++ b/digest/src/core_api/ct_variable.rs @@ -10,7 +10,7 @@ use const_oid::{AssociatedOid, ObjectIdentifier}; use core::{fmt, marker::PhantomData}; use crypto_common::{ generic_array::{ArrayLength, GenericArray}, - typenum::{IsLess, IsLessOrEqual, Le, LeEq, NonZero, U256}, + typenum::{IsLessOrEqual, LeEq, NonZero}, Block, BlockSizeUser, OutputSizeUser, }; @@ -27,8 +27,6 @@ where T: VariableOutputCore, OutSize: ArrayLength + IsLessOrEqual, LeEq: NonZero, - T::BlockSize: IsLess, - Le: NonZero, { inner: T, _out: PhantomData<(OutSize, O)>, @@ -39,8 +37,6 @@ where T: VariableOutputCore + HashMarker, OutSize: ArrayLength + IsLessOrEqual, LeEq: NonZero, - T::BlockSize: IsLess, - Le: NonZero, { } @@ -50,8 +46,6 @@ where T: VariableOutputCore + MacMarker, OutSize: ArrayLength + IsLessOrEqual, LeEq: NonZero, - T::BlockSize: IsLess, - Le: NonZero, { } @@ -60,8 +54,6 @@ where T: VariableOutputCore, OutSize: ArrayLength + IsLessOrEqual, LeEq: NonZero, - T::BlockSize: IsLess, - Le: NonZero, { type BlockSize = T::BlockSize; } @@ -71,8 +63,6 @@ where T: VariableOutputCore, OutSize: ArrayLength + IsLessOrEqual, LeEq: NonZero, - T::BlockSize: IsLess, - Le: NonZero, { #[inline] fn update_blocks(&mut self, blocks: &[Block]) { @@ -85,8 +75,6 @@ where T: VariableOutputCore, OutSize: ArrayLength + IsLessOrEqual + 'static, LeEq: NonZero, - T::BlockSize: IsLess, - Le: NonZero, { type OutputSize = OutSize; } @@ -96,8 +84,6 @@ where T: VariableOutputCore, OutSize: ArrayLength + IsLessOrEqual, LeEq: NonZero, - T::BlockSize: IsLess, - Le: NonZero, { type BufferKind = T::BufferKind; } @@ -107,8 +93,6 @@ where T: VariableOutputCore, OutSize: ArrayLength + IsLessOrEqual + 'static, LeEq: NonZero, - T::BlockSize: IsLess, - Le: NonZero, { #[inline] fn finalize_fixed_core( @@ -132,8 +116,6 @@ where T: VariableOutputCore, OutSize: ArrayLength + IsLessOrEqual, LeEq: NonZero, - T::BlockSize: IsLess, - Le: NonZero, { #[inline] fn default() -> Self { @@ -149,8 +131,6 @@ where T: VariableOutputCore, OutSize: ArrayLength + IsLessOrEqual, LeEq: NonZero, - T::BlockSize: IsLess, - Le: NonZero, { #[inline] fn reset(&mut self) { @@ -163,8 +143,6 @@ where T: VariableOutputCore + AlgorithmName, OutSize: ArrayLength + IsLessOrEqual, LeEq: NonZero, - T::BlockSize: IsLess, - Le: NonZero, { fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { T::write_alg_name(f)?; @@ -181,8 +159,6 @@ where O: AssociatedOid, OutSize: ArrayLength + IsLessOrEqual, LeEq: NonZero, - T::BlockSize: IsLess, - Le: NonZero, { const OID: ObjectIdentifier = O::OID; } diff --git a/digest/src/core_api/rt_variable.rs b/digest/src/core_api/rt_variable.rs index 3dae748f5..94708ee77 100644 --- a/digest/src/core_api/rt_variable.rs +++ b/digest/src/core_api/rt_variable.rs @@ -5,16 +5,14 @@ use crate::{HashMarker, InvalidBufferSize}; use crate::{InvalidOutputSize, Reset, Update, VariableOutput, VariableOutputReset}; use block_buffer::BlockBuffer; use core::fmt; -use crypto_common::typenum::{IsLess, Le, NonZero, Unsigned, U256}; +use crypto_common::typenum::Unsigned; /// Wrapper around [`VariableOutputCore`] which selects output size /// at run time. #[derive(Clone)] pub struct RtVariableCoreWrapper where - T: VariableOutputCore + UpdateCore, - T::BlockSize: IsLess, - Le: NonZero, + T: VariableOutputCore, { core: T, buffer: BlockBuffer, @@ -24,8 +22,6 @@ where impl RtVariableCoreWrapper where T: VariableOutputCore, - T::BlockSize: IsLess, - Le: NonZero, { #[inline] fn finalize_dirty(&mut self, out: &mut [u8]) -> Result<(), InvalidBufferSize> { @@ -49,29 +45,15 @@ where } } -impl HashMarker for RtVariableCoreWrapper -where - T: VariableOutputCore + HashMarker, - T::BlockSize: IsLess, - Le: NonZero, -{ -} +impl HashMarker for RtVariableCoreWrapper where T: VariableOutputCore + HashMarker {} #[cfg(feature = "mac")] #[cfg_attr(docsrs, doc(cfg(feature = "mac")))] -impl MacMarker for RtVariableCoreWrapper -where - T: VariableOutputCore + MacMarker, - T::BlockSize: IsLess, - Le: NonZero, -{ -} +impl MacMarker for RtVariableCoreWrapper where T: VariableOutputCore + MacMarker {} impl Reset for RtVariableCoreWrapper where T: VariableOutputCore + UpdateCore + Reset, - T::BlockSize: IsLess, - Le: NonZero, { #[inline] fn reset(&mut self) { @@ -83,8 +65,6 @@ where impl Update for RtVariableCoreWrapper where T: VariableOutputCore + UpdateCore, - T::BlockSize: IsLess, - Le: NonZero, { #[inline] fn update(&mut self, input: &[u8]) { @@ -96,8 +76,6 @@ where impl VariableOutput for RtVariableCoreWrapper where T: VariableOutputCore + UpdateCore, - T::BlockSize: IsLess, - Le: NonZero, { const MAX_OUTPUT_SIZE: usize = T::OutputSize::USIZE; @@ -122,8 +100,6 @@ where impl VariableOutputReset for RtVariableCoreWrapper where T: VariableOutputCore + UpdateCore + Reset, - T::BlockSize: IsLess, - Le: NonZero, { fn finalize_variable_reset(&mut self, out: &mut [u8]) -> Result<(), InvalidBufferSize> { self.finalize_dirty(out)?; @@ -136,8 +112,6 @@ where impl fmt::Debug for RtVariableCoreWrapper where T: VariableOutputCore + UpdateCore + AlgorithmName, - T::BlockSize: IsLess, - Le: NonZero, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { T::write_alg_name(f)?; @@ -150,8 +124,6 @@ where impl std::io::Write for RtVariableCoreWrapper where T: VariableOutputCore + UpdateCore, - T::BlockSize: IsLess, - Le: NonZero, { #[inline] fn write(&mut self, buf: &[u8]) -> std::io::Result { diff --git a/digest/src/core_api/wrapper.rs b/digest/src/core_api/wrapper.rs index ca977381e..af77b11c8 100644 --- a/digest/src/core_api/wrapper.rs +++ b/digest/src/core_api/wrapper.rs @@ -7,10 +7,7 @@ use crate::{ }; use block_buffer::BlockBuffer; use core::fmt; -use crypto_common::{ - typenum::{IsLess, Le, NonZero, U256}, - BlockSizeUser, InvalidLength, Key, KeyInit, KeySizeUser, Output, -}; +use crypto_common::{BlockSizeUser, InvalidLength, Key, KeyInit, KeySizeUser, Output}; #[cfg(feature = "mac")] use crate::MacMarker; @@ -24,37 +21,21 @@ use const_oid::{AssociatedOid, ObjectIdentifier}; pub struct CoreWrapper where T: BufferKindUser, - T::BlockSize: IsLess, - Le: NonZero, { core: T, buffer: BlockBuffer, } -impl HashMarker for CoreWrapper -where - T: BufferKindUser + HashMarker, - T::BlockSize: IsLess, - Le: NonZero, -{ -} +impl HashMarker for CoreWrapper where T: BufferKindUser + HashMarker {} #[cfg(feature = "mac")] #[cfg_attr(docsrs, doc(cfg(feature = "mac")))] -impl MacMarker for CoreWrapper -where - T: BufferKindUser + MacMarker, - T::BlockSize: IsLess, - Le: NonZero, -{ -} +impl MacMarker for CoreWrapper where T: BufferKindUser + MacMarker {} // this blanket impl is needed for HMAC impl BlockSizeUser for CoreWrapper where T: BufferKindUser + HashMarker, - T::BlockSize: IsLess, - Le: NonZero, { type BlockSize = T::BlockSize; } @@ -62,8 +43,6 @@ where impl CoreWrapper where T: BufferKindUser, - T::BlockSize: IsLess, - Le: NonZero, { /// Create new wrapper from `core`. #[inline] @@ -83,8 +62,6 @@ where impl KeySizeUser for CoreWrapper where T: BufferKindUser + KeySizeUser, - T::BlockSize: IsLess, - Le: NonZero, { type KeySize = T::KeySize; } @@ -92,8 +69,6 @@ where impl KeyInit for CoreWrapper where T: BufferKindUser + KeyInit, - T::BlockSize: IsLess, - Le: NonZero, { #[inline] fn new(key: &Key) -> Self { @@ -115,8 +90,6 @@ where impl fmt::Debug for CoreWrapper where T: BufferKindUser + AlgorithmName, - T::BlockSize: IsLess, - Le: NonZero, { #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { @@ -128,8 +101,6 @@ where impl Reset for CoreWrapper where T: BufferKindUser + Reset, - T::BlockSize: IsLess, - Le: NonZero, { #[inline] fn reset(&mut self) { @@ -141,8 +112,6 @@ where impl Update for CoreWrapper where T: BufferKindUser + UpdateCore, - T::BlockSize: IsLess, - Le: NonZero, { #[inline] fn update(&mut self, input: &[u8]) { @@ -154,8 +123,6 @@ where impl OutputSizeUser for CoreWrapper where T: BufferKindUser + OutputSizeUser, - T::BlockSize: IsLess, - Le: NonZero, { type OutputSize = T::OutputSize; } @@ -163,8 +130,6 @@ where impl FixedOutput for CoreWrapper where T: FixedOutputCore, - T::BlockSize: IsLess, - Le: NonZero, { #[inline] fn finalize_into(mut self, out: &mut Output) { @@ -176,8 +141,6 @@ where impl FixedOutputReset for CoreWrapper where T: FixedOutputCore + Reset, - T::BlockSize: IsLess, - Le: NonZero, { #[inline] fn finalize_into_reset(&mut self, out: &mut Output) { @@ -191,10 +154,6 @@ where impl ExtendableOutput for CoreWrapper where T: ExtendableOutputCore, - T::BlockSize: IsLess, - Le: NonZero, - ::BlockSize: IsLess, - Le<::BlockSize, U256>: NonZero, { type Reader = XofReaderCoreWrapper; @@ -210,10 +169,6 @@ where impl ExtendableOutputReset for CoreWrapper where T: ExtendableOutputCore + Reset, - T::BlockSize: IsLess, - Le: NonZero, - ::BlockSize: IsLess, - Le<::BlockSize, U256>: NonZero, { #[inline] fn finalize_xof_reset(&mut self) -> Self::Reader { @@ -234,8 +189,6 @@ where impl AssociatedOid for CoreWrapper where T: BufferKindUser + AssociatedOid, - T::BlockSize: IsLess, - Le: NonZero, { const OID: ObjectIdentifier = T::OID; } @@ -245,8 +198,6 @@ where impl std::io::Write for CoreWrapper where T: BufferKindUser + UpdateCore, - T::BlockSize: IsLess, - Le: NonZero, { #[inline] fn write(&mut self, buf: &[u8]) -> std::io::Result { @@ -272,19 +223,11 @@ mod sealed { pub trait Sealed {} } -impl sealed::Sealed for CoreWrapper -where - T: BufferKindUser, - T::BlockSize: IsLess, - Le: NonZero, -{ -} +impl sealed::Sealed for CoreWrapper where T: BufferKindUser {} impl CoreProxy for CoreWrapper where T: BufferKindUser, - T::BlockSize: IsLess, - Le: NonZero, { type Core = T; } diff --git a/digest/src/core_api/xof_reader.rs b/digest/src/core_api/xof_reader.rs index e18ac133a..665e2a76d 100644 --- a/digest/src/core_api/xof_reader.rs +++ b/digest/src/core_api/xof_reader.rs @@ -1,8 +1,7 @@ use super::{AlgorithmName, XofReaderCore}; use crate::XofReader; -use block_buffer::EagerBuffer; +use block_buffer::ReadBuffer; use core::fmt; -use crypto_common::typenum::{IsLess, Le, NonZero, U256}; /// Wrapper around [`XofReaderCore`] implementations. /// @@ -11,18 +10,14 @@ use crypto_common::typenum::{IsLess, Le, NonZero, U256}; pub struct XofReaderCoreWrapper where T: XofReaderCore, - T::BlockSize: IsLess, - Le: NonZero, { pub(super) core: T, - pub(super) buffer: EagerBuffer, + pub(super) buffer: ReadBuffer, } impl fmt::Debug for XofReaderCoreWrapper where T: XofReaderCore + AlgorithmName, - T::BlockSize: IsLess, - Le: NonZero, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { T::write_alg_name(f)?; @@ -33,17 +28,11 @@ where impl XofReader for XofReaderCoreWrapper where T: XofReaderCore, - T::BlockSize: IsLess, - Le: NonZero, { #[inline] fn read(&mut self, buffer: &mut [u8]) { let Self { core, buffer: buf } = self; - buf.set_data(buffer, |blocks| { - for block in blocks { - *block = core.read_block(); - } - }); + buf.read(buffer, |block| *block = core.read_block()); } } @@ -52,8 +41,6 @@ where impl std::io::Read for XofReaderCoreWrapper where T: XofReaderCore, - T::BlockSize: IsLess, - Le: NonZero, { #[inline] fn read(&mut self, buf: &mut [u8]) -> std::io::Result { diff --git a/digest/src/dev/mac.rs b/digest/src/dev/mac.rs index 0d4a37dfc..18f985471 100644 --- a/digest/src/dev/mac.rs +++ b/digest/src/dev/mac.rs @@ -17,10 +17,10 @@ macro_rules! new_mac_test { fn $name() { use core::cmp::min; use digest::dev::blobby::Blob3Iterator; - use digest::Mac; + use digest::{KeyInit, Mac}; fn run_test(key: &[u8], input: &[u8], tag: &[u8]) -> Option<&'static str> { - let mac0 = <$mac as Mac>::new_from_slice(key).unwrap(); + let mac0 = <$mac as KeyInit>::new_from_slice(key).unwrap(); let mut mac = mac0.clone(); mac.update(input); @@ -92,10 +92,10 @@ macro_rules! new_resettable_mac_test { fn $name() { use core::cmp::min; use digest::dev::blobby::Blob3Iterator; - use digest::Mac; + use digest::{KeyInit, Mac}; fn run_test(key: &[u8], input: &[u8], tag: &[u8]) -> Option<&'static str> { - let mac0 = <$mac as Mac>::new_from_slice(key).unwrap(); + let mac0 = <$mac as KeyInit>::new_from_slice(key).unwrap(); let mut mac = mac0.clone(); mac.update(input); diff --git a/digest/src/mac.rs b/digest/src/mac.rs index 1c31359ea..9e91b8ef7 100644 --- a/digest/src/mac.rs +++ b/digest/src/mac.rs @@ -1,8 +1,6 @@ use crate::{FixedOutput, FixedOutputReset, Update}; -use crypto_common::{InvalidLength, Key, KeyInit, Output, OutputSizeUser, Reset}; +use crypto_common::{Output, OutputSizeUser, Reset}; -#[cfg(feature = "rand_core")] -use crate::rand_core::{CryptoRng, RngCore}; use core::fmt; use crypto_common::typenum::Unsigned; use subtle::{Choice, ConstantTimeEq}; @@ -13,27 +11,10 @@ pub trait MacMarker {} /// Convenience wrapper trait covering functionality of Message Authentication algorithms. /// -/// This trait wraps [`KeyInit`], [`Update`], [`FixedOutput`], and [`MacMarker`] -/// traits and provides additional convenience methods. +/// This trait wraps [`Update`], [`FixedOutput`], and [`MacMarker`] traits +/// and provides additional convenience methods. #[cfg_attr(docsrs, doc(cfg(feature = "mac")))] pub trait Mac: OutputSizeUser + Sized { - /// Create new value from fixed size key. - fn new(key: &Key) -> Self - where - Self: KeyInit; - - /// Generate random key using the provided [`CryptoRng`]. - #[cfg(feature = "rand_core")] - #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] - fn generate_key(rng: impl CryptoRng + RngCore) -> Key - where - Self: KeyInit; - - /// Create new value from variable size key. - fn new_from_slice(key: &[u8]) -> Result - where - Self: KeyInit; - /// Update state using the provided data. fn update(&mut self, data: &[u8]); @@ -95,22 +76,6 @@ pub trait Mac: OutputSizeUser + Sized { } impl Mac for T { - #[inline(always)] - fn new(key: &Key) -> Self - where - Self: KeyInit, - { - KeyInit::new(key) - } - - #[inline(always)] - fn new_from_slice(key: &[u8]) -> Result - where - Self: KeyInit, - { - KeyInit::new_from_slice(key) - } - #[inline] fn update(&mut self, data: &[u8]) { Update::update(self, data); @@ -223,16 +188,6 @@ impl Mac for T { Err(MacError) } } - - #[cfg(feature = "rand_core")] - #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] - #[inline] - fn generate_key(rng: impl CryptoRng + RngCore) -> Key - where - Self: KeyInit, - { - ::generate_key(rng) - } } /// Fixed size output value which provides a safe [`Eq`] implementation that From b1af9a9baecb1648401f8fcb09cca41d259a6655 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Mon, 26 Dec 2022 22:10:53 +0100 Subject: [PATCH 0913/1461] Implement serde for `NonZeroScalar` (#1178) --- elliptic-curve/src/scalar/nonzero.rs | 39 +++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/elliptic-curve/src/scalar/nonzero.rs b/elliptic-curve/src/scalar/nonzero.rs index 5f901d581..547bc1fff 100644 --- a/elliptic-curve/src/scalar/nonzero.rs +++ b/elliptic-curve/src/scalar/nonzero.rs @@ -4,8 +4,7 @@ use crate::{ bigint::Encoding as _, ops::{Invert, Reduce, ReduceNonZero}, rand_core::{CryptoRng, RngCore}, - Curve, Error, FieldBytes, IsHigh, PrimeCurve, Result, Scalar, ScalarArithmetic, ScalarCore, - SecretKey, + Curve, Error, FieldBytes, IsHigh, PrimeCurve, Scalar, ScalarArithmetic, ScalarCore, SecretKey, }; use base16ct::HexDisplay; use core::{ @@ -19,6 +18,9 @@ use generic_array::GenericArray; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; use zeroize::Zeroize; +#[cfg(feature = "serde")] +use serdect::serde::{de, ser, Deserialize, Serialize}; + /// Non-zero scalar type. /// /// This type ensures that its value is not zero, ala `core::num::NonZero*`. @@ -260,7 +262,7 @@ where { type Error = Error; - fn try_from(bytes: &[u8]) -> Result { + fn try_from(bytes: &[u8]) -> Result { if bytes.len() == C::UInt::BYTE_SIZE { Option::from(NonZeroScalar::from_repr(GenericArray::clone_from_slice( bytes, @@ -319,7 +321,7 @@ where { type Err = Error; - fn from_str(hex: &str) -> Result { + fn from_str(hex: &str) -> Result { let mut bytes = FieldBytes::::default(); if base16ct::mixed::decode(hex, &mut bytes)?.len() == bytes.len() { @@ -330,6 +332,35 @@ where } } +#[cfg(feature = "serde")] +#[cfg_attr(docsrs, doc(cfg(feature = "serde")))] +impl Serialize for NonZeroScalar +where + C: Curve + ScalarArithmetic, +{ + fn serialize(&self, serializer: S) -> Result + where + S: ser::Serializer, + { + ScalarCore::from(self).serialize(serializer) + } +} + +#[cfg(feature = "serde")] +#[cfg_attr(docsrs, doc(cfg(feature = "serde")))] +impl<'de, C> Deserialize<'de> for NonZeroScalar +where + C: Curve + ScalarArithmetic, +{ + fn deserialize(deserializer: D) -> Result + where + D: de::Deserializer<'de>, + { + Option::from(Self::new(ScalarCore::deserialize(deserializer)?.into())) + .ok_or_else(|| de::Error::custom("expected non-zero scalar")) + } +} + #[cfg(all(test, feature = "dev"))] mod tests { use crate::dev::{NonZeroScalar, Scalar}; From 59490b50e88c252d179087072c1559303f8c5872 Mon Sep 17 00:00:00 2001 From: Corey Shupe Date: Thu, 29 Dec 2022 15:39:15 -0500 Subject: [PATCH 0914/1461] cipher: remove unnecessary block initialization in AsyncStreamCipher (#1179) --- cipher/src/stream.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cipher/src/stream.rs b/cipher/src/stream.rs index 735f2c867..3ac454e6d 100644 --- a/cipher/src/stream.rs +++ b/cipher/src/stream.rs @@ -17,9 +17,9 @@ pub trait AsyncStreamCipher: Sized { { let (blocks, mut tail) = data.into_chunks(); self.encrypt_blocks_inout_mut(blocks); - let mut block = Block::::default(); let n = tail.len(); if n != 0 { + let mut block = Block::::default(); block[..n].copy_from_slice(tail.get_in()); self.encrypt_block_mut(&mut block); tail.get_out().copy_from_slice(&block[..n]); @@ -33,9 +33,9 @@ pub trait AsyncStreamCipher: Sized { { let (blocks, mut tail) = data.into_chunks(); self.decrypt_blocks_inout_mut(blocks); - let mut block = Block::::default(); let n = tail.len(); if n != 0 { + let mut block = Block::::default(); block[..n].copy_from_slice(tail.get_in()); self.decrypt_block_mut(&mut block); tail.get_out().copy_from_slice(&block[..n]); From b0f2c1f49b12eb94201738664c6ea9d09efbcc0d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 30 Dec 2022 11:38:18 -0700 Subject: [PATCH 0915/1461] signature: remove `Error` bound on `SignatureEncoding` (#1180) Previously it mandated the use of `signature::Error` as the associated `Error` type for `TryFrom<&'a [u8]>`. This isn't strictly necessary though. Downstream impls should be able to use their own error type. It's also inconsistent with the `TryInto` bounds, which allow any error type. --- signature/src/encoding.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/signature/src/encoding.rs b/signature/src/encoding.rs index 1d82c826b..1f6010fd4 100644 --- a/signature/src/encoding.rs +++ b/signature/src/encoding.rs @@ -1,13 +1,11 @@ //! Encoding support. -use crate::Error; - #[cfg(feature = "alloc")] use alloc::vec::Vec; /// Support for decoding/encoding signatures as bytes. pub trait SignatureEncoding: - Clone + Sized + for<'a> TryFrom<&'a [u8], Error = Error> + TryInto + Clone + Sized + for<'a> TryFrom<&'a [u8]> + TryInto { /// Byte representation of a signature. type Repr: 'static + AsRef<[u8]> + Clone + Send + Sync; From 1f99a0a9d3c0dac1d2d91b1c8241011d847fbf65 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Tue, 3 Jan 2023 16:54:52 +0100 Subject: [PATCH 0916/1461] Implement `NonIdentity` (#1176) --- elliptic-curve/src/dev.rs | 73 +++++++++- elliptic-curve/src/lib.rs | 5 + elliptic-curve/src/non_identity.rs | 205 +++++++++++++++++++++++++++++ elliptic-curve/src/public_key.rs | 25 +++- 4 files changed, 300 insertions(+), 8 deletions(-) create mode 100644 elliptic-curve/src/non_identity.rs diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index f7205e52c..405dbedaa 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -9,7 +9,7 @@ use crate::{ ops::{LinearCombination, Reduce}, pkcs8, rand_core::RngCore, - sec1::{FromEncodedPoint, ToEncodedPoint}, + sec1::{CompressedPoint, FromEncodedPoint, ToEncodedPoint}, subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}, zeroize::DefaultIsZeroes, AffineArithmetic, AffineXCoordinate, Curve, IsHigh, PrimeCurve, ProjectiveArithmetic, @@ -392,8 +392,15 @@ impl AffineXCoordinate for AffinePoint { } impl ConstantTimeEq for AffinePoint { - fn ct_eq(&self, _other: &Self) -> Choice { - unimplemented!(); + fn ct_eq(&self, other: &Self) -> Choice { + match (self, other) { + (Self::FixedBaseOutput(scalar), Self::FixedBaseOutput(other_scalar)) => { + scalar.ct_eq(other_scalar) + } + (Self::Identity, Self::Identity) | (Self::Generator, Self::Generator) => 1.into(), + (Self::Other(point), Self::Other(other_point)) => u8::from(point == other_point).into(), + _ => 0.into(), + } } } @@ -473,14 +480,25 @@ pub enum ProjectivePoint { } impl ConstantTimeEq for ProjectivePoint { - fn ct_eq(&self, _other: &Self) -> Choice { - unimplemented!(); + fn ct_eq(&self, other: &Self) -> Choice { + match (self, other) { + (Self::FixedBaseOutput(scalar), Self::FixedBaseOutput(other_scalar)) => { + scalar.ct_eq(other_scalar) + } + (Self::Identity, Self::Identity) | (Self::Generator, Self::Generator) => 1.into(), + (Self::Other(point), Self::Other(other_point)) => point.ct_eq(other_point), + _ => 0.into(), + } } } impl ConditionallySelectable for ProjectivePoint { - fn conditional_select(_a: &Self, _b: &Self, _choice: Choice) -> Self { - unimplemented!(); + fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { + if choice.into() { + *b + } else { + *a + } } } @@ -546,6 +564,47 @@ impl group::Group for ProjectivePoint { } } +impl group::GroupEncoding for AffinePoint { + type Repr = CompressedPoint; + + fn from_bytes(bytes: &Self::Repr) -> CtOption { + EncodedPoint::from_bytes(bytes) + .map(|point| CtOption::new(point, Choice::from(1))) + .unwrap_or_else(|_| { + let is_identity = bytes.ct_eq(&Self::Repr::default()); + CtOption::new(EncodedPoint::identity(), is_identity) + }) + .and_then(|point| Self::from_encoded_point(&point)) + } + + fn from_bytes_unchecked(bytes: &Self::Repr) -> CtOption { + Self::from_bytes(bytes) + } + + fn to_bytes(&self) -> Self::Repr { + let encoded = self.to_encoded_point(true); + let mut result = CompressedPoint::::default(); + result[..encoded.len()].copy_from_slice(encoded.as_bytes()); + result + } +} + +impl group::GroupEncoding for ProjectivePoint { + type Repr = CompressedPoint; + + fn from_bytes(bytes: &Self::Repr) -> CtOption { + ::from_bytes(bytes).map(Into::into) + } + + fn from_bytes_unchecked(bytes: &Self::Repr) -> CtOption { + Self::from_bytes(bytes) + } + + fn to_bytes(&self) -> Self::Repr { + group::Curve::to_affine(self).to_bytes() + } +} + impl group::Curve for ProjectivePoint { type AffineRepr = AffinePoint; diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 2f9481206..ffd30b6e4 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -80,6 +80,10 @@ pub mod ecdh; #[cfg_attr(docsrs, doc(cfg(feature = "hash2curve")))] pub mod hash2curve; +#[cfg(feature = "arithmetic")] +#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] +pub mod non_identity; + #[cfg(feature = "sec1")] #[cfg_attr(docsrs, doc(cfg(feature = "sec1")))] pub mod sec1; @@ -121,6 +125,7 @@ pub use { arithmetic::{ AffineArithmetic, PrimeCurveArithmetic, ProjectiveArithmetic, ScalarArithmetic, }, + non_identity::NonIdentity, public_key::PublicKey, scalar::{nonzero::NonZeroScalar, Scalar}, }, diff --git a/elliptic-curve/src/non_identity.rs b/elliptic-curve/src/non_identity.rs new file mode 100644 index 000000000..ec2342903 --- /dev/null +++ b/elliptic-curve/src/non_identity.rs @@ -0,0 +1,205 @@ +//! Non-identity point type. + +use core::ops::Deref; + +use group::{prime::PrimeCurveAffine, Curve, GroupEncoding}; +use rand_core::{CryptoRng, RngCore}; +use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; + +#[cfg(feature = "serde")] +use serdect::serde::{de, ser, Deserialize, Serialize}; + +/// Non-identity point type. +/// +/// This type ensures that its value is not the identity point, ala `core::num::NonZero*`. +/// +/// In the context of ECC, it's useful for ensuring that certain arithmetic +/// cannot result in the identity point. +#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] +#[derive(Clone, Copy)] +pub struct NonIdentity

{ + point: P, +} + +impl

NonIdentity

+where + P: ConditionallySelectable + ConstantTimeEq + Default + GroupEncoding, +{ + /// Create a [`NonIdentity`] from a point. + pub fn new(point: P) -> CtOption { + CtOption::new(Self { point }, !point.ct_eq(&P::default())) + } + + /// Decode a [`NonIdentity`] from its encoding. + pub fn from_repr(repr: &P::Repr) -> CtOption { + Self::from_bytes(repr) + } +} + +impl NonIdentity

{ + /// Return wrapped point. + pub fn to_point(&self) -> P { + self.point + } +} + +impl

NonIdentity

+where + P: ConditionallySelectable + ConstantTimeEq + Curve + Default + GroupEncoding, +{ + /// Generate a random `NonIdentity`. + pub fn random(mut rng: impl CryptoRng + RngCore) -> Self { + loop { + if let Some(point) = Self::new(P::random(&mut rng)).into() { + break point; + } + } + } + + /// Converts this element into its affine representation. + pub fn to_affine(&self) -> NonIdentity { + NonIdentity { + point: self.point.to_affine(), + } + } +} + +impl

NonIdentity

+where + P: PrimeCurveAffine, +{ + /// Converts this element to its curve representation. + pub fn to_curve(&self) -> NonIdentity { + NonIdentity { + point: self.point.to_curve(), + } + } +} + +impl

AsRef

for NonIdentity

{ + fn as_ref(&self) -> &P { + &self.point + } +} + +impl

ConditionallySelectable for NonIdentity

+where + P: ConditionallySelectable, +{ + fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { + Self { + point: P::conditional_select(&a.point, &b.point, choice), + } + } +} + +impl

ConstantTimeEq for NonIdentity

+where + P: ConstantTimeEq, +{ + fn ct_eq(&self, other: &Self) -> Choice { + self.point.ct_eq(&other.point) + } +} + +impl

Deref for NonIdentity

{ + type Target = P; + + fn deref(&self) -> &Self::Target { + &self.point + } +} + +impl

GroupEncoding for NonIdentity

+where + P: ConditionallySelectable + ConstantTimeEq + Default + GroupEncoding, +{ + type Repr = P::Repr; + + fn from_bytes(bytes: &Self::Repr) -> CtOption { + let point = P::from_bytes(bytes); + point.and_then(|point| CtOption::new(Self { point }, !point.ct_eq(&P::default()))) + } + + fn from_bytes_unchecked(bytes: &Self::Repr) -> CtOption { + P::from_bytes_unchecked(bytes).map(|point| Self { point }) + } + + fn to_bytes(&self) -> Self::Repr { + self.point.to_bytes() + } +} + +#[cfg(feature = "serde")] +#[cfg_attr(docsrs, doc(cfg(feature = "serde")))] +impl

Serialize for NonIdentity

+where + P: Serialize, +{ + fn serialize(&self, serializer: S) -> Result + where + S: ser::Serializer, + { + self.point.serialize(serializer) + } +} + +#[cfg(feature = "serde")] +#[cfg_attr(docsrs, doc(cfg(feature = "serde")))] +impl<'de, P> Deserialize<'de> for NonIdentity

+where + P: ConditionallySelectable + ConstantTimeEq + Default + Deserialize<'de> + GroupEncoding, +{ + fn deserialize(deserializer: D) -> Result + where + D: de::Deserializer<'de>, + { + Option::from(Self::new(P::deserialize(deserializer)?)) + .ok_or_else(|| de::Error::custom("expected non-identity point")) + } +} + +#[cfg(all(test, feature = "dev"))] +mod tests { + use crate::{ + dev::{AffinePoint, ProjectivePoint}, + NonIdentity, + }; + use group::GroupEncoding; + use hex_literal::hex; + + #[test] + fn new_success() { + let point = ProjectivePoint::from_bytes( + &hex!("02c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721").into(), + ) + .unwrap(); + + assert!(bool::from(NonIdentity::new(point).is_some())); + + assert!(bool::from( + NonIdentity::new(AffinePoint::from(point)).is_some() + )); + } + + #[test] + fn new_fail() { + assert!(bool::from( + NonIdentity::new(ProjectivePoint::default()).is_none() + )); + assert!(bool::from( + NonIdentity::new(AffinePoint::default()).is_none() + )); + } + + #[test] + fn round_trip() { + let bytes = hex!("02c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721"); + let point = NonIdentity::::from_repr(&bytes.into()).unwrap(); + assert_eq!(&bytes, point.to_bytes().as_slice()); + + let bytes = hex!("02c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721"); + let point = NonIdentity::::from_repr(&bytes.into()).unwrap(); + assert_eq!(&bytes, point.to_bytes().as_slice()); + } +} diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index f5ca8887b..e77eb2931 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -1,7 +1,8 @@ //! Elliptic curve public keys. use crate::{ - AffinePoint, Curve, Error, NonZeroScalar, ProjectiveArithmetic, ProjectivePoint, Result, + AffinePoint, Curve, Error, NonIdentity, NonZeroScalar, ProjectiveArithmetic, ProjectivePoint, + Result, }; use core::fmt::Debug; use group::{Curve as _, Group}; @@ -271,6 +272,28 @@ where } } +impl From> for PublicKey +where + C: Curve + ProjectiveArithmetic, + P: Copy + Into>, +{ + fn from(value: NonIdentity

) -> Self { + PublicKey::from(&value) + } +} + +impl From<&NonIdentity

> for PublicKey +where + C: Curve + ProjectiveArithmetic, + P: Copy + Into>, +{ + fn from(value: &NonIdentity

) -> Self { + Self { + point: value.to_point().into(), + } + } +} + #[cfg(feature = "sec1")] #[cfg_attr(docsrs, doc(cfg(feature = "sec1")))] impl PartialOrd for PublicKey From 4fca56364dcc74c8f1b21178592d38209f167381 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 4 Jan 2023 13:04:40 -0700 Subject: [PATCH 0917/1461] signature v2.0.0-rc.0 (#1181) --- Cargo.lock | 6 +++--- crypto/Cargo.toml | 2 +- signature/Cargo.toml | 2 +- signature/async/Cargo.toml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3a3838ce0..36d7f1f92 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -53,7 +53,7 @@ name = "async-signature" version = "0.3.0-pre" dependencies = [ "async-trait", - "signature 2.0.0-pre.3", + "signature 2.0.0-rc.0", ] [[package]] @@ -267,7 +267,7 @@ dependencies = [ "digest 0.10.6", "elliptic-curve 0.12.3", "password-hash", - "signature 2.0.0-pre.3", + "signature 2.0.0-rc.0", "universal-hash 0.5.0", ] @@ -1092,7 +1092,7 @@ dependencies = [ [[package]] name = "signature" -version = "2.0.0-pre.3" +version = "2.0.0-rc.0" dependencies = [ "digest 0.10.6", "hex-literal", diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index c533bc075..50f9d8a20 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -23,7 +23,7 @@ cipher = { version = "0.4", optional = true } digest = { version = "0.10", optional = true, features = ["mac"] } elliptic-curve = { version = "0.12", optional = true } # TODO(tarcieri): path = "../elliptic-curve" password-hash = { version = "0.4", optional = true, path = "../password-hash" } -signature = { version = "=2.0.0-pre.3", optional = true, default-features = false, path = "../signature" } +signature = { version = "=2.0.0-rc.0", optional = true, default-features = false, path = "../signature" } universal-hash = { version = "0.5", optional = true, path = "../universal-hash" } [features] diff --git a/signature/Cargo.toml b/signature/Cargo.toml index ba5765da6..cd3ba569b 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "2.0.0-pre.3" +version = "2.0.0-rc.0" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/signature" diff --git a/signature/async/Cargo.toml b/signature/async/Cargo.toml index 8783af2ae..e405983e8 100644 --- a/signature/async/Cargo.toml +++ b/signature/async/Cargo.toml @@ -14,7 +14,7 @@ rust-version = "1.56" [dependencies] async-trait = "0.1.9" -signature = { version = "=2.0.0-pre.3", path = ".." } +signature = { version = "=2.0.0-rc.0", path = ".." } [features] digest = ["signature/digest-preview"] From 5671cb69238028604b3f447da1ffa3f9530d065f Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 6 Jan 2023 14:29:01 -0700 Subject: [PATCH 0918/1461] Revert "signature: use `R: CryptoRngCore + ?Sized` (#1167)" (#1183) This reverts commit b12237e540df00cdd2949cf8f3d996fb1d766a1c. As further discussed in #1148, passing a trait object to `&mut impl CryptoRngCore` is possible by mutably borrowing it, and upstream changes to `CryptoRng` should eliminate the requirement for the `?Sized` bound. --- signature/src/hazmat.rs | 4 ++-- signature/src/signer.rs | 17 +++++------------ 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/signature/src/hazmat.rs b/signature/src/hazmat.rs index c7b188efd..3233033c0 100644 --- a/signature/src/hazmat.rs +++ b/signature/src/hazmat.rs @@ -48,9 +48,9 @@ pub trait RandomizedPrehashSigner { /// /// Allowed lengths are algorithm-dependent and up to a particular /// implementation to decide. - fn sign_prehash_with_rng( + fn sign_prehash_with_rng( &self, - rng: &mut R, + rng: &mut impl CryptoRngCore, prehash: &[u8], ) -> Result; } diff --git a/signature/src/signer.rs b/signature/src/signer.rs index de77f08c0..be3de2ec5 100644 --- a/signature/src/signer.rs +++ b/signature/src/signer.rs @@ -87,7 +87,7 @@ pub trait DigestSigner { #[cfg_attr(docsrs, doc(cfg(feature = "rand-preview")))] pub trait RandomizedSigner { /// Sign the given message and return a digital signature - fn sign_with_rng(&self, rng: &mut R, msg: &[u8]) -> S { + fn sign_with_rng(&self, rng: &mut impl CryptoRngCore, msg: &[u8]) -> S { self.try_sign_with_rng(rng, msg) .expect("signature operation failed") } @@ -97,11 +97,7 @@ pub trait RandomizedSigner { /// /// The main intended use case for signing errors is when communicating /// with external signers, e.g. cloud KMS, HSMs, or other hardware tokens. - fn try_sign_with_rng( - &self, - rng: &mut R, - msg: &[u8], - ) -> Result; + fn try_sign_with_rng(&self, rng: &mut impl CryptoRngCore, msg: &[u8]) -> Result; } /// Combination of [`DigestSigner`] and [`RandomizedSigner`] with support for @@ -113,16 +109,13 @@ pub trait RandomizedDigestSigner { /// Sign the given prehashed message `Digest`, returning a signature. /// /// Panics in the event of a signing error. - fn sign_digest_with_rng(&self, rng: &mut R, digest: D) -> S { + fn sign_digest_with_rng(&self, rng: &mut impl CryptoRngCore, digest: D) -> S { self.try_sign_digest_with_rng(rng, digest) .expect("signature operation failed") } /// Attempt to sign the given prehashed message `Digest`, returning a /// digital signature on success, or an error if something went wrong. - fn try_sign_digest_with_rng( - &self, - rng: &mut R, - digest: D, - ) -> Result; + fn try_sign_digest_with_rng(&self, rng: &mut impl CryptoRngCore, digest: D) + -> Result; } From 1d04c33c820ecc58bd7f13f898038515e3e323cc Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 7 Jan 2023 15:12:48 -0700 Subject: [PATCH 0919/1461] signature v2.0.0-rc.1 (#1185) --- Cargo.lock | 6 +++--- crypto/Cargo.toml | 2 +- signature/Cargo.toml | 2 +- signature/async/Cargo.toml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 36d7f1f92..0a934ab17 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -53,7 +53,7 @@ name = "async-signature" version = "0.3.0-pre" dependencies = [ "async-trait", - "signature 2.0.0-rc.0", + "signature 2.0.0-rc.1", ] [[package]] @@ -267,7 +267,7 @@ dependencies = [ "digest 0.10.6", "elliptic-curve 0.12.3", "password-hash", - "signature 2.0.0-rc.0", + "signature 2.0.0-rc.1", "universal-hash 0.5.0", ] @@ -1092,7 +1092,7 @@ dependencies = [ [[package]] name = "signature" -version = "2.0.0-rc.0" +version = "2.0.0-rc.1" dependencies = [ "digest 0.10.6", "hex-literal", diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 50f9d8a20..753374165 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -23,7 +23,7 @@ cipher = { version = "0.4", optional = true } digest = { version = "0.10", optional = true, features = ["mac"] } elliptic-curve = { version = "0.12", optional = true } # TODO(tarcieri): path = "../elliptic-curve" password-hash = { version = "0.4", optional = true, path = "../password-hash" } -signature = { version = "=2.0.0-rc.0", optional = true, default-features = false, path = "../signature" } +signature = { version = "=2.0.0-rc.1", optional = true, default-features = false, path = "../signature" } universal-hash = { version = "0.5", optional = true, path = "../universal-hash" } [features] diff --git a/signature/Cargo.toml b/signature/Cargo.toml index cd3ba569b..f81072509 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "2.0.0-rc.0" +version = "2.0.0-rc.1" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/signature" diff --git a/signature/async/Cargo.toml b/signature/async/Cargo.toml index e405983e8..99073901f 100644 --- a/signature/async/Cargo.toml +++ b/signature/async/Cargo.toml @@ -14,7 +14,7 @@ rust-version = "1.56" [dependencies] async-trait = "0.1.9" -signature = { version = "=2.0.0-rc.0", path = ".." } +signature = { version = "=2.0.0-rc.1", path = ".." } [features] digest = ["signature/digest-preview"] From cc8641c664ad7514a2384c3d1776531291f07797 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 8 Jan 2023 17:02:03 -0700 Subject: [PATCH 0920/1461] elliptic-curve: move `NonIdentity` under `point` (#1186) Reflects that the type represents a non-identity curve point --- elliptic-curve/src/lib.rs | 5 ----- elliptic-curve/src/point.rs | 7 +++++++ elliptic-curve/src/{ => point}/non_identity.rs | 12 +++++------- elliptic-curve/src/public_key.rs | 4 ++-- 4 files changed, 14 insertions(+), 14 deletions(-) rename elliptic-curve/src/{ => point}/non_identity.rs (95%) diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index ffd30b6e4..2f9481206 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -80,10 +80,6 @@ pub mod ecdh; #[cfg_attr(docsrs, doc(cfg(feature = "hash2curve")))] pub mod hash2curve; -#[cfg(feature = "arithmetic")] -#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] -pub mod non_identity; - #[cfg(feature = "sec1")] #[cfg_attr(docsrs, doc(cfg(feature = "sec1")))] pub mod sec1; @@ -125,7 +121,6 @@ pub use { arithmetic::{ AffineArithmetic, PrimeCurveArithmetic, ProjectiveArithmetic, ScalarArithmetic, }, - non_identity::NonIdentity, public_key::PublicKey, scalar::{nonzero::NonZeroScalar, Scalar}, }, diff --git a/elliptic-curve/src/point.rs b/elliptic-curve/src/point.rs index 7257be66c..5d76481a6 100644 --- a/elliptic-curve/src/point.rs +++ b/elliptic-curve/src/point.rs @@ -1,5 +1,12 @@ //! Traits for elliptic curve points. +#[cfg(feature = "arithmetic")] +#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] +mod non_identity; + +#[cfg(feature = "arithmetic")] +pub use self::non_identity::NonIdentity; + use crate::{Curve, FieldBytes}; use subtle::{Choice, CtOption}; diff --git a/elliptic-curve/src/non_identity.rs b/elliptic-curve/src/point/non_identity.rs similarity index 95% rename from elliptic-curve/src/non_identity.rs rename to elliptic-curve/src/point/non_identity.rs index ec2342903..200f909cd 100644 --- a/elliptic-curve/src/non_identity.rs +++ b/elliptic-curve/src/point/non_identity.rs @@ -38,7 +38,7 @@ where impl NonIdentity

{ /// Return wrapped point. - pub fn to_point(&self) -> P { + pub fn to_point(self) -> P { self.point } } @@ -57,7 +57,7 @@ where } /// Converts this element into its affine representation. - pub fn to_affine(&self) -> NonIdentity { + pub fn to_affine(self) -> NonIdentity { NonIdentity { point: self.point.to_affine(), } @@ -69,7 +69,7 @@ where P: PrimeCurveAffine, { /// Converts this element to its curve representation. - pub fn to_curve(&self) -> NonIdentity { + pub fn to_curve(self) -> NonIdentity { NonIdentity { point: self.point.to_curve(), } @@ -161,10 +161,8 @@ where #[cfg(all(test, feature = "dev"))] mod tests { - use crate::{ - dev::{AffinePoint, ProjectivePoint}, - NonIdentity, - }; + use super::NonIdentity; + use crate::dev::{AffinePoint, ProjectivePoint}; use group::GroupEncoding; use hex_literal::hex; diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index e77eb2931..28b0232ae 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -1,8 +1,8 @@ //! Elliptic curve public keys. use crate::{ - AffinePoint, Curve, Error, NonIdentity, NonZeroScalar, ProjectiveArithmetic, ProjectivePoint, - Result, + point::NonIdentity, AffinePoint, Curve, Error, NonZeroScalar, ProjectiveArithmetic, + ProjectivePoint, Result, }; use core::fmt::Debug; use group::{Curve as _, Group}; From 18871f760e54b227549279d855de657e928cd08d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 8 Jan 2023 18:57:37 -0700 Subject: [PATCH 0921/1461] password-hash: use `Salt` type with `PasswordHasher` (#1187) Previously `PasswordHash::hash_password` and `PasswordHash::generate` took `&str` for `Salt`, however this is a bit of a confusing API because the first thing it does is attempt to convert to a `Salt` which upholds several invariants including "B64" encoding. This change makes the `Salt` parameter explicit so it's clear what type is responsible for checking those invariants. --- Cargo.lock | 4 ++-- crypto/Cargo.toml | 4 ++-- password-hash/Cargo.toml | 2 +- password-hash/src/lib.rs | 2 +- password-hash/src/traits.rs | 17 ++++++----------- password-hash/tests/hashing.rs | 4 ++-- 6 files changed, 14 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0a934ab17..8c9931b70 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -265,7 +265,7 @@ dependencies = [ "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "crypto-common 0.1.6", "digest 0.10.6", - "elliptic-curve 0.12.3", + "elliptic-curve 0.13.0-pre", "password-hash", "signature 2.0.0-rc.1", "universal-hash 0.5.0", @@ -777,7 +777,7 @@ dependencies = [ [[package]] name = "password-hash" -version = "0.4.2" +version = "0.5.0-pre" dependencies = [ "base64ct", "rand_core 0.6.4", diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 753374165..1bef3c71d 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -21,8 +21,8 @@ crypto-common = { version = "0.1", default-features = false } aead = { version = "0.5", optional = true, path = "../aead" } cipher = { version = "0.4", optional = true } digest = { version = "0.10", optional = true, features = ["mac"] } -elliptic-curve = { version = "0.12", optional = true } # TODO(tarcieri): path = "../elliptic-curve" -password-hash = { version = "0.4", optional = true, path = "../password-hash" } +elliptic-curve = { version = "=0.13.0-pre", optional = true, path = "../elliptic-curve" } +password-hash = { version = "=0.5.0-pre", optional = true, path = "../password-hash" } signature = { version = "=2.0.0-rc.1", optional = true, default-features = false, path = "../signature" } universal-hash = { version = "0.5", optional = true, path = "../universal-hash" } diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index 9a0cc299d..a056eb6dc 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -5,7 +5,7 @@ Traits which describe the functionality of password hashing algorithms, as well as a `no_std`-friendly implementation of the PHC string format (a well-defined subset of the Modular Crypt Format a.k.a. MCF) """ -version = "0.4.2" +version = "0.5.0-pre" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index f451fb0a8..fda38c994 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -203,7 +203,7 @@ impl<'a> PasswordHash<'a> { pub fn generate( phf: impl PasswordHasher, password: impl AsRef<[u8]>, - salt: &'a str, + salt: impl Into>, ) -> Result { phf.hash_password(password.as_ref(), salt) } diff --git a/password-hash/src/traits.rs b/password-hash/src/traits.rs index 61e04adda..4c9952e90 100644 --- a/password-hash/src/traits.rs +++ b/password-hash/src/traits.rs @@ -30,17 +30,12 @@ pub trait PasswordHasher { /// salt value. /// /// Uses the default recommended parameters for a given algorithm. - fn hash_password<'a, S>(&self, password: &[u8], salt: &'a S) -> Result> - where - S: AsRef + ?Sized, - { - self.hash_password_customized( - password, - None, - None, - Self::Params::default(), - Salt::try_from(salt.as_ref())?, - ) + fn hash_password<'a>( + &self, + password: &[u8], + salt: impl Into>, + ) -> Result> { + self.hash_password_customized(password, None, None, Self::Params::default(), salt) } } diff --git a/password-hash/tests/hashing.rs b/password-hash/tests/hashing.rs index ef30c71ac..73378440a 100644 --- a/password-hash/tests/hashing.rs +++ b/password-hash/tests/hashing.rs @@ -68,12 +68,12 @@ impl<'a> TryFrom for ParamsString { #[test] fn verify_password_hash() { let valid_password = "test password"; - let salt = "test-salt"; + let salt = Salt::new("test-salt").unwrap(); let hash = PasswordHash::generate(StubPasswordHasher, valid_password, salt).unwrap(); // Sanity tests for StubFunction impl above assert_eq!(hash.algorithm, ALG); - assert_eq!(hash.salt.unwrap().as_str(), salt); + assert_eq!(hash.salt.unwrap(), salt); // Tests for generic password verification logic assert_eq!( From da3fb4cc69e978867dbdc5b578c6ca1565a33cdb Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 8 Jan 2023 19:13:20 -0700 Subject: [PATCH 0922/1461] password-hash v0.5.0-pre.0 (#1188) --- Cargo.lock | 2 +- crypto/Cargo.toml | 2 +- password-hash/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8c9931b70..69be79f67 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -777,7 +777,7 @@ dependencies = [ [[package]] name = "password-hash" -version = "0.5.0-pre" +version = "0.5.0-pre.0" dependencies = [ "base64ct", "rand_core 0.6.4", diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 1bef3c71d..ad0f49ea6 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -22,7 +22,7 @@ aead = { version = "0.5", optional = true, path = "../aead" } cipher = { version = "0.4", optional = true } digest = { version = "0.10", optional = true, features = ["mac"] } elliptic-curve = { version = "=0.13.0-pre", optional = true, path = "../elliptic-curve" } -password-hash = { version = "=0.5.0-pre", optional = true, path = "../password-hash" } +password-hash = { version = "=0.5.0-pre.0", optional = true, path = "../password-hash" } signature = { version = "=2.0.0-rc.1", optional = true, default-features = false, path = "../signature" } universal-hash = { version = "0.5", optional = true, path = "../universal-hash" } diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index a056eb6dc..5cc5dbd30 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -5,7 +5,7 @@ Traits which describe the functionality of password hashing algorithms, as well as a `no_std`-friendly implementation of the PHC string format (a well-defined subset of the Modular Crypt Format a.k.a. MCF) """ -version = "0.5.0-pre" +version = "0.5.0-pre.0" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" From e1c4d9d22eef5c94b65ca20541f2686d692b0eed Mon Sep 17 00:00:00 2001 From: daxpedda Date: Mon, 9 Jan 2023 17:37:40 +0100 Subject: [PATCH 0923/1461] password-hash: add `Error::OutputSize` (#1026) --- password-hash/src/errors.rs | 54 +++++++++++++++++++++++++------------ password-hash/src/lib.rs | 8 +++--- password-hash/src/output.rs | 34 ++++++++++++++++++----- 3 files changed, 69 insertions(+), 27 deletions(-) diff --git a/password-hash/src/errors.rs b/password-hash/src/errors.rs index 48ff66b0b..f4719af31 100644 --- a/password-hash/src/errors.rs +++ b/password-hash/src/errors.rs @@ -2,6 +2,7 @@ pub use base64ct::Error as B64Error; +use core::cmp::Ordering; use core::fmt; /// Result type. @@ -20,11 +21,21 @@ pub enum Error { /// Cryptographic error. Crypto, - /// Output too short (min 10-bytes). - OutputTooShort, - - /// Output too long (max 64-bytes). - OutputTooLong, + /// Output size unexpected. + OutputSize { + /// Indicates why the output size is unexpected. + /// + /// - [`Ordering::Less`]: Size is too small. + /// - [`Ordering::Equal`]: Size is not exactly as `expected`. + /// - [`Ordering::Greater`]: Size is too long. + provided: Ordering, + /// Expected output size in relation to `provided`. + /// + /// - [`Ordering::Less`]: Minimum size. + /// - [`Ordering::Equal`]: Expecrted size. + /// - [`Ordering::Greater`]: Maximum size. + expected: usize, + }, /// Duplicate parameter name encountered. ParamNameDuplicated, @@ -41,14 +52,11 @@ pub enum Error { /// Invalid password. Password, - /// Password hash string contains invalid characters. - PhcStringInvalid, - - /// Password hash string too short. - PhcStringTooShort, + /// Password hash string invalid. + PhcStringField, - /// Password hash string too long. - PhcStringTooLong, + /// Password hash string contains trailing data. + PhcStringTrailingData, /// Salt invalid. SaltInvalid(InvalidValue), @@ -63,16 +71,28 @@ impl fmt::Display for Error { Self::Algorithm => write!(f, "unsupported algorithm"), Self::B64Encoding(err) => write!(f, "{}", err), Self::Crypto => write!(f, "cryptographic error"), - Self::OutputTooShort => f.write_str("PHF output too short (min 10-bytes)"), - Self::OutputTooLong => f.write_str("PHF output too long (max 64-bytes)"), + Self::OutputSize { provided, expected } => match provided { + Ordering::Less => write!( + f, + "output size too short, expected at least {} bytes", + expected + ), + Ordering::Equal => write!(f, "output size unexpected, expected {} bytes", expected), + Ordering::Greater => write!( + f, + "output size too long, expected at most {} bytes", + expected + ), + }, Self::ParamNameDuplicated => f.write_str("duplicate parameter"), Self::ParamNameInvalid => f.write_str("invalid parameter name"), Self::ParamValueInvalid(val_err) => write!(f, "invalid parameter value: {}", val_err), Self::ParamsMaxExceeded => f.write_str("maximum number of parameters reached"), Self::Password => write!(f, "invalid password"), - Self::PhcStringInvalid => write!(f, "password hash string invalid"), - Self::PhcStringTooShort => write!(f, "password hash string too short"), - Self::PhcStringTooLong => write!(f, "password hash string too long"), + Self::PhcStringField => write!(f, "password hash string missing field"), + Self::PhcStringTrailingData => { + write!(f, "password hash string contains trailing characters") + } Self::SaltInvalid(val_err) => write!(f, "salt invalid: {}", val_err), Self::Version => write!(f, "invalid algorithm version"), } diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index fda38c994..54c139d89 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -132,19 +132,19 @@ impl<'a> PasswordHash<'a> { /// Parse a password hash from the given [`Encoding`]. pub fn parse(s: &'a str, encoding: Encoding) -> Result { if s.is_empty() { - return Err(Error::PhcStringTooShort); + return Err(Error::PhcStringField); } let mut fields = s.split(PASSWORD_HASH_SEPARATOR); let beginning = fields.next().expect("no first field"); if beginning.chars().next().is_some() { - return Err(Error::PhcStringInvalid); + return Err(Error::PhcStringField); } let algorithm = fields .next() - .ok_or(Error::PhcStringTooShort) + .ok_or(Error::PhcStringField) .and_then(Ident::try_from)?; let mut version = None; @@ -187,7 +187,7 @@ impl<'a> PasswordHash<'a> { } if fields.next().is_some() { - return Err(Error::PhcStringTooLong); + return Err(Error::PhcStringTrailingData); } Ok(Self { diff --git a/password-hash/src/output.rs b/password-hash/src/output.rs index c2560ce12..d988b55d8 100644 --- a/password-hash/src/output.rs +++ b/password-hash/src/output.rs @@ -1,7 +1,11 @@ //! Outputs from password hashing functions. use crate::{Encoding, Error, Result}; -use core::{cmp::PartialEq, fmt, str::FromStr}; +use core::{ + cmp::{Ordering, PartialEq}, + fmt, + str::FromStr, +}; use subtle::{Choice, ConstantTimeEq}; /// Output from password hashing functions, i.e. the "hash" or "digest" @@ -149,11 +153,17 @@ impl Output { F: FnOnce(&mut [u8]) -> Result<()>, { if output_size < Self::MIN_LENGTH { - return Err(Error::OutputTooShort); + return Err(Error::OutputSize { + provided: Ordering::Less, + expected: Self::MIN_LENGTH, + }); } if output_size > Self::MAX_LENGTH { - return Err(Error::OutputTooLong); + return Err(Error::OutputSize { + provided: Ordering::Greater, + expected: Self::MAX_LENGTH, + }); } let mut bytes = [0u8; Self::MAX_LENGTH]; @@ -266,7 +276,7 @@ impl fmt::Debug for Output { #[cfg(test)] mod tests { - use super::{Error, Output}; + use super::{Error, Ordering, Output}; #[test] fn new_with_valid_min_length_input() { @@ -286,14 +296,26 @@ mod tests { fn reject_new_too_short() { let bytes = [9u8; 9]; let err = Output::new(&bytes).err().unwrap(); - assert_eq!(err, Error::OutputTooShort); + assert_eq!( + err, + Error::OutputSize { + provided: Ordering::Less, + expected: Output::MIN_LENGTH + } + ); } #[test] fn reject_new_too_long() { let bytes = [65u8; 65]; let err = Output::new(&bytes).err().unwrap(); - assert_eq!(err, Error::OutputTooLong); + assert_eq!( + err, + Error::OutputSize { + provided: Ordering::Greater, + expected: Output::MAX_LENGTH + } + ); } #[test] From 8041325e945884a1c7e7888bd3a1232b6361a080 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 13 Jan 2023 17:06:58 -0700 Subject: [PATCH 0924/1461] elliptic-curve: bump `crypto-bigint` to v0.5.0-pre.1; MSRV 1.61 (#1190) This also moves `elliptic-curve` out of the toplevel workspace since `crypto-bigint` now uses namespaced features, which are incompatible with older crates. --- .github/workflows/elliptic-curve.yml | 8 +- Cargo.lock | 154 +-------------------------- Cargo.toml | 4 +- crypto/Cargo.toml | 2 +- elliptic-curve/Cargo.toml | 4 +- elliptic-curve/README.md | 4 +- elliptic-curve/src/dev.rs | 2 +- elliptic-curve/src/scalar/core.rs | 4 +- elliptic-curve/src/scalar/nonzero.rs | 3 +- elliptic-curve/src/secret_key.rs | 4 +- 10 files changed, 20 insertions(+), 169 deletions(-) diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index b8991acb3..68a40e9ab 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -23,7 +23,7 @@ jobs: strategy: matrix: rust: - - 1.57.0 # MSRV + - 1.61.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -58,8 +58,8 @@ jobs: - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features pem,pkcs8,sec1 - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,digest,ecdh,hazmat,hash2curve,jwk,pem,pkcs8,sec1,serde,voprf - # TODO: use the reusable workflow after this crate will be part of the - # toot workspace + # TODO: use the reusable workflow after this crate is re-added to the + # toplevel workspace # minimal-versions: # runs-on: ubuntu-latest # steps: @@ -79,7 +79,7 @@ jobs: strategy: matrix: rust: - - 1.57.0 # MSRV + - 1.61.0 # MSRV - stable - nightly steps: diff --git a/Cargo.lock b/Cargo.lock index 69be79f67..b83a06492 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -103,18 +103,6 @@ dependencies = [ "serde", ] -[[package]] -name = "bitvec" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" -dependencies = [ - "funty", - "radium", - "tap", - "wyz", -] - [[package]] name = "blobby" version = "0.3.1" @@ -265,7 +253,7 @@ dependencies = [ "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "crypto-common 0.1.6", "digest 0.10.6", - "elliptic-curve 0.13.0-pre", + "elliptic-curve 0.12.3", "password-hash", "signature 2.0.0-rc.1", "universal-hash 0.5.0", @@ -374,7 +362,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" dependencies = [ "const-oid 0.9.1", - "pem-rfc7468 0.6.0", "zeroize", ] @@ -463,32 +450,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "elliptic-curve" -version = "0.13.0-pre" -dependencies = [ - "base16ct", - "base64ct", - "crypto-bigint 0.4.9", - "der 0.6.1", - "digest 0.10.6", - "ff 0.13.0", - "generic-array", - "group 0.13.0", - "hex-literal", - "hkdf 0.12.3", - "pem-rfc7468 0.6.0", - "pkcs8 0.9.0", - "rand_core 0.6.4", - "sec1", - "serde_json", - "serdect", - "sha2 0.10.6", - "sha3", - "subtle", - "zeroize", -] - [[package]] name = "ff" version = "0.10.1" @@ -509,23 +470,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "ff" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" -dependencies = [ - "bitvec", - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "funty" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" - [[package]] name = "generic-array" version = "0.14.6" @@ -585,17 +529,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "group" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" -dependencies = [ - "ff 0.13.0", - "rand_core 0.6.4", - "subtle", -] - [[package]] name = "hash32" version = "0.2.1" @@ -694,12 +627,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "itoa" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440" - [[package]] name = "jobserver" version = "0.1.25" @@ -709,15 +636,6 @@ dependencies = [ "libc", ] -[[package]] -name = "keccak" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3afef3b6eff9ce9d8ff9b3601125eec7f0c8cbac7abd14f355d053fa56c98768" -dependencies = [ - "cpufeatures", -] - [[package]] name = "kem" version = "0.2.0" @@ -793,15 +711,6 @@ dependencies = [ "base64ct", ] -[[package]] -name = "pem-rfc7468" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d159833a9105500e0398934e205e0773f0b27529557134ecfc51c27646adac" -dependencies = [ - "base64ct", -] - [[package]] name = "pkcs8" version = "0.7.6" @@ -809,7 +718,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee3ef9b64d26bad0536099c816c6734379e45bbd5f14798def6809e5cc350447" dependencies = [ "der 0.4.5", - "pem-rfc7468 0.2.3", + "pem-rfc7468", "spki 0.4.1", "zeroize", ] @@ -912,12 +821,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "radium" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" - [[package]] name = "rand" version = "0.8.5" @@ -963,12 +866,6 @@ dependencies = [ "semver", ] -[[package]] -name = "ryu" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" - [[package]] name = "scopeguard" version = "1.1.0" @@ -985,7 +882,6 @@ dependencies = [ "der 0.6.1", "generic-array", "pkcs8 0.9.0", - "serdect", "subtle", "zeroize", ] @@ -1025,27 +921,6 @@ dependencies = [ "syn", ] -[[package]] -name = "serde_json" -version = "1.0.91" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "serdect" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038fce1bf4d74b9b30ea7dcd59df75ba8ec669a5dcb3cc64fbfcef7334ced32c" -dependencies = [ - "base16ct", - "serde", -] - [[package]] name = "sha2" version = "0.9.9" @@ -1070,16 +945,6 @@ dependencies = [ "digest 0.10.6", ] -[[package]] -name = "sha3" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdf0c33fae925bdc080598b84bc15c55e7b9a4a43b3c704da051f977469691c9" -dependencies = [ - "digest 0.10.6", - "keccak", -] - [[package]] name = "signature" version = "1.3.2" @@ -1173,12 +1038,6 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "tap" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" - [[package]] name = "typenum" version = "1.16.0" @@ -1227,15 +1086,6 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" -[[package]] -name = "wyz" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" -dependencies = [ - "tap", -] - [[package]] name = "x25519-dalek" version = "2.0.0-pre.1" diff --git a/Cargo.toml b/Cargo.toml index dc7d95785..16f91e046 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,9 +6,11 @@ members = [ "crypto", "crypto-common", "digest", - "elliptic-curve", "kem", "signature", "signature/async", "universal-hash", ] +exclude = [ + "elliptic-curve" # re-add when all crates are MSRV 1.60+ +] diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index ad0f49ea6..daef44770 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -21,7 +21,7 @@ crypto-common = { version = "0.1", default-features = false } aead = { version = "0.5", optional = true, path = "../aead" } cipher = { version = "0.4", optional = true } digest = { version = "0.10", optional = true, features = ["mac"] } -elliptic-curve = { version = "=0.13.0-pre", optional = true, path = "../elliptic-curve" } +elliptic-curve = { version = "0.12", optional = true } # path = "../elliptic-curve" password-hash = { version = "=0.5.0-pre.0", optional = true, path = "../password-hash" } signature = { version = "=2.0.0-rc.1", optional = true, default-features = false, path = "../signature" } universal-hash = { version = "0.5", optional = true, path = "../universal-hash" } diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 00378302f..d5f02813b 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -13,11 +13,11 @@ readme = "README.md" categories = ["cryptography", "no-std"] keywords = ["crypto", "ecc", "elliptic", "weierstrass"] edition = "2021" -rust-version = "1.57" +rust-version = "1.61" [dependencies] base16ct = "0.1.1" -crypto-bigint = { version = "0.4.9", default-features = false, features = ["rand_core", "generic-array", "zeroize"] } +crypto-bigint = { version = "=0.5.0-pre.1", default-features = false, features = ["rand_core", "generic-array", "zeroize"] } der = { version = "0.6", default-features = false, features = ["oid"] } generic-array = { version = "0.14", default-features = false } rand_core = { version = "0.6", default-features = false } diff --git a/elliptic-curve/README.md b/elliptic-curve/README.md index 254a99433..e30b8503a 100644 --- a/elliptic-curve/README.md +++ b/elliptic-curve/README.md @@ -15,7 +15,7 @@ and public/secret keys composed thereof. ## Minimum Supported Rust Version -Requires Rust **1.57** or higher. +Requires Rust **1.61** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -49,6 +49,6 @@ dual licensed as above, without any additional terms or conditions. [build-image]: https://github.com/RustCrypto/traits/actions/workflows/elliptic-curve.yml/badge.svg [build-link]: https://github.com/RustCrypto/traits/actions/workflows/elliptic-curve.yml [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.57+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.61+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260040-elliptic-curves diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 405dbedaa..ee02aa009 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -333,7 +333,7 @@ impl<'a> Product<&'a Scalar> for Scalar { impl Reduce for Scalar { fn from_uint_reduced(w: U256) -> Self { let (r, underflow) = w.sbb(&MockCurve::ORDER, Limb::ZERO); - let underflow = Choice::from((underflow.0 >> (Limb::BIT_SIZE - 1)) as u8); + let underflow = Choice::from((underflow.0 >> (Limb::BITS - 1)) as u8); let reduced = U256::conditional_select(&w, &r, !underflow); Self(ScalarCore::new(reduced).unwrap()) } diff --git a/elliptic-curve/src/scalar/core.rs b/elliptic-curve/src/scalar/core.rs index 6a088ca55..9e0721314 100644 --- a/elliptic-curve/src/scalar/core.rs +++ b/elliptic-curve/src/scalar/core.rs @@ -85,7 +85,7 @@ where /// Decode [`ScalarCore`] from a big endian byte slice. pub fn from_be_slice(slice: &[u8]) -> Result { - if slice.len() == C::UInt::BYTE_SIZE { + if slice.len() == C::UInt::BYTES { Option::from(Self::from_be_bytes(GenericArray::clone_from_slice(slice))).ok_or(Error) } else { Err(Error) @@ -99,7 +99,7 @@ where /// Decode [`ScalarCore`] from a little endian byte slice. pub fn from_le_slice(slice: &[u8]) -> Result { - if slice.len() == C::UInt::BYTE_SIZE { + if slice.len() == C::UInt::BYTES { Option::from(Self::from_le_bytes(GenericArray::clone_from_slice(slice))).ok_or(Error) } else { Err(Error) diff --git a/elliptic-curve/src/scalar/nonzero.rs b/elliptic-curve/src/scalar/nonzero.rs index 547bc1fff..03ce82145 100644 --- a/elliptic-curve/src/scalar/nonzero.rs +++ b/elliptic-curve/src/scalar/nonzero.rs @@ -1,7 +1,6 @@ //! Non-zero scalar type. use crate::{ - bigint::Encoding as _, ops::{Invert, Reduce, ReduceNonZero}, rand_core::{CryptoRng, RngCore}, Curve, Error, FieldBytes, IsHigh, PrimeCurve, Scalar, ScalarArithmetic, ScalarCore, SecretKey, @@ -263,7 +262,7 @@ where type Error = Error; fn try_from(bytes: &[u8]) -> Result { - if bytes.len() == C::UInt::BYTE_SIZE { + if bytes.len() == C::UInt::BYTES { Option::from(NonZeroScalar::from_repr(GenericArray::clone_from_slice( bytes, ))) diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 0fc3dafb1..a6d26068b 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -10,7 +10,7 @@ mod pkcs8; use crate::{Curve, Error, FieldBytes, Result, ScalarCore}; use core::fmt::{self, Debug}; -use crypto_bigint::Encoding; +use crypto_bigint::Integer; use generic_array::GenericArray; use subtle::{Choice, ConstantTimeEq}; use zeroize::{Zeroize, ZeroizeOnDrop}; @@ -146,7 +146,7 @@ where /// Deserialize raw secret scalar as a big endian integer. pub fn from_be_bytes(bytes: &[u8]) -> Result { - if bytes.len() != C::UInt::BYTE_SIZE { + if bytes.len() != C::UInt::BYTES { return Err(Error); } From 675c27c1cbf7644e44fabc0534a9a8c7c8af66b4 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 13 Jan 2023 17:26:32 -0700 Subject: [PATCH 0925/1461] elliptic-curve: rename `Curve::UInt` => `Curve::Uint` (#1191) From https://rust-lang.github.io/api-guidelines/naming.html > In UpperCamelCase, acronyms and contractions of compound words count > as one word: use Uuid rather than UUID, Usize rather than USize or > Stdin rather than StdIn. Based on the `Usize` example, it's pretty clear we should be using `Uint` rather than `UInt`. This is also consistent with `crypto-bigint`: https://github.com/RustCrypto/crypto-bigint/pull/143 --- elliptic-curve/src/arithmetic.rs | 2 +- elliptic-curve/src/dev.rs | 2 +- elliptic-curve/src/lib.rs | 12 +++++------ elliptic-curve/src/ops.rs | 20 +++++++++---------- elliptic-curve/src/scalar/core.rs | 30 ++++++++++++++-------------- elliptic-curve/src/scalar/nonzero.rs | 6 +++--- elliptic-curve/src/secret_key.rs | 2 +- 7 files changed, 37 insertions(+), 37 deletions(-) diff --git a/elliptic-curve/src/arithmetic.rs b/elliptic-curve/src/arithmetic.rs index fa445f1bc..6da4a7c41 100644 --- a/elliptic-curve/src/arithmetic.rs +++ b/elliptic-curve/src/arithmetic.rs @@ -80,7 +80,7 @@ pub trait ScalarArithmetic: Curve { type Scalar: DefaultIsZeroes + From> + Into> - + Into + + Into + IsHigh + ff::Field + ff::PrimeField>; diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index ee02aa009..d6e115fbf 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -65,7 +65,7 @@ pub type ScalarBits = crate::ScalarBits; pub struct MockCurve; impl Curve for MockCurve { - type UInt = U256; + type Uint = U256; const ORDER: U256 = U256::from_be_hex("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551"); diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 2f9481206..cc29c66a6 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -159,30 +159,30 @@ pub const ALGORITHM_OID: pkcs8::ObjectIdentifier = /// curves (e.g. [`SecretKey`]). pub trait Curve: 'static + Copy + Clone + Debug + Default + Eq + Ord + Send + Sync { /// Integer type used to represent field elements of this elliptic curve. - // TODO(tarcieri): replace this with an e.g. `const Curve::MODULUS: UInt`. + // TODO(tarcieri): replace this with an e.g. `const Curve::MODULUS: Uint`. // Requires rust-lang/rust#60551, i.e. `const_evaluatable_checked` - type UInt: bigint::AddMod + type Uint: bigint::AddMod + bigint::ArrayEncoding + bigint::Encoding + bigint::Integer - + bigint::NegMod + + bigint::NegMod + bigint::Random + bigint::RandomMod - + bigint::SubMod + + bigint::SubMod + zeroize::Zeroize; /// Order constant. /// /// Subdivided into either 32-bit or 64-bit "limbs" (depending on the /// target CPU's word size), specified from least to most significant. - const ORDER: Self::UInt; + const ORDER: Self::Uint; } /// Marker trait for elliptic curves with prime order. pub trait PrimeCurve: Curve {} /// Size of field elements of this elliptic curve. -pub type FieldSize = <::UInt as bigint::ArrayEncoding>::ByteSize; +pub type FieldSize = <::Uint as bigint::ArrayEncoding>::ByteSize; /// Byte representation of a base/scalar field element of a given curve. pub type FieldBytes = GenericArray>; diff --git a/elliptic-curve/src/ops.rs b/elliptic-curve/src/ops.rs index 580c5aefc..2cdfa7cf4 100644 --- a/elliptic-curve/src/ops.rs +++ b/elliptic-curve/src/ops.rs @@ -44,20 +44,20 @@ pub trait LinearCombination: Group { } /// Modular reduction. -pub trait Reduce: Sized { +pub trait Reduce: Sized { /// Perform a modular reduction, returning a field element. - fn from_uint_reduced(n: UInt) -> Self; + fn from_uint_reduced(n: Uint) -> Self; /// Interpret the given byte array as a big endian integer and perform /// a modular reduction. - fn from_be_bytes_reduced(bytes: ByteArray) -> Self { - Self::from_uint_reduced(UInt::from_be_byte_array(bytes)) + fn from_be_bytes_reduced(bytes: ByteArray) -> Self { + Self::from_uint_reduced(Uint::from_be_byte_array(bytes)) } /// Interpret the given byte array as a little endian integer and perform a /// modular reduction. - fn from_le_bytes_reduced(bytes: ByteArray) -> Self { - Self::from_uint_reduced(UInt::from_le_byte_array(bytes)) + fn from_le_bytes_reduced(bytes: ByteArray) -> Self { + Self::from_uint_reduced(Uint::from_le_byte_array(bytes)) } /// Interpret a digest as a big endian integer and perform a modular @@ -66,7 +66,7 @@ pub trait Reduce: Sized { #[cfg_attr(docsrs, doc(cfg(feature = "digest")))] fn from_be_digest_reduced(digest: D) -> Self where - D: FixedOutput, + D: FixedOutput, { Self::from_be_bytes_reduced(digest.finalize_fixed()) } @@ -77,7 +77,7 @@ pub trait Reduce: Sized { #[cfg_attr(docsrs, doc(cfg(feature = "digest")))] fn from_le_digest_reduced(digest: D) -> Self where - D: FixedOutput, + D: FixedOutput, { Self::from_le_bytes_reduced(digest.finalize_fixed()) } @@ -90,7 +90,7 @@ pub trait Reduce: Sized { /// /// End users should use the [`Reduce`] impl on /// [`NonZeroScalar`][`crate::NonZeroScalar`] instead. -pub trait ReduceNonZero: Sized { +pub trait ReduceNonZero: Sized { /// Perform a modular reduction, returning a field element. - fn from_uint_reduced_nonzero(n: UInt) -> Self; + fn from_uint_reduced_nonzero(n: Uint) -> Self; } diff --git a/elliptic-curve/src/scalar/core.rs b/elliptic-curve/src/scalar/core.rs index 9e0721314..4f8e650ca 100644 --- a/elliptic-curve/src/scalar/core.rs +++ b/elliptic-curve/src/scalar/core.rs @@ -46,7 +46,7 @@ use serdect::serde::{de, ser, Deserialize, Serialize}; #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub struct ScalarCore { /// Inner unsigned integer type. - inner: C::UInt, + inner: C::Uint, } impl ScalarCore @@ -55,37 +55,37 @@ where { /// Zero scalar. pub const ZERO: Self = Self { - inner: C::UInt::ZERO, + inner: C::Uint::ZERO, }; /// Multiplicative identity. pub const ONE: Self = Self { - inner: C::UInt::ONE, + inner: C::Uint::ONE, }; /// Scalar modulus. - pub const MODULUS: C::UInt = C::ORDER; + pub const MODULUS: C::Uint = C::ORDER; /// Generate a random [`ScalarCore`]. pub fn random(rng: impl CryptoRng + RngCore) -> Self { Self { - inner: C::UInt::random_mod(rng, &NonZero::new(Self::MODULUS).unwrap()), + inner: C::Uint::random_mod(rng, &NonZero::new(Self::MODULUS).unwrap()), } } - /// Create a new scalar from [`Curve::UInt`]. - pub fn new(uint: C::UInt) -> CtOption { + /// Create a new scalar from [`Curve::Uint`]. + pub fn new(uint: C::Uint) -> CtOption { CtOption::new(Self { inner: uint }, uint.ct_lt(&Self::MODULUS)) } /// Decode [`ScalarCore`] from big endian bytes. pub fn from_be_bytes(bytes: FieldBytes) -> CtOption { - Self::new(C::UInt::from_be_byte_array(bytes)) + Self::new(C::Uint::from_be_byte_array(bytes)) } /// Decode [`ScalarCore`] from a big endian byte slice. pub fn from_be_slice(slice: &[u8]) -> Result { - if slice.len() == C::UInt::BYTES { + if slice.len() == C::Uint::BYTES { Option::from(Self::from_be_bytes(GenericArray::clone_from_slice(slice))).ok_or(Error) } else { Err(Error) @@ -94,20 +94,20 @@ where /// Decode [`ScalarCore`] from little endian bytes. pub fn from_le_bytes(bytes: FieldBytes) -> CtOption { - Self::new(C::UInt::from_le_byte_array(bytes)) + Self::new(C::Uint::from_le_byte_array(bytes)) } /// Decode [`ScalarCore`] from a little endian byte slice. pub fn from_le_slice(slice: &[u8]) -> Result { - if slice.len() == C::UInt::BYTES { + if slice.len() == C::Uint::BYTES { Option::from(Self::from_le_bytes(GenericArray::clone_from_slice(slice))).ok_or(Error) } else { Err(Error) } } - /// Borrow the inner `C::UInt`. - pub fn as_uint(&self) -> &C::UInt { + /// Borrow the inner `C::Uint`. + pub fn as_uint(&self) -> &C::Uint { &self.inner } @@ -170,7 +170,7 @@ where { fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { Self { - inner: C::UInt::conditional_select(&a.inner, &b.inner, choice), + inner: C::Uint::conditional_select(&a.inner, &b.inner, choice), } } } @@ -239,7 +239,7 @@ where { fn from(n: u64) -> Self { Self { - inner: C::UInt::from(n), + inner: C::Uint::from(n), } } } diff --git a/elliptic-curve/src/scalar/nonzero.rs b/elliptic-curve/src/scalar/nonzero.rs index 03ce82145..3ee875518 100644 --- a/elliptic-curve/src/scalar/nonzero.rs +++ b/elliptic-curve/src/scalar/nonzero.rs @@ -63,8 +63,8 @@ where Scalar::::from_repr(repr).and_then(Self::new) } - /// Create a [`NonZeroScalar`] from a `C::UInt`. - pub fn from_uint(uint: C::UInt) -> CtOption { + /// Create a [`NonZeroScalar`] from a `C::Uint`. + pub fn from_uint(uint: C::Uint) -> CtOption { ScalarCore::new(uint).and_then(|scalar| Self::new(scalar.into())) } } @@ -262,7 +262,7 @@ where type Error = Error; fn try_from(bytes: &[u8]) -> Result { - if bytes.len() == C::UInt::BYTES { + if bytes.len() == C::Uint::BYTES { Option::from(NonZeroScalar::from_repr(GenericArray::clone_from_slice( bytes, ))) diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index a6d26068b..cf973ce39 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -146,7 +146,7 @@ where /// Deserialize raw secret scalar as a big endian integer. pub fn from_be_bytes(bytes: &[u8]) -> Result { - if bytes.len() != C::UInt::BYTES { + if bytes.len() != C::Uint::BYTES { return Err(Error); } From 43367132dc4b7a340765b1d5c4ca0d20bf7288a1 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 13 Jan 2023 17:38:55 -0700 Subject: [PATCH 0926/1461] elliptic-curve: use weak feature activation (#1192) Activates the `alloc` and `std` features in more dependencies, but only if they're explicitly linked otherwise --- elliptic-curve/Cargo.toml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index d5f02813b..6f3d0cf12 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -44,7 +44,9 @@ sha3 = "0.10" [features] default = ["arithmetic"] -alloc = ["base16ct/alloc", "der/alloc", "sec1/alloc", "zeroize/alloc"] # todo: use weak activation for `group`/`sec1` alloc when available +alloc = ["base16ct/alloc", "der/alloc", "ff?/alloc", "group?/alloc", "sec1?/alloc", "zeroize/alloc"] +std = ["alloc", "rand_core/std", "sec1?/std"] + arithmetic = ["ff", "group"] bits = ["arithmetic", "ff/bits"] dev = ["arithmetic", "hex-literal", "pem", "pkcs8"] @@ -54,7 +56,6 @@ hazmat = [] jwk = ["alloc", "base64ct/alloc", "serde", "serde_json", "zeroize/alloc"] pem = ["alloc", "arithmetic", "der/pem", "pem-rfc7468/alloc", "pkcs8", "sec1/pem"] serde = ["alloc", "pkcs8", "sec1/serde", "serdect"] -std = ["alloc", "rand_core/std", "sec1/std"] voprf = ["digest"] [package.metadata.docs.rs] From 178c7bc8e30302c5a1c2d893c051790da8b64e60 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 13 Jan 2023 18:37:24 -0700 Subject: [PATCH 0927/1461] elliptic-curve: use `doc_auto_cfg` (#1193) Replaces manual `cfg(doc(...))` annotations with `doc_auto_cfg`, which populates them automatically --- elliptic-curve/src/arithmetic.rs | 5 ----- elliptic-curve/src/dev.rs | 1 - elliptic-curve/src/jwk.rs | 18 ------------------ elliptic-curve/src/lib.rs | 20 +------------------- elliptic-curve/src/ops.rs | 3 --- elliptic-curve/src/point.rs | 1 - elliptic-curve/src/point/non_identity.rs | 3 --- elliptic-curve/src/public_key.rs | 18 ------------------ elliptic-curve/src/scalar.rs | 2 -- elliptic-curve/src/scalar/core.rs | 3 --- elliptic-curve/src/scalar/nonzero.rs | 3 --- elliptic-curve/src/secret_key.rs | 19 ------------------- elliptic-curve/src/secret_key/pkcs8.rs | 5 ----- 13 files changed, 1 insertion(+), 100 deletions(-) diff --git a/elliptic-curve/src/arithmetic.rs b/elliptic-curve/src/arithmetic.rs index 6da4a7c41..7dd2f7748 100644 --- a/elliptic-curve/src/arithmetic.rs +++ b/elliptic-curve/src/arithmetic.rs @@ -8,13 +8,11 @@ use subtle::{ConditionallySelectable, ConstantTimeEq}; use zeroize::DefaultIsZeroes; /// Elliptic curve with affine arithmetic implementation. -#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub trait AffineArithmetic: Curve + ScalarArithmetic { /// Elliptic curve point in affine coordinates. type AffinePoint: 'static + AffineXCoordinate + Copy - + Clone + ConditionallySelectable + ConstantTimeEq + Debug @@ -28,7 +26,6 @@ pub trait AffineArithmetic: Curve + ScalarArithmetic { } /// Prime order elliptic curve with projective arithmetic implementation. -#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub trait PrimeCurveArithmetic: PrimeCurve + ProjectiveArithmetic { @@ -37,7 +34,6 @@ pub trait PrimeCurveArithmetic: } /// Elliptic curve with projective arithmetic implementation. -#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub trait ProjectiveArithmetic: Curve + AffineArithmetic { /// Elliptic curve point in projective coordinates. /// @@ -63,7 +59,6 @@ pub trait ProjectiveArithmetic: Curve + AffineArithmetic { /// Scalar arithmetic. #[cfg(feature = "arithmetic")] -#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub trait ScalarArithmetic: Curve { /// Scalar field type. /// diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index d6e115fbf..999ccc3dc 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -91,7 +91,6 @@ impl AssociatedOid for MockCurve { } #[cfg(feature = "jwk")] -#[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] impl JwkParameters for MockCurve { const CRV: &'static str = "P-256"; } diff --git a/elliptic-curve/src/jwk.rs b/elliptic-curve/src/jwk.rs index ff5e6e638..23c3e8845 100644 --- a/elliptic-curve/src/jwk.rs +++ b/elliptic-curve/src/jwk.rs @@ -42,7 +42,6 @@ const JWK_TYPE_NAME: &str = "JwkEcKey"; const FIELDS: &[&str] = &["kty", "crv", "x", "y", "d"]; /// Elliptic curve parameters used by JSON Web Keys. -#[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] pub trait JwkParameters: Curve { /// The `crv` parameter which identifies a particular elliptic curve /// as defined in RFC 7518 Section 6.2.1.1: @@ -64,7 +63,6 @@ pub trait JwkParameters: Curve { /// [1]: https://tools.ietf.org/html/rfc7518#section-6 // TODO(tarcieri): eagerly decode or validate `x`, `y`, and `d` as Base64 #[derive(Clone)] -#[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] pub struct JwkEcKey { /// The `crv` parameter which identifies a particular elliptic curve /// as defined in RFC 7518 Section 6.2.1.1: @@ -110,7 +108,6 @@ impl JwkEcKey { /// Decode a JWK into a [`PublicKey`]. #[cfg(feature = "arithmetic")] - #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub fn to_public_key(&self) -> Result> where C: Curve + JwkParameters + ProjectiveArithmetic, @@ -154,7 +151,6 @@ impl JwkEcKey { /// Decode a JWK into a [`SecretKey`]. #[cfg(feature = "arithmetic")] - #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub fn to_secret_key(&self) -> Result> where C: Curve + JwkParameters + ValidatePublicKey, @@ -178,7 +174,6 @@ impl ToString for JwkEcKey { } } -#[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] impl TryFrom for SecretKey where C: Curve + JwkParameters + ValidatePublicKey, @@ -191,7 +186,6 @@ where } } -#[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] impl TryFrom<&JwkEcKey> for SecretKey where C: Curve + JwkParameters + ValidatePublicKey, @@ -217,8 +211,6 @@ where } #[cfg(feature = "arithmetic")] -#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] -#[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] impl From> for JwkEcKey where C: Curve + JwkParameters + ProjectiveArithmetic, @@ -231,8 +223,6 @@ where } #[cfg(feature = "arithmetic")] -#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] -#[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] impl From<&SecretKey> for JwkEcKey where C: Curve + JwkParameters + ProjectiveArithmetic, @@ -249,8 +239,6 @@ where } #[cfg(feature = "arithmetic")] -#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] -#[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] impl TryFrom for PublicKey where C: Curve + JwkParameters + ProjectiveArithmetic, @@ -265,8 +253,6 @@ where } #[cfg(feature = "arithmetic")] -#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] -#[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] impl TryFrom<&JwkEcKey> for PublicKey where C: Curve + JwkParameters + ProjectiveArithmetic, @@ -281,8 +267,6 @@ where } #[cfg(feature = "arithmetic")] -#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] -#[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] impl From> for JwkEcKey where C: Curve + JwkParameters + ProjectiveArithmetic, @@ -295,8 +279,6 @@ where } #[cfg(feature = "arithmetic")] -#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] -#[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] impl From<&PublicKey> for JwkEcKey where C: Curve + JwkParameters + ProjectiveArithmetic, diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index cc29c66a6..0c7d7cf9f 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -1,5 +1,5 @@ #![no_std] -#![cfg_attr(docsrs, feature(doc_cfg))] +#![cfg_attr(docsrs, feature(doc_auto_cfg))] #![doc = include_str!("../README.md")] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", @@ -58,34 +58,20 @@ #[allow(unused_imports)] #[macro_use] extern crate alloc; - #[cfg(feature = "std")] extern crate std; -#[cfg(feature = "rand_core")] -#[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] -pub use rand_core; - pub mod ops; #[cfg(feature = "dev")] -#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] pub mod dev; - #[cfg(feature = "ecdh")] -#[cfg_attr(docsrs, doc(cfg(feature = "ecdh")))] pub mod ecdh; - #[cfg(feature = "hash2curve")] -#[cfg_attr(docsrs, doc(cfg(feature = "hash2curve")))] pub mod hash2curve; - #[cfg(feature = "sec1")] -#[cfg_attr(docsrs, doc(cfg(feature = "sec1")))] pub mod sec1; - #[cfg(feature = "arithmetic")] -#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub mod weierstrass; mod error; @@ -145,7 +131,6 @@ use generic_array::GenericArray; /// /// #[cfg(feature = "pkcs8")] -#[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))] pub const ALGORITHM_OID: pkcs8::ObjectIdentifier = pkcs8::ObjectIdentifier::new_unwrap("1.2.840.10045.2.1"); @@ -189,19 +174,16 @@ pub type FieldBytes = GenericArray>; /// Affine point type for a given curve with a [`ProjectiveArithmetic`] /// implementation. -#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] #[cfg(feature = "arithmetic")] pub type AffinePoint = ::AffinePoint; /// Projective point type for a given curve with a [`ProjectiveArithmetic`] /// implementation. #[cfg(feature = "arithmetic")] -#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub type ProjectivePoint = ::ProjectivePoint; /// Elliptic curve parameters used by VOPRF. #[cfg(feature = "voprf")] -#[cfg_attr(docsrs, doc(cfg(feature = "voprf")))] pub trait VoprfParameters: Curve { /// The `ID` parameter which identifies a particular elliptic curve /// as defined in [section 4 of `draft-irtf-cfrg-voprf-08`][voprf]. diff --git a/elliptic-curve/src/ops.rs b/elliptic-curve/src/ops.rs index 2cdfa7cf4..769a0173a 100644 --- a/elliptic-curve/src/ops.rs +++ b/elliptic-curve/src/ops.rs @@ -35,7 +35,6 @@ impl Invert for F { /// non-optimized implementation. // TODO(tarcieri): replace this with a trait from the `group` crate? (see zkcrypto/group#25) #[cfg(feature = "arithmetic")] -#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub trait LinearCombination: Group { /// Calculates `x * k + y * l`. fn lincomb(x: &Self, k: &Self::Scalar, y: &Self, l: &Self::Scalar) -> Self { @@ -63,7 +62,6 @@ pub trait Reduce: Sized { /// Interpret a digest as a big endian integer and perform a modular /// reduction. #[cfg(feature = "digest")] - #[cfg_attr(docsrs, doc(cfg(feature = "digest")))] fn from_be_digest_reduced(digest: D) -> Self where D: FixedOutput, @@ -74,7 +72,6 @@ pub trait Reduce: Sized { /// Interpret a digest as a little endian integer and perform a modular /// reduction. #[cfg(feature = "digest")] - #[cfg_attr(docsrs, doc(cfg(feature = "digest")))] fn from_le_digest_reduced(digest: D) -> Self where D: FixedOutput, diff --git a/elliptic-curve/src/point.rs b/elliptic-curve/src/point.rs index 5d76481a6..e05a44848 100644 --- a/elliptic-curve/src/point.rs +++ b/elliptic-curve/src/point.rs @@ -1,7 +1,6 @@ //! Traits for elliptic curve points. #[cfg(feature = "arithmetic")] -#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] mod non_identity; #[cfg(feature = "arithmetic")] diff --git a/elliptic-curve/src/point/non_identity.rs b/elliptic-curve/src/point/non_identity.rs index 200f909cd..075e3a94d 100644 --- a/elliptic-curve/src/point/non_identity.rs +++ b/elliptic-curve/src/point/non_identity.rs @@ -15,7 +15,6 @@ use serdect::serde::{de, ser, Deserialize, Serialize}; /// /// In the context of ECC, it's useful for ensuring that certain arithmetic /// cannot result in the identity point. -#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] #[derive(Clone, Copy)] pub struct NonIdentity

{ point: P, @@ -131,7 +130,6 @@ where } #[cfg(feature = "serde")] -#[cfg_attr(docsrs, doc(cfg(feature = "serde")))] impl

Serialize for NonIdentity

where P: Serialize, @@ -145,7 +143,6 @@ where } #[cfg(feature = "serde")] -#[cfg_attr(docsrs, doc(cfg(feature = "serde")))] impl<'de, P> Deserialize<'de> for NonIdentity

where P: ConditionallySelectable + ConstantTimeEq + Default + Deserialize<'de> + GroupEncoding, diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index 28b0232ae..ade3e9538 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -77,7 +77,6 @@ use alloc::boxed::Box; /// Subject Public Key Info (SPKI) as the encoding format. /// /// For a more text-friendly encoding of public keys, use [`JwkEcKey`] instead. -#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] #[derive(Clone, Debug, Eq, PartialEq)] pub struct PublicKey where @@ -156,7 +155,6 @@ where /// Parse a [`JwkEcKey`] JSON Web Key (JWK) into a [`PublicKey`]. #[cfg(feature = "jwk")] - #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] pub fn from_jwk(jwk: &JwkEcKey) -> Result where C: Curve + JwkParameters, @@ -168,7 +166,6 @@ where /// Parse a string containing a JSON Web Key (JWK) into a [`PublicKey`]. #[cfg(feature = "jwk")] - #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] pub fn from_jwk_str(jwk: &str) -> Result where C: Curve + JwkParameters, @@ -180,7 +177,6 @@ where /// Serialize this public key as [`JwkEcKey`] JSON Web Key (JWK). #[cfg(feature = "jwk")] - #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] pub fn to_jwk(&self) -> JwkEcKey where C: Curve + JwkParameters, @@ -192,7 +188,6 @@ where /// Serialize this public key as JSON Web Key (JWK) string. #[cfg(feature = "jwk")] - #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] pub fn to_jwk_string(&self) -> String where C: Curve + JwkParameters, @@ -215,7 +210,6 @@ where impl Copy for PublicKey where C: Curve + ProjectiveArithmetic {} #[cfg(feature = "sec1")] -#[cfg_attr(docsrs, doc(cfg(feature = "sec1")))] impl FromEncodedPoint for PublicKey where C: Curve + ProjectiveArithmetic, @@ -232,7 +226,6 @@ where } #[cfg(feature = "sec1")] -#[cfg_attr(docsrs, doc(cfg(feature = "sec1")))] impl ToEncodedPoint for PublicKey where C: Curve + ProjectiveArithmetic, @@ -247,7 +240,6 @@ where } #[cfg(feature = "sec1")] -#[cfg_attr(docsrs, doc(cfg(feature = "sec1")))] impl From> for EncodedPoint where C: Curve + ProjectiveArithmetic + PointCompression, @@ -260,7 +252,6 @@ where } #[cfg(feature = "sec1")] -#[cfg_attr(docsrs, doc(cfg(feature = "sec1")))] impl From<&PublicKey> for EncodedPoint where C: Curve + ProjectiveArithmetic + PointCompression, @@ -295,7 +286,6 @@ where } #[cfg(feature = "sec1")] -#[cfg_attr(docsrs, doc(cfg(feature = "sec1")))] impl PartialOrd for PublicKey where C: Curve + ProjectiveArithmetic, @@ -308,7 +298,6 @@ where } #[cfg(feature = "sec1")] -#[cfg_attr(docsrs, doc(cfg(feature = "sec1")))] impl Ord for PublicKey where C: Curve + ProjectiveArithmetic, @@ -324,7 +313,6 @@ where } #[cfg(all(feature = "pkcs8", feature = "sec1"))] -#[cfg_attr(docsrs, doc(cfg(all(feature = "pkcs8", feature = "sec1"))))] impl TryFrom> for PublicKey where C: Curve + AssociatedOid + ProjectiveArithmetic, @@ -341,7 +329,6 @@ where } #[cfg(all(feature = "pkcs8", feature = "sec1"))] -#[cfg_attr(docsrs, doc(cfg(all(feature = "pkcs8", feature = "sec1"))))] impl DecodePublicKey for PublicKey where C: Curve + AssociatedOid + ProjectiveArithmetic, @@ -351,7 +338,6 @@ where } #[cfg(all(feature = "alloc", feature = "pkcs8"))] -#[cfg_attr(docsrs, doc(cfg(all(feature = "alloc", feature = "pkcs8"))))] impl EncodePublicKey for PublicKey where C: Curve + AssociatedOid + ProjectiveArithmetic, @@ -375,7 +361,6 @@ where } #[cfg(feature = "pem")] -#[cfg_attr(docsrs, doc(cfg(feature = "pem")))] impl FromStr for PublicKey where C: Curve + AssociatedOid + ProjectiveArithmetic, @@ -390,7 +375,6 @@ where } #[cfg(feature = "pem")] -#[cfg_attr(docsrs, doc(cfg(feature = "pem")))] impl ToString for PublicKey where C: Curve + AssociatedOid + ProjectiveArithmetic, @@ -404,7 +388,6 @@ where } #[cfg(feature = "serde")] -#[cfg_attr(docsrs, doc(cfg(feature = "serde")))] impl Serialize for PublicKey where C: Curve + AssociatedOid + ProjectiveArithmetic, @@ -421,7 +404,6 @@ where } #[cfg(feature = "serde")] -#[cfg_attr(docsrs, doc(cfg(feature = "serde")))] impl<'de, C> Deserialize<'de> for PublicKey where C: Curve + AssociatedOid + ProjectiveArithmetic, diff --git a/elliptic-curve/src/scalar.rs b/elliptic-curve/src/scalar.rs index 72d796847..0081a97fe 100644 --- a/elliptic-curve/src/scalar.rs +++ b/elliptic-curve/src/scalar.rs @@ -12,12 +12,10 @@ use crate::ScalarArithmetic; /// Scalar field element for a particular elliptic curve. #[cfg(feature = "arithmetic")] -#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub type Scalar = ::Scalar; /// Bit representation of a scalar field element of a given curve. #[cfg(feature = "bits")] -#[cfg_attr(docsrs, doc(cfg(feature = "bits")))] pub type ScalarBits = ff::FieldBits< as ff::PrimeFieldBits>::ReprBits>; /// Is this scalar greater than n / 2? diff --git a/elliptic-curve/src/scalar/core.rs b/elliptic-curve/src/scalar/core.rs index 4f8e650ca..de12685b1 100644 --- a/elliptic-curve/src/scalar/core.rs +++ b/elliptic-curve/src/scalar/core.rs @@ -43,7 +43,6 @@ use serdect::serde::{de, ser, Deserialize, Serialize}; /// textual formats, the binary data is encoded as hexadecimal. // TODO(tarcieri): make this a fully generic `Scalar` type and use it for `ScalarArithmetic` #[derive(Copy, Clone, Debug, Default)] -#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub struct ScalarCore { /// Inner unsigned integer type. inner: C::Uint, @@ -403,7 +402,6 @@ where } #[cfg(feature = "serde")] -#[cfg_attr(docsrs, doc(cfg(feature = "serde")))] impl Serialize for ScalarCore where C: Curve, @@ -417,7 +415,6 @@ where } #[cfg(feature = "serde")] -#[cfg_attr(docsrs, doc(cfg(feature = "serde")))] impl<'de, C> Deserialize<'de> for ScalarCore where C: Curve, diff --git a/elliptic-curve/src/scalar/nonzero.rs b/elliptic-curve/src/scalar/nonzero.rs index 3ee875518..06ef1155c 100644 --- a/elliptic-curve/src/scalar/nonzero.rs +++ b/elliptic-curve/src/scalar/nonzero.rs @@ -28,7 +28,6 @@ use serdect::serde::{de, ser, Deserialize, Serialize}; /// /// In the context of ECC, it's useful for ensuring that scalar multiplication /// cannot result in the point at infinity. -#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] #[derive(Clone)] pub struct NonZeroScalar where @@ -332,7 +331,6 @@ where } #[cfg(feature = "serde")] -#[cfg_attr(docsrs, doc(cfg(feature = "serde")))] impl Serialize for NonZeroScalar where C: Curve + ScalarArithmetic, @@ -346,7 +344,6 @@ where } #[cfg(feature = "serde")] -#[cfg_attr(docsrs, doc(cfg(feature = "serde")))] impl<'de, C> Deserialize<'de> for NonZeroScalar where C: Curve + ScalarArithmetic, diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index cf973ce39..0127f1d34 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -92,7 +92,6 @@ where { /// Generate a random [`SecretKey`]. #[cfg(feature = "arithmetic")] - #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub fn random(rng: impl CryptoRng + RngCore) -> Self where C: ProjectiveArithmetic, @@ -126,7 +125,6 @@ where /// /// Please treat it with the care it deserves! #[cfg(feature = "arithmetic")] - #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub fn to_nonzero_scalar(&self) -> NonZeroScalar where C: Curve + ProjectiveArithmetic, @@ -136,7 +134,6 @@ where /// Get the [`PublicKey`] which corresponds to this secret key #[cfg(feature = "arithmetic")] - #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub fn public_key(&self) -> PublicKey where C: Curve + ProjectiveArithmetic, @@ -169,7 +166,6 @@ where /// Deserialize secret key encoded in the SEC1 ASN.1 DER `ECPrivateKey` format. #[cfg(all(feature = "sec1"))] - #[cfg_attr(docsrs, doc(cfg(feature = "sec1")))] pub fn from_sec1_der(der_bytes: &[u8]) -> Result where C: Curve + ValidatePublicKey, @@ -182,10 +178,6 @@ where /// Serialize secret key in the SEC1 ASN.1 DER `ECPrivateKey` format. #[cfg(all(feature = "alloc", feature = "arithmetic", feature = "sec1"))] - #[cfg_attr( - docsrs, - doc(cfg(all(feature = "alloc", feature = "arithmetic", feature = "sec1"))) - )] pub fn to_sec1_der(&self) -> der::Result>> where C: Curve + ProjectiveArithmetic, @@ -219,7 +211,6 @@ where /// -----BEGIN EC PRIVATE KEY----- /// ``` #[cfg(feature = "pem")] - #[cfg_attr(docsrs, doc(cfg(feature = "pem")))] pub fn from_sec1_pem(s: &str) -> Result where C: Curve + ValidatePublicKey, @@ -239,7 +230,6 @@ where /// /// Pass `Default::default()` to use the OS's native line endings. #[cfg(feature = "pem")] - #[cfg_attr(docsrs, doc(cfg(feature = "pem")))] pub fn to_pem(&self, line_ending: pem::LineEnding) -> Result> where C: Curve + ProjectiveArithmetic, @@ -255,7 +245,6 @@ where /// Parse a [`JwkEcKey`] JSON Web Key (JWK) into a [`SecretKey`]. #[cfg(feature = "jwk")] - #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] pub fn from_jwk(jwk: &JwkEcKey) -> Result where C: JwkParameters + ValidatePublicKey, @@ -266,7 +255,6 @@ where /// Parse a string containing a JSON Web Key (JWK) into a [`SecretKey`]. #[cfg(feature = "jwk")] - #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] pub fn from_jwk_str(jwk: &str) -> Result where C: JwkParameters + ValidatePublicKey, @@ -277,8 +265,6 @@ where /// Serialize this secret key as [`JwkEcKey`] JSON Web Key (JWK). #[cfg(all(feature = "arithmetic", feature = "jwk"))] - #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] - #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] pub fn to_jwk(&self) -> JwkEcKey where C: Curve + JwkParameters + ProjectiveArithmetic, @@ -290,8 +276,6 @@ where /// Serialize this secret key as JSON Web Key (JWK) string. #[cfg(all(feature = "arithmetic", feature = "jwk"))] - #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] - #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] pub fn to_jwk_string(&self) -> Zeroizing where C: Curve + JwkParameters + ProjectiveArithmetic, @@ -344,7 +328,6 @@ where } #[cfg(all(feature = "sec1"))] -#[cfg_attr(docsrs, doc(cfg(feature = "sec1")))] impl TryFrom> for SecretKey where C: Curve + ValidatePublicKey, @@ -371,7 +354,6 @@ where } #[cfg(feature = "arithmetic")] -#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] impl From> for SecretKey where C: Curve + ProjectiveArithmetic, @@ -382,7 +364,6 @@ where } #[cfg(feature = "arithmetic")] -#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] impl From<&NonZeroScalar> for SecretKey where C: Curve + ProjectiveArithmetic, diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs index 3c1a509bf..ad769ca6e 100644 --- a/elliptic-curve/src/secret_key/pkcs8.rs +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -27,7 +27,6 @@ use { core::str::FromStr, }; -#[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))] impl TryFrom> for SecretKey where C: Curve + AssociatedOid + ValidatePublicKey, @@ -45,7 +44,6 @@ where } } -#[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))] impl DecodePrivateKey for SecretKey where C: Curve + AssociatedOid + ValidatePublicKey, @@ -57,8 +55,6 @@ where // It doesn't strictly depend on `pkcs8/pem` but we can't easily activate `pkcs8/alloc` // without adding a separate crate feature just for this functionality. #[cfg(all(feature = "arithmetic", feature = "pem"))] -#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] -#[cfg_attr(docsrs, doc(cfg(feature = "pem")))] impl EncodePrivateKey for SecretKey where C: Curve + AssociatedOid + ProjectiveArithmetic, @@ -78,7 +74,6 @@ where } #[cfg(feature = "pem")] -#[cfg_attr(docsrs, doc(cfg(feature = "pem")))] impl FromStr for SecretKey where C: Curve + AssociatedOid + ValidatePublicKey, From 40dfed8d6cf5019a1682e93c4be538165b482396 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 13 Jan 2023 18:53:44 -0700 Subject: [PATCH 0928/1461] elliptic-curve: fix weak feature activation TODOs (#1194) These TODOs described a way to do a bit more fine-grained feature activation. Now that we've bumped MSRV and can do it, this addresses them. It also uses namespaced feature activation to enable the `sec1` feature when the `pkcs8` feature is enabled. --- .github/workflows/elliptic-curve.yml | 3 +-- elliptic-curve/Cargo.toml | 4 +++- elliptic-curve/src/dev.rs | 2 +- elliptic-curve/src/scalar/core.rs | 2 +- elliptic-curve/src/secret_key/pkcs8.rs | 8 ++------ 5 files changed, 8 insertions(+), 11 deletions(-) diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index 68a40e9ab..c9eee6497 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -52,10 +52,9 @@ jobs: - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features sec1 - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features serde - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features voprf + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,arithmetic,pkcs8 - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,serde - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features arithmetic,serde - - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features pkcs8,sec1 - - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features pem,pkcs8,sec1 - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,digest,ecdh,hazmat,hash2curve,jwk,pem,pkcs8,sec1,serde,voprf # TODO: use the reusable workflow after this crate is re-added to the diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 6f3d0cf12..46e4cc216 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -47,13 +47,15 @@ default = ["arithmetic"] alloc = ["base16ct/alloc", "der/alloc", "ff?/alloc", "group?/alloc", "sec1?/alloc", "zeroize/alloc"] std = ["alloc", "rand_core/std", "sec1?/std"] -arithmetic = ["ff", "group"] +arithmetic = ["group"] bits = ["arithmetic", "ff/bits"] dev = ["arithmetic", "hex-literal", "pem", "pkcs8"] hash2curve = ["arithmetic", "digest"] ecdh = ["arithmetic", "digest", "hkdf"] +group = ["dep:group", "ff"] hazmat = [] jwk = ["alloc", "base64ct/alloc", "serde", "serde_json", "zeroize/alloc"] +pkcs8 = ["dep:pkcs8", "sec1"] pem = ["alloc", "arithmetic", "der/pem", "pem-rfc7468/alloc", "pkcs8", "sec1/pem"] serde = ["alloc", "pkcs8", "sec1/serde", "serdect"] voprf = ["digest"] diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 999ccc3dc..d316d33d1 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -24,7 +24,7 @@ use hex_literal::hex; use pkcs8::AssociatedOid; #[cfg(feature = "bits")] -use crate::group::ff::PrimeFieldBits; +use ff::PrimeFieldBits; #[cfg(feature = "jwk")] use crate::JwkParameters; diff --git a/elliptic-curve/src/scalar/core.rs b/elliptic-curve/src/scalar/core.rs index de12685b1..94fd8bfab 100644 --- a/elliptic-curve/src/scalar/core.rs +++ b/elliptic-curve/src/scalar/core.rs @@ -22,7 +22,7 @@ use zeroize::DefaultIsZeroes; #[cfg(feature = "arithmetic")] use { super::{Scalar, ScalarArithmetic}, - group::ff::PrimeField, + ff::PrimeField, }; #[cfg(feature = "serde")] diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs index ad769ca6e..934cd7d62 100644 --- a/elliptic-curve/src/secret_key/pkcs8.rs +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -10,8 +10,7 @@ use der::Decode; use sec1::EcPrivateKey; // Imports for the `EncodePrivateKey` impl -// TODO(tarcieri): use weak activation of `pkcs8/alloc` for gating `EncodePrivateKey` impl -#[cfg(all(feature = "arithmetic", feature = "pem"))] +#[cfg(all(feature = "alloc", feature = "arithmetic"))] use { crate::{ sec1::{FromEncodedPoint, ToEncodedPoint}, @@ -51,10 +50,7 @@ where { } -// TODO(tarcieri): use weak activation of `pkcs8/alloc` for this when possible -// It doesn't strictly depend on `pkcs8/pem` but we can't easily activate `pkcs8/alloc` -// without adding a separate crate feature just for this functionality. -#[cfg(all(feature = "arithmetic", feature = "pem"))] +#[cfg(all(feature = "alloc", feature = "arithmetic"))] impl EncodePrivateKey for SecretKey where C: Curve + AssociatedOid + ProjectiveArithmetic, From 8c79d51a8b6373d5835d5a0c775c1b664d214119 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 13 Jan 2023 19:16:55 -0700 Subject: [PATCH 0929/1461] elliptic-curve: remove direct `der` crate dependency (#1195) This removes a hard dependency on the `der` crate. With weak feature activation it now becomes possible to pull in the `der` crate transitively via the `pkcs8` and `sec1` crates. --- elliptic-curve/Cargo.toml | 20 +++++++++++++----- elliptic-curve/src/public_key.rs | 29 ++++++++++++++------------ elliptic-curve/src/secret_key.rs | 7 ++++++- elliptic-curve/src/secret_key/pkcs8.rs | 5 ++--- elliptic-curve/tests/pkcs8.rs | 1 + 5 files changed, 40 insertions(+), 22 deletions(-) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 46e4cc216..a9e120a7b 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -18,7 +18,6 @@ rust-version = "1.61" [dependencies] base16ct = "0.1.1" crypto-bigint = { version = "=0.5.0-pre.1", default-features = false, features = ["rand_core", "generic-array", "zeroize"] } -der = { version = "0.6", default-features = false, features = ["oid"] } generic-array = { version = "0.14", default-features = false } rand_core = { version = "0.6", default-features = false } subtle = { version = "2", default-features = false } @@ -44,8 +43,19 @@ sha3 = "0.10" [features] default = ["arithmetic"] -alloc = ["base16ct/alloc", "der/alloc", "ff?/alloc", "group?/alloc", "sec1?/alloc", "zeroize/alloc"] -std = ["alloc", "rand_core/std", "sec1?/std"] +alloc = [ + "base16ct/alloc", + "ff?/alloc", + "group?/alloc", + "pkcs8?/alloc", + "sec1?/alloc", + "zeroize/alloc" +] +std = [ + "alloc", + "rand_core/std", + "sec1?/std" +] arithmetic = ["group"] bits = ["arithmetic", "ff/bits"] @@ -56,8 +66,8 @@ group = ["dep:group", "ff"] hazmat = [] jwk = ["alloc", "base64ct/alloc", "serde", "serde_json", "zeroize/alloc"] pkcs8 = ["dep:pkcs8", "sec1"] -pem = ["alloc", "arithmetic", "der/pem", "pem-rfc7468/alloc", "pkcs8", "sec1/pem"] -serde = ["alloc", "pkcs8", "sec1/serde", "serdect"] +pem = ["alloc", "arithmetic", "pem-rfc7468/alloc", "pkcs8", "sec1/pem"] +serde = ["alloc", "sec1/serde", "serdect"] voprf = ["digest"] [package.metadata.docs.rs] diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index ade3e9538..ef5216613 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -7,15 +7,12 @@ use crate::{ use core::fmt::Debug; use group::{Curve as _, Group}; +#[cfg(feature = "alloc")] +use alloc::boxed::Box; + #[cfg(feature = "jwk")] use crate::{JwkEcKey, JwkParameters}; -#[cfg(all(feature = "sec1", feature = "pkcs8"))] -use crate::{ - pkcs8::{self, AssociatedOid, DecodePublicKey}, - ALGORITHM_OID, -}; - #[cfg(feature = "pem")] use core::str::FromStr; @@ -29,17 +26,23 @@ use { subtle::CtOption, }; -#[cfg(feature = "serde")] -use serdect::serde::{de, ser, Deserialize, Serialize}; - #[cfg(all(feature = "alloc", feature = "pkcs8"))] use pkcs8::EncodePublicKey; #[cfg(any(feature = "jwk", feature = "pem"))] use alloc::string::{String, ToString}; -#[cfg(feature = "alloc")] -use alloc::boxed::Box; +#[cfg(all(feature = "pkcs8", feature = "serde"))] +use serdect::serde::{de, ser, Deserialize, Serialize}; + +#[cfg(all(feature = "sec1", feature = "pkcs8"))] +use { + crate::{ + pkcs8::{self, AssociatedOid, DecodePublicKey}, + ALGORITHM_OID, + }, + pkcs8::der, +}; /// Elliptic curve public keys. /// @@ -387,7 +390,7 @@ where } } -#[cfg(feature = "serde")] +#[cfg(all(feature = "pkcs8", feature = "serde"))] impl Serialize for PublicKey where C: Curve + AssociatedOid + ProjectiveArithmetic, @@ -403,7 +406,7 @@ where } } -#[cfg(feature = "serde")] +#[cfg(all(feature = "pkcs8", feature = "serde"))] impl<'de, C> Deserialize<'de> for PublicKey where C: Curve + AssociatedOid + ProjectiveArithmetic, diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 0127f1d34..fc777ab39 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -22,7 +22,6 @@ use { AffinePoint, }, alloc::vec::Vec, - der::Encode, zeroize::Zeroizing, }; @@ -35,6 +34,12 @@ use crate::{ #[cfg(feature = "jwk")] use crate::jwk::{JwkEcKey, JwkParameters}; +#[cfg(feature = "sec1")] +use sec1::der; + +#[cfg(all(feature = "alloc", feature = "arithmetic", feature = "sec1"))] +use sec1::der::Encode; + #[cfg(all(feature = "arithmetic", any(feature = "jwk", feature = "pem")))] use alloc::string::String; diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs index 934cd7d62..f30832cfd 100644 --- a/elliptic-curve/src/secret_key/pkcs8.rs +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -2,11 +2,10 @@ use super::SecretKey; use crate::{ - pkcs8::{self, AssociatedOid, DecodePrivateKey}, + pkcs8::{self, der::Decode, AssociatedOid, DecodePrivateKey}, sec1::{ModulusSize, ValidatePublicKey}, Curve, FieldSize, ALGORITHM_OID, }; -use der::Decode; use sec1::EcPrivateKey; // Imports for the `EncodePrivateKey` impl @@ -16,7 +15,7 @@ use { sec1::{FromEncodedPoint, ToEncodedPoint}, AffinePoint, ProjectiveArithmetic, }, - pkcs8::EncodePrivateKey, + pkcs8::{der, EncodePrivateKey}, }; // Imports for actual PEM support diff --git a/elliptic-curve/tests/pkcs8.rs b/elliptic-curve/tests/pkcs8.rs index cffb06802..336b3f0ca 100644 --- a/elliptic-curve/tests/pkcs8.rs +++ b/elliptic-curve/tests/pkcs8.rs @@ -8,6 +8,7 @@ use elliptic_curve::{ sec1::ToEncodedPoint, }; use hex_literal::hex; +use pkcs8::der; /// DER-encoded PKCS#8 public key const PKCS8_PUBLIC_KEY_DER: &[u8; 91] = include_bytes!("examples/pkcs8-public-key.der"); From df3f85b4a4fcea7150b4f44662404771fcca4d94 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 13 Jan 2023 20:24:01 -0700 Subject: [PATCH 0930/1461] elliptic-curve: consolidate `CurveArithmetic` trait (#1196) Consolidates the following former three traits into a single trait: - `AffineArithmetic` - `ProjectiveArithmetic` - `ScalarArithmetic` It doesn't make sense to impl one of these traits without impl'ing them all, so this commit combines them into a single trait. --- elliptic-curve/src/arithmetic.rs | 29 ++++------ elliptic-curve/src/dev.rs | 11 +--- elliptic-curve/src/ecdh.rs | 20 +++---- elliptic-curve/src/hash2curve/group_digest.rs | 4 +- elliptic-curve/src/jwk.rs | 16 ++--- elliptic-curve/src/lib.rs | 8 +-- elliptic-curve/src/public_key.rs | 45 +++++++------- elliptic-curve/src/scalar.rs | 4 +- elliptic-curve/src/scalar/core.rs | 6 +- elliptic-curve/src/scalar/nonzero.rs | 58 +++++++++---------- elliptic-curve/src/sec1.rs | 4 +- elliptic-curve/src/secret_key.rs | 20 +++---- elliptic-curve/src/secret_key/pkcs8.rs | 4 +- 13 files changed, 106 insertions(+), 123 deletions(-) diff --git a/elliptic-curve/src/arithmetic.rs b/elliptic-curve/src/arithmetic.rs index 7dd2f7748..1d8d76c49 100644 --- a/elliptic-curve/src/arithmetic.rs +++ b/elliptic-curve/src/arithmetic.rs @@ -7,8 +7,8 @@ use core::fmt::Debug; use subtle::{ConditionallySelectable, ConstantTimeEq}; use zeroize::DefaultIsZeroes; -/// Elliptic curve with affine arithmetic implementation. -pub trait AffineArithmetic: Curve + ScalarArithmetic { +/// Elliptic curve with an arithmetic implementation. +pub trait CurveArithmetic: Curve { /// Elliptic curve point in affine coordinates. type AffinePoint: 'static + AffineXCoordinate @@ -23,18 +23,7 @@ pub trait AffineArithmetic: Curve + ScalarArithmetic { + Sized + Send + Sync; -} - -/// Prime order elliptic curve with projective arithmetic implementation. -pub trait PrimeCurveArithmetic: - PrimeCurve + ProjectiveArithmetic -{ - /// Prime order elliptic curve group. - type CurveGroup: group::prime::PrimeCurve::AffinePoint>; -} -/// Elliptic curve with projective arithmetic implementation. -pub trait ProjectiveArithmetic: Curve + AffineArithmetic { /// Elliptic curve point in projective coordinates. /// /// Note: the following bounds are provided by [`group::Group`]: @@ -55,12 +44,8 @@ pub trait ProjectiveArithmetic: Curve + AffineArithmetic { + LinearCombination + group::Curve + group::Group; -} -/// Scalar arithmetic. -#[cfg(feature = "arithmetic")] -pub trait ScalarArithmetic: Curve { - /// Scalar field type. + /// Scalar field modulo this curve's order. /// /// Note: the following bounds are provided by [`ff::Field`]: /// - `'static` @@ -80,3 +65,11 @@ pub trait ScalarArithmetic: Curve { + ff::Field + ff::PrimeField>; } + +/// Prime order elliptic curve with projective arithmetic implementation. +pub trait PrimeCurveArithmetic: + PrimeCurve + CurveArithmetic +{ + /// Prime order elliptic curve group. + type CurveGroup: group::prime::PrimeCurve::AffinePoint>; +} diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index d316d33d1..4f759ae25 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -12,8 +12,7 @@ use crate::{ sec1::{CompressedPoint, FromEncodedPoint, ToEncodedPoint}, subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}, zeroize::DefaultIsZeroes, - AffineArithmetic, AffineXCoordinate, Curve, IsHigh, PrimeCurve, ProjectiveArithmetic, - ScalarArithmetic, + AffineXCoordinate, Curve, CurveArithmetic, IsHigh, PrimeCurve, }; use core::{ iter::{Product, Sum}, @@ -73,15 +72,9 @@ impl Curve for MockCurve { impl PrimeCurve for MockCurve {} -impl AffineArithmetic for MockCurve { +impl CurveArithmetic for MockCurve { type AffinePoint = AffinePoint; -} - -impl ProjectiveArithmetic for MockCurve { type ProjectivePoint = ProjectivePoint; -} - -impl ScalarArithmetic for MockCurve { type Scalar = Scalar; } diff --git a/elliptic-curve/src/ecdh.rs b/elliptic-curve/src/ecdh.rs index 1e9f7bc31..2d0d3d9a9 100644 --- a/elliptic-curve/src/ecdh.rs +++ b/elliptic-curve/src/ecdh.rs @@ -27,8 +27,8 @@ //! [SIGMA]: https://webee.technion.ac.il/~hugo/sigma-pdf.pdf use crate::{ - AffineArithmetic, AffinePoint, AffineXCoordinate, Curve, FieldBytes, NonZeroScalar, - ProjectiveArithmetic, ProjectivePoint, PublicKey, + AffinePoint, AffineXCoordinate, Curve, CurveArithmetic, FieldBytes, NonZeroScalar, + ProjectivePoint, PublicKey, }; use core::borrow::Borrow; use digest::{crypto_common::BlockSizeUser, Digest}; @@ -62,7 +62,7 @@ pub fn diffie_hellman( public_key: impl Borrow>, ) -> SharedSecret where - C: Curve + ProjectiveArithmetic, + C: CurveArithmetic, { let public_point = ProjectivePoint::::from(*public_key.borrow()); let secret_point = (public_point * secret_key.borrow().as_ref()).to_affine(); @@ -92,14 +92,14 @@ where /// takes further steps to authenticate the peers in a key exchange. pub struct EphemeralSecret where - C: Curve + ProjectiveArithmetic, + C: CurveArithmetic, { scalar: NonZeroScalar, } impl EphemeralSecret where - C: Curve + ProjectiveArithmetic, + C: CurveArithmetic, { /// Generate a cryptographically random [`EphemeralSecret`]. pub fn random(rng: impl CryptoRng + RngCore) -> Self { @@ -124,7 +124,7 @@ where impl From<&EphemeralSecret> for PublicKey where - C: Curve + ProjectiveArithmetic, + C: CurveArithmetic, { fn from(ephemeral_secret: &EphemeralSecret) -> Self { ephemeral_secret.public_key() @@ -133,18 +133,18 @@ where impl Zeroize for EphemeralSecret where - C: Curve + ProjectiveArithmetic, + C: CurveArithmetic, { fn zeroize(&mut self) { self.scalar.zeroize() } } -impl ZeroizeOnDrop for EphemeralSecret where C: Curve + ProjectiveArithmetic {} +impl ZeroizeOnDrop for EphemeralSecret where C: CurveArithmetic {} impl Drop for EphemeralSecret where - C: Curve + ProjectiveArithmetic, + C: CurveArithmetic, { fn drop(&mut self) { self.zeroize(); @@ -162,7 +162,7 @@ impl SharedSecret { #[inline] fn new(point: AffinePoint) -> Self where - C: AffineArithmetic, + C: CurveArithmetic, { Self { secret_bytes: point.x(), diff --git a/elliptic-curve/src/hash2curve/group_digest.rs b/elliptic-curve/src/hash2curve/group_digest.rs index dbcb1512b..4de06140c 100644 --- a/elliptic-curve/src/hash2curve/group_digest.rs +++ b/elliptic-curve/src/hash2curve/group_digest.rs @@ -1,11 +1,11 @@ //! Traits for handling hash to curve. use super::{hash_to_field, ExpandMsg, FromOkm, MapToCurve}; -use crate::{ProjectiveArithmetic, ProjectivePoint, Result}; +use crate::{CurveArithmetic, ProjectivePoint, Result}; use group::cofactor::CofactorGroup; /// Adds hashing arbitrary byte sequences to a valid group element -pub trait GroupDigest: ProjectiveArithmetic +pub trait GroupDigest: CurveArithmetic where ProjectivePoint: CofactorGroup, { diff --git a/elliptic-curve/src/jwk.rs b/elliptic-curve/src/jwk.rs index 23c3e8845..cac1f79ba 100644 --- a/elliptic-curve/src/jwk.rs +++ b/elliptic-curve/src/jwk.rs @@ -26,7 +26,7 @@ use zeroize::{Zeroize, ZeroizeOnDrop}; use crate::{ public_key::PublicKey, sec1::{FromEncodedPoint, ToEncodedPoint}, - AffinePoint, ProjectiveArithmetic, + AffinePoint, CurveArithmetic, }; /// Key Type (`kty`) for elliptic curve keys. @@ -110,7 +110,7 @@ impl JwkEcKey { #[cfg(feature = "arithmetic")] pub fn to_public_key(&self) -> Result> where - C: Curve + JwkParameters + ProjectiveArithmetic, + C: CurveArithmetic + JwkParameters, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -213,7 +213,7 @@ where #[cfg(feature = "arithmetic")] impl From> for JwkEcKey where - C: Curve + JwkParameters + ProjectiveArithmetic, + C: CurveArithmetic + JwkParameters, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -225,7 +225,7 @@ where #[cfg(feature = "arithmetic")] impl From<&SecretKey> for JwkEcKey where - C: Curve + JwkParameters + ProjectiveArithmetic, + C: CurveArithmetic + JwkParameters, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -241,7 +241,7 @@ where #[cfg(feature = "arithmetic")] impl TryFrom for PublicKey where - C: Curve + JwkParameters + ProjectiveArithmetic, + C: CurveArithmetic + JwkParameters, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -255,7 +255,7 @@ where #[cfg(feature = "arithmetic")] impl TryFrom<&JwkEcKey> for PublicKey where - C: Curve + JwkParameters + ProjectiveArithmetic, + C: CurveArithmetic + JwkParameters, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -269,7 +269,7 @@ where #[cfg(feature = "arithmetic")] impl From> for JwkEcKey where - C: Curve + JwkParameters + ProjectiveArithmetic, + C: CurveArithmetic + JwkParameters, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -281,7 +281,7 @@ where #[cfg(feature = "arithmetic")] impl From<&PublicKey> for JwkEcKey where - C: Curve + JwkParameters + ProjectiveArithmetic, + C: CurveArithmetic + JwkParameters, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 0c7d7cf9f..be154b5f6 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -104,9 +104,7 @@ pub use zeroize; #[cfg(feature = "arithmetic")] pub use { crate::{ - arithmetic::{ - AffineArithmetic, PrimeCurveArithmetic, ProjectiveArithmetic, ScalarArithmetic, - }, + arithmetic::{CurveArithmetic, PrimeCurveArithmetic}, public_key::PublicKey, scalar::{nonzero::NonZeroScalar, Scalar}, }, @@ -175,12 +173,12 @@ pub type FieldBytes = GenericArray>; /// Affine point type for a given curve with a [`ProjectiveArithmetic`] /// implementation. #[cfg(feature = "arithmetic")] -pub type AffinePoint = ::AffinePoint; +pub type AffinePoint = ::AffinePoint; /// Projective point type for a given curve with a [`ProjectiveArithmetic`] /// implementation. #[cfg(feature = "arithmetic")] -pub type ProjectivePoint = ::ProjectivePoint; +pub type ProjectivePoint = ::ProjectivePoint; /// Elliptic curve parameters used by VOPRF. #[cfg(feature = "voprf")] diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index ef5216613..a916cd8a8 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -1,8 +1,7 @@ //! Elliptic curve public keys. use crate::{ - point::NonIdentity, AffinePoint, Curve, Error, NonZeroScalar, ProjectiveArithmetic, - ProjectivePoint, Result, + point::NonIdentity, AffinePoint, CurveArithmetic, Error, NonZeroScalar, ProjectivePoint, Result, }; use core::fmt::Debug; use group::{Curve as _, Group}; @@ -20,7 +19,7 @@ use core::str::FromStr; use { crate::{ sec1::{EncodedPoint, FromEncodedPoint, ModulusSize, ToEncodedPoint}, - FieldSize, PointCompression, + Curve, FieldSize, PointCompression, }, core::cmp::Ordering, subtle::CtOption, @@ -83,14 +82,14 @@ use { #[derive(Clone, Debug, Eq, PartialEq)] pub struct PublicKey where - C: Curve + ProjectiveArithmetic, + C: CurveArithmetic, { point: AffinePoint, } impl PublicKey where - C: Curve + ProjectiveArithmetic, + C: CurveArithmetic, { /// Convert an [`AffinePoint`] into a [`PublicKey`] pub fn from_affine(point: AffinePoint) -> Result { @@ -136,7 +135,7 @@ where #[cfg(feature = "alloc")] pub fn to_sec1_bytes(&self) -> Box<[u8]> where - C: Curve + ProjectiveArithmetic + PointCompression, + C: CurveArithmetic + PointCompression, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -203,19 +202,19 @@ where impl AsRef> for PublicKey where - C: Curve + ProjectiveArithmetic, + C: CurveArithmetic, { fn as_ref(&self) -> &AffinePoint { self.as_affine() } } -impl Copy for PublicKey where C: Curve + ProjectiveArithmetic {} +impl Copy for PublicKey where C: CurveArithmetic {} #[cfg(feature = "sec1")] impl FromEncodedPoint for PublicKey where - C: Curve + ProjectiveArithmetic, + C: CurveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -231,7 +230,7 @@ where #[cfg(feature = "sec1")] impl ToEncodedPoint for PublicKey where - C: Curve + ProjectiveArithmetic, + C: CurveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -245,7 +244,7 @@ where #[cfg(feature = "sec1")] impl From> for EncodedPoint where - C: Curve + ProjectiveArithmetic + PointCompression, + C: CurveArithmetic + PointCompression, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -257,7 +256,7 @@ where #[cfg(feature = "sec1")] impl From<&PublicKey> for EncodedPoint where - C: Curve + ProjectiveArithmetic + PointCompression, + C: CurveArithmetic + PointCompression, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -268,7 +267,7 @@ where impl From> for PublicKey where - C: Curve + ProjectiveArithmetic, + C: CurveArithmetic, P: Copy + Into>, { fn from(value: NonIdentity

) -> Self { @@ -278,7 +277,7 @@ where impl From<&NonIdentity

> for PublicKey where - C: Curve + ProjectiveArithmetic, + C: CurveArithmetic, P: Copy + Into>, { fn from(value: &NonIdentity

) -> Self { @@ -291,7 +290,7 @@ where #[cfg(feature = "sec1")] impl PartialOrd for PublicKey where - C: Curve + ProjectiveArithmetic, + C: CurveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -303,7 +302,7 @@ where #[cfg(feature = "sec1")] impl Ord for PublicKey where - C: Curve + ProjectiveArithmetic, + C: CurveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -318,7 +317,7 @@ where #[cfg(all(feature = "pkcs8", feature = "sec1"))] impl TryFrom> for PublicKey where - C: Curve + AssociatedOid + ProjectiveArithmetic, + C: AssociatedOid + CurveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -334,7 +333,7 @@ where #[cfg(all(feature = "pkcs8", feature = "sec1"))] impl DecodePublicKey for PublicKey where - C: Curve + AssociatedOid + ProjectiveArithmetic, + C: AssociatedOid + CurveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -343,7 +342,7 @@ where #[cfg(all(feature = "alloc", feature = "pkcs8"))] impl EncodePublicKey for PublicKey where - C: Curve + AssociatedOid + ProjectiveArithmetic, + C: AssociatedOid + CurveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -366,7 +365,7 @@ where #[cfg(feature = "pem")] impl FromStr for PublicKey where - C: Curve + AssociatedOid + ProjectiveArithmetic, + C: AssociatedOid + CurveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -380,7 +379,7 @@ where #[cfg(feature = "pem")] impl ToString for PublicKey where - C: Curve + AssociatedOid + ProjectiveArithmetic, + C: AssociatedOid + CurveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -393,7 +392,7 @@ where #[cfg(all(feature = "pkcs8", feature = "serde"))] impl Serialize for PublicKey where - C: Curve + AssociatedOid + ProjectiveArithmetic, + C: AssociatedOid + CurveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -409,7 +408,7 @@ where #[cfg(all(feature = "pkcs8", feature = "serde"))] impl<'de, C> Deserialize<'de> for PublicKey where - C: Curve + AssociatedOid + ProjectiveArithmetic, + C: AssociatedOid + CurveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { diff --git a/elliptic-curve/src/scalar.rs b/elliptic-curve/src/scalar.rs index 0081a97fe..aedd57ea8 100644 --- a/elliptic-curve/src/scalar.rs +++ b/elliptic-curve/src/scalar.rs @@ -8,11 +8,11 @@ pub(crate) mod core; pub(crate) mod nonzero; #[cfg(feature = "arithmetic")] -use crate::ScalarArithmetic; +use crate::CurveArithmetic; /// Scalar field element for a particular elliptic curve. #[cfg(feature = "arithmetic")] -pub type Scalar = ::Scalar; +pub type Scalar = ::Scalar; /// Bit representation of a scalar field element of a given curve. #[cfg(feature = "bits")] diff --git a/elliptic-curve/src/scalar/core.rs b/elliptic-curve/src/scalar/core.rs index 94fd8bfab..472e8376f 100644 --- a/elliptic-curve/src/scalar/core.rs +++ b/elliptic-curve/src/scalar/core.rs @@ -21,7 +21,7 @@ use zeroize::DefaultIsZeroes; #[cfg(feature = "arithmetic")] use { - super::{Scalar, ScalarArithmetic}, + super::{CurveArithmetic, Scalar}, ff::PrimeField, }; @@ -41,7 +41,7 @@ use serdect::serde::{de, ser, Deserialize, Serialize}; /// /// The serialization is a fixed-width big endian encoding. When used with /// textual formats, the binary data is encoded as hexadecimal. -// TODO(tarcieri): make this a fully generic `Scalar` type and use it for `ScalarArithmetic` +// TODO(tarcieri): make this a fully generic `Scalar` type and use it for `CurveArithmetic` #[derive(Copy, Clone, Debug, Default)] pub struct ScalarCore { /// Inner unsigned integer type. @@ -144,7 +144,7 @@ where #[cfg(feature = "arithmetic")] impl ScalarCore where - C: Curve + ScalarArithmetic, + C: CurveArithmetic, { /// Convert [`ScalarCore`] into a given curve's scalar type // TODO(tarcieri): replace curve-specific scalars with `ScalarCore` diff --git a/elliptic-curve/src/scalar/nonzero.rs b/elliptic-curve/src/scalar/nonzero.rs index 06ef1155c..311d2a465 100644 --- a/elliptic-curve/src/scalar/nonzero.rs +++ b/elliptic-curve/src/scalar/nonzero.rs @@ -3,7 +3,7 @@ use crate::{ ops::{Invert, Reduce, ReduceNonZero}, rand_core::{CryptoRng, RngCore}, - Curve, Error, FieldBytes, IsHigh, PrimeCurve, Scalar, ScalarArithmetic, ScalarCore, SecretKey, + CurveArithmetic, Error, FieldBytes, IsHigh, PrimeCurve, Scalar, ScalarCore, SecretKey, }; use base16ct::HexDisplay; use core::{ @@ -31,14 +31,14 @@ use serdect::serde::{de, ser, Deserialize, Serialize}; #[derive(Clone)] pub struct NonZeroScalar where - C: Curve + ScalarArithmetic, + C: CurveArithmetic, { scalar: Scalar, } impl NonZeroScalar where - C: Curve + ScalarArithmetic, + C: CurveArithmetic, { /// Generate a random `NonZeroScalar`. pub fn random(mut rng: impl CryptoRng + RngCore) -> Self { @@ -70,7 +70,7 @@ where impl AsRef> for NonZeroScalar where - C: Curve + ScalarArithmetic, + C: CurveArithmetic, { fn as_ref(&self) -> &Scalar { &self.scalar @@ -79,7 +79,7 @@ where impl ConditionallySelectable for NonZeroScalar where - C: Curve + ScalarArithmetic, + C: CurveArithmetic, { fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { Self { @@ -90,18 +90,18 @@ where impl ConstantTimeEq for NonZeroScalar where - C: Curve + ScalarArithmetic, + C: CurveArithmetic, { fn ct_eq(&self, other: &Self) -> Choice { self.scalar.ct_eq(&other.scalar) } } -impl Copy for NonZeroScalar where C: Curve + ScalarArithmetic {} +impl Copy for NonZeroScalar where C: CurveArithmetic {} impl Deref for NonZeroScalar where - C: Curve + ScalarArithmetic, + C: CurveArithmetic, { type Target = Scalar; @@ -112,7 +112,7 @@ where impl From> for FieldBytes where - C: Curve + ScalarArithmetic, + C: CurveArithmetic, { fn from(scalar: NonZeroScalar) -> FieldBytes { Self::from(&scalar) @@ -121,7 +121,7 @@ where impl From<&NonZeroScalar> for FieldBytes where - C: Curve + ScalarArithmetic, + C: CurveArithmetic, { fn from(scalar: &NonZeroScalar) -> FieldBytes { scalar.to_repr() @@ -130,7 +130,7 @@ where impl From> for ScalarCore where - C: Curve + ScalarArithmetic, + C: CurveArithmetic, { fn from(scalar: NonZeroScalar) -> ScalarCore { ScalarCore::from_be_bytes(scalar.to_repr()).unwrap() @@ -139,7 +139,7 @@ where impl From<&NonZeroScalar> for ScalarCore where - C: Curve + ScalarArithmetic, + C: CurveArithmetic, { fn from(scalar: &NonZeroScalar) -> ScalarCore { ScalarCore::from_be_bytes(scalar.to_repr()).unwrap() @@ -148,7 +148,7 @@ where impl From> for NonZeroScalar where - C: Curve + ScalarArithmetic, + C: CurveArithmetic, { fn from(sk: SecretKey) -> NonZeroScalar { Self::from(&sk) @@ -157,7 +157,7 @@ where impl From<&SecretKey> for NonZeroScalar where - C: Curve + ScalarArithmetic, + C: CurveArithmetic, { fn from(sk: &SecretKey) -> NonZeroScalar { let scalar = sk.as_scalar_core().to_scalar(); @@ -168,7 +168,7 @@ where impl Invert for NonZeroScalar where - C: Curve + ScalarArithmetic, + C: CurveArithmetic, { type Output = Self; @@ -182,7 +182,7 @@ where impl IsHigh for NonZeroScalar where - C: Curve + ScalarArithmetic, + C: CurveArithmetic, { fn is_high(&self) -> Choice { self.scalar.is_high() @@ -191,7 +191,7 @@ where impl Neg for NonZeroScalar where - C: Curve + ScalarArithmetic, + C: CurveArithmetic, { type Output = NonZeroScalar; @@ -204,7 +204,7 @@ where impl Mul> for NonZeroScalar where - C: PrimeCurve + ScalarArithmetic, + C: PrimeCurve + CurveArithmetic, { type Output = Self; @@ -216,7 +216,7 @@ where impl Mul<&NonZeroScalar> for NonZeroScalar where - C: PrimeCurve + ScalarArithmetic, + C: PrimeCurve + CurveArithmetic, { type Output = Self; @@ -232,7 +232,7 @@ where /// Note: implementation is the same as `ReduceNonZero` impl Reduce for NonZeroScalar where - C: Curve + ScalarArithmetic, + C: CurveArithmetic, I: Integer + ArrayEncoding, Scalar: ReduceNonZero, { @@ -243,7 +243,7 @@ where impl ReduceNonZero for NonZeroScalar where - C: Curve + ScalarArithmetic, + C: CurveArithmetic, I: Integer + ArrayEncoding, Scalar: ReduceNonZero, { @@ -256,7 +256,7 @@ where impl TryFrom<&[u8]> for NonZeroScalar where - C: Curve + ScalarArithmetic, + C: CurveArithmetic, { type Error = Error; @@ -274,7 +274,7 @@ where impl Zeroize for NonZeroScalar where - C: Curve + ScalarArithmetic, + C: CurveArithmetic, { fn zeroize(&mut self) { // Use zeroize's volatile writes to ensure value is cleared. @@ -288,7 +288,7 @@ where impl fmt::Display for NonZeroScalar where - C: Curve + ScalarArithmetic, + C: CurveArithmetic, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{:X}", self) @@ -297,7 +297,7 @@ where impl fmt::LowerHex for NonZeroScalar where - C: Curve + ScalarArithmetic, + C: CurveArithmetic, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{:x}", HexDisplay(&self.to_repr())) @@ -306,7 +306,7 @@ where impl fmt::UpperHex for NonZeroScalar where - C: Curve + ScalarArithmetic, + C: CurveArithmetic, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{:}", HexDisplay(&self.to_repr())) @@ -315,7 +315,7 @@ where impl str::FromStr for NonZeroScalar where - C: Curve + ScalarArithmetic, + C: CurveArithmetic, { type Err = Error; @@ -333,7 +333,7 @@ where #[cfg(feature = "serde")] impl Serialize for NonZeroScalar where - C: Curve + ScalarArithmetic, + C: CurveArithmetic, { fn serialize(&self, serializer: S) -> Result where @@ -346,7 +346,7 @@ where #[cfg(feature = "serde")] impl<'de, C> Deserialize<'de> for NonZeroScalar where - C: Curve + ScalarArithmetic, + C: CurveArithmetic, { fn deserialize(deserializer: D) -> Result where diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index 3e1635941..ea0b27541 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -9,7 +9,7 @@ use generic_array::GenericArray; use subtle::CtOption; #[cfg(feature = "arithmetic")] -use crate::{AffinePoint, Error, ProjectiveArithmetic}; +use crate::{AffinePoint, CurveArithmetic, Error}; /// Encoded elliptic curve point with point compression. pub type CompressedPoint = GenericArray>; @@ -96,7 +96,7 @@ where #[cfg(all(feature = "arithmetic"))] impl ValidatePublicKey for C where - C: Curve + ProjectiveArithmetic, + C: CurveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index fc777ab39..bc335f952 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -28,7 +28,7 @@ use { #[cfg(feature = "arithmetic")] use crate::{ rand_core::{CryptoRng, RngCore}, - NonZeroScalar, ProjectiveArithmetic, PublicKey, + CurveArithmetic, NonZeroScalar, PublicKey, }; #[cfg(feature = "jwk")] @@ -99,7 +99,7 @@ where #[cfg(feature = "arithmetic")] pub fn random(rng: impl CryptoRng + RngCore) -> Self where - C: ProjectiveArithmetic, + C: CurveArithmetic, { Self { inner: NonZeroScalar::::random(rng).into(), @@ -132,7 +132,7 @@ where #[cfg(feature = "arithmetic")] pub fn to_nonzero_scalar(&self) -> NonZeroScalar where - C: Curve + ProjectiveArithmetic, + C: CurveArithmetic, { self.into() } @@ -141,7 +141,7 @@ where #[cfg(feature = "arithmetic")] pub fn public_key(&self) -> PublicKey where - C: Curve + ProjectiveArithmetic, + C: CurveArithmetic, { PublicKey::from_secret_scalar(&self.to_nonzero_scalar()) } @@ -185,7 +185,7 @@ where #[cfg(all(feature = "alloc", feature = "arithmetic", feature = "sec1"))] pub fn to_sec1_der(&self) -> der::Result>> where - C: Curve + ProjectiveArithmetic, + C: CurveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -237,7 +237,7 @@ where #[cfg(feature = "pem")] pub fn to_pem(&self, line_ending: pem::LineEnding) -> Result> where - C: Curve + ProjectiveArithmetic, + C: CurveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -272,7 +272,7 @@ where #[cfg(all(feature = "arithmetic", feature = "jwk"))] pub fn to_jwk(&self) -> JwkEcKey where - C: Curve + JwkParameters + ProjectiveArithmetic, + C: CurveArithmetic + JwkParameters, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -283,7 +283,7 @@ where #[cfg(all(feature = "arithmetic", feature = "jwk"))] pub fn to_jwk_string(&self) -> Zeroizing where - C: Curve + JwkParameters + ProjectiveArithmetic, + C: CurveArithmetic + JwkParameters, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -361,7 +361,7 @@ where #[cfg(feature = "arithmetic")] impl From> for SecretKey where - C: Curve + ProjectiveArithmetic, + C: CurveArithmetic, { fn from(scalar: NonZeroScalar) -> SecretKey { SecretKey::from(&scalar) @@ -371,7 +371,7 @@ where #[cfg(feature = "arithmetic")] impl From<&NonZeroScalar> for SecretKey where - C: Curve + ProjectiveArithmetic, + C: CurveArithmetic, { fn from(scalar: &NonZeroScalar) -> SecretKey { SecretKey { diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs index f30832cfd..52090a23b 100644 --- a/elliptic-curve/src/secret_key/pkcs8.rs +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -13,7 +13,7 @@ use sec1::EcPrivateKey; use { crate::{ sec1::{FromEncodedPoint, ToEncodedPoint}, - AffinePoint, ProjectiveArithmetic, + AffinePoint, CurveArithmetic, }, pkcs8::{der, EncodePrivateKey}, }; @@ -52,7 +52,7 @@ where #[cfg(all(feature = "alloc", feature = "arithmetic"))] impl EncodePrivateKey for SecretKey where - C: Curve + AssociatedOid + ProjectiveArithmetic, + C: AssociatedOid + CurveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { From f69babe25a750db5d6f1792b287d6a6e850c1361 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 13 Jan 2023 20:32:30 -0700 Subject: [PATCH 0931/1461] elliptic-curve: lint improvements (#1197) Adopts the following lints: #![warn( clippy::mod_module_files, clippy::unwrap_used, missing_docs, rust_2018_idioms, unused_lifetimes, unused_qualifications )] --- elliptic-curve/src/ecdh.rs | 2 +- .../src/hash2curve/hash2field/expand_msg.rs | 2 +- elliptic-curve/src/hash2curve/osswu.rs | 2 +- elliptic-curve/src/lib.rs | 11 +++++++++-- elliptic-curve/src/secret_key.rs | 2 +- 5 files changed, 13 insertions(+), 6 deletions(-) diff --git a/elliptic-curve/src/ecdh.rs b/elliptic-curve/src/ecdh.rs index 2d0d3d9a9..cc67b9ace 100644 --- a/elliptic-curve/src/ecdh.rs +++ b/elliptic-curve/src/ecdh.rs @@ -118,7 +118,7 @@ where /// Compute a Diffie-Hellman shared secret from an ephemeral secret and the /// public key of the other participant in the exchange. pub fn diffie_hellman(&self, public_key: &PublicKey) -> SharedSecret { - diffie_hellman(&self.scalar, public_key.as_affine()) + diffie_hellman(self.scalar, public_key.as_affine()) } } diff --git a/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs b/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs index dfb3bab9c..4a4db7119 100644 --- a/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs +++ b/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs @@ -94,7 +94,7 @@ where pub fn data(&self) -> &[u8] { match self { Self::Hashed(d) => &d[..], - Self::Array(d) => *d, + Self::Array(d) => d, } } diff --git a/elliptic-curve/src/hash2curve/osswu.rs b/elliptic-curve/src/hash2curve/osswu.rs index ced69c7b9..60796ebe5 100644 --- a/elliptic-curve/src/hash2curve/osswu.rs +++ b/elliptic-curve/src/hash2curve/osswu.rs @@ -64,7 +64,7 @@ pub trait OsswuMap: Field + Sgn0 { tv2 = gx1 * gxd; // gx1 * gxd tv4 *= tv2; - let y1 = tv4.pow_vartime(&Self::PARAMS.c1) * tv2; // tv4^C1 * tv2 + let y1 = tv4.pow_vartime(Self::PARAMS.c1) * tv2; // tv4^C1 * tv2 let x2n = tv3 * x1n; // tv3 * x1n let y2 = y1 * Self::PARAMS.c2 * tv1 * self; // y1 * c2 * tv1 * u diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index be154b5f6..4743c3cee 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -5,8 +5,15 @@ html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg" )] -#![forbid(unsafe_code, clippy::unwrap_used)] -#![warn(missing_docs, rust_2018_idioms, unused_qualifications)] +#![forbid(unsafe_code)] +#![warn( + clippy::mod_module_files, + clippy::unwrap_used, + missing_docs, + rust_2018_idioms, + unused_lifetimes, + unused_qualifications +)] //! ## Usage //! diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index bc335f952..12d427a20 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -227,7 +227,7 @@ where return Err(Error); } - Self::from_sec1_der(&*der_bytes).map_err(|_| Error) + Self::from_sec1_der(&der_bytes).map_err(|_| Error) } /// Serialize private key as self-zeroizing PEM-encoded SEC1 `ECPrivateKey` From 8101e04efe98433f312f76828d8dbe5526663cb5 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 14 Jan 2023 09:23:10 -0700 Subject: [PATCH 0932/1461] elliptic-curve: add `MulByGenerator` trait (#1198) Adds a trait for performing scalar multiplication by the generator point, which may use optimizations (e.g. precomputed tables) when available --- elliptic-curve/src/arithmetic.rs | 4 +++- elliptic-curve/src/dev.rs | 4 +++- elliptic-curve/src/ops.rs | 13 +++++++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/elliptic-curve/src/arithmetic.rs b/elliptic-curve/src/arithmetic.rs index 1d8d76c49..4bf8925e8 100644 --- a/elliptic-curve/src/arithmetic.rs +++ b/elliptic-curve/src/arithmetic.rs @@ -1,7 +1,8 @@ //! Elliptic curve arithmetic traits. use crate::{ - ops::LinearCombination, AffineXCoordinate, Curve, FieldBytes, IsHigh, PrimeCurve, ScalarCore, + ops::{LinearCombination, MulByGenerator}, + AffineXCoordinate, Curve, FieldBytes, IsHigh, PrimeCurve, ScalarCore, }; use core::fmt::Debug; use subtle::{ConditionallySelectable, ConstantTimeEq}; @@ -42,6 +43,7 @@ pub trait CurveArithmetic: Curve { + From + Into + LinearCombination + + MulByGenerator + group::Curve + group::Group; diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 4f759ae25..057541555 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -6,7 +6,7 @@ use crate::{ bigint::{Limb, U256}, error::{Error, Result}, - ops::{LinearCombination, Reduce}, + ops::{LinearCombination, MulByGenerator, Reduce}, pkcs8, rand_core::RngCore, sec1::{CompressedPoint, FromEncodedPoint, ToEncodedPoint}, @@ -766,6 +766,8 @@ impl MulAssign<&Scalar> for ProjectivePoint { } } +impl MulByGenerator for ProjectivePoint {} + impl Neg for ProjectivePoint { type Output = ProjectivePoint; diff --git a/elliptic-curve/src/ops.rs b/elliptic-curve/src/ops.rs index 769a0173a..888c17939 100644 --- a/elliptic-curve/src/ops.rs +++ b/elliptic-curve/src/ops.rs @@ -42,6 +42,19 @@ pub trait LinearCombination: Group { } } +/// Multiplication by the generator. +/// +/// May use optimizations (e.g. precomputed tables) when available. +// TODO(tarcieri): replace this with `Group::mul_by_generator``? (see zkcrypto/group#44) +#[cfg(feature = "arithmetic")] +pub trait MulByGenerator: Group { + /// Multiply by the generator of the prime-order subgroup. + #[must_use] + fn mul_by_generator(scalar: &Self::Scalar) -> Self { + Self::generator() * scalar + } +} + /// Modular reduction. pub trait Reduce: Sized { /// Perform a modular reduction, returning a field element. From ca760f11f267b2cfe4b6baf4f9b394890c56b1d0 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 14 Jan 2023 09:44:49 -0700 Subject: [PATCH 0933/1461] elliptic-curve: add `AffineYIsOdd` trait (#1199) This trait is useful for generic point compression implementations which are also useful for a generic implementation of recoverable ECDSA signing, which presently isn't possible due to an inability to query this information --- elliptic-curve/src/arithmetic.rs | 5 +++-- elliptic-curve/src/dev.rs | 12 ++++++++++-- elliptic-curve/src/lib.rs | 3 ++- elliptic-curve/src/point.rs | 13 +++++++++++-- 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/elliptic-curve/src/arithmetic.rs b/elliptic-curve/src/arithmetic.rs index 4bf8925e8..84cc92555 100644 --- a/elliptic-curve/src/arithmetic.rs +++ b/elliptic-curve/src/arithmetic.rs @@ -2,7 +2,7 @@ use crate::{ ops::{LinearCombination, MulByGenerator}, - AffineXCoordinate, Curve, FieldBytes, IsHigh, PrimeCurve, ScalarCore, + AffineXCoordinate, AffineYIsOdd, Curve, FieldBytes, IsHigh, PrimeCurve, ScalarCore, }; use core::fmt::Debug; use subtle::{ConditionallySelectable, ConstantTimeEq}; @@ -12,7 +12,8 @@ use zeroize::DefaultIsZeroes; pub trait CurveArithmetic: Curve { /// Elliptic curve point in affine coordinates. type AffinePoint: 'static - + AffineXCoordinate + + AffineXCoordinate> + + AffineYIsOdd + Copy + ConditionallySelectable + ConstantTimeEq diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 057541555..11cf4cae5 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -12,7 +12,7 @@ use crate::{ sec1::{CompressedPoint, FromEncodedPoint, ToEncodedPoint}, subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}, zeroize::DefaultIsZeroes, - AffineXCoordinate, Curve, CurveArithmetic, IsHigh, PrimeCurve, + AffineXCoordinate, AffineYIsOdd, Curve, CurveArithmetic, IsHigh, PrimeCurve, }; use core::{ iter::{Product, Sum}, @@ -377,12 +377,20 @@ pub enum AffinePoint { Other(EncodedPoint), } -impl AffineXCoordinate for AffinePoint { +impl AffineXCoordinate for AffinePoint { + type FieldRepr = FieldBytes; + fn x(&self) -> FieldBytes { unimplemented!(); } } +impl AffineYIsOdd for AffinePoint { + fn y_is_odd(&self) -> Choice { + unimplemented!(); + } +} + impl ConstantTimeEq for AffinePoint { fn ct_eq(&self, other: &Self) -> Choice { match (self, other) { diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 4743c3cee..c33ebd489 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -97,7 +97,8 @@ mod jwk; pub use crate::{ error::{Error, Result}, point::{ - AffineXCoordinate, DecompactPoint, DecompressPoint, PointCompaction, PointCompression, + AffineXCoordinate, AffineYIsOdd, DecompactPoint, DecompressPoint, PointCompaction, + PointCompression, }, scalar::{core::ScalarCore, IsHigh}, secret_key::SecretKey, diff --git a/elliptic-curve/src/point.rs b/elliptic-curve/src/point.rs index e05a44848..bce130c11 100644 --- a/elliptic-curve/src/point.rs +++ b/elliptic-curve/src/point.rs @@ -10,9 +10,18 @@ use crate::{Curve, FieldBytes}; use subtle::{Choice, CtOption}; /// Obtain the affine x-coordinate of an elliptic curve point. -pub trait AffineXCoordinate { +pub trait AffineXCoordinate { + /// Field element representation. + type FieldRepr: AsRef<[u8]>; + /// Get the affine x-coordinate as a serialized field element. - fn x(&self) -> FieldBytes; + fn x(&self) -> Self::FieldRepr; +} + +/// Is the affine y-coordinate of this elliptic curve point odd? +pub trait AffineYIsOdd { + /// Is the affine y-coordinate odd? + fn y_is_odd(&self) -> Choice; } /// Decompress an elliptic curve point. From 098b5295ffd8544ed678c733e326664179cbf408 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 14 Jan 2023 10:37:29 -0700 Subject: [PATCH 0934/1461] elliptic-curve: add generic implemenation of Stein's algorithm (#1200) Extracted from this implementation in the `p256` crate: https://github.com/RustCrypto/elliptic-curves/blob/1a03b8a/p256/src/arithmetic/scalar.rs#L145-L194 --- elliptic-curve/src/lib.rs | 6 +-- elliptic-curve/src/ops.rs | 6 +++ elliptic-curve/src/scalar.rs | 29 +++++++++++--- elliptic-curve/src/scalar/invert.rs | 60 +++++++++++++++++++++++++++++ 4 files changed, 93 insertions(+), 8 deletions(-) create mode 100644 elliptic-curve/src/scalar/invert.rs diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index c33ebd489..cbf8b1e29 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -69,6 +69,7 @@ extern crate alloc; extern crate std; pub mod ops; +pub mod scalar; #[cfg(feature = "dev")] pub mod dev; @@ -83,7 +84,6 @@ pub mod weierstrass; mod error; mod point; -mod scalar; mod secret_key; #[cfg(feature = "arithmetic")] @@ -100,7 +100,7 @@ pub use crate::{ AffineXCoordinate, AffineYIsOdd, DecompactPoint, DecompressPoint, PointCompaction, PointCompression, }, - scalar::{core::ScalarCore, IsHigh}, + scalar::{IsHigh, ScalarCore}, secret_key::SecretKey, }; pub use crypto_bigint as bigint; @@ -114,7 +114,7 @@ pub use { crate::{ arithmetic::{CurveArithmetic, PrimeCurveArithmetic}, public_key::PublicKey, - scalar::{nonzero::NonZeroScalar, Scalar}, + scalar::{NonZeroScalar, Scalar}, }, ff::{self, Field, PrimeField}, group::{self, Group}, diff --git a/elliptic-curve/src/ops.rs b/elliptic-curve/src/ops.rs index 888c17939..9cfeeb2c2 100644 --- a/elliptic-curve/src/ops.rs +++ b/elliptic-curve/src/ops.rs @@ -104,3 +104,9 @@ pub trait ReduceNonZero: Sized { /// Perform a modular reduction, returning a field element. fn from_uint_reduced_nonzero(n: Uint) -> Self; } + +/// Right shift this value by one, storing the result in-place. +pub trait Shr1 { + /// Right shift this value by one in-place. + fn shr1(&mut self); +} diff --git a/elliptic-curve/src/scalar.rs b/elliptic-curve/src/scalar.rs index aedd57ea8..0a93b257a 100644 --- a/elliptic-curve/src/scalar.rs +++ b/elliptic-curve/src/scalar.rs @@ -1,14 +1,19 @@ //! Scalar types. -use subtle::Choice; - -pub(crate) mod core; +mod core; +#[cfg(feature = "arithmetic")] +mod invert; +#[cfg(feature = "arithmetic")] +mod nonzero; +pub use self::core::ScalarCore; #[cfg(feature = "arithmetic")] -pub(crate) mod nonzero; +pub use self::{invert::invert_vartime, nonzero::NonZeroScalar}; + +use subtle::Choice; #[cfg(feature = "arithmetic")] -use crate::CurveArithmetic; +use crate::{bigint::Integer, CurveArithmetic}; /// Scalar field element for a particular elliptic curve. #[cfg(feature = "arithmetic")] @@ -18,6 +23,20 @@ pub type Scalar = ::Scalar; #[cfg(feature = "bits")] pub type ScalarBits = ff::FieldBits< as ff::PrimeFieldBits>::ReprBits>; +/// Instantiate a scalar from an unsigned integer without checking for overflow. +#[cfg(feature = "arithmetic")] +pub trait FromUintUnchecked: ff::Field { + /// Unsigned integer type (i.e. `Curve::Uint`) + type Uint: Integer; + + /// Instantiate scalar from an unsigned integer without checking + /// whether the value overflows the field modulus. + /// + /// Incorrectly used this can lead to mathematically invalid results. + /// Use with care! + fn from_uint_unchecked(uint: Self::Uint) -> Self; +} + /// Is this scalar greater than n / 2? /// /// # Returns diff --git a/elliptic-curve/src/scalar/invert.rs b/elliptic-curve/src/scalar/invert.rs new file mode 100644 index 000000000..67e4581e2 --- /dev/null +++ b/elliptic-curve/src/scalar/invert.rs @@ -0,0 +1,60 @@ +use super::FromUintUnchecked; +use crate::{ops::Shr1, CurveArithmetic, Scalar}; +use ff::{Field, PrimeField}; +use subtle::{ConstantTimeLess, CtOption}; + +/// Fast variable-time inversion using Stein's algorithm. +/// +/// +#[allow(non_snake_case)] +pub fn invert_vartime(scalar: &Scalar) -> CtOption> +where + C: CurveArithmetic, + Scalar: ConstantTimeLess + FromUintUnchecked + Shr1, +{ + let order_div_2 = Scalar::::from_uint_unchecked(C::ORDER >> 1); + + let mut u = *scalar; + let mut v = Scalar::::from_uint_unchecked(C::ORDER); // note: technically invalid + let mut A = Scalar::::ONE; + let mut C = Scalar::::ZERO; + + while !bool::from(u.is_zero()) { + // u-loop + while bool::from(u.is_even()) { + u.shr1(); + + let was_odd: bool = A.is_odd().into(); + A.shr1(); + + if was_odd { + A += order_div_2; + A += Scalar::::ONE; + } + } + + // v-loop + while bool::from(v.is_even()) { + v.shr1(); + + let was_odd: bool = C.is_odd().into(); + C.shr1(); + + if was_odd { + C += order_div_2; + C += Scalar::::ONE; + } + } + + // sub-step + if bool::from(u.ct_lt(&v)) { + v -= &u; + C -= &A; + } else { + u -= &v; + A -= &C; + } + } + + CtOption::new(C, !scalar.is_zero()) +} From 7488fe4caaf2d32d7b66a5134818795d7e26b466 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 14 Jan 2023 10:55:11 -0700 Subject: [PATCH 0935/1461] elliptic-curve: test docs in CI (#1201) Ensures `cargo doc` builds successfully --- .github/workflows/elliptic-curve.yml | 12 ++++++++++++ elliptic-curve/src/ecdh.rs | 2 +- elliptic-curve/src/lib.rs | 4 ++-- elliptic-curve/src/sec1.rs | 2 +- elliptic-curve/src/secret_key.rs | 2 +- 5 files changed, 17 insertions(+), 5 deletions(-) diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index c9eee6497..93e0061a8 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -16,6 +16,7 @@ defaults: env: CARGO_INCREMENTAL: 0 RUSTFLAGS: "-Dwarnings" + RUSTDOCFLAGS: "-Dwarnings" jobs: build: @@ -93,3 +94,14 @@ jobs: - run: cargo test --no-default-features - run: cargo test - run: cargo test --all-features + + doc: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions-rs/toolchain@v1 + with: + toolchain: stable + override: true + profile: minimal + - run: cargo doc --all-features diff --git a/elliptic-curve/src/ecdh.rs b/elliptic-curve/src/ecdh.rs index cc67b9ace..70e1bc045 100644 --- a/elliptic-curve/src/ecdh.rs +++ b/elliptic-curve/src/ecdh.rs @@ -1,7 +1,7 @@ //! Elliptic Curve Diffie-Hellman Support. //! //! This module contains a generic ECDH implementation which is usable with -//! any elliptic curve which implements the [`ProjectiveArithmetic`] trait (presently +//! any elliptic curve which implements the [`CurveArithmetic`] trait (presently //! the `k256` and `p256` crates) //! //! # ECDH Ephemeral (ECDHE) Usage diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index cbf8b1e29..cbc96c467 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -178,12 +178,12 @@ pub type FieldSize = <::Uint as bigint::ArrayEncoding>::ByteSize; /// Byte representation of a base/scalar field element of a given curve. pub type FieldBytes = GenericArray>; -/// Affine point type for a given curve with a [`ProjectiveArithmetic`] +/// Affine point type for a given curve with a [`CurveArithmetic`] /// implementation. #[cfg(feature = "arithmetic")] pub type AffinePoint = ::AffinePoint; -/// Projective point type for a given curve with a [`ProjectiveArithmetic`] +/// Projective point type for a given curve with a [`CurveArithmetic`] /// implementation. #[cfg(feature = "arithmetic")] pub type ProjectivePoint = ::ProjectivePoint; diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index ea0b27541..0d0b387c4 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -68,7 +68,7 @@ where /// Validate that the given [`EncodedPoint`] represents the encoded public key /// value of the given secret. /// -/// Curve implementations which also impl [`ProjectiveArithmetic`] will receive +/// Curve implementations which also impl [`CurveArithmetic`] will receive /// a blanket default impl of this trait. pub trait ValidatePublicKey where diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 12d427a20..5a90a1639 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -55,7 +55,7 @@ use crate::{ FieldSize, }; -#[cfg(all(docsrs, feature = "pkcs8"))] +#[cfg(all(doc, feature = "pkcs8"))] use {crate::pkcs8::DecodePrivateKey, core::str::FromStr}; /// Type label for PEM-encoded SEC1 private keys. From adb5baa9a8e7f323a994a65d8671b33f2db7b6d1 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 14 Jan 2023 10:57:23 -0700 Subject: [PATCH 0936/1461] elliptic-curve: rename `SecretKey::to_sec1_pem` (#1202) Was formerly `SecretKey::to_pem` which is ambiguous as to what PEM serialization is used. PKCS#8 is also possible (and preferred). --- elliptic-curve/src/secret_key.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 5a90a1639..17189852a 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -235,7 +235,7 @@ where /// /// Pass `Default::default()` to use the OS's native line endings. #[cfg(feature = "pem")] - pub fn to_pem(&self, line_ending: pem::LineEnding) -> Result> + pub fn to_sec1_pem(&self, line_ending: pem::LineEnding) -> Result> where C: CurveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, From 6c519b02472a1bbfba40d9cd1b55ebd96c10b432 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 14 Jan 2023 11:06:27 -0700 Subject: [PATCH 0937/1461] elliptic-curve: rename `ScalarCore` to `ScalarPrimitive` (#1203) This is a slightly more descriptive name: `ScalarPrimitive` is a scalar type with primitive functionality. --- elliptic-curve/src/arithmetic.rs | 4 +- elliptic-curve/src/dev.rs | 24 ++-- elliptic-curve/src/lib.rs | 4 +- elliptic-curve/src/scalar.rs | 4 +- elliptic-curve/src/scalar/nonzero.rs | 21 ++-- .../src/scalar/{core.rs => primitive.rs} | 106 +++++++++--------- elliptic-curve/src/secret_key.rs | 12 +- 7 files changed, 88 insertions(+), 87 deletions(-) rename elliptic-curve/src/scalar/{core.rs => primitive.rs} (74%) diff --git a/elliptic-curve/src/arithmetic.rs b/elliptic-curve/src/arithmetic.rs index 84cc92555..70c86b4bd 100644 --- a/elliptic-curve/src/arithmetic.rs +++ b/elliptic-curve/src/arithmetic.rs @@ -2,7 +2,7 @@ use crate::{ ops::{LinearCombination, MulByGenerator}, - AffineXCoordinate, AffineYIsOdd, Curve, FieldBytes, IsHigh, PrimeCurve, ScalarCore, + AffineXCoordinate, AffineYIsOdd, Curve, FieldBytes, IsHigh, PrimeCurve, ScalarPrimitive, }; use core::fmt::Debug; use subtle::{ConditionallySelectable, ConstantTimeEq}; @@ -61,7 +61,7 @@ pub trait CurveArithmetic: Curve { /// - [`Send`] /// - [`Sync`] type Scalar: DefaultIsZeroes - + From> + + From> + Into> + Into + IsHigh diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 11cf4cae5..2951733f8 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -47,9 +47,9 @@ pub type PublicKey = crate::PublicKey; /// Secret key. pub type SecretKey = crate::SecretKey; -/// Scalar core. -// TODO(tarcieri): make this the scalar type -pub type ScalarCore = crate::ScalarCore; +/// Scalar primitive type. +// TODO(tarcieri): make this the scalar type when it's more capable +pub type ScalarPrimitive = crate::ScalarPrimitive; /// Scalar bits. #[cfg(feature = "bits")] @@ -90,11 +90,11 @@ impl JwkParameters for MockCurve { /// Example scalar type #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] -pub struct Scalar(ScalarCore); +pub struct Scalar(ScalarPrimitive); impl Field for Scalar { - const ZERO: Self = Self(ScalarCore::ZERO); - const ONE: Self = Self(ScalarCore::ONE); + const ZERO: Self = Self(ScalarPrimitive::ZERO); + const ONE: Self = Self(ScalarPrimitive::ONE); fn random(mut rng: impl RngCore) -> Self { let mut bytes = FieldBytes::default(); @@ -149,7 +149,7 @@ impl PrimeField for Scalar { const DELTA: Self = Self::ZERO; // BOGUS! fn from_repr(bytes: FieldBytes) -> CtOption { - ScalarCore::from_be_bytes(bytes).map(Self) + ScalarPrimitive::from_be_bytes(bytes).map(Self) } fn to_repr(&self) -> FieldBytes { @@ -182,7 +182,7 @@ impl TryFrom for Scalar { type Error = Error; fn try_from(w: U256) -> Result { - Option::from(ScalarCore::new(w)).map(Self).ok_or(Error) + Option::from(ScalarPrimitive::new(w)).map(Self).ok_or(Error) } } @@ -194,7 +194,7 @@ impl From for U256 { impl ConditionallySelectable for Scalar { fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { - Self(ScalarCore::conditional_select(&a.0, &b.0, choice)) + Self(ScalarPrimitive::conditional_select(&a.0, &b.0, choice)) } } @@ -327,7 +327,7 @@ impl Reduce for Scalar { let (r, underflow) = w.sbb(&MockCurve::ORDER, Limb::ZERO); let underflow = Choice::from((underflow.0 >> (Limb::BITS - 1)) as u8); let reduced = U256::conditional_select(&w, &r, !underflow); - Self(ScalarCore::new(reduced).unwrap()) + Self(ScalarPrimitive::new(reduced).unwrap()) } } @@ -337,8 +337,8 @@ impl From for Scalar { } } -impl From for Scalar { - fn from(scalar: ScalarCore) -> Scalar { +impl From for Scalar { + fn from(scalar: ScalarPrimitive) -> Scalar { Self(scalar) } } diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index cbc96c467..507345596 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -49,7 +49,7 @@ //! //! - [`JwkEcKey`] //! - [`PublicKey`] -//! - [`ScalarCore`] +//! - [`ScalarPrimitive`] //! //! Please see type-specific documentation for more information. //! @@ -100,7 +100,7 @@ pub use crate::{ AffineXCoordinate, AffineYIsOdd, DecompactPoint, DecompressPoint, PointCompaction, PointCompression, }, - scalar::{IsHigh, ScalarCore}, + scalar::{IsHigh, ScalarPrimitive}, secret_key::SecretKey, }; pub use crypto_bigint as bigint; diff --git a/elliptic-curve/src/scalar.rs b/elliptic-curve/src/scalar.rs index 0a93b257a..1d0c77677 100644 --- a/elliptic-curve/src/scalar.rs +++ b/elliptic-curve/src/scalar.rs @@ -1,12 +1,12 @@ //! Scalar types. -mod core; #[cfg(feature = "arithmetic")] mod invert; #[cfg(feature = "arithmetic")] mod nonzero; +mod primitive; -pub use self::core::ScalarCore; +pub use self::primitive::ScalarPrimitive; #[cfg(feature = "arithmetic")] pub use self::{invert::invert_vartime, nonzero::NonZeroScalar}; diff --git a/elliptic-curve/src/scalar/nonzero.rs b/elliptic-curve/src/scalar/nonzero.rs index 311d2a465..ecfdb9ede 100644 --- a/elliptic-curve/src/scalar/nonzero.rs +++ b/elliptic-curve/src/scalar/nonzero.rs @@ -3,7 +3,7 @@ use crate::{ ops::{Invert, Reduce, ReduceNonZero}, rand_core::{CryptoRng, RngCore}, - CurveArithmetic, Error, FieldBytes, IsHigh, PrimeCurve, Scalar, ScalarCore, SecretKey, + CurveArithmetic, Error, FieldBytes, IsHigh, PrimeCurve, Scalar, ScalarPrimitive, SecretKey, }; use base16ct::HexDisplay; use core::{ @@ -64,7 +64,7 @@ where /// Create a [`NonZeroScalar`] from a `C::Uint`. pub fn from_uint(uint: C::Uint) -> CtOption { - ScalarCore::new(uint).and_then(|scalar| Self::new(scalar.into())) + ScalarPrimitive::new(uint).and_then(|scalar| Self::new(scalar.into())) } } @@ -128,21 +128,21 @@ where } } -impl From> for ScalarCore +impl From> for ScalarPrimitive where C: CurveArithmetic, { - fn from(scalar: NonZeroScalar) -> ScalarCore { - ScalarCore::from_be_bytes(scalar.to_repr()).unwrap() + fn from(scalar: NonZeroScalar) -> ScalarPrimitive { + ScalarPrimitive::from_be_bytes(scalar.to_repr()).unwrap() } } -impl From<&NonZeroScalar> for ScalarCore +impl From<&NonZeroScalar> for ScalarPrimitive where C: CurveArithmetic, { - fn from(scalar: &NonZeroScalar) -> ScalarCore { - ScalarCore::from_be_bytes(scalar.to_repr()).unwrap() + fn from(scalar: &NonZeroScalar) -> ScalarPrimitive { + ScalarPrimitive::from_be_bytes(scalar.to_repr()).unwrap() } } @@ -339,7 +339,7 @@ where where S: ser::Serializer, { - ScalarCore::from(self).serialize(serializer) + ScalarPrimitive::from(self).serialize(serializer) } } @@ -352,7 +352,8 @@ where where D: de::Deserializer<'de>, { - Option::from(Self::new(ScalarCore::deserialize(deserializer)?.into())) + let scalar = ScalarPrimitive::deserialize(deserializer)?; + Option::from(Self::new(scalar.into())) .ok_or_else(|| de::Error::custom("expected non-zero scalar")) } } diff --git a/elliptic-curve/src/scalar/core.rs b/elliptic-curve/src/scalar/primitive.rs similarity index 74% rename from elliptic-curve/src/scalar/core.rs rename to elliptic-curve/src/scalar/primitive.rs index 472e8376f..31637380e 100644 --- a/elliptic-curve/src/scalar/core.rs +++ b/elliptic-curve/src/scalar/primitive.rs @@ -1,12 +1,7 @@ -//! Generic scalar type with core functionality. +//! Generic scalar type with primitive functionality. use crate::{ bigint::{prelude::*, Limb, NonZero}, - rand_core::{CryptoRng, RngCore}, - subtle::{ - Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeGreater, ConstantTimeLess, - CtOption, - }, Curve, Error, FieldBytes, IsHigh, Result, }; use base16ct::HexDisplay; @@ -17,6 +12,11 @@ use core::{ str, }; use generic_array::GenericArray; +use rand_core::{CryptoRng, RngCore}; +use subtle::{ + Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeGreater, ConstantTimeLess, + CtOption, +}; use zeroize::DefaultIsZeroes; #[cfg(feature = "arithmetic")] @@ -28,7 +28,7 @@ use { #[cfg(feature = "serde")] use serdect::serde::{de, ser, Deserialize, Serialize}; -/// Generic scalar type with core functionality. +/// Generic scalar type with primitive functionality. /// /// This type provides a baseline level of scalar arithmetic functionality /// which is always available for all curves, regardless of if they implement @@ -41,14 +41,14 @@ use serdect::serde::{de, ser, Deserialize, Serialize}; /// /// The serialization is a fixed-width big endian encoding. When used with /// textual formats, the binary data is encoded as hexadecimal. -// TODO(tarcieri): make this a fully generic `Scalar` type and use it for `CurveArithmetic` +// TODO(tarcieri): use `crypto-bigint`'s `Residue` type, expose more functionality? #[derive(Copy, Clone, Debug, Default)] -pub struct ScalarCore { +pub struct ScalarPrimitive { /// Inner unsigned integer type. inner: C::Uint, } -impl ScalarCore +impl ScalarPrimitive where C: Curve, { @@ -65,7 +65,7 @@ where /// Scalar modulus. pub const MODULUS: C::Uint = C::ORDER; - /// Generate a random [`ScalarCore`]. + /// Generate a random [`ScalarPrimitive`]. pub fn random(rng: impl CryptoRng + RngCore) -> Self { Self { inner: C::Uint::random_mod(rng, &NonZero::new(Self::MODULUS).unwrap()), @@ -77,12 +77,12 @@ where CtOption::new(Self { inner: uint }, uint.ct_lt(&Self::MODULUS)) } - /// Decode [`ScalarCore`] from big endian bytes. + /// Decode [`ScalarPrimitive`] from big endian bytes. pub fn from_be_bytes(bytes: FieldBytes) -> CtOption { Self::new(C::Uint::from_be_byte_array(bytes)) } - /// Decode [`ScalarCore`] from a big endian byte slice. + /// Decode [`ScalarPrimitive`] from a big endian byte slice. pub fn from_be_slice(slice: &[u8]) -> Result { if slice.len() == C::Uint::BYTES { Option::from(Self::from_be_bytes(GenericArray::clone_from_slice(slice))).ok_or(Error) @@ -91,12 +91,12 @@ where } } - /// Decode [`ScalarCore`] from little endian bytes. + /// Decode [`ScalarPrimitive`] from little endian bytes. pub fn from_le_bytes(bytes: FieldBytes) -> CtOption { Self::new(C::Uint::from_le_byte_array(bytes)) } - /// Decode [`ScalarCore`] from a little endian byte slice. + /// Decode [`ScalarPrimitive`] from a little endian byte slice. pub fn from_le_slice(slice: &[u8]) -> Result { if slice.len() == C::Uint::BYTES { Option::from(Self::from_le_bytes(GenericArray::clone_from_slice(slice))).ok_or(Error) @@ -115,46 +115,46 @@ where self.inner.as_ref() } - /// Is this [`ScalarCore`] value equal to zero? + /// Is this [`ScalarPrimitive`] value equal to zero? pub fn is_zero(&self) -> Choice { self.inner.is_zero() } - /// Is this [`ScalarCore`] value even? + /// Is this [`ScalarPrimitive`] value even? pub fn is_even(&self) -> Choice { self.inner.is_even() } - /// Is this [`ScalarCore`] value odd? + /// Is this [`ScalarPrimitive`] value odd? pub fn is_odd(&self) -> Choice { self.inner.is_odd() } - /// Encode [`ScalarCore`] as big endian bytes. + /// Encode [`ScalarPrimitive`] as big endian bytes. pub fn to_be_bytes(self) -> FieldBytes { self.inner.to_be_byte_array() } - /// Encode [`ScalarCore`] as little endian bytes. + /// Encode [`ScalarPrimitive`] as little endian bytes. pub fn to_le_bytes(self) -> FieldBytes { self.inner.to_le_byte_array() } } #[cfg(feature = "arithmetic")] -impl ScalarCore +impl ScalarPrimitive where C: CurveArithmetic, { - /// Convert [`ScalarCore`] into a given curve's scalar type - // TODO(tarcieri): replace curve-specific scalars with `ScalarCore` + /// Convert [`ScalarPrimitive`] into a given curve's scalar type + // TODO(tarcieri): replace curve-specific scalars with `ScalarPrimitive` pub(super) fn to_scalar(self) -> Scalar { Scalar::::from_repr(self.to_be_bytes()).unwrap() } } // TODO(tarcieri): better encapsulate this? -impl AsRef<[Limb]> for ScalarCore +impl AsRef<[Limb]> for ScalarPrimitive where C: Curve, { @@ -163,7 +163,7 @@ where } } -impl ConditionallySelectable for ScalarCore +impl ConditionallySelectable for ScalarPrimitive where C: Curve, { @@ -174,7 +174,7 @@ where } } -impl ConstantTimeEq for ScalarCore +impl ConstantTimeEq for ScalarPrimitive where C: Curve, { @@ -183,7 +183,7 @@ where } } -impl ConstantTimeLess for ScalarCore +impl ConstantTimeLess for ScalarPrimitive where C: Curve, { @@ -192,7 +192,7 @@ where } } -impl ConstantTimeGreater for ScalarCore +impl ConstantTimeGreater for ScalarPrimitive where C: Curve, { @@ -201,11 +201,11 @@ where } } -impl DefaultIsZeroes for ScalarCore {} +impl DefaultIsZeroes for ScalarPrimitive {} -impl Eq for ScalarCore {} +impl Eq for ScalarPrimitive {} -impl PartialEq for ScalarCore +impl PartialEq for ScalarPrimitive where C: Curve, { @@ -214,7 +214,7 @@ where } } -impl PartialOrd for ScalarCore +impl PartialOrd for ScalarPrimitive where C: Curve, { @@ -223,7 +223,7 @@ where } } -impl Ord for ScalarCore +impl Ord for ScalarPrimitive where C: Curve, { @@ -232,7 +232,7 @@ where } } -impl From for ScalarCore +impl From for ScalarPrimitive where C: Curve, { @@ -243,7 +243,7 @@ where } } -impl Add> for ScalarCore +impl Add> for ScalarPrimitive where C: Curve, { @@ -254,7 +254,7 @@ where } } -impl Add<&ScalarCore> for ScalarCore +impl Add<&ScalarPrimitive> for ScalarPrimitive where C: Curve, { @@ -267,7 +267,7 @@ where } } -impl AddAssign> for ScalarCore +impl AddAssign> for ScalarPrimitive where C: Curve, { @@ -276,7 +276,7 @@ where } } -impl AddAssign<&ScalarCore> for ScalarCore +impl AddAssign<&ScalarPrimitive> for ScalarPrimitive where C: Curve, { @@ -285,7 +285,7 @@ where } } -impl Sub> for ScalarCore +impl Sub> for ScalarPrimitive where C: Curve, { @@ -296,7 +296,7 @@ where } } -impl Sub<&ScalarCore> for ScalarCore +impl Sub<&ScalarPrimitive> for ScalarPrimitive where C: Curve, { @@ -309,7 +309,7 @@ where } } -impl SubAssign> for ScalarCore +impl SubAssign> for ScalarPrimitive where C: Curve, { @@ -318,7 +318,7 @@ where } } -impl SubAssign<&ScalarCore> for ScalarCore +impl SubAssign<&ScalarPrimitive> for ScalarPrimitive where C: Curve, { @@ -327,7 +327,7 @@ where } } -impl Neg for ScalarCore +impl Neg for ScalarPrimitive where C: Curve, { @@ -340,18 +340,18 @@ where } } -impl Neg for &ScalarCore +impl Neg for &ScalarPrimitive where C: Curve, { - type Output = ScalarCore; + type Output = ScalarPrimitive; - fn neg(self) -> ScalarCore { + fn neg(self) -> ScalarPrimitive { -*self } } -impl IsHigh for ScalarCore +impl IsHigh for ScalarPrimitive where C: Curve, { @@ -361,7 +361,7 @@ where } } -impl fmt::Display for ScalarCore +impl fmt::Display for ScalarPrimitive where C: Curve, { @@ -370,7 +370,7 @@ where } } -impl fmt::LowerHex for ScalarCore +impl fmt::LowerHex for ScalarPrimitive where C: Curve, { @@ -379,7 +379,7 @@ where } } -impl fmt::UpperHex for ScalarCore +impl fmt::UpperHex for ScalarPrimitive where C: Curve, { @@ -388,7 +388,7 @@ where } } -impl str::FromStr for ScalarCore +impl str::FromStr for ScalarPrimitive where C: Curve, { @@ -402,7 +402,7 @@ where } #[cfg(feature = "serde")] -impl Serialize for ScalarCore +impl Serialize for ScalarPrimitive where C: Curve, { @@ -415,7 +415,7 @@ where } #[cfg(feature = "serde")] -impl<'de, C> Deserialize<'de> for ScalarCore +impl<'de, C> Deserialize<'de> for ScalarPrimitive where C: Curve, { diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 17189852a..73bf8e244 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -8,7 +8,7 @@ #[cfg(all(feature = "pkcs8", feature = "sec1"))] mod pkcs8; -use crate::{Curve, Error, FieldBytes, Result, ScalarCore}; +use crate::{Curve, Error, FieldBytes, Result, ScalarPrimitive}; use core::fmt::{self, Debug}; use crypto_bigint::Integer; use generic_array::GenericArray; @@ -88,7 +88,7 @@ pub(crate) const SEC1_PEM_TYPE_LABEL: &str = "EC PRIVATE KEY"; #[derive(Clone)] pub struct SecretKey { /// Scalar value - inner: ScalarCore, + inner: ScalarPrimitive, } impl SecretKey @@ -107,18 +107,18 @@ where } /// Create a new secret key from a scalar value. - pub fn new(scalar: ScalarCore) -> Self { + pub fn new(scalar: ScalarPrimitive) -> Self { Self { inner: scalar } } - /// Borrow the inner secret [`ScalarCore`] value. + /// Borrow the inner secret [`ScalarPrimitive`] value. /// /// # ⚠️ Warning /// /// This value is key material. /// /// Please treat it with the care it deserves! - pub fn as_scalar_core(&self) -> &ScalarCore { + pub fn as_scalar_core(&self) -> &ScalarPrimitive { &self.inner } @@ -152,7 +152,7 @@ where return Err(Error); } - let inner: ScalarCore = Option::from(ScalarCore::from_be_bytes( + let inner: ScalarPrimitive = Option::from(ScalarPrimitive::from_be_bytes( GenericArray::clone_from_slice(bytes), )) .ok_or(Error)?; From a238514aad886f037b8f933c27077abc6c338f3d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 14 Jan 2023 11:24:38 -0700 Subject: [PATCH 0938/1461] elliptic-curve: mandate `scalar::FromUintUnchecked` (#1204) Bounds `CurveArithmetic::Scalar` on this trait and uses it to simplify conversions to/from `ScalarPrimitive`. Also adds bounds to ensure `ScalarPrimitive` conversions are bidirectional. --- elliptic-curve/src/arithmetic.rs | 3 ++ elliptic-curve/src/dev.rs | 43 +++++++++++++++++--------- elliptic-curve/src/scalar.rs | 6 ++-- elliptic-curve/src/scalar/primitive.rs | 31 +++++++++++++------ 4 files changed, 57 insertions(+), 26 deletions(-) diff --git a/elliptic-curve/src/arithmetic.rs b/elliptic-curve/src/arithmetic.rs index 70c86b4bd..fdaf19b4e 100644 --- a/elliptic-curve/src/arithmetic.rs +++ b/elliptic-curve/src/arithmetic.rs @@ -2,6 +2,7 @@ use crate::{ ops::{LinearCombination, MulByGenerator}, + scalar::FromUintUnchecked, AffineXCoordinate, AffineYIsOdd, Curve, FieldBytes, IsHigh, PrimeCurve, ScalarPrimitive, }; use core::fmt::Debug; @@ -62,8 +63,10 @@ pub trait CurveArithmetic: Curve { /// - [`Sync`] type Scalar: DefaultIsZeroes + From> + + FromUintUnchecked + Into> + Into + + Into> + IsHigh + ff::Field + ff::PrimeField>; diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 2951733f8..2582c4464 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -9,6 +9,7 @@ use crate::{ ops::{LinearCombination, MulByGenerator, Reduce}, pkcs8, rand_core::RngCore, + scalar::FromUintUnchecked, sec1::{CompressedPoint, FromEncodedPoint, ToEncodedPoint}, subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}, zeroize::DefaultIsZeroes, @@ -178,20 +179,6 @@ impl PrimeFieldBits for Scalar { } } -impl TryFrom for Scalar { - type Error = Error; - - fn try_from(w: U256) -> Result { - Option::from(ScalarPrimitive::new(w)).map(Self).ok_or(Error) - } -} - -impl From for U256 { - fn from(scalar: Scalar) -> U256 { - *scalar.0.as_uint() - } -} - impl ConditionallySelectable for Scalar { fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { Self(ScalarPrimitive::conditional_select(&a.0, &b.0, choice)) @@ -343,6 +330,34 @@ impl From for Scalar { } } +impl From for ScalarPrimitive { + fn from(scalar: Scalar) -> ScalarPrimitive { + scalar.0 + } +} + +impl From for U256 { + fn from(scalar: Scalar) -> U256 { + scalar.0.to_uint() + } +} + +impl TryFrom for Scalar { + type Error = Error; + + fn try_from(w: U256) -> Result { + Option::from(ScalarPrimitive::new(w)).map(Self).ok_or(Error) + } +} + +impl FromUintUnchecked for Scalar { + type Uint = U256; + + fn from_uint_unchecked(uint: U256) -> Self { + Self(ScalarPrimitive::from_uint_unchecked(uint)) + } +} + impl From for FieldBytes { fn from(scalar: Scalar) -> Self { Self::from(&scalar) diff --git a/elliptic-curve/src/scalar.rs b/elliptic-curve/src/scalar.rs index 1d0c77677..9eb165cb5 100644 --- a/elliptic-curve/src/scalar.rs +++ b/elliptic-curve/src/scalar.rs @@ -10,10 +10,11 @@ pub use self::primitive::ScalarPrimitive; #[cfg(feature = "arithmetic")] pub use self::{invert::invert_vartime, nonzero::NonZeroScalar}; +use crypto_bigint::Integer; use subtle::Choice; #[cfg(feature = "arithmetic")] -use crate::{bigint::Integer, CurveArithmetic}; +use crate::CurveArithmetic; /// Scalar field element for a particular elliptic curve. #[cfg(feature = "arithmetic")] @@ -24,8 +25,7 @@ pub type Scalar = ::Scalar; pub type ScalarBits = ff::FieldBits< as ff::PrimeFieldBits>::ReprBits>; /// Instantiate a scalar from an unsigned integer without checking for overflow. -#[cfg(feature = "arithmetic")] -pub trait FromUintUnchecked: ff::Field { +pub trait FromUintUnchecked { /// Unsigned integer type (i.e. `Curve::Uint`) type Uint: Integer; diff --git a/elliptic-curve/src/scalar/primitive.rs b/elliptic-curve/src/scalar/primitive.rs index 31637380e..93a605cb6 100644 --- a/elliptic-curve/src/scalar/primitive.rs +++ b/elliptic-curve/src/scalar/primitive.rs @@ -2,6 +2,7 @@ use crate::{ bigint::{prelude::*, Limb, NonZero}, + scalar::FromUintUnchecked, Curve, Error, FieldBytes, IsHigh, Result, }; use base16ct::HexDisplay; @@ -20,10 +21,7 @@ use subtle::{ use zeroize::DefaultIsZeroes; #[cfg(feature = "arithmetic")] -use { - super::{CurveArithmetic, Scalar}, - ff::PrimeField, -}; +use super::{CurveArithmetic, Scalar}; #[cfg(feature = "serde")] use serdect::serde::{de, ser, Deserialize, Serialize}; @@ -131,14 +129,30 @@ where } /// Encode [`ScalarPrimitive`] as big endian bytes. - pub fn to_be_bytes(self) -> FieldBytes { + pub fn to_be_bytes(&self) -> FieldBytes { self.inner.to_be_byte_array() } /// Encode [`ScalarPrimitive`] as little endian bytes. - pub fn to_le_bytes(self) -> FieldBytes { + pub fn to_le_bytes(&self) -> FieldBytes { self.inner.to_le_byte_array() } + + /// Convert to a `C::Uint`. + pub fn to_uint(&self) -> C::Uint { + self.inner + } +} + +impl FromUintUnchecked for ScalarPrimitive +where + C: Curve, +{ + type Uint = C::Uint; + + fn from_uint_unchecked(uint: C::Uint) -> Self { + Self { inner: uint } + } } #[cfg(feature = "arithmetic")] @@ -146,10 +160,9 @@ impl ScalarPrimitive where C: CurveArithmetic, { - /// Convert [`ScalarPrimitive`] into a given curve's scalar type - // TODO(tarcieri): replace curve-specific scalars with `ScalarPrimitive` + /// Convert [`ScalarPrimitive`] into a given curve's scalar type. pub(super) fn to_scalar(self) -> Scalar { - Scalar::::from_repr(self.to_be_bytes()).unwrap() + Scalar::::from_uint_unchecked(self.inner) } } From e835a1c67f8c00d6e88e4a462c6e87388064a218 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 14 Jan 2023 11:34:03 -0700 Subject: [PATCH 0939/1461] elliptic-curve: improve `SecretKey` impl for `Debug` (#1205) Addresses a TODO --- elliptic-curve/src/secret_key.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 73bf8e244..096a8a33a 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -305,8 +305,8 @@ where C: Curve, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - // TODO(tarcieri): use `debug_struct` and `finish_non_exhaustive` when stable - write!(f, "SecretKey<{:?}>{{ ... }}", C::default()) + f.debug_struct(core::any::type_name::()) + .finish_non_exhaustive() } } From 322377a5975434052805fad68ef6b687fe1b4f3e Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 14 Jan 2023 12:50:42 -0700 Subject: [PATCH 0940/1461] elliptic-curve: use `CryptoRngCore` trait (#1206) Marker trait for `CryptoRng + RngCore`; added in `rand_core` v0.6.4 --- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/ecdh.rs | 4 ++-- elliptic-curve/src/scalar/nonzero.rs | 4 ++-- elliptic-curve/src/scalar/primitive.rs | 4 ++-- elliptic-curve/src/secret_key.rs | 7 ++----- 5 files changed, 9 insertions(+), 12 deletions(-) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index a9e120a7b..f1f51d46a 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -19,7 +19,7 @@ rust-version = "1.61" base16ct = "0.1.1" crypto-bigint = { version = "=0.5.0-pre.1", default-features = false, features = ["rand_core", "generic-array", "zeroize"] } generic-array = { version = "0.14", default-features = false } -rand_core = { version = "0.6", default-features = false } +rand_core = { version = "0.6.4", default-features = false } subtle = { version = "2", default-features = false } zeroize = { version = "1.5", default-features = false } diff --git a/elliptic-curve/src/ecdh.rs b/elliptic-curve/src/ecdh.rs index 70e1bc045..9a4f8cc51 100644 --- a/elliptic-curve/src/ecdh.rs +++ b/elliptic-curve/src/ecdh.rs @@ -34,7 +34,7 @@ use core::borrow::Borrow; use digest::{crypto_common::BlockSizeUser, Digest}; use group::Curve as _; use hkdf::{hmac::SimpleHmac, Hkdf}; -use rand_core::{CryptoRng, RngCore}; +use rand_core::CryptoRngCore; use zeroize::{Zeroize, ZeroizeOnDrop}; /// Low-level Elliptic Curve Diffie-Hellman (ECDH) function. @@ -102,7 +102,7 @@ where C: CurveArithmetic, { /// Generate a cryptographically random [`EphemeralSecret`]. - pub fn random(rng: impl CryptoRng + RngCore) -> Self { + pub fn random(rng: &mut impl CryptoRngCore) -> Self { Self { scalar: NonZeroScalar::random(rng), } diff --git a/elliptic-curve/src/scalar/nonzero.rs b/elliptic-curve/src/scalar/nonzero.rs index ecfdb9ede..bd6f415fd 100644 --- a/elliptic-curve/src/scalar/nonzero.rs +++ b/elliptic-curve/src/scalar/nonzero.rs @@ -2,7 +2,6 @@ use crate::{ ops::{Invert, Reduce, ReduceNonZero}, - rand_core::{CryptoRng, RngCore}, CurveArithmetic, Error, FieldBytes, IsHigh, PrimeCurve, Scalar, ScalarPrimitive, SecretKey, }; use base16ct::HexDisplay; @@ -14,6 +13,7 @@ use core::{ use crypto_bigint::{ArrayEncoding, Integer}; use ff::{Field, PrimeField}; use generic_array::GenericArray; +use rand_core::CryptoRngCore; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; use zeroize::Zeroize; @@ -41,7 +41,7 @@ where C: CurveArithmetic, { /// Generate a random `NonZeroScalar`. - pub fn random(mut rng: impl CryptoRng + RngCore) -> Self { + pub fn random(mut rng: &mut impl CryptoRngCore) -> Self { // Use rejection sampling to eliminate zero values. // While this method isn't constant-time, the attacker shouldn't learn // anything about unrelated outputs so long as `rng` is a secure `CryptoRng`. diff --git a/elliptic-curve/src/scalar/primitive.rs b/elliptic-curve/src/scalar/primitive.rs index 93a605cb6..d0d4d0a71 100644 --- a/elliptic-curve/src/scalar/primitive.rs +++ b/elliptic-curve/src/scalar/primitive.rs @@ -13,7 +13,7 @@ use core::{ str, }; use generic_array::GenericArray; -use rand_core::{CryptoRng, RngCore}; +use rand_core::CryptoRngCore; use subtle::{ Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeGreater, ConstantTimeLess, CtOption, @@ -64,7 +64,7 @@ where pub const MODULUS: C::Uint = C::ORDER; /// Generate a random [`ScalarPrimitive`]. - pub fn random(rng: impl CryptoRng + RngCore) -> Self { + pub fn random(rng: &mut impl CryptoRngCore) -> Self { Self { inner: C::Uint::random_mod(rng, &NonZero::new(Self::MODULUS).unwrap()), } diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 096a8a33a..c7b2a3f43 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -26,10 +26,7 @@ use { }; #[cfg(feature = "arithmetic")] -use crate::{ - rand_core::{CryptoRng, RngCore}, - CurveArithmetic, NonZeroScalar, PublicKey, -}; +use crate::{rand_core::CryptoRngCore, CurveArithmetic, NonZeroScalar, PublicKey}; #[cfg(feature = "jwk")] use crate::jwk::{JwkEcKey, JwkParameters}; @@ -97,7 +94,7 @@ where { /// Generate a random [`SecretKey`]. #[cfg(feature = "arithmetic")] - pub fn random(rng: impl CryptoRng + RngCore) -> Self + pub fn random(rng: &mut impl CryptoRngCore) -> Self where C: CurveArithmetic, { From c394a0209d1dec1394bf5b1fe01afcd505b84266 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 14 Jan 2023 14:43:41 -0700 Subject: [PATCH 0941/1461] elliptic-curve: add `NonZeroScalar::invert_vartime` (#1207) Adds support for variable-time inversions of `NonZeroScalar`, which allows the inversion to be infallible. An example use case is ECDSA verification, where the `s` component of the signature needs to be inverted. --- elliptic-curve/src/arithmetic.rs | 6 ++++-- elliptic-curve/src/dev.rs | 10 ++++++++-- elliptic-curve/src/lib.rs | 5 +++-- elliptic-curve/src/ops.rs | 4 ++-- elliptic-curve/src/scalar.rs | 6 +++++- elliptic-curve/src/scalar/invert.rs | 14 +++++++++----- elliptic-curve/src/scalar/nonzero.rs | 13 +++++++++++++ elliptic-curve/src/scalar/primitive.rs | 17 +++++++++++------ 8 files changed, 55 insertions(+), 20 deletions(-) diff --git a/elliptic-curve/src/arithmetic.rs b/elliptic-curve/src/arithmetic.rs index fdaf19b4e..8113f5763 100644 --- a/elliptic-curve/src/arithmetic.rs +++ b/elliptic-curve/src/arithmetic.rs @@ -1,7 +1,7 @@ //! Elliptic curve arithmetic traits. use crate::{ - ops::{LinearCombination, MulByGenerator}, + ops::{LinearCombination, MulByGenerator, Shr1}, scalar::FromUintUnchecked, AffineXCoordinate, AffineYIsOdd, Curve, FieldBytes, IsHigh, PrimeCurve, ScalarPrimitive, }; @@ -65,9 +65,11 @@ pub trait CurveArithmetic: Curve { + From> + FromUintUnchecked + Into> - + Into + Into> + + Into + IsHigh + + PartialOrd + + Shr1 + ff::Field + ff::PrimeField>; } diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 2582c4464..c60d38b0e 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -6,7 +6,7 @@ use crate::{ bigint::{Limb, U256}, error::{Error, Result}, - ops::{LinearCombination, MulByGenerator, Reduce}, + ops::{LinearCombination, MulByGenerator, Reduce, Shr1}, pkcs8, rand_core::RngCore, scalar::FromUintUnchecked, @@ -90,7 +90,7 @@ impl JwkParameters for MockCurve { } /// Example scalar type -#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, PartialOrd, Ord)] pub struct Scalar(ScalarPrimitive); impl Field for Scalar { @@ -285,6 +285,12 @@ impl Neg for Scalar { } } +impl Shr1 for Scalar { + fn shr1(&mut self) { + self.0.shr1(); + } +} + impl Sum for Scalar { fn sum>(_iter: I) -> Self { unimplemented!(); diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 507345596..1c55378fe 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -129,7 +129,7 @@ pub use crate::jwk::{JwkEcKey, JwkParameters}; #[cfg(feature = "pkcs8")] pub use pkcs8; -use core::fmt::Debug; +use core::{fmt::Debug, ops::ShrAssign}; use generic_array::GenericArray; /// Algorithm [`ObjectIdentifier`][`pkcs8::ObjectIdentifier`] for elliptic @@ -160,7 +160,8 @@ pub trait Curve: 'static + Copy + Clone + Debug + Default + Eq + Ord + Send + Sy + bigint::Random + bigint::RandomMod + bigint::SubMod - + zeroize::Zeroize; + + zeroize::Zeroize + + ShrAssign; /// Order constant. /// diff --git a/elliptic-curve/src/ops.rs b/elliptic-curve/src/ops.rs index 9cfeeb2c2..399364536 100644 --- a/elliptic-curve/src/ops.rs +++ b/elliptic-curve/src/ops.rs @@ -105,8 +105,8 @@ pub trait ReduceNonZero: Sized { fn from_uint_reduced_nonzero(n: Uint) -> Self; } -/// Right shift this value by one, storing the result in-place. +/// Right shift this value by one bit, storing the result in-place. pub trait Shr1 { - /// Right shift this value by one in-place. + /// Right shift this value by one bit in-place. fn shr1(&mut self); } diff --git a/elliptic-curve/src/scalar.rs b/elliptic-curve/src/scalar.rs index 9eb165cb5..d4d344423 100644 --- a/elliptic-curve/src/scalar.rs +++ b/elliptic-curve/src/scalar.rs @@ -32,7 +32,11 @@ pub trait FromUintUnchecked { /// Instantiate scalar from an unsigned integer without checking /// whether the value overflows the field modulus. /// - /// Incorrectly used this can lead to mathematically invalid results. + /// ⚠️ WARNING! + /// + /// Incorrectly used this can lead to mathematically invalid results, + /// which can lead to potential security vulnerabilities. + /// /// Use with care! fn from_uint_unchecked(uint: Self::Uint) -> Self; } diff --git a/elliptic-curve/src/scalar/invert.rs b/elliptic-curve/src/scalar/invert.rs index 67e4581e2..d0b2bbedd 100644 --- a/elliptic-curve/src/scalar/invert.rs +++ b/elliptic-curve/src/scalar/invert.rs @@ -1,17 +1,21 @@ use super::FromUintUnchecked; use crate::{ops::Shr1, CurveArithmetic, Scalar}; use ff::{Field, PrimeField}; -use subtle::{ConstantTimeLess, CtOption}; /// Fast variable-time inversion using Stein's algorithm. /// +/// Returns `None` if the scalar is zero. +/// /// #[allow(non_snake_case)] -pub fn invert_vartime(scalar: &Scalar) -> CtOption> +pub fn invert_vartime(scalar: &Scalar) -> Option> where C: CurveArithmetic, - Scalar: ConstantTimeLess + FromUintUnchecked + Shr1, { + if scalar.is_zero().into() { + return None; + } + let order_div_2 = Scalar::::from_uint_unchecked(C::ORDER >> 1); let mut u = *scalar; @@ -47,7 +51,7 @@ where } // sub-step - if bool::from(u.ct_lt(&v)) { + if u < v { v -= &u; C -= &A; } else { @@ -56,5 +60,5 @@ where } } - CtOption::new(C, !scalar.is_zero()) + Some(C) } diff --git a/elliptic-curve/src/scalar/nonzero.rs b/elliptic-curve/src/scalar/nonzero.rs index bd6f415fd..c9bb6ff68 100644 --- a/elliptic-curve/src/scalar/nonzero.rs +++ b/elliptic-curve/src/scalar/nonzero.rs @@ -66,6 +66,19 @@ where pub fn from_uint(uint: C::Uint) -> CtOption { ScalarPrimitive::new(uint).and_then(|scalar| Self::new(scalar.into())) } + + /// Perform an inversion in variable-time. + /// + /// ⚠️ WARNING! + /// + /// This method should not be used with (unblinded) secret scalars, as its + /// variable-time operation can potentially leak secrets through + /// sidechannels. + pub fn invert_vartime(&self) -> Self { + Self { + scalar: super::invert_vartime::(&self.scalar).expect("nonzero input"), + } + } } impl AsRef> for NonZeroScalar diff --git a/elliptic-curve/src/scalar/primitive.rs b/elliptic-curve/src/scalar/primitive.rs index d0d4d0a71..2bdec9e16 100644 --- a/elliptic-curve/src/scalar/primitive.rs +++ b/elliptic-curve/src/scalar/primitive.rs @@ -2,16 +2,12 @@ use crate::{ bigint::{prelude::*, Limb, NonZero}, + ops::{Add, AddAssign, Neg, Shr1, Sub, SubAssign}, scalar::FromUintUnchecked, Curve, Error, FieldBytes, IsHigh, Result, }; use base16ct::HexDisplay; -use core::{ - cmp::Ordering, - fmt, - ops::{Add, AddAssign, Neg, Sub, SubAssign}, - str, -}; +use core::{cmp::Ordering, fmt, str}; use generic_array::GenericArray; use rand_core::CryptoRngCore; use subtle::{ @@ -364,6 +360,15 @@ where } } +impl Shr1 for ScalarPrimitive +where + C: Curve, +{ + fn shr1(&mut self) { + self.inner >>= 1; + } +} + impl IsHigh for ScalarPrimitive where C: Curve, From ca920c61de237c53edb1140db452708b9e77b196 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 14 Jan 2023 19:13:06 -0700 Subject: [PATCH 0942/1461] elliptic-curve: add `BlindedScalar` (#1208) Adds a scalar type with random blinding. It implements `Invert` using Stein's algorithm which runs in variable time, but masks the value first with multiplication. This is useful for embedded devices where it can save the full cost of an inversion. https://link.springer.com/article/10.1007/s13389-016-0135-4 --- elliptic-curve/src/arithmetic.rs | 3 +- elliptic-curve/src/dev.rs | 6 +++ elliptic-curve/src/scalar.rs | 4 +- elliptic-curve/src/scalar/blinded.rs | 73 ++++++++++++++++++++++++++++ elliptic-curve/src/scalar/invert.rs | 11 ++--- elliptic-curve/src/scalar/nonzero.rs | 2 +- 6 files changed, 89 insertions(+), 10 deletions(-) create mode 100644 elliptic-curve/src/scalar/blinded.rs diff --git a/elliptic-curve/src/arithmetic.rs b/elliptic-curve/src/arithmetic.rs index 8113f5763..8153fb011 100644 --- a/elliptic-curve/src/arithmetic.rs +++ b/elliptic-curve/src/arithmetic.rs @@ -61,7 +61,8 @@ pub trait CurveArithmetic: Curve { /// - [`Default`] /// - [`Send`] /// - [`Sync`] - type Scalar: DefaultIsZeroes + type Scalar: AsRef + + DefaultIsZeroes + From> + FromUintUnchecked + Into> diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index c60d38b0e..ded320769 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -179,6 +179,12 @@ impl PrimeFieldBits for Scalar { } } +impl AsRef for Scalar { + fn as_ref(&self) -> &Scalar { + self + } +} + impl ConditionallySelectable for Scalar { fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { Self(ScalarPrimitive::conditional_select(&a.0, &b.0, choice)) diff --git a/elliptic-curve/src/scalar.rs b/elliptic-curve/src/scalar.rs index d4d344423..6ffd63bea 100644 --- a/elliptic-curve/src/scalar.rs +++ b/elliptic-curve/src/scalar.rs @@ -1,5 +1,7 @@ //! Scalar types. +#[cfg(feature = "arithmetic")] +mod blinded; #[cfg(feature = "arithmetic")] mod invert; #[cfg(feature = "arithmetic")] @@ -8,7 +10,7 @@ mod primitive; pub use self::primitive::ScalarPrimitive; #[cfg(feature = "arithmetic")] -pub use self::{invert::invert_vartime, nonzero::NonZeroScalar}; +pub use self::{blinded::BlindedScalar, invert::invert_vartime, nonzero::NonZeroScalar}; use crypto_bigint::Integer; use subtle::Choice; diff --git a/elliptic-curve/src/scalar/blinded.rs b/elliptic-curve/src/scalar/blinded.rs new file mode 100644 index 000000000..33303aef1 --- /dev/null +++ b/elliptic-curve/src/scalar/blinded.rs @@ -0,0 +1,73 @@ +//! Random blinding support for [`Scalar`] + +use super::{invert_vartime, Scalar}; +use crate::{ops::Invert, CurveArithmetic}; +use group::ff::Field; +use rand_core::CryptoRngCore; +use subtle::CtOption; +use zeroize::Zeroize; + +/// Scalar blinded with a randomly generated masking value. +/// +/// This provides a randomly blinded impl of [`Invert`] which is useful for +/// e.g. ECDSA ephemeral (`k`) scalars. +/// +/// It implements masked variable-time inversions using Stein's algorithm, which +/// may be helpful for performance on embedded platforms. +#[derive(Clone)] +pub struct BlindedScalar +where + C: CurveArithmetic, +{ + /// Actual scalar value. + scalar: Scalar, + + /// Mask value. + mask: Scalar, +} + +impl BlindedScalar +where + C: CurveArithmetic, +{ + /// Create a new [`BlindedScalar`] from a scalar and a [`CryptoRngCore`]. + pub fn new(scalar: Scalar, rng: &mut impl CryptoRngCore) -> Self { + Self { + scalar, + mask: Scalar::::random(rng), + } + } +} + +impl AsRef> for BlindedScalar +where + C: CurveArithmetic, +{ + fn as_ref(&self) -> &Scalar { + &self.scalar + } +} + +impl Invert for BlindedScalar +where + C: CurveArithmetic, +{ + type Output = CtOption>; + + fn invert(&self) -> CtOption> { + // prevent side channel analysis of scalar inversion by pre-and-post-multiplying + // with the random masking scalar + let masked_scalar = self.scalar * self.mask; + invert_vartime::(&masked_scalar).map(|s| s * self.mask) + } +} + +impl Drop for BlindedScalar +where + C: CurveArithmetic, +{ + fn drop(&mut self) { + self.scalar.zeroize(); + self.mask.zeroize(); + } +} diff --git a/elliptic-curve/src/scalar/invert.rs b/elliptic-curve/src/scalar/invert.rs index d0b2bbedd..0b949718e 100644 --- a/elliptic-curve/src/scalar/invert.rs +++ b/elliptic-curve/src/scalar/invert.rs @@ -1,21 +1,18 @@ use super::FromUintUnchecked; use crate::{ops::Shr1, CurveArithmetic, Scalar}; use ff::{Field, PrimeField}; +use subtle::CtOption; /// Fast variable-time inversion using Stein's algorithm. /// -/// Returns `None` if the scalar is zero. +/// Returns none if the scalar is zero. /// /// #[allow(non_snake_case)] -pub fn invert_vartime(scalar: &Scalar) -> Option> +pub fn invert_vartime(scalar: &Scalar) -> CtOption> where C: CurveArithmetic, { - if scalar.is_zero().into() { - return None; - } - let order_div_2 = Scalar::::from_uint_unchecked(C::ORDER >> 1); let mut u = *scalar; @@ -60,5 +57,5 @@ where } } - Some(C) + CtOption::new(C, !scalar.is_zero()) } diff --git a/elliptic-curve/src/scalar/nonzero.rs b/elliptic-curve/src/scalar/nonzero.rs index c9bb6ff68..1d2a7fdae 100644 --- a/elliptic-curve/src/scalar/nonzero.rs +++ b/elliptic-curve/src/scalar/nonzero.rs @@ -76,7 +76,7 @@ where /// sidechannels. pub fn invert_vartime(&self) -> Self { Self { - scalar: super::invert_vartime::(&self.scalar).expect("nonzero input"), + scalar: super::invert_vartime::(&self.scalar).unwrap(), } } } From d041d1fcefeb7b22f34d8d9e63aec75af0ee90df Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 15 Jan 2023 09:20:40 -0700 Subject: [PATCH 0943/1461] signature: use `doc_auto_cfg` (#1209) Replaces manual (redundant) feature annotations with automatic feature documentation --- .github/workflows/signature.yml | 12 ++++++++++++ signature/README.md | 1 + signature/async/src/lib.rs | 3 +-- signature/src/encoding.rs | 1 - signature/src/error.rs | 1 - signature/src/hazmat.rs | 1 - signature/src/lib.rs | 5 +---- signature/src/prehash_signature.rs | 1 - signature/src/signer.rs | 11 ++++------- signature/src/verifier.rs | 1 - 10 files changed, 19 insertions(+), 18 deletions(-) diff --git a/.github/workflows/signature.yml b/.github/workflows/signature.yml index 592915ecf..6f0f8c602 100644 --- a/.github/workflows/signature.yml +++ b/.github/workflows/signature.yml @@ -15,6 +15,7 @@ defaults: env: CARGO_INCREMENTAL: 0 RUSTFLAGS: "-Dwarnings" + RUSTDOCFLAGS: "-Dwarnings" jobs: build: @@ -84,3 +85,14 @@ jobs: profile: minimal - run: cargo test --release working-directory: signature/derive + + doc: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions-rs/toolchain@v1 + with: + toolchain: stable + override: true + profile: minimal + - run: cargo doc --all-features diff --git a/signature/README.md b/signature/README.md index 52ae899de..c3c20e500 100644 --- a/signature/README.md +++ b/signature/README.md @@ -61,6 +61,7 @@ dual licensed as above, without any additional terms or conditions. [//]: # (links) +[RustCrypto]: https://github.com/RustCrypto/ [digital signatures]: https://en.wikipedia.org/wiki/Digital_signature [`dsa`]: https://github.com/RustCrypto/signatures/tree/master/dsa [`ecdsa`]: https://github.com/RustCrypto/signatures/tree/master/ecdsa diff --git a/signature/async/src/lib.rs b/signature/async/src/lib.rs index 2e8bb09f0..8a1cd6415 100644 --- a/signature/async/src/lib.rs +++ b/signature/async/src/lib.rs @@ -3,7 +3,7 @@ html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg" )] -#![cfg_attr(docsrs, feature(doc_cfg))] +#![cfg_attr(docsrs, feature(doc_auto_cfg))] #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms, unused_qualifications)] @@ -47,7 +47,6 @@ where /// /// This trait is an async equivalent of the [`signature::DigestSigner`] trait. #[cfg(feature = "digest")] -#[cfg_attr(docsrs, doc(cfg(feature = "digest")))] #[async_trait] pub trait AsyncDigestSigner where diff --git a/signature/src/encoding.rs b/signature/src/encoding.rs index 1f6010fd4..d8371e433 100644 --- a/signature/src/encoding.rs +++ b/signature/src/encoding.rs @@ -20,7 +20,6 @@ pub trait SignatureEncoding: /// Encode signature as a byte vector. #[cfg(feature = "alloc")] - #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] fn to_vec(&self) -> Vec { self.to_bytes().as_ref().to_vec() } diff --git a/signature/src/error.rs b/signature/src/error.rs index 831dbc89d..1bfaf33bf 100644 --- a/signature/src/error.rs +++ b/signature/src/error.rs @@ -42,7 +42,6 @@ impl Error { /// cases are for propagating errors related to external signers, e.g. /// communication/authentication errors with HSMs, KMS, etc. #[cfg(feature = "std")] - #[cfg_attr(docsrs, doc(cfg(feature = "std")))] pub fn from_source( source: impl Into>, ) -> Self { diff --git a/signature/src/hazmat.rs b/signature/src/hazmat.rs index 3233033c0..5fb17ad60 100644 --- a/signature/src/hazmat.rs +++ b/signature/src/hazmat.rs @@ -34,7 +34,6 @@ pub trait PrehashSigner { /// Sign the provided message prehash using the provided external randomness source, returning a digital signature. #[cfg(feature = "rand-preview")] -#[cfg_attr(docsrs, doc(cfg(feature = "rand-preview")))] pub trait RandomizedPrehashSigner { /// Attempt to sign the given message digest, returning a digital signature /// on success, or an error if something went wrong. diff --git a/signature/src/lib.rs b/signature/src/lib.rs index d35ec5f9a..0fdef65ab 100644 --- a/signature/src/lib.rs +++ b/signature/src/lib.rs @@ -4,7 +4,7 @@ html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg" )] -#![cfg_attr(docsrs, feature(doc_cfg))] +#![cfg_attr(docsrs, feature(doc_auto_cfg))] #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms, unused_qualifications)] @@ -162,16 +162,13 @@ mod prehash_signature; pub use crate::{encoding::*, error::*, keypair::*, signer::*, verifier::*}; #[cfg(feature = "derive")] -#[cfg_attr(docsrs, doc(cfg(feature = "derive")))] pub use derive::{Signer, Verifier}; #[cfg(all(feature = "derive", feature = "digest-preview"))] -#[cfg_attr(docsrs, doc(cfg(all(feature = "derive", feature = "digest-preview"))))] pub use derive::{DigestSigner, DigestVerifier}; #[cfg(feature = "digest-preview")] pub use {crate::prehash_signature::*, digest}; #[cfg(feature = "rand-preview")] -#[cfg_attr(docsrs, doc(cfg(feature = "rand-preview")))] pub use rand_core; diff --git a/signature/src/prehash_signature.rs b/signature/src/prehash_signature.rs index 779b0dcdb..1a2049abd 100644 --- a/signature/src/prehash_signature.rs +++ b/signature/src/prehash_signature.rs @@ -25,7 +25,6 @@ use crate::{ /// types which impl [`DigestVerifier`]. /// /// [Fiat-Shamir heuristic]: https://en.wikipedia.org/wiki/Fiat%E2%80%93Shamir_heuristic -#[cfg_attr(docsrs, doc(cfg(feature = "digest")))] pub trait PrehashSignature { /// Preferred `Digest` algorithm to use when computing this signature type. type Digest: digest::Digest; diff --git a/signature/src/signer.rs b/signature/src/signer.rs index be3de2ec5..2875fc068 100644 --- a/signature/src/signer.rs +++ b/signature/src/signer.rs @@ -24,10 +24,11 @@ pub trait Signer { fn try_sign(&self, msg: &[u8]) -> Result; } -/// Sign the provided message bytestring using `&mut Self` (e.g., an evolving -/// cryptographic key), returning a digital signature. +/// Sign the provided message bytestring using `&mut Self` (e.g. an evolving +/// cryptographic key such as a stateful hash-based signature), returning a +/// digital signature. pub trait SignerMut { - /// Sign the given message, update the state, and return a digital signature + /// Sign the given message, update the state, and return a digital signature. fn sign(&mut self, msg: &[u8]) -> S { self.try_sign(msg).expect("signature operation failed") } @@ -67,7 +68,6 @@ impl> SignerMut for T { /// /// [Fiat-Shamir heuristic]: https://en.wikipedia.org/wiki/Fiat%E2%80%93Shamir_heuristic #[cfg(feature = "digest-preview")] -#[cfg_attr(docsrs, doc(cfg(feature = "digest-preview")))] pub trait DigestSigner { /// Sign the given prehashed message [`Digest`], returning a signature. /// @@ -84,7 +84,6 @@ pub trait DigestSigner { /// Sign the given message using the provided external randomness source. #[cfg(feature = "rand-preview")] -#[cfg_attr(docsrs, doc(cfg(feature = "rand-preview")))] pub trait RandomizedSigner { /// Sign the given message and return a digital signature fn sign_with_rng(&self, rng: &mut impl CryptoRngCore, msg: &[u8]) -> S { @@ -103,8 +102,6 @@ pub trait RandomizedSigner { /// Combination of [`DigestSigner`] and [`RandomizedSigner`] with support for /// computing a signature over a digest which requires entropy from an RNG. #[cfg(all(feature = "digest-preview", feature = "rand-preview"))] -#[cfg_attr(docsrs, doc(cfg(feature = "digest-preview")))] -#[cfg_attr(docsrs, doc(cfg(feature = "rand-preview")))] pub trait RandomizedDigestSigner { /// Sign the given prehashed message `Digest`, returning a signature. /// diff --git a/signature/src/verifier.rs b/signature/src/verifier.rs index 47bfef360..8b993e041 100644 --- a/signature/src/verifier.rs +++ b/signature/src/verifier.rs @@ -35,7 +35,6 @@ pub trait Verifier { /// /// [Fiat-Shamir heuristic]: https://en.wikipedia.org/wiki/Fiat%E2%80%93Shamir_heuristic #[cfg(feature = "digest-preview")] -#[cfg_attr(docsrs, doc(cfg(feature = "digest-preview")))] pub trait DigestVerifier { /// Verify the signature against the given [`Digest`] output. fn verify_digest(&self, digest: D, signature: &S) -> Result<(), Error>; From fa1fec4adbe2fc1869a18a0baf9e82d58ac05e7a Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 15 Jan 2023 09:47:11 -0700 Subject: [PATCH 0944/1461] signature: rename `*-preview` features to crate names (#1210) Renames the following features: - `digest-preview` => `digest` - `rand-preview` => `rand_core` Adding `*-preview` to these features is just needless indirection. Yes, it helped highlight their unstable, out-of-semver nature, but that's something we can also just document. Having the feature names different from what they would prospectively be also makes stabilization harder, since stabilization could otherwise just be bumping the version with the feature names and APIs otherwise unchanged. Since we're in a breaking release cycle, this is a good time to change the names. --- .github/workflows/signature.yml | 6 ++--- signature/Cargo.toml | 7 +----- signature/README.md | 9 ++++--- signature/async/Cargo.toml | 2 +- signature/src/hazmat.rs | 8 ++---- signature/src/lib.rs | 39 ++++++++++-------------------- signature/src/prehash_signature.rs | 4 +-- signature/src/signer.rs | 10 ++++---- signature/src/verifier.rs | 4 +-- signature/tests/derive.rs | 2 +- 10 files changed, 35 insertions(+), 56 deletions(-) diff --git a/.github/workflows/signature.yml b/.github/workflows/signature.yml index 6f0f8c602..bd5934b2c 100644 --- a/.github/workflows/signature.yml +++ b/.github/workflows/signature.yml @@ -39,9 +39,9 @@ jobs: profile: minimal - run: cargo build --target ${{ matrix.target }} --release --no-default-features - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features derive - - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features digest-preview - - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features rand-preview - - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features derive,digest-preview,rand-preview + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features digest + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features rand_core + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features derive,digest,rand_core minimal-versions: uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master diff --git a/signature/Cargo.toml b/signature/Cargo.toml index f81072509..ea1f9db89 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -13,9 +13,9 @@ keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"] categories = ["cryptography", "no-std"] [dependencies] +derive = { package = "signature_derive", version = "=2.0.0-pre.0", optional = true, path = "derive" } digest = { version = "0.10.6", optional = true, default-features = false } rand_core = { version = "0.6.4", optional = true, default-features = false } -derive = { package = "signature_derive", version = "=2.0.0-pre.0", optional = true, path = "derive" } [dev-dependencies] hex-literal = "0.3" @@ -25,11 +25,6 @@ sha2 = { version = "0.10", default-features = false } alloc = [] std = ["alloc"] -# Preview features are unstable and exempt from semver. -# See https://docs.rs/signature/latest/signature/#unstable-features for more information. -digest-preview = ["digest"] -rand-preview = ["rand_core"] - [package.metadata.docs.rs] all-features = true rustdoc-args = ["--cfg", "docsrs"] diff --git a/signature/README.md b/signature/README.md index c3c20e500..6f205d603 100644 --- a/signature/README.md +++ b/signature/README.md @@ -26,10 +26,11 @@ done with a minor version bump. - All on-by-default features of this library are covered by SemVer - MSRV is considered exempt from SemVer as noted above -- The off-by-default features `derive-preview` and `digest-preview` are - unstable "preview" features which are also considered exempt from SemVer. - Breaking changes to these features will, like MSRV, be done with a minor - version bump. +- The `derive` feature is stable and covered by SemVer +- The off-by-default features `digest` and `rand_core` are unstable features + which are also considered exempt from SemVer as they correspond to pre-1.0 + crates which are still subject to changes. Breaking changes to these features + will, like MSRV, be done with a minor version bump. ## License diff --git a/signature/async/Cargo.toml b/signature/async/Cargo.toml index 99073901f..c72705b73 100644 --- a/signature/async/Cargo.toml +++ b/signature/async/Cargo.toml @@ -17,7 +17,7 @@ async-trait = "0.1.9" signature = { version = "=2.0.0-rc.1", path = ".." } [features] -digest = ["signature/digest-preview"] +digest = ["signature/digest"] [package.metadata.docs.rs] all-features = true diff --git a/signature/src/hazmat.rs b/signature/src/hazmat.rs index 5fb17ad60..d2f3e9523 100644 --- a/signature/src/hazmat.rs +++ b/signature/src/hazmat.rs @@ -5,14 +5,10 @@ //! //! Using them incorrectly can introduce security vulnerabilities. Please //! carefully read the documentation before attempting to use them. -//! -//! To use them, enable the `hazmat-preview` crate feature. Note that this -//! feature is semi-unstable and not subject to regular 1.x SemVer guarantees. -//! However, any breaking changes will be accompanied with a minor version bump. use crate::Error; -#[cfg(feature = "rand-preview")] +#[cfg(feature = "rand_core")] use crate::rand_core::CryptoRngCore; /// Sign the provided message prehash, returning a digital signature. @@ -33,7 +29,7 @@ pub trait PrehashSigner { } /// Sign the provided message prehash using the provided external randomness source, returning a digital signature. -#[cfg(feature = "rand-preview")] +#[cfg(feature = "rand_core")] pub trait RandomizedPrehashSigner { /// Attempt to sign the given message digest, returning a digital signature /// on success, or an error if something went wrong. diff --git a/signature/src/lib.rs b/signature/src/lib.rs index 0fdef65ab..a917a6c27 100644 --- a/signature/src/lib.rs +++ b/signature/src/lib.rs @@ -95,8 +95,8 @@ //! //! ## Unstable features //! -//! Despite being post-1.0, this crate includes a number of off-by-default -//! unstable features named `*-preview`, each of which depends on a pre-1.0 +//! Despite being post-1.0, this crate includes off-by-default unstable +//! optional features, each of which depends on a pre-1.0 //! crate. //! //! These features are considered exempt from SemVer. See the @@ -104,21 +104,21 @@ //! //! The following unstable features are presently supported: //! -//! - `derive-preview`: for implementers of signature systems using -//! [`DigestSigner`] and [`DigestVerifier`], the `derive-preview` feature -//! can be used to derive [`Signer`] and [`Verifier`] traits which prehash -//! the input message using the [`PrehashSignature::Digest`] algorithm for -//! a given signature type. When the `derive-preview` feature is enabled +//! - `derive`: for implementers of signature systems using [`DigestSigner`] +//! and [`DigestVerifier`], the `derive` feature can be used to +//! derive [`Signer`] and [`Verifier`] traits which prehash the input +//! message using the [`PrehashSignature::Digest`] algorithm for +//! a given signature type. When the `derive` feature is enabled //! import the proc macros with `use signature::{Signer, Verifier}` and then //! add a `derive(Signer)` or `derive(Verifier)` attribute to the given //! digest signer/verifier type. Enabling this feature also enables `digest` //! support (see immediately below). -//! - `digest-preview`: enables the [`DigestSigner`] and [`DigestVerifier`] +//! - `digest`: enables the [`DigestSigner`] and [`DigestVerifier`] //! traits which are based on the [`Digest`] trait from the [`digest`] crate. //! These traits are used for representing signature systems based on the //! [Fiat-Shamir heuristic] which compute a random challenge value to sign //! by computing a cryptographically secure digest of the input message. -//! - `rand-preview`: enables the [`RandomizedSigner`] trait for signature +//! - `rand_core`: enables the [`RandomizedSigner`] trait for signature //! systems which rely on a cryptographically secure random number generator //! for security. //! @@ -132,22 +132,9 @@ #[cfg(feature = "alloc")] extern crate alloc; - #[cfg(feature = "std")] extern crate std; -#[cfg(all(feature = "digest", not(feature = "digest-preview")))] -compile_error!( - "The `digest` feature should not be enabled directly. \ - Use the `digest-preview` feature instead." -); - -#[cfg(all(feature = "rand_core", not(feature = "rand-preview")))] -compile_error!( - "The `rand_core` feature should not be enabled directly. \ - Use the `rand-preview` feature instead." -); - pub mod hazmat; mod encoding; @@ -156,7 +143,7 @@ mod keypair; mod signer; mod verifier; -#[cfg(feature = "digest-preview")] +#[cfg(feature = "digest")] mod prehash_signature; pub use crate::{encoding::*, error::*, keypair::*, signer::*, verifier::*}; @@ -164,11 +151,11 @@ pub use crate::{encoding::*, error::*, keypair::*, signer::*, verifier::*}; #[cfg(feature = "derive")] pub use derive::{Signer, Verifier}; -#[cfg(all(feature = "derive", feature = "digest-preview"))] +#[cfg(all(feature = "derive", feature = "digest"))] pub use derive::{DigestSigner, DigestVerifier}; -#[cfg(feature = "digest-preview")] +#[cfg(feature = "digest")] pub use {crate::prehash_signature::*, digest}; -#[cfg(feature = "rand-preview")] +#[cfg(feature = "rand_core")] pub use rand_core; diff --git a/signature/src/prehash_signature.rs b/signature/src/prehash_signature.rs index 1a2049abd..d9a86456d 100644 --- a/signature/src/prehash_signature.rs +++ b/signature/src/prehash_signature.rs @@ -19,8 +19,8 @@ use crate::{ /// This approach is relatively common in signature schemes based on the /// [Fiat-Shamir heuristic]. /// -/// For signature types that implement this trait, when the `derive-preview` -/// Cargo feature is enabled a custom derive for [`Signer`] is available for any +/// For signature types that implement this trait, when the `derive` crate +/// feature is enabled a custom derive for [`Signer`] is available for any /// types that impl [`DigestSigner`], and likewise for deriving [`Verifier`] for /// types which impl [`DigestVerifier`]. /// diff --git a/signature/src/signer.rs b/signature/src/signer.rs index 2875fc068..b339ddf59 100644 --- a/signature/src/signer.rs +++ b/signature/src/signer.rs @@ -2,10 +2,10 @@ use crate::error::Error; -#[cfg(feature = "digest-preview")] +#[cfg(feature = "digest")] use crate::digest::Digest; -#[cfg(feature = "rand-preview")] +#[cfg(feature = "rand_core")] use crate::rand_core::CryptoRngCore; /// Sign the provided message bytestring using `Self` (e.g. a cryptographic key @@ -67,7 +67,7 @@ impl> SignerMut for T { /// API accepts a [`Digest`] instance, rather than a raw digest value. /// /// [Fiat-Shamir heuristic]: https://en.wikipedia.org/wiki/Fiat%E2%80%93Shamir_heuristic -#[cfg(feature = "digest-preview")] +#[cfg(feature = "digest")] pub trait DigestSigner { /// Sign the given prehashed message [`Digest`], returning a signature. /// @@ -83,7 +83,7 @@ pub trait DigestSigner { } /// Sign the given message using the provided external randomness source. -#[cfg(feature = "rand-preview")] +#[cfg(feature = "rand_core")] pub trait RandomizedSigner { /// Sign the given message and return a digital signature fn sign_with_rng(&self, rng: &mut impl CryptoRngCore, msg: &[u8]) -> S { @@ -101,7 +101,7 @@ pub trait RandomizedSigner { /// Combination of [`DigestSigner`] and [`RandomizedSigner`] with support for /// computing a signature over a digest which requires entropy from an RNG. -#[cfg(all(feature = "digest-preview", feature = "rand-preview"))] +#[cfg(all(feature = "digest", feature = "rand_core"))] pub trait RandomizedDigestSigner { /// Sign the given prehashed message `Digest`, returning a signature. /// diff --git a/signature/src/verifier.rs b/signature/src/verifier.rs index 8b993e041..65409a929 100644 --- a/signature/src/verifier.rs +++ b/signature/src/verifier.rs @@ -2,7 +2,7 @@ use crate::error::Error; -#[cfg(feature = "digest-preview")] +#[cfg(feature = "digest")] use crate::digest::Digest; /// Verify the provided message bytestring using `Self` (e.g. a public key) @@ -34,7 +34,7 @@ pub trait Verifier { /// API accepts a [`Digest`] instance, rather than a raw digest value. /// /// [Fiat-Shamir heuristic]: https://en.wikipedia.org/wiki/Fiat%E2%80%93Shamir_heuristic -#[cfg(feature = "digest-preview")] +#[cfg(feature = "digest")] pub trait DigestVerifier { /// Verify the signature against the given [`Digest`] output. fn verify_digest(&self, digest: D, signature: &S) -> Result<(), Error>; diff --git a/signature/tests/derive.rs b/signature/tests/derive.rs index 684aca66f..70e2dc0fc 100644 --- a/signature/tests/derive.rs +++ b/signature/tests/derive.rs @@ -1,6 +1,6 @@ //! Tests for code generated by `signature_derive` -#![cfg(all(feature = "derive-preview", feature = "hazmat-preview"))] +#![cfg(feature = "derive")] use digest::{generic_array::GenericArray, Digest, OutputSizeUser}; use hex_literal::hex; From 115d2316ff1ffda1e7a15ad367b2c0e4d09960fc Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 15 Jan 2023 11:59:37 -0700 Subject: [PATCH 0945/1461] signature v2.0.0 (#1211) --- Cargo.lock | 8 ++++---- crypto/Cargo.toml | 2 +- signature/CHANGELOG.md | 24 ++++++++++++++++++++++++ signature/Cargo.toml | 4 ++-- signature/LICENSE-MIT | 2 +- signature/async/Cargo.toml | 2 +- signature/derive/CHANGELOG.md | 6 ++++++ signature/derive/Cargo.toml | 2 +- signature/src/lib.rs | 9 ++++++++- 9 files changed, 48 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b83a06492..129befc76 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -53,7 +53,7 @@ name = "async-signature" version = "0.3.0-pre" dependencies = [ "async-trait", - "signature 2.0.0-rc.1", + "signature 2.0.0", ] [[package]] @@ -255,7 +255,7 @@ dependencies = [ "digest 0.10.6", "elliptic-curve 0.12.3", "password-hash", - "signature 2.0.0-rc.1", + "signature 2.0.0", "universal-hash 0.5.0", ] @@ -957,7 +957,7 @@ dependencies = [ [[package]] name = "signature" -version = "2.0.0-rc.1" +version = "2.0.0" dependencies = [ "digest 0.10.6", "hex-literal", @@ -968,7 +968,7 @@ dependencies = [ [[package]] name = "signature_derive" -version = "2.0.0-pre.0" +version = "2.0.0" dependencies = [ "proc-macro2", "quote", diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index daef44770..1462189ee 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -23,7 +23,7 @@ cipher = { version = "0.4", optional = true } digest = { version = "0.10", optional = true, features = ["mac"] } elliptic-curve = { version = "0.12", optional = true } # path = "../elliptic-curve" password-hash = { version = "=0.5.0-pre.0", optional = true, path = "../password-hash" } -signature = { version = "=2.0.0-rc.1", optional = true, default-features = false, path = "../signature" } +signature = { version = "2", optional = true, default-features = false, path = "../signature" } universal-hash = { version = "0.5", optional = true, path = "../universal-hash" } [features] diff --git a/signature/CHANGELOG.md b/signature/CHANGELOG.md index 86198d54c..65a1c8c1f 100644 --- a/signature/CHANGELOG.md +++ b/signature/CHANGELOG.md @@ -4,6 +4,30 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 2.0.0 (2023-01-15) +### Added +- `SignatureEncoding` trait as a replacement for `Signature` trait and the + now removed `AsRef<[u8]>` bound on signatures ([#1141]) +- New `Keypair` trait which returns owned keys instead of borrowed ([#1141]) + +### Changed +- `derive-preview` has been renamed to `derive` and stabilized ([#1141]) +- `digest-preview` renamed to `digest`, still unstable ([#1210]) +- `hazmat-preview` feature stabilized and removed, always on ([#1141]) +- `rand-preview` renamed to `rand_core`, still unstable ([#1210]) +- `std` feature is no longer enabled by default ([#1141]) +- Old `Keypair` trait renamed to `KeypairRef` ([#1141]) +- Signature generic parameter removed from `Keypair`/`KeypairRef` ([#1141]) +- Use `&mut impl CryptoRngCore` RNG arguments ([#1147]) + +### Removed +- `Signature` trait - replaced by `SignatureEncoding` ([#1141]) +- `hazmat-preview` feature, now always on ([#1141]) + +[#1141]: https://github.com/RustCrypto/traits/pull/1141 +[#1147]: https://github.com/RustCrypto/traits/pull/1147 +[#1210]: https://github.com/RustCrypto/traits/pull/1141 + ## 1.6.4 (2022-10-06) ### Added - `RandomizedPrehashSigner` trait in `hazmat` module ([#1130]) diff --git a/signature/Cargo.toml b/signature/Cargo.toml index ea1f9db89..eab41d760 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "2.0.0-rc.1" +version = "2.0.0" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/signature" @@ -13,7 +13,7 @@ keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"] categories = ["cryptography", "no-std"] [dependencies] -derive = { package = "signature_derive", version = "=2.0.0-pre.0", optional = true, path = "derive" } +derive = { package = "signature_derive", version = "2", optional = true, path = "derive" } digest = { version = "0.10.6", optional = true, default-features = false } rand_core = { version = "0.6.4", optional = true, default-features = false } diff --git a/signature/LICENSE-MIT b/signature/LICENSE-MIT index 81a3d57ac..d8d87fe29 100644 --- a/signature/LICENSE-MIT +++ b/signature/LICENSE-MIT @@ -1,4 +1,4 @@ -Copyright (c) 2018-2022 RustCrypto Developers +Copyright (c) 2018-2023 RustCrypto Developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated diff --git a/signature/async/Cargo.toml b/signature/async/Cargo.toml index c72705b73..680416e7c 100644 --- a/signature/async/Cargo.toml +++ b/signature/async/Cargo.toml @@ -14,7 +14,7 @@ rust-version = "1.56" [dependencies] async-trait = "0.1.9" -signature = { version = "=2.0.0-rc.1", path = ".." } +signature = { version = "2", path = ".." } [features] digest = ["signature/digest"] diff --git a/signature/derive/CHANGELOG.md b/signature/derive/CHANGELOG.md index 65caa4655..cfe4bb995 100644 --- a/signature/derive/CHANGELOG.md +++ b/signature/derive/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 2.0.0 (2023-01-15) +### Changed +- `Signature` trait has been removed, so don't emit it in custom derive ([#1141]) + +[#1141]: https://github.com/RustCrypto/traits/pull/1141 + ## 1.0.0-pre.7 (2022-09-16) ### Fixed - Support for `where` bounds ([#1118]) diff --git a/signature/derive/Cargo.toml b/signature/derive/Cargo.toml index 294a39474..cdd59e5cf 100644 --- a/signature/derive/Cargo.toml +++ b/signature/derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "signature_derive" -version = "2.0.0-pre.0" +version = "2.0.0" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" description = "Custom derive support for the 'signature' crate" diff --git a/signature/src/lib.rs b/signature/src/lib.rs index a917a6c27..ba1feb494 100644 --- a/signature/src/lib.rs +++ b/signature/src/lib.rs @@ -6,7 +6,14 @@ )] #![cfg_attr(docsrs, feature(doc_auto_cfg))] #![forbid(unsafe_code)] -#![warn(missing_docs, rust_2018_idioms, unused_qualifications)] +#![warn( + clippy::mod_module_files, + clippy::unwrap_used, + missing_docs, + rust_2018_idioms, + unused_lifetimes, + unused_qualifications +)] //! # Design //! From e791364e071f727410196a854bb14b8ce4faa8da Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 15 Jan 2023 12:20:01 -0700 Subject: [PATCH 0946/1461] async-signature v0.3.0 (#1212) --- Cargo.lock | 2 +- signature/async/CHANGELOG.md | 10 ++++++++++ signature/async/Cargo.toml | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 129befc76..955b65f92 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -50,7 +50,7 @@ dependencies = [ [[package]] name = "async-signature" -version = "0.3.0-pre" +version = "0.3.0" dependencies = [ "async-trait", "signature 2.0.0", diff --git a/signature/async/CHANGELOG.md b/signature/async/CHANGELOG.md index 754c8d55a..ae44dcb7b 100644 --- a/signature/async/CHANGELOG.md +++ b/signature/async/CHANGELOG.md @@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.3.0 (2022-01-15) +### Changed +- Bump `signature` to v2 ([#1141], [#1211]) + +### Removed +- `AsyncKeypair` is no longer needed due to `signature` v2 bounds changes ([#1141]) + +[#1141]: https://github.com/RustCrypto/traits/pull/1141 +[#1211]: https://github.com/RustCrypto/traits/pull/1211 + ## 0.2.1 (2022-09-15) ### Changed - Relax `AsyncKeypair` bounds ([#1107]) diff --git a/signature/async/Cargo.toml b/signature/async/Cargo.toml index 680416e7c..227fd439b 100644 --- a/signature/async/Cargo.toml +++ b/signature/async/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "async-signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "0.3.0-pre" +version = "0.3.0" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/async-signature" From 2329564ce0cdaa2743985e44ecf6fab4a8719654 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 15 Jan 2023 12:35:33 -0700 Subject: [PATCH 0947/1461] async-signature: fix `signature` version requirement (#1213) It uses the `digest` feature, which means version updates need to be coordinates around minor versions. --- signature/async/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/signature/async/Cargo.toml b/signature/async/Cargo.toml index 227fd439b..178e57e0b 100644 --- a/signature/async/Cargo.toml +++ b/signature/async/Cargo.toml @@ -14,7 +14,7 @@ rust-version = "1.56" [dependencies] async-trait = "0.1.9" -signature = { version = "2", path = ".." } +signature = { version = "2.0, <2.1", path = ".." } [features] digest = ["signature/digest"] From 778e6f4368422f87ba5d667095673423f8abccda Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 19 Jan 2023 11:30:34 -0700 Subject: [PATCH 0948/1461] README.md: remove copypasta (#1215) This seems to have originally come from the `signature` crate --- kem/README.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/kem/README.md b/kem/README.md index b989278a7..3be7d0cf9 100644 --- a/kem/README.md +++ b/kem/README.md @@ -24,10 +24,6 @@ done with a minor version bump. - All on-by-default features of this library are covered by SemVer - MSRV is considered exempt from SemVer as noted above -- The off-by-default features `derive-preview` and `digest-preview` are - unstable "preview" features which are also considered exempt from SemVer. - Breaking changes to these features will, like MSRV, be done with a minor - version bump. ## License From 5916a017b616a51f1cc321df3b1ab0566186630c Mon Sep 17 00:00:00 2001 From: daxpedda Date: Thu, 26 Jan 2023 21:46:42 +0100 Subject: [PATCH 0949/1461] elliptic-curve: expand `NonIdentity` usage (#1217) --- elliptic-curve/src/lib.rs | 2 +- elliptic-curve/src/point/non_identity.rs | 43 ++++++++++++++++++++++-- elliptic-curve/src/public_key.rs | 25 +++++++++++++- 3 files changed, 65 insertions(+), 5 deletions(-) diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 1c55378fe..d13365992 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -69,6 +69,7 @@ extern crate alloc; extern crate std; pub mod ops; +pub mod point; pub mod scalar; #[cfg(feature = "dev")] @@ -83,7 +84,6 @@ pub mod sec1; pub mod weierstrass; mod error; -mod point; mod secret_key; #[cfg(feature = "arithmetic")] diff --git a/elliptic-curve/src/point/non_identity.rs b/elliptic-curve/src/point/non_identity.rs index 075e3a94d..81c31cd19 100644 --- a/elliptic-curve/src/point/non_identity.rs +++ b/elliptic-curve/src/point/non_identity.rs @@ -1,6 +1,6 @@ //! Non-identity point type. -use core::ops::Deref; +use core::ops::{Deref, Mul}; use group::{prime::PrimeCurveAffine, Curve, GroupEncoding}; use rand_core::{CryptoRng, RngCore}; @@ -9,6 +9,8 @@ use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; #[cfg(feature = "serde")] use serdect::serde::{de, ser, Deserialize, Serialize}; +use crate::{CurveArithmetic, NonZeroScalar, Scalar}; + /// Non-identity point type. /// /// This type ensures that its value is not the identity point, ala `core::num::NonZero*`. @@ -22,13 +24,22 @@ pub struct NonIdentity

{ impl

NonIdentity

where - P: ConditionallySelectable + ConstantTimeEq + Default + GroupEncoding, + P: ConditionallySelectable + ConstantTimeEq + Default, { /// Create a [`NonIdentity`] from a point. pub fn new(point: P) -> CtOption { CtOption::new(Self { point }, !point.ct_eq(&P::default())) } + pub(crate) fn new_unchecked(point: P) -> Self { + Self { point } + } +} + +impl

NonIdentity

+where + P: ConditionallySelectable + ConstantTimeEq + Default + GroupEncoding, +{ /// Decode a [`NonIdentity`] from its encoding. pub fn from_repr(repr: &P::Repr) -> CtOption { Self::from_bytes(repr) @@ -44,7 +55,7 @@ impl NonIdentity

{ impl

NonIdentity

where - P: ConditionallySelectable + ConstantTimeEq + Curve + Default + GroupEncoding, + P: ConditionallySelectable + ConstantTimeEq + Curve + Default, { /// Generate a random `NonIdentity`. pub fn random(mut rng: impl CryptoRng + RngCore) -> Self { @@ -129,6 +140,32 @@ where } } +impl Mul> for NonIdentity

+where + C: CurveArithmetic, + P: Copy + Mul, Output = P>, +{ + type Output = NonIdentity

; + + fn mul(self, rhs: NonZeroScalar) -> Self::Output { + &self * &rhs + } +} + +impl Mul<&NonZeroScalar> for &NonIdentity

+where + C: CurveArithmetic, + P: Copy + Mul, Output = P>, +{ + type Output = NonIdentity

; + + fn mul(self, rhs: &NonZeroScalar) -> Self::Output { + NonIdentity { + point: self.point * *rhs.as_ref(), + } + } +} + #[cfg(feature = "serde")] impl

Serialize for NonIdentity

where diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index a916cd8a8..045a1aa6a 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -155,6 +155,11 @@ where self.point.into() } + /// Convert this [`PublicKey`] to a [`NonIdentity`] of the inner [`AffinePoint`] + pub fn to_non_identity(&self) -> NonIdentity> { + NonIdentity::new_unchecked(self.point) + } + /// Parse a [`JwkEcKey`] JSON Web Key (JWK) into a [`PublicKey`]. #[cfg(feature = "jwk")] pub fn from_jwk(jwk: &JwkEcKey) -> Result @@ -271,7 +276,7 @@ where P: Copy + Into>, { fn from(value: NonIdentity

) -> Self { - PublicKey::from(&value) + Self::from(&value) } } @@ -287,6 +292,24 @@ where } } +impl From> for NonIdentity> +where + C: CurveArithmetic, +{ + fn from(value: PublicKey) -> Self { + Self::from(&value) + } +} + +impl From<&PublicKey> for NonIdentity> +where + C: CurveArithmetic, +{ + fn from(value: &PublicKey) -> Self { + PublicKey::to_non_identity(value) + } +} + #[cfg(feature = "sec1")] impl PartialOrd for PublicKey where From 2307a33368032c4834540f0de6aecd6e154b1fff Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 26 Jan 2023 19:41:53 -0700 Subject: [PATCH 0950/1461] elliptic-curve: add `point::Double` (#1218) This is useful for supporting multiple potential `Double` implementations in generic code. See RustCrypto/elliptic-curves#728 for an example. --- elliptic-curve/src/point.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/elliptic-curve/src/point.rs b/elliptic-curve/src/point.rs index bce130c11..0584e2e28 100644 --- a/elliptic-curve/src/point.rs +++ b/elliptic-curve/src/point.rs @@ -24,6 +24,12 @@ pub trait AffineYIsOdd { fn y_is_odd(&self) -> Choice; } +/// Double a point (i.e. add it to itself) +pub trait Double { + /// Double this point. + fn double(&self) -> Self; +} + /// Decompress an elliptic curve point. /// /// Point decompression recovers an original curve point from its x-coordinate From 462d35f5c2677e6fba540fa2e4d7bf2c01291ca5 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 27 Jan 2023 10:47:11 -0700 Subject: [PATCH 0951/1461] elliptic-curve: refactor field element decoding/encoding (#1220) Previously `FieldBytes` was defined in terms of `C::Uint::ByteSize`, which lead to it being improperly sized for curves with unusual modulus sizes like P-224 and P-521 (which aren't multiples of 64). This commit adds an associated `C::FieldBytesSize` which makes it possible to specifically define the size of a serialized field element. The previous `FieldSize` type alias is retained as `FieldBytesSize`, which handles specifying that the associated type should be accessed using `Curve::FieldBytesSize`. To handle potential discrepancies between `C::Uint::ByteSize` and `C::FieldBytesSize`, provided `Curve::decode_field_bytes` and `Curve::encode_field_bytes` methods have been added for handling decoding/encoding serialized field elements to/from `C::Uint`. The methods use a default big endian serialization. Now that curves can customize the endianness used for encoding field elements, this eliminates the need to have separate `from_be_bytes`/`from_le_bytes` and `to_be_bytes`/`to_le_bytes` methods. Instead the endianness can be known a priori, which eliminates the need for the caller to select a specific endianness. As such, this PR folds these methods (defined on e.g. `ScalarPrimitive` and `NonZeroScalar`) into `from_bytes` and `to_bytes`. --- elliptic-curve/src/dev.rs | 6 +- elliptic-curve/src/field.rs | 10 +++ elliptic-curve/src/jwk.rs | 30 ++++----- elliptic-curve/src/lib.rs | 91 ++++++++++++++------------ elliptic-curve/src/point.rs | 12 +++- elliptic-curve/src/public_key.rs | 40 +++++------ elliptic-curve/src/scalar/nonzero.rs | 5 +- elliptic-curve/src/scalar/primitive.rs | 46 ++++--------- elliptic-curve/src/sec1.rs | 18 ++--- elliptic-curve/src/secret_key.rs | 52 ++++++++------- elliptic-curve/src/secret_key/pkcs8.rs | 10 +-- elliptic-curve/src/voprf.rs | 20 ++++++ elliptic-curve/tests/pkcs8.rs | 4 +- elliptic-curve/tests/secret_key.rs | 2 +- 14 files changed, 191 insertions(+), 155 deletions(-) create mode 100644 elliptic-curve/src/field.rs create mode 100644 elliptic-curve/src/voprf.rs diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index ded320769..9971b8999 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -6,6 +6,7 @@ use crate::{ bigint::{Limb, U256}, error::{Error, Result}, + generic_array::typenum::U32, ops::{LinearCombination, MulByGenerator, Reduce, Shr1}, pkcs8, rand_core::RngCore, @@ -65,6 +66,7 @@ pub type ScalarBits = crate::ScalarBits; pub struct MockCurve; impl Curve for MockCurve { + type FieldBytesSize = U32; type Uint = U256; const ORDER: U256 = @@ -150,11 +152,11 @@ impl PrimeField for Scalar { const DELTA: Self = Self::ZERO; // BOGUS! fn from_repr(bytes: FieldBytes) -> CtOption { - ScalarPrimitive::from_be_bytes(bytes).map(Self) + ScalarPrimitive::from_bytes(&bytes).map(Self) } fn to_repr(&self) -> FieldBytes { - self.0.to_be_bytes() + self.0.to_bytes() } fn is_odd(&self) -> Choice { diff --git a/elliptic-curve/src/field.rs b/elliptic-curve/src/field.rs new file mode 100644 index 000000000..d1cae0179 --- /dev/null +++ b/elliptic-curve/src/field.rs @@ -0,0 +1,10 @@ +//! Field elements. + +use crate::Curve; +use generic_array::GenericArray; + +/// Size of serialized field elements of this elliptic curve. +pub type FieldBytesSize = ::FieldBytesSize; + +/// Byte representation of a base/scalar field element of a given curve. +pub type FieldBytes = GenericArray>; diff --git a/elliptic-curve/src/jwk.rs b/elliptic-curve/src/jwk.rs index cac1f79ba..0c13d3e97 100644 --- a/elliptic-curve/src/jwk.rs +++ b/elliptic-curve/src/jwk.rs @@ -6,7 +6,7 @@ use crate::{ sec1::{Coordinates, EncodedPoint, ModulusSize, ValidatePublicKey}, secret_key::SecretKey, - Curve, Error, FieldBytes, FieldSize, Result, + Curve, Error, FieldBytes, FieldBytesSize, Result, }; use alloc::{ borrow::ToOwned, @@ -112,7 +112,7 @@ impl JwkEcKey { where C: CurveArithmetic + JwkParameters, AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { PublicKey::from_sec1_bytes(self.to_encoded_point::()?.as_bytes()) } @@ -121,7 +121,7 @@ impl JwkEcKey { pub fn from_encoded_point(point: &EncodedPoint) -> Option where C: Curve + JwkParameters, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { match point.coordinates() { Coordinates::Uncompressed { x, y } => Some(JwkEcKey { @@ -138,7 +138,7 @@ impl JwkEcKey { pub fn to_encoded_point(&self) -> Result> where C: Curve + JwkParameters, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { if self.crv != C::CRV { return Err(Error); @@ -154,7 +154,7 @@ impl JwkEcKey { pub fn to_secret_key(&self) -> Result> where C: Curve + JwkParameters + ValidatePublicKey, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { self.try_into() } @@ -177,7 +177,7 @@ impl ToString for JwkEcKey { impl TryFrom for SecretKey where C: Curve + JwkParameters + ValidatePublicKey, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { type Error = Error; @@ -189,7 +189,7 @@ where impl TryFrom<&JwkEcKey> for SecretKey where C: Curve + JwkParameters + ValidatePublicKey, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { type Error = Error; @@ -197,7 +197,7 @@ where if let Some(d_base64) = &jwk.d { let pk = jwk.to_encoded_point::()?; let mut d_bytes = decode_base64url_fe::(d_base64)?; - let result = SecretKey::from_be_bytes(&d_bytes); + let result = SecretKey::from_slice(&d_bytes); d_bytes.zeroize(); result.and_then(|secret_key| { @@ -215,7 +215,7 @@ impl From> for JwkEcKey where C: CurveArithmetic + JwkParameters, AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { fn from(sk: SecretKey) -> JwkEcKey { (&sk).into() @@ -227,11 +227,11 @@ impl From<&SecretKey> for JwkEcKey where C: CurveArithmetic + JwkParameters, AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { fn from(sk: &SecretKey) -> JwkEcKey { let mut jwk = sk.public_key().to_jwk(); - let mut d = sk.to_be_bytes(); + let mut d = sk.to_bytes(); jwk.d = Some(Base64Url::encode_string(&d)); d.zeroize(); jwk @@ -243,7 +243,7 @@ impl TryFrom for PublicKey where C: CurveArithmetic + JwkParameters, AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { type Error = Error; @@ -257,7 +257,7 @@ impl TryFrom<&JwkEcKey> for PublicKey where C: CurveArithmetic + JwkParameters, AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { type Error = Error; @@ -271,7 +271,7 @@ impl From> for JwkEcKey where C: CurveArithmetic + JwkParameters, AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { fn from(pk: PublicKey) -> JwkEcKey { (&pk).into() @@ -283,7 +283,7 @@ impl From<&PublicKey> for JwkEcKey where C: CurveArithmetic + JwkParameters, AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { fn from(pk: &PublicKey) -> JwkEcKey { Self::from_encoded_point::(&pk.to_encoded_point(false)).expect("JWK encoding error") diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index d13365992..04b0ad10b 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -27,8 +27,10 @@ //! - [`bp256`]: brainpoolP256r1 and brainpoolP256t1 //! - [`bp384`]: brainpoolP384r1 and brainpoolP384t1 //! - [`k256`]: secp256k1 a.k.a. K-256 +//! - [`p224`]: NIST P-224 a.k.a. secp224r1 //! - [`p256`]: NIST P-256 a.k.a secp256r1, prime256v1 //! - [`p384`]: NIST P-384 a.k.a. secp384r1 +//! - [`p521`]: NIST P-521 a.k.a. secp521r1 //! //! The [`ecdsa`] crate provides a generic implementation of the //! Elliptic Curve Digital Signature Algorithm which can be used with any of @@ -57,8 +59,10 @@ //! [`bp256`]: https://github.com/RustCrypto/elliptic-curves/tree/master/bp256 //! [`bp384`]: https://github.com/RustCrypto/elliptic-curves/tree/master/bp384 //! [`k256`]: https://github.com/RustCrypto/elliptic-curves/tree/master/k256 +//! [`p224`]: https://github.com/RustCrypto/elliptic-curves/tree/master/p224 //! [`p256`]: https://github.com/RustCrypto/elliptic-curves/tree/master/p256 //! [`p384`]: https://github.com/RustCrypto/elliptic-curves/tree/master/p384 +//! [`p521`]: https://github.com/RustCrypto/elliptic-curves/tree/master/p521 //! [`ecdsa`]: https://github.com/RustCrypto/signatures/tree/master/ecdsa #[cfg(feature = "alloc")] @@ -84,6 +88,7 @@ pub mod sec1; pub mod weierstrass; mod error; +mod field; mod secret_key; #[cfg(feature = "arithmetic")] @@ -94,8 +99,12 @@ mod public_key; #[cfg(feature = "jwk")] mod jwk; +#[cfg(feature = "voprf")] +mod voprf; + pub use crate::{ error::{Error, Result}, + field::{FieldBytes, FieldBytesSize}, point::{ AffineXCoordinate, AffineYIsOdd, DecompactPoint, DecompressPoint, PointCompaction, PointCompression, @@ -113,6 +122,7 @@ pub use zeroize; pub use { crate::{ arithmetic::{CurveArithmetic, PrimeCurveArithmetic}, + point::{AffinePoint, ProjectivePoint}, public_key::PublicKey, scalar::{NonZeroScalar, Scalar}, }, @@ -129,8 +139,15 @@ pub use crate::jwk::{JwkEcKey, JwkParameters}; #[cfg(feature = "pkcs8")] pub use pkcs8; -use core::{fmt::Debug, ops::ShrAssign}; -use generic_array::GenericArray; +#[cfg(feature = "voprf")] +pub use crate::voprf::VoprfParameters; + +use core::{ + fmt::Debug, + ops::{Add, ShrAssign}, +}; +use crypto_bigint::{ArrayEncoding, ByteArray}; +use generic_array::{typenum::Unsigned, ArrayLength}; /// Algorithm [`ObjectIdentifier`][`pkcs8::ObjectIdentifier`] for elliptic /// curve public key cryptography (`id-ecPublicKey`). @@ -149,11 +166,15 @@ pub const ALGORITHM_OID: pkcs8::ObjectIdentifier = /// be impl'd by these ZSTs, facilitating types which are generic over elliptic /// curves (e.g. [`SecretKey`]). pub trait Curve: 'static + Copy + Clone + Debug + Default + Eq + Ord + Send + Sync { + /// Size of a serialized field element in bytes. + /// + /// This is typically the same as `Self::Uint::ByteSize` but for curves + /// with an unusual field modulus (e.g. P-224, P-521) it may be different. + type FieldBytesSize: ArrayLength + Add + Eq; + /// Integer type used to represent field elements of this elliptic curve. - // TODO(tarcieri): replace this with an e.g. `const Curve::MODULUS: Uint`. - // Requires rust-lang/rust#60551, i.e. `const_evaluatable_checked` type Uint: bigint::AddMod - + bigint::ArrayEncoding + + ArrayEncoding + bigint::Encoding + bigint::Integer + bigint::NegMod @@ -163,44 +184,32 @@ pub trait Curve: 'static + Copy + Clone + Debug + Default + Eq + Ord + Send + Sy + zeroize::Zeroize + ShrAssign; - /// Order constant. - /// - /// Subdivided into either 32-bit or 64-bit "limbs" (depending on the - /// target CPU's word size), specified from least to most significant. + /// Order of this elliptic curve, i.e. number of elements in the scalar + /// field. const ORDER: Self::Uint; -} - -/// Marker trait for elliptic curves with prime order. -pub trait PrimeCurve: Curve {} -/// Size of field elements of this elliptic curve. -pub type FieldSize = <::Uint as bigint::ArrayEncoding>::ByteSize; - -/// Byte representation of a base/scalar field element of a given curve. -pub type FieldBytes = GenericArray>; - -/// Affine point type for a given curve with a [`CurveArithmetic`] -/// implementation. -#[cfg(feature = "arithmetic")] -pub type AffinePoint = ::AffinePoint; - -/// Projective point type for a given curve with a [`CurveArithmetic`] -/// implementation. -#[cfg(feature = "arithmetic")] -pub type ProjectivePoint = ::ProjectivePoint; - -/// Elliptic curve parameters used by VOPRF. -#[cfg(feature = "voprf")] -pub trait VoprfParameters: Curve { - /// The `ID` parameter which identifies a particular elliptic curve - /// as defined in [section 4 of `draft-irtf-cfrg-voprf-08`][voprf]. + /// Decode unsigned integer from serialized field element. /// - /// [voprf]: https://www.ietf.org/archive/id/draft-irtf-cfrg-voprf-08.html#section-4 - const ID: u16; - - /// The `Hash` parameter which assigns a particular hash function to this - /// ciphersuite as defined in [section 4 of `draft-irtf-cfrg-voprf-08`][voprf]. + /// The default implementation assumes a big endian encoding. + fn decode_field_bytes(field_bytes: &FieldBytes) -> Self::Uint { + debug_assert!(field_bytes.len() <= ::ByteSize::USIZE); + let mut byte_array = ByteArray::::default(); + byte_array[..field_bytes.len()].copy_from_slice(field_bytes); + Self::Uint::from_be_byte_array(byte_array) + } + + /// Encode unsigned integer into serialized field element. /// - /// [voprf]: https://www.ietf.org/archive/id/draft-irtf-cfrg-voprf-08.html#section-4 - type Hash: digest::Digest; + /// The default implementation assumes a big endian encoding. + fn encode_field_bytes(uint: &Self::Uint) -> FieldBytes { + let mut field_bytes = FieldBytes::::default(); + debug_assert!(field_bytes.len() <= ::ByteSize::USIZE); + + let len = field_bytes.len(); + field_bytes.copy_from_slice(&uint.to_be_byte_array()[..len]); + field_bytes + } } + +/// Marker trait for elliptic curves with prime order. +pub trait PrimeCurve: Curve {} diff --git a/elliptic-curve/src/point.rs b/elliptic-curve/src/point.rs index 0584e2e28..6dd3b0908 100644 --- a/elliptic-curve/src/point.rs +++ b/elliptic-curve/src/point.rs @@ -4,11 +4,21 @@ mod non_identity; #[cfg(feature = "arithmetic")] -pub use self::non_identity::NonIdentity; +pub use {self::non_identity::NonIdentity, crate::CurveArithmetic}; use crate::{Curve, FieldBytes}; use subtle::{Choice, CtOption}; +/// Affine point type for a given curve with a [`CurveArithmetic`] +/// implementation. +#[cfg(feature = "arithmetic")] +pub type AffinePoint = ::AffinePoint; + +/// Projective point type for a given curve with a [`CurveArithmetic`] +/// implementation. +#[cfg(feature = "arithmetic")] +pub type ProjectivePoint = ::ProjectivePoint; + /// Obtain the affine x-coordinate of an elliptic curve point. pub trait AffineXCoordinate { /// Field element representation. diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index 045a1aa6a..e5f67edc0 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -19,7 +19,7 @@ use core::str::FromStr; use { crate::{ sec1::{EncodedPoint, FromEncodedPoint, ModulusSize, ToEncodedPoint}, - Curve, FieldSize, PointCompression, + Curve, FieldBytesSize, PointCompression, }, core::cmp::Ordering, subtle::CtOption, @@ -119,7 +119,7 @@ where pub fn from_sec1_bytes(bytes: &[u8]) -> Result where C: Curve, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, AffinePoint: FromEncodedPoint + ToEncodedPoint, { let point = EncodedPoint::::from_bytes(bytes).map_err(|_| Error)?; @@ -137,7 +137,7 @@ where where C: CurveArithmetic + PointCompression, AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { let point = EncodedPoint::::from(self); point.to_bytes() @@ -166,7 +166,7 @@ where where C: Curve + JwkParameters, AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { jwk.to_public_key::() } @@ -177,7 +177,7 @@ where where C: Curve + JwkParameters, AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { jwk.parse::().and_then(|jwk| Self::from_jwk(&jwk)) } @@ -188,7 +188,7 @@ where where C: Curve + JwkParameters, AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { self.into() } @@ -199,7 +199,7 @@ where where C: Curve + JwkParameters, AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { self.to_jwk().to_string() } @@ -221,7 +221,7 @@ impl FromEncodedPoint for PublicKey where C: CurveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { /// Initialize [`PublicKey`] from an [`EncodedPoint`] fn from_encoded_point(encoded_point: &EncodedPoint) -> CtOption { @@ -237,7 +237,7 @@ impl ToEncodedPoint for PublicKey where C: CurveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { /// Serialize this [`PublicKey`] as a SEC1 [`EncodedPoint`], optionally applying /// point compression @@ -251,7 +251,7 @@ impl From> for EncodedPoint where C: CurveArithmetic + PointCompression, AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { fn from(public_key: PublicKey) -> EncodedPoint { EncodedPoint::::from(&public_key) @@ -263,7 +263,7 @@ impl From<&PublicKey> for EncodedPoint where C: CurveArithmetic + PointCompression, AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { fn from(public_key: &PublicKey) -> EncodedPoint { public_key.to_encoded_point(C::COMPRESS_POINTS) @@ -315,7 +315,7 @@ impl PartialOrd for PublicKey where C: CurveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) @@ -327,7 +327,7 @@ impl Ord for PublicKey where C: CurveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { fn cmp(&self, other: &Self) -> Ordering { // TODO(tarcieri): more efficient implementation? @@ -342,7 +342,7 @@ impl TryFrom> for PublicKey where C: AssociatedOid + CurveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { type Error = pkcs8::spki::Error; @@ -358,7 +358,7 @@ impl DecodePublicKey for PublicKey where C: AssociatedOid + CurveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { } @@ -367,7 +367,7 @@ impl EncodePublicKey for PublicKey where C: AssociatedOid + CurveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { fn to_public_key_der(&self) -> pkcs8::spki::Result { let algorithm = pkcs8::AlgorithmIdentifier { @@ -390,7 +390,7 @@ impl FromStr for PublicKey where C: AssociatedOid + CurveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { type Err = Error; @@ -404,7 +404,7 @@ impl ToString for PublicKey where C: AssociatedOid + CurveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { fn to_string(&self) -> String { self.to_public_key_pem(Default::default()) @@ -417,7 +417,7 @@ impl Serialize for PublicKey where C: AssociatedOid + CurveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { fn serialize(&self, serializer: S) -> core::result::Result where @@ -433,7 +433,7 @@ impl<'de, C> Deserialize<'de> for PublicKey where C: AssociatedOid + CurveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { fn deserialize(deserializer: D) -> core::result::Result where diff --git a/elliptic-curve/src/scalar/nonzero.rs b/elliptic-curve/src/scalar/nonzero.rs index 1d2a7fdae..6ca6e234b 100644 --- a/elliptic-curve/src/scalar/nonzero.rs +++ b/elliptic-curve/src/scalar/nonzero.rs @@ -145,8 +145,9 @@ impl From> for ScalarPrimitive where C: CurveArithmetic, { + #[inline] fn from(scalar: NonZeroScalar) -> ScalarPrimitive { - ScalarPrimitive::from_be_bytes(scalar.to_repr()).unwrap() + Self::from(&scalar) } } @@ -155,7 +156,7 @@ where C: CurveArithmetic, { fn from(scalar: &NonZeroScalar) -> ScalarPrimitive { - ScalarPrimitive::from_be_bytes(scalar.to_repr()).unwrap() + ScalarPrimitive::from_bytes(&scalar.to_repr()).unwrap() } } diff --git a/elliptic-curve/src/scalar/primitive.rs b/elliptic-curve/src/scalar/primitive.rs index 2bdec9e16..932df237f 100644 --- a/elliptic-curve/src/scalar/primitive.rs +++ b/elliptic-curve/src/scalar/primitive.rs @@ -71,29 +71,15 @@ where CtOption::new(Self { inner: uint }, uint.ct_lt(&Self::MODULUS)) } - /// Decode [`ScalarPrimitive`] from big endian bytes. - pub fn from_be_bytes(bytes: FieldBytes) -> CtOption { - Self::new(C::Uint::from_be_byte_array(bytes)) + /// Decode [`ScalarPrimitive`] from a serialized field element + pub fn from_bytes(bytes: &FieldBytes) -> CtOption { + Self::new(C::decode_field_bytes(bytes)) } /// Decode [`ScalarPrimitive`] from a big endian byte slice. - pub fn from_be_slice(slice: &[u8]) -> Result { + pub fn from_slice(slice: &[u8]) -> Result { if slice.len() == C::Uint::BYTES { - Option::from(Self::from_be_bytes(GenericArray::clone_from_slice(slice))).ok_or(Error) - } else { - Err(Error) - } - } - - /// Decode [`ScalarPrimitive`] from little endian bytes. - pub fn from_le_bytes(bytes: FieldBytes) -> CtOption { - Self::new(C::Uint::from_le_byte_array(bytes)) - } - - /// Decode [`ScalarPrimitive`] from a little endian byte slice. - pub fn from_le_slice(slice: &[u8]) -> Result { - if slice.len() == C::Uint::BYTES { - Option::from(Self::from_le_bytes(GenericArray::clone_from_slice(slice))).ok_or(Error) + Option::from(Self::from_bytes(GenericArray::from_slice(slice))).ok_or(Error) } else { Err(Error) } @@ -124,14 +110,9 @@ where self.inner.is_odd() } - /// Encode [`ScalarPrimitive`] as big endian bytes. - pub fn to_be_bytes(&self) -> FieldBytes { - self.inner.to_be_byte_array() - } - - /// Encode [`ScalarPrimitive`] as little endian bytes. - pub fn to_le_bytes(&self) -> FieldBytes { - self.inner.to_le_byte_array() + /// Encode [`ScalarPrimitive`] as a serialized field element. + pub fn to_bytes(&self) -> FieldBytes { + C::encode_field_bytes(&self.inner) } /// Convert to a `C::Uint`. @@ -393,7 +374,7 @@ where C: Curve, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{:x}", HexDisplay(&self.to_be_bytes())) + write!(f, "{:x}", HexDisplay(&self.to_bytes())) } } @@ -402,7 +383,7 @@ where C: Curve, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{:X}", HexDisplay(&self.to_be_bytes())) + write!(f, "{:X}", HexDisplay(&self.to_bytes())) } } @@ -415,7 +396,7 @@ where fn from_str(hex: &str) -> Result { let mut bytes = FieldBytes::::default(); base16ct::lower::decode(hex, &mut bytes)?; - Option::from(Self::from_be_bytes(bytes)).ok_or(Error) + Self::from_slice(&bytes) } } @@ -428,7 +409,7 @@ where where S: ser::Serializer, { - serdect::array::serialize_hex_upper_or_bin(&self.to_be_bytes(), serializer) + serdect::array::serialize_hex_upper_or_bin(&self.to_bytes(), serializer) } } @@ -443,7 +424,6 @@ where { let mut bytes = FieldBytes::::default(); serdect::array::deserialize_hex_or_bin(&mut bytes, deserializer)?; - Option::from(Self::from_be_bytes(bytes)) - .ok_or_else(|| de::Error::custom("scalar out of range")) + Self::from_slice(&bytes).map_err(|_| de::Error::custom("scalar out of range")) } } diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index 0d0b387c4..7673386b8 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -4,7 +4,7 @@ pub use sec1::point::{Coordinates, ModulusSize, Tag}; -use crate::{Curve, FieldSize, Result, SecretKey}; +use crate::{Curve, FieldBytesSize, Result, SecretKey}; use generic_array::GenericArray; use subtle::CtOption; @@ -15,16 +15,16 @@ use crate::{AffinePoint, CurveArithmetic, Error}; pub type CompressedPoint = GenericArray>; /// Size of a compressed elliptic curve point. -pub type CompressedPointSize = as ModulusSize>::CompressedPointSize; +pub type CompressedPointSize = as ModulusSize>::CompressedPointSize; /// Encoded elliptic curve point sized appropriately for a given curve. -pub type EncodedPoint = sec1::point::EncodedPoint>; +pub type EncodedPoint = sec1::point::EncodedPoint>; /// Encoded elliptic curve point *without* point compression. pub type UncompressedPoint = GenericArray>; /// Size of an uncompressed elliptic curve point. -pub type UncompressedPointSize = as ModulusSize>::UncompressedPointSize; +pub type UncompressedPointSize = as ModulusSize>::UncompressedPointSize; /// Trait for deserializing a value from a SEC1 encoded curve point. /// @@ -33,7 +33,7 @@ pub trait FromEncodedPoint where Self: Sized, C: Curve, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { /// Deserialize the type this trait is impl'd on from an [`EncodedPoint`]. fn from_encoded_point(point: &EncodedPoint) -> CtOption; @@ -45,7 +45,7 @@ where pub trait ToEncodedPoint where C: Curve, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { /// Serialize this value as a SEC1 [`EncodedPoint`], optionally applying /// point compression. @@ -58,7 +58,7 @@ where pub trait ToCompactEncodedPoint where C: Curve, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { /// Serialize this value as a SEC1 [`EncodedPoint`], optionally applying /// point compression. @@ -73,7 +73,7 @@ where pub trait ValidatePublicKey where Self: Curve, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { /// Validate that the given [`EncodedPoint`] is a valid public key for the /// provided secret value. @@ -98,7 +98,7 @@ impl ValidatePublicKey for C where C: CurveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { fn validate_public_key(secret_key: &SecretKey, public_key: &EncodedPoint) -> Result<()> { let pk = secret_key diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index c7b2a3f43..d94f90df5 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -49,7 +49,7 @@ use pem_rfc7468 as pem; #[cfg(feature = "sec1")] use crate::{ sec1::{EncodedPoint, ModulusSize, ValidatePublicKey}, - FieldSize, + FieldBytesSize, }; #[cfg(all(doc, feature = "pkcs8"))] @@ -143,16 +143,10 @@ where PublicKey::from_secret_scalar(&self.to_nonzero_scalar()) } - /// Deserialize raw secret scalar as a big endian integer. - pub fn from_be_bytes(bytes: &[u8]) -> Result { - if bytes.len() != C::Uint::BYTES { - return Err(Error); - } - - let inner: ScalarPrimitive = Option::from(ScalarPrimitive::from_be_bytes( - GenericArray::clone_from_slice(bytes), - )) - .ok_or(Error)?; + /// Deserialize secret key from an encoded secret scalar. + pub fn from_bytes(bytes: &FieldBytes) -> Result { + let inner: ScalarPrimitive = + Option::from(ScalarPrimitive::from_bytes(bytes)).ok_or(Error)?; if inner.is_zero().into() { return Err(Error); @@ -161,9 +155,19 @@ where Ok(Self { inner }) } + /// Deserialize secret key from an encoded secret scalar passed as a + /// byte slice. + pub fn from_slice(slice: &[u8]) -> Result { + if slice.len() == C::Uint::BYTES { + Self::from_bytes(GenericArray::from_slice(slice)) + } else { + Err(Error) + } + } + /// Serialize raw secret scalar as a big endian integer. - pub fn to_be_bytes(&self) -> FieldBytes { - self.inner.to_be_bytes() + pub fn to_bytes(&self) -> FieldBytes { + self.inner.to_bytes() } /// Deserialize secret key encoded in the SEC1 ASN.1 DER `ECPrivateKey` format. @@ -171,7 +175,7 @@ where pub fn from_sec1_der(der_bytes: &[u8]) -> Result where C: Curve + ValidatePublicKey, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { sec1::EcPrivateKey::try_from(der_bytes)? .try_into() @@ -184,10 +188,10 @@ where where C: CurveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { // TODO(tarcieri): wrap `secret_key_bytes` in `Zeroizing` - let mut private_key_bytes = self.to_be_bytes(); + let mut private_key_bytes = self.to_bytes(); let public_key_bytes = self.public_key().to_encoded_point(false); let ec_private_key = Zeroizing::new( @@ -216,7 +220,7 @@ where pub fn from_sec1_pem(s: &str) -> Result where C: Curve + ValidatePublicKey, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { let (label, der_bytes) = pem::decode_vec(s.as_bytes()).map_err(|_| Error)?; @@ -236,7 +240,7 @@ where where C: CurveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { self.to_sec1_der() .ok() @@ -250,7 +254,7 @@ where pub fn from_jwk(jwk: &JwkEcKey) -> Result where C: JwkParameters + ValidatePublicKey, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { Self::try_from(jwk) } @@ -260,7 +264,7 @@ where pub fn from_jwk_str(jwk: &str) -> Result where C: JwkParameters + ValidatePublicKey, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { jwk.parse::().and_then(|jwk| Self::from_jwk(&jwk)) } @@ -271,7 +275,7 @@ where where C: CurveArithmetic + JwkParameters, AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { self.into() } @@ -282,7 +286,7 @@ where where C: CurveArithmetic + JwkParameters, AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { Zeroizing::new(self.to_jwk().to_string()) } @@ -333,12 +337,12 @@ where impl TryFrom> for SecretKey where C: Curve + ValidatePublicKey, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { type Error = der::Error; fn try_from(sec1_private_key: sec1::EcPrivateKey<'_>) -> der::Result { - let secret_key = Self::from_be_bytes(sec1_private_key.private_key) + let secret_key = Self::from_slice(sec1_private_key.private_key) .map_err(|_| der::Tag::Sequence.value_error())?; // TODO(tarcieri): validate `sec1_private_key.params`? diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs index 52090a23b..d1fca76a7 100644 --- a/elliptic-curve/src/secret_key/pkcs8.rs +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -4,7 +4,7 @@ use super::SecretKey; use crate::{ pkcs8::{self, der::Decode, AssociatedOid, DecodePrivateKey}, sec1::{ModulusSize, ValidatePublicKey}, - Curve, FieldSize, ALGORITHM_OID, + Curve, FieldBytesSize, ALGORITHM_OID, }; use sec1::EcPrivateKey; @@ -28,7 +28,7 @@ use { impl TryFrom> for SecretKey where C: Curve + AssociatedOid + ValidatePublicKey, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { type Error = pkcs8::Error; @@ -45,7 +45,7 @@ where impl DecodePrivateKey for SecretKey where C: Curve + AssociatedOid + ValidatePublicKey, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { } @@ -54,7 +54,7 @@ impl EncodePrivateKey for SecretKey where C: AssociatedOid + CurveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { fn to_pkcs8_der(&self) -> pkcs8::Result { let algorithm_identifier = pkcs8::AlgorithmIdentifier { @@ -72,7 +72,7 @@ where impl FromStr for SecretKey where C: Curve + AssociatedOid + ValidatePublicKey, - FieldSize: ModulusSize, + FieldBytesSize: ModulusSize, { type Err = Error; diff --git a/elliptic-curve/src/voprf.rs b/elliptic-curve/src/voprf.rs new file mode 100644 index 000000000..dc15d5f98 --- /dev/null +++ b/elliptic-curve/src/voprf.rs @@ -0,0 +1,20 @@ +//! Verifiable Oblivious Pseudorandom Function (VOPRF) using prime order groups +//! +//! + +use crate::PrimeCurve; + +/// Elliptic curve parameters used by VOPRF. +pub trait VoprfParameters: PrimeCurve { + /// The `ID` parameter which identifies a particular elliptic curve + /// as defined in [section 4 of `draft-irtf-cfrg-voprf-08`][voprf]. + /// + /// [voprf]: https://www.ietf.org/archive/id/draft-irtf-cfrg-voprf-08.html#section-4 + const ID: u16; + + /// The `Hash` parameter which assigns a particular hash function to this + /// ciphersuite as defined in [section 4 of `draft-irtf-cfrg-voprf-08`][voprf]. + /// + /// [voprf]: https://www.ietf.org/archive/id/draft-irtf-cfrg-voprf-08.html#section-4 + type Hash: digest::Digest; +} diff --git a/elliptic-curve/tests/pkcs8.rs b/elliptic-curve/tests/pkcs8.rs index 336b3f0ca..20982fc4e 100644 --- a/elliptic-curve/tests/pkcs8.rs +++ b/elliptic-curve/tests/pkcs8.rs @@ -23,7 +23,7 @@ const EXAMPLE_SCALAR: [u8; 32] = /// Example PKCS#8 private key fn example_private_key() -> der::SecretDocument { - SecretKey::from_be_bytes(&EXAMPLE_SCALAR) + SecretKey::from_slice(&EXAMPLE_SCALAR) .unwrap() .to_pkcs8_der() .unwrap() @@ -32,7 +32,7 @@ fn example_private_key() -> der::SecretDocument { #[test] fn decode_pkcs8_private_key_from_der() { let secret_key = SecretKey::from_pkcs8_der(example_private_key().as_bytes()).unwrap(); - assert_eq!(secret_key.to_be_bytes().as_slice(), &EXAMPLE_SCALAR); + assert_eq!(secret_key.to_bytes().as_slice(), &EXAMPLE_SCALAR); } #[test] diff --git a/elliptic-curve/tests/secret_key.rs b/elliptic-curve/tests/secret_key.rs index 50e5a95cb..0d7678cc2 100644 --- a/elliptic-curve/tests/secret_key.rs +++ b/elliptic-curve/tests/secret_key.rs @@ -6,5 +6,5 @@ use elliptic_curve::dev::SecretKey; #[test] fn undersize_secret_key() { - assert!(SecretKey::from_be_bytes(&[]).is_err()); + assert!(SecretKey::from_slice(&[]).is_err()); } From 5ba8c558947d5ac73c0a0fd02ce00aabe4a03288 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 27 Jan 2023 10:55:32 -0700 Subject: [PATCH 0952/1461] elliptic-curve: interpolate variables in format strings (#1221) Uses the newly added support for interpolating variables in format strings instead of passing them as arguments. --- elliptic-curve/src/jwk.rs | 4 ++-- elliptic-curve/src/scalar/nonzero.rs | 2 +- elliptic-curve/src/scalar/primitive.rs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/elliptic-curve/src/jwk.rs b/elliptic-curve/src/jwk.rs index 0c13d3e97..e0233cc00 100644 --- a/elliptic-curve/src/jwk.rs +++ b/elliptic-curve/src/jwk.rs @@ -440,7 +440,7 @@ impl<'de> Deserialize<'de> for JwkEcKey { .ok_or_else(|| de::Error::invalid_length(0, &DE_ERROR_MSG))?; if kty != EC_KTY { - return Err(de::Error::custom(format!("unsupported JWK kty: {:?}", kty))); + return Err(de::Error::custom(format!("unsupported JWK kty: {kty:?}"))); } let crv = de::SeqAccess::next_element::(&mut seq)? @@ -512,7 +512,7 @@ impl<'de> Deserialize<'de> for JwkEcKey { let kty = kty.ok_or_else(|| de::Error::missing_field("kty"))?; if kty != EC_KTY { - return Err(de::Error::custom(format!("unsupported JWK kty: {}", kty))); + return Err(de::Error::custom(format!("unsupported JWK kty: {kty}"))); } let crv = crv.ok_or_else(|| de::Error::missing_field("crv"))?; diff --git a/elliptic-curve/src/scalar/nonzero.rs b/elliptic-curve/src/scalar/nonzero.rs index 6ca6e234b..6d7164ffc 100644 --- a/elliptic-curve/src/scalar/nonzero.rs +++ b/elliptic-curve/src/scalar/nonzero.rs @@ -305,7 +305,7 @@ where C: CurveArithmetic, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{:X}", self) + write!(f, "{self:X}") } } diff --git a/elliptic-curve/src/scalar/primitive.rs b/elliptic-curve/src/scalar/primitive.rs index 932df237f..68a067ecd 100644 --- a/elliptic-curve/src/scalar/primitive.rs +++ b/elliptic-curve/src/scalar/primitive.rs @@ -365,7 +365,7 @@ where C: Curve, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{:X}", self) + write!(f, "{self:X}") } } From 581ab7c09e48e5624f8ca7e7f9c52b6286d30cce Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 27 Jan 2023 11:09:05 -0700 Subject: [PATCH 0953/1461] elliptic-curve: replace `Shr1` with `ShrAssign` (#1222) Eliminates a bespoke point solution trait with a standard core trait. Since `C::Uint` already bounds on `ShrAssign` this should be fairly trivial to support, even in generic code. --- elliptic-curve/src/arithmetic.rs | 4 ++-- elliptic-curve/src/dev.rs | 8 ++++---- elliptic-curve/src/lib.rs | 4 ++-- elliptic-curve/src/ops.rs | 8 +------- elliptic-curve/src/scalar/invert.rs | 10 +++++----- elliptic-curve/src/scalar/primitive.rs | 8 ++++---- 6 files changed, 18 insertions(+), 24 deletions(-) diff --git a/elliptic-curve/src/arithmetic.rs b/elliptic-curve/src/arithmetic.rs index 8153fb011..874321bc8 100644 --- a/elliptic-curve/src/arithmetic.rs +++ b/elliptic-curve/src/arithmetic.rs @@ -1,7 +1,7 @@ //! Elliptic curve arithmetic traits. use crate::{ - ops::{LinearCombination, MulByGenerator, Shr1}, + ops::{LinearCombination, MulByGenerator, ShrAssign}, scalar::FromUintUnchecked, AffineXCoordinate, AffineYIsOdd, Curve, FieldBytes, IsHigh, PrimeCurve, ScalarPrimitive, }; @@ -70,7 +70,7 @@ pub trait CurveArithmetic: Curve { + Into + IsHigh + PartialOrd - + Shr1 + + ShrAssign + ff::Field + ff::PrimeField>; } diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 9971b8999..65e62d197 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -7,7 +7,7 @@ use crate::{ bigint::{Limb, U256}, error::{Error, Result}, generic_array::typenum::U32, - ops::{LinearCombination, MulByGenerator, Reduce, Shr1}, + ops::{LinearCombination, MulByGenerator, Reduce, ShrAssign}, pkcs8, rand_core::RngCore, scalar::FromUintUnchecked, @@ -293,9 +293,9 @@ impl Neg for Scalar { } } -impl Shr1 for Scalar { - fn shr1(&mut self) { - self.0.shr1(); +impl ShrAssign for Scalar { + fn shr_assign(&mut self, rhs: usize) { + self.0 >>= rhs; } } diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 04b0ad10b..d719a2a89 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -173,8 +173,8 @@ pub trait Curve: 'static + Copy + Clone + Debug + Default + Eq + Ord + Send + Sy type FieldBytesSize: ArrayLength + Add + Eq; /// Integer type used to represent field elements of this elliptic curve. - type Uint: bigint::AddMod - + ArrayEncoding + type Uint: ArrayEncoding + + bigint::AddMod + bigint::Encoding + bigint::Integer + bigint::NegMod diff --git a/elliptic-curve/src/ops.rs b/elliptic-curve/src/ops.rs index 399364536..b93e96d11 100644 --- a/elliptic-curve/src/ops.rs +++ b/elliptic-curve/src/ops.rs @@ -1,6 +1,6 @@ //! Traits for arithmetic operations on elliptic curve field elements. -pub use core::ops::{Add, AddAssign, Mul, Neg, Sub, SubAssign}; +pub use core::ops::{Add, AddAssign, Mul, Neg, Shr, ShrAssign, Sub, SubAssign}; use crypto_bigint::{ArrayEncoding, ByteArray, Integer}; @@ -104,9 +104,3 @@ pub trait ReduceNonZero: Sized { /// Perform a modular reduction, returning a field element. fn from_uint_reduced_nonzero(n: Uint) -> Self; } - -/// Right shift this value by one bit, storing the result in-place. -pub trait Shr1 { - /// Right shift this value by one bit in-place. - fn shr1(&mut self); -} diff --git a/elliptic-curve/src/scalar/invert.rs b/elliptic-curve/src/scalar/invert.rs index 0b949718e..e9ee44ea9 100644 --- a/elliptic-curve/src/scalar/invert.rs +++ b/elliptic-curve/src/scalar/invert.rs @@ -1,5 +1,5 @@ use super::FromUintUnchecked; -use crate::{ops::Shr1, CurveArithmetic, Scalar}; +use crate::{CurveArithmetic, Scalar}; use ff::{Field, PrimeField}; use subtle::CtOption; @@ -23,10 +23,10 @@ where while !bool::from(u.is_zero()) { // u-loop while bool::from(u.is_even()) { - u.shr1(); + u >>= 1; let was_odd: bool = A.is_odd().into(); - A.shr1(); + A >>= 1; if was_odd { A += order_div_2; @@ -36,10 +36,10 @@ where // v-loop while bool::from(v.is_even()) { - v.shr1(); + v >>= 1; let was_odd: bool = C.is_odd().into(); - C.shr1(); + C >>= 1; if was_odd { C += order_div_2; diff --git a/elliptic-curve/src/scalar/primitive.rs b/elliptic-curve/src/scalar/primitive.rs index 68a067ecd..fb5923ca7 100644 --- a/elliptic-curve/src/scalar/primitive.rs +++ b/elliptic-curve/src/scalar/primitive.rs @@ -2,7 +2,7 @@ use crate::{ bigint::{prelude::*, Limb, NonZero}, - ops::{Add, AddAssign, Neg, Shr1, Sub, SubAssign}, + ops::{Add, AddAssign, Neg, ShrAssign, Sub, SubAssign}, scalar::FromUintUnchecked, Curve, Error, FieldBytes, IsHigh, Result, }; @@ -341,12 +341,12 @@ where } } -impl Shr1 for ScalarPrimitive +impl ShrAssign for ScalarPrimitive where C: Curve, { - fn shr1(&mut self) { - self.inner >>= 1; + fn shr_assign(&mut self, rhs: usize) { + self.inner >>= rhs; } } From f6484cf96c51d016105113c76d105dced5b69909 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 27 Jan 2023 11:18:14 -0700 Subject: [PATCH 0954/1461] elliptic-curve: fewer toplevel re-exports (#1223) Gets rid of re-exports at the toplevel for modules that are newly `pub` to avoid polluting the namespace. Only the `AffinePoint`, `ProjectivePoint`, and `Scalar` re-exports are retained. --- elliptic-curve/src/arithmetic.rs | 4 +++- elliptic-curve/src/dev.rs | 7 ++++--- elliptic-curve/src/ecdh.rs | 2 +- elliptic-curve/src/lib.rs | 9 +-------- elliptic-curve/src/public_key.rs | 3 ++- elliptic-curve/src/scalar/nonzero.rs | 3 ++- elliptic-curve/src/scalar/primitive.rs | 3 ++- 7 files changed, 15 insertions(+), 16 deletions(-) diff --git a/elliptic-curve/src/arithmetic.rs b/elliptic-curve/src/arithmetic.rs index 874321bc8..f09e8d728 100644 --- a/elliptic-curve/src/arithmetic.rs +++ b/elliptic-curve/src/arithmetic.rs @@ -2,8 +2,10 @@ use crate::{ ops::{LinearCombination, MulByGenerator, ShrAssign}, + point::{AffineXCoordinate, AffineYIsOdd}, scalar::FromUintUnchecked, - AffineXCoordinate, AffineYIsOdd, Curve, FieldBytes, IsHigh, PrimeCurve, ScalarPrimitive, + scalar::IsHigh, + Curve, FieldBytes, PrimeCurve, ScalarPrimitive, }; use core::fmt::Debug; use subtle::{ConditionallySelectable, ConstantTimeEq}; diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 65e62d197..e3bd8f8b0 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -9,12 +9,13 @@ use crate::{ generic_array::typenum::U32, ops::{LinearCombination, MulByGenerator, Reduce, ShrAssign}, pkcs8, + point::{AffineXCoordinate, AffineYIsOdd}, rand_core::RngCore, - scalar::FromUintUnchecked, + scalar::{FromUintUnchecked, IsHigh}, sec1::{CompressedPoint, FromEncodedPoint, ToEncodedPoint}, subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}, zeroize::DefaultIsZeroes, - AffineXCoordinate, AffineYIsOdd, Curve, CurveArithmetic, IsHigh, PrimeCurve, + Curve, CurveArithmetic, PrimeCurve, }; use core::{ iter::{Product, Sum}, @@ -55,7 +56,7 @@ pub type ScalarPrimitive = crate::ScalarPrimitive; /// Scalar bits. #[cfg(feature = "bits")] -pub type ScalarBits = crate::ScalarBits; +pub type ScalarBits = crate::scalar::ScalarBits; /// Mock elliptic curve type useful for writing tests which require a concrete /// curve type. diff --git a/elliptic-curve/src/ecdh.rs b/elliptic-curve/src/ecdh.rs index 9a4f8cc51..7bfd4c446 100644 --- a/elliptic-curve/src/ecdh.rs +++ b/elliptic-curve/src/ecdh.rs @@ -27,7 +27,7 @@ //! [SIGMA]: https://webee.technion.ac.il/~hugo/sigma-pdf.pdf use crate::{ - AffinePoint, AffineXCoordinate, Curve, CurveArithmetic, FieldBytes, NonZeroScalar, + point::AffineXCoordinate, AffinePoint, Curve, CurveArithmetic, FieldBytes, NonZeroScalar, ProjectivePoint, PublicKey, }; use core::borrow::Borrow; diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index d719a2a89..fb14e0df7 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -105,11 +105,7 @@ mod voprf; pub use crate::{ error::{Error, Result}, field::{FieldBytes, FieldBytesSize}, - point::{ - AffineXCoordinate, AffineYIsOdd, DecompactPoint, DecompressPoint, PointCompaction, - PointCompression, - }, - scalar::{IsHigh, ScalarPrimitive}, + scalar::ScalarPrimitive, secret_key::SecretKey, }; pub use crypto_bigint as bigint; @@ -130,9 +126,6 @@ pub use { group::{self, Group}, }; -#[cfg(feature = "bits")] -pub use crate::scalar::ScalarBits; - #[cfg(feature = "jwk")] pub use crate::jwk::{JwkEcKey, JwkParameters}; diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index e5f67edc0..9e8a2ebb2 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -18,8 +18,9 @@ use core::str::FromStr; #[cfg(feature = "sec1")] use { crate::{ + point::PointCompression, sec1::{EncodedPoint, FromEncodedPoint, ModulusSize, ToEncodedPoint}, - Curve, FieldBytesSize, PointCompression, + Curve, FieldBytesSize, }, core::cmp::Ordering, subtle::CtOption, diff --git a/elliptic-curve/src/scalar/nonzero.rs b/elliptic-curve/src/scalar/nonzero.rs index 6d7164ffc..db88ec56a 100644 --- a/elliptic-curve/src/scalar/nonzero.rs +++ b/elliptic-curve/src/scalar/nonzero.rs @@ -2,7 +2,8 @@ use crate::{ ops::{Invert, Reduce, ReduceNonZero}, - CurveArithmetic, Error, FieldBytes, IsHigh, PrimeCurve, Scalar, ScalarPrimitive, SecretKey, + scalar::IsHigh, + CurveArithmetic, Error, FieldBytes, PrimeCurve, Scalar, ScalarPrimitive, SecretKey, }; use base16ct::HexDisplay; use core::{ diff --git a/elliptic-curve/src/scalar/primitive.rs b/elliptic-curve/src/scalar/primitive.rs index fb5923ca7..d0a78f083 100644 --- a/elliptic-curve/src/scalar/primitive.rs +++ b/elliptic-curve/src/scalar/primitive.rs @@ -4,7 +4,8 @@ use crate::{ bigint::{prelude::*, Limb, NonZero}, ops::{Add, AddAssign, Neg, ShrAssign, Sub, SubAssign}, scalar::FromUintUnchecked, - Curve, Error, FieldBytes, IsHigh, Result, + scalar::IsHigh, + Curve, Error, FieldBytes, Result, }; use base16ct::HexDisplay; use core::{cmp::Ordering, fmt, str}; From 942902f0eb458ea653e5c2ddaa6eff1babea4e65 Mon Sep 17 00:00:00 2001 From: Anton Lazarev <22821309+antonok-edm@users.noreply.github.com> Date: Fri, 27 Jan 2023 10:54:59 -0800 Subject: [PATCH 0955/1461] add support for arrayvec in aead (#1219) --- Cargo.lock | 7 +++++++ aead/Cargo.toml | 1 + aead/src/lib.rs | 15 +++++++++++++++ 3 files changed, 23 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 955b65f92..039fa0286 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6,6 +6,7 @@ version = 3 name = "aead" version = "0.5.1" dependencies = [ + "arrayvec", "blobby", "bytes", "crypto-common 0.1.6", @@ -48,6 +49,12 @@ dependencies = [ "subtle", ] +[[package]] +name = "arrayvec" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" + [[package]] name = "async-signature" version = "0.3.0" diff --git a/aead/Cargo.toml b/aead/Cargo.toml index 6837bf118..893282217 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -20,6 +20,7 @@ crypto-common = "0.1.4" generic-array = { version = "0.14", default-features = false } # optional dependencies +arrayvec = { version = "0.7", optional = true, default-features = false } blobby = { version = "0.3", optional = true } bytes = { version = "1", optional = true, default-features = false } heapless = { version = "0.7", optional = true, default-features = false } diff --git a/aead/src/lib.rs b/aead/src/lib.rs index 41191cf32..ab3ca38ae 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -39,6 +39,10 @@ pub mod stream; pub use crypto_common::{Key, KeyInit, KeySizeUser}; pub use generic_array::{self, typenum::consts}; +#[cfg(feature = "arrayvec")] +#[cfg_attr(docsrs, doc(cfg(feature = "arrayvec")))] +pub use arrayvec; + #[cfg(feature = "bytes")] #[cfg_attr(docsrs, doc(cfg(feature = "bytes")))] pub use bytes; @@ -549,6 +553,17 @@ impl Buffer for BytesMut { } } +#[cfg(feature = "arrayvec")] +impl Buffer for arrayvec::ArrayVec { + fn extend_from_slice(&mut self, other: &[u8]) -> Result<()> { + arrayvec::ArrayVec::try_extend_from_slice(self, other).map_err(|_| Error) + } + + fn truncate(&mut self, len: usize) { + arrayvec::ArrayVec::truncate(self, len); + } +} + #[cfg(feature = "heapless")] impl Buffer for heapless::Vec { fn extend_from_slice(&mut self, other: &[u8]) -> Result<()> { From ff2bdf701397025bc1aca603e6f2fc4cb2935475 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 27 Jan 2023 12:19:23 -0700 Subject: [PATCH 0956/1461] elliptic-curve: bump `crypto-bigint` to v0.5.0-pre.2 (#1224) --- elliptic-curve/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index f1f51d46a..39fc377ec 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -17,7 +17,7 @@ rust-version = "1.61" [dependencies] base16ct = "0.1.1" -crypto-bigint = { version = "=0.5.0-pre.1", default-features = false, features = ["rand_core", "generic-array", "zeroize"] } +crypto-bigint = { version = "=0.5.0-pre.2", default-features = false, features = ["rand_core", "generic-array", "zeroize"] } generic-array = { version = "0.14", default-features = false } rand_core = { version = "0.6.4", default-features = false } subtle = { version = "2", default-features = false } From d22bd8d92f0dbc49fdba05195975caab959fad54 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 27 Jan 2023 12:23:12 -0700 Subject: [PATCH 0957/1461] elliptic-curve v0.13.0-pre.0 --- .gitignore | 1 - elliptic-curve/Cargo.lock | 378 ++++++++++++++++++++++++++++++++++++++ elliptic-curve/Cargo.toml | 2 +- 3 files changed, 379 insertions(+), 2 deletions(-) create mode 100644 elliptic-curve/Cargo.lock diff --git a/.gitignore b/.gitignore index f1148d25a..0bac88e3a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,2 @@ target/ **/target/ -**/Cargo.lock diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock new file mode 100644 index 000000000..239671cfb --- /dev/null +++ b/elliptic-curve/Cargo.lock @@ -0,0 +1,378 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "base16ct" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" + +[[package]] +name = "base64ct" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b645a089122eccb6111b4f81cbc1a49f5900ac4666bb93ac027feaecf15607bf" + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "block-buffer" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" +dependencies = [ + "generic-array", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "const-oid" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cec318a675afcb6a1ea1d4340e2d377e56e47c266f28043ceccbf4412ddfdd3b" + +[[package]] +name = "cpufeatures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-bigint" +version = "0.5.0-pre.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c77f9ab26f2f9ea03c23c9da7d10ca989f6888e6960dbbbe1dc13cfe0d6d07b2" +dependencies = [ + "generic-array", + "rand_core", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "der" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + +[[package]] +name = "digest" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "elliptic-curve" +version = "0.13.0-pre.0" +dependencies = [ + "base16ct", + "base64ct", + "crypto-bigint", + "digest", + "ff", + "generic-array", + "group", + "hex-literal", + "hkdf", + "pem-rfc7468", + "pkcs8", + "rand_core", + "sec1", + "serde_json", + "serdect", + "sha2", + "sha3", + "subtle", + "zeroize", +] + +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "bitvec", + "rand_core", + "subtle", +] + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "generic-array" +version = "0.14.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core", + "subtle", +] + +[[package]] +name = "hex-literal" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" + +[[package]] +name = "hkdf" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "itoa" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440" + +[[package]] +name = "keccak" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3afef3b6eff9ce9d8ff9b3601125eec7f0c8cbac7abd14f355d053fa56c98768" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "libc" +version = "0.2.139" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" + +[[package]] +name = "pem-rfc7468" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d159833a9105500e0398934e205e0773f0b27529557134ecfc51c27646adac" +dependencies = [ + "base64ct", +] + +[[package]] +name = "pkcs8" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "ryu" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" + +[[package]] +name = "sec1" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "serdect", + "subtle", + "zeroize", +] + +[[package]] +name = "serde" +version = "1.0.152" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" + +[[package]] +name = "serde_json" +version = "1.0.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serdect" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "038fce1bf4d74b9b30ea7dcd59df75ba8ec669a5dcb3cc64fbfcef7334ced32c" +dependencies = [ + "base16ct", + "serde", +] + +[[package]] +name = "sha2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha3" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdf0c33fae925bdc080598b84bc15c55e7b9a4a43b3c704da051f977469691c9" +dependencies = [ + "digest", + "keccak", +] + +[[package]] +name = "spki" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "typenum" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "zeroize" +version = "1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f" diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 39fc377ec..3dfb71c01 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.13.0-pre" +version = "0.13.0-pre.0" description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, From 9189b74193bbae67725e76ff4ec36250fe3c788b Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 27 Jan 2023 15:53:38 -0700 Subject: [PATCH 0958/1461] elliptic-curve: remove `Reduce` methods (#1225) Removes all methods from `Reduce` except the newly renamed `Reduce::reduce` (formerly `from_uint_reduced`). This follows #1220 which changed APIs to handle discrepancies between the serialized size of the big integer type used to represent field elements and the on-the-wire serialization which respects the size of the curve's field modulus and order. --- elliptic-curve/src/dev.rs | 2 +- elliptic-curve/src/ops.rs | 45 ++++------------------------ elliptic-curve/src/public_key.rs | 4 +-- elliptic-curve/src/scalar/nonzero.rs | 8 ++--- 4 files changed, 12 insertions(+), 47 deletions(-) diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index e3bd8f8b0..f63d34b76 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -325,7 +325,7 @@ impl<'a> Product<&'a Scalar> for Scalar { } impl Reduce for Scalar { - fn from_uint_reduced(w: U256) -> Self { + fn reduce(w: U256) -> Self { let (r, underflow) = w.sbb(&MockCurve::ORDER, Limb::ZERO); let underflow = Choice::from((underflow.0 >> (Limb::BITS - 1)) as u8); let reduced = U256::conditional_select(&w, &r, !underflow); diff --git a/elliptic-curve/src/ops.rs b/elliptic-curve/src/ops.rs index b93e96d11..aa16ee701 100644 --- a/elliptic-curve/src/ops.rs +++ b/elliptic-curve/src/ops.rs @@ -2,14 +2,11 @@ pub use core::ops::{Add, AddAssign, Mul, Neg, Shr, ShrAssign, Sub, SubAssign}; -use crypto_bigint::{ArrayEncoding, ByteArray, Integer}; +use crypto_bigint::Integer; #[cfg(feature = "arithmetic")] use {group::Group, subtle::CtOption}; -#[cfg(feature = "digest")] -use digest::FixedOutput; - /// Perform an inversion on a field element (i.e. base field element or scalar) pub trait Invert { /// Field element type @@ -56,41 +53,9 @@ pub trait MulByGenerator: Group { } /// Modular reduction. -pub trait Reduce: Sized { +pub trait Reduce: Sized { /// Perform a modular reduction, returning a field element. - fn from_uint_reduced(n: Uint) -> Self; - - /// Interpret the given byte array as a big endian integer and perform - /// a modular reduction. - fn from_be_bytes_reduced(bytes: ByteArray) -> Self { - Self::from_uint_reduced(Uint::from_be_byte_array(bytes)) - } - - /// Interpret the given byte array as a little endian integer and perform a - /// modular reduction. - fn from_le_bytes_reduced(bytes: ByteArray) -> Self { - Self::from_uint_reduced(Uint::from_le_byte_array(bytes)) - } - - /// Interpret a digest as a big endian integer and perform a modular - /// reduction. - #[cfg(feature = "digest")] - fn from_be_digest_reduced(digest: D) -> Self - where - D: FixedOutput, - { - Self::from_be_bytes_reduced(digest.finalize_fixed()) - } - - /// Interpret a digest as a little endian integer and perform a modular - /// reduction. - #[cfg(feature = "digest")] - fn from_le_digest_reduced(digest: D) -> Self - where - D: FixedOutput, - { - Self::from_le_bytes_reduced(digest.finalize_fixed()) - } + fn reduce(n: Uint) -> Self; } /// Modular reduction to a non-zero output. @@ -100,7 +65,7 @@ pub trait Reduce: Sized { /// /// End users should use the [`Reduce`] impl on /// [`NonZeroScalar`][`crate::NonZeroScalar`] instead. -pub trait ReduceNonZero: Sized { +pub trait ReduceNonZero: Sized { /// Perform a modular reduction, returning a field element. - fn from_uint_reduced_nonzero(n: Uint) -> Self; + fn reduce_nonzero(n: Uint) -> Self; } diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index 9e8a2ebb2..1a6b01b9b 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -157,7 +157,7 @@ where } /// Convert this [`PublicKey`] to a [`NonIdentity`] of the inner [`AffinePoint`] - pub fn to_non_identity(&self) -> NonIdentity> { + pub fn to_nonidentity(&self) -> NonIdentity> { NonIdentity::new_unchecked(self.point) } @@ -307,7 +307,7 @@ where C: CurveArithmetic, { fn from(value: &PublicKey) -> Self { - PublicKey::to_non_identity(value) + PublicKey::to_nonidentity(value) } } diff --git a/elliptic-curve/src/scalar/nonzero.rs b/elliptic-curve/src/scalar/nonzero.rs index db88ec56a..44e0cad7e 100644 --- a/elliptic-curve/src/scalar/nonzero.rs +++ b/elliptic-curve/src/scalar/nonzero.rs @@ -251,8 +251,8 @@ where I: Integer + ArrayEncoding, Scalar: ReduceNonZero, { - fn from_uint_reduced(n: I) -> Self { - Self::from_uint_reduced_nonzero(n) + fn reduce(n: I) -> Self { + Self::reduce_nonzero(n) } } @@ -262,8 +262,8 @@ where I: Integer + ArrayEncoding, Scalar: ReduceNonZero, { - fn from_uint_reduced_nonzero(n: I) -> Self { - let scalar = Scalar::::from_uint_reduced_nonzero(n); + fn reduce_nonzero(n: I) -> Self { + let scalar = Scalar::::reduce_nonzero(n); debug_assert!(!bool::from(scalar.is_zero())); Self::new(scalar).unwrap() } From db47e6fb4055e6de5f698dc561973197bf2b6b05 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 27 Jan 2023 16:04:54 -0700 Subject: [PATCH 0959/1461] elliptic-curve v0.13.0-pre.1 (#1226) --- elliptic-curve/Cargo.lock | 2 +- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index 239671cfb..a2fcd99d6 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -102,7 +102,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.13.0-pre.0" +version = "0.13.0-pre.1" dependencies = [ "base16ct", "base64ct", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 3dfb71c01..283e08914 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.13.0-pre.0" +version = "0.13.0-pre.1" description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, From eca2d23f8578448c364393eeb7823de700bb9b9b Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 30 Jan 2023 12:43:49 -0700 Subject: [PATCH 0960/1461] elliptic-curve: rename `SecretKey::as_scalar_primitive` (#1228) Formerly `::as_scalar_core`. Follows the renaming of `ScalarCore` => `ScalarPrimitive`. --- elliptic-curve/src/scalar/nonzero.rs | 2 +- elliptic-curve/src/secret_key.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/elliptic-curve/src/scalar/nonzero.rs b/elliptic-curve/src/scalar/nonzero.rs index 44e0cad7e..a4a2dbeca 100644 --- a/elliptic-curve/src/scalar/nonzero.rs +++ b/elliptic-curve/src/scalar/nonzero.rs @@ -175,7 +175,7 @@ where C: CurveArithmetic, { fn from(sk: &SecretKey) -> NonZeroScalar { - let scalar = sk.as_scalar_core().to_scalar(); + let scalar = sk.as_scalar_primitive().to_scalar(); debug_assert!(!bool::from(scalar.is_zero())); Self { scalar } } diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index d94f90df5..88119ee66 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -115,7 +115,7 @@ where /// This value is key material. /// /// Please treat it with the care it deserves! - pub fn as_scalar_core(&self) -> &ScalarPrimitive { + pub fn as_scalar_primitive(&self) -> &ScalarPrimitive { &self.inner } From a3844beacdd24ca914fb094317a426aaca348024 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 30 Jan 2023 20:52:23 -0700 Subject: [PATCH 0961/1461] elliptic-curve: add (back) reduction from bytes (#1229) As a replacement for the previous methods on `Reduce` which take bytes as input, this adds a new curve-specific method for reducing from bytes to a field element. Bytes is defined as an associated type rather than inferred from the unsigned integer parameter. This is because the integer size may not map exactly to the size of the input, especially for wide reductions. Bytes are interpreted according to curve-specific rules. --- elliptic-curve/src/arithmetic.rs | 3 ++- elliptic-curve/src/dev.rs | 6 ++++++ elliptic-curve/src/lib.rs | 3 ++- elliptic-curve/src/ops.rs | 17 +++++++++++------ elliptic-curve/src/scalar/nonzero.rs | 16 ++++++++++++++-- elliptic-curve/src/scalar/primitive.rs | 8 ++++++-- 6 files changed, 41 insertions(+), 12 deletions(-) diff --git a/elliptic-curve/src/arithmetic.rs b/elliptic-curve/src/arithmetic.rs index f09e8d728..53654d57e 100644 --- a/elliptic-curve/src/arithmetic.rs +++ b/elliptic-curve/src/arithmetic.rs @@ -1,7 +1,7 @@ //! Elliptic curve arithmetic traits. use crate::{ - ops::{LinearCombination, MulByGenerator, ShrAssign}, + ops::{LinearCombination, MulByGenerator, Reduce, ShrAssign}, point::{AffineXCoordinate, AffineYIsOdd}, scalar::FromUintUnchecked, scalar::IsHigh, @@ -72,6 +72,7 @@ pub trait CurveArithmetic: Curve { + Into + IsHigh + PartialOrd + + Reduce> + ShrAssign + ff::Field + ff::PrimeField>; diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index f63d34b76..2d45bf32f 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -325,12 +325,18 @@ impl<'a> Product<&'a Scalar> for Scalar { } impl Reduce for Scalar { + type Bytes = FieldBytes; + fn reduce(w: U256) -> Self { let (r, underflow) = w.sbb(&MockCurve::ORDER, Limb::ZERO); let underflow = Choice::from((underflow.0 >> (Limb::BITS - 1)) as u8); let reduced = U256::conditional_select(&w, &r, !underflow); Self(ScalarPrimitive::new(reduced).unwrap()) } + + fn reduce_bytes(_: &FieldBytes) -> Self { + todo!() + } } impl From for Scalar { diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index fb14e0df7..cda6ebad7 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -72,7 +72,6 @@ extern crate alloc; #[cfg(feature = "std")] extern crate std; -pub mod ops; pub mod point; pub mod scalar; @@ -82,6 +81,8 @@ pub mod dev; pub mod ecdh; #[cfg(feature = "hash2curve")] pub mod hash2curve; +#[cfg(feature = "arithmetic")] +pub mod ops; #[cfg(feature = "sec1")] pub mod sec1; #[cfg(feature = "arithmetic")] diff --git a/elliptic-curve/src/ops.rs b/elliptic-curve/src/ops.rs index aa16ee701..377558a15 100644 --- a/elliptic-curve/src/ops.rs +++ b/elliptic-curve/src/ops.rs @@ -3,8 +3,6 @@ pub use core::ops::{Add, AddAssign, Mul, Neg, Shr, ShrAssign, Sub, SubAssign}; use crypto_bigint::Integer; - -#[cfg(feature = "arithmetic")] use {group::Group, subtle::CtOption}; /// Perform an inversion on a field element (i.e. base field element or scalar) @@ -16,7 +14,6 @@ pub trait Invert { fn invert(&self) -> Self::Output; } -#[cfg(feature = "arithmetic")] impl Invert for F { type Output = CtOption; @@ -31,7 +28,6 @@ impl Invert for F { /// linear combinations (e.g. Shamir's Trick), or otherwise provides a default /// non-optimized implementation. // TODO(tarcieri): replace this with a trait from the `group` crate? (see zkcrypto/group#25) -#[cfg(feature = "arithmetic")] pub trait LinearCombination: Group { /// Calculates `x * k + y * l`. fn lincomb(x: &Self, k: &Self::Scalar, y: &Self, l: &Self::Scalar) -> Self { @@ -43,7 +39,6 @@ pub trait LinearCombination: Group { /// /// May use optimizations (e.g. precomputed tables) when available. // TODO(tarcieri): replace this with `Group::mul_by_generator``? (see zkcrypto/group#44) -#[cfg(feature = "arithmetic")] pub trait MulByGenerator: Group { /// Multiply by the generator of the prime-order subgroup. #[must_use] @@ -54,8 +49,14 @@ pub trait MulByGenerator: Group { /// Modular reduction. pub trait Reduce: Sized { + /// Bytes used as input to [`Reduce::reduce_bytes`]. + type Bytes: AsRef<[u8]>; + /// Perform a modular reduction, returning a field element. fn reduce(n: Uint) -> Self; + + /// Interpret the given bytes as an integer and perform a modular reduction. + fn reduce_bytes(bytes: &Self::Bytes) -> Self; } /// Modular reduction to a non-zero output. @@ -65,7 +66,11 @@ pub trait Reduce: Sized { /// /// End users should use the [`Reduce`] impl on /// [`NonZeroScalar`][`crate::NonZeroScalar`] instead. -pub trait ReduceNonZero: Sized { +pub trait ReduceNonZero: Reduce + Sized { /// Perform a modular reduction, returning a field element. fn reduce_nonzero(n: Uint) -> Self; + + /// Interpret the given bytes as an integer and perform a modular reduction + /// to a non-zero output. + fn reduce_nonzero_bytes(bytes: &Self::Bytes) -> Self; } diff --git a/elliptic-curve/src/scalar/nonzero.rs b/elliptic-curve/src/scalar/nonzero.rs index a4a2dbeca..460d6fc5f 100644 --- a/elliptic-curve/src/scalar/nonzero.rs +++ b/elliptic-curve/src/scalar/nonzero.rs @@ -249,24 +249,36 @@ impl Reduce for NonZeroScalar where C: CurveArithmetic, I: Integer + ArrayEncoding, - Scalar: ReduceNonZero, + Scalar: Reduce> + ReduceNonZero, { + type Bytes = FieldBytes; + fn reduce(n: I) -> Self { Self::reduce_nonzero(n) } + + fn reduce_bytes(bytes: &FieldBytes) -> Self { + Self::reduce_nonzero_bytes(bytes) + } } impl ReduceNonZero for NonZeroScalar where C: CurveArithmetic, I: Integer + ArrayEncoding, - Scalar: ReduceNonZero, + Scalar: Reduce> + ReduceNonZero, { fn reduce_nonzero(n: I) -> Self { let scalar = Scalar::::reduce_nonzero(n); debug_assert!(!bool::from(scalar.is_zero())); Self::new(scalar).unwrap() } + + fn reduce_nonzero_bytes(bytes: &FieldBytes) -> Self { + let scalar = Scalar::::reduce_nonzero_bytes(bytes); + debug_assert!(!bool::from(scalar.is_zero())); + Self::new(scalar).unwrap() + } } impl TryFrom<&[u8]> for NonZeroScalar diff --git a/elliptic-curve/src/scalar/primitive.rs b/elliptic-curve/src/scalar/primitive.rs index d0a78f083..0da18f589 100644 --- a/elliptic-curve/src/scalar/primitive.rs +++ b/elliptic-curve/src/scalar/primitive.rs @@ -2,13 +2,17 @@ use crate::{ bigint::{prelude::*, Limb, NonZero}, - ops::{Add, AddAssign, Neg, ShrAssign, Sub, SubAssign}, scalar::FromUintUnchecked, scalar::IsHigh, Curve, Error, FieldBytes, Result, }; use base16ct::HexDisplay; -use core::{cmp::Ordering, fmt, str}; +use core::{ + cmp::Ordering, + fmt, + ops::{Add, AddAssign, Neg, ShrAssign, Sub, SubAssign}, + str, +}; use generic_array::GenericArray; use rand_core::CryptoRngCore; use subtle::{ From d19771a12ac84564c7ed4242c2a93eb25a858412 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 31 Jan 2023 10:33:41 -0700 Subject: [PATCH 0962/1461] elliptic-curve: bump `crypto-bigint` to v0.5.0-pre.3 (#1230) --- elliptic-curve/Cargo.lock | 4 ++-- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index a2fcd99d6..aeca708d0 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -58,9 +58,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.5.0-pre.2" +version = "0.5.0-pre.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c77f9ab26f2f9ea03c23c9da7d10ca989f6888e6960dbbbe1dc13cfe0d6d07b2" +checksum = "c37ac947d5ac4ad24acbfe3ae18154b71eb91a360319c2f82e8c9d54d8de71c9" dependencies = [ "generic-array", "rand_core", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 283e08914..ca37978e0 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -17,7 +17,7 @@ rust-version = "1.61" [dependencies] base16ct = "0.1.1" -crypto-bigint = { version = "=0.5.0-pre.2", default-features = false, features = ["rand_core", "generic-array", "zeroize"] } +crypto-bigint = { version = "=0.5.0-pre.3", default-features = false, features = ["rand_core", "generic-array", "zeroize"] } generic-array = { version = "0.14", default-features = false } rand_core = { version = "0.6.4", default-features = false } subtle = { version = "2", default-features = false } From 09031c09d652cbe75b00f63e64e1ca1fa7e8b3ca Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 31 Jan 2023 10:42:21 -0700 Subject: [PATCH 0963/1461] elliptic-curve v0.13.0-pre.2 (#1231) --- elliptic-curve/Cargo.lock | 2 +- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index aeca708d0..8b6c950e4 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -102,7 +102,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.13.0-pre.1" +version = "0.13.0-pre.2" dependencies = [ "base16ct", "base64ct", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index ca37978e0..222993115 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.13.0-pre.1" +version = "0.13.0-pre.2" description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, From d44b7d34569ce1ba6b278712caa6d7c9239642a2 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 31 Jan 2023 12:54:59 -0700 Subject: [PATCH 0964/1461] elliptic-curve: propagate `Reduce::Bytes` for `NonZeroScalar` impls (#1232) It was previously hardcoded to `FieldBytes` which means it won't work for "wide" reductions. This propagates it to match the `Reduce` impls on `Scalar`. --- elliptic-curve/src/scalar/nonzero.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/elliptic-curve/src/scalar/nonzero.rs b/elliptic-curve/src/scalar/nonzero.rs index 460d6fc5f..596928e18 100644 --- a/elliptic-curve/src/scalar/nonzero.rs +++ b/elliptic-curve/src/scalar/nonzero.rs @@ -251,7 +251,7 @@ where I: Integer + ArrayEncoding, Scalar: Reduce> + ReduceNonZero, { - type Bytes = FieldBytes; + type Bytes = as Reduce>::Bytes; fn reduce(n: I) -> Self { Self::reduce_nonzero(n) @@ -264,9 +264,10 @@ where impl ReduceNonZero for NonZeroScalar where + Self: Reduce, C: CurveArithmetic, I: Integer + ArrayEncoding, - Scalar: Reduce> + ReduceNonZero, + Scalar: Reduce + ReduceNonZero, { fn reduce_nonzero(n: I) -> Self { let scalar = Scalar::::reduce_nonzero(n); @@ -274,7 +275,7 @@ where Self::new(scalar).unwrap() } - fn reduce_nonzero_bytes(bytes: &FieldBytes) -> Self { + fn reduce_nonzero_bytes(bytes: &Self::Bytes) -> Self { let scalar = Scalar::::reduce_nonzero_bytes(bytes); debug_assert!(!bool::from(scalar.is_zero())); Self::new(scalar).unwrap() From adbf0ad45be30b6866f733c4f366cdb129ad50ce Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 31 Jan 2023 13:37:26 -0700 Subject: [PATCH 0965/1461] elliptic-curve: fix `Reduce` impls for `NonZeroScalar` (#1233) They were still coupled to `FieldBytes` rather than forwarding to ` as Reduce>::Bytes` properly. Also, this commit reverses the relationship so `Reduce` has the non-zero reduction implementation (forwarding to `Scalar`'s `ReduceNonZero` impl) and the `ReduceNonZero` impl for `NonZeroScalar` calls `Reduce`. This is needed because `Reduce` defines the `Bytes` type and `ReduceNonZero` is bounded on it (in the trait definition). --- elliptic-curve/src/scalar/nonzero.rs | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/elliptic-curve/src/scalar/nonzero.rs b/elliptic-curve/src/scalar/nonzero.rs index 596928e18..6839d42a8 100644 --- a/elliptic-curve/src/scalar/nonzero.rs +++ b/elliptic-curve/src/scalar/nonzero.rs @@ -244,24 +244,29 @@ where } } -/// Note: implementation is the same as `ReduceNonZero` +/// Note: this is a non-zero reduction, as it's impl'd for [`NonZeroScalar`]. impl Reduce for NonZeroScalar where C: CurveArithmetic, I: Integer + ArrayEncoding, - Scalar: Reduce> + ReduceNonZero, + Scalar: Reduce + ReduceNonZero, { type Bytes = as Reduce>::Bytes; fn reduce(n: I) -> Self { - Self::reduce_nonzero(n) + let scalar = Scalar::::reduce_nonzero(n); + debug_assert!(!bool::from(scalar.is_zero())); + Self { scalar } } - fn reduce_bytes(bytes: &FieldBytes) -> Self { - Self::reduce_nonzero_bytes(bytes) + fn reduce_bytes(bytes: &Self::Bytes) -> Self { + let scalar = Scalar::::reduce_nonzero_bytes(bytes); + debug_assert!(!bool::from(scalar.is_zero())); + Self { scalar } } } +/// Note: forwards to the [`Reduce`] impl. impl ReduceNonZero for NonZeroScalar where Self: Reduce, @@ -270,15 +275,11 @@ where Scalar: Reduce + ReduceNonZero, { fn reduce_nonzero(n: I) -> Self { - let scalar = Scalar::::reduce_nonzero(n); - debug_assert!(!bool::from(scalar.is_zero())); - Self::new(scalar).unwrap() + Self::reduce(n) } fn reduce_nonzero_bytes(bytes: &Self::Bytes) -> Self { - let scalar = Scalar::::reduce_nonzero_bytes(bytes); - debug_assert!(!bool::from(scalar.is_zero())); - Self::new(scalar).unwrap() + Self::reduce_bytes(bytes) } } From c0c47018b4754c43ee474ba5ea31de2b0b6c14a9 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Tue, 31 Jan 2023 22:26:23 +0100 Subject: [PATCH 0966/1461] Update VOPRF identifier type (#1175) --- elliptic-curve/src/voprf.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/elliptic-curve/src/voprf.rs b/elliptic-curve/src/voprf.rs index dc15d5f98..68f2abf18 100644 --- a/elliptic-curve/src/voprf.rs +++ b/elliptic-curve/src/voprf.rs @@ -7,14 +7,14 @@ use crate::PrimeCurve; /// Elliptic curve parameters used by VOPRF. pub trait VoprfParameters: PrimeCurve { /// The `ID` parameter which identifies a particular elliptic curve - /// as defined in [section 4 of `draft-irtf-cfrg-voprf-08`][voprf]. + /// as defined in [section 4 of `draft-irtf-cfrg-voprf-19`][voprf]. /// - /// [voprf]: https://www.ietf.org/archive/id/draft-irtf-cfrg-voprf-08.html#section-4 - const ID: u16; + /// [voprf]: https://www.ietf.org/archive/id/draft-irtf-cfrg-voprf-19.html#name-ciphersuites-2 + const ID: &'static str; /// The `Hash` parameter which assigns a particular hash function to this - /// ciphersuite as defined in [section 4 of `draft-irtf-cfrg-voprf-08`][voprf]. + /// ciphersuite as defined in [section 4 of `draft-irtf-cfrg-voprf-19`][voprf]. /// - /// [voprf]: https://www.ietf.org/archive/id/draft-irtf-cfrg-voprf-08.html#section-4 + /// [voprf]: https://www.ietf.org/archive/id/draft-irtf-cfrg-voprf-19.html#name-ciphersuites-2 type Hash: digest::Digest; } From 3f03b406f57a2f5afcbe57e98066a1182282bf0f Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 31 Jan 2023 19:44:38 -0700 Subject: [PATCH 0967/1461] elliptic-curve: factor out `FieldBytesEncoding` trait (#1235) Extracts a trait to be impl'd on `Curve::Uint` which provides curve-specific rules for how field elements should be encoded as bytes. These rules include both endianness and how to pad/truncate bytes to match the size of the integer (which may be larger than the size of the field modulus, to be a multiple of the limb size) --- elliptic-curve/src/dev.rs | 4 ++- elliptic-curve/src/field.rs | 44 ++++++++++++++++++++++++-- elliptic-curve/src/lib.rs | 30 +++--------------- elliptic-curve/src/scalar/primitive.rs | 6 ++-- 4 files changed, 52 insertions(+), 32 deletions(-) diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 2d45bf32f..f59085742 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -15,7 +15,7 @@ use crate::{ sec1::{CompressedPoint, FromEncodedPoint, ToEncodedPoint}, subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}, zeroize::DefaultIsZeroes, - Curve, CurveArithmetic, PrimeCurve, + Curve, CurveArithmetic, FieldBytesEncoding, PrimeCurve, }; use core::{ iter::{Product, Sum}, @@ -339,6 +339,8 @@ impl Reduce for Scalar { } } +impl FieldBytesEncoding for U256 {} + impl From for Scalar { fn from(n: u64) -> Scalar { Self(n.into()) diff --git a/elliptic-curve/src/field.rs b/elliptic-curve/src/field.rs index d1cae0179..605f6c728 100644 --- a/elliptic-curve/src/field.rs +++ b/elliptic-curve/src/field.rs @@ -1,10 +1,50 @@ //! Field elements. -use crate::Curve; -use generic_array::GenericArray; +use crate::{ + bigint::{ArrayEncoding, ByteArray, Integer}, + Curve, +}; +use generic_array::{typenum::Unsigned, GenericArray}; /// Size of serialized field elements of this elliptic curve. pub type FieldBytesSize = ::FieldBytesSize; /// Byte representation of a base/scalar field element of a given curve. pub type FieldBytes = GenericArray>; + +/// Trait for decoding/encoding `Curve::Uint` from/to [`FieldBytes`] using +/// curve-specific rules. +/// +/// Namely a curve's modulus may be smaller than the big integer type used to +/// internally represent field elements (since the latter are multiples of the +/// limb size), such as in the case of curves like NIST P-224 and P-521, and so +/// it may need to be padded/truncated to the right length. +/// +/// Additionally, different curves have different endianness conventions, also +/// captured here. +pub trait FieldBytesEncoding: ArrayEncoding + Integer +where + C: Curve, +{ + /// Decode unsigned integer from serialized field element. + /// + /// The default implementation assumes a big endian encoding. + fn decode_field_bytes(field_bytes: &FieldBytes) -> Self { + debug_assert!(field_bytes.len() <= Self::ByteSize::USIZE); + let mut byte_array = ByteArray::::default(); + byte_array[..field_bytes.len()].copy_from_slice(field_bytes); + Self::from_be_byte_array(byte_array) + } + + /// Encode unsigned integer into serialized field element. + /// + /// The default implementation assumes a big endian encoding. + fn encode_field_bytes(&self) -> FieldBytes { + let mut field_bytes = FieldBytes::::default(); + debug_assert!(field_bytes.len() <= Self::ByteSize::USIZE); + + let len = field_bytes.len(); + field_bytes.copy_from_slice(&self.to_be_byte_array()[..len]); + field_bytes + } +} diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index cda6ebad7..7e5b3879a 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -105,7 +105,7 @@ mod voprf; pub use crate::{ error::{Error, Result}, - field::{FieldBytes, FieldBytesSize}, + field::{FieldBytes, FieldBytesEncoding, FieldBytesSize}, scalar::ScalarPrimitive, secret_key::SecretKey, }; @@ -140,8 +140,7 @@ use core::{ fmt::Debug, ops::{Add, ShrAssign}, }; -use crypto_bigint::{ArrayEncoding, ByteArray}; -use generic_array::{typenum::Unsigned, ArrayLength}; +use generic_array::ArrayLength; /// Algorithm [`ObjectIdentifier`][`pkcs8::ObjectIdentifier`] for elliptic /// curve public key cryptography (`id-ecPublicKey`). @@ -167,7 +166,7 @@ pub trait Curve: 'static + Copy + Clone + Debug + Default + Eq + Ord + Send + Sy type FieldBytesSize: ArrayLength + Add + Eq; /// Integer type used to represent field elements of this elliptic curve. - type Uint: ArrayEncoding + type Uint: bigint::ArrayEncoding + bigint::AddMod + bigint::Encoding + bigint::Integer @@ -176,33 +175,12 @@ pub trait Curve: 'static + Copy + Clone + Debug + Default + Eq + Ord + Send + Sy + bigint::RandomMod + bigint::SubMod + zeroize::Zeroize + + FieldBytesEncoding + ShrAssign; /// Order of this elliptic curve, i.e. number of elements in the scalar /// field. const ORDER: Self::Uint; - - /// Decode unsigned integer from serialized field element. - /// - /// The default implementation assumes a big endian encoding. - fn decode_field_bytes(field_bytes: &FieldBytes) -> Self::Uint { - debug_assert!(field_bytes.len() <= ::ByteSize::USIZE); - let mut byte_array = ByteArray::::default(); - byte_array[..field_bytes.len()].copy_from_slice(field_bytes); - Self::Uint::from_be_byte_array(byte_array) - } - - /// Encode unsigned integer into serialized field element. - /// - /// The default implementation assumes a big endian encoding. - fn encode_field_bytes(uint: &Self::Uint) -> FieldBytes { - let mut field_bytes = FieldBytes::::default(); - debug_assert!(field_bytes.len() <= ::ByteSize::USIZE); - - let len = field_bytes.len(); - field_bytes.copy_from_slice(&uint.to_be_byte_array()[..len]); - field_bytes - } } /// Marker trait for elliptic curves with prime order. diff --git a/elliptic-curve/src/scalar/primitive.rs b/elliptic-curve/src/scalar/primitive.rs index 0da18f589..c81f1bd7e 100644 --- a/elliptic-curve/src/scalar/primitive.rs +++ b/elliptic-curve/src/scalar/primitive.rs @@ -4,7 +4,7 @@ use crate::{ bigint::{prelude::*, Limb, NonZero}, scalar::FromUintUnchecked, scalar::IsHigh, - Curve, Error, FieldBytes, Result, + Curve, Error, FieldBytes, FieldBytesEncoding, Result, }; use base16ct::HexDisplay; use core::{ @@ -78,7 +78,7 @@ where /// Decode [`ScalarPrimitive`] from a serialized field element pub fn from_bytes(bytes: &FieldBytes) -> CtOption { - Self::new(C::decode_field_bytes(bytes)) + Self::new(C::Uint::decode_field_bytes(bytes)) } /// Decode [`ScalarPrimitive`] from a big endian byte slice. @@ -117,7 +117,7 @@ where /// Encode [`ScalarPrimitive`] as a serialized field element. pub fn to_bytes(&self) -> FieldBytes { - C::encode_field_bytes(&self.inner) + self.inner.encode_field_bytes() } /// Convert to a `C::Uint`. From 4ad2fc12f64f391eebf6298f0cb55cef520caebc Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 31 Jan 2023 19:58:17 -0700 Subject: [PATCH 0968/1461] elliptic-curve v0.13.0-pre.3 (#1236) --- elliptic-curve/Cargo.lock | 2 +- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index 8b6c950e4..d485fe6a5 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -102,7 +102,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.13.0-pre.2" +version = "0.13.0-pre.3" dependencies = [ "base16ct", "base64ct", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 222993115..d13947166 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.13.0-pre.2" +version = "0.13.0-pre.3" description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, From d69d5b99ef3f906442030663fb2be515ebfe4e83 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 31 Jan 2023 20:30:16 -0700 Subject: [PATCH 0969/1461] elliptic-curve: consolidate `AffineCoordinates` trait (#1237) See RustCrypto/elliptic-curves#50 for some historic context. After being able to get by on `AffineXCoordinate` for generic ECDH and ECDSA, #1199 added an `AffineYIsOdd` trait which was needed to enable the generic ECDSA implementation in the `ecdsa` crate to compute the "recovery ID" for signatures (which is effectively point compression for the `R` curve point). This commit consolidates `AffineXCoordinate` and `AffineYIsOdd` into an `AffineCoordinates` trait. Some observations since prior discussion in RustCrypto/elliptic-curves#50: - Access to coordinates is through bytes, namely `FieldBytes`. This is so as to avoid exposing a crate's field element type. This approach isn't type safe (base field elements and scalar field elements share the same serialization) but does make ECDSA's weird reduction of a base field element into the scalar field straightforward in generic code. - Prior to this attempts were made to extract ECDSA-specific bits into a trait to handle these conversions, but it complicates both writing generic code and optimizing performance. While this still might be worth exploring, so far those explorations have largely failed. - Generally there have been a lot of requests for coordinate access specifically for things like point serialization formats. We ended up adding "compaction" support upstream but we have had requests for several other formats (e.g. Elligator Squared) where direct coordinate access would be useful. This trait can hopefully be replaced by a coordinate access API provided by the `group` crate in the future. See zkcrypto/group#30 --- elliptic-curve/src/arithmetic.rs | 5 ++--- elliptic-curve/src/dev.rs | 6 ++---- elliptic-curve/src/ecdh.rs | 2 +- elliptic-curve/src/point.rs | 8 +++----- 4 files changed, 8 insertions(+), 13 deletions(-) diff --git a/elliptic-curve/src/arithmetic.rs b/elliptic-curve/src/arithmetic.rs index 53654d57e..6bb9389d5 100644 --- a/elliptic-curve/src/arithmetic.rs +++ b/elliptic-curve/src/arithmetic.rs @@ -2,7 +2,7 @@ use crate::{ ops::{LinearCombination, MulByGenerator, Reduce, ShrAssign}, - point::{AffineXCoordinate, AffineYIsOdd}, + point::AffineCoordinates, scalar::FromUintUnchecked, scalar::IsHigh, Curve, FieldBytes, PrimeCurve, ScalarPrimitive, @@ -15,8 +15,7 @@ use zeroize::DefaultIsZeroes; pub trait CurveArithmetic: Curve { /// Elliptic curve point in affine coordinates. type AffinePoint: 'static - + AffineXCoordinate> - + AffineYIsOdd + + AffineCoordinates> + Copy + ConditionallySelectable + ConstantTimeEq diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index f59085742..51d0b1e90 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -9,7 +9,7 @@ use crate::{ generic_array::typenum::U32, ops::{LinearCombination, MulByGenerator, Reduce, ShrAssign}, pkcs8, - point::{AffineXCoordinate, AffineYIsOdd}, + point::AffineCoordinates, rand_core::RngCore, scalar::{FromUintUnchecked, IsHigh}, sec1::{CompressedPoint, FromEncodedPoint, ToEncodedPoint}, @@ -415,15 +415,13 @@ pub enum AffinePoint { Other(EncodedPoint), } -impl AffineXCoordinate for AffinePoint { +impl AffineCoordinates for AffinePoint { type FieldRepr = FieldBytes; fn x(&self) -> FieldBytes { unimplemented!(); } -} -impl AffineYIsOdd for AffinePoint { fn y_is_odd(&self) -> Choice { unimplemented!(); } diff --git a/elliptic-curve/src/ecdh.rs b/elliptic-curve/src/ecdh.rs index 7bfd4c446..c64a696aa 100644 --- a/elliptic-curve/src/ecdh.rs +++ b/elliptic-curve/src/ecdh.rs @@ -27,7 +27,7 @@ //! [SIGMA]: https://webee.technion.ac.il/~hugo/sigma-pdf.pdf use crate::{ - point::AffineXCoordinate, AffinePoint, Curve, CurveArithmetic, FieldBytes, NonZeroScalar, + point::AffineCoordinates, AffinePoint, Curve, CurveArithmetic, FieldBytes, NonZeroScalar, ProjectivePoint, PublicKey, }; use core::borrow::Borrow; diff --git a/elliptic-curve/src/point.rs b/elliptic-curve/src/point.rs index 6dd3b0908..25b872a0e 100644 --- a/elliptic-curve/src/point.rs +++ b/elliptic-curve/src/point.rs @@ -19,17 +19,15 @@ pub type AffinePoint = ::AffinePoint; #[cfg(feature = "arithmetic")] pub type ProjectivePoint = ::ProjectivePoint; -/// Obtain the affine x-coordinate of an elliptic curve point. -pub trait AffineXCoordinate { +/// Access to the affine coordinates of an elliptic curve point. +// TODO: use zkcrypto/group#30 coordinate API when available +pub trait AffineCoordinates { /// Field element representation. type FieldRepr: AsRef<[u8]>; /// Get the affine x-coordinate as a serialized field element. fn x(&self) -> Self::FieldRepr; -} -/// Is the affine y-coordinate of this elliptic curve point odd? -pub trait AffineYIsOdd { /// Is the affine y-coordinate odd? fn y_is_odd(&self) -> Choice; } From cd2ecd3bff18ad4c162ac41f275f405537dc439c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Feb 2023 09:45:25 -0700 Subject: [PATCH 0970/1461] build(deps): bump bytes from 1.3.0 to 1.4.0 (#1234) Bumps [bytes](https://github.com/tokio-rs/bytes) from 1.3.0 to 1.4.0. - [Release notes](https://github.com/tokio-rs/bytes/releases) - [Changelog](https://github.com/tokio-rs/bytes/blob/master/CHANGELOG.md) - [Commits](https://github.com/tokio-rs/bytes/compare/v1.3.0...v1.4.0) --- updated-dependencies: - dependency-name: bytes dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 039fa0286..de3d66796 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -161,9 +161,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" [[package]] name = "cc" From 771f5dfcf232d54f7cca25d0b90c1705b21217a5 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Wed, 1 Feb 2023 18:30:35 +0100 Subject: [PATCH 0971/1461] elliptic-curve: allow multiple `dst`s in the hash2curve API (#1238) --- elliptic-curve/src/hash2curve/group_digest.rs | 15 ++-- elliptic-curve/src/hash2curve/hash2field.rs | 2 +- .../src/hash2curve/hash2field/expand_msg.rs | 74 ++++++++++++------ .../hash2curve/hash2field/expand_msg/xmd.rs | 75 ++++++++++--------- .../hash2curve/hash2field/expand_msg/xof.rs | 31 ++++---- 5 files changed, 115 insertions(+), 82 deletions(-) diff --git a/elliptic-curve/src/hash2curve/group_digest.rs b/elliptic-curve/src/hash2curve/group_digest.rs index 4de06140c..ea7f0471f 100644 --- a/elliptic-curve/src/hash2curve/group_digest.rs +++ b/elliptic-curve/src/hash2curve/group_digest.rs @@ -48,10 +48,10 @@ where /// [`ExpandMsgXof`]: crate::hash2curve::ExpandMsgXof fn hash_from_bytes<'a, X: ExpandMsg<'a>>( msgs: &[&[u8]], - dst: &'a [u8], + dsts: &'a [&'a [u8]], ) -> Result> { let mut u = [Self::FieldElement::default(), Self::FieldElement::default()]; - hash_to_field::(msgs, dst, &mut u)?; + hash_to_field::(msgs, dsts, &mut u)?; let q0 = u[0].map_to_curve(); let q1 = u[1].map_to_curve(); // Ideally we could add and then clear cofactor once @@ -88,10 +88,10 @@ where /// [`ExpandMsgXof`]: crate::hash2curve::ExpandMsgXof fn encode_from_bytes<'a, X: ExpandMsg<'a>>( msgs: &[&[u8]], - dst: &'a [u8], + dsts: &'a [&'a [u8]], ) -> Result> { let mut u = [Self::FieldElement::default()]; - hash_to_field::(msgs, dst, &mut u)?; + hash_to_field::(msgs, dsts, &mut u)?; let q0 = u[0].map_to_curve(); Ok(q0.clear_cofactor().into()) } @@ -109,12 +109,15 @@ where /// /// [`ExpandMsgXmd`]: crate::hash2curve::ExpandMsgXmd /// [`ExpandMsgXof`]: crate::hash2curve::ExpandMsgXof - fn hash_to_scalar<'a, X: ExpandMsg<'a>>(msgs: &[&[u8]], dst: &'a [u8]) -> Result + fn hash_to_scalar<'a, X: ExpandMsg<'a>>( + msgs: &[&[u8]], + dsts: &'a [&'a [u8]], + ) -> Result where Self::Scalar: FromOkm, { let mut u = [Self::Scalar::default()]; - hash_to_field::(msgs, dst, &mut u)?; + hash_to_field::(msgs, dsts, &mut u)?; Ok(u[0]) } } diff --git a/elliptic-curve/src/hash2curve/hash2field.rs b/elliptic-curve/src/hash2curve/hash2field.rs index 6cd0723aa..b0ee5b2d6 100644 --- a/elliptic-curve/src/hash2curve/hash2field.rs +++ b/elliptic-curve/src/hash2curve/hash2field.rs @@ -32,7 +32,7 @@ pub trait FromOkm { /// [`ExpandMsgXmd`]: crate::hash2field::ExpandMsgXmd /// [`ExpandMsgXof`]: crate::hash2field::ExpandMsgXof #[doc(hidden)] -pub fn hash_to_field<'a, E, T>(data: &[&[u8]], domain: &'a [u8], out: &mut [T]) -> Result<()> +pub fn hash_to_field<'a, E, T>(data: &[&[u8]], domain: &'a [&'a [u8]], out: &mut [T]) -> Result<()> where E: ExpandMsg<'a>, T: FromOkm + Default, diff --git a/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs b/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs index 4a4db7119..96a659b9a 100644 --- a/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs +++ b/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs @@ -25,8 +25,11 @@ pub trait ExpandMsg<'a> { /// /// Returns an expander that can be used to call `read` until enough /// bytes have been consumed - fn expand_message(msgs: &[&[u8]], dst: &'a [u8], len_in_bytes: usize) - -> Result; + fn expand_message( + msgs: &[&[u8]], + dsts: &'a [&'a [u8]], + len_in_bytes: usize, + ) -> Result; } /// Expander that, call `read` until enough bytes have been consumed. @@ -47,54 +50,66 @@ where /// > 255 Hashed(GenericArray), /// <= 255 - Array(&'a [u8]), + Array(&'a [&'a [u8]]), } impl<'a, L> Domain<'a, L> where L: ArrayLength + IsLess, { - pub fn xof(dst: &'a [u8]) -> Result + pub fn xof(dsts: &'a [&'a [u8]]) -> Result where X: Default + ExtendableOutput + Update, { - if dst.is_empty() { + if dsts.is_empty() { Err(Error) - } else if dst.len() > MAX_DST_LEN { + } else if dsts.iter().map(|dst| dst.len()).sum::() > MAX_DST_LEN { let mut data = GenericArray::::default(); - X::default() - .chain(OVERSIZE_DST_SALT) - .chain(dst) - .finalize_xof() - .read(&mut data); + let mut hash = X::default(); + hash.update(OVERSIZE_DST_SALT); + + for dst in dsts { + hash.update(dst); + } + + hash.finalize_xof().read(&mut data); + Ok(Self::Hashed(data)) } else { - Ok(Self::Array(dst)) + Ok(Self::Array(dsts)) } } - pub fn xmd(dst: &'a [u8]) -> Result + pub fn xmd(dsts: &'a [&'a [u8]]) -> Result where X: Digest, { - if dst.is_empty() { + if dsts.is_empty() { Err(Error) - } else if dst.len() > MAX_DST_LEN { + } else if dsts.iter().map(|dst| dst.len()).sum::() > MAX_DST_LEN { Ok(Self::Hashed({ let mut hash = X::new(); hash.update(OVERSIZE_DST_SALT); - hash.update(dst); + + for dst in dsts { + hash.update(dst); + } + hash.finalize() })) } else { - Ok(Self::Array(dst)) + Ok(Self::Array(dsts)) } } - pub fn data(&self) -> &[u8] { + pub fn update_hash(&self, hash: &mut HashT) { match self { - Self::Hashed(d) => &d[..], - Self::Array(d) => d, + Self::Hashed(d) => hash.update(d), + Self::Array(d) => { + for d in d.iter() { + hash.update(d) + } + } } } @@ -103,13 +118,28 @@ where // Can't overflow because it's enforced on a type level. Self::Hashed(_) => L::to_u8(), // Can't overflow because it's checked on creation. - Self::Array(d) => u8::try_from(d.len()).expect("length overflow"), + Self::Array(d) => { + u8::try_from(d.iter().map(|d| d.len()).sum::()).expect("length overflow") + } } } #[cfg(test)] pub fn assert(&self, bytes: &[u8]) { - assert_eq!(self.data(), &bytes[..bytes.len() - 1]); + let data = match self { + Domain::Hashed(d) => d.to_vec(), + Domain::Array(d) => d.iter().copied().flatten().copied().collect(), + }; + assert_eq!(data, bytes); + } + + #[cfg(test)] + pub fn assert_dst(&self, bytes: &[u8]) { + let data = match self { + Domain::Hashed(d) => d.to_vec(), + Domain::Array(d) => d.iter().copied().flatten().copied().collect(), + }; + assert_eq!(data, &bytes[..bytes.len() - 1]); assert_eq!(self.len(), bytes[bytes.len() - 1]); } } diff --git a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs index 876b012f5..baf6f31b2 100644 --- a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs +++ b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs @@ -10,7 +10,7 @@ use digest::{ typenum::{IsLess, IsLessOrEqual, Unsigned, U256}, GenericArray, }, - Digest, + FixedOutput, HashMarker, }; /// Placeholder type for implementing `expand_message_xmd` based on a hash function @@ -22,14 +22,14 @@ use digest::{ /// - `len_in_bytes > 255 * HashT::OutputSize` pub struct ExpandMsgXmd(PhantomData) where - HashT: Digest + BlockSizeUser, + HashT: BlockSizeUser + Default + FixedOutput + HashMarker, HashT::OutputSize: IsLess, HashT::OutputSize: IsLessOrEqual; /// ExpandMsgXmd implements expand_message_xmd for the ExpandMsg trait impl<'a, HashT> ExpandMsg<'a> for ExpandMsgXmd where - HashT: Digest + BlockSizeUser, + HashT: BlockSizeUser + Default + FixedOutput + HashMarker, // If `len_in_bytes` is bigger then 256, length of the `DST` will depend on // the output size of the hash, which is still not allowed to be bigger then 256: // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-13.html#section-5.4.1-6 @@ -42,7 +42,7 @@ where fn expand_message( msgs: &[&[u8]], - dst: &'a [u8], + dsts: &'a [&'a [u8]], len_in_bytes: usize, ) -> Result { if len_in_bytes == 0 { @@ -54,26 +54,26 @@ where let b_in_bytes = HashT::OutputSize::to_usize(); let ell = u8::try_from((len_in_bytes + b_in_bytes - 1) / b_in_bytes).map_err(|_| Error)?; - let domain = Domain::xmd::(dst)?; - let mut b_0 = HashT::new(); - b_0.update(GenericArray::::default()); + let domain = Domain::xmd::(dsts)?; + let mut b_0 = HashT::default(); + b_0.update(&GenericArray::::default()); for msg in msgs { b_0.update(msg); } - b_0.update(len_in_bytes_u16.to_be_bytes()); - b_0.update([0]); - b_0.update(domain.data()); - b_0.update([domain.len()]); - let b_0 = b_0.finalize(); + b_0.update(&len_in_bytes_u16.to_be_bytes()); + b_0.update(&[0]); + domain.update_hash(&mut b_0); + b_0.update(&[domain.len()]); + let b_0 = b_0.finalize_fixed(); - let mut b_vals = HashT::new(); + let mut b_vals = HashT::default(); b_vals.update(&b_0[..]); - b_vals.update([1u8]); - b_vals.update(domain.data()); - b_vals.update([domain.len()]); - let b_vals = b_vals.finalize(); + b_vals.update(&[1u8]); + domain.update_hash(&mut b_vals); + b_vals.update(&[domain.len()]); + let b_vals = b_vals.finalize_fixed(); Ok(ExpanderXmd { b_0, @@ -89,7 +89,7 @@ where /// [`Expander`] type for [`ExpandMsgXmd`]. pub struct ExpanderXmd<'a, HashT> where - HashT: Digest + BlockSizeUser, + HashT: BlockSizeUser + Default + FixedOutput + HashMarker, HashT::OutputSize: IsLess, HashT::OutputSize: IsLessOrEqual, { @@ -103,7 +103,7 @@ where impl<'a, HashT> ExpanderXmd<'a, HashT> where - HashT: Digest + BlockSizeUser, + HashT: BlockSizeUser + Default + FixedOutput + HashMarker, HashT::OutputSize: IsLess, HashT::OutputSize: IsLessOrEqual, { @@ -118,12 +118,12 @@ where .zip(&self.b_vals[..]) .enumerate() .for_each(|(j, (b0val, bi1val))| tmp[j] = b0val ^ bi1val); - let mut b_vals = HashT::new(); - b_vals.update(tmp); - b_vals.update([self.index]); - b_vals.update(self.domain.data()); - b_vals.update([self.domain.len()]); - self.b_vals = b_vals.finalize(); + let mut b_vals = HashT::default(); + b_vals.update(&tmp); + b_vals.update(&[self.index]); + self.domain.update_hash(&mut b_vals); + b_vals.update(&[self.domain.len()]); + self.b_vals = b_vals.finalize_fixed(); true } else { false @@ -133,7 +133,7 @@ where impl<'a, HashT> Expander for ExpanderXmd<'a, HashT> where - HashT: Digest + BlockSizeUser, + HashT: BlockSizeUser + Default + FixedOutput + HashMarker, HashT::OutputSize: IsLess, HashT::OutputSize: IsLessOrEqual, { @@ -165,7 +165,7 @@ mod test { len_in_bytes: u16, bytes: &[u8], ) where - HashT: Digest + BlockSizeUser, + HashT: BlockSizeUser + Default + FixedOutput + HashMarker, HashT::OutputSize: IsLess, { let block = HashT::BlockSize::to_usize(); @@ -183,8 +183,8 @@ mod test { let pad = l + mem::size_of::(); assert_eq!([0], &bytes[l..pad]); - let dst = pad + domain.data().len(); - assert_eq!(domain.data(), &bytes[pad..dst]); + let dst = pad + usize::from(domain.len()); + domain.assert(&bytes[pad..dst]); let dst_len = dst + mem::size_of::(); assert_eq!([domain.len()], &bytes[dst..dst_len]); @@ -205,13 +205,14 @@ mod test { domain: &Domain<'_, HashT::OutputSize>, ) -> Result<()> where - HashT: Digest + BlockSizeUser, + HashT: BlockSizeUser + Default + FixedOutput + HashMarker, HashT::OutputSize: IsLess + IsLessOrEqual, { assert_message::(self.msg, domain, L::to_u16(), self.msg_prime); + let dst = [dst]; let mut expander = - ExpandMsgXmd::::expand_message(&[self.msg], dst, L::to_usize())?; + ExpandMsgXmd::::expand_message(&[self.msg], &dst, L::to_usize())?; let mut uniform_bytes = GenericArray::::default(); expander.fill_bytes(&mut uniform_bytes); @@ -227,8 +228,8 @@ mod test { const DST_PRIME: &[u8] = &hex!("515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826"); - let dst_prime = Domain::xmd::(DST)?; - dst_prime.assert(DST_PRIME); + let dst_prime = Domain::xmd::(&[DST])?; + dst_prime.assert_dst(DST_PRIME); const TEST_VECTORS_32: &[TestVector] = &[ TestVector { @@ -299,8 +300,8 @@ mod test { const DST_PRIME: &[u8] = &hex!("412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620"); - let dst_prime = Domain::xmd::(DST)?; - dst_prime.assert(DST_PRIME); + let dst_prime = Domain::xmd::(&[DST])?; + dst_prime.assert_dst(DST_PRIME); const TEST_VECTORS_32: &[TestVector] = &[ TestVector { @@ -377,8 +378,8 @@ mod test { const DST_PRIME: &[u8] = &hex!("515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626"); - let dst_prime = Domain::xmd::(DST)?; - dst_prime.assert(DST_PRIME); + let dst_prime = Domain::xmd::(&[DST])?; + dst_prime.assert_dst(DST_PRIME); const TEST_VECTORS_32: &[TestVector] = &[ TestVector { diff --git a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs index 107ac5e06..9a5ff19e9 100644 --- a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs +++ b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs @@ -27,7 +27,7 @@ where fn expand_message( msgs: &[&[u8]], - dst: &'a [u8], + dsts: &'a [&'a [u8]], len_in_bytes: usize, ) -> Result { if len_in_bytes == 0 { @@ -36,18 +36,17 @@ where let len_in_bytes = u16::try_from(len_in_bytes).map_err(|_| Error)?; - let domain = Domain::::xof::(dst)?; + let domain = Domain::::xof::(dsts)?; let mut reader = HashT::default(); for msg in msgs { reader = reader.chain(msg); } - let reader = reader - .chain(len_in_bytes.to_be_bytes()) - .chain(domain.data()) - .chain([domain.len()]) - .finalize_xof(); + reader.update(&len_in_bytes.to_be_bytes()); + domain.update_hash(&mut reader); + reader.update(&[domain.len()]); + let reader = reader.finalize_xof(); Ok(Self { reader }) } } @@ -87,8 +86,8 @@ mod test { &bytes[msg_len..len_in_bytes_len] ); - let dst = len_in_bytes_len + domain.data().len(); - assert_eq!(domain.data(), &bytes[len_in_bytes_len..dst]); + let dst = len_in_bytes_len + usize::from(domain.len()); + domain.assert(&bytes[len_in_bytes_len..dst]); let dst_len = dst + mem::size_of::(); assert_eq!([domain.len()], &bytes[dst..dst_len]); @@ -111,7 +110,7 @@ mod test { assert_message::(self.msg, domain, L::to_u16(), self.msg_prime); let mut expander = - ExpandMsgXof::::expand_message(&[self.msg], dst, L::to_usize())?; + ExpandMsgXof::::expand_message(&[self.msg], &[dst], L::to_usize())?; let mut uniform_bytes = GenericArray::::default(); expander.fill_bytes(&mut uniform_bytes); @@ -127,8 +126,8 @@ mod test { const DST_PRIME: &[u8] = &hex!("515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824"); - let dst_prime = Domain::::xof::(DST)?; - dst_prime.assert(DST_PRIME); + let dst_prime = Domain::::xof::(&[DST])?; + dst_prime.assert_dst(DST_PRIME); const TEST_VECTORS_32: &[TestVector] = &[ TestVector { @@ -203,8 +202,8 @@ mod test { const DST_PRIME: &[u8] = &hex!("acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20"); - let dst_prime = Domain::::xof::(DST)?; - dst_prime.assert(DST_PRIME); + let dst_prime = Domain::::xof::(&[DST])?; + dst_prime.assert_dst(DST_PRIME); const TEST_VECTORS_32: &[TestVector] = &[ TestVector { @@ -281,8 +280,8 @@ mod test { const DST_PRIME: &[u8] = &hex!("515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624"); - let dst_prime = Domain::::xof::(DST)?; - dst_prime.assert(DST_PRIME); + let dst_prime = Domain::::xof::(&[DST])?; + dst_prime.assert_dst(DST_PRIME); const TEST_VECTORS_32: &[TestVector] = &[ TestVector { From d19d50f4db46d987f7ed59dd3b6b5f83ff2f95e0 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 2 Feb 2023 19:36:01 -0700 Subject: [PATCH 0972/1461] elliptic-curve: add `Invert::invert_vartime` (#1239) Adds support for optimized variable-time inversions via the `Invert` trait. By default, the implementation uses a constant-time inversion by calling `Invert::invert`. --- elliptic-curve/src/ops.rs | 11 +++++++++++ elliptic-curve/src/scalar/invert.rs | 8 ++++++++ elliptic-curve/src/scalar/nonzero.rs | 10 +++++++++- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/elliptic-curve/src/ops.rs b/elliptic-curve/src/ops.rs index 377558a15..4b2ee3329 100644 --- a/elliptic-curve/src/ops.rs +++ b/elliptic-curve/src/ops.rs @@ -12,6 +12,17 @@ pub trait Invert { /// Invert a field element. fn invert(&self) -> Self::Output; + + /// Invert a field element in variable time. + /// + /// ⚠️ WARNING! + /// + /// This method should not be used with secret values, as its variable-time + /// operation can potentially leak secrets through sidechannels. + fn invert_vartime(&self) -> Self::Output { + // Fall back on constant-time implementation by default. + self.invert() + } } impl Invert for F { diff --git a/elliptic-curve/src/scalar/invert.rs b/elliptic-curve/src/scalar/invert.rs index e9ee44ea9..1087835ec 100644 --- a/elliptic-curve/src/scalar/invert.rs +++ b/elliptic-curve/src/scalar/invert.rs @@ -8,6 +8,14 @@ use subtle::CtOption; /// Returns none if the scalar is zero. /// /// +/// +/// ⚠️ WARNING! +/// +/// This generic implementation relies on special properties of the scalar +/// field implementation and may not work correctly! Please ensure your use +/// cases are well-tested! +/// +/// USE AT YOUR OWN RISK! #[allow(non_snake_case)] pub fn invert_vartime(scalar: &Scalar) -> CtOption> where diff --git a/elliptic-curve/src/scalar/nonzero.rs b/elliptic-curve/src/scalar/nonzero.rs index 6839d42a8..e4769cb87 100644 --- a/elliptic-curve/src/scalar/nonzero.rs +++ b/elliptic-curve/src/scalar/nonzero.rs @@ -184,13 +184,21 @@ where impl Invert for NonZeroScalar where C: CurveArithmetic, + Scalar: Invert>>, { type Output = Self; fn invert(&self) -> Self { Self { // This will always succeed since `scalar` will never be 0 - scalar: ff::Field::invert(&self.scalar).unwrap(), + scalar: Invert::invert(&self.scalar).unwrap(), + } + } + + fn invert_vartime(&self) -> Self::Output { + Self { + // This will always succeed since `scalar` will never be 0 + scalar: Invert::invert_vartime(&self.scalar).unwrap(), } } } From c7bfb6d05c3f16578b57776ad63e82b2c98ce789 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 2 Feb 2023 19:56:06 -0700 Subject: [PATCH 0973/1461] elliptic-curve: remove generic `invert_vartime` implementation (#1240) It's mathematically unsafe in that it relies on field element representations outside the curve's modulus, which doesn't work in a generic context. The newly added `Invert::invert_vartime` method allows plugging in generic variable-time inversions. --- elliptic-curve/src/scalar.rs | 4 +- elliptic-curve/src/scalar/blinded.rs | 7 +-- elliptic-curve/src/scalar/invert.rs | 69 ---------------------------- elliptic-curve/src/scalar/nonzero.rs | 13 ------ 4 files changed, 5 insertions(+), 88 deletions(-) delete mode 100644 elliptic-curve/src/scalar/invert.rs diff --git a/elliptic-curve/src/scalar.rs b/elliptic-curve/src/scalar.rs index 6ffd63bea..eb992493a 100644 --- a/elliptic-curve/src/scalar.rs +++ b/elliptic-curve/src/scalar.rs @@ -3,14 +3,12 @@ #[cfg(feature = "arithmetic")] mod blinded; #[cfg(feature = "arithmetic")] -mod invert; -#[cfg(feature = "arithmetic")] mod nonzero; mod primitive; pub use self::primitive::ScalarPrimitive; #[cfg(feature = "arithmetic")] -pub use self::{blinded::BlindedScalar, invert::invert_vartime, nonzero::NonZeroScalar}; +pub use self::{blinded::BlindedScalar, nonzero::NonZeroScalar}; use crypto_bigint::Integer; use subtle::Choice; diff --git a/elliptic-curve/src/scalar/blinded.rs b/elliptic-curve/src/scalar/blinded.rs index 33303aef1..29cfea98c 100644 --- a/elliptic-curve/src/scalar/blinded.rs +++ b/elliptic-curve/src/scalar/blinded.rs @@ -1,6 +1,6 @@ //! Random blinding support for [`Scalar`] -use super::{invert_vartime, Scalar}; +use super::Scalar; use crate::{ops::Invert, CurveArithmetic}; use group::ff::Field; use rand_core::CryptoRngCore; @@ -57,8 +57,9 @@ where fn invert(&self) -> CtOption> { // prevent side channel analysis of scalar inversion by pre-and-post-multiplying // with the random masking scalar - let masked_scalar = self.scalar * self.mask; - invert_vartime::(&masked_scalar).map(|s| s * self.mask) + (self.scalar * self.mask) + .invert_vartime() + .map(|s| s * self.mask) } } diff --git a/elliptic-curve/src/scalar/invert.rs b/elliptic-curve/src/scalar/invert.rs deleted file mode 100644 index 1087835ec..000000000 --- a/elliptic-curve/src/scalar/invert.rs +++ /dev/null @@ -1,69 +0,0 @@ -use super::FromUintUnchecked; -use crate::{CurveArithmetic, Scalar}; -use ff::{Field, PrimeField}; -use subtle::CtOption; - -/// Fast variable-time inversion using Stein's algorithm. -/// -/// Returns none if the scalar is zero. -/// -/// -/// -/// ⚠️ WARNING! -/// -/// This generic implementation relies on special properties of the scalar -/// field implementation and may not work correctly! Please ensure your use -/// cases are well-tested! -/// -/// USE AT YOUR OWN RISK! -#[allow(non_snake_case)] -pub fn invert_vartime(scalar: &Scalar) -> CtOption> -where - C: CurveArithmetic, -{ - let order_div_2 = Scalar::::from_uint_unchecked(C::ORDER >> 1); - - let mut u = *scalar; - let mut v = Scalar::::from_uint_unchecked(C::ORDER); // note: technically invalid - let mut A = Scalar::::ONE; - let mut C = Scalar::::ZERO; - - while !bool::from(u.is_zero()) { - // u-loop - while bool::from(u.is_even()) { - u >>= 1; - - let was_odd: bool = A.is_odd().into(); - A >>= 1; - - if was_odd { - A += order_div_2; - A += Scalar::::ONE; - } - } - - // v-loop - while bool::from(v.is_even()) { - v >>= 1; - - let was_odd: bool = C.is_odd().into(); - C >>= 1; - - if was_odd { - C += order_div_2; - C += Scalar::::ONE; - } - } - - // sub-step - if u < v { - v -= &u; - C -= &A; - } else { - u -= &v; - A -= &C; - } - } - - CtOption::new(C, !scalar.is_zero()) -} diff --git a/elliptic-curve/src/scalar/nonzero.rs b/elliptic-curve/src/scalar/nonzero.rs index e4769cb87..c1f326b83 100644 --- a/elliptic-curve/src/scalar/nonzero.rs +++ b/elliptic-curve/src/scalar/nonzero.rs @@ -67,19 +67,6 @@ where pub fn from_uint(uint: C::Uint) -> CtOption { ScalarPrimitive::new(uint).and_then(|scalar| Self::new(scalar.into())) } - - /// Perform an inversion in variable-time. - /// - /// ⚠️ WARNING! - /// - /// This method should not be used with (unblinded) secret scalars, as its - /// variable-time operation can potentially leak secrets through - /// sidechannels. - pub fn invert_vartime(&self) -> Self { - Self { - scalar: super::invert_vartime::(&self.scalar).unwrap(), - } - } } impl AsRef> for NonZeroScalar From d57b54b9fcf5b28745547cb9fef313ab09780918 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 2 Feb 2023 20:05:32 -0700 Subject: [PATCH 0974/1461] elliptic-curve v0.13.0-pre.4 (#1241) --- elliptic-curve/Cargo.lock | 2 +- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index d485fe6a5..e2d175565 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -102,7 +102,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.13.0-pre.3" +version = "0.13.0-pre.4" dependencies = [ "base16ct", "base64ct", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index d13947166..0bc6c1d3f 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.13.0-pre.3" +version = "0.13.0-pre.4" description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, From d14be8eb1510812efc7422711ee285ee79f76a80 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 3 Feb 2023 07:52:29 -0700 Subject: [PATCH 0975/1461] elliptic-curve: remove blanket impl for `Invert` (#1242) Previously there was a blanket impl for types which impl `ff::Field`, however this precludes implementations being able to define their own `Invert::inert_vartime`. --- elliptic-curve/src/arithmetic.rs | 8 ++++---- elliptic-curve/src/dev.rs | 10 +++++++++- elliptic-curve/src/ops.rs | 10 +--------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/elliptic-curve/src/arithmetic.rs b/elliptic-curve/src/arithmetic.rs index 6bb9389d5..7ef7fc53d 100644 --- a/elliptic-curve/src/arithmetic.rs +++ b/elliptic-curve/src/arithmetic.rs @@ -1,14 +1,13 @@ //! Elliptic curve arithmetic traits. use crate::{ - ops::{LinearCombination, MulByGenerator, Reduce, ShrAssign}, + ops::{Invert, LinearCombination, MulByGenerator, Reduce, ShrAssign}, point::AffineCoordinates, - scalar::FromUintUnchecked, - scalar::IsHigh, + scalar::{FromUintUnchecked, IsHigh}, Curve, FieldBytes, PrimeCurve, ScalarPrimitive, }; use core::fmt::Debug; -use subtle::{ConditionallySelectable, ConstantTimeEq}; +use subtle::{ConditionallySelectable, ConstantTimeEq, CtOption}; use zeroize::DefaultIsZeroes; /// Elliptic curve with an arithmetic implementation. @@ -69,6 +68,7 @@ pub trait CurveArithmetic: Curve { + Into> + Into> + Into + + Invert> + IsHigh + PartialOrd + Reduce> diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 51d0b1e90..5ca2d9791 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -7,7 +7,7 @@ use crate::{ bigint::{Limb, U256}, error::{Error, Result}, generic_array::typenum::U32, - ops::{LinearCombination, MulByGenerator, Reduce, ShrAssign}, + ops::{Invert, LinearCombination, MulByGenerator, Reduce, ShrAssign}, pkcs8, point::AffineCoordinates, rand_core::RngCore, @@ -324,6 +324,14 @@ impl<'a> Product<&'a Scalar> for Scalar { } } +impl Invert for Scalar { + type Output = CtOption; + + fn invert(&self) -> CtOption { + unimplemented!(); + } +} + impl Reduce for Scalar { type Bytes = FieldBytes; diff --git a/elliptic-curve/src/ops.rs b/elliptic-curve/src/ops.rs index 4b2ee3329..b7e9e3d46 100644 --- a/elliptic-curve/src/ops.rs +++ b/elliptic-curve/src/ops.rs @@ -3,7 +3,7 @@ pub use core::ops::{Add, AddAssign, Mul, Neg, Shr, ShrAssign, Sub, SubAssign}; use crypto_bigint::Integer; -use {group::Group, subtle::CtOption}; +use group::Group; /// Perform an inversion on a field element (i.e. base field element or scalar) pub trait Invert { @@ -25,14 +25,6 @@ pub trait Invert { } } -impl Invert for F { - type Output = CtOption; - - fn invert(&self) -> CtOption { - ff::Field::invert(self) - } -} - /// Linear combination. /// /// This trait enables crates to provide an optimized implementation of From bae41969049499dcb1b1509372579deda0e732a1 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 3 Feb 2023 10:26:44 -0700 Subject: [PATCH 0976/1461] elliptic-curve v0.13.0-pre.5 (#1243) --- elliptic-curve/Cargo.lock | 2 +- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index e2d175565..a55d7d36f 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -102,7 +102,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.13.0-pre.4" +version = "0.13.0-pre.5" dependencies = [ "base16ct", "base64ct", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 0bc6c1d3f..54c56483d 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.13.0-pre.4" +version = "0.13.0-pre.5" description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, From 7cd5482de4b02f25f78a60c1ed49e0d781a0b9c4 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 12 Feb 2023 10:03:09 -0700 Subject: [PATCH 0977/1461] elliptic-curve: have `serde` feature activate `pkcs8` (#1245) Previously the `Serialize`/`Deserialize` impls for `PublicKey` were gated on both the `pkcs8` and `serde` features being enabled, which is potentially confusing. `PublicKey` uses `pkcs8` to serialize the public key as SPKI, which includes OIDs which identify it as an elliptic curve public key and also another OID which identifies the curve. Now that features are namespaced, it's easy to activate `pkcs8` from the `serde` feature to make this a bit easier. --- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/public_key.rs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 54c56483d..f57e2787c 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -67,7 +67,7 @@ hazmat = [] jwk = ["alloc", "base64ct/alloc", "serde", "serde_json", "zeroize/alloc"] pkcs8 = ["dep:pkcs8", "sec1"] pem = ["alloc", "arithmetic", "pem-rfc7468/alloc", "pkcs8", "sec1/pem"] -serde = ["alloc", "sec1/serde", "serdect"] +serde = ["dep:serdect", "alloc", "pkcs8", "sec1/serde"] voprf = ["digest"] [package.metadata.docs.rs] diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index 1a6b01b9b..d9704f960 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -32,7 +32,7 @@ use pkcs8::EncodePublicKey; #[cfg(any(feature = "jwk", feature = "pem"))] use alloc::string::{String, ToString}; -#[cfg(all(feature = "pkcs8", feature = "serde"))] +#[cfg(feature = "serde")] use serdect::serde::{de, ser, Deserialize, Serialize}; #[cfg(all(feature = "sec1", feature = "pkcs8"))] @@ -413,7 +413,7 @@ where } } -#[cfg(all(feature = "pkcs8", feature = "serde"))] +#[cfg(feature = "serde")] impl Serialize for PublicKey where C: AssociatedOid + CurveArithmetic, @@ -429,7 +429,7 @@ where } } -#[cfg(all(feature = "pkcs8", feature = "serde"))] +#[cfg(feature = "serde")] impl<'de, C> Deserialize<'de> for PublicKey where C: AssociatedOid + CurveArithmetic, From bf9cf0fc84aa2d1159c979d45a63945a411e3bcf Mon Sep 17 00:00:00 2001 From: FssAy <49795742+DmitrijVC@users.noreply.github.com> Date: Fri, 17 Feb 2023 17:42:41 +0100 Subject: [PATCH 0978/1461] password-hash: fix invalid operator (#1246) Allow the length of `s` to be exactly the same amount as `MAX_LENGTH` value. --- password-hash/src/salt.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/password-hash/src/salt.rs b/password-hash/src/salt.rs index 9702f742c..e6fb9d853 100644 --- a/password-hash/src/salt.rs +++ b/password-hash/src/salt.rs @@ -198,7 +198,7 @@ impl SaltString { let length = s.as_bytes().len(); - if length < Salt::MAX_LENGTH { + if length <= Salt::MAX_LENGTH { let mut bytes = [0u8; Salt::MAX_LENGTH]; bytes[..length].copy_from_slice(s.as_bytes()); Ok(SaltString { From 25a6b2b49d4bd3e9c950e8bd58b5b2897eebae96 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 27 Feb 2023 10:44:00 -0700 Subject: [PATCH 0979/1461] password-hash: bump `base64ct` to 1.6; MSRV 1.60 (#1248) --- .github/workflows/crypto.yml | 6 +++--- .github/workflows/kem.yml | 4 ++-- .github/workflows/password-hash.yml | 4 ++-- .github/workflows/workspace.yml | 2 +- Cargo.lock | 4 ++-- crypto/Cargo.toml | 2 +- crypto/README.md | 4 ++-- kem/Cargo.toml | 2 +- kem/README.md | 4 ++-- password-hash/Cargo.toml | 2 +- password-hash/README.md | 4 ++-- password-hash/src/ident.rs | 2 +- password-hash/src/value.rs | 2 +- 13 files changed, 21 insertions(+), 21 deletions(-) diff --git a/.github/workflows/crypto.yml b/.github/workflows/crypto.yml index 276594d36..5b9060050 100644 --- a/.github/workflows/crypto.yml +++ b/.github/workflows/crypto.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.57.0 # MSRV + - 1.60.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -59,7 +59,7 @@ jobs: strategy: matrix: rust: - - 1.57.0 # MSRV + - 1.60.0 # MSRV - stable steps: - uses: actions/checkout@v3 @@ -81,7 +81,7 @@ jobs: - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: - toolchain: 1.57.0 + toolchain: 1.60.0 components: clippy override: true profile: minimal diff --git a/.github/workflows/kem.yml b/.github/workflows/kem.yml index 4ece828aa..20cd62198 100644 --- a/.github/workflows/kem.yml +++ b/.github/workflows/kem.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.57.0 # Next MSRV candidate + - 1.60.0 # Next MSRV candidate - stable target: - thumbv7em-none-eabi @@ -59,7 +59,7 @@ jobs: strategy: matrix: rust: - - 1.57.0 # Next MSRV candidate + - 1.60.0 # Next MSRV candidate - stable steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/password-hash.yml b/.github/workflows/password-hash.yml index 2914e66e5..51ccb2a87 100644 --- a/.github/workflows/password-hash.yml +++ b/.github/workflows/password-hash.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.57.0 # MSRV + - 1.60.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -61,7 +61,7 @@ jobs: strategy: matrix: rust: - - 1.57.0 # MSRV + - 1.60.0 # MSRV - stable steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index 7b506044d..3793f3a23 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -26,7 +26,7 @@ jobs: - uses: RustCrypto/actions/cargo-cache@master - uses: actions-rs/toolchain@v1 with: - toolchain: 1.57.0 + toolchain: 1.60.0 components: clippy override: true profile: minimal diff --git a/Cargo.lock b/Cargo.lock index de3d66796..44106034b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -97,9 +97,9 @@ checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" [[package]] name = "base64ct" -version = "1.5.3" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b645a089122eccb6111b4f81cbc1a49f5900ac4666bb93ac027feaecf15607bf" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "bincode" diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 1462189ee..ebfcdf9a0 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -12,7 +12,7 @@ keywords = ["crypto", "encryption", "rustcrypto"] categories = ["cryptography", "no-std"] readme = "README.md" edition = "2021" -rust-version = "1.57" +rust-version = "1.60" [dependencies] crypto-common = { version = "0.1", default-features = false } diff --git a/crypto/README.md b/crypto/README.md index 3ed0ced44..4057e637f 100644 --- a/crypto/README.md +++ b/crypto/README.md @@ -14,7 +14,7 @@ access compatible versions of all traits from the Rust Crypto project. ## Minimum Supported Rust Version -Rust **1.57** or higher. +Rust **1.60** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -46,7 +46,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/crypto/badge.svg [docs-link]: https://docs.rs/crypto/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.57+-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/260050-Traits [build-image]: https://github.com/RustCrypto/traits/workflows/crypto/badge.svg?branch=master&event=push diff --git a/kem/Cargo.toml b/kem/Cargo.toml index b81be916f..12587fd0f 100644 --- a/kem/Cargo.toml +++ b/kem/Cargo.toml @@ -10,7 +10,7 @@ readme = "README.md" edition = "2021" keywords = ["crypto"] categories = ["cryptography", "no-std"] -rust-version = "1.56" +rust-version = "1.60" [dependencies] rand_core = "0.6" diff --git a/kem/README.md b/kem/README.md index 3be7d0cf9..f9a933329 100644 --- a/kem/README.md +++ b/kem/README.md @@ -15,7 +15,7 @@ The crate exposes four traits, `Encapsulator`, `Decapsulator`, `AuthEncapsulator ## Minimum Supported Rust Version -Rust **1.56** or higher. +Rust **1.60** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -47,7 +47,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/kem/badge.svg [docs-link]: https://docs.rs/kem/ [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/260048-signatures [build-image]: https://github.com/RustCrypto/traits/workflows/kem/badge.svg?branch=master&event=push diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index 5cc5dbd30..98b076868 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -14,7 +14,7 @@ repository = "https://github.com/RustCrypto/traits/tree/master/password-hash" categories = ["authentication", "cryptography", "no-std"] keywords = ["crypt", "mcf", "password", "pbkdf", "phc"] edition = "2021" -rust-version = "1.57" +rust-version = "1.60" [dependencies] base64ct = "1" diff --git a/password-hash/README.md b/password-hash/README.md index 499cb44f4..a3a91adf4 100644 --- a/password-hash/README.md +++ b/password-hash/README.md @@ -29,7 +29,7 @@ this crate for interoperability: ## Minimum Supported Rust Version -Rust **1.57** or higher. +Rust **1.60** or higher. Minimum supported Rust version may be changed in the future, but it will be accompanied by a minor version bump. @@ -63,7 +63,7 @@ dual licensed as above, without any additional terms or conditions. [build-image]: https://github.com/RustCrypto/traits/workflows/password-hash/badge.svg?branch=master&event=push [build-link]: https://github.com/RustCrypto/traits/actions?query=workflow:password-hash [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.57+-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/260046-password-hashes diff --git a/password-hash/src/ident.rs b/password-hash/src/ident.rs index 02e326916..ce82b6a99 100644 --- a/password-hash/src/ident.rs +++ b/password-hash/src/ident.rs @@ -117,7 +117,7 @@ impl<'a> TryFrom<&'a str> for Ident<'a> { impl<'a> fmt::Display for Ident<'a> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(&*self) + f.write_str(self) } } diff --git a/password-hash/src/value.rs b/password-hash/src/value.rs index acce35cc9..5cac55919 100644 --- a/password-hash/src/value.rs +++ b/password-hash/src/value.rs @@ -130,7 +130,7 @@ impl<'a> Value<'a> { // Ensure all characters are digits for c in value.chars() { - if !matches!(c, '0'..='9') { + if !c.is_ascii_digit() { return Err(Error::ParamValueInvalid(InvalidValue::InvalidChar(c))); } } From 9da51bafb0b7e56f96b44bd6b14b31d14a6a8baa Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 27 Feb 2023 11:15:11 -0700 Subject: [PATCH 0980/1461] password-hash v0.5.0-pre.1 (#1249) --- Cargo.lock | 2 +- crypto/Cargo.toml | 2 +- password-hash/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 44106034b..f49c79633 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -702,7 +702,7 @@ dependencies = [ [[package]] name = "password-hash" -version = "0.5.0-pre.0" +version = "0.5.0-pre.1" dependencies = [ "base64ct", "rand_core 0.6.4", diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index ebfcdf9a0..f565daf8d 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -22,7 +22,7 @@ aead = { version = "0.5", optional = true, path = "../aead" } cipher = { version = "0.4", optional = true } digest = { version = "0.10", optional = true, features = ["mac"] } elliptic-curve = { version = "0.12", optional = true } # path = "../elliptic-curve" -password-hash = { version = "=0.5.0-pre.0", optional = true, path = "../password-hash" } +password-hash = { version = "=0.5.0-pre.1", optional = true, path = "../password-hash" } signature = { version = "2", optional = true, default-features = false, path = "../signature" } universal-hash = { version = "0.5", optional = true, path = "../universal-hash" } diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index 98b076868..296e46354 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -5,7 +5,7 @@ Traits which describe the functionality of password hashing algorithms, as well as a `no_std`-friendly implementation of the PHC string format (a well-defined subset of the Modular Crypt Format a.k.a. MCF) """ -version = "0.5.0-pre.0" +version = "0.5.0-pre.1" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" From db3b52c98086909de6c20079afc902eab15bc5e2 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 28 Feb 2023 09:12:31 -0700 Subject: [PATCH 0981/1461] elliptic-curve: bump `crypto-bigint` and format crates; MSRV 1.65 (#1251) Bumps the following dependencies: - `crypto-bigint` v0.5 - `pem-rfc7468` v0.7 - `pkcs8` v0.10 - `sec1` v0.7 - `serdect` v0.2 --- .github/workflows/elliptic-curve.yml | 4 +- elliptic-curve/Cargo.lock | 53 +++++++++++++++----------- elliptic-curve/Cargo.toml | 16 ++++---- elliptic-curve/README.md | 4 +- elliptic-curve/src/public_key.rs | 33 ++++++++-------- elliptic-curve/src/secret_key.rs | 8 +--- elliptic-curve/src/secret_key/pkcs8.rs | 12 ++---- elliptic-curve/tests/pkcs8.rs | 1 + 8 files changed, 65 insertions(+), 66 deletions(-) diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index 93e0061a8..c12e4a503 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -24,7 +24,7 @@ jobs: strategy: matrix: rust: - - 1.61.0 # MSRV + - 1.65.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -79,7 +79,7 @@ jobs: strategy: matrix: rust: - - 1.61.0 # MSRV + - 1.65.0 # MSRV - stable - nightly steps: diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index a55d7d36f..2ad17425b 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -8,11 +8,17 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + [[package]] name = "base64ct" -version = "1.5.3" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b645a089122eccb6111b4f81cbc1a49f5900ac4666bb93ac027feaecf15607bf" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "bitvec" @@ -43,9 +49,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "const-oid" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cec318a675afcb6a1ea1d4340e2d377e56e47c266f28043ceccbf4412ddfdd3b" +checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" [[package]] name = "cpufeatures" @@ -58,9 +64,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.5.0-pre.3" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c37ac947d5ac4ad24acbfe3ae18154b71eb91a360319c2f82e8c9d54d8de71c9" +checksum = "071c0f5945634bc9ba7a452f492377dd6b1993665ddb58f28704119b32f07a9a" dependencies = [ "generic-array", "rand_core", @@ -80,9 +86,9 @@ dependencies = [ [[package]] name = "der" -version = "0.6.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +checksum = "bc302fd9b18d66834a6f092d10ea85489c0ca8ad6b7304092135fab171d853cd" dependencies = [ "const-oid", "pem-rfc7468", @@ -104,7 +110,7 @@ dependencies = [ name = "elliptic-curve" version = "0.13.0-pre.5" dependencies = [ - "base16ct", + "base16ct 0.1.1", "base64ct", "crypto-bigint", "digest", @@ -150,6 +156,7 @@ checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] @@ -221,18 +228,18 @@ checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" [[package]] name = "pem-rfc7468" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d159833a9105500e0398934e205e0773f0b27529557134ecfc51c27646adac" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" dependencies = [ "base64ct", ] [[package]] name = "pkcs8" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +checksum = "e34154ec92c136238e7c210443538e64350962b8e2788cadcf5f781a6da70c36" dependencies = [ "der", "spki", @@ -261,11 +268,11 @@ checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" [[package]] name = "sec1" -version = "0.3.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +checksum = "48518a2b5775ba8ca5b46596aae011caa431e6ce7e4a67ead66d92f08884220e" dependencies = [ - "base16ct", + "base16ct 0.2.0", "der", "generic-array", "pkcs8", @@ -282,9 +289,9 @@ checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" [[package]] name = "serde_json" -version = "1.0.91" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883" +checksum = "cad406b69c91885b5107daf2c29572f6c8cdb3c66826821e286c533490c0bc76" dependencies = [ "itoa", "ryu", @@ -293,11 +300,11 @@ dependencies = [ [[package]] name = "serdect" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038fce1bf4d74b9b30ea7dcd59df75ba8ec669a5dcb3cc64fbfcef7334ced32c" +checksum = "a84f14a19e9a014bb9f4512488d9829a68e04ecabffb0f9904cd1ace94598177" dependencies = [ - "base16ct", + "base16ct 0.2.0", "serde", ] @@ -324,9 +331,9 @@ dependencies = [ [[package]] name = "spki" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +checksum = "c0445c905640145c7ea8c1993555957f65e7c46d0535b91ba501bc9bfc85522f" dependencies = [ "base64ct", "der", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index f57e2787c..e87dabad5 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -13,12 +13,12 @@ readme = "README.md" categories = ["cryptography", "no-std"] keywords = ["crypto", "ecc", "elliptic", "weierstrass"] edition = "2021" -rust-version = "1.61" +rust-version = "1.65" [dependencies] base16ct = "0.1.1" -crypto-bigint = { version = "=0.5.0-pre.3", default-features = false, features = ["rand_core", "generic-array", "zeroize"] } -generic-array = { version = "0.14", default-features = false } +crypto-bigint = { version = "0.5", default-features = false, features = ["rand_core", "generic-array", "zeroize"] } +generic-array = { version = "0.14.6", default-features = false, features = ["zeroize"] } rand_core = { version = "0.6.4", default-features = false } subtle = { version = "2", default-features = false } zeroize = { version = "1.5", default-features = false } @@ -30,10 +30,10 @@ ff = { version = "0.13", optional = true, default-features = false } group = { version = "0.13", optional = true, default-features = false } hkdf = { version = "0.12", optional = true, default-features = false } hex-literal = { version = "0.3", optional = true } -pem-rfc7468 = { version = "0.6", optional = true } -pkcs8 = { version = "0.9", optional = true, default-features = false } -sec1 = { version = "0.3", optional = true, features = ["subtle", "zeroize"] } -serdect = { version = "0.1", optional = true, default-features = false, features = ["alloc"] } +pem-rfc7468 = { version = "0.7", optional = true } +pkcs8 = { version = "0.10", optional = true, default-features = false } +sec1 = { version = "0.7.1", optional = true, features = ["subtle", "zeroize"] } +serdect = { version = "0.2", optional = true, default-features = false, features = ["alloc"] } serde_json = { version = "1", optional = true, default-features = false, features = ["alloc"] } [dev-dependencies] @@ -59,7 +59,7 @@ std = [ arithmetic = ["group"] bits = ["arithmetic", "ff/bits"] -dev = ["arithmetic", "hex-literal", "pem", "pkcs8"] +dev = ["arithmetic", "dep:hex-literal", "pem", "pkcs8"] hash2curve = ["arithmetic", "digest"] ecdh = ["arithmetic", "digest", "hkdf"] group = ["dep:group", "ff"] diff --git a/elliptic-curve/README.md b/elliptic-curve/README.md index e30b8503a..37163a775 100644 --- a/elliptic-curve/README.md +++ b/elliptic-curve/README.md @@ -15,7 +15,7 @@ and public/secret keys composed thereof. ## Minimum Supported Rust Version -Requires Rust **1.61** or higher. +Requires Rust **1.65** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -49,6 +49,6 @@ dual licensed as above, without any additional terms or conditions. [build-image]: https://github.com/RustCrypto/traits/actions/workflows/elliptic-curve.yml/badge.svg [build-link]: https://github.com/RustCrypto/traits/actions/workflows/elliptic-curve.yml [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.61+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.65+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260040-elliptic-curves diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index d9704f960..a7787ac0d 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -35,10 +35,13 @@ use alloc::string::{String, ToString}; #[cfg(feature = "serde")] use serdect::serde::{de, ser, Deserialize, Serialize}; +#[cfg(any(feature = "pem", feature = "serde"))] +use pkcs8::DecodePublicKey; + #[cfg(all(feature = "sec1", feature = "pkcs8"))] use { crate::{ - pkcs8::{self, AssociatedOid, DecodePublicKey}, + pkcs8::{self, AssociatedOid}, ALGORITHM_OID, }, pkcs8::der, @@ -339,7 +342,7 @@ where } #[cfg(all(feature = "pkcs8", feature = "sec1"))] -impl TryFrom> for PublicKey +impl TryFrom> for PublicKey where C: AssociatedOid + CurveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, @@ -347,22 +350,19 @@ where { type Error = pkcs8::spki::Error; - fn try_from(spki: pkcs8::SubjectPublicKeyInfo<'_>) -> pkcs8::spki::Result { + fn try_from(spki: pkcs8::SubjectPublicKeyInfoRef<'_>) -> pkcs8::spki::Result { spki.algorithm.assert_oids(ALGORITHM_OID, C::OID)?; - Self::from_sec1_bytes(spki.subject_public_key) + + let public_key_bytes = spki + .subject_public_key + .as_bytes() + .ok_or_else(|| der::Tag::BitString.value_error())?; + + Self::from_sec1_bytes(public_key_bytes) .map_err(|_| der::Tag::BitString.value_error().into()) } } -#[cfg(all(feature = "pkcs8", feature = "sec1"))] -impl DecodePublicKey for PublicKey -where - C: AssociatedOid + CurveArithmetic, - AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldBytesSize: ModulusSize, -{ -} - #[cfg(all(feature = "alloc", feature = "pkcs8"))] impl EncodePublicKey for PublicKey where @@ -371,16 +371,17 @@ where FieldBytesSize: ModulusSize, { fn to_public_key_der(&self) -> pkcs8::spki::Result { - let algorithm = pkcs8::AlgorithmIdentifier { + let algorithm = pkcs8::AlgorithmIdentifierRef { oid: ALGORITHM_OID, parameters: Some((&C::OID).into()), }; let public_key_bytes = self.to_encoded_point(false); + let subject_public_key = der::asn1::BitStringRef::new(0, public_key_bytes.as_bytes())?; - pkcs8::SubjectPublicKeyInfo { + pkcs8::SubjectPublicKeyInfoRef { algorithm, - subject_public_key: public_key_bytes.as_ref(), + subject_public_key, } .try_into() } diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 88119ee66..1ade30a6b 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -190,8 +190,7 @@ where AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldBytesSize: ModulusSize, { - // TODO(tarcieri): wrap `secret_key_bytes` in `Zeroizing` - let mut private_key_bytes = self.to_bytes(); + let private_key_bytes = Zeroizing::new(self.to_bytes()); let public_key_bytes = self.public_key().to_encoded_point(false); let ec_private_key = Zeroizing::new( @@ -200,12 +199,9 @@ where parameters: None, public_key: Some(public_key_bytes.as_bytes()), } - .to_vec()?, + .to_der()?, ); - // TODO(tarcieri): wrap `private_key_bytes` in `Zeroizing` - private_key_bytes.zeroize(); - Ok(ec_private_key) } diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs index d1fca76a7..79215b71f 100644 --- a/elliptic-curve/src/secret_key/pkcs8.rs +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -2,7 +2,7 @@ use super::SecretKey; use crate::{ - pkcs8::{self, der::Decode, AssociatedOid, DecodePrivateKey}, + pkcs8::{self, der::Decode, AssociatedOid}, sec1::{ModulusSize, ValidatePublicKey}, Curve, FieldBytesSize, ALGORITHM_OID, }; @@ -23,6 +23,7 @@ use { use { crate::{error::Error, Result}, core::str::FromStr, + pkcs8::DecodePrivateKey, }; impl TryFrom> for SecretKey @@ -42,13 +43,6 @@ where } } -impl DecodePrivateKey for SecretKey -where - C: Curve + AssociatedOid + ValidatePublicKey, - FieldBytesSize: ModulusSize, -{ -} - #[cfg(all(feature = "alloc", feature = "arithmetic"))] impl EncodePrivateKey for SecretKey where @@ -57,7 +51,7 @@ where FieldBytesSize: ModulusSize, { fn to_pkcs8_der(&self) -> pkcs8::Result { - let algorithm_identifier = pkcs8::AlgorithmIdentifier { + let algorithm_identifier = pkcs8::AlgorithmIdentifierRef { oid: ALGORITHM_OID, parameters: Some((&C::OID).into()), }; diff --git a/elliptic-curve/tests/pkcs8.rs b/elliptic-curve/tests/pkcs8.rs index 20982fc4e..2a27fc0c7 100644 --- a/elliptic-curve/tests/pkcs8.rs +++ b/elliptic-curve/tests/pkcs8.rs @@ -31,6 +31,7 @@ fn example_private_key() -> der::SecretDocument { #[test] fn decode_pkcs8_private_key_from_der() { + dbg!(example_private_key().as_bytes()); let secret_key = SecretKey::from_pkcs8_der(example_private_key().as_bytes()).unwrap(); assert_eq!(secret_key.to_bytes().as_slice(), &EXAMPLE_SCALAR); } From b792cc7fe9c62bdc5d8eea2f5bb0960f92b9bf88 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 Feb 2023 09:24:28 -0700 Subject: [PATCH 0982/1461] build(deps): bump const-oid from 0.9.1 to 0.9.2 (#1250) Bumps [const-oid](https://github.com/RustCrypto/formats) from 0.9.1 to 0.9.2. - [Release notes](https://github.com/RustCrypto/formats/releases) - [Commits](https://github.com/RustCrypto/formats/compare/const-oid/v0.9.1...const-oid/v0.9.2) --- updated-dependencies: - dependency-name: const-oid dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f49c79633..b3abe032e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -233,9 +233,9 @@ checksum = "9d6f2aa4d0537bcc1c74df8755072bd31c1ef1a3a1b85a68e8404a8c353b7b8b" [[package]] name = "const-oid" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cec318a675afcb6a1ea1d4340e2d377e56e47c266f28043ceccbf4412ddfdd3b" +checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" [[package]] name = "cpufeatures" @@ -368,7 +368,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" dependencies = [ - "const-oid 0.9.1", + "const-oid 0.9.2", "zeroize", ] @@ -398,7 +398,7 @@ version = "0.11.0-pre" dependencies = [ "blobby", "block-buffer 0.11.0-pre", - "const-oid 0.9.1", + "const-oid 0.9.2", "crypto-common 0.2.0-pre (registry+https://github.com/rust-lang/crates.io-index)", "subtle", ] From 61074bbfa71882e0b73152bb1bc2263e2983f23d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 28 Feb 2023 11:34:23 -0700 Subject: [PATCH 0983/1461] elliptic-curve v0.13.0-rc.0 (#1253) --- elliptic-curve/Cargo.lock | 2 +- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index 2ad17425b..5b4d5959f 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -108,7 +108,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.13.0-pre.5" +version = "0.13.0-rc.0" dependencies = [ "base16ct 0.1.1", "base64ct", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index e87dabad5..ba63abdcb 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.13.0-pre.5" +version = "0.13.0-rc.0" description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, From 410ecf54745469e14e1119c5b664f79f28f3c537 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 28 Feb 2023 15:35:37 -0700 Subject: [PATCH 0984/1461] elliptic-curve: dependency cleanups (#1254) - Bump `base16ct` to v0.2 - Put more dependencies behind namespaced features --- elliptic-curve/Cargo.lock | 12 +++--------- elliptic-curve/Cargo.toml | 12 ++++++------ 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index 5b4d5959f..81beb5817 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -2,12 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "base16ct" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" - [[package]] name = "base16ct" version = "0.2.0" @@ -110,7 +104,7 @@ dependencies = [ name = "elliptic-curve" version = "0.13.0-rc.0" dependencies = [ - "base16ct 0.1.1", + "base16ct", "base64ct", "crypto-bigint", "digest", @@ -272,7 +266,7 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48518a2b5775ba8ca5b46596aae011caa431e6ce7e4a67ead66d92f08884220e" dependencies = [ - "base16ct 0.2.0", + "base16ct", "der", "generic-array", "pkcs8", @@ -304,7 +298,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a84f14a19e9a014bb9f4512488d9829a68e04ecabffb0f9904cd1ace94598177" dependencies = [ - "base16ct 0.2.0", + "base16ct", "serde", ] diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index ba63abdcb..fc5d32706 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -16,7 +16,7 @@ edition = "2021" rust-version = "1.65" [dependencies] -base16ct = "0.1.1" +base16ct = "0.2" crypto-bigint = { version = "0.5", default-features = false, features = ["rand_core", "generic-array", "zeroize"] } generic-array = { version = "0.14.6", default-features = false, features = ["zeroize"] } rand_core = { version = "0.6.4", default-features = false } @@ -24,13 +24,13 @@ subtle = { version = "2", default-features = false } zeroize = { version = "1.5", default-features = false } # optional dependencies -base64ct = { version = "1", optional = true, default-features = false } +base64ct = { version = "1", optional = true, default-features = false, features = ["alloc"] } digest = { version = "0.10", optional = true } ff = { version = "0.13", optional = true, default-features = false } group = { version = "0.13", optional = true, default-features = false } hkdf = { version = "0.12", optional = true, default-features = false } hex-literal = { version = "0.3", optional = true } -pem-rfc7468 = { version = "0.7", optional = true } +pem-rfc7468 = { version = "0.7", optional = true, features = ["alloc"] } pkcs8 = { version = "0.10", optional = true, default-features = false } sec1 = { version = "0.7.1", optional = true, features = ["subtle", "zeroize"] } serdect = { version = "0.2", optional = true, default-features = false, features = ["alloc"] } @@ -61,12 +61,12 @@ arithmetic = ["group"] bits = ["arithmetic", "ff/bits"] dev = ["arithmetic", "dep:hex-literal", "pem", "pkcs8"] hash2curve = ["arithmetic", "digest"] -ecdh = ["arithmetic", "digest", "hkdf"] +ecdh = ["arithmetic", "digest", "dep:hkdf"] group = ["dep:group", "ff"] hazmat = [] -jwk = ["alloc", "base64ct/alloc", "serde", "serde_json", "zeroize/alloc"] +jwk = ["dep:base64ct", "dep:serde_json", "alloc", "serde", "zeroize/alloc"] pkcs8 = ["dep:pkcs8", "sec1"] -pem = ["alloc", "arithmetic", "pem-rfc7468/alloc", "pkcs8", "sec1/pem"] +pem = ["dep:pem-rfc7468", "alloc", "arithmetic", "pkcs8", "sec1/pem"] serde = ["dep:serdect", "alloc", "pkcs8", "sec1/serde"] voprf = ["digest"] From 3ab3a2df2d6464311119bdf4483341e69777e722 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 28 Feb 2023 17:14:35 -0700 Subject: [PATCH 0985/1461] elliptic-curve v0.13.0 (#1255) --- elliptic-curve/CHANGELOG.md | 77 ++++++++++++++++++++++++++++++++++++- elliptic-curve/Cargo.lock | 2 +- elliptic-curve/Cargo.toml | 2 +- 3 files changed, 77 insertions(+), 4 deletions(-) diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index 619c175cd..ae6731c66 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,11 +4,84 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## Unreleased - +## 0.13.0 (2023-02-28) +### Added +- `PublicKey::to_sec1_bytes` ([#1102]) - Forward `std` feature to `sec1` dependency ([#1131]) +- `NonIdentity` wrapper type ([#1176]) +- Impl `serde` traits for `NonZeroScalar` ([#1178]) +- `MulByGenerator` trait ([#1198]) +- `NonZeroScalar::invert_vartime` ([#1207]) +- `BlindedScalar` type ([#1208]) +- `point::Double` trait ([#1218]) +- `FieldBytesEncoding` trait ([#1235]) +- `Invert::invert_vartime` ([#1239]) +### Changed +- Allow bigger `c1` constant in `OsswuMapParams` ([#1024]) +- Rename `Curve::UInt` => `Curve::Uint` ([#1191]) +- Use weak feature activation ([#1192], [#1194]) +- Consolidate `CurveArithmetic` trait ([#1196]) +- Rename `SecretKey::to_pem` => `::to_sec1_pem` ([#1202]) +- Rename `ScalarCore` to `ScalarPrimitive` ([#1203]) +- Use `CryptoRngCore` trait ([#1206]) +- Refactor field element decoding/encoding ([#1220]) +- Update VOPRF identifier type ([#1175]) +- Rename `SecretKey::as_scalar_core` => `::as_scalar_primitive` ([#1228]) +- Rename `Reduce::from_bytes_reduced` => `::reduce_bytes` ([#1225], [#1229]) +- Consolidate `AffineCoordinates` trait ([#1237]) +- Allow multiple `dst`s in the `hash2curve` API ([#1238]) +- Have `serde` feature activate `pkcs8` ([#1245]) +- Dependency upgrades: + - `base16ct` ([#1254]) + - `crypto-bigint` v0.5 ([#1251]) + - `ff` and `group` v0.13 ([#1166]) + - `pem-rfc7468` v0.7 ([#1251]) + - `pkcs8` v0.10 ([#1251]) + - `sec1` v0.7 ([#1251]) + - `serdect` v0.2 ([#1251]) + +### Removed +- `impl_field_element!` macro ([#1165]) +- Direct `der` crate dependency ([#1195]) +- `AffineArithmetic`, `ProjectiveArithmetic`, `ScalarArithmetic` traits ([#1196]) +- Toplevel re-exports except for `AffinePoint`, `ProjectivePoint`, and `Scalar` ([#1223]) +- `Reduce` methods ([#1225]) +- Blanket impl for `Invert` ([#1242]) + +[#1024]: https://github.com/RustCrypto/traits/pull/1024 +[#1102]: https://github.com/RustCrypto/traits/pull/1102 [#1131]: https://github.com/RustCrypto/traits/pull/1131 +[#1165]: https://github.com/RustCrypto/traits/pull/1165 +[#1166]: https://github.com/RustCrypto/traits/pull/1166 +[#1175]: https://github.com/RustCrypto/traits/pull/1175 +[#1176]: https://github.com/RustCrypto/traits/pull/1176 +[#1178]: https://github.com/RustCrypto/traits/pull/1178 +[#1191]: https://github.com/RustCrypto/traits/pull/1191 +[#1192]: https://github.com/RustCrypto/traits/pull/1192 +[#1194]: https://github.com/RustCrypto/traits/pull/1194 +[#1195]: https://github.com/RustCrypto/traits/pull/1195 +[#1196]: https://github.com/RustCrypto/traits/pull/1196 +[#1198]: https://github.com/RustCrypto/traits/pull/1198 +[#1202]: https://github.com/RustCrypto/traits/pull/1202 +[#1203]: https://github.com/RustCrypto/traits/pull/1203 +[#1206]: https://github.com/RustCrypto/traits/pull/1206 +[#1207]: https://github.com/RustCrypto/traits/pull/1207 +[#1208]: https://github.com/RustCrypto/traits/pull/1208 +[#1218]: https://github.com/RustCrypto/traits/pull/1218 +[#1220]: https://github.com/RustCrypto/traits/pull/1220 +[#1223]: https://github.com/RustCrypto/traits/pull/1223 +[#1225]: https://github.com/RustCrypto/traits/pull/1225 +[#1228]: https://github.com/RustCrypto/traits/pull/1228 +[#1229]: https://github.com/RustCrypto/traits/pull/1229 +[#1235]: https://github.com/RustCrypto/traits/pull/1235 +[#1237]: https://github.com/RustCrypto/traits/pull/1237 +[#1238]: https://github.com/RustCrypto/traits/pull/1238 +[#1239]: https://github.com/RustCrypto/traits/pull/1239 +[#1242]: https://github.com/RustCrypto/traits/pull/1242 +[#1245]: https://github.com/RustCrypto/traits/pull/1245 +[#1251]: https://github.com/RustCrypto/traits/pull/1251 +[#1254]: https://github.com/RustCrypto/traits/pull/1254 ## 0.12.3 (2022-08-01) ### Added diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index 81beb5817..ab34a33a6 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -102,7 +102,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.13.0-rc.0" +version = "0.13.0" dependencies = [ "base16ct", "base64ct", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index fc5d32706..3b868e8e3 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.13.0-rc.0" +version = "0.13.0" description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, From b3abecb973993b8efc7345b325331d0daf90398d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 1 Mar 2023 14:56:46 -0700 Subject: [PATCH 0986/1461] elliptic-curve: `SecretKey::from_slice` short input support (#1256) Tolerates inputs which are slightly shorter than expected (up to 4-bytes) to handle inputs from formats which strip leading zeroes from serialized scalars --- elliptic-curve/src/secret_key.rs | 27 +++++++++++++++++++++++---- elliptic-curve/tests/secret_key.rs | 20 +++++++++++++++++++- 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 1ade30a6b..97b3d58bd 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -10,8 +10,7 @@ mod pkcs8; use crate::{Curve, Error, FieldBytes, Result, ScalarPrimitive}; use core::fmt::{self, Debug}; -use crypto_bigint::Integer; -use generic_array::GenericArray; +use generic_array::typenum::Unsigned; use subtle::{Choice, ConstantTimeEq}; use zeroize::{Zeroize, ZeroizeOnDrop}; @@ -157,9 +156,29 @@ where /// Deserialize secret key from an encoded secret scalar passed as a /// byte slice. + /// + /// The slice is expected to be at most `C::FieldBytesSize` bytes in + /// length but may be up to 4-bytes shorter than that, which is handled by + /// zero-padding the value. pub fn from_slice(slice: &[u8]) -> Result { - if slice.len() == C::Uint::BYTES { - Self::from_bytes(GenericArray::from_slice(slice)) + if slice.len() > C::FieldBytesSize::USIZE { + return Err(Error); + } + + /// Maximum number of "missing" bytes to interpret as zeroes. + const MAX_LEADING_ZEROES: usize = 4; + + let offset = C::FieldBytesSize::USIZE.saturating_sub(slice.len()); + + if offset == 0 { + Self::from_bytes(FieldBytes::::from_slice(slice)) + } else if offset <= MAX_LEADING_ZEROES { + let mut bytes = FieldBytes::::default(); + bytes[offset..].copy_from_slice(slice); + + let ret = Self::from_bytes(&bytes); + bytes.zeroize(); + ret } else { Err(Error) } diff --git a/elliptic-curve/tests/secret_key.rs b/elliptic-curve/tests/secret_key.rs index 0d7678cc2..a01de9067 100644 --- a/elliptic-curve/tests/secret_key.rs +++ b/elliptic-curve/tests/secret_key.rs @@ -5,6 +5,24 @@ use elliptic_curve::dev::SecretKey; #[test] -fn undersize_secret_key() { +fn from_slice_undersize() { assert!(SecretKey::from_slice(&[]).is_err()); } + +#[test] +fn from_slice_expected_size() { + let bytes = [1u8; 32]; + assert!(SecretKey::from_slice(&bytes).is_ok()); +} + +#[test] +fn from_slice_allowed_short() { + let bytes = [1u8; 28]; + assert!(SecretKey::from_slice(&bytes).is_ok()); +} + +#[test] +fn from_slice_too_short() { + let bytes = [1u8; 27]; + assert!(SecretKey::from_slice(&bytes).is_err()); +} From 0c7a6bfde0de0236d0699dee6339171acea0182f Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 1 Mar 2023 16:24:37 -0700 Subject: [PATCH 0987/1461] elliptic-curve v0.13.1 (#1258) --- elliptic-curve/CHANGELOG.md | 6 ++++++ elliptic-curve/Cargo.lock | 2 +- elliptic-curve/Cargo.toml | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index ae6731c66..7c7c32927 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.13.1 (2023-03-01) +### Added +- `SecretKey::from_slice` short input support ([#1256]) + +[#1256]: https://github.com/RustCrypto/traits/pull/1256 + ## 0.13.0 (2023-02-28) ### Added - `PublicKey::to_sec1_bytes` ([#1102]) diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index ab34a33a6..87eff8e03 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -102,7 +102,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.13.0" +version = "0.13.1" dependencies = [ "base16ct", "base64ct", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 3b868e8e3..9338b0eb0 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.13.0" +version = "0.13.1" description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, From 3716369cd01e7a14ba71079828e20fb38379ab02 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 3 Mar 2023 21:00:07 -0700 Subject: [PATCH 0988/1461] elliptic-curve: weakly activate `pkcs8?/std` (#1263) Activates the `std` feature of `pkcs8` when it's otherwise depended upon Closes #1262 --- elliptic-curve/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 9338b0eb0..994bb17fd 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -54,6 +54,7 @@ alloc = [ std = [ "alloc", "rand_core/std", + "pkcs8?/std", "sec1?/std" ] From 0a2ca9eff92ac298becb31aaf0072bd4b397a77a Mon Sep 17 00:00:00 2001 From: z33ky <1zeeky@gmail.com> Date: Sat, 4 Mar 2023 16:03:39 +0100 Subject: [PATCH 0989/1461] password-hash: provide std::error::Error::source() for Error (#1264) - Impl `std::error::Error` for `InvalidValue` - Provide `std::error::Error::source()` for `Error` The `Error` type sometimes wraps other errors, which are now returned by the `source()` method. --- password-hash/src/errors.rs | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/password-hash/src/errors.rs b/password-hash/src/errors.rs index f4719af31..44b95d438 100644 --- a/password-hash/src/errors.rs +++ b/password-hash/src/errors.rs @@ -100,7 +100,25 @@ impl fmt::Display for Error { } #[cfg(feature = "std")] -impl std::error::Error for Error {} +impl std::error::Error for Error { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match self { + Self::Algorithm => None, + Self::B64Encoding(err) => Some(err), + Self::Crypto => None, + Self::OutputSize { .. } => None, + Self::ParamNameDuplicated => None, + Self::ParamNameInvalid => None, + Self::ParamValueInvalid(err) => Some(err), + Self::ParamsMaxExceeded => None, + Self::Password => None, + Self::PhcStringField => None, + Self::PhcStringTrailingData => None, + Self::SaltInvalid(err) => Some(err), + Self::Version => None, + } + } +} impl From for Error { fn from(err: B64Error) -> Error { @@ -157,3 +175,6 @@ impl fmt::Display for InvalidValue { } } } + +#[cfg(feature = "std")] +impl std::error::Error for InvalidValue {} From d7e80c3e7b6b7579b12b13feb79d3c814a3260c0 Mon Sep 17 00:00:00 2001 From: z33ky <1zeeky@gmail.com> Date: Sat, 4 Mar 2023 17:41:17 +0100 Subject: [PATCH 0990/1461] password-hashes: Simplify Error::source() (#1265) --- password-hash/src/errors.rs | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/password-hash/src/errors.rs b/password-hash/src/errors.rs index 44b95d438..e43350617 100644 --- a/password-hash/src/errors.rs +++ b/password-hash/src/errors.rs @@ -103,19 +103,10 @@ impl fmt::Display for Error { impl std::error::Error for Error { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match self { - Self::Algorithm => None, Self::B64Encoding(err) => Some(err), - Self::Crypto => None, - Self::OutputSize { .. } => None, - Self::ParamNameDuplicated => None, - Self::ParamNameInvalid => None, Self::ParamValueInvalid(err) => Some(err), - Self::ParamsMaxExceeded => None, - Self::Password => None, - Self::PhcStringField => None, - Self::PhcStringTrailingData => None, Self::SaltInvalid(err) => Some(err), - Self::Version => None, + _ => None, } } } From da4c3de2e99f3847b1a1f84c54e3d848ca5f4c8f Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 4 Mar 2023 10:33:39 -0700 Subject: [PATCH 0991/1461] digest+universal-hash: loosen `subtle` version requirement (#1260) Relaxes the version requirement from `=2.4` to `^2.4`, which allows usage of the newly published `subtle` v2.5.0 release. --- digest/Cargo.toml | 2 +- universal-hash/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 61f468357..9e936809c 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -17,7 +17,7 @@ crypto-common = "0.2.0-pre" # optional dependencies block-buffer = { version = "0.11.0-pre", optional = true } -subtle = { version = "=2.4", default-features = false, optional = true } +subtle = { version = "2.4", default-features = false, optional = true } blobby = { version = "0.3", optional = true } const-oid = { version = "0.9", optional = true } diff --git a/universal-hash/Cargo.toml b/universal-hash/Cargo.toml index cd954a971..37a41f46d 100644 --- a/universal-hash/Cargo.toml +++ b/universal-hash/Cargo.toml @@ -14,7 +14,7 @@ categories = ["cryptography", "no-std"] [dependencies] crypto-common = "0.1.6" -subtle = { version = "=2.4", default-features = false } +subtle = { version = "2.4", default-features = false } [features] std = ["crypto-common/std"] From 74e85e7432a8a71e2b55544a7747d419f8522c6a Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 4 Mar 2023 11:32:41 -0700 Subject: [PATCH 0992/1461] password-hash: clarity improvements for `Salt*` APIs (#1266) The `Salt` and `SaltString` types are wrappers for B64-encoded salt strings as used by the PHC string format. These API changes make it clearer that the input string needs to be B64-encoded. The old API is preserved but with deprecations to ease upgrades. The following methods were renamed: - `Salt::new` => `Salt::from_b64` - `Salt::b64_decode` => `Salt::decode_b64` (for consistency) - `SaltString::new` => `SaltString::from_b64` - `SaltString::b64_decode` => `SaltString::decode_b64` - `SaltString::b64_encode` => `SaltString::encode_b64` The `Salt::as_bytes` and `SaltString::as_bytes` methods were removed, as they return the B64-encoded string as bytes, rather than decoding B64 to bytes, which is what a user might be expecting. --- password-hash/Cargo.toml | 2 +- password-hash/src/salt.rs | 148 +++++++++++++++++---------- password-hash/tests/encoding.rs | 4 +- password-hash/tests/hashing.rs | 4 +- password-hash/tests/password_hash.rs | 10 +- 5 files changed, 102 insertions(+), 66 deletions(-) diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index 296e46354..17e49b010 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -21,7 +21,7 @@ base64ct = "1" subtle = { version = "2", default-features = false } # optional dependencies -rand_core = { version = "0.6", optional = true, default-features = false } +rand_core = { version = "0.6.4", optional = true, default-features = false } [features] default = ["rand_core"] diff --git a/password-hash/src/salt.rs b/password-hash/src/salt.rs index e6fb9d853..85198b679 100644 --- a/password-hash/src/salt.rs +++ b/password-hash/src/salt.rs @@ -5,7 +5,7 @@ use core::{fmt, str}; use crate::errors::InvalidValue; #[cfg(feature = "rand_core")] -use rand_core::{CryptoRng, RngCore}; +use rand_core::CryptoRngCore; /// Error message used with `expect` for when internal invariants are violated /// (i.e. the contents of a [`Salt`] should always be valid) @@ -100,9 +100,9 @@ impl<'a> Salt<'a> { /// [PHC string format specification]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#function-duties pub const RECOMMENDED_LENGTH: usize = 16; - /// Create a [`Salt`] from the given `str`, validating it according to - /// [`Salt::MIN_LENGTH`] and [`Salt::MAX_LENGTH`] length restrictions. - pub fn new(input: &'a str) -> Result { + /// Create a [`Salt`] from the given B64-encoded input string, validating + /// [`Salt::MIN_LENGTH`] and [`Salt::MAX_LENGTH`] restrictions. + pub fn from_b64(input: &'a str) -> Result { let length = input.as_bytes().len(); if length < Self::MIN_LENGTH { @@ -113,18 +113,27 @@ impl<'a> Salt<'a> { return Err(Error::SaltInvalid(InvalidValue::TooLong)); } + // TODO(tarcieri): full B64 decoding check? + for char in input.chars() { + // From the PHC string format spec: + // + // > The salt consists in a sequence of characters in: `[a-zA-Z0-9/+.-]` + // > (lowercase letters, uppercase letters, digits, /, +, . and -). + if !matches!(char, 'a'..='z' | 'A'..='Z' | '0'..='9' | '/' | '+' | '.' | '-') { + return Err(Error::SaltInvalid(InvalidValue::InvalidChar(char))); + } + } + input.try_into().map(Self).map_err(|e| match e { Error::ParamValueInvalid(value_err) => Error::SaltInvalid(value_err), err => err, }) } - /// Attempt to decode a B64-encoded [`Salt`], writing the decoded result - /// into the provided buffer, and returning a slice of the buffer - /// containing the decoded result on success. - /// - /// [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#argon2-encoding - pub fn b64_decode<'b>(&self, buf: &'b mut [u8]) -> Result<&'b [u8]> { + /// Attempt to decode a B64-encoded [`Salt`] into bytes, writing the + /// decoded output into the provided buffer, and returning a slice of the + /// portion of the buffer containing the decoded result on success. + pub fn decode_b64<'b>(&self, buf: &'b mut [u8]) -> Result<&'b [u8]> { self.0.b64_decode(buf) } @@ -133,15 +142,25 @@ impl<'a> Salt<'a> { self.0.as_str() } - /// Borrow this value as bytes. - pub fn as_bytes(&self) -> &'a [u8] { - self.as_str().as_bytes() - } - /// Get the length of this value in ASCII characters. pub fn len(&self) -> usize { self.as_str().len() } + + /// Create a [`Salt`] from the given B64-encoded input string, validating + /// [`Salt::MIN_LENGTH`] and [`Salt::MAX_LENGTH`] restrictions. + #[deprecated(since = "0.5.0", note = "use `from_b64` instead")] + pub fn new(input: &'a str) -> Result { + Self::from_b64(input) + } + + /// Attempt to decode a B64-encoded [`Salt`] into bytes, writing the + /// decoded output into the provided buffer, and returning a slice of the + /// portion of the buffer containing the decoded result on success. + #[deprecated(since = "0.5.0", note = "use `decode_b64` instead")] + pub fn b64_decode<'b>(&self, buf: &'b mut [u8]) -> Result<&'b [u8]> { + self.decode_b64(buf) + } } impl<'a> AsRef for Salt<'a> { @@ -154,7 +173,7 @@ impl<'a> TryFrom<&'a str> for Salt<'a> { type Error = Error; fn try_from(input: &'a str) -> Result { - Self::new(input) + Self::from_b64(input) } } @@ -173,8 +192,8 @@ impl<'a> fmt::Debug for Salt<'a> { /// Owned stack-allocated equivalent of [`Salt`]. #[derive(Clone, Eq)] pub struct SaltString { - /// Byte array containing an ASCiI-encoded string. - bytes: [u8; Salt::MAX_LENGTH], + /// ASCII-encoded characters which comprise the salt. + chars: [u8; Salt::MAX_LENGTH], /// Length of the string in ASCII characters (i.e. bytes). length: u8, @@ -185,64 +204,81 @@ impl SaltString { /// Generate a random B64-encoded [`SaltString`]. #[cfg(feature = "rand_core")] #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] - pub fn generate(mut rng: impl CryptoRng + RngCore) -> Self { + pub fn generate(mut rng: impl CryptoRngCore) -> Self { let mut bytes = [0u8; Salt::RECOMMENDED_LENGTH]; rng.fill_bytes(&mut bytes); - Self::b64_encode(&bytes).expect(INVARIANT_VIOLATED_MSG) + Self::encode_b64(&bytes).expect(INVARIANT_VIOLATED_MSG) } - /// Create a new [`SaltString`]. - pub fn new(s: &str) -> Result { + /// Create a new [`SaltString`] from the given B64-encoded input string, + /// validating [`Salt::MIN_LENGTH`] and [`Salt::MAX_LENGTH`] restrictions. + pub fn from_b64(s: &str) -> Result { // Assert `s` parses successfully as a `Salt` - Salt::new(s)?; - - let length = s.as_bytes().len(); - - if length <= Salt::MAX_LENGTH { - let mut bytes = [0u8; Salt::MAX_LENGTH]; - bytes[..length].copy_from_slice(s.as_bytes()); - Ok(SaltString { - bytes, - length: length as u8, - }) - } else { - Err(Error::SaltInvalid(InvalidValue::TooLong)) - } + Salt::from_b64(s)?; + + let len = s.as_bytes().len(); + + let mut bytes = [0u8; Salt::MAX_LENGTH]; + bytes[..len].copy_from_slice(s.as_bytes()); + + Ok(SaltString { + chars: bytes, + length: len as u8, // `Salt::from_b64` check prevents overflow + }) + } + + /// Decode this [`SaltString`] from B64 into the provided output buffer. + pub fn decode_b64<'a>(&self, buf: &'a mut [u8]) -> Result<&'a [u8]> { + self.as_salt().decode_b64(buf) } /// Encode the given byte slice as B64 into a new [`SaltString`]. /// - /// Returns `None` if the slice is too long. - pub fn b64_encode(input: &[u8]) -> Result { + /// Returns `Error` if the slice is too long. + pub fn encode_b64(input: &[u8]) -> Result { let mut bytes = [0u8; Salt::MAX_LENGTH]; let length = Encoding::B64.encode(input, &mut bytes)?.len() as u8; - Ok(Self { bytes, length }) - } - - /// Decode this [`SaltString`] from B64 into the provided output buffer. - pub fn b64_decode<'a>(&self, buf: &'a mut [u8]) -> Result<&'a [u8]> { - self.as_salt().b64_decode(buf) + Ok(Self { + chars: bytes, + length, + }) } /// Borrow the contents of a [`SaltString`] as a [`Salt`]. pub fn as_salt(&self) -> Salt<'_> { - Salt::new(self.as_str()).expect(INVARIANT_VIOLATED_MSG) + Salt::from_b64(self.as_str()).expect(INVARIANT_VIOLATED_MSG) } /// Borrow the contents of a [`SaltString`] as a `str`. pub fn as_str(&self) -> &str { - str::from_utf8(&self.bytes[..(self.length as usize)]).expect(INVARIANT_VIOLATED_MSG) - } - - /// Borrow this value as bytes. - pub fn as_bytes(&self) -> &[u8] { - self.as_str().as_bytes() + str::from_utf8(&self.chars[..(self.length as usize)]).expect(INVARIANT_VIOLATED_MSG) } /// Get the length of this value in ASCII characters. pub fn len(&self) -> usize { self.as_str().len() } + + /// Create a new [`SaltString`] from the given B64-encoded input string, + /// validating [`Salt::MIN_LENGTH`] and [`Salt::MAX_LENGTH`] restrictions. + #[deprecated(since = "0.5.0", note = "use `from_b64` instead")] + pub fn new(s: &str) -> Result { + Self::from_b64(s) + } + + /// Decode this [`SaltString`] from B64 into the provided output buffer. + #[deprecated(since = "0.5.0", note = "use `decode_b64` instead")] + pub fn b64_decode<'a>(&self, buf: &'a mut [u8]) -> Result<&'a [u8]> { + self.decode_b64(buf) + } + + /// Encode the given byte slice as B64 into a new [`SaltString`]. + /// + /// Returns `Error` if the slice is too long. + #[deprecated(since = "0.5.0", note = "use `encode_b64` instead")] + pub fn b64_encode(input: &[u8]) -> Result { + Self::encode_b64(input) + } } impl AsRef for SaltString { @@ -284,21 +320,21 @@ mod tests { #[test] fn new_with_valid_min_length_input() { let s = "abcd"; - let salt = Salt::new(s).unwrap(); + let salt = Salt::from_b64(s).unwrap(); assert_eq!(salt.as_ref(), s); } #[test] fn new_with_valid_max_length_input() { let s = "012345678911234567892123456789312345678941234567"; - let salt = Salt::new(s).unwrap(); + let salt = Salt::from_b64(s).unwrap(); assert_eq!(salt.as_ref(), s); } #[test] fn reject_new_too_short() { for &too_short in &["", "a", "ab", "abc"] { - let err = Salt::new(too_short).err().unwrap(); + let err = Salt::from_b64(too_short).err().unwrap(); assert_eq!(err, Error::SaltInvalid(InvalidValue::TooShort)); } } @@ -306,14 +342,14 @@ mod tests { #[test] fn reject_new_too_long() { let s = "01234567891123456789212345678931234567894123456785234567896234567"; - let err = Salt::new(s).err().unwrap(); + let err = Salt::from_b64(s).err().unwrap(); assert_eq!(err, Error::SaltInvalid(InvalidValue::TooLong)); } #[test] fn reject_new_invalid_char() { let s = "01234_abcd"; - let err = Salt::new(s).err().unwrap(); + let err = Salt::from_b64(s).err().unwrap(); assert_eq!(err, Error::SaltInvalid(InvalidValue::InvalidChar('_'))); } } diff --git a/password-hash/tests/encoding.rs b/password-hash/tests/encoding.rs index faaa746d5..0d7c16f2e 100644 --- a/password-hash/tests/encoding.rs +++ b/password-hash/tests/encoding.rs @@ -23,10 +23,10 @@ const EXAMPLE_OUTPUT_RAW: &[u8] = #[test] fn salt_roundtrip() { let mut buffer = [0u8; 64]; - let salt = Salt::new(EXAMPLE_SALT_B64).unwrap(); + let salt = Salt::from_b64(EXAMPLE_SALT_B64).unwrap(); assert_eq!(salt.as_ref(), EXAMPLE_SALT_B64); - let salt_decoded = salt.b64_decode(&mut buffer).unwrap(); + let salt_decoded = salt.decode_b64(&mut buffer).unwrap(); assert_eq!(salt_decoded, EXAMPLE_SALT_RAW); } diff --git a/password-hash/tests/hashing.rs b/password-hash/tests/hashing.rs index 73378440a..ccb587324 100644 --- a/password-hash/tests/hashing.rs +++ b/password-hash/tests/hashing.rs @@ -29,7 +29,7 @@ impl PasswordHasher for StubPasswordHasher { } } - for slice in &[b"pw", password, b",salt:", salt.as_bytes()] { + for slice in &[b"pw", password, b",salt:", salt.as_str().as_bytes()] { output.extend_from_slice(slice); } @@ -68,7 +68,7 @@ impl<'a> TryFrom for ParamsString { #[test] fn verify_password_hash() { let valid_password = "test password"; - let salt = Salt::new("test-salt").unwrap(); + let salt = Salt::from_b64("test-salt").unwrap(); let hash = PasswordHash::generate(StubPasswordHasher, valid_password, salt).unwrap(); // Sanity tests for StubFunction impl above diff --git a/password-hash/tests/password_hash.rs b/password-hash/tests/password_hash.rs index 6b391f6b1..a8c7a2cc9 100644 --- a/password-hash/tests/password_hash.rs +++ b/password-hash/tests/password_hash.rs @@ -57,7 +57,7 @@ fn salt() { algorithm: EXAMPLE_ALGORITHM, version: None, params: ParamsString::new(), - salt: Some(Salt::new(EXAMPLE_SALT).unwrap()), + salt: Some(Salt::from_b64(EXAMPLE_SALT).unwrap()), hash: None, }; @@ -77,7 +77,7 @@ fn one_param_and_salt() { algorithm: EXAMPLE_ALGORITHM, version: None, params, - salt: Some(Salt::new(EXAMPLE_SALT).unwrap()), + salt: Some(Salt::from_b64(EXAMPLE_SALT).unwrap()), hash: None, }; @@ -94,7 +94,7 @@ fn params_and_salt() { algorithm: EXAMPLE_ALGORITHM, version: None, params: example_params(), - salt: Some(Salt::new(EXAMPLE_SALT).unwrap()), + salt: Some(Salt::from_b64(EXAMPLE_SALT).unwrap()), hash: None, }; @@ -111,7 +111,7 @@ fn salt_and_hash() { algorithm: EXAMPLE_ALGORITHM, version: None, params: ParamsString::default(), - salt: Some(Salt::new(EXAMPLE_SALT).unwrap()), + salt: Some(Salt::from_b64(EXAMPLE_SALT).unwrap()), hash: Some(EXAMPLE_HASH.try_into().unwrap()), }; @@ -131,7 +131,7 @@ fn all_fields() { algorithm: EXAMPLE_ALGORITHM, version: None, params: example_params(), - salt: Some(Salt::new(EXAMPLE_SALT).unwrap()), + salt: Some(Salt::from_b64(EXAMPLE_SALT).unwrap()), hash: Some(EXAMPLE_HASH.try_into().unwrap()), }; From fa4185db66d2e2c403e559219fb28405915c568e Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 4 Mar 2023 11:55:22 -0700 Subject: [PATCH 0993/1461] password-hash: add `getrandom` feature (#1267) --- password-hash/Cargo.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index 17e49b010..0cc3f58d3 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -28,6 +28,8 @@ default = ["rand_core"] alloc = ["base64ct/alloc"] std = ["alloc", "base64ct/std", "rand_core/std"] +getrandom = ["rand_core/getrandom"] + [package.metadata.docs.rs] all-features = true rustdoc-args = ["--cfg", "docsrs"] From c26f1548009d6655133a0caf921de21cf657c0c9 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 4 Mar 2023 12:44:56 -0700 Subject: [PATCH 0994/1461] password-hash: use `doc_auto_cfg` (#1268) Automatically generate feature-specific documentation --- password-hash/src/lib.rs | 5 +---- password-hash/src/salt.rs | 1 - 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index 54c139d89..4ba94a099 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -1,5 +1,5 @@ #![no_std] -#![cfg_attr(docsrs, feature(doc_cfg))] +#![cfg_attr(docsrs, feature(doc_auto_cfg))] #![doc = include_str!("../README.md")] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", @@ -26,7 +26,6 @@ extern crate alloc; extern crate std; #[cfg(feature = "rand_core")] -#[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] pub use rand_core; pub mod errors; @@ -231,7 +230,6 @@ impl<'a> PasswordHash<'a> { /// Serialize this [`PasswordHash`] as a [`PasswordHashString`]. #[cfg(feature = "alloc")] - #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] pub fn serialize(&self) -> PasswordHashString { self.into() } @@ -277,7 +275,6 @@ impl<'a> fmt::Display for PasswordHash<'a> { /// parse successfully. // TODO(tarcieri): cached parsed representations? or at least structural data #[cfg(feature = "alloc")] -#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] #[derive(Clone, Debug, Eq, PartialEq)] pub struct PasswordHashString { /// String value diff --git a/password-hash/src/salt.rs b/password-hash/src/salt.rs index 85198b679..2fb8784a3 100644 --- a/password-hash/src/salt.rs +++ b/password-hash/src/salt.rs @@ -203,7 +203,6 @@ pub struct SaltString { impl SaltString { /// Generate a random B64-encoded [`SaltString`]. #[cfg(feature = "rand_core")] - #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] pub fn generate(mut rng: impl CryptoRngCore) -> Self { let mut bytes = [0u8; Salt::RECOMMENDED_LENGTH]; rng.fill_bytes(&mut bytes); From 2975bae5d7224ede315ac70874cd1595ae0e6f8d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 4 Mar 2023 13:13:48 -0700 Subject: [PATCH 0995/1461] password-hash v0.5.0-rc.0 (#1269) --- Cargo.lock | 2 +- crypto/Cargo.toml | 2 +- password-hash/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b3abe032e..da5f70152 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -702,7 +702,7 @@ dependencies = [ [[package]] name = "password-hash" -version = "0.5.0-pre.1" +version = "0.5.0-rc.0" dependencies = [ "base64ct", "rand_core 0.6.4", diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index f565daf8d..d279f2c71 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -22,7 +22,7 @@ aead = { version = "0.5", optional = true, path = "../aead" } cipher = { version = "0.4", optional = true } digest = { version = "0.10", optional = true, features = ["mac"] } elliptic-curve = { version = "0.12", optional = true } # path = "../elliptic-curve" -password-hash = { version = "=0.5.0-pre.1", optional = true, path = "../password-hash" } +password-hash = { version = "=0.5.0-rc.0", optional = true, path = "../password-hash" } signature = { version = "2", optional = true, default-features = false, path = "../signature" } universal-hash = { version = "0.5", optional = true, path = "../universal-hash" } diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index 0cc3f58d3..acbc807f8 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -5,7 +5,7 @@ Traits which describe the functionality of password hashing algorithms, as well as a `no_std`-friendly implementation of the PHC string format (a well-defined subset of the Modular Crypt Format a.k.a. MCF) """ -version = "0.5.0-pre.1" +version = "0.5.0-rc.0" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" From 5691d072503ce3df9b7d1296c5f5b30240f4c161 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 4 Mar 2023 16:22:05 -0700 Subject: [PATCH 0996/1461] password-hash v0.5.0 (#1271) --- Cargo.lock | 2 +- crypto/Cargo.toml | 2 +- password-hash/CHANGELOG.md | 24 ++++++++++++++++++++++++ password-hash/Cargo.toml | 2 +- password-hash/LICENSE-MIT | 2 +- 5 files changed, 28 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index da5f70152..5d3a9c92a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -702,7 +702,7 @@ dependencies = [ [[package]] name = "password-hash" -version = "0.5.0-rc.0" +version = "0.5.0" dependencies = [ "base64ct", "rand_core 0.6.4", diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index d279f2c71..1e2b659ea 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -22,7 +22,7 @@ aead = { version = "0.5", optional = true, path = "../aead" } cipher = { version = "0.4", optional = true } digest = { version = "0.10", optional = true, features = ["mac"] } elliptic-curve = { version = "0.12", optional = true } # path = "../elliptic-curve" -password-hash = { version = "=0.5.0-rc.0", optional = true, path = "../password-hash" } +password-hash = { version = "0.5", optional = true, path = "../password-hash" } signature = { version = "2", optional = true, default-features = false, path = "../signature" } universal-hash = { version = "0.5", optional = true, path = "../universal-hash" } diff --git a/password-hash/CHANGELOG.md b/password-hash/CHANGELOG.md index 9328fce19..e32dd4271 100644 --- a/password-hash/CHANGELOG.md +++ b/password-hash/CHANGELOG.md @@ -5,6 +5,30 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.5.0 (2023-03-04) +### Added +- `Error::OutputSize` ([#1026]) +- `std::error::Error::source` for `Error` ([#1264]) +- `getrandom` feature ([#1267]) + +### Changed +- Use `Salt` type with `PasswordHasher` ([#1187]) +- Rename `Salt::new` => `Salt::from_b64` ([#1266]) +- Rename `Salt::b64_decode` => `Salt::decode_b64` ([#1266]) +- Rename `SaltString::new` => `SaltString::from_b64` ([#1266]) +- Rename `SaltString::b64_decode` => `SaltString::decode_b64` ([#1266]) +- Rename `SaltString::b64_encode` => `SaltString::encode_b64` ([#1266]) + +### Fixed +- Allow `Salt` to be exactly the same amount as `MAX_LENGTH` value ([#1246]) + +[#1026]: https://github.com/RustCrypto/traits/pull/1026 +[#1187]: https://github.com/RustCrypto/traits/pull/1187 +[#1246]: https://github.com/RustCrypto/traits/pull/1246 +[#1264]: https://github.com/RustCrypto/traits/pull/1264 +[#1266]: https://github.com/RustCrypto/traits/pull/1266 +[#1267]: https://github.com/RustCrypto/traits/pull/1267 + ## 0.4.2 (2022-06-27) ### Fixed - docs.rs metadata ([#1031]) diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index acbc807f8..e98b5ad0c 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -5,7 +5,7 @@ Traits which describe the functionality of password hashing algorithms, as well as a `no_std`-friendly implementation of the PHC string format (a well-defined subset of the Modular Crypt Format a.k.a. MCF) """ -version = "0.5.0-rc.0" +version = "0.5.0" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/password-hash/LICENSE-MIT b/password-hash/LICENSE-MIT index f39f9ff82..50b1254c1 100644 --- a/password-hash/LICENSE-MIT +++ b/password-hash/LICENSE-MIT @@ -1,4 +1,4 @@ -Copyright (c) 2020 RustCrypto Developers +Copyright (c) 2020-2023 RustCrypto Developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated From 947a4dba709b9d51b2a600f5bc5b4664b41675cf Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 4 Mar 2023 16:24:44 -0700 Subject: [PATCH 0997/1461] README.md: update MSRVs --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d907874ad..a83f72662 100644 --- a/README.md +++ b/README.md @@ -13,9 +13,9 @@ Collection of traits which describe functionality of cryptographic primitives. | [`cipher`] | [Block] and [stream cipher] | [![crates.io](https://img.shields.io/crates/v/cipher.svg)](https://crates.io/crates/cipher) | [![Documentation](https://docs.rs/cipher/badge.svg)](https://docs.rs/cipher) | ![MSRV 1.56][msrv-1.56] | | [`crypto‑common`] | Common cryptographic traits | [![crates.io](https://img.shields.io/crates/v/crypto-common.svg)](https://crates.io/crates/crypto-common) | [![Documentation](https://docs.rs/crypto-common/badge.svg)](https://docs.rs/crypto-common) | ![MSRV 1.56][msrv-1.56] | | [`digest`] | [Cryptographic hash function] | [![crates.io](https://img.shields.io/crates/v/digest.svg)](https://crates.io/crates/digest) | [![Documentation](https://docs.rs/digest/badge.svg)](https://docs.rs/digest) | ![MSRV 1.57][msrv-1.57] | -| [`elliptic‑curve`] | [Elliptic curve cryptography] | [![crates.io](https://img.shields.io/crates/v/elliptic-curve.svg)](https://crates.io/crates/elliptic-curve) | [![Documentation](https://docs.rs/elliptic-curve/badge.svg)](https://docs.rs/elliptic-curve) | ![MSRV 1.57][msrv-1.57] | +| [`elliptic‑curve`] | [Elliptic curve cryptography] | [![crates.io](https://img.shields.io/crates/v/elliptic-curve.svg)](https://crates.io/crates/elliptic-curve) | [![Documentation](https://docs.rs/elliptic-curve/badge.svg)](https://docs.rs/elliptic-curve) | ![MSRV 1.65][msrv-1.65] | | [`kem`] | [Key encapsulation mechanism] | [![crates.io](https://img.shields.io/crates/v/kem.svg)](https://crates.io/crates/kem) | [![Documentation](https://docs.rs/kem/badge.svg)](https://docs.rs/kem) | ![MSRV 1.56][msrv-1.56] | -| [`password-hash`] | [Password hashing] | [![crates.io](https://img.shields.io/crates/v/password-hash.svg)](https://crates.io/crates/password-hash) | [![Documentation](https://docs.rs/password-hash/badge.svg)](https://docs.rs/password-hash) | ![MSRV 1.57][msrv-1.57] | +| [`password-hash`] | [Password hashing] | [![crates.io](https://img.shields.io/crates/v/password-hash.svg)](https://crates.io/crates/password-hash) | [![Documentation](https://docs.rs/password-hash/badge.svg)](https://docs.rs/password-hash) | ![MSRV 1.60][msrv-1.60] | | [`signature`] | [Digital signature] | [![crates.io](https://img.shields.io/crates/v/signature.svg)](https://crates.io/crates/signature) | [![Documentation](https://docs.rs/signature/badge.svg)](https://docs.rs/signature) | ![MSRV 1.56][msrv-1.56] | | [`universal‑hash`] | [Universal hash function] | [![crates.io](https://img.shields.io/crates/v/universal-hash.svg)](https://crates.io/crates/universal-hash) | [![Documentation](https://docs.rs/universal-hash/badge.svg)](https://docs.rs/universal-hash) | ![MSRV 1.56][msrv-1.56] | @@ -51,6 +51,8 @@ Unless you explicitly state otherwise, any contribution intentionally submitted [deps-link]: https://deps.rs/repo/github/RustCrypto/traits [msrv-1.56]: https://img.shields.io/badge/rustc-1.56.0+-blue.svg [msrv-1.57]: https://img.shields.io/badge/rustc-1.57.0+-blue.svg +[msrv-1.60]: https://img.shields.io/badge/rustc-1.60.0+-blue.svg +[msrv-1.65]: https://img.shields.io/badge/rustc-1.65.0+-blue.svg [//]: # (crates) From 71783b9145d2bd6ab39e92a00bd649cb74377a38 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 8 Mar 2023 10:19:18 -0700 Subject: [PATCH 0998/1461] elliptic-curve: `PublicKey` <-> SEC1 conversions (#1272) Adds the following conversion impls to `PublicKey` - `TryFrom`: `sec1::{CompressedPoint`, `EncodedPoint}` - `Into` (via `From`): `sec1::{CompressedPoint`, `EncodedPoint}` --- elliptic-curve/src/public_key.rs | 99 +++++++++++++++++++++++++++++++- 1 file changed, 96 insertions(+), 3 deletions(-) diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index a7787ac0d..9237ef458 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -19,7 +19,7 @@ use core::str::FromStr; use { crate::{ point::PointCompression, - sec1::{EncodedPoint, FromEncodedPoint, ModulusSize, ToEncodedPoint}, + sec1::{CompressedPoint, EncodedPoint, FromEncodedPoint, ModulusSize, ToEncodedPoint}, Curve, FieldBytesSize, }, core::cmp::Ordering, @@ -143,8 +143,7 @@ where AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldBytesSize: ModulusSize, { - let point = EncodedPoint::::from(self); - point.to_bytes() + EncodedPoint::::from(self).to_bytes() } /// Borrow the inner [`AffinePoint`] from this [`PublicKey`]. @@ -250,6 +249,30 @@ where } } +#[cfg(feature = "sec1")] +impl From> for CompressedPoint +where + C: CurveArithmetic + PointCompression, + AffinePoint: FromEncodedPoint + ToEncodedPoint, + FieldBytesSize: ModulusSize, +{ + fn from(public_key: PublicKey) -> CompressedPoint { + CompressedPoint::::from(&public_key) + } +} + +#[cfg(feature = "sec1")] +impl From<&PublicKey> for CompressedPoint +where + C: CurveArithmetic + PointCompression, + AffinePoint: FromEncodedPoint + ToEncodedPoint, + FieldBytesSize: ModulusSize, +{ + fn from(public_key: &PublicKey) -> CompressedPoint { + CompressedPoint::::clone_from_slice(public_key.to_encoded_point(true).as_bytes()) + } +} + #[cfg(feature = "sec1")] impl From> for EncodedPoint where @@ -341,6 +364,62 @@ where } } +#[cfg(feature = "sec1")] +impl TryFrom> for PublicKey +where + C: CurveArithmetic, + FieldBytesSize: ModulusSize, + AffinePoint: FromEncodedPoint + ToEncodedPoint, +{ + type Error = Error; + + fn try_from(point: CompressedPoint) -> Result { + Self::from_sec1_bytes(&point) + } +} + +#[cfg(feature = "sec1")] +impl TryFrom<&CompressedPoint> for PublicKey +where + C: CurveArithmetic, + FieldBytesSize: ModulusSize, + AffinePoint: FromEncodedPoint + ToEncodedPoint, +{ + type Error = Error; + + fn try_from(point: &CompressedPoint) -> Result { + Self::from_sec1_bytes(point) + } +} + +#[cfg(feature = "sec1")] +impl TryFrom> for PublicKey +where + C: CurveArithmetic, + FieldBytesSize: ModulusSize, + AffinePoint: FromEncodedPoint + ToEncodedPoint, +{ + type Error = Error; + + fn try_from(point: EncodedPoint) -> Result { + Self::from_sec1_bytes(point.as_bytes()) + } +} + +#[cfg(feature = "sec1")] +impl TryFrom<&EncodedPoint> for PublicKey +where + C: CurveArithmetic, + FieldBytesSize: ModulusSize, + AffinePoint: FromEncodedPoint + ToEncodedPoint, +{ + type Error = Error; + + fn try_from(point: &EncodedPoint) -> Result { + Self::from_sec1_bytes(point.as_bytes()) + } +} + #[cfg(all(feature = "pkcs8", feature = "sec1"))] impl TryFrom> for PublicKey where @@ -351,6 +430,20 @@ where type Error = pkcs8::spki::Error; fn try_from(spki: pkcs8::SubjectPublicKeyInfoRef<'_>) -> pkcs8::spki::Result { + Self::try_from(&spki) + } +} + +#[cfg(all(feature = "pkcs8", feature = "sec1"))] +impl TryFrom<&pkcs8::SubjectPublicKeyInfoRef<'_>> for PublicKey +where + C: AssociatedOid + CurveArithmetic, + AffinePoint: FromEncodedPoint + ToEncodedPoint, + FieldBytesSize: ModulusSize, +{ + type Error = pkcs8::spki::Error; + + fn try_from(spki: &pkcs8::SubjectPublicKeyInfoRef<'_>) -> pkcs8::spki::Result { spki.algorithm.assert_oids(ALGORITHM_OID, C::OID)?; let public_key_bytes = spki From 8bd426128a5d2f0749a67bcfa338c45596fa10c4 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 8 Mar 2023 10:26:51 -0700 Subject: [PATCH 0999/1461] elliptic-curve v0.13.2 (#1273) --- elliptic-curve/CHANGELOG.md | 8 ++++++++ elliptic-curve/Cargo.lock | 2 +- elliptic-curve/Cargo.toml | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index 7c7c32927..f5bacf4a4 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.13.2 (2023-03-08) +### Added +- Weakly activate `pkcs8?/std` ([#1263]) +- More `PublicKey` <-> SEC1 conversions ([#1272]) + +[#1263]: https://github.com/RustCrypto/traits/pull/1263 +[#1272]: https://github.com/RustCrypto/traits/pull/1272 + ## 0.13.1 (2023-03-01) ### Added - `SecretKey::from_slice` short input support ([#1256]) diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index 87eff8e03..8cf4ebe3a 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -102,7 +102,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.13.1" +version = "0.13.2" dependencies = [ "base16ct", "base64ct", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 994bb17fd..6a34fbe12 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.13.1" +version = "0.13.2" description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, From 48517bc708fd3b67225571c14cd13c26806b737d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 8 Mar 2023 10:36:13 -0700 Subject: [PATCH 1000/1461] elliptic-curve: remove redundant bounds (#1274) Remove explicit bounds which are already ensured via supertrait bounds. --- elliptic-curve/src/public_key.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index 9237ef458..6af60d4dc 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -4,7 +4,7 @@ use crate::{ point::NonIdentity, AffinePoint, CurveArithmetic, Error, NonZeroScalar, ProjectivePoint, Result, }; use core::fmt::Debug; -use group::{Curve as _, Group}; +use group::{Curve, Group}; #[cfg(feature = "alloc")] use alloc::boxed::Box; @@ -20,7 +20,7 @@ use { crate::{ point::PointCompression, sec1::{CompressedPoint, EncodedPoint, FromEncodedPoint, ModulusSize, ToEncodedPoint}, - Curve, FieldBytesSize, + FieldBytesSize, }, core::cmp::Ordering, subtle::CtOption, @@ -122,7 +122,6 @@ where #[cfg(feature = "sec1")] pub fn from_sec1_bytes(bytes: &[u8]) -> Result where - C: Curve, FieldBytesSize: ModulusSize, AffinePoint: FromEncodedPoint + ToEncodedPoint, { @@ -139,7 +138,7 @@ where #[cfg(feature = "alloc")] pub fn to_sec1_bytes(&self) -> Box<[u8]> where - C: CurveArithmetic + PointCompression, + C: PointCompression, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldBytesSize: ModulusSize, { @@ -167,7 +166,7 @@ where #[cfg(feature = "jwk")] pub fn from_jwk(jwk: &JwkEcKey) -> Result where - C: Curve + JwkParameters, + C: JwkParameters, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldBytesSize: ModulusSize, { @@ -178,7 +177,7 @@ where #[cfg(feature = "jwk")] pub fn from_jwk_str(jwk: &str) -> Result where - C: Curve + JwkParameters, + C: JwkParameters, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldBytesSize: ModulusSize, { @@ -189,7 +188,7 @@ where #[cfg(feature = "jwk")] pub fn to_jwk(&self) -> JwkEcKey where - C: Curve + JwkParameters, + C: JwkParameters, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldBytesSize: ModulusSize, { @@ -200,7 +199,7 @@ where #[cfg(feature = "jwk")] pub fn to_jwk_string(&self) -> String where - C: Curve + JwkParameters, + C: JwkParameters, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldBytesSize: ModulusSize, { From 0de66adfade3683b1a97bf2453c81b3d0dbf68c9 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Wed, 8 Mar 2023 23:14:48 +0000 Subject: [PATCH 1001/1461] Fix unsoundness with block size equal to zero (#1277) --- cipher/src/stream_wrapper.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cipher/src/stream_wrapper.rs b/cipher/src/stream_wrapper.rs index 1d0d3155c..e3495bc14 100644 --- a/cipher/src/stream_wrapper.rs +++ b/cipher/src/stream_wrapper.rs @@ -47,6 +47,9 @@ where #[inline] fn get_pos(&self) -> usize { let pos = self.pos as usize; + if T::BlockSize::USIZE == 0 { + panic!("Block size can not be equal to zero"); + } if pos >= T::BlockSize::USIZE { debug_assert!(false); // SAFETY: `pos` is set only to values smaller than block size From 0af93f6076a76757c65cb2ef6f6abd9756440478 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Thu, 9 Mar 2023 00:10:59 +0000 Subject: [PATCH 1002/1461] cipher: release v0.4.4 (#1278) --- Cargo.lock | 76 ++++++++++++++++++++++----------------------- cipher/CHANGELOG.md | 6 +++- cipher/Cargo.toml | 2 +- cipher/src/lib.rs | 3 +- 4 files changed, 45 insertions(+), 42 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5d3a9c92a..90331deef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -31,7 +31,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "433cfd6710c9986c576a25ca913c39d66a6474107b406f34f91d4a8923395241" dependencies = [ "cfg-if", - "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cipher 0.4.3", "cpufeatures", ] @@ -43,7 +43,7 @@ checksum = "82e1366e0c69c9f927b1fa5ce2c7bf9eafc8f9268c0b9800729e8b267612447c" dependencies = [ "aead 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "aes", - "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cipher 0.4.3", "ctr", "ghash", "subtle", @@ -65,9 +65,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.60" +version = "0.1.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d1d8ab452a3936018a687b20e6f7cf5363d713b732b8884001317b0e48aa3" +checksum = "b84f9ebcc6c1f5b8cb160f6990096a5c127f423fcb6e1ccc46c370cbdfb75dfc" dependencies = [ "proc-macro2", "quote", @@ -97,9 +97,9 @@ checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" [[package]] name = "base64ct" -version = "1.6.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +checksum = "e6b4d9b1225d28d360ec6a231d65af1fd99a2a095154c8040689617290569c5c" [[package]] name = "bincode" @@ -167,9 +167,9 @@ checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" [[package]] name = "cc" -version = "1.0.78" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" dependencies = [ "jobserver", ] @@ -187,7 +187,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c7fc89c7c5b9e7a02dfe45cd2367bae382f9ed31c61ca8debe5f827c420a2f08" dependencies = [ "cfg-if", - "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cipher 0.4.3", "cpufeatures", ] @@ -199,7 +199,7 @@ checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" dependencies = [ "aead 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "chacha20", - "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cipher 0.4.3", "poly1305", "zeroize", ] @@ -207,8 +207,9 @@ dependencies = [ [[package]] name = "cipher" version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1873270f8f7942c191139cb8a40fd228da6c3fd2fc376d7e92d47aa14aeb59e" dependencies = [ - "blobby", "crypto-common 0.1.6", "inout", "zeroize", @@ -216,10 +217,9 @@ dependencies = [ [[package]] name = "cipher" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1873270f8f7942c191139cb8a40fd228da6c3fd2fc376d7e92d47aa14aeb59e" +version = "0.4.4" dependencies = [ + "blobby", "crypto-common 0.1.6", "inout", "zeroize", @@ -257,7 +257,7 @@ name = "crypto" version = "0.5.0-pre" dependencies = [ "aead 0.5.1", - "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cipher 0.4.3", "crypto-common 0.1.6", "digest 0.10.6", "elliptic-curve 0.12.3", @@ -337,7 +337,7 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" dependencies = [ - "cipher 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cipher 0.4.3", ] [[package]] @@ -510,9 +510,9 @@ dependencies = [ [[package]] name = "glob" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "group" @@ -636,9 +636,9 @@ dependencies = [ [[package]] name = "jobserver" -version = "0.1.25" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "068b1ee6743e4d11fb9c6a1e6064b3693a1b600e7f5f5988047d98b3dc9fb90b" +checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" dependencies = [ "libc", ] @@ -660,9 +660,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.138" +version = "0.2.139" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" +checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" [[package]] name = "lock_api" @@ -711,9 +711,9 @@ dependencies = [ [[package]] name = "pem-rfc7468" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f22eb0e3c593294a99e9ff4b24cf6b752d43f193aa4415fe5077c159996d497" +checksum = "84e93a3b1cc0510b03020f33f21e62acdde3dcaef432edc95bea377fbd4c2cd4" dependencies = [ "base64ct", ] @@ -812,9 +812,9 @@ checksum = "97e91cb6af081c6daad5fa705f8adb0634c027662052cb3174bdf2957bf07e25" [[package]] name = "proc-macro2" -version = "1.0.49" +version = "1.0.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5" +checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6" dependencies = [ "unicode-ident", ] @@ -901,27 +901,27 @@ checksum = "58bc9567378fc7690d6b2addae4e60ac2eeea07becb2c64b9f218b53865cba2a" [[package]] name = "serde" -version = "1.0.151" +version = "1.0.154" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fed41fc1a24994d044e6db6935e69511a1153b52c15eb42493b26fa87feba0" +checksum = "8cdd151213925e7f1ab45a9bbfb129316bd00799784b174b7cc7bcd16961c49e" dependencies = [ "serde_derive", ] [[package]] name = "serde_bytes" -version = "0.11.8" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "718dc5fff5b36f99093fc49b280cfc96ce6fc824317783bff5a1fed0c7a64819" +checksum = "416bda436f9aab92e02c8e10d49a15ddd339cea90b6e340fe51ed97abb548294" dependencies = [ "serde", ] [[package]] name = "serde_derive" -version = "1.0.151" +version = "1.0.154" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "255abe9a125a985c05190d687b320c12f9b1f0b99445e608c21ba0782c719ad8" +checksum = "4fc80d722935453bcafdc2c9a73cd6fac4dc1938f0346035d84bf99fa9e33217" dependencies = [ "proc-macro2", "quote", @@ -984,9 +984,9 @@ dependencies = [ [[package]] name = "spin" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f6002a767bff9e83f8eeecf883ecb8011875a21ae8da43bffb817a57e78cc09" +checksum = "7dccf47db1b41fa1573ed27ccf5e08e3ca771cb994f776668c5ebda893b248fc" dependencies = [ "lock_api", ] @@ -1024,9 +1024,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.107" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", "quote", @@ -1053,9 +1053,9 @@ checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "unicode-ident" -version = "1.0.6" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" [[package]] name = "unicode-xid" diff --git a/cipher/CHANGELOG.md b/cipher/CHANGELOG.md index d48764969..4a388fb37 100644 --- a/cipher/CHANGELOG.md +++ b/cipher/CHANGELOG.md @@ -5,11 +5,15 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 0.4.4 [UNRELEASED] +## 0.4.4 (2022-03-09) ### Changed - Move `ParBlocks`/`ParBlocksSizeUser` to the `crypto-common` crate ([#1052]) +### Fixed +- Unsoundness triggered by zero block size ([#1277]) + [#1052]: https://github.com/RustCrypto/traits/pull/1052 +[#1277]: https://github.com/RustCrypto/traits/pull/1277 ## 0.4.3 (2022-02-22) ### Fixed diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index 2242e1a27..7edac76c5 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "cipher" description = "Traits for describing block ciphers and stream ciphers" -version = "0.4.3" # Also update html_root_url in lib.rs when bumping this +version = "0.4.4" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/cipher/src/lib.rs b/cipher/src/lib.rs index 59b0d75d2..87041c19a 100644 --- a/cipher/src/lib.rs +++ b/cipher/src/lib.rs @@ -9,8 +9,7 @@ #![cfg_attr(docsrs, feature(doc_cfg))] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", - html_root_url = "https://docs.rs/cipher/0.4.3" + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg" )] #![warn(missing_docs, rust_2018_idioms)] From 03124bd9c4fecf2b29eeb2b6924bcfe159844f7b Mon Sep 17 00:00:00 2001 From: daxpedda Date: Fri, 17 Mar 2023 19:52:40 +0100 Subject: [PATCH 1003/1461] Update OSSWU code (#1157) --- elliptic-curve/src/hash2curve/osswu.rs | 125 +++++++++++++++++-------- 1 file changed, 84 insertions(+), 41 deletions(-) diff --git a/elliptic-curve/src/hash2curve/osswu.rs b/elliptic-curve/src/hash2curve/osswu.rs index 60796ebe5..3c3669ac3 100644 --- a/elliptic-curve/src/hash2curve/osswu.rs +++ b/elliptic-curve/src/hash2curve/osswu.rs @@ -1,9 +1,11 @@ //! Optimized simplified Shallue-van de Woestijne-Ulas methods. //! -//! +//! use ff::Field; use subtle::Choice; +use subtle::ConditionallySelectable; +use subtle::ConstantTimeEq; /// The Optimized Simplified Shallue-van de Woestijne-Ulas parameters pub struct OsswuMapParams @@ -38,50 +40,91 @@ pub trait OsswuMap: Field + Sgn0 { /// should be for isogeny where A≠0 and B≠0. const PARAMS: OsswuMapParams; + /// Optimized sqrt_ratio for q = 3 mod 4. + fn sqrt_ratio_3mod4(u: Self, v: Self) -> (Choice, Self) { + // 1. tv1 = v^2 + let tv1 = v.square(); + // 2. tv2 = u * v + let tv2 = u * v; + // 3. tv1 = tv1 * tv2 + let tv1 = tv1 * tv2; + // 4. y1 = tv1^c1 + let y1 = tv1.pow_vartime(Self::PARAMS.c1); + // 5. y1 = y1 * tv2 + let y1 = y1 * tv2; + // 6. y2 = y1 * c2 + let y2 = y1 * Self::PARAMS.c2; + // 7. tv3 = y1^2 + let tv3 = y1.square(); + // 8. tv3 = tv3 * v + let tv3 = tv3 * v; + // 9. isQR = tv3 == u + let is_qr = tv3.ct_eq(&u); + // 10. y = CMOV(y2, y1, isQR) + let y = ConditionallySelectable::conditional_select(&y2, &y1, is_qr); + // 11. return (isQR, y) + (is_qr, y) + } + /// Convert this field element into an affine point on the elliptic curve /// returning (X, Y). For Weierstrass curves having A==0 or B==0 /// the result is a point on an isogeny. fn osswu(&self) -> (Self, Self) { - let tv1 = self.square(); // u^2 - let tv3 = Self::PARAMS.z * tv1; // Z * u^2 - let mut tv2 = tv3.square(); // tv3^2 - let mut xd = tv2 + tv3; // tv3^2 + tv3 - let x1n = Self::PARAMS.map_b * (xd + Self::ONE); // B * (xd + 1) - xd *= -Self::PARAMS.map_a; // -A * xd - - let tv = Self::PARAMS.z * Self::PARAMS.map_a; - xd.conditional_assign(&tv, xd.is_zero()); - - tv2 = xd.square(); //xd^2 - let gxd = tv2 * xd; // xd^3 - tv2 *= Self::PARAMS.map_a; // A * tv2 - - let mut gx1 = x1n * (tv2 + x1n.square()); //x1n *(tv2 + x1n^2) - tv2 = gxd * Self::PARAMS.map_b; // B * gxd - gx1 += tv2; // gx1 + tv2 - - let mut tv4 = gxd.square(); // gxd^2 - tv2 = gx1 * gxd; // gx1 * gxd - tv4 *= tv2; - - let y1 = tv4.pow_vartime(Self::PARAMS.c1) * tv2; // tv4^C1 * tv2 - let x2n = tv3 * x1n; // tv3 * x1n - - let y2 = y1 * Self::PARAMS.c2 * tv1 * self; // y1 * c2 * tv1 * u - - tv2 = y1.square() * gxd; //y1^2 * gxd - - let e2 = tv2.ct_eq(&gx1); - - // if e2 , x = x1, else x = x2 - let mut x = Self::conditional_select(&x2n, &x1n, e2); - // xn / xd - x *= xd.invert().unwrap(); - - // if e2, y = y1, else y = y2 - let mut y = Self::conditional_select(&y2, &y1, e2); - - y.conditional_assign(&-y, self.sgn0() ^ y.sgn0()); + // 1. tv1 = u^2 + let tv1 = self.square(); + // 2. tv1 = Z * tv1 + let tv1 = Self::PARAMS.z * tv1; + // 3. tv2 = tv1^2 + let tv2 = tv1.square(); + // 4. tv2 = tv2 + tv1 + let tv2 = tv2 + tv1; + // 5. tv3 = tv2 + 1 + let tv3 = tv2 + Self::ONE; + // 6. tv3 = B * tv3 + let tv3 = Self::PARAMS.map_b * tv3; + // 7. tv4 = CMOV(Z, -tv2, tv2 != 0) + let tv4 = ConditionallySelectable::conditional_select( + &Self::PARAMS.z, + &-tv2, + !Field::is_zero(&tv2), + ); + // 8. tv4 = A * tv4 + let tv4 = Self::PARAMS.map_a * tv4; + // 9. tv2 = tv3^2 + let tv2 = tv3.square(); + // 10. tv6 = tv4^2 + let tv6 = tv4.square(); + // 11. tv5 = A * tv6 + let tv5 = Self::PARAMS.map_a * tv6; + // 12. tv2 = tv2 + tv5 + let tv2 = tv2 + tv5; + // 13. tv2 = tv2 * tv3 + let tv2 = tv2 * tv3; + // 14. tv6 = tv6 * tv4 + let tv6 = tv6 * tv4; + // 15. tv5 = B * tv6 + let tv5 = Self::PARAMS.map_b * tv6; + // 16. tv2 = tv2 + tv5 + let tv2 = tv2 + tv5; + // 17. x = tv1 * tv3 + let x = tv1 * tv3; + // 18. (is_gx1_square, y1) = sqrt_ratio(tv2, tv6) + let (is_gx1_square, y1) = Self::sqrt_ratio_3mod4(tv2, tv6); + // 19. y = tv1 * u + let y = tv1 * self; + // 20. y = y * y1 + let y = y * y1; + // 21. x = CMOV(x, tv3, is_gx1_square) + let x = ConditionallySelectable::conditional_select(&x, &tv3, is_gx1_square); + // 22. y = CMOV(y, y1, is_gx1_square) + let y = ConditionallySelectable::conditional_select(&y, &y1, is_gx1_square); + // 23. e1 = sgn0(u) == sgn0(y) + let e1 = self.sgn0().ct_eq(&y.sgn0()); + // 24. y = CMOV(-y, y, e1) + let y = ConditionallySelectable::conditional_select(&-y, &y, e1); + // 25. x = x / tv4 + let x = x * tv4.invert().unwrap(); + // 26. return (x, y) (x, y) } } From cddce88365751becf8dcdde41f66c06f470f09df Mon Sep 17 00:00:00 2001 From: Dirk Stolle Date: Tue, 21 Mar 2023 03:32:41 +0100 Subject: [PATCH 1004/1461] Replace unmaintained actions-rs/* actions in CI workflows (#1279) Basically all of the `actions-rs/*` actions are unmaintained. See for more information. Due to their age they generate several warnings in CI runs. To get rid of some of those warnings the occurrences of `actions-rs/toolchain` are replaced by `dtolnay/rust-toolchain`, and the occurrences of `actions-rs/cargo` are replaced by direct invocations of `cargo`. --- .github/workflows/aead.yml | 10 +++------- .github/workflows/async-signature.yml | 8 ++------ .github/workflows/cipher.yml | 13 ++++--------- .github/workflows/crypto-common.yml | 10 +++------- .github/workflows/crypto.yml | 18 +++++------------- .github/workflows/digest.yml | 10 +++------- .github/workflows/elliptic-curve.yml | 18 +++++------------- .github/workflows/kem.yml | 14 ++++---------- .github/workflows/password-hash.yml | 14 ++++---------- .github/workflows/signature.yml | 18 +++++------------- .github/workflows/universal-hash.yml | 10 +++------- .github/workflows/workspace.yml | 13 +++---------- 12 files changed, 44 insertions(+), 112 deletions(-) diff --git a/.github/workflows/aead.yml b/.github/workflows/aead.yml index 308d562b3..e697614bc 100644 --- a/.github/workflows/aead.yml +++ b/.github/workflows/aead.yml @@ -30,12 +30,10 @@ jobs: steps: - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - - uses: actions-rs/toolchain@v1 + - uses: dtolnay/rust-toolchain@master with: - profile: minimal toolchain: ${{ matrix.rust }} - target: ${{ matrix.target }} - override: true + targets: ${{ matrix.target }} - run: cargo check --all-features - run: cargo build --target ${{ matrix.target }} --release --no-default-features - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc @@ -59,11 +57,9 @@ jobs: steps: - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - - uses: actions-rs/toolchain@v1 + - uses: dtolnay/rust-toolchain@master with: toolchain: ${{ matrix.rust }} - override: true - profile: minimal - run: cargo test --release --no-default-features - run: cargo test --release - run: cargo test --release --all-features diff --git a/.github/workflows/async-signature.yml b/.github/workflows/async-signature.yml index 75bcf327a..d75c4e679 100644 --- a/.github/workflows/async-signature.yml +++ b/.github/workflows/async-signature.yml @@ -27,11 +27,9 @@ jobs: steps: - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - - uses: actions-rs/toolchain@v1 + - uses: dtolnay/rust-toolchain@master with: toolchain: ${{ matrix.rust }} - override: true - profile: minimal - run: cargo check --all-features - run: cargo test --release - run: cargo test --all-features --release @@ -41,11 +39,9 @@ jobs: steps: - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - - uses: actions-rs/toolchain@v1 + - uses: dtolnay/rust-toolchain@master with: toolchain: nightly - override: true - profile: minimal - uses: RustCrypto/actions/cargo-hack-install@master - run: rm ../../Cargo.toml - run: cargo update -Z minimal-versions diff --git a/.github/workflows/cipher.yml b/.github/workflows/cipher.yml index 575bba883..28ae4e6ec 100644 --- a/.github/workflows/cipher.yml +++ b/.github/workflows/cipher.yml @@ -30,12 +30,10 @@ jobs: steps: - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - - uses: actions-rs/toolchain@v1 + - uses: dtolnay/rust-toolchain@master with: toolchain: ${{ matrix.rust }} - target: ${{ matrix.target }} - override: true - profile: minimal + targets: ${{ matrix.target }} - run: cargo build --target ${{ matrix.target }} - run: cargo build --target ${{ matrix.target }} --features rand_core - run: cargo build --target ${{ matrix.target }} --features block-padding @@ -47,11 +45,9 @@ jobs: steps: - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - - uses: actions-rs/toolchain@v1 + - uses: dtolnay/rust-toolchain@master with: toolchain: nightly - override: true - profile: minimal - uses: RustCrypto/actions/cargo-hack-install@master - run: cargo update -Z minimal-versions - run: cargo hack test --release --feature-powerset @@ -66,9 +62,8 @@ jobs: steps: - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - - uses: actions-rs/toolchain@v1 + - uses: dtolnay/rust-toolchain@master with: - profile: minimal toolchain: ${{ matrix.rust }} - run: cargo check --all-features - run: cargo test diff --git a/.github/workflows/crypto-common.yml b/.github/workflows/crypto-common.yml index b5fd9464d..e761daa9b 100644 --- a/.github/workflows/crypto-common.yml +++ b/.github/workflows/crypto-common.yml @@ -30,12 +30,10 @@ jobs: steps: - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - - uses: actions-rs/toolchain@v1 + - uses: dtolnay/rust-toolchain@master with: toolchain: ${{ matrix.rust }} - target: ${{ matrix.target }} - override: true - profile: minimal + targets: ${{ matrix.target }} - run: cargo build --target ${{ matrix.target }} minimal-versions: @@ -53,11 +51,9 @@ jobs: steps: - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - - uses: actions-rs/toolchain@v1 + - uses: dtolnay/rust-toolchain@master with: toolchain: ${{ matrix.rust }} - override: true - profile: minimal - run: cargo check --all-features - run: cargo test - run: cargo test --features std diff --git a/.github/workflows/crypto.yml b/.github/workflows/crypto.yml index 5b9060050..b10972631 100644 --- a/.github/workflows/crypto.yml +++ b/.github/workflows/crypto.yml @@ -30,12 +30,10 @@ jobs: steps: - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - - uses: actions-rs/toolchain@v1 + - uses: dtolnay/rust-toolchain@master with: toolchain: ${{ matrix.rust }} - target: ${{ matrix.target }} - override: true - profile: minimal + targets: ${{ matrix.target }} - run: cargo build --no-default-features --release --target ${{ matrix.target }} - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features aead,cipher,digest,elliptic-curve,signature,universal-hash @@ -45,11 +43,9 @@ jobs: steps: - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - - uses: actions-rs/toolchain@v1 + - uses: dtolnay/rust-toolchain@master with: toolchain: nightly - override: true - profile: minimal - uses: RustCrypto/actions/cargo-hack-install@master - run: cargo update -Z minimal-versions - run: cargo hack test --release --feature-powerset @@ -64,11 +60,9 @@ jobs: steps: - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - - uses: actions-rs/toolchain@v1 + - uses: dtolnay/rust-toolchain@master with: toolchain: ${{ matrix.rust }} - override: true - profile: minimal - run: cargo check --all-features - run: cargo test --no-default-features --release - run: cargo test --release @@ -79,10 +73,8 @@ jobs: steps: - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - - uses: actions-rs/toolchain@v1 + - uses: dtolnay/rust-toolchain@master with: toolchain: 1.60.0 components: clippy - override: true - profile: minimal - run: cargo clippy --all --all-features -- -D warnings diff --git a/.github/workflows/digest.yml b/.github/workflows/digest.yml index 625127772..2a91753d9 100644 --- a/.github/workflows/digest.yml +++ b/.github/workflows/digest.yml @@ -30,12 +30,10 @@ jobs: steps: - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - - uses: actions-rs/toolchain@v1 + - uses: dtolnay/rust-toolchain@master with: toolchain: ${{ matrix.rust }} - target: ${{ matrix.target }} - override: true - profile: minimal + targets: ${{ matrix.target }} # Isolate this crate from workspace which is otherwise MSRV 1.56 due to 2021 edition crates - run: rm ../Cargo.toml - run: cargo build --target ${{ matrix.target }} @@ -55,11 +53,9 @@ jobs: steps: - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - - uses: actions-rs/toolchain@v1 + - uses: dtolnay/rust-toolchain@master with: toolchain: ${{ matrix.rust }} - override: true - profile: minimal - run: cargo check --all-features - run: cargo test --no-default-features - run: cargo test diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index c12e4a503..fc60207f5 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -32,12 +32,10 @@ jobs: steps: - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - - uses: actions-rs/toolchain@v1 + - uses: dtolnay/rust-toolchain@master with: - profile: minimal toolchain: ${{ matrix.rust }} - target: ${{ matrix.target }} - override: true + targets: ${{ matrix.target }} - run: cargo build --target ${{ matrix.target }} --release --no-default-features - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features arithmetic @@ -65,11 +63,9 @@ jobs: # steps: # - uses: actions/checkout@v3 # - uses: RustCrypto/actions/cargo-cache@master - # - uses: actions-rs/toolchain@v1 + # - uses: dtolnay/rust-toolchain@master # with: # toolchain: nightly - # override: true - # profile: minimal # - uses: RustCrypto/actions/cargo-hack-install@master # - run: cargo update -Z minimal-versions # - run: cargo hack test --release --feature-powerset @@ -85,11 +81,9 @@ jobs: steps: - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - - uses: actions-rs/toolchain@v1 + - uses: dtolnay/rust-toolchain@master with: toolchain: ${{ matrix.rust }} - override: true - profile: minimal - run: cargo check --all-features - run: cargo test --no-default-features - run: cargo test @@ -99,9 +93,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - uses: actions-rs/toolchain@v1 + - uses: dtolnay/rust-toolchain@master with: toolchain: stable - override: true - profile: minimal - run: cargo doc --all-features diff --git a/.github/workflows/kem.yml b/.github/workflows/kem.yml index 20cd62198..a2204bc23 100644 --- a/.github/workflows/kem.yml +++ b/.github/workflows/kem.yml @@ -30,12 +30,10 @@ jobs: steps: - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - - uses: actions-rs/toolchain@v1 + - uses: dtolnay/rust-toolchain@master with: toolchain: ${{ matrix.rust }} - target: ${{ matrix.target }} - override: true - profile: minimal + targets: ${{ matrix.target }} - run: cargo build --no-default-features --release --target ${{ matrix.target }} # TODO: use the reusable workflow after this crate will be part of the @@ -45,11 +43,9 @@ jobs: # steps: # - uses: actions/checkout@v3 # - uses: RustCrypto/actions/cargo-cache@master - # - uses: actions-rs/toolchain@v1 + # - uses: dtolnay/rust-toolchain@master # with: # toolchain: nightly - # override: true - # profile: minimal # - uses: RustCrypto/actions/cargo-hack-install@master # - run: cargo update -Z minimal-versions # - run: cargo hack test --release --feature-powerset @@ -64,11 +60,9 @@ jobs: steps: - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - - uses: actions-rs/toolchain@v1 + - uses: dtolnay/rust-toolchain@master with: toolchain: ${{ matrix.rust }} - override: true - profile: minimal - run: cargo check --all-features - run: cargo test --no-default-features --release - run: cargo test --release diff --git a/.github/workflows/password-hash.yml b/.github/workflows/password-hash.yml index 51ccb2a87..c49d00322 100644 --- a/.github/workflows/password-hash.yml +++ b/.github/workflows/password-hash.yml @@ -30,12 +30,10 @@ jobs: steps: - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - - uses: actions-rs/toolchain@v1 + - uses: dtolnay/rust-toolchain@master with: toolchain: ${{ matrix.rust }} - target: ${{ matrix.target }} - override: true - profile: minimal + targets: ${{ matrix.target }} - run: cargo build --target ${{ matrix.target }} --release --no-default-features - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features rand_core @@ -47,11 +45,9 @@ jobs: steps: - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - - uses: actions-rs/toolchain@v1 + - uses: dtolnay/rust-toolchain@master with: toolchain: nightly - override: true - profile: minimal - uses: RustCrypto/actions/cargo-hack-install@master - run: cargo update -Z minimal-versions - run: cargo hack test --release --feature-powerset @@ -66,11 +62,9 @@ jobs: steps: - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - - uses: actions-rs/toolchain@v1 + - uses: dtolnay/rust-toolchain@master with: toolchain: ${{ matrix.rust }} - override: true - profile: minimal - run: cargo check --all-features - run: cargo test --release --no-default-features - run: cargo test --release diff --git a/.github/workflows/signature.yml b/.github/workflows/signature.yml index bd5934b2c..c8801008a 100644 --- a/.github/workflows/signature.yml +++ b/.github/workflows/signature.yml @@ -31,12 +31,10 @@ jobs: steps: - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - - uses: actions-rs/toolchain@v1 + - uses: dtolnay/rust-toolchain@master with: toolchain: ${{ matrix.rust }} - target: ${{ matrix.target }} - override: true - profile: minimal + targets: ${{ matrix.target }} - run: cargo build --target ${{ matrix.target }} --release --no-default-features - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features derive - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features digest @@ -58,11 +56,9 @@ jobs: steps: - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - - uses: actions-rs/toolchain@v1 + - uses: dtolnay/rust-toolchain@master with: toolchain: ${{ matrix.rust }} - override: true - profile: minimal - run: cargo check --all-features - run: cargo test --no-default-features --release - run: cargo test --release @@ -78,11 +74,9 @@ jobs: steps: - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - - uses: actions-rs/toolchain@v1 + - uses: dtolnay/rust-toolchain@master with: toolchain: ${{ matrix.rust }} - override: true - profile: minimal - run: cargo test --release working-directory: signature/derive @@ -90,9 +84,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - uses: actions-rs/toolchain@v1 + - uses: dtolnay/rust-toolchain@master with: toolchain: stable - override: true - profile: minimal - run: cargo doc --all-features diff --git a/.github/workflows/universal-hash.yml b/.github/workflows/universal-hash.yml index cb82170c2..7bb64fcce 100644 --- a/.github/workflows/universal-hash.yml +++ b/.github/workflows/universal-hash.yml @@ -30,12 +30,10 @@ jobs: steps: - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - - uses: actions-rs/toolchain@v1 + - uses: dtolnay/rust-toolchain@master with: toolchain: ${{ matrix.rust }} - target: ${{ matrix.target }} - override: true - profile: minimal + targets: ${{ matrix.target }} # Isolate this crate from workspace which is otherwise MSRV 1.56 due to 2021 edition crates - run: rm ../Cargo.toml - run: cargo build --no-default-features --release --target ${{ matrix.target }} @@ -55,11 +53,9 @@ jobs: steps: - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - - uses: actions-rs/toolchain@v1 + - uses: dtolnay/rust-toolchain@master with: toolchain: ${{ matrix.rust }} - override: true - profile: minimal # Isolate this crate from workspace which is otherwise MSRV 1.56 due to 2021 edition crates - run: rm ../Cargo.toml - run: cargo check --all-features diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index 3793f3a23..bba6e00b7 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -24,25 +24,18 @@ jobs: steps: - uses: actions/checkout@v3 - uses: RustCrypto/actions/cargo-cache@master - - uses: actions-rs/toolchain@v1 + - uses: dtolnay/rust-toolchain@master with: toolchain: 1.60.0 components: clippy - override: true - profile: minimal - run: cargo clippy --all --all-features -- -D warnings rustfmt: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - uses: actions-rs/toolchain@v1 + - uses: dtolnay/rust-toolchain@master with: toolchain: stable components: rustfmt - profile: minimal - override: true - - uses: actions-rs/cargo@v1 - with: - command: fmt - args: --all -- --check + - run: cargo fmt --all -- --check From 3d4a2ba3b6f3c4565d1cb41b2b91afe8bfc36a80 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Mar 2023 17:16:58 -0600 Subject: [PATCH 1005/1461] build(deps): bump zeroize from 1.5.7 to 1.6.0 (#1280) Bumps [zeroize](https://github.com/RustCrypto/utils) from 1.5.7 to 1.6.0. - [Release notes](https://github.com/RustCrypto/utils/releases) - [Commits](https://github.com/RustCrypto/utils/compare/zeroize-v1.5.7...zeroize-v1.6.0) --- updated-dependencies: - dependency-name: zeroize dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- cipher/Cargo.toml | 2 +- kem/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 90331deef..e893b66c2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1124,9 +1124,9 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.5.7" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" dependencies = [ "zeroize_derive", ] diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index 7edac76c5..c36b31cc5 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -18,7 +18,7 @@ inout = "0.1" # optional dependencies blobby = { version = "0.3", optional = true } -zeroize = { version = "1.5", optional = true, default-features = false } +zeroize = { version = "1.6", optional = true, default-features = false } [features] alloc = [] diff --git a/kem/Cargo.toml b/kem/Cargo.toml index 12587fd0f..78a074619 100644 --- a/kem/Cargo.toml +++ b/kem/Cargo.toml @@ -15,7 +15,7 @@ rust-version = "1.60" [dependencies] rand_core = "0.6" generic-array = "0.14" -zeroize = { version = "1.5", default-features = false } +zeroize = { version = "1.6", default-features = false } [dev-dependencies] hpke = "0.10" From 1ed0617ffc34272be7da22c9f68d5c259edf16ba Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 1 Apr 2023 19:03:38 -0600 Subject: [PATCH 1006/1461] signature: add `SignatureEncoding::encoded_len` (#1283) Adds a new provided method to the `SignatureEncoding` trait for computing the length of the signature when it's serialized. --- signature/src/encoding.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/signature/src/encoding.rs b/signature/src/encoding.rs index d8371e433..8bc475b01 100644 --- a/signature/src/encoding.rs +++ b/signature/src/encoding.rs @@ -23,4 +23,9 @@ pub trait SignatureEncoding: fn to_vec(&self) -> Vec { self.to_bytes().as_ref().to_vec() } + + /// Get the length of this signature when encoded. + fn encoded_len(&self) -> usize { + self.to_bytes().as_ref().len() + } } From 1ffc7d9125b41255629b3dcfb436e457cfe660f8 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 1 Apr 2023 20:00:05 -0600 Subject: [PATCH 1007/1461] signature v2.1.0 (#1284) --- Cargo.lock | 6 +++--- signature/CHANGELOG.md | 6 ++++++ signature/Cargo.toml | 6 +++--- signature/async/Cargo.toml | 2 +- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e893b66c2..7104661da 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -60,7 +60,7 @@ name = "async-signature" version = "0.3.0" dependencies = [ "async-trait", - "signature 2.0.0", + "signature 2.1.0", ] [[package]] @@ -262,7 +262,7 @@ dependencies = [ "digest 0.10.6", "elliptic-curve 0.12.3", "password-hash", - "signature 2.0.0", + "signature 2.1.0", "universal-hash 0.5.0", ] @@ -964,7 +964,7 @@ dependencies = [ [[package]] name = "signature" -version = "2.0.0" +version = "2.1.0" dependencies = [ "digest 0.10.6", "hex-literal", diff --git a/signature/CHANGELOG.md b/signature/CHANGELOG.md index 65a1c8c1f..4f999de55 100644 --- a/signature/CHANGELOG.md +++ b/signature/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 2.1.0 (2023-04-01) +### Added +- `SignatureEncoding::encoded_len` ([#1283]) + +[#1283]: https://github.com/RustCrypto/traits/pull/1283 + ## 2.0.0 (2023-01-15) ### Added - `SignatureEncoding` trait as a replacement for `Signature` trait and the diff --git a/signature/Cargo.toml b/signature/Cargo.toml index eab41d760..e8fec5988 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,16 +1,16 @@ [package] name = "signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "2.0.0" +version = "2.1.0" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/signature" repository = "https://github.com/RustCrypto/traits/tree/master/signature" readme = "README.md" -edition = "2021" -rust-version = "1.56" keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"] categories = ["cryptography", "no-std"] +edition = "2021" +rust-version = "1.56" [dependencies] derive = { package = "signature_derive", version = "2", optional = true, path = "derive" } diff --git a/signature/async/Cargo.toml b/signature/async/Cargo.toml index 178e57e0b..2fa5df953 100644 --- a/signature/async/Cargo.toml +++ b/signature/async/Cargo.toml @@ -14,7 +14,7 @@ rust-version = "1.56" [dependencies] async-trait = "0.1.9" -signature = { version = "2.0, <2.1", path = ".." } +signature = { version = "2.0, <2.2", path = ".." } [features] digest = ["signature/digest"] From 425c68cb1ee2f8182cb0b55779b4b4a5fbcd7325 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Sun, 2 Apr 2023 05:17:24 +0300 Subject: [PATCH 1008/1461] Update Cargo.lock --- Cargo.lock | 102 ++++++++++++++++++++++++----------------------------- 1 file changed, 47 insertions(+), 55 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7104661da..9b39df721 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -31,7 +31,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "433cfd6710c9986c576a25ca913c39d66a6474107b406f34f91d4a8923395241" dependencies = [ "cfg-if", - "cipher 0.4.3", + "cipher 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "cpufeatures", ] @@ -43,7 +43,7 @@ checksum = "82e1366e0c69c9f927b1fa5ce2c7bf9eafc8f9268c0b9800729e8b267612447c" dependencies = [ "aead 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "aes", - "cipher 0.4.3", + "cipher 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "ctr", "ghash", "subtle", @@ -65,13 +65,13 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.66" +version = "0.1.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b84f9ebcc6c1f5b8cb160f6990096a5c127f423fcb6e1ccc46c370cbdfb75dfc" +checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.13", ] [[package]] @@ -127,9 +127,9 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ "generic-array", ] @@ -146,9 +146,9 @@ dependencies = [ [[package]] name = "block-padding" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a90ec2df9600c28a01c56c4784c9207a96d2451833aeceb8cc97e4c9548bb78" +checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" dependencies = [ "generic-array", ] @@ -182,12 +182,12 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chacha20" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7fc89c7c5b9e7a02dfe45cd2367bae382f9ed31c61ca8debe5f827c420a2f08" +checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" dependencies = [ "cfg-if", - "cipher 0.4.3", + "cipher 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "cpufeatures", ] @@ -199,17 +199,16 @@ checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" dependencies = [ "aead 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "chacha20", - "cipher 0.4.3", + "cipher 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "poly1305", "zeroize", ] [[package]] name = "cipher" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1873270f8f7942c191139cb8a40fd228da6c3fd2fc376d7e92d47aa14aeb59e" +version = "0.4.4" dependencies = [ + "blobby", "crypto-common 0.1.6", "inout", "zeroize", @@ -218,8 +217,9 @@ dependencies = [ [[package]] name = "cipher" version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ - "blobby", "crypto-common 0.1.6", "inout", "zeroize", @@ -239,9 +239,9 @@ checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" [[package]] name = "cpufeatures" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +checksum = "280a9f2d8b3a38871a3c8a46fb80db65e5e5ed97da80c4d08bf27fb63e35e181" dependencies = [ "libc", ] @@ -257,7 +257,7 @@ name = "crypto" version = "0.5.0-pre" dependencies = [ "aead 0.5.1", - "cipher 0.4.3", + "cipher 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "crypto-common 0.1.6", "digest 0.10.6", "elliptic-curve 0.12.3", @@ -337,7 +337,7 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" dependencies = [ - "cipher 0.4.3", + "cipher 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -387,7 +387,7 @@ version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" dependencies = [ - "block-buffer 0.10.3", + "block-buffer 0.10.4", "crypto-common 0.1.6", "subtle", ] @@ -479,9 +479,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.6" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", @@ -660,9 +660,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.139" +version = "0.2.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" +checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" [[package]] name = "lock_api" @@ -812,18 +812,18 @@ checksum = "97e91cb6af081c6daad5fa705f8adb0634c027662052cb3174bdf2957bf07e25" [[package]] name = "proc-macro2" -version = "1.0.51" +version = "1.0.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6" +checksum = "1d0dd4be24fcdcfeaa12a432d588dc59bbad6cad3510c67e74a2b6b2fc950564" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.23" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" +checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" dependencies = [ "proc-macro2", ] @@ -895,15 +895,15 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.16" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58bc9567378fc7690d6b2addae4e60ac2eeea07becb2c64b9f218b53865cba2a" +checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" -version = "1.0.154" +version = "1.0.159" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cdd151213925e7f1ab45a9bbfb129316bd00799784b174b7cc7bcd16961c49e" +checksum = "3c04e8343c3daeec41f58990b9d77068df31209f2af111e059e9fe9646693065" dependencies = [ "serde_derive", ] @@ -919,13 +919,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.154" +version = "1.0.159" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fc80d722935453bcafdc2c9a73cd6fac4dc1938f0346035d84bf99fa9e33217" +checksum = "4c614d17805b093df4b147b51339e7e44bf05ef59fba1e45d83500bcfb4d8585" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.13", ] [[package]] @@ -979,14 +979,14 @@ version = "2.0.0" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "spin" -version = "0.9.5" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dccf47db1b41fa1573ed27ccf5e08e3ca771cb994f776668c5ebda893b248fc" +checksum = "c0959fd6f767df20b231736396e4f602171e00d95205676286e79d4a4eb67bef" dependencies = [ "lock_api", ] @@ -1034,15 +1034,14 @@ dependencies = [ ] [[package]] -name = "synstructure" -version = "0.12.6" +name = "syn" +version = "2.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +checksum = "4c9da457c5285ac1f936ebd076af6dac17a61cfe7826f2076b4d015cf47bc8ec" dependencies = [ "proc-macro2", "quote", - "syn", - "unicode-xid", + "unicode-ident", ] [[package]] @@ -1057,12 +1056,6 @@ version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" -[[package]] -name = "unicode-xid" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" - [[package]] name = "universal-hash" version = "0.5.0" @@ -1133,12 +1126,11 @@ dependencies = [ [[package]] name = "zeroize_derive" -version = "1.3.3" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44bf07cb3e50ea2003396695d58bf46bc9887a1f362260446fad6bc4e79bd36c" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn", - "synstructure", + "syn 2.0.13", ] From 35d94f05ad9a03aa15c5324b640bcbe7fea52ff2 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 2 Apr 2023 09:43:13 -0600 Subject: [PATCH 1009/1461] aead v0.5.2 (#1285) --- Cargo.lock | 22 +++++++++++----------- aead/CHANGELOG.md | 6 ++++++ aead/Cargo.toml | 2 +- aead/src/lib.rs | 4 ++-- 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9b39df721..eac5a2e32 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5,23 +5,23 @@ version = 3 [[package]] name = "aead" version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c192eb8f11fc081b0fe4259ba5af04217d4e0faddd02417310a927911abd7c8" dependencies = [ - "arrayvec", - "blobby", - "bytes", "crypto-common 0.1.6", "generic-array", - "heapless", ] [[package]] name = "aead" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c192eb8f11fc081b0fe4259ba5af04217d4e0faddd02417310a927911abd7c8" +version = "0.5.2" dependencies = [ + "arrayvec", + "blobby", + "bytes", "crypto-common 0.1.6", "generic-array", + "heapless", ] [[package]] @@ -41,7 +41,7 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "82e1366e0c69c9f927b1fa5ce2c7bf9eafc8f9268c0b9800729e8b267612447c" dependencies = [ - "aead 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "aead 0.5.1", "aes", "cipher 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "ctr", @@ -197,7 +197,7 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" dependencies = [ - "aead 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "aead 0.5.1", "chacha20", "cipher 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "poly1305", @@ -256,7 +256,7 @@ checksum = "6548a0ad5d2549e111e1f6a11a6c2e2d00ce6a3dafe22948d67c2b443f775e52" name = "crypto" version = "0.5.0-pre" dependencies = [ - "aead 0.5.1", + "aead 0.5.2", "cipher 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "crypto-common 0.1.6", "digest 0.10.6", @@ -608,7 +608,7 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf39e5461bfdc6ad0fbc97067519fcaf96a7a2e67f24cc0eb8a1e7c0c45af792" dependencies = [ - "aead 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "aead 0.5.1", "aes-gcm", "byteorder", "chacha20poly1305", diff --git a/aead/CHANGELOG.md b/aead/CHANGELOG.md index e4834b239..d5413f8e2 100644 --- a/aead/CHANGELOG.md +++ b/aead/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.5.2 (2023-04-02) +### Added +- `arrayvec` feature ([#1219]) + +[#1219]: https://github.com/RustCrypto/traits/pull/1219 + ## 0.5.1 (2022-08-09) ### Added - `AeadCore::generate_nonce` ([#1073]) diff --git a/aead/Cargo.toml b/aead/Cargo.toml index 893282217..29eb0bf26 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aead" -version = "0.5.1" # Also update html_root_url in lib.rs when bumping this +version = "0.5.2" description = """ Traits for Authenticated Encryption with Associated Data (AEAD) algorithms, such as AES-GCM as ChaCha20Poly1305, which provide a high-level API diff --git a/aead/src/lib.rs b/aead/src/lib.rs index ab3ca38ae..c5856a072 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -15,12 +15,12 @@ #![no_std] #![cfg_attr(docsrs, feature(doc_cfg))] -#![forbid(unsafe_code, clippy::unwrap_used)] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg" )] -#![warn(missing_docs, rust_2018_idioms)] +#![forbid(unsafe_code)] +#![warn(clippy::unwrap_used, missing_docs, rust_2018_idioms)] #[cfg(feature = "alloc")] extern crate alloc; From 3562e79a2df6bcd2f717a1999e05db1a3e68364b Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 2 Apr 2023 15:00:54 -0600 Subject: [PATCH 1010/1461] elliptic-curve: impl `AssociatedAlgorithmIdentifier` (#1286) Adds impls for `SecretKey` and `PublicKey` --- elliptic-curve/Cargo.lock | 35 +++++++++++++++++--------- elliptic-curve/Cargo.toml | 5 ++++ elliptic-curve/src/public_key.rs | 29 ++++++++++++++------- elliptic-curve/src/secret_key/pkcs8.rs | 16 +++++++++++- 4 files changed, 63 insertions(+), 22 deletions(-) diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index 8cf4ebe3a..33bca6c28 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -14,6 +14,11 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +[[package]] +name = "base64ct" +version = "1.6.0" +source = "git+https://github.com/RustCrypto/formats.git#fd069a6ff7a9f5abfd3d797b51f50ca0a5307e44" + [[package]] name = "bitvec" version = "1.0.1" @@ -80,12 +85,11 @@ dependencies = [ [[package]] name = "der" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc302fd9b18d66834a6f092d10ea85489c0ca8ad6b7304092135fab171d853cd" +version = "0.7.1" +source = "git+https://github.com/RustCrypto/formats.git#fd069a6ff7a9f5abfd3d797b51f50ca0a5307e44" dependencies = [ "const-oid", - "pem-rfc7468", + "pem-rfc7468 0.7.0 (git+https://github.com/RustCrypto/formats.git)", "zeroize", ] @@ -105,7 +109,7 @@ name = "elliptic-curve" version = "0.13.2" dependencies = [ "base16ct", - "base64ct", + "base64ct 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "crypto-bigint", "digest", "ff", @@ -113,7 +117,7 @@ dependencies = [ "group", "hex-literal", "hkdf", - "pem-rfc7468", + "pem-rfc7468 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "pkcs8", "rand_core", "sec1", @@ -226,7 +230,15 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" dependencies = [ - "base64ct", + "base64ct 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "git+https://github.com/RustCrypto/formats.git#fd069a6ff7a9f5abfd3d797b51f50ca0a5307e44" +dependencies = [ + "base64ct 1.6.0 (git+https://github.com/RustCrypto/formats.git)", ] [[package]] @@ -326,10 +338,9 @@ dependencies = [ [[package]] name = "spki" version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0445c905640145c7ea8c1993555957f65e7c46d0535b91ba501bc9bfc85522f" +source = "git+https://github.com/RustCrypto/formats.git#fd069a6ff7a9f5abfd3d797b51f50ca0a5307e44" dependencies = [ - "base64ct", + "base64ct 1.6.0 (git+https://github.com/RustCrypto/formats.git)", "der", ] @@ -374,6 +385,6 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.5.7" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 6a34fbe12..0a5442935 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -74,3 +74,8 @@ voprf = ["digest"] [package.metadata.docs.rs] features = ["bits", "ecdh", "hash2curve", "jwk", "pem", "std", "voprf"] rustdoc-args = ["--cfg", "docsrs"] + + +[patch.crates-io] +der = { git = "https://github.com/RustCrypto/formats.git" } +spki = { git = "https://github.com/RustCrypto/formats.git" } diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index 6af60d4dc..e2d71b3f0 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -12,6 +12,9 @@ use alloc::boxed::Box; #[cfg(feature = "jwk")] use crate::{JwkEcKey, JwkParameters}; +#[cfg(feature = "pkcs8")] +use pkcs8::spki::{AlgorithmIdentifier, AssociatedAlgorithmIdentifier, ObjectIdentifier}; + #[cfg(feature = "pem")] use core::str::FromStr; @@ -419,7 +422,20 @@ where } } -#[cfg(all(feature = "pkcs8", feature = "sec1"))] +#[cfg(feature = "pkcs8")] +impl AssociatedAlgorithmIdentifier for PublicKey +where + C: AssociatedOid + CurveArithmetic, +{ + type Params = ObjectIdentifier; + + const ALGORITHM_IDENTIFIER: AlgorithmIdentifier = AlgorithmIdentifier { + oid: ALGORITHM_OID, + parameters: Some(C::OID), + }; +} + +#[cfg(feature = "pkcs8")] impl TryFrom> for PublicKey where C: AssociatedOid + CurveArithmetic, @@ -433,7 +449,7 @@ where } } -#[cfg(all(feature = "pkcs8", feature = "sec1"))] +#[cfg(feature = "pkcs8")] impl TryFrom<&pkcs8::SubjectPublicKeyInfoRef<'_>> for PublicKey where C: AssociatedOid + CurveArithmetic, @@ -463,16 +479,11 @@ where FieldBytesSize: ModulusSize, { fn to_public_key_der(&self) -> pkcs8::spki::Result { - let algorithm = pkcs8::AlgorithmIdentifierRef { - oid: ALGORITHM_OID, - parameters: Some((&C::OID).into()), - }; - let public_key_bytes = self.to_encoded_point(false); let subject_public_key = der::asn1::BitStringRef::new(0, public_key_bytes.as_bytes())?; - pkcs8::SubjectPublicKeyInfoRef { - algorithm, + pkcs8::SubjectPublicKeyInfo { + algorithm: Self::ALGORITHM_IDENTIFIER, subject_public_key, } .try_into() diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs index 79215b71f..92c81f18a 100644 --- a/elliptic-curve/src/secret_key/pkcs8.rs +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -6,6 +6,7 @@ use crate::{ sec1::{ModulusSize, ValidatePublicKey}, Curve, FieldBytesSize, ALGORITHM_OID, }; +use pkcs8::spki::{AlgorithmIdentifier, AssociatedAlgorithmIdentifier, ObjectIdentifier}; use sec1::EcPrivateKey; // Imports for the `EncodePrivateKey` impl @@ -26,9 +27,21 @@ use { pkcs8::DecodePrivateKey, }; +impl AssociatedAlgorithmIdentifier for SecretKey +where + C: AssociatedOid + Curve, +{ + type Params = ObjectIdentifier; + + const ALGORITHM_IDENTIFIER: AlgorithmIdentifier = AlgorithmIdentifier { + oid: ALGORITHM_OID, + parameters: Some(C::OID), + }; +} + impl TryFrom> for SecretKey where - C: Curve + AssociatedOid + ValidatePublicKey, + C: AssociatedOid + Curve + ValidatePublicKey, FieldBytesSize: ModulusSize, { type Error = pkcs8::Error; @@ -51,6 +64,7 @@ where FieldBytesSize: ModulusSize, { fn to_pkcs8_der(&self) -> pkcs8::Result { + // TODO(tarcieri): make `PrivateKeyInfo` generic around `Params` let algorithm_identifier = pkcs8::AlgorithmIdentifierRef { oid: ALGORITHM_OID, parameters: Some((&C::OID).into()), From e8804f636a28e68e4699611244c6ac5816e9675b Mon Sep 17 00:00:00 2001 From: Willian Wang Date: Mon, 3 Apr 2023 10:21:21 -0300 Subject: [PATCH 1011/1461] elliptic-curve: fix FieldBytesEncoding ranges (#1287) --- elliptic-curve/src/field.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/elliptic-curve/src/field.rs b/elliptic-curve/src/field.rs index 605f6c728..33dd565e4 100644 --- a/elliptic-curve/src/field.rs +++ b/elliptic-curve/src/field.rs @@ -32,7 +32,8 @@ where fn decode_field_bytes(field_bytes: &FieldBytes) -> Self { debug_assert!(field_bytes.len() <= Self::ByteSize::USIZE); let mut byte_array = ByteArray::::default(); - byte_array[..field_bytes.len()].copy_from_slice(field_bytes); + let offset = Self::ByteSize::USIZE - field_bytes.len(); + byte_array[offset..].copy_from_slice(field_bytes); Self::from_be_byte_array(byte_array) } @@ -43,8 +44,8 @@ where let mut field_bytes = FieldBytes::::default(); debug_assert!(field_bytes.len() <= Self::ByteSize::USIZE); - let len = field_bytes.len(); - field_bytes.copy_from_slice(&self.to_be_byte_array()[..len]); + let offset = Self::ByteSize::USIZE - field_bytes.len(); + field_bytes.copy_from_slice(&self.to_be_byte_array()[offset..]); field_bytes } } From 05a0dea094f99545d8043f83af85e1893d7854d0 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 3 Apr 2023 09:00:48 -0600 Subject: [PATCH 1012/1461] elliptic-curve: expand clippy lints (#1288) Adds the following clippy lints and fixes violations thereof: - clippy::cast_lossless - clippy::cast_possible_truncation - clippy::cast_possible_wrap - clippy::cast_precision_loss - clippy::cast_sign_loss - clippy::checked_conversions - clippy::implicit_saturating_sub - clippy::integer_arithmetic - clippy::panic - clippy::panic_in_result_fn --- elliptic-curve/src/dev.rs | 3 ++- elliptic-curve/src/field.rs | 4 ++-- elliptic-curve/src/hash2curve/hash2field.rs | 4 ++-- .../src/hash2curve/hash2field/expand_msg/xmd.rs | 3 +++ elliptic-curve/src/hash2curve/isogeny.rs | 1 + elliptic-curve/src/lib.rs | 10 ++++++++++ 6 files changed, 20 insertions(+), 5 deletions(-) diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 5ca2d9791..36c684ad4 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -335,6 +335,7 @@ impl Invert for Scalar { impl Reduce for Scalar { type Bytes = FieldBytes; + #[allow(clippy::integer_arithmetic)] fn reduce(w: U256) -> Self { let (r, underflow) = w.sbb(&MockCurve::ORDER, Limb::ZERO); let underflow = Choice::from((underflow.0 >> (Limb::BITS - 1)) as u8); @@ -599,7 +600,7 @@ impl group::Group for ProjectivePoint { } fn is_identity(&self) -> Choice { - Choice::from((self == &Self::Identity) as u8) + Choice::from(u8::from(self == &Self::Identity)) } #[must_use] diff --git a/elliptic-curve/src/field.rs b/elliptic-curve/src/field.rs index 33dd565e4..66055abc2 100644 --- a/elliptic-curve/src/field.rs +++ b/elliptic-curve/src/field.rs @@ -32,7 +32,7 @@ where fn decode_field_bytes(field_bytes: &FieldBytes) -> Self { debug_assert!(field_bytes.len() <= Self::ByteSize::USIZE); let mut byte_array = ByteArray::::default(); - let offset = Self::ByteSize::USIZE - field_bytes.len(); + let offset = Self::ByteSize::USIZE.saturating_sub(field_bytes.len()); byte_array[offset..].copy_from_slice(field_bytes); Self::from_be_byte_array(byte_array) } @@ -44,7 +44,7 @@ where let mut field_bytes = FieldBytes::::default(); debug_assert!(field_bytes.len() <= Self::ByteSize::USIZE); - let offset = Self::ByteSize::USIZE - field_bytes.len(); + let offset = Self::ByteSize::USIZE.saturating_sub(field_bytes.len()); field_bytes.copy_from_slice(&self.to_be_byte_array()[offset..]); field_bytes } diff --git a/elliptic-curve/src/hash2curve/hash2field.rs b/elliptic-curve/src/hash2curve/hash2field.rs index b0ee5b2d6..67ede111c 100644 --- a/elliptic-curve/src/hash2curve/hash2field.rs +++ b/elliptic-curve/src/hash2curve/hash2field.rs @@ -6,7 +6,7 @@ mod expand_msg; pub use expand_msg::{xmd::*, xof::*, *}; -use crate::Result; +use crate::{Error, Result}; use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; /// The trait for helping to convert to a field element. @@ -37,7 +37,7 @@ where E: ExpandMsg<'a>, T: FromOkm + Default, { - let len_in_bytes = T::Length::to_usize() * out.len(); + let len_in_bytes = T::Length::to_usize().checked_mul(out.len()).ok_or(Error)?; let mut tmp = GenericArray::::Length>::default(); let mut expander = E::expand_message(data, domain, len_in_bytes)?; for o in out.iter_mut() { diff --git a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs index baf6f31b2..50edb648b 100644 --- a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs +++ b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs @@ -1,5 +1,8 @@ //! `expand_message_xmd` based on a hash function. +// TODO(tarcieri): checked arithmetic +#![allow(clippy::integer_arithmetic)] + use core::marker::PhantomData; use super::{Domain, ExpandMsg, Expander}; diff --git a/elliptic-curve/src/hash2curve/isogeny.rs b/elliptic-curve/src/hash2curve/isogeny.rs index fc870d010..7a28983dd 100644 --- a/elliptic-curve/src/hash2curve/isogeny.rs +++ b/elliptic-curve/src/hash2curve/isogeny.rs @@ -26,6 +26,7 @@ pub trait Isogeny: Field + AddAssign + Mul { const COEFFICIENTS: IsogenyCoefficients; /// Map from the isogeny points to the main curve + #[allow(clippy::integer_arithmetic)] fn isogeny(x: Self, y: Self) -> (Self, Self) { let mut xs = GenericArray::::default(); xs[0] = Self::ONE; diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 7e5b3879a..5f2a6c62e 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -7,7 +7,17 @@ )] #![forbid(unsafe_code)] #![warn( + clippy::cast_lossless, + clippy::cast_possible_truncation, + clippy::cast_possible_wrap, + clippy::cast_precision_loss, + clippy::cast_sign_loss, + clippy::checked_conversions, + clippy::implicit_saturating_sub, + clippy::integer_arithmetic, clippy::mod_module_files, + clippy::panic, + clippy::panic_in_result_fn, clippy::unwrap_used, missing_docs, rust_2018_idioms, From 25e2e1102e14dcebd6330314eebf00eabc162fb5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Apr 2023 20:04:07 -0600 Subject: [PATCH 1013/1461] build(deps): bump spin from 0.9.7 to 0.9.8 (#1290) Bumps [spin](https://github.com/mvdnes/spin-rs) from 0.9.7 to 0.9.8. - [Release notes](https://github.com/mvdnes/spin-rs/releases) - [Changelog](https://github.com/mvdnes/spin-rs/blob/master/CHANGELOG.md) - [Commits](https://github.com/mvdnes/spin-rs/commits) --- updated-dependencies: - dependency-name: spin dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index eac5a2e32..560b9adb7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -984,9 +984,9 @@ dependencies = [ [[package]] name = "spin" -version = "0.9.7" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0959fd6f767df20b231736396e4f602171e00d95205676286e79d4a4eb67bef" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" dependencies = [ "lock_api", ] From 1644e10f0556f798bc6b5042d7963914177a3752 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 4 Apr 2023 19:40:39 -0600 Subject: [PATCH 1014/1461] elliptic-curve: bump `pkcs8` to v0.10.2 (#1291) --- elliptic-curve/Cargo.lock | 73 +++++++++++++++++---------------------- elliptic-curve/Cargo.toml | 7 +--- 2 files changed, 32 insertions(+), 48 deletions(-) diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index 33bca6c28..4b22b68c8 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -14,11 +14,6 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" -[[package]] -name = "base64ct" -version = "1.6.0" -source = "git+https://github.com/RustCrypto/formats.git#fd069a6ff7a9f5abfd3d797b51f50ca0a5307e44" - [[package]] name = "bitvec" version = "1.0.1" @@ -33,9 +28,9 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ "generic-array", ] @@ -54,18 +49,18 @@ checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" [[package]] name = "cpufeatures" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +checksum = "280a9f2d8b3a38871a3c8a46fb80db65e5e5ed97da80c4d08bf27fb63e35e181" dependencies = [ "libc", ] [[package]] name = "crypto-bigint" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071c0f5945634bc9ba7a452f492377dd6b1993665ddb58f28704119b32f07a9a" +checksum = "7c2538c4e68e52548bacb3e83ac549f903d44f011ac9d5abb5e132e67d0808f7" dependencies = [ "generic-array", "rand_core", @@ -85,11 +80,12 @@ dependencies = [ [[package]] name = "der" -version = "0.7.1" -source = "git+https://github.com/RustCrypto/formats.git#fd069a6ff7a9f5abfd3d797b51f50ca0a5307e44" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19c5cb402c5c958281c7c0702edea7b780d03b86b606497ca3a10fcd3fc393ac" dependencies = [ "const-oid", - "pem-rfc7468 0.7.0 (git+https://github.com/RustCrypto/formats.git)", + "pem-rfc7468", "zeroize", ] @@ -109,7 +105,7 @@ name = "elliptic-curve" version = "0.13.2" dependencies = [ "base16ct", - "base64ct 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "base64ct", "crypto-bigint", "digest", "ff", @@ -117,7 +113,7 @@ dependencies = [ "group", "hex-literal", "hkdf", - "pem-rfc7468 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pem-rfc7468", "pkcs8", "rand_core", "sec1", @@ -148,9 +144,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "generic-array" -version = "0.14.6" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", @@ -205,9 +201,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" [[package]] name = "keccak" @@ -220,9 +216,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.139" +version = "0.2.141" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" +checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5" [[package]] name = "pem-rfc7468" @@ -230,22 +226,14 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" dependencies = [ - "base64ct 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "pem-rfc7468" -version = "0.7.0" -source = "git+https://github.com/RustCrypto/formats.git#fd069a6ff7a9f5abfd3d797b51f50ca0a5307e44" -dependencies = [ - "base64ct 1.6.0 (git+https://github.com/RustCrypto/formats.git)", + "base64ct", ] [[package]] name = "pkcs8" -version = "0.10.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e34154ec92c136238e7c210443538e64350962b8e2788cadcf5f781a6da70c36" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ "der", "spki", @@ -268,9 +256,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" [[package]] name = "sec1" @@ -289,15 +277,15 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.152" +version = "1.0.159" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" +checksum = "3c04e8343c3daeec41f58990b9d77068df31209f2af111e059e9fe9646693065" [[package]] name = "serde_json" -version = "1.0.93" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cad406b69c91885b5107daf2c29572f6c8cdb3c66826821e286c533490c0bc76" +checksum = "d721eca97ac802aa7777b701877c8004d950fc142651367300d21c1cc0194744" dependencies = [ "itoa", "ryu", @@ -337,10 +325,11 @@ dependencies = [ [[package]] name = "spki" -version = "0.7.0" -source = "git+https://github.com/RustCrypto/formats.git#fd069a6ff7a9f5abfd3d797b51f50ca0a5307e44" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37a5be806ab6f127c3da44b7378837ebf01dadca8510a0e572460216b228bd0e" dependencies = [ - "base64ct 1.6.0 (git+https://github.com/RustCrypto/formats.git)", + "base64ct", "der", ] diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 0a5442935..64bc4f712 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -31,7 +31,7 @@ group = { version = "0.13", optional = true, default-features = false } hkdf = { version = "0.12", optional = true, default-features = false } hex-literal = { version = "0.3", optional = true } pem-rfc7468 = { version = "0.7", optional = true, features = ["alloc"] } -pkcs8 = { version = "0.10", optional = true, default-features = false } +pkcs8 = { version = "0.10.2", optional = true, default-features = false } sec1 = { version = "0.7.1", optional = true, features = ["subtle", "zeroize"] } serdect = { version = "0.2", optional = true, default-features = false, features = ["alloc"] } serde_json = { version = "1", optional = true, default-features = false, features = ["alloc"] } @@ -74,8 +74,3 @@ voprf = ["digest"] [package.metadata.docs.rs] features = ["bits", "ecdh", "hash2curve", "jwk", "pem", "std", "voprf"] rustdoc-args = ["--cfg", "docsrs"] - - -[patch.crates-io] -der = { git = "https://github.com/RustCrypto/formats.git" } -spki = { git = "https://github.com/RustCrypto/formats.git" } From 30b389e00e1df6230d2061dcbbe5d5a27e3ff9e1 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 4 Apr 2023 20:10:35 -0600 Subject: [PATCH 1015/1461] elliptic-curve v0.13.3 (#1292) --- elliptic-curve/CHANGELOG.md | 16 ++++++++++++++++ elliptic-curve/Cargo.lock | 2 +- elliptic-curve/Cargo.toml | 2 +- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index f5bacf4a4..83b27687e 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,22 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.13.3 (2023-04-04) +### Added +- Impl `AssociatedAlgorithmIdentifier` for `SecretKey` and `PublicKey` ([#1286]) + +### Changed +- Update OSSWU code ([#1157]) +- Bump `pkcs8` to v0.10.2 ([#1291]) + +### Fixed +- `FieldBytesEncoding` provided impl ([#1287]) + +[#1157]: https://github.com/RustCrypto/traits/pull/1157 +[#1286]: https://github.com/RustCrypto/traits/pull/1286 +[#1287]: https://github.com/RustCrypto/traits/pull/1287 +[#1291]: https://github.com/RustCrypto/traits/pull/1291 + ## 0.13.2 (2023-03-08) ### Added - Weakly activate `pkcs8?/std` ([#1263]) diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index 4b22b68c8..b180bda63 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -102,7 +102,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.13.2" +version = "0.13.3" dependencies = [ "base16ct", "base64ct", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 64bc4f712..c9ef60c0b 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.13.2" +version = "0.13.3" description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, From 09dacdf8d1239d41a200fdc51dd5c5f1871770ff Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 8 Apr 2023 17:44:20 -0600 Subject: [PATCH 1016/1461] elliptic-curve: bump `hex-literal` to v0.4 (#1295) --- elliptic-curve/Cargo.lock | 4 ++-- elliptic-curve/Cargo.toml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index b180bda63..c87106741 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -177,9 +177,9 @@ dependencies = [ [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "hkdf" diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index c9ef60c0b..c95768db0 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -29,7 +29,7 @@ digest = { version = "0.10", optional = true } ff = { version = "0.13", optional = true, default-features = false } group = { version = "0.13", optional = true, default-features = false } hkdf = { version = "0.12", optional = true, default-features = false } -hex-literal = { version = "0.3", optional = true } +hex-literal = { version = "0.4", optional = true } pem-rfc7468 = { version = "0.7", optional = true, features = ["alloc"] } pkcs8 = { version = "0.10.2", optional = true, default-features = false } sec1 = { version = "0.7.1", optional = true, features = ["subtle", "zeroize"] } @@ -37,7 +37,7 @@ serdect = { version = "0.2", optional = true, default-features = false, features serde_json = { version = "1", optional = true, default-features = false, features = ["alloc"] } [dev-dependencies] -hex-literal = "0.3" +hex-literal = "0.4" sha2 = "0.10" sha3 = "0.10" From 383438d6aca8588d4f71f14693a03329a08d44d7 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 8 Apr 2023 20:21:54 -0600 Subject: [PATCH 1017/1461] elliptic-curve: fix remaining `FieldBytesSize` handling (#1296) Fixes the two remaining usages of `C::Uint::BYTES` to use `C::FieldBytesSize::USIZE` instead. These usages were: - `NonZeroScalar::from_slice` - `ScalarPrimitive::from_slice` --- elliptic-curve/src/scalar/nonzero.rs | 4 ++-- elliptic-curve/src/scalar/primitive.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/elliptic-curve/src/scalar/nonzero.rs b/elliptic-curve/src/scalar/nonzero.rs index c1f326b83..c0e45740f 100644 --- a/elliptic-curve/src/scalar/nonzero.rs +++ b/elliptic-curve/src/scalar/nonzero.rs @@ -13,7 +13,7 @@ use core::{ }; use crypto_bigint::{ArrayEncoding, Integer}; use ff::{Field, PrimeField}; -use generic_array::GenericArray; +use generic_array::{typenum::Unsigned, GenericArray}; use rand_core::CryptoRngCore; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; use zeroize::Zeroize; @@ -285,7 +285,7 @@ where type Error = Error; fn try_from(bytes: &[u8]) -> Result { - if bytes.len() == C::Uint::BYTES { + if bytes.len() == C::FieldBytesSize::USIZE { Option::from(NonZeroScalar::from_repr(GenericArray::clone_from_slice( bytes, ))) diff --git a/elliptic-curve/src/scalar/primitive.rs b/elliptic-curve/src/scalar/primitive.rs index c81f1bd7e..a4f64cb58 100644 --- a/elliptic-curve/src/scalar/primitive.rs +++ b/elliptic-curve/src/scalar/primitive.rs @@ -13,7 +13,7 @@ use core::{ ops::{Add, AddAssign, Neg, ShrAssign, Sub, SubAssign}, str, }; -use generic_array::GenericArray; +use generic_array::{typenum::Unsigned, GenericArray}; use rand_core::CryptoRngCore; use subtle::{ Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeGreater, ConstantTimeLess, @@ -83,7 +83,7 @@ where /// Decode [`ScalarPrimitive`] from a big endian byte slice. pub fn from_slice(slice: &[u8]) -> Result { - if slice.len() == C::Uint::BYTES { + if slice.len() == C::FieldBytesSize::USIZE { Option::from(Self::from_bytes(GenericArray::from_slice(slice))).ok_or(Error) } else { Err(Error) From 6225999e75c9bba5dd380394999547d82bae2576 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 8 Apr 2023 20:56:08 -0600 Subject: [PATCH 1018/1461] elliptic-curve v0.13.4 (#1297) --- elliptic-curve/CHANGELOG.md | 11 +++++++++++ elliptic-curve/Cargo.lock | 2 +- elliptic-curve/Cargo.toml | 2 +- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index 83b27687e..a6128cd91 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,17 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.13.4 (2023-04-08) +### Changed +- Bump `hex-literal` to v0.4 ([#1295]) + +### Fixed +- `NonZeroScalar::from_slice` ([#1296]) +- `ScalarPrimitive::from_slice` ([#1296]) + +[#1295]: https://github.com/RustCrypto/traits/pull/1295 +[#1296]: https://github.com/RustCrypto/traits/pull/1296 + ## 0.13.3 (2023-04-04) ### Added - Impl `AssociatedAlgorithmIdentifier` for `SecretKey` and `PublicKey` ([#1286]) diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index c87106741..0877e7589 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -102,7 +102,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.13.3" +version = "0.13.4" dependencies = [ "base16ct", "base64ct", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index c95768db0..db07d03c5 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.13.3" +version = "0.13.4" description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, From 3ac426bf04ccd261163099bb54a52ecbeef5cb60 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 17 Apr 2023 11:31:29 -0600 Subject: [PATCH 1019/1461] signature_derive: bump `syn` to v2 (#1299) --- Cargo.lock | 19 ++++--------------- signature/derive/Cargo.toml | 2 +- signature/src/lib.rs | 18 ++++-------------- 3 files changed, 9 insertions(+), 30 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 560b9adb7..15e8d2ea7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -71,7 +71,7 @@ checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" dependencies = [ "proc-macro2", "quote", - "syn 2.0.13", + "syn", ] [[package]] @@ -925,7 +925,7 @@ checksum = "4c614d17805b093df4b147b51339e7e44bf05ef59fba1e45d83500bcfb4d8585" dependencies = [ "proc-macro2", "quote", - "syn 2.0.13", + "syn", ] [[package]] @@ -979,7 +979,7 @@ version = "2.0.0" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] @@ -1022,17 +1022,6 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - [[package]] name = "syn" version = "2.0.13" @@ -1132,5 +1121,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.13", + "syn", ] diff --git a/signature/derive/Cargo.toml b/signature/derive/Cargo.toml index cdd59e5cf..297ed4bf8 100644 --- a/signature/derive/Cargo.toml +++ b/signature/derive/Cargo.toml @@ -18,4 +18,4 @@ proc-macro = true [dependencies] proc-macro2 = "1" quote = "1" -syn = "1" +syn = "2" diff --git a/signature/src/lib.rs b/signature/src/lib.rs index ba1feb494..c90f5cc8a 100644 --- a/signature/src/lib.rs +++ b/signature/src/lib.rs @@ -92,13 +92,12 @@ //! and compiler errors, and in our experience makes them unsuitable for this //! sort of API. We believe such an API is the natural one for signature //! systems, reflecting the natural way they are written absent a trait. -//! - Associated types preclude multiple (or generic) implementations of the -//! same trait. These parameters are common in signature systems, notably -//! ones which support different digest algorithms. +//! - Associated types preclude multiple implementations of the same trait. +//! These parameters are common in signature systems, notably ones which +//! support different serializations of a signature (e.g. raw vs ASN.1). //! - Digital signatures are almost always larger than the present 32-entry -//! trait impl limitation on array types, which complicates trait signatures +//! trait impl limitation on array types, which complicates bounds //! for these types (particularly things like `From` or `Borrow` bounds). -//! This may be more interesting to explore after const generics. //! //! ## Unstable features //! @@ -111,15 +110,6 @@ //! //! The following unstable features are presently supported: //! -//! - `derive`: for implementers of signature systems using [`DigestSigner`] -//! and [`DigestVerifier`], the `derive` feature can be used to -//! derive [`Signer`] and [`Verifier`] traits which prehash the input -//! message using the [`PrehashSignature::Digest`] algorithm for -//! a given signature type. When the `derive` feature is enabled -//! import the proc macros with `use signature::{Signer, Verifier}` and then -//! add a `derive(Signer)` or `derive(Verifier)` attribute to the given -//! digest signer/verifier type. Enabling this feature also enables `digest` -//! support (see immediately below). //! - `digest`: enables the [`DigestSigner`] and [`DigestVerifier`] //! traits which are based on the [`Digest`] trait from the [`digest`] crate. //! These traits are used for representing signature systems based on the From 7da098c42ea4a08064ca2411a33579bf2cc9e642 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 17 Apr 2023 11:45:11 -0600 Subject: [PATCH 1020/1461] signature_derive v2.0.1 (#1300) --- signature/derive/CHANGELOG.md | 6 ++++++ signature/derive/Cargo.toml | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/signature/derive/CHANGELOG.md b/signature/derive/CHANGELOG.md index cfe4bb995..4e0656283 100644 --- a/signature/derive/CHANGELOG.md +++ b/signature/derive/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 2.0.1 (2023-04-17) +### Changed +- Bump `syn` to v2 ([#1299]) + +[#1299]: https://github.com/RustCrypto/traits/pull/1299 + ## 2.0.0 (2023-01-15) ### Changed - `Signature` trait has been removed, so don't emit it in custom derive ([#1141]) diff --git a/signature/derive/Cargo.toml b/signature/derive/Cargo.toml index 297ed4bf8..35a1e8488 100644 --- a/signature/derive/Cargo.toml +++ b/signature/derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "signature_derive" -version = "2.0.0" +version = "2.0.1" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" description = "Custom derive support for the 'signature' crate" From 6560211c7d5628f729d002efb811394c2ff5a5b9 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 17 Apr 2023 20:12:17 -0600 Subject: [PATCH 1021/1461] elliptic-curve: fix/test alloc+arithmetic features w/o sec1 (#1301) The combination of `alloc`+`arithmetic` would previously cause compile errors because some `sec1`-related code was not properly gated. This fixes the feature gating. --- .github/workflows/elliptic-curve.yml | 1 + Cargo.lock | 2 +- elliptic-curve/src/public_key.rs | 8 ++++---- elliptic-curve/src/secret_key.rs | 20 +++++++++----------- 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index fc60207f5..31b2f148a 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -51,6 +51,7 @@ jobs: - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features sec1 - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features serde - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features voprf + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,arithmetic - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,arithmetic,pkcs8 - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,serde - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features arithmetic,serde diff --git a/Cargo.lock b/Cargo.lock index 15e8d2ea7..e835baee6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -975,7 +975,7 @@ dependencies = [ [[package]] name = "signature_derive" -version = "2.0.0" +version = "2.0.1" dependencies = [ "proc-macro2", "quote", diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index e2d71b3f0..c3d548095 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -6,9 +6,6 @@ use crate::{ use core::fmt::Debug; use group::{Curve, Group}; -#[cfg(feature = "alloc")] -use alloc::boxed::Box; - #[cfg(feature = "jwk")] use crate::{JwkEcKey, JwkParameters}; @@ -32,6 +29,9 @@ use { #[cfg(all(feature = "alloc", feature = "pkcs8"))] use pkcs8::EncodePublicKey; +#[cfg(all(feature = "alloc", feature = "sec1"))] +use alloc::boxed::Box; + #[cfg(any(feature = "jwk", feature = "pem"))] use alloc::string::{String, ToString}; @@ -138,7 +138,7 @@ where /// (page 10). /// /// - #[cfg(feature = "alloc")] + #[cfg(all(feature = "alloc", feature = "sec1"))] pub fn to_sec1_bytes(&self) -> Box<[u8]> where C: PointCompression, diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 97b3d58bd..a8da65ccd 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -14,16 +14,6 @@ use generic_array::typenum::Unsigned; use subtle::{Choice, ConstantTimeEq}; use zeroize::{Zeroize, ZeroizeOnDrop}; -#[cfg(all(feature = "alloc", feature = "arithmetic"))] -use { - crate::{ - sec1::{FromEncodedPoint, ToEncodedPoint}, - AffinePoint, - }, - alloc::vec::Vec, - zeroize::Zeroizing, -}; - #[cfg(feature = "arithmetic")] use crate::{rand_core::CryptoRngCore, CurveArithmetic, NonZeroScalar, PublicKey}; @@ -34,7 +24,15 @@ use crate::jwk::{JwkEcKey, JwkParameters}; use sec1::der; #[cfg(all(feature = "alloc", feature = "arithmetic", feature = "sec1"))] -use sec1::der::Encode; +use { + crate::{ + sec1::{FromEncodedPoint, ToEncodedPoint}, + AffinePoint, + }, + alloc::vec::Vec, + sec1::der::Encode, + zeroize::Zeroizing, +}; #[cfg(all(feature = "arithmetic", any(feature = "jwk", feature = "pem")))] use alloc::string::String; From 7d5523165e9493fc2a95c30711a65fc5c9ab0810 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 17 Apr 2023 20:26:30 -0600 Subject: [PATCH 1022/1461] crypto: bump `elliptic-curve` to v0.13; MSRV 1.65 (#1302) --- .github/workflows/crypto.yml | 6 +- Cargo.lock | 40 +---- Cargo.toml | 6 +- crypto/Cargo.lock | 290 +++++++++++++++++++++++++++++++++++ crypto/Cargo.toml | 4 +- crypto/README.md | 4 +- 6 files changed, 303 insertions(+), 47 deletions(-) create mode 100644 crypto/Cargo.lock diff --git a/.github/workflows/crypto.yml b/.github/workflows/crypto.yml index b10972631..cab9c5da6 100644 --- a/.github/workflows/crypto.yml +++ b/.github/workflows/crypto.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.60.0 # MSRV + - 1.65.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -55,7 +55,7 @@ jobs: strategy: matrix: rust: - - 1.60.0 # MSRV + - 1.65.0 # MSRV - stable steps: - uses: actions/checkout@v3 @@ -75,6 +75,6 @@ jobs: - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: - toolchain: 1.60.0 + toolchain: 1.65.0 components: clippy - run: cargo clippy --all --all-features -- -D warnings diff --git a/Cargo.lock b/Cargo.lock index e835baee6..8a8ca2d84 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -252,20 +252,6 @@ version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6548a0ad5d2549e111e1f6a11a6c2e2d00ce6a3dafe22948d67c2b443f775e52" -[[package]] -name = "crypto" -version = "0.5.0-pre" -dependencies = [ - "aead 0.5.2", - "cipher 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "crypto-common 0.1.6", - "digest 0.10.6", - "elliptic-curve 0.12.3", - "password-hash", - "signature 2.1.0", - "universal-hash 0.5.0", -] - [[package]] name = "crypto-bigint" version = "0.2.5" @@ -369,7 +355,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" dependencies = [ "const-oid 0.9.2", - "zeroize", ] [[package]] @@ -431,7 +416,7 @@ dependencies = [ "ff 0.10.1", "generic-array", "group 0.10.0", - "pkcs8 0.7.6", + "pkcs8", "rand_core 0.6.4", "subtle", "zeroize", @@ -726,20 +711,10 @@ checksum = "ee3ef9b64d26bad0536099c816c6734379e45bbd5f14798def6809e5cc350447" dependencies = [ "der 0.4.5", "pem-rfc7468", - "spki 0.4.1", + "spki", "zeroize", ] -[[package]] -name = "pkcs8" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" -dependencies = [ - "der 0.6.1", - "spki 0.6.0", -] - [[package]] name = "poly1305" version = "0.8.0" @@ -888,7 +863,6 @@ dependencies = [ "base16ct", "der 0.6.1", "generic-array", - "pkcs8 0.9.0", "subtle", "zeroize", ] @@ -1000,16 +974,6 @@ dependencies = [ "der 0.4.5", ] -[[package]] -name = "spki" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" -dependencies = [ - "base64ct", - "der 0.6.1", -] - [[package]] name = "stable_deref_trait" version = "1.2.0" diff --git a/Cargo.toml b/Cargo.toml index 16f91e046..e7b7482b6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,14 +3,16 @@ resolver = "2" members = [ "aead", "cipher", - "crypto", "crypto-common", "digest", "kem", + "password-hash", "signature", "signature/async", "universal-hash", ] +# re-add when all crates are MSRV 1.60+ exclude = [ - "elliptic-curve" # re-add when all crates are MSRV 1.60+ + "crypto", + "elliptic-curve" ] diff --git a/crypto/Cargo.lock b/crypto/Cargo.lock new file mode 100644 index 000000000..7a9833963 --- /dev/null +++ b/crypto/Cargo.lock @@ -0,0 +1,290 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aead" +version = "0.5.2" +dependencies = [ + "crypto-common", + "generic-array", +] + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-padding" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" +dependencies = [ + "generic-array", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "const-oid" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" + +[[package]] +name = "crypto" +version = "0.5.0-pre" +dependencies = [ + "aead", + "cipher", + "crypto-common", + "digest", + "elliptic-curve", + "password-hash", + "signature", + "universal-hash", +] + +[[package]] +name = "crypto-bigint" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c2538c4e68e52548bacb3e83ac549f903d44f011ac9d5abb5e132e67d0808f7" +dependencies = [ + "generic-array", + "rand_core", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "rand_core", + "typenum", +] + +[[package]] +name = "der" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82b10af9f9f9f2134a42d3f8aa74658660f2e0234b0eb81bd171df8aa32779ed" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "digest" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "elliptic-curve" +version = "0.13.4" +dependencies = [ + "base16ct", + "crypto-bigint", + "ff", + "generic-array", + "group", + "pkcs8", + "rand_core", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core", + "subtle", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "getrandom" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core", + "subtle", +] + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "block-padding", + "generic-array", +] + +[[package]] +name = "libc" +version = "0.2.141" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5" + +[[package]] +name = "password-hash" +version = "0.5.0" +dependencies = [ + "base64ct", + "rand_core", + "subtle", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "sec1" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0aec48e813d6b90b15f0b8948af3c63483992dee44c03e9930b3eebdabe046e" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + +[[package]] +name = "signature" +version = "2.1.0" + +[[package]] +name = "spki" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37a5be806ab6f127c3da44b7378837ebf01dadca8510a0e572460216b228bd0e" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "typenum" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + +[[package]] +name = "universal-hash" +version = "0.5.0" +dependencies = [ + "crypto-common", + "subtle", +] + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "zeroize" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 1e2b659ea..596893cec 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -12,7 +12,7 @@ keywords = ["crypto", "encryption", "rustcrypto"] categories = ["cryptography", "no-std"] readme = "README.md" edition = "2021" -rust-version = "1.60" +rust-version = "1.65" [dependencies] crypto-common = { version = "0.1", default-features = false } @@ -21,7 +21,7 @@ crypto-common = { version = "0.1", default-features = false } aead = { version = "0.5", optional = true, path = "../aead" } cipher = { version = "0.4", optional = true } digest = { version = "0.10", optional = true, features = ["mac"] } -elliptic-curve = { version = "0.12", optional = true } # path = "../elliptic-curve" +elliptic-curve = { version = "0.13", optional = true, path = "../elliptic-curve" } password-hash = { version = "0.5", optional = true, path = "../password-hash" } signature = { version = "2", optional = true, default-features = false, path = "../signature" } universal-hash = { version = "0.5", optional = true, path = "../universal-hash" } diff --git a/crypto/README.md b/crypto/README.md index 4057e637f..19a48b647 100644 --- a/crypto/README.md +++ b/crypto/README.md @@ -14,7 +14,7 @@ access compatible versions of all traits from the Rust Crypto project. ## Minimum Supported Rust Version -Rust **1.60** or higher. +Rust **1.65** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -46,7 +46,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/crypto/badge.svg [docs-link]: https://docs.rs/crypto/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.60+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.65+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260050-Traits [build-image]: https://github.com/RustCrypto/traits/workflows/crypto/badge.svg?branch=master&event=push From f0dbe44fea56d4c17e625ababacb580fec842137 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 17 Apr 2023 20:38:52 -0600 Subject: [PATCH 1023/1461] crypto v0.5.0 (#1303) --- crypto/CHANGELOG.md | 10 ++++++++++ crypto/Cargo.lock | 2 +- crypto/Cargo.toml | 7 +++---- crypto/README.md | 38 ++++++++++++++++++++++++++++++++++++++ crypto/src/lib.rs | 41 +++-------------------------------------- 5 files changed, 55 insertions(+), 43 deletions(-) diff --git a/crypto/CHANGELOG.md b/crypto/CHANGELOG.md index a63d4dca6..e78f1d66e 100644 --- a/crypto/CHANGELOG.md +++ b/crypto/CHANGELOG.md @@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.5.0 (2023-04-17) +### Changed +- Bump `signature` to v2 ([#1211]) +- Bump `password-hash` to v0.5 ([#1271]) +- Bump `elliptic-curve` to v0.13; MSRV 1.65 ([#1302]) + +[#1211]: https://github.com/RustCrypto/traits/pull/1211 +[#1271]: https://github.com/RustCrypto/traits/pull/1271 +[#1302]: https://github.com/RustCrypto/traits/pull/1302 + ## 0.4.0 (2022-08-09) ### Added - Re-export `crypto-common` as `common` ([#1076]) diff --git a/crypto/Cargo.lock b/crypto/Cargo.lock index 7a9833963..93f411d09 100644 --- a/crypto/Cargo.lock +++ b/crypto/Cargo.lock @@ -64,7 +64,7 @@ checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" [[package]] name = "crypto" -version = "0.5.0-pre" +version = "0.5.0" dependencies = [ "aead", "cipher", diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 596893cec..e1e9ab1a7 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -1,9 +1,7 @@ [package] name = "crypto" -version = "0.5.0-pre" # Also update html_root_url in lib.rs when bumping this -description = """ -Resources for building cryptosystems in Rust using the RustCrypto project's ecosystem. -""" +version = "0.5.0" +description = "Facade crate for all of the RustCrypto traits (e.g. `aead`, `cipher`, `digest`)" authors = ["The RustCrypto Project Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/crypto" @@ -41,3 +39,4 @@ rand_core = ["crypto-common/rand_core"] [package.metadata.docs.rs] all-features = true +rustdoc-args = ["--cfg", "docsrs"] diff --git a/crypto/README.md b/crypto/README.md index 19a48b647..7c5ac4c49 100644 --- a/crypto/README.md +++ b/crypto/README.md @@ -12,6 +12,44 @@ access compatible versions of all traits from the Rust Crypto project. [Documentation][docs-link] +## About + +Facade crate for [RustCrypto Traits][1], providing a single place to +access compatible versions of all traits from the Rust Crypto project. + +# About + +The [RustCrypto Project][2] publishes and maintains independently versioned +crates containing traits for many different kinds of cryptographic +algorithms. + +However, these algorithms are often interdependent (e.g. many depend on digest +algorithms), which requires figuring out which versions of the trait crates +are compatible with each other. + +This crate will automatically pull in compatible versions of these crates, +with each one gated under a cargo feature, providing a single place to both +import and upgrade these crates while ensuring they remain compatible. + +# Traits + +The following traits are available as re-exports of RustCrypto crates through +this crate's facade. To access a particular re-export you (or a crate you +depend on) must enable the associated Cargo feature named below. + +| Re-export | Cargo feature | Description | +|-----------|---------------|-------------| +| [`aead`](https://docs.rs/aead) | `aead` | Authenticated Encryption with Associated Data (i.e. high-level symmetric encryption) | +| [`cipher`](https://docs.rs/cipher) | `cipher` | Block and stream ciphers (i.e. low-level symmetric encryption) | +| [`digest`](https://docs.rs/digest) | `digest` | Cryptographic hash functions | +| [`elliptic_curve`](https://docs.rs/elliptic-curve) | `elliptic-curve` | Elliptic curve cryptography | +| [`password_hash`](https://docs.rs/password-hash) | `password-hash` | Password hashing functions | +| [`signature`](https://docs.rs/signature) | `signature` | Digital signatures (i.e. public key-based message authentication) | +| [`universal_hash`](https://docs.rs/universal-hash) | `universal‑hash` | Universal Hash Functions (used to build MACs) | + +[1]: https://github.com/RustCrypto/traits +[2]: https://github.com/RustCrypto + ## Minimum Supported Rust Version Rust **1.65** or higher. diff --git a/crypto/src/lib.rs b/crypto/src/lib.rs index 9a5f397eb..c28db6fce 100644 --- a/crypto/src/lib.rs +++ b/crypto/src/lib.rs @@ -1,48 +1,13 @@ #![no_std] +#![cfg_attr(docsrs, feature(doc_auto_cfg))] +#![doc = include_str!("../README.md")] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/crypto/0.4.0-pre" + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg" )] #![forbid(unsafe_code)] #![warn(rust_2018_idioms)] -//! Facade crate for [RustCrypto Traits][1], providing a single place to -//! access compatible versions of all traits from the Rust Crypto project. -//! -//! # About -//! -//! The [RustCrypto Project][2] publishes and maintains independently versioned -//! crates containing traits for many different kinds of cryptographic -//! algorithms. -//! -//! However, these algorithms are often interdependent (e.g. many depend on digest -//! algorithms), which requires figuring out which versions of the trait crates -//! are compatible with each other. -//! -//! This crate will automatically pull in compatible versions of these crates, -//! with each one gated under a cargo feature, providing a single place to both -//! import and upgrade these crates while ensuring they remain compatible. -//! -//! # Traits -//! -//! The following traits are available as re-exports of RustCrypto crates through -//! this crate's facade. To access a particular re-export you (or a crate you -//! depend on) must enable the associated Cargo feature named below. -//! -//! | Re-export | Cargo feature | Description | -//! |-----------|---------------|-------------| -//! | [`aead`](https://docs.rs/aead) | `aead` | Authenticated Encryption with Associated Data (i.e. high-level symmetric encryption) | -//! | [`cipher`](https://docs.rs/cipher) | `cipher` | Block and stream ciphers (i.e. low-level symmetric encryption) | -//! | [`digest`](https://docs.rs/digest) | `digest` | Cryptographic hash functions | -//! | [`elliptic_curve`](https://docs.rs/elliptic-curve) | `elliptic-curve` | Elliptic curve cryptography | -//! | [`password_hash`](https://docs.rs/password-hash) | `password-hash` | Password hashing functions | -//! | [`signature`](https://docs.rs/signature) | `signature` | Digital signatures (i.e. public key-based message authentication) | -//! | [`universal_hash`](https://docs.rs/universal-hash) | `universal‑hash` | Universal Hash Functions (used to build MACs) | -//! -//! [1]: https://github.com/RustCrypto/traits -//! [2]: https://github.com/RustCrypto - pub use crypto_common as common; #[cfg(feature = "aead")] From a7a62e2de9b0f077958405246f553e3ce5c3c26f Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 23 Apr 2023 20:03:18 -0600 Subject: [PATCH 1024/1461] Add SECURITY.md --- SECURITY.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 000000000..15e176975 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,17 @@ +# Security Policy + +## Supported Versions + +Security updates are applied only to the most recent release. + +## Reporting a Vulnerability + +If you have discovered a security vulnerability in this project, please report +it privately. **Do not disclose it as a public issue.** This gives us time to +work with you to fix the issue before public exposure, reducing the chance that +the exploit will be used before a patch is released. + +Please disclose it at [security advisory](https://github.com/RustCrypto/traits/security/advisories/new). + +This project is maintained by a team of volunteers on a reasonable-effort basis. +As such, please give us at least 90 days to work on a fix before public exposure. From 808fa1e0c2e8c66d38744b3c1d98dd0b4e291e28 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 18 May 2023 13:38:55 -0600 Subject: [PATCH 1025/1461] elliptic-curve: faster `PublicKey::from_encoded_point` (#1310) Checks if the SEC1 point is using the identity encoding directly, rather than round tripping through `ProjectivePoint`. --- elliptic-curve/src/public_key.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index c3d548095..485b0ecfd 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -23,7 +23,7 @@ use { FieldBytesSize, }, core::cmp::Ordering, - subtle::CtOption, + subtle::{Choice, CtOption}, }; #[cfg(all(feature = "alloc", feature = "pkcs8"))] @@ -231,7 +231,7 @@ where /// Initialize [`PublicKey`] from an [`EncodedPoint`] fn from_encoded_point(encoded_point: &EncodedPoint) -> CtOption { AffinePoint::::from_encoded_point(encoded_point).and_then(|point| { - let is_identity = ProjectivePoint::::from(point).is_identity(); + let is_identity = Choice::from(encoded_point.is_identity() as u8); CtOption::new(PublicKey { point }, !is_identity) }) } From 86e7b149141484d14bc2aab97c6227c72fc9d8c1 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 19 May 2023 09:25:53 -0600 Subject: [PATCH 1026/1461] universal-hash v0.5.1 (#1312) --- Cargo.lock | 10 +++++----- universal-hash/CHANGELOG.md | 8 +++++++- universal-hash/Cargo.toml | 2 +- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8a8ca2d84..950d72d98 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -723,7 +723,7 @@ checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" dependencies = [ "cpufeatures", "opaque-debug", - "universal-hash 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "universal-hash 0.5.0", ] [[package]] @@ -735,7 +735,7 @@ dependencies = [ "cfg-if", "cpufeatures", "opaque-debug", - "universal-hash 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "universal-hash 0.5.0", ] [[package]] @@ -1012,6 +1012,8 @@ checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" [[package]] name = "universal-hash" version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d3160b73c9a19f7e2939a2fdad446c57c1bbbbf4d919d3213ff1267a580d8b5" dependencies = [ "crypto-common 0.1.6", "subtle", @@ -1019,9 +1021,7 @@ dependencies = [ [[package]] name = "universal-hash" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d3160b73c9a19f7e2939a2fdad446c57c1bbbbf4d919d3213ff1267a580d8b5" +version = "0.5.1" dependencies = [ "crypto-common 0.1.6", "subtle", diff --git a/universal-hash/CHANGELOG.md b/universal-hash/CHANGELOG.md index bb9f52879..e495d3d56 100644 --- a/universal-hash/CHANGELOG.md +++ b/universal-hash/CHANGELOG.md @@ -5,7 +5,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 0.5.0 (2021-07-30) +## 0.5.1 (2023-05-19) +### Changed +- Loosen `subtle` version requirement to `^2.4` ([#1260]) + +[#1260]: https://github.com/RustCrypto/traits/pull/1260 + +## 0.5.0 (2022-07-30) ### Added - `UhfBackend` trait ([#1051], [#1059]) - `UhfClosure` trait ([#1051]) diff --git a/universal-hash/Cargo.toml b/universal-hash/Cargo.toml index 37a41f46d..2cae13be1 100644 --- a/universal-hash/Cargo.toml +++ b/universal-hash/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "universal-hash" -version = "0.5.0" +version = "0.5.1" description = "Traits which describe the functionality of universal hash functions (UHFs)" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" From 1164e44383c2517ce1ce35bf0331d681d4093362 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 19 May 2023 11:00:51 -0600 Subject: [PATCH 1027/1461] elliptic-curve v0.13.5 (#1313) --- Cargo.lock | 10 +++++----- elliptic-curve/CHANGELOG.md | 10 ++++++++++ elliptic-curve/Cargo.lock | 2 +- elliptic-curve/Cargo.toml | 2 +- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 950d72d98..3a2a5e3b4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -723,7 +723,7 @@ checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" dependencies = [ "cpufeatures", "opaque-debug", - "universal-hash 0.5.0", + "universal-hash 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -735,7 +735,7 @@ dependencies = [ "cfg-if", "cpufeatures", "opaque-debug", - "universal-hash 0.5.0", + "universal-hash 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1011,9 +1011,7 @@ checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" [[package]] name = "universal-hash" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d3160b73c9a19f7e2939a2fdad446c57c1bbbbf4d919d3213ff1267a580d8b5" +version = "0.5.1" dependencies = [ "crypto-common 0.1.6", "subtle", @@ -1022,6 +1020,8 @@ dependencies = [ [[package]] name = "universal-hash" version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" dependencies = [ "crypto-common 0.1.6", "subtle", diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index a6128cd91..62b62eb09 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.13.5 (2023-05-19) +### Changed +- Faster `PublicKey::from_encoded_point` ([#1310]) + +### Fixed +- `alloc`+`arithmetic` features w/o `sec1` feature ([#1301]) + +[#1301]: https://github.com/RustCrypto/traits/pull/1301 +[#1310]: https://github.com/RustCrypto/traits/pull/1310 + ## 0.13.4 (2023-04-08) ### Changed - Bump `hex-literal` to v0.4 ([#1295]) diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index 0877e7589..cdca21f9b 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -102,7 +102,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.13.4" +version = "0.13.5" dependencies = [ "base16ct", "base64ct", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index db07d03c5..825ad51b9 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.13.4" +version = "0.13.5" description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, From d6a67869f446a91b8d83294763aed5ba865c6d5b Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 19 May 2023 11:14:46 -0600 Subject: [PATCH 1028/1461] digest: add CHANGELOG.md entry for v0.10.7 It was released in #1314 --- digest/CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/digest/CHANGELOG.md b/digest/CHANGELOG.md index 6713389fd..f715b731b 100644 --- a/digest/CHANGELOG.md +++ b/digest/CHANGELOG.md @@ -15,6 +15,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [#1173]: https://github.com/RustCrypto/traits/pull/1173 +## 0.10.7 (2023-05-19) +### Changed +- Loosen `subtle` version requirement ([#1260]) + +[#1260]: https://github.com/RustCrypto/traits/pull/1260 + ## 0.10.6 (2022-11-17) ### Added - `Mac::verify_reset` and `Mac::verify_slice_reset` methods ([#1154]) From 40a0d2e14b59339babe04785e6185a767de83227 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hendrik=20B=C3=B6ck?= Date: Mon, 29 May 2023 17:24:35 +0200 Subject: [PATCH 1029/1461] fix documentation for `struct Salt` (#1316) (#1317) --- password-hash/src/salt.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/password-hash/src/salt.rs b/password-hash/src/salt.rs index 2fb8784a3..a73288c3b 100644 --- a/password-hash/src/salt.rs +++ b/password-hash/src/salt.rs @@ -50,14 +50,14 @@ const INVARIANT_VIOLATED_MSG: &str = "salt string invariant violated"; /// guidelines from the spec: /// /// - Minimum length: **4**-bytes -/// - Maximum length: **64**-bytes +/// - Maximum length: **48**-bytes /// /// A maximum length is enforced based on the above recommendation for /// supporting stack-allocated buffers (which this library uses), and the -/// specific determination of 64-bytes is taken as a best practice from the +/// specific determination of 48-bytes is taken as a best practice from the /// [Argon2 Encoding][3] specification in the same document: /// -/// > The length in bytes of the salt is between 8 and 64 bytes, thus +/// > The length in bytes of the salt is between 8 and 48 bytes, thus /// > yielding a length in characters between 11 and 64 characters (and that /// > length is never equal to 1 modulo 4). The default byte length of the salt /// > is 16 bytes (22 characters in B64 encoding). An encoded UUID, or a From 3be350f2d482f8b275b66e1d40a96afc0724f050 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 31 May 2023 08:32:03 -0600 Subject: [PATCH 1030/1461] crypto-common: use `CryptoRngCore` (#1318) Added in `rand_core` v0.6.4. I think in the next `rand_core` release we'll be able to replace it with `CryptoRng` (by leveraging a supertrait bound) but for now this reduces the number of traits needed to just one. --- crypto-common/Cargo.toml | 2 +- crypto-common/src/lib.rs | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index 03f4d2b9e..63fca3de6 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -17,7 +17,7 @@ generic-array = { version = "0.14.6", features = ["more_lengths"] } typenum = "1.14" # earlier versions of typenum don't satisfy the 'static bound on U* types # optional dependencies -rand_core = { version = "0.6", optional = true } +rand_core = { version = "0.6.4", optional = true } [features] std = [] diff --git a/crypto-common/src/lib.rs b/crypto-common/src/lib.rs index 53f0fa9cf..f4d3993da 100644 --- a/crypto-common/src/lib.rs +++ b/crypto-common/src/lib.rs @@ -21,7 +21,7 @@ pub use generic_array::typenum; use core::fmt; use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; #[cfg(feature = "rand_core")] -use rand_core::{CryptoRng, RngCore}; +use rand_core::CryptoRngCore; /// Block on which [`BlockSizeUser`] implementors operate. pub type Block = GenericArray::BlockSize>; @@ -158,11 +158,11 @@ pub trait KeyInit: KeySizeUser + Sized { } } - /// Generate random key using the provided [`CryptoRng`]. + /// Generate random key using the provided [`CryptoRngCore`]. #[cfg(feature = "rand_core")] #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] #[inline] - fn generate_key(mut rng: impl CryptoRng + RngCore) -> Key { + fn generate_key(mut rng: impl CryptoRngCore) -> Key { let mut key = Key::::default(); rng.fill_bytes(&mut key); key @@ -189,31 +189,31 @@ pub trait KeyIvInit: KeySizeUser + IvSizeUser + Sized { } } - /// Generate random key using the provided [`CryptoRng`]. + /// Generate random key using the provided [`CryptoRngCore`]. #[cfg(feature = "rand_core")] #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] #[inline] - fn generate_key(mut rng: impl CryptoRng + RngCore) -> Key { + fn generate_key(mut rng: impl CryptoRngCore) -> Key { let mut key = Key::::default(); rng.fill_bytes(&mut key); key } - /// Generate random IV using the provided [`CryptoRng`]. + /// Generate random IV using the provided [`CryptoRngCore`]. #[cfg(feature = "rand_core")] #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] #[inline] - fn generate_iv(mut rng: impl CryptoRng + RngCore) -> Iv { + fn generate_iv(mut rng: impl CryptoRngCore) -> Iv { let mut iv = Iv::::default(); rng.fill_bytes(&mut iv); iv } - /// Generate random key and nonce using the provided [`CryptoRng`]. + /// Generate random key and nonce using the provided [`CryptoRngCore`]. #[cfg(feature = "rand_core")] #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] #[inline] - fn generate_key_iv(mut rng: impl CryptoRng + RngCore) -> (Key, Iv) { + fn generate_key_iv(mut rng: impl CryptoRngCore) -> (Key, Iv) { (Self::generate_key(&mut rng), Self::generate_iv(&mut rng)) } } @@ -244,11 +244,11 @@ pub trait InnerIvInit: InnerUser + IvSizeUser + Sized { } } - /// Generate random IV using the provided [`CryptoRng`]. + /// Generate random IV using the provided [`CryptoRngCore`]. #[cfg(feature = "rand_core")] #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] #[inline] - fn generate_iv(mut rng: impl CryptoRng + RngCore) -> Iv { + fn generate_iv(mut rng: impl CryptoRngCore) -> Iv { let mut iv = Iv::::default(); rng.fill_bytes(&mut iv); iv From ad5540627467b5dff93a1ba42e5df408a89e2208 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Sun, 11 Jun 2023 23:27:37 +0300 Subject: [PATCH 1031/1461] digest: explicitly state that size is measured in bytes (#1321) --- digest/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/digest/src/lib.rs b/digest/src/lib.rs index fc82e2e3a..04ea98931 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -201,16 +201,16 @@ pub trait ExtendableOutputReset: ExtendableOutput + Reset { /// Trait for hash functions with variable-size output. pub trait VariableOutput: Sized + Update { - /// Maximum size of output hash. + /// Maximum size of output hash in bytes. const MAX_OUTPUT_SIZE: usize; - /// Create new hasher instance with the given output size. + /// Create new hasher instance with the given output size in bytes. /// /// It will return `Err(InvalidOutputSize)` in case if hasher can not return /// hash of the specified output size. fn new(output_size: usize) -> Result; - /// Get output size of the hasher instance provided to the `new` method + /// Get output size in bytes of the hasher instance provided to the `new` method fn output_size(&self) -> usize; /// Write result into the output buffer. From 805fd3186e9a6acde34c7a184d6c1e2f48ca8a2a Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 24 Jun 2023 07:30:35 -0600 Subject: [PATCH 1032/1461] elliptic-curve: use `sec1::EcPrivateKey::PEM_LABEL` (#1326) Instead of defining a separate constant for this, it can be obtained from the `EcPrivateKey` type, which impls the `PemLabel` trait. --- elliptic-curve/src/secret_key.rs | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index a8da65ccd..607589a75 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -20,8 +20,17 @@ use crate::{rand_core::CryptoRngCore, CurveArithmetic, NonZeroScalar, PublicKey} #[cfg(feature = "jwk")] use crate::jwk::{JwkEcKey, JwkParameters}; +#[cfg(feature = "pem")] +use pem_rfc7468::{self as pem, PemLabel}; + #[cfg(feature = "sec1")] -use sec1::der; +use { + crate::{ + sec1::{EncodedPoint, ModulusSize, ValidatePublicKey}, + FieldBytesSize, + }, + sec1::der, +}; #[cfg(all(feature = "alloc", feature = "arithmetic", feature = "sec1"))] use { @@ -40,22 +49,9 @@ use alloc::string::String; #[cfg(all(feature = "arithmetic", feature = "jwk"))] use alloc::string::ToString; -#[cfg(feature = "pem")] -use pem_rfc7468 as pem; - -#[cfg(feature = "sec1")] -use crate::{ - sec1::{EncodedPoint, ModulusSize, ValidatePublicKey}, - FieldBytesSize, -}; - #[cfg(all(doc, feature = "pkcs8"))] use {crate::pkcs8::DecodePrivateKey, core::str::FromStr}; -/// Type label for PEM-encoded SEC1 private keys. -#[cfg(feature = "pem")] -pub(crate) const SEC1_PEM_TYPE_LABEL: &str = "EC PRIVATE KEY"; - /// Elliptic curve secret keys. /// /// This type wraps a secret scalar value, helping to prevent accidental @@ -237,7 +233,7 @@ where { let (label, der_bytes) = pem::decode_vec(s.as_bytes()).map_err(|_| Error)?; - if label != SEC1_PEM_TYPE_LABEL { + if label != sec1::EcPrivateKey::PEM_LABEL { return Err(Error); } @@ -257,7 +253,9 @@ where { self.to_sec1_der() .ok() - .and_then(|der| pem::encode_string(SEC1_PEM_TYPE_LABEL, line_ending, &der).ok()) + .and_then(|der| { + pem::encode_string(sec1::EcPrivateKey::PEM_LABEL, line_ending, &der).ok() + }) .map(Zeroizing::new) .ok_or(Error) } From edeaafad94ba55f77204bf40027e62e496e19232 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Mon, 26 Jun 2023 16:18:48 +0300 Subject: [PATCH 1033/1461] Update Cargo.lock --- Cargo.lock | 110 ++++++++++++++++++++++++++--------------------------- 1 file changed, 55 insertions(+), 55 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3a2a5e3b4..138ddcb17 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,31 +4,31 @@ version = 3 [[package]] name = "aead" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c192eb8f11fc081b0fe4259ba5af04217d4e0faddd02417310a927911abd7c8" +version = "0.5.2" dependencies = [ + "arrayvec", + "blobby", + "bytes", "crypto-common 0.1.6", "generic-array", + "heapless", ] [[package]] name = "aead" version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" dependencies = [ - "arrayvec", - "blobby", - "bytes", "crypto-common 0.1.6", "generic-array", - "heapless", ] [[package]] name = "aes" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "433cfd6710c9986c576a25ca913c39d66a6474107b406f34f91d4a8923395241" +checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" dependencies = [ "cfg-if", "cipher 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -37,11 +37,11 @@ dependencies = [ [[package]] name = "aes-gcm" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e1366e0c69c9f927b1fa5ce2c7bf9eafc8f9268c0b9800729e8b267612447c" +checksum = "209b47e8954a928e1d72e86eca7000ebb6655fe1436d33eefc2201cad027e237" dependencies = [ - "aead 0.5.1", + "aead 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "aes", "cipher 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "ctr", @@ -51,9 +51,9 @@ dependencies = [ [[package]] name = "arrayvec" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "async-signature" @@ -197,7 +197,7 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" dependencies = [ - "aead 0.5.1", + "aead 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "chacha20", "cipher 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "poly1305", @@ -239,9 +239,9 @@ checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" [[package]] name = "cpufeatures" -version = "0.2.6" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "280a9f2d8b3a38871a3c8a46fb80db65e5e5ed97da80c4d08bf27fb63e35e181" +checksum = "03e69e28e9f7f77debdedbaafa2866e1de9ba56df55a8bd7cfc724c25a09987c" dependencies = [ "libc", ] @@ -309,9 +309,9 @@ dependencies = [ [[package]] name = "crypto-mac" -version = "0.11.1" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" +checksum = "25fab6889090c8133f3deb8f73ba3c65a7f456f66436fc012a1b1e272b1e103e" dependencies = [ "generic-array", "subtle", @@ -368,9 +368,9 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer 0.10.4", "crypto-common 0.1.6", @@ -390,9 +390,9 @@ dependencies = [ [[package]] name = "dunce" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bd4b30a6560bbd9b4620f4de34c3f14f60848e58a9b7216801afcb4c7b31c3c" +checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" [[package]] name = "ecdsa" @@ -431,7 +431,7 @@ dependencies = [ "base16ct", "crypto-bigint 0.4.9", "der 0.6.1", - "digest 0.10.6", + "digest 0.10.7", "ff 0.12.1", "generic-array", "group 0.12.1", @@ -474,9 +474,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.8" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", "libc", @@ -584,7 +584,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -593,17 +593,17 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf39e5461bfdc6ad0fbc97067519fcaf96a7a2e67f24cc0eb8a1e7c0c45af792" dependencies = [ - "aead 0.5.1", + "aead 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "aes-gcm", "byteorder", "chacha20poly1305", - "digest 0.10.6", + "digest 0.10.7", "generic-array", "hkdf 0.12.3", "hmac 0.12.1", "p256 0.11.1", "rand_core 0.6.4", - "sha2 0.10.6", + "sha2 0.10.7", "subtle", "x25519-dalek", "zeroize", @@ -645,15 +645,15 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.140" +version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] name = "lock_api" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" dependencies = [ "autocfg", "scopeguard", @@ -728,9 +728,9 @@ dependencies = [ [[package]] name = "polyval" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef234e08c11dfcb2e56f79fd70f6f2eb7f025c0ce2333e82f4f0518ecad30c6" +checksum = "d52cff9d1d4dee5fe6d03729099f4a310a41179e0a10dbf542039873f2e826fb" dependencies = [ "cfg-if", "cpufeatures", @@ -787,18 +787,18 @@ checksum = "97e91cb6af081c6daad5fa705f8adb0634c027662052cb3174bdf2957bf07e25" [[package]] name = "proc-macro2" -version = "1.0.55" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d0dd4be24fcdcfeaa12a432d588dc59bbad6cad3510c67e74a2b6b2fc950564" +checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.26" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" +checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" dependencies = [ "proc-macro2", ] @@ -875,9 +875,9 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" -version = "1.0.159" +version = "1.0.164" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c04e8343c3daeec41f58990b9d77068df31209f2af111e059e9fe9646693065" +checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" dependencies = [ "serde_derive", ] @@ -893,9 +893,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.159" +version = "1.0.164" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c614d17805b093df4b147b51339e7e44bf05ef59fba1e45d83500bcfb4d8585" +checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" dependencies = [ "proc-macro2", "quote", @@ -917,13 +917,13 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -940,10 +940,10 @@ dependencies = [ name = "signature" version = "2.1.0" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", "hex-literal", "rand_core 0.6.4", - "sha2 0.10.6", + "sha2 0.10.7", "signature_derive", ] @@ -982,15 +982,15 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "subtle" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "syn" -version = "2.0.13" +version = "2.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c9da457c5285ac1f936ebd076af6dac17a61cfe7826f2076b4d015cf47bc8ec" +checksum = "2efbeae7acf4eabd6bcdcbd11c92f45231ddda7539edc7806bd1a04a03b24616" dependencies = [ "proc-macro2", "quote", @@ -1005,9 +1005,9 @@ checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "unicode-ident" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" +checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" [[package]] name = "universal-hash" From b6206884e7b818916c1d2fc202130cef1e0686d2 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 27 Jun 2023 19:51:40 -0600 Subject: [PATCH 1034/1461] crypto v0.5.1 (#1329) --- crypto/CHANGELOG.md | 3 +++ crypto/Cargo.lock | 6 +++--- crypto/Cargo.toml | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/crypto/CHANGELOG.md b/crypto/CHANGELOG.md index e78f1d66e..55339b261 100644 --- a/crypto/CHANGELOG.md +++ b/crypto/CHANGELOG.md @@ -5,6 +5,9 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.5.1 (2023-05-27) +Unchanged from v0.5.0, but published to trigger a new docs.rs build. + ## 0.5.0 (2023-04-17) ### Changed - Bump `signature` to v2 ([#1211]) diff --git a/crypto/Cargo.lock b/crypto/Cargo.lock index 93f411d09..8fa3352f6 100644 --- a/crypto/Cargo.lock +++ b/crypto/Cargo.lock @@ -64,7 +64,7 @@ checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" [[package]] name = "crypto" -version = "0.5.0" +version = "0.5.1" dependencies = [ "aead", "cipher", @@ -122,7 +122,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.13.4" +version = "0.13.5" dependencies = [ "base16ct", "crypto-bigint", @@ -265,7 +265,7 @@ checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "universal-hash" -version = "0.5.0" +version = "0.5.1" dependencies = [ "crypto-common", "subtle", diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index e1e9ab1a7..ede350b70 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "crypto" -version = "0.5.0" +version = "0.5.1" description = "Facade crate for all of the RustCrypto traits (e.g. `aead`, `cipher`, `digest`)" authors = ["The RustCrypto Project Developers"] license = "Apache-2.0 OR MIT" From ac2e00dc5aaa147fb6692fae7f5b138794483dc7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 Jun 2023 16:42:15 -0600 Subject: [PATCH 1035/1461] build(deps): bump const-oid from 0.9.2 to 0.9.3 (#1331) Bumps [const-oid](https://github.com/RustCrypto/formats) from 0.9.2 to 0.9.3. - [Commits](https://github.com/RustCrypto/formats/compare/const-oid/v0.9.2...const-oid/v0.9.3) --- updated-dependencies: - dependency-name: const-oid dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 138ddcb17..7b08c5d7d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -233,9 +233,9 @@ checksum = "9d6f2aa4d0537bcc1c74df8755072bd31c1ef1a3a1b85a68e8404a8c353b7b8b" [[package]] name = "const-oid" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" +checksum = "6340df57935414636969091153f35f68d9f00bbc8fb4a9c6054706c213e6c6bc" [[package]] name = "cpufeatures" @@ -354,7 +354,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" dependencies = [ - "const-oid 0.9.2", + "const-oid 0.9.3", ] [[package]] @@ -383,7 +383,7 @@ version = "0.11.0-pre" dependencies = [ "blobby", "block-buffer 0.11.0-pre", - "const-oid 0.9.2", + "const-oid 0.9.3", "crypto-common 0.2.0-pre (registry+https://github.com/rust-lang/crates.io-index)", "subtle", ] From 962dabad2c0a316a018b0a1dcbc399aa9408ac9e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Jul 2023 16:17:31 -0600 Subject: [PATCH 1036/1461] build(deps): bump const-oid from 0.9.3 to 0.9.4 (#1333) Bumps [const-oid](https://github.com/RustCrypto/formats) from 0.9.3 to 0.9.4. - [Commits](https://github.com/RustCrypto/formats/compare/const-oid/v0.9.3...const-oid/v0.9.4) --- updated-dependencies: - dependency-name: const-oid dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7b08c5d7d..177af8d00 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -233,9 +233,9 @@ checksum = "9d6f2aa4d0537bcc1c74df8755072bd31c1ef1a3a1b85a68e8404a8c353b7b8b" [[package]] name = "const-oid" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6340df57935414636969091153f35f68d9f00bbc8fb4a9c6054706c213e6c6bc" +checksum = "795bc6e66a8e340f075fcf6227e417a2dc976b92b91f3cdc778bb858778b6747" [[package]] name = "cpufeatures" @@ -354,7 +354,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" dependencies = [ - "const-oid 0.9.3", + "const-oid 0.9.4", ] [[package]] @@ -383,7 +383,7 @@ version = "0.11.0-pre" dependencies = [ "blobby", "block-buffer 0.11.0-pre", - "const-oid 0.9.3", + "const-oid 0.9.4", "crypto-common 0.2.0-pre (registry+https://github.com/rust-lang/crates.io-index)", "subtle", ] From bd87a32d0eadf1d70c5e8024715029f687e6980d Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Mon, 7 Aug 2023 17:53:15 +0300 Subject: [PATCH 1037/1461] Update Clippy and fix lints (#1335) --- .github/workflows/workspace.yml | 2 +- cipher/src/lib.rs | 1 + kem/tests/hpke.rs | 2 +- password-hash/src/params.rs | 2 +- password-hash/tests/hashing.rs | 2 +- signature/tests/derive.rs | 4 +--- 6 files changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index bba6e00b7..60b98966f 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -26,7 +26,7 @@ jobs: - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: - toolchain: 1.60.0 + toolchain: 1.71.0 components: clippy - run: cargo clippy --all --all-features -- -D warnings diff --git a/cipher/src/lib.rs b/cipher/src/lib.rs index 87041c19a..87813d940 100644 --- a/cipher/src/lib.rs +++ b/cipher/src/lib.rs @@ -12,6 +12,7 @@ html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg" )] #![warn(missing_docs, rust_2018_idioms)] +#![allow(clippy::needless_lifetimes)] pub use crypto_common; pub use inout; diff --git a/kem/tests/hpke.rs b/kem/tests/hpke.rs index 0b5d07b3f..43df15cd2 100644 --- a/kem/tests/hpke.rs +++ b/kem/tests/hpke.rs @@ -32,7 +32,7 @@ impl EncappedKey for X25519EncappedKey { type SenderPublicKey = X25519PublicKey; fn from_bytes(bytes: &GenericArray) -> Result { - Ok(X25519EncappedKey(bytes.clone())) + Ok(X25519EncappedKey(*bytes)) } } impl AsRef<[u8]> for X25519EncappedKey { diff --git a/password-hash/src/params.rs b/password-hash/src/params.rs index d0524e9f5..68648777e 100644 --- a/password-hash/src/params.rs +++ b/password-hash/src/params.rs @@ -362,7 +362,7 @@ mod tests { let mut params = ParamsString::new(); params.add_decimal(name, 1).unwrap(); - let err = params.add_decimal(name, 2u32.into()).err().unwrap(); + let err = params.add_decimal(name, 2u32).err().unwrap(); assert_eq!(err, Error::ParamNameDuplicated); } diff --git a/password-hash/tests/hashing.rs b/password-hash/tests/hashing.rs index ccb587324..7c53a72fc 100644 --- a/password-hash/tests/hashing.rs +++ b/password-hash/tests/hashing.rs @@ -57,7 +57,7 @@ impl<'a> TryFrom<&PasswordHash<'a>> for StubParams { } } -impl<'a> TryFrom for ParamsString { +impl TryFrom for ParamsString { type Error = Error; fn try_from(_: StubParams) -> Result { diff --git a/signature/tests/derive.rs b/signature/tests/derive.rs index 70e2dc0fc..e76408afd 100644 --- a/signature/tests/derive.rs +++ b/signature/tests/derive.rs @@ -35,9 +35,7 @@ impl TryFrom<&[u8]> for DummySignature { type Error = Error; fn try_from(bytes: &[u8]) -> Result { - Ok(DummySignature(GenericArray::clone_from_slice( - bytes.as_ref(), - ))) + Ok(DummySignature(GenericArray::clone_from_slice(bytes))) } } From eb8e409d81b7708a9ed18304c9102b5165fe4c7a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Aug 2023 17:58:06 -0600 Subject: [PATCH 1038/1461] build(deps): bump const-oid from 0.9.4 to 0.9.5 (#1337) Bumps [const-oid](https://github.com/RustCrypto/formats) from 0.9.4 to 0.9.5. - [Commits](https://github.com/RustCrypto/formats/compare/const-oid/v0.9.4...const-oid/v0.9.5) --- updated-dependencies: - dependency-name: const-oid dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 177af8d00..c75684544 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -233,9 +233,9 @@ checksum = "9d6f2aa4d0537bcc1c74df8755072bd31c1ef1a3a1b85a68e8404a8c353b7b8b" [[package]] name = "const-oid" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "795bc6e66a8e340f075fcf6227e417a2dc976b92b91f3cdc778bb858778b6747" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" [[package]] name = "cpufeatures" @@ -354,7 +354,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" dependencies = [ - "const-oid 0.9.4", + "const-oid 0.9.5", ] [[package]] @@ -383,7 +383,7 @@ version = "0.11.0-pre" dependencies = [ "blobby", "block-buffer 0.11.0-pre", - "const-oid 0.9.4", + "const-oid 0.9.5", "crypto-common 0.2.0-pre (registry+https://github.com/rust-lang/crates.io-index)", "subtle", ] From 38c0ff9af8c6c85507553a25df31cd7c3c2e9d76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Kj=C3=A4ll?= Date: Tue, 22 Aug 2023 17:26:09 +0200 Subject: [PATCH 1039/1461] the derive.rs tests also depends on the digest feature (#1339) --- signature/tests/derive.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/signature/tests/derive.rs b/signature/tests/derive.rs index e76408afd..b54eec823 100644 --- a/signature/tests/derive.rs +++ b/signature/tests/derive.rs @@ -1,6 +1,6 @@ //! Tests for code generated by `signature_derive` -#![cfg(feature = "derive")] +#![cfg(all(feature = "derive", feature = "digest"))] use digest::{generic_array::GenericArray, Digest, OutputSizeUser}; use hex_literal::hex; From ecaf2432422ff8300c1430b30cba7502c04efcd7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Sep 2023 17:08:02 -0600 Subject: [PATCH 1040/1461] build(deps): bump actions/checkout from 3 to 4 (#1343) Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/aead.yml | 4 ++-- .github/workflows/async-signature.yml | 4 ++-- .github/workflows/cipher.yml | 6 +++--- .github/workflows/crypto-common.yml | 4 ++-- .github/workflows/crypto.yml | 8 ++++---- .github/workflows/digest.yml | 4 ++-- .github/workflows/elliptic-curve.yml | 8 ++++---- .github/workflows/kem.yml | 6 +++--- .github/workflows/password-hash.yml | 6 +++--- .github/workflows/security-audit.yml | 10 +++++----- .github/workflows/signature.yml | 8 ++++---- .github/workflows/universal-hash.yml | 4 ++-- .github/workflows/workspace.yml | 4 ++-- 13 files changed, 38 insertions(+), 38 deletions(-) diff --git a/.github/workflows/aead.yml b/.github/workflows/aead.yml index e697614bc..409b6bd58 100644 --- a/.github/workflows/aead.yml +++ b/.github/workflows/aead.yml @@ -28,7 +28,7 @@ jobs: - thumbv7em-none-eabi - wasm32-unknown-unknown steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: @@ -55,7 +55,7 @@ jobs: - 1.56.0 # MSRV - stable steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: diff --git a/.github/workflows/async-signature.yml b/.github/workflows/async-signature.yml index d75c4e679..4ae365481 100644 --- a/.github/workflows/async-signature.yml +++ b/.github/workflows/async-signature.yml @@ -25,7 +25,7 @@ jobs: - 1.56.0 # MSRV - stable steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: @@ -37,7 +37,7 @@ jobs: minimal-versions: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: diff --git a/.github/workflows/cipher.yml b/.github/workflows/cipher.yml index 28ae4e6ec..4601f517a 100644 --- a/.github/workflows/cipher.yml +++ b/.github/workflows/cipher.yml @@ -28,7 +28,7 @@ jobs: - thumbv7em-none-eabi - wasm32-unknown-unknown steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: @@ -43,7 +43,7 @@ jobs: minimal-versions: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: @@ -60,7 +60,7 @@ jobs: - 1.56.0 # MSRV - stable steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: diff --git a/.github/workflows/crypto-common.yml b/.github/workflows/crypto-common.yml index e761daa9b..67316ed6e 100644 --- a/.github/workflows/crypto-common.yml +++ b/.github/workflows/crypto-common.yml @@ -28,7 +28,7 @@ jobs: - thumbv7em-none-eabi - wasm32-unknown-unknown steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: @@ -49,7 +49,7 @@ jobs: - 1.56.0 # MSRV - stable steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: diff --git a/.github/workflows/crypto.yml b/.github/workflows/crypto.yml index cab9c5da6..c0294947a 100644 --- a/.github/workflows/crypto.yml +++ b/.github/workflows/crypto.yml @@ -28,7 +28,7 @@ jobs: - thumbv7em-none-eabi - wasm32-unknown-unknown steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: @@ -41,7 +41,7 @@ jobs: minimal-versions: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: @@ -58,7 +58,7 @@ jobs: - 1.65.0 # MSRV - stable steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: @@ -71,7 +71,7 @@ jobs: clippy: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: diff --git a/.github/workflows/digest.yml b/.github/workflows/digest.yml index 2a91753d9..7338e8843 100644 --- a/.github/workflows/digest.yml +++ b/.github/workflows/digest.yml @@ -28,7 +28,7 @@ jobs: - thumbv7em-none-eabi - wasm32-unknown-unknown steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: @@ -51,7 +51,7 @@ jobs: - 1.57.0 # MSRV - stable steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index 31b2f148a..f1179b204 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -30,7 +30,7 @@ jobs: - thumbv7em-none-eabi - wasm32-unknown-unknown steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: @@ -62,7 +62,7 @@ jobs: # minimal-versions: # runs-on: ubuntu-latest # steps: - # - uses: actions/checkout@v3 + # - uses: actions/checkout@v4 # - uses: RustCrypto/actions/cargo-cache@master # - uses: dtolnay/rust-toolchain@master # with: @@ -80,7 +80,7 @@ jobs: - stable - nightly steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: @@ -93,7 +93,7 @@ jobs: doc: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master with: toolchain: stable diff --git a/.github/workflows/kem.yml b/.github/workflows/kem.yml index a2204bc23..be3c7dcbc 100644 --- a/.github/workflows/kem.yml +++ b/.github/workflows/kem.yml @@ -28,7 +28,7 @@ jobs: - thumbv7em-none-eabi - wasm32-unknown-unknown steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: @@ -41,7 +41,7 @@ jobs: # minimal-versions: # runs-on: ubuntu-latest # steps: - # - uses: actions/checkout@v3 + # - uses: actions/checkout@v4 # - uses: RustCrypto/actions/cargo-cache@master # - uses: dtolnay/rust-toolchain@master # with: @@ -58,7 +58,7 @@ jobs: - 1.60.0 # Next MSRV candidate - stable steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: diff --git a/.github/workflows/password-hash.yml b/.github/workflows/password-hash.yml index c49d00322..2a732455f 100644 --- a/.github/workflows/password-hash.yml +++ b/.github/workflows/password-hash.yml @@ -28,7 +28,7 @@ jobs: - thumbv7em-none-eabi - wasm32-unknown-unknown steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: @@ -43,7 +43,7 @@ jobs: minimal-versions: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: @@ -60,7 +60,7 @@ jobs: - 1.60.0 # MSRV - stable steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: diff --git a/.github/workflows/security-audit.yml b/.github/workflows/security-audit.yml index 64ce9c73a..8dd60ff37 100644 --- a/.github/workflows/security-audit.yml +++ b/.github/workflows/security-audit.yml @@ -13,7 +13,7 @@ jobs: name: Security Audit Workspace runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Cache cargo bin uses: actions/cache@v3 with: @@ -30,7 +30,7 @@ jobs: run: working-directory: crypto steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Cache cargo bin uses: actions/cache@v3 with: @@ -47,7 +47,7 @@ jobs: run: working-directory: elliptic-curve steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Cache cargo bin uses: actions/cache@v3 with: @@ -64,7 +64,7 @@ jobs: run: working-directory: kem steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Cache cargo bin uses: actions/cache@v3 with: @@ -81,7 +81,7 @@ jobs: run: working-directory: password-hash steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Cache cargo bin uses: actions/cache@v3 with: diff --git a/.github/workflows/signature.yml b/.github/workflows/signature.yml index c8801008a..4816bd0e8 100644 --- a/.github/workflows/signature.yml +++ b/.github/workflows/signature.yml @@ -29,7 +29,7 @@ jobs: - thumbv7em-none-eabi - wasm32-unknown-unknown steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: @@ -54,7 +54,7 @@ jobs: - 1.56.0 # MSRV - stable steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: @@ -72,7 +72,7 @@ jobs: - 1.56.0 # MSRV - stable steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: @@ -83,7 +83,7 @@ jobs: doc: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master with: toolchain: stable diff --git a/.github/workflows/universal-hash.yml b/.github/workflows/universal-hash.yml index 7bb64fcce..c87c3909c 100644 --- a/.github/workflows/universal-hash.yml +++ b/.github/workflows/universal-hash.yml @@ -28,7 +28,7 @@ jobs: - thumbv7em-none-eabi - wasm32-unknown-unknown steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: @@ -51,7 +51,7 @@ jobs: - 1.56.0 # MSRV - stable steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index 60b98966f..b70dad454 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -22,7 +22,7 @@ jobs: clippy: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: @@ -33,7 +33,7 @@ jobs: rustfmt: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master with: toolchain: stable From 94f57bb051552d114146dd2e8d00fdb42e2d7b34 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 Sep 2023 10:33:35 -0600 Subject: [PATCH 1041/1461] build(deps): bump aes-gcm from 0.10.2 to 0.10.3 (#1347) Bumps [aes-gcm](https://github.com/RustCrypto/AEADs) from 0.10.2 to 0.10.3. - [Commits](https://github.com/RustCrypto/AEADs/compare/aes-gcm-v0.10.2...aes-gcm-v0.10.3) --- updated-dependencies: - dependency-name: aes-gcm dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c75684544..334ee810d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -37,9 +37,9 @@ dependencies = [ [[package]] name = "aes-gcm" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "209b47e8954a928e1d72e86eca7000ebb6655fe1436d33eefc2201cad027e237" +checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" dependencies = [ "aead 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "aes", From e1bdc05cae0f921fbbde484d25461ce3aeb612fc Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Fri, 22 Sep 2023 20:09:57 +0300 Subject: [PATCH 1042/1461] cipher: mark set_pos_unchecked private method as unsafe (#1346) --- cipher/src/stream_wrapper.rs | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/cipher/src/stream_wrapper.rs b/cipher/src/stream_wrapper.rs index e3495bc14..fb128389f 100644 --- a/cipher/src/stream_wrapper.rs +++ b/cipher/src/stream_wrapper.rs @@ -64,8 +64,13 @@ where T::BlockSize::USIZE } + /// Set buffer position without checking that it's smaller + /// than buffer size. + /// + /// # Safety + /// `pos` MUST be smaller than `T::BlockSize::USIZE`. #[inline] - fn set_pos_unchecked(&mut self, pos: usize) { + unsafe fn set_pos_unchecked(&mut self, pos: usize) { debug_assert!(pos < T::BlockSize::USIZE); self.pos = pos as u8; } @@ -124,7 +129,13 @@ where let n = data.len(); if n < rem.len() { data.xor_in2out(&rem[..n]); - self.set_pos_unchecked(pos + n); + // SAFETY: we have checked that `n` is less than length of `rem`, + // which is equal to buffer length minus `pos`, thus `pos + n` is + // less than buffer length and satisfies the `set_pos_unchecked` + // safety condition + unsafe { + self.set_pos_unchecked(pos + n); + } return Ok(()); } let (mut left, right) = data.split_at(rem.len()); @@ -140,7 +151,12 @@ where self.core.write_keystream_block(&mut self.buffer); leftover.xor_in2out(&self.buffer[..n]); } - self.set_pos_unchecked(n); + // SAFETY: `into_chunks` always returns tail with size + // less than buffer length, thus `n` satisfies the `set_pos_unchecked` + // safety condition + unsafe { + self.set_pos_unchecked(n); + } Ok(()) } From 446f912b5ea34ccda100cb2ec1d7b89916c23820 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Wed, 27 Sep 2023 01:14:56 +0300 Subject: [PATCH 1043/1461] Update Cargo.lock --- Cargo.lock | 77 +++++++++++++++++++++++++++--------------------------- 1 file changed, 39 insertions(+), 38 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 334ee810d..226889202 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -65,9 +65,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.68" +version = "0.1.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" +checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", @@ -161,17 +161,18 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "cc" -version = "1.0.79" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" dependencies = [ "jobserver", + "libc", ] [[package]] @@ -239,18 +240,18 @@ checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" [[package]] name = "cpufeatures" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03e69e28e9f7f77debdedbaafa2866e1de9ba56df55a8bd7cfc724c25a09987c" +checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" dependencies = [ "libc", ] [[package]] name = "critical-section" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6548a0ad5d2549e111e1f6a11a6c2e2d00ce6a3dafe22948d67c2b443f775e52" +checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216" [[package]] name = "crypto-bigint" @@ -603,7 +604,7 @@ dependencies = [ "hmac 0.12.1", "p256 0.11.1", "rand_core 0.6.4", - "sha2 0.10.7", + "sha2 0.10.8", "subtle", "x25519-dalek", "zeroize", @@ -645,9 +646,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.147" +version = "0.2.148" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" +checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" [[package]] name = "lock_api" @@ -756,9 +757,9 @@ dependencies = [ [[package]] name = "pqcrypto-internals" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0127cbc0239f585139a56effd7867921eae3425a000a72dde2b0a156062346b2" +checksum = "d9d34bec6abe2283e6de7748b68b292d1ffa2203397e3e71380ff8418a49fb46" dependencies = [ "cc", "dunce", @@ -787,18 +788,18 @@ checksum = "97e91cb6af081c6daad5fa705f8adb0634c027662052cb3174bdf2957bf07e25" [[package]] name = "proc-macro2" -version = "1.0.63" +version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb" +checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.28" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] @@ -850,9 +851,9 @@ dependencies = [ [[package]] name = "scopeguard" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sec1" @@ -869,33 +870,33 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.17" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" +checksum = "ad977052201c6de01a8ef2aa3378c4bd23217a056337d1d6da40468d267a4fb0" [[package]] name = "serde" -version = "1.0.164" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" dependencies = [ "serde_derive", ] [[package]] name = "serde_bytes" -version = "0.11.9" +version = "0.11.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "416bda436f9aab92e02c8e10d49a15ddd339cea90b6e340fe51ed97abb548294" +checksum = "ab33ec92f677585af6d88c65593ae2375adde54efdbf16d597f2cbc7a6d368ff" dependencies = [ "serde", ] [[package]] name = "serde_derive" -version = "1.0.164" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", @@ -917,9 +918,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.7" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", @@ -943,7 +944,7 @@ dependencies = [ "digest 0.10.7", "hex-literal", "rand_core 0.6.4", - "sha2 0.10.7", + "sha2 0.10.8", "signature_derive", ] @@ -988,9 +989,9 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "syn" -version = "2.0.22" +version = "2.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2efbeae7acf4eabd6bcdcbd11c92f45231ddda7539edc7806bd1a04a03b24616" +checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" dependencies = [ "proc-macro2", "quote", @@ -999,15 +1000,15 @@ dependencies = [ [[package]] name = "typenum" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "unicode-ident" -version = "1.0.9" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "universal-hash" From 1f9f72fe8e692ab325f8254eb0f31a1fbf72a6e1 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Thu, 28 Sep 2023 00:57:30 +0300 Subject: [PATCH 1044/1461] kem: fix MSRV tests in CI (#1349) --- .github/workflows/kem.yml | 16 ++++++++++++++-- README.md | 2 +- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/.github/workflows/kem.yml b/.github/workflows/kem.yml index be3c7dcbc..8f70e5644 100644 --- a/.github/workflows/kem.yml +++ b/.github/workflows/kem.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.60.0 # Next MSRV candidate + - 1.61.0 # Next MSRV candidate - stable target: - thumbv7em-none-eabi @@ -55,7 +55,7 @@ jobs: strategy: matrix: rust: - - 1.60.0 # Next MSRV candidate + - 1.61.0 # Next MSRV candidate - stable steps: - uses: actions/checkout@v4 @@ -67,3 +67,15 @@ jobs: - run: cargo test --no-default-features --release - run: cargo test --release - run: cargo test --all-features --release + + # build-only test of MSRV + # TODO: remove on MSRV bump higher than MSRV of `cc` + test-msrv: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: RustCrypto/actions/cargo-cache@master + - uses: dtolnay/rust-toolchain@master + with: + toolchain: 1.60.0 + - run: cargo check --all-features diff --git a/README.md b/README.md index a83f72662..39f486ac5 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ Collection of traits which describe functionality of cryptographic primitives. | [`crypto‑common`] | Common cryptographic traits | [![crates.io](https://img.shields.io/crates/v/crypto-common.svg)](https://crates.io/crates/crypto-common) | [![Documentation](https://docs.rs/crypto-common/badge.svg)](https://docs.rs/crypto-common) | ![MSRV 1.56][msrv-1.56] | | [`digest`] | [Cryptographic hash function] | [![crates.io](https://img.shields.io/crates/v/digest.svg)](https://crates.io/crates/digest) | [![Documentation](https://docs.rs/digest/badge.svg)](https://docs.rs/digest) | ![MSRV 1.57][msrv-1.57] | | [`elliptic‑curve`] | [Elliptic curve cryptography] | [![crates.io](https://img.shields.io/crates/v/elliptic-curve.svg)](https://crates.io/crates/elliptic-curve) | [![Documentation](https://docs.rs/elliptic-curve/badge.svg)](https://docs.rs/elliptic-curve) | ![MSRV 1.65][msrv-1.65] | -| [`kem`] | [Key encapsulation mechanism] | [![crates.io](https://img.shields.io/crates/v/kem.svg)](https://crates.io/crates/kem) | [![Documentation](https://docs.rs/kem/badge.svg)](https://docs.rs/kem) | ![MSRV 1.56][msrv-1.56] | +| [`kem`] | [Key encapsulation mechanism] | [![crates.io](https://img.shields.io/crates/v/kem.svg)](https://crates.io/crates/kem) | [![Documentation](https://docs.rs/kem/badge.svg)](https://docs.rs/kem) | ![MSRV 1.60][msrv-1.60] | | [`password-hash`] | [Password hashing] | [![crates.io](https://img.shields.io/crates/v/password-hash.svg)](https://crates.io/crates/password-hash) | [![Documentation](https://docs.rs/password-hash/badge.svg)](https://docs.rs/password-hash) | ![MSRV 1.60][msrv-1.60] | | [`signature`] | [Digital signature] | [![crates.io](https://img.shields.io/crates/v/signature.svg)](https://crates.io/crates/signature) | [![Documentation](https://docs.rs/signature/badge.svg)](https://docs.rs/signature) | ![MSRV 1.56][msrv-1.56] | | [`universal‑hash`] | [Universal hash function] | [![crates.io](https://img.shields.io/crates/v/universal-hash.svg)](https://crates.io/crates/universal-hash) | [![Documentation](https://docs.rs/universal-hash/badge.svg)](https://docs.rs/universal-hash) | ![MSRV 1.56][msrv-1.56] | From 2c68560944f29123ade4d1e6fa6da5ecaeb35ff1 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 2 Oct 2023 09:40:17 -0600 Subject: [PATCH 1045/1461] elliptic-curve: fix `hkdf` version requirement and test in CI (#1353) The minimal supported version of `hkdf` is v0.12.1, which added a generic parameter with a default which selects the backend. This also (mostly) re-enables a `minimal-versions` check in CI, although it still doesn't quite test all features. --- .github/workflows/elliptic-curve.yml | 24 +++++++++++------------- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index f1179b204..f318c244b 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -57,19 +57,17 @@ jobs: - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features arithmetic,serde - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,digest,ecdh,hazmat,hash2curve,jwk,pem,pkcs8,sec1,serde,voprf - # TODO: use the reusable workflow after this crate is re-added to the - # toplevel workspace - # minimal-versions: - # runs-on: ubuntu-latest - # steps: - # - uses: actions/checkout@v4 - # - uses: RustCrypto/actions/cargo-cache@master - # - uses: dtolnay/rust-toolchain@master - # with: - # toolchain: nightly - # - uses: RustCrypto/actions/cargo-hack-install@master - # - run: cargo update -Z minimal-versions - # - run: cargo hack test --release --feature-powerset + minimal-versions: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: RustCrypto/actions/cargo-cache@master + - uses: dtolnay/rust-toolchain@master + with: + toolchain: nightly + - uses: RustCrypto/actions/cargo-hack-install@master + - run: cargo update -Z minimal-versions + - run: cargo build --release --features ecdh,hash2curve,pem,std,voprf # TODO(tarcieri): test all features test: runs-on: ubuntu-latest diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 825ad51b9..25e816aa7 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -28,7 +28,7 @@ base64ct = { version = "1", optional = true, default-features = false, features digest = { version = "0.10", optional = true } ff = { version = "0.13", optional = true, default-features = false } group = { version = "0.13", optional = true, default-features = false } -hkdf = { version = "0.12", optional = true, default-features = false } +hkdf = { version = "0.12.1", optional = true, default-features = false } hex-literal = { version = "0.4", optional = true } pem-rfc7468 = { version = "0.7", optional = true, features = ["alloc"] } pkcs8 = { version = "0.10.2", optional = true, default-features = false } From 0c7cb34755d54ccd3ff220feaffbbb1878f5b18e Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 2 Oct 2023 09:59:26 -0600 Subject: [PATCH 1046/1461] elliptic-curve: minimum supported `serde_json` is v1.0.47 (#1354) ...when resolving with `-Z minimal-versions` This appears to be due to earlier versions of `serde_json` itself misspecifying its required `serde` version. --- .github/workflows/elliptic-curve.yml | 2 +- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index f318c244b..53a2994d1 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -67,7 +67,7 @@ jobs: toolchain: nightly - uses: RustCrypto/actions/cargo-hack-install@master - run: cargo update -Z minimal-versions - - run: cargo build --release --features ecdh,hash2curve,pem,std,voprf # TODO(tarcieri): test all features + - run: cargo build --release --features ecdh,hash2curve,jwk,pem,std,voprf # TODO(tarcieri): test all features test: runs-on: ubuntu-latest diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 25e816aa7..dc71b368b 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -34,7 +34,7 @@ pem-rfc7468 = { version = "0.7", optional = true, features = ["alloc"] } pkcs8 = { version = "0.10.2", optional = true, default-features = false } sec1 = { version = "0.7.1", optional = true, features = ["subtle", "zeroize"] } serdect = { version = "0.2", optional = true, default-features = false, features = ["alloc"] } -serde_json = { version = "1", optional = true, default-features = false, features = ["alloc"] } +serde_json = { version = "1.0.47", optional = true, default-features = false, features = ["alloc"] } [dev-dependencies] hex-literal = "0.4" From bed2d467dce91425e8cd29a382a4f06c8fa30e61 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 2 Oct 2023 10:14:54 -0600 Subject: [PATCH 1047/1461] elliptic-curve: minimum supported `tap` for `bits` is v1.0.1 (#1355) ...when resolving with `-Z minimal-versions` `tap` is a transitive dependency of `bitvec` by way of `wyz` v0.5, which misspecifies the required `tap` version. This is addressed in newer v0.6 releases of `wyz`, which `bitvec` does not yet use. So, as a workaround, this adds an explicit `dep:tap` dependency on v1.0.1 for the `bits` feature. This was the last remaining `minimal-versions` incompatibility in this crate, allowing all features to now be tested in the `minimal-versions` check in CI. --- .github/workflows/elliptic-curve.yml | 2 +- elliptic-curve/Cargo.lock | 1 + elliptic-curve/Cargo.toml | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index 53a2994d1..b99fddd5a 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -67,7 +67,7 @@ jobs: toolchain: nightly - uses: RustCrypto/actions/cargo-hack-install@master - run: cargo update -Z minimal-versions - - run: cargo build --release --features ecdh,hash2curve,jwk,pem,std,voprf # TODO(tarcieri): test all features + - run: cargo +stable build --release --all-features test: runs-on: ubuntu-latest diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index cdca21f9b..683b8ddfa 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -122,6 +122,7 @@ dependencies = [ "sha2", "sha3", "subtle", + "tap", "zeroize", ] diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index dc71b368b..84ded370b 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -35,6 +35,7 @@ pkcs8 = { version = "0.10.2", optional = true, default-features = false } sec1 = { version = "0.7.1", optional = true, features = ["subtle", "zeroize"] } serdect = { version = "0.2", optional = true, default-features = false, features = ["alloc"] } serde_json = { version = "1.0.47", optional = true, default-features = false, features = ["alloc"] } +tap = { version = "1.0.1", optional = true, default-features = false } # hack for minimal-versions support for `bits` [dev-dependencies] hex-literal = "0.4" @@ -59,7 +60,7 @@ std = [ ] arithmetic = ["group"] -bits = ["arithmetic", "ff/bits"] +bits = ["arithmetic", "ff/bits", "dep:tap"] dev = ["arithmetic", "dep:hex-literal", "pem", "pkcs8"] hash2curve = ["arithmetic", "digest"] ecdh = ["arithmetic", "digest", "dep:hkdf"] From aa21684383d524fb9604a13245a01e2f0f3482b1 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 2 Oct 2023 11:54:27 -0600 Subject: [PATCH 1048/1461] elliptic-curve v0.13.6 (#1356) --- elliptic-curve/CHANGELOG.md | 10 ++++++++++ elliptic-curve/Cargo.lock | 2 +- elliptic-curve/Cargo.toml | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index 62b62eb09..1e5a5529e 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.13.6 (2023-10-02) +### Fixed +- Minimum supported `hkdf` version is v0.12.1 ([#1353]) +- Minimum supported `serde_json` version for `jwk` feature is v1.0.47 ([#1354]) +- Minimum supported `tap` version for `bits` feature is v1.0.1 ([#1355]) + +[#1353]: https://github.com/RustCrypto/traits/pull/1353 +[#1354]: https://github.com/RustCrypto/traits/pull/1354 +[#1355]: https://github.com/RustCrypto/traits/pull/1355 + ## 0.13.5 (2023-05-19) ### Changed - Faster `PublicKey::from_encoded_point` ([#1310]) diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index 683b8ddfa..827b3abe9 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -102,7 +102,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.13.5" +version = "0.13.6" dependencies = [ "base16ct", "base64ct", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 84ded370b..c6cc181fa 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.13.5" +version = "0.13.6" description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, From 5011178822f20c7c03a527265a5a890ecd0534b1 Mon Sep 17 00:00:00 2001 From: Ryan Lee Date: Tue, 3 Oct 2023 06:43:12 -0700 Subject: [PATCH 1049/1461] Fix minor documentation error in AeadCore::TagSize (#1351) The documentation originally described TagSize as "the maximum length of the nonce" when it is, in fact, the maximum length of the tag. --- aead/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aead/src/lib.rs b/aead/src/lib.rs index c5856a072..700667998 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -104,7 +104,7 @@ pub trait AeadCore { /// The length of a nonce. type NonceSize: ArrayLength; - /// The maximum length of the nonce. + /// The maximum length of the tag. type TagSize: ArrayLength; /// The upper bound amount of additional space required to support a From 2837040e225b568f2d2f27bc0ce4c92e21b101de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Fri, 20 Oct 2023 23:34:28 +0300 Subject: [PATCH 1050/1461] Update Cargo.lock --- Cargo.lock | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 226889202..0774b8154 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -65,9 +65,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.73" +version = "0.1.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" +checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" dependencies = [ "proc-macro2", "quote", @@ -155,9 +155,9 @@ dependencies = [ [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" @@ -240,9 +240,9 @@ checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" [[package]] name = "cpufeatures" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +checksum = "3fbc60abd742b35f2492f808e1abbb83d45f72db402e14c55057edc9c7b1e9e4" dependencies = [ "libc", ] @@ -622,9 +622,9 @@ dependencies = [ [[package]] name = "jobserver" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" +checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" dependencies = [ "libc", ] @@ -646,15 +646,15 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.148" +version = "0.2.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" +checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" [[package]] name = "lock_api" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ "autocfg", "scopeguard", @@ -782,15 +782,15 @@ dependencies = [ [[package]] name = "pqcrypto-traits" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97e91cb6af081c6daad5fa705f8adb0634c027662052cb3174bdf2957bf07e25" +checksum = "94e851c7654eed9e68d7d27164c454961a616cf8c203d500607ef22c737b51bb" [[package]] name = "proc-macro2" -version = "1.0.67" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" dependencies = [ "unicode-ident", ] @@ -870,15 +870,15 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.19" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad977052201c6de01a8ef2aa3378c4bd23217a056337d1d6da40468d267a4fb0" +checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" [[package]] name = "serde" -version = "1.0.188" +version = "1.0.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +checksum = "8e422a44e74ad4001bdc8eede9a4570ab52f71190e9c076d14369f38b9200537" dependencies = [ "serde_derive", ] @@ -894,9 +894,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.188" +version = "1.0.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" dependencies = [ "proc-macro2", "quote", @@ -989,9 +989,9 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "syn" -version = "2.0.37" +version = "2.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" +checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" dependencies = [ "proc-macro2", "quote", From fa5fde576bd079b8de0a76b0be71d2d45df7c7d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Sun, 22 Oct 2023 09:20:28 +0300 Subject: [PATCH 1051/1461] Downgrade byteorder and jobserver to work around CI failure --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0774b8154..f878923e3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -155,9 +155,9 @@ dependencies = [ [[package]] name = "byteorder" -version = "1.5.0" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" @@ -622,9 +622,9 @@ dependencies = [ [[package]] name = "jobserver" -version = "0.1.27" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" +checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" dependencies = [ "libc", ] From 81ab91b43b63a14c5c43955b9fbe926d8a6e7f51 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 26 Oct 2023 08:47:25 -0600 Subject: [PATCH 1052/1461] cipher: test `minimal-versions` on stable in CI (#1366) I suspect a nightly regression is responsible for this build failure: https://github.com/RustCrypto/traits/actions/runs/6648272740/job/18065054230?pr=1319 --- .github/workflows/cipher.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/cipher.yml b/.github/workflows/cipher.yml index 4601f517a..0897add5c 100644 --- a/.github/workflows/cipher.yml +++ b/.github/workflows/cipher.yml @@ -3,6 +3,7 @@ name: cipher on: pull_request: paths: + - ".github/workflows/cipher.yml" - "cipher/**" - "Cargo.*" push: @@ -39,17 +40,16 @@ jobs: - run: cargo build --target ${{ matrix.target }} --features block-padding # TODO: use the reusable workflow after this crate will be part of the - # toot workspace + # root workspace minimal-versions: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: RustCrypto/actions/cargo-cache@master - - uses: dtolnay/rust-toolchain@master - with: - toolchain: nightly + - uses: dtolnay/rust-toolchain@nightly - uses: RustCrypto/actions/cargo-hack-install@master - run: cargo update -Z minimal-versions + - uses: dtolnay/rust-toolchain@stable - run: cargo hack test --release --feature-powerset test: From 766c138c2671329bc7bd89a40981027659b016c9 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 26 Oct 2023 11:19:15 -0600 Subject: [PATCH 1053/1461] crypto-common: migrate to `hybrid-array`; MSRV 1.65 (#1319) Replaces `generic-array` with `hybrid-array`, which is built on a combination of `typenum` and const generics, providing a degree of interoperability between the two systems. `hybrid-array` is designed to be a largely drop-in replacement, and the number of changes required to switch are relatively minimal aside from some idiosyncrasies. --- .github/workflows/crypto-common.yml | 4 +- Cargo.lock | 12 +++++- crypto-common/Cargo.toml | 3 +- crypto-common/README.md | 6 +-- crypto-common/src/lib.rs | 62 ++++++++++++----------------- 5 files changed, 41 insertions(+), 46 deletions(-) diff --git a/.github/workflows/crypto-common.yml b/.github/workflows/crypto-common.yml index 67316ed6e..efb87ad46 100644 --- a/.github/workflows/crypto-common.yml +++ b/.github/workflows/crypto-common.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.65.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -46,7 +46,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.65.0 # MSRV - stable steps: - uses: actions/checkout@v4 diff --git a/Cargo.lock b/Cargo.lock index f878923e3..68a79738e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -292,9 +292,8 @@ dependencies = [ name = "crypto-common" version = "0.2.0-pre" dependencies = [ - "generic-array", + "hybrid-array", "rand_core 0.6.4", - "typenum", ] [[package]] @@ -610,6 +609,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "hybrid-array" +version = "0.2.0-pre.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "431615b6a66a159a76ac38f4b0bcbd5999433d08425d79e152438e3ab9f1013c" +dependencies = [ + "typenum", +] + [[package]] name = "inout" version = "0.1.3" diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index 63fca3de6..beb671fa4 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -13,8 +13,7 @@ keywords = ["crypto", "traits"] categories = ["cryptography", "no-std"] [dependencies] -generic-array = { version = "0.14.6", features = ["more_lengths"] } -typenum = "1.14" # earlier versions of typenum don't satisfy the 'static bound on U* types +hybrid-array = "=0.2.0-pre.5" # optional dependencies rand_core = { version = "0.6.4", optional = true } diff --git a/crypto-common/README.md b/crypto-common/README.md index ba35578f8..21008623a 100644 --- a/crypto-common/README.md +++ b/crypto-common/README.md @@ -2,10 +2,10 @@ [![crate][crate-image]][crate-link] [![Docs][docs-image]][docs-link] +[![Build Status][build-image]][build-link] ![Apache2/MIT licensed][license-image] ![Rust Version][rustc-image] [![Project Chat][chat-image]][chat-link] -[![Build Status][build-image]][build-link] Common traits used by cryptographic algorithms. Users should generally use higher-level trait crates instead of this one. @@ -14,7 +14,7 @@ higher-level trait crates instead of this one. ## Minimum Supported Rust Version -Rust **1.56** or higher. +Rust **1.65** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -46,7 +46,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/crypto-common/badge.svg [docs-link]: https://docs.rs/crypto-common/ [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.65+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260041-hashes [build-image]: https://github.com/RustCrypto/traits/workflows/crypto-common/badge.svg?branch=master&event=push diff --git a/crypto-common/src/lib.rs b/crypto-common/src/lib.rs index f4d3993da..420bb7a59 100644 --- a/crypto-common/src/lib.rs +++ b/crypto-common/src/lib.rs @@ -15,28 +15,28 @@ extern crate std; #[cfg(feature = "rand_core")] pub use rand_core; -pub use generic_array; -pub use generic_array::typenum; +pub use hybrid_array as array; +pub use hybrid_array::typenum; use core::fmt; -use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; +use hybrid_array::{typenum::Unsigned, Array, ArraySize, ByteArray}; #[cfg(feature = "rand_core")] use rand_core::CryptoRngCore; /// Block on which [`BlockSizeUser`] implementors operate. -pub type Block = GenericArray::BlockSize>; +pub type Block = ByteArray<::BlockSize>; /// Parallel blocks on which [`ParBlocksSizeUser`] implementors operate. -pub type ParBlocks = GenericArray, ::ParBlocksSize>; +pub type ParBlocks = Array, ::ParBlocksSize>; /// Output array of [`OutputSizeUser`] implementors. -pub type Output = GenericArray::OutputSize>; +pub type Output = ByteArray<::OutputSize>; /// Key used by [`KeySizeUser`] implementors. -pub type Key = GenericArray::KeySize>; +pub type Key = ByteArray<::KeySize>; /// Initialization vector (nonce) used by [`IvSizeUser`] implementors. -pub type Iv = GenericArray::IvSize>; +pub type Iv = ByteArray<::IvSize>; /// Types which process data in blocks. pub trait BlockSizeUser { @@ -59,20 +59,20 @@ impl BlockSizeUser for &mut T { } /// Trait implemented for supported block sizes, i.e. for types from `U1` to `U255`. -pub trait BlockSizes: ArrayLength + sealed::BlockSizes + 'static {} +pub trait BlockSizes: ArraySize + sealed::BlockSizes {} -impl + sealed::BlockSizes> BlockSizes for T {} +impl BlockSizes for T {} mod sealed { - use generic_array::typenum::{Gr, IsGreater, IsLess, Le, NonZero, Unsigned, U1, U256}; + use crate::typenum::{Gr, IsGreater, IsLess, Le, NonZero, Unsigned, U0, U256}; pub trait BlockSizes {} impl BlockSizes for T where - Self: IsLess + IsGreater, + Self: IsLess + IsGreater, Le: NonZero, - Gr: NonZero, + Gr: NonZero, { } } @@ -80,13 +80,13 @@ mod sealed { /// Types which can process blocks in parallel. pub trait ParBlocksSizeUser: BlockSizeUser { /// Number of blocks which can be processed in parallel. - type ParBlocksSize: ArrayLength>; + type ParBlocksSize: ArraySize; } /// Types which return data with the given size. pub trait OutputSizeUser { /// Size of the output in bytes. - type OutputSize: ArrayLength + 'static; + type OutputSize: ArraySize; /// Return output size in bytes. #[inline(always)] @@ -100,7 +100,7 @@ pub trait OutputSizeUser { /// Generally it's used indirectly via [`KeyInit`] or [`KeyIvInit`]. pub trait KeySizeUser { /// Key size in bytes. - type KeySize: ArrayLength + 'static; + type KeySize: ArraySize; /// Return key size in bytes. #[inline(always)] @@ -114,7 +114,7 @@ pub trait KeySizeUser { /// Generally it's used indirectly via [`KeyIvInit`] or [`InnerIvInit`]. pub trait IvSizeUser { /// Initialization vector size in bytes. - type IvSize: ArrayLength + 'static; + type IvSize: ArraySize; /// Return IV size in bytes. #[inline(always)] @@ -151,11 +151,9 @@ pub trait KeyInit: KeySizeUser + Sized { /// Create new value from variable size key. #[inline] fn new_from_slice(key: &[u8]) -> Result { - if key.len() != Self::KeySize::to_usize() { - Err(InvalidLength) - } else { - Ok(Self::new(Key::::from_slice(key))) - } + <&Key>::try_from(key) + .map(Self::new) + .map_err(|_| InvalidLength) } /// Generate random key using the provided [`CryptoRngCore`]. @@ -177,16 +175,9 @@ pub trait KeyIvInit: KeySizeUser + IvSizeUser + Sized { /// Create new value from variable length key and nonce. #[inline] fn new_from_slices(key: &[u8], iv: &[u8]) -> Result { - let key_len = Self::KeySize::USIZE; - let iv_len = Self::IvSize::USIZE; - if key.len() != key_len || iv.len() != iv_len { - Err(InvalidLength) - } else { - Ok(Self::new( - Key::::from_slice(key), - Iv::::from_slice(iv), - )) - } + let key = <&Key>::try_from(key).map_err(|_| InvalidLength)?; + let iv = <&Iv>::try_from(iv).map_err(|_| InvalidLength)?; + Ok(Self::new(key, iv)) } /// Generate random key using the provided [`CryptoRngCore`]. @@ -237,11 +228,8 @@ pub trait InnerIvInit: InnerUser + IvSizeUser + Sized { /// Initialize value using `inner` and `iv` slice. #[inline] fn inner_iv_slice_init(inner: Self::Inner, iv: &[u8]) -> Result { - if iv.len() != Self::IvSize::to_usize() { - Err(InvalidLength) - } else { - Ok(Self::inner_iv_init(inner, Iv::::from_slice(iv))) - } + let iv = <&Iv>::try_from(iv).map_err(|_| InvalidLength)?; + Ok(Self::inner_iv_init(inner, iv)) } /// Generate random IV using the provided [`CryptoRngCore`]. From 102d328e6effa2301a8fe85a46a17b19844438ec Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 27 Oct 2023 12:15:23 -0600 Subject: [PATCH 1054/1461] cipher+digest: migrate to hybrid array; MSRV 1.65 (#1358) Replaces `generic-array` with `hybrid-array`, which is built on a combination of `typenum` and const generics, providing a degree of interoperability between the two systems. `hybrid-array` is designed to be a largely drop-in replacement, and the number of changes required to switch are relatively minimal aside from some idiosyncrasies. --- .github/workflows/cipher.yml | 4 +- .github/workflows/digest.yml | 15 ++++--- Cargo.lock | 63 +++++++++++++----------------- Cargo.toml | 6 +++ cipher/Cargo.toml | 8 ++-- cipher/README.md | 4 +- cipher/src/block.rs | 15 +++---- cipher/src/dev/block.rs | 14 +++---- cipher/src/dev/stream.rs | 4 +- cipher/src/lib.rs | 2 +- cipher/src/stream_core.rs | 34 ++++++++-------- digest/Cargo.toml | 6 +-- digest/README.md | 8 ++-- digest/src/core_api/ct_variable.rs | 28 ++++++------- digest/src/digest.rs | 18 +++------ digest/src/lib.rs | 2 +- 16 files changed, 112 insertions(+), 119 deletions(-) diff --git a/.github/workflows/cipher.yml b/.github/workflows/cipher.yml index 0897add5c..aecc168a2 100644 --- a/.github/workflows/cipher.yml +++ b/.github/workflows/cipher.yml @@ -23,7 +23,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.65.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -57,7 +57,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.65.0 # MSRV - stable steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/digest.yml b/.github/workflows/digest.yml index 7338e8843..3535a1172 100644 --- a/.github/workflows/digest.yml +++ b/.github/workflows/digest.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.57.0 # MSRV + - 1.65.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -34,21 +34,20 @@ jobs: with: toolchain: ${{ matrix.rust }} targets: ${{ matrix.target }} - # Isolate this crate from workspace which is otherwise MSRV 1.56 due to 2021 edition crates - - run: rm ../Cargo.toml - run: cargo build --target ${{ matrix.target }} - minimal-versions: - uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master - with: - working-directory: ${{ github.workflow }} + # TODO(tarcieri): re-enable after next `crypto-common` release + #minimal-versions: + # uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master + # with: + # working-directory: ${{ github.workflow }} test: runs-on: ubuntu-latest strategy: matrix: rust: - - 1.57.0 # MSRV + - 1.65.0 # MSRV - stable steps: - uses: actions/checkout@v4 diff --git a/Cargo.lock b/Cargo.lock index 68a79738e..cc4f6fb2b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -31,7 +31,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" dependencies = [ "cfg-if", - "cipher 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cipher 0.4.4", "cpufeatures", ] @@ -43,7 +43,7 @@ checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" dependencies = [ "aead 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "aes", - "cipher 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cipher 0.4.4", "ctr", "ghash", "subtle", @@ -137,20 +137,17 @@ dependencies = [ [[package]] name = "block-buffer" version = "0.11.0-pre" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b6a33d658e9ef24ba0c4566d3d023d7978ca2ea3efb65e4eacd4586695892b" +source = "git+https://github.com/RustCrypto/utils.git#b755f1a29b074d8b0a6fc5fda5744312a11632c7" dependencies = [ - "crypto-common 0.2.0-pre (registry+https://github.com/rust-lang/crates.io-index)", - "generic-array", + "crypto-common 0.2.0-pre", ] [[package]] name = "block-padding" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" +version = "0.4.0-pre" +source = "git+https://github.com/RustCrypto/utils.git#b755f1a29b074d8b0a6fc5fda5744312a11632c7" dependencies = [ - "generic-array", + "hybrid-array", ] [[package]] @@ -188,7 +185,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" dependencies = [ "cfg-if", - "cipher 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cipher 0.4.4", "cpufeatures", ] @@ -200,7 +197,7 @@ checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" dependencies = [ "aead 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "chacha20", - "cipher 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cipher 0.4.4", "poly1305", "zeroize", ] @@ -208,21 +205,21 @@ dependencies = [ [[package]] name = "cipher" version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ - "blobby", "crypto-common 0.1.6", - "inout", + "inout 0.1.3", "zeroize", ] [[package]] name = "cipher" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +version = "0.5.0-pre" dependencies = [ - "crypto-common 0.1.6", - "inout", + "blobby", + "crypto-common 0.2.0-pre", + "inout 0.2.0-pre", "zeroize", ] @@ -296,17 +293,6 @@ dependencies = [ "rand_core 0.6.4", ] -[[package]] -name = "crypto-common" -version = "0.2.0-pre" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6faaa83e7700e0832cbbf84854d4c356270526907d9b14fab927fc7a9b5befb8" -dependencies = [ - "generic-array", - "rand_core 0.6.4", - "typenum", -] - [[package]] name = "crypto-mac" version = "0.11.0" @@ -323,7 +309,7 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" dependencies = [ - "cipher 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cipher 0.4.4", ] [[package]] @@ -384,7 +370,7 @@ dependencies = [ "blobby", "block-buffer 0.11.0-pre", "const-oid 0.9.5", - "crypto-common 0.2.0-pre (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.2.0-pre", "subtle", ] @@ -612,8 +598,7 @@ dependencies = [ [[package]] name = "hybrid-array" version = "0.2.0-pre.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "431615b6a66a159a76ac38f4b0bcbd5999433d08425d79e152438e3ab9f1013c" +source = "git+https://github.com/RustCrypto/utils.git#b755f1a29b074d8b0a6fc5fda5744312a11632c7" dependencies = [ "typenum", ] @@ -624,10 +609,18 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" dependencies = [ - "block-padding", "generic-array", ] +[[package]] +name = "inout" +version = "0.2.0-pre" +source = "git+https://github.com/RustCrypto/utils.git#b755f1a29b074d8b0a6fc5fda5744312a11632c7" +dependencies = [ + "block-padding", + "hybrid-array", +] + [[package]] name = "jobserver" version = "0.1.26" diff --git a/Cargo.toml b/Cargo.toml index e7b7482b6..59dd5ff5d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,3 +16,9 @@ exclude = [ "crypto", "elliptic-curve" ] + +[patch.crates-io] +block-buffer = { git = "https://github.com/RustCrypto/utils.git" } +crypto-common = { path = "crypto-common" } +hybrid-array = { git = "https://github.com/RustCrypto/utils.git" } +inout = { git = "https://github.com/RustCrypto/utils.git" } diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index c36b31cc5..60e9426f0 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -1,20 +1,20 @@ [package] name = "cipher" description = "Traits for describing block ciphers and stream ciphers" -version = "0.4.4" +version = "0.5.0-pre" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" edition = "2021" -rust-version = "1.56" +rust-version = "1.65" documentation = "https://docs.rs/cipher" repository = "https://github.com/RustCrypto/traits" keywords = ["crypto", "block-cipher", "stream-cipher", "trait"] categories = ["cryptography", "no-std"] [dependencies] -crypto-common = "0.1.6" -inout = "0.1" +crypto-common = "=0.2.0-pre" +inout = "=0.2.0-pre" # optional dependencies blobby = { version = "0.3", optional = true } diff --git a/cipher/README.md b/cipher/README.md index 9d117626d..716973c1c 100644 --- a/cipher/README.md +++ b/cipher/README.md @@ -16,7 +16,7 @@ implementations which use these traits. ## Minimum Supported Rust Version -Rust **1.56** or higher. +Rust **1.65** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -48,7 +48,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/cipher/badge.svg [docs-link]: https://docs.rs/cipher/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.65+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260050-traits [build-image]: https://github.com/RustCrypto/traits/workflows/cipher/badge.svg?branch=master&event=push diff --git a/cipher/src/block.rs b/cipher/src/block.rs index 0742ced14..7b8c99cf9 100644 --- a/cipher/src/block.rs +++ b/cipher/src/block.rs @@ -13,6 +13,7 @@ use crate::{ParBlocks, ParBlocksSizeUser}; #[cfg(all(feature = "block-padding", feature = "alloc"))] use alloc::{vec, vec::Vec}; +use crypto_common::BlockSizes; #[cfg(feature = "block-padding")] use inout::{ block_padding::{Padding, UnpadError}, @@ -20,7 +21,7 @@ use inout::{ }; use inout::{InOut, InOutBuf, NotEqualError}; -pub use crypto_common::{generic_array::ArrayLength, typenum::Unsigned, Block, BlockSizeUser}; +pub use crypto_common::{array::ArraySize, typenum::Unsigned, Block, BlockSizeUser}; /// Marker trait for block ciphers. pub trait BlockCipher: BlockSizeUser {} @@ -593,15 +594,15 @@ impl BlockDecrypt for &Alg { } /// Closure used in methods which operate over separate blocks. -struct BlockCtx<'inp, 'out, BS: ArrayLength> { +struct BlockCtx<'inp, 'out, BS: BlockSizes> { block: InOut<'inp, 'out, Block>, } -impl<'inp, 'out, BS: ArrayLength> BlockSizeUser for BlockCtx<'inp, 'out, BS> { +impl<'inp, 'out, BS: BlockSizes> BlockSizeUser for BlockCtx<'inp, 'out, BS> { type BlockSize = BS; } -impl<'inp, 'out, BS: ArrayLength> BlockClosure for BlockCtx<'inp, 'out, BS> { +impl<'inp, 'out, BS: BlockSizes> BlockClosure for BlockCtx<'inp, 'out, BS> { #[inline(always)] fn call>(self, backend: &mut B) { backend.proc_block(self.block); @@ -609,15 +610,15 @@ impl<'inp, 'out, BS: ArrayLength> BlockClosure for BlockCtx<'inp, 'out, BS> } /// Closure used in methods which operate over slice of blocks. -struct BlocksCtx<'inp, 'out, BS: ArrayLength> { +struct BlocksCtx<'inp, 'out, BS: BlockSizes> { blocks: InOutBuf<'inp, 'out, Block>, } -impl<'inp, 'out, BS: ArrayLength> BlockSizeUser for BlocksCtx<'inp, 'out, BS> { +impl<'inp, 'out, BS: BlockSizes> BlockSizeUser for BlocksCtx<'inp, 'out, BS> { type BlockSize = BS; } -impl<'inp, 'out, BS: ArrayLength> BlockClosure for BlocksCtx<'inp, 'out, BS> { +impl<'inp, 'out, BS: BlockSizes> BlockClosure for BlocksCtx<'inp, 'out, BS> { #[inline(always)] fn call>(self, backend: &mut B) { if B::ParBlocksSize::USIZE > 1 { diff --git a/cipher/src/dev/block.rs b/cipher/src/dev/block.rs index d3115c5d8..ee0995dba 100644 --- a/cipher/src/dev/block.rs +++ b/cipher/src/dev/block.rs @@ -10,14 +10,14 @@ macro_rules! block_cipher_test { #[test] fn $name() { use cipher::{ - blobby::Blob3Iterator, generic_array::GenericArray, typenum::Unsigned, - BlockDecryptMut, BlockEncryptMut, BlockSizeUser, KeyInit, + array::Array, blobby::Blob3Iterator, typenum::Unsigned, BlockDecryptMut, + BlockEncryptMut, BlockSizeUser, KeyInit, }; fn run_test(key: &[u8], pt: &[u8], ct: &[u8]) -> bool { let mut state = <$cipher as KeyInit>::new_from_slice(key).unwrap(); - let mut block = GenericArray::clone_from_slice(pt); + let mut block = Array::clone_from_slice(pt); state.encrypt_block_mut(&mut block); if ct != block.as_slice() { return false; @@ -105,8 +105,8 @@ macro_rules! block_mode_enc_test { #[test] fn $name() { use cipher::{ - blobby::Blob4Iterator, generic_array::GenericArray, inout::InOutBuf, - typenum::Unsigned, BlockEncryptMut, BlockSizeUser, KeyIvInit, + array::Array, blobby::Blob4Iterator, inout::InOutBuf, typenum::Unsigned, + BlockEncryptMut, BlockSizeUser, KeyIvInit, }; fn run_test(key: &[u8], iv: &[u8], pt: &[u8], ct: &[u8]) -> bool { @@ -164,8 +164,8 @@ macro_rules! block_mode_dec_test { #[test] fn $name() { use cipher::{ - blobby::Blob4Iterator, generic_array::GenericArray, inout::InOutBuf, - typenum::Unsigned, BlockDecryptMut, BlockSizeUser, KeyIvInit, + array::Array, blobby::Blob4Iterator, inout::InOutBuf, typenum::Unsigned, + BlockDecryptMut, BlockSizeUser, KeyIvInit, }; fn run_test(key: &[u8], iv: &[u8], pt: &[u8], ct: &[u8]) -> bool { diff --git a/cipher/src/dev/stream.rs b/cipher/src/dev/stream.rs index 0496345d4..d65f80c70 100644 --- a/cipher/src/dev/stream.rs +++ b/cipher/src/dev/stream.rs @@ -7,7 +7,7 @@ macro_rules! stream_cipher_test { ($name:ident, $test_name:expr, $cipher:ty $(,)?) => { #[test] fn $name() { - use cipher::generic_array::GenericArray; + use cipher::array::Array; use cipher::{blobby::Blob4Iterator, KeyIvInit, StreamCipher}; let data = include_bytes!(concat!("data/", $test_name, ".blb")); @@ -43,7 +43,7 @@ macro_rules! stream_cipher_seek_test { ($name:ident, $cipher:ty) => { #[test] fn $name() { - use cipher::generic_array::GenericArray; + use cipher::array::Array; use cipher::{KeyIvInit, StreamCipher, StreamCipherSeek}; fn get_cipher() -> $cipher { diff --git a/cipher/src/lib.rs b/cipher/src/lib.rs index 87813d940..a8af951b8 100644 --- a/cipher/src/lib.rs +++ b/cipher/src/lib.rs @@ -48,7 +48,7 @@ mod stream_wrapper; pub use crate::{block::*, errors::*, stream::*, stream_core::*, stream_wrapper::*}; pub use crypto_common::{ - generic_array, + array, typenum::{self, consts}, AlgorithmName, Block, InnerIvInit, InvalidLength, Iv, IvSizeUser, Key, KeyInit, KeyIvInit, KeySizeUser, ParBlocks, ParBlocksSizeUser, diff --git a/cipher/src/stream_core.rs b/cipher/src/stream_core.rs index 1e4b302ea..5a9232dbe 100644 --- a/cipher/src/stream_core.rs +++ b/cipher/src/stream_core.rs @@ -1,8 +1,8 @@ use crate::{ParBlocks, ParBlocksSizeUser, StreamCipherError}; use crypto_common::{ - generic_array::{ArrayLength, GenericArray}, + array::{Array, ArraySize}, typenum::Unsigned, - Block, BlockSizeUser, + Block, BlockSizeUser, BlockSizes, }; use inout::{InOut, InOutBuf}; @@ -195,7 +195,7 @@ impl_counter! { u32 u64 u128 } /// In case if `N` is less or equal to 1, buffer of arrays has length /// of zero and tail is equal to `self`. #[inline] -fn into_chunks>(buf: &mut [T]) -> (&mut [GenericArray], &mut [T]) { +fn into_chunks(buf: &mut [T]) -> (&mut [Array], &mut [T]) { use core::slice; if N::USIZE <= 1 { return (&mut [], buf); @@ -205,32 +205,32 @@ fn into_chunks>(buf: &mut [T]) -> (&mut [GenericArray let tail_len = buf.len() - tail_pos; unsafe { let ptr = buf.as_mut_ptr(); - let chunks = slice::from_raw_parts_mut(ptr as *mut GenericArray, chunks_len); + let chunks = slice::from_raw_parts_mut(ptr as *mut Array, chunks_len); let tail = slice::from_raw_parts_mut(ptr.add(tail_pos), tail_len); (chunks, tail) } } -struct WriteBlockCtx<'a, BS: ArrayLength> { +struct WriteBlockCtx<'a, BS: BlockSizes> { block: &'a mut Block, } -impl<'a, BS: ArrayLength> BlockSizeUser for WriteBlockCtx<'a, BS> { +impl<'a, BS: BlockSizes> BlockSizeUser for WriteBlockCtx<'a, BS> { type BlockSize = BS; } -impl<'a, BS: ArrayLength> StreamClosure for WriteBlockCtx<'a, BS> { +impl<'a, BS: BlockSizes> StreamClosure for WriteBlockCtx<'a, BS> { #[inline(always)] fn call>(self, backend: &mut B) { backend.gen_ks_block(self.block); } } -struct WriteBlocksCtx<'a, BS: ArrayLength> { +struct WriteBlocksCtx<'a, BS: BlockSizes> { blocks: &'a mut [Block], } -impl<'a, BS: ArrayLength> BlockSizeUser for WriteBlocksCtx<'a, BS> { +impl<'a, BS: BlockSizes> BlockSizeUser for WriteBlocksCtx<'a, BS> { type BlockSize = BS; } -impl<'a, BS: ArrayLength> StreamClosure for WriteBlocksCtx<'a, BS> { +impl<'a, BS: BlockSizes> StreamClosure for WriteBlocksCtx<'a, BS> { #[inline(always)] fn call>(self, backend: &mut B) { if B::ParBlocksSize::USIZE > 1 { @@ -247,15 +247,15 @@ impl<'a, BS: ArrayLength> StreamClosure for WriteBlocksCtx<'a, BS> { } } -struct ApplyBlockCtx<'inp, 'out, BS: ArrayLength> { +struct ApplyBlockCtx<'inp, 'out, BS: BlockSizes> { block: InOut<'inp, 'out, Block>, } -impl<'inp, 'out, BS: ArrayLength> BlockSizeUser for ApplyBlockCtx<'inp, 'out, BS> { +impl<'inp, 'out, BS: BlockSizes> BlockSizeUser for ApplyBlockCtx<'inp, 'out, BS> { type BlockSize = BS; } -impl<'inp, 'out, BS: ArrayLength> StreamClosure for ApplyBlockCtx<'inp, 'out, BS> { +impl<'inp, 'out, BS: BlockSizes> StreamClosure for ApplyBlockCtx<'inp, 'out, BS> { #[inline(always)] fn call>(mut self, backend: &mut B) { let mut t = Default::default(); @@ -264,15 +264,15 @@ impl<'inp, 'out, BS: ArrayLength> StreamClosure for ApplyBlockCtx<'inp, 'out } } -struct ApplyBlocksCtx<'inp, 'out, BS: ArrayLength> { +struct ApplyBlocksCtx<'inp, 'out, BS: BlockSizes> { blocks: InOutBuf<'inp, 'out, Block>, } -impl<'inp, 'out, BS: ArrayLength> BlockSizeUser for ApplyBlocksCtx<'inp, 'out, BS> { +impl<'inp, 'out, BS: BlockSizes> BlockSizeUser for ApplyBlocksCtx<'inp, 'out, BS> { type BlockSize = BS; } -impl<'inp, 'out, BS: ArrayLength> StreamClosure for ApplyBlocksCtx<'inp, 'out, BS> { +impl<'inp, 'out, BS: BlockSizes> StreamClosure for ApplyBlocksCtx<'inp, 'out, BS> { #[inline(always)] #[allow(clippy::needless_range_loop)] fn call>(self, backend: &mut B) { @@ -284,7 +284,7 @@ impl<'inp, 'out, BS: ArrayLength> StreamClosure for ApplyBlocksCtx<'inp, 'ou chunk.xor_in2out(&tmp); } let n = tail.len(); - let mut buf = GenericArray::<_, B::ParBlocksSize>::default(); + let mut buf = Array::<_, B::ParBlocksSize>::default(); let ks = &mut buf[..n]; backend.gen_tail_blocks(ks); for i in 0..n { diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 9e936809c..261494a01 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -6,17 +6,17 @@ authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" edition = "2021" -rust-version = "1.57" +rust-version = "1.65" documentation = "https://docs.rs/digest" repository = "https://github.com/RustCrypto/traits" keywords = ["digest", "crypto", "hash"] categories = ["cryptography", "no-std"] [dependencies] -crypto-common = "0.2.0-pre" +crypto-common = "=0.2.0-pre" # optional dependencies -block-buffer = { version = "0.11.0-pre", optional = true } +block-buffer = { version = "=0.11.0-pre", optional = true } subtle = { version = "2.4", default-features = false, optional = true } blobby = { version = "0.3", optional = true } const-oid = { version = "0.9", optional = true } diff --git a/digest/README.md b/digest/README.md index 1d5f1f8fb..3748879a6 100644 --- a/digest/README.md +++ b/digest/README.md @@ -16,7 +16,7 @@ See [RustCrypto/hashes][1] for implementations which use this trait. ## Minimum Supported Rust Version -Rust **1.57** or higher. +Rust **1.65** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -56,7 +56,7 @@ let hash = hasher.finalize(); println!("Result: {:x}", hash); ``` -In this example `hash` has type [`GenericArray`][2], which is a generic +In this example `hash` has type [`Array`][2], which is a generic alternative to `[u8; 64]`. Alternatively you can use chained approach, which is equivalent to the previous @@ -147,7 +147,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/digest/badge.svg [docs-link]: https://docs.rs/digest/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.57+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.65+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260041-hashes [build-image]: https://github.com/RustCrypto/traits/workflows/digest/badge.svg?branch=master&event=push @@ -157,7 +157,7 @@ dual licensed as above, without any additional terms or conditions. [0]: https://en.wikipedia.org/wiki/Cryptographic_hash_function [1]: https://github.com/RustCrypto/hashes -[2]: https://docs.rs/generic-array +[2]: https://docs.rs/hybrid-array [3]: https://doc.rust-lang.org/std/io/trait.Read.html [4]: https://doc.rust-lang.org/std/io/trait.Write.html [5]: https://en.wikipedia.org/wiki/Hash-based_message_authentication_code diff --git a/digest/src/core_api/ct_variable.rs b/digest/src/core_api/ct_variable.rs index 0011a9262..c06f13904 100644 --- a/digest/src/core_api/ct_variable.rs +++ b/digest/src/core_api/ct_variable.rs @@ -9,7 +9,7 @@ use crate::MacMarker; use const_oid::{AssociatedOid, ObjectIdentifier}; use core::{fmt, marker::PhantomData}; use crypto_common::{ - generic_array::{ArrayLength, GenericArray}, + array::{Array, ArraySize}, typenum::{IsLessOrEqual, LeEq, NonZero}, Block, BlockSizeUser, OutputSizeUser, }; @@ -25,7 +25,7 @@ pub struct NoOid; pub struct CtVariableCoreWrapper where T: VariableOutputCore, - OutSize: ArrayLength + IsLessOrEqual, + OutSize: ArraySize + IsLessOrEqual, LeEq: NonZero, { inner: T, @@ -35,7 +35,7 @@ where impl HashMarker for CtVariableCoreWrapper where T: VariableOutputCore + HashMarker, - OutSize: ArrayLength + IsLessOrEqual, + OutSize: ArraySize + IsLessOrEqual, LeEq: NonZero, { } @@ -44,7 +44,7 @@ where impl MacMarker for CtVariableCoreWrapper where T: VariableOutputCore + MacMarker, - OutSize: ArrayLength + IsLessOrEqual, + OutSize: ArraySize + IsLessOrEqual, LeEq: NonZero, { } @@ -52,7 +52,7 @@ where impl BlockSizeUser for CtVariableCoreWrapper where T: VariableOutputCore, - OutSize: ArrayLength + IsLessOrEqual, + OutSize: ArraySize + IsLessOrEqual, LeEq: NonZero, { type BlockSize = T::BlockSize; @@ -61,7 +61,7 @@ where impl UpdateCore for CtVariableCoreWrapper where T: VariableOutputCore, - OutSize: ArrayLength + IsLessOrEqual, + OutSize: ArraySize + IsLessOrEqual, LeEq: NonZero, { #[inline] @@ -73,7 +73,7 @@ where impl OutputSizeUser for CtVariableCoreWrapper where T: VariableOutputCore, - OutSize: ArrayLength + IsLessOrEqual + 'static, + OutSize: ArraySize + IsLessOrEqual, LeEq: NonZero, { type OutputSize = OutSize; @@ -82,7 +82,7 @@ where impl BufferKindUser for CtVariableCoreWrapper where T: VariableOutputCore, - OutSize: ArrayLength + IsLessOrEqual, + OutSize: ArraySize + IsLessOrEqual, LeEq: NonZero, { type BufferKind = T::BufferKind; @@ -91,14 +91,14 @@ where impl FixedOutputCore for CtVariableCoreWrapper where T: VariableOutputCore, - OutSize: ArrayLength + IsLessOrEqual + 'static, + OutSize: ArraySize + IsLessOrEqual, LeEq: NonZero, { #[inline] fn finalize_fixed_core( &mut self, buffer: &mut Buffer, - out: &mut GenericArray, + out: &mut Array, ) { let mut full_res = Default::default(); self.inner.finalize_variable_core(buffer, &mut full_res); @@ -114,7 +114,7 @@ where impl Default for CtVariableCoreWrapper where T: VariableOutputCore, - OutSize: ArrayLength + IsLessOrEqual, + OutSize: ArraySize + IsLessOrEqual, LeEq: NonZero, { #[inline] @@ -129,7 +129,7 @@ where impl Reset for CtVariableCoreWrapper where T: VariableOutputCore, - OutSize: ArrayLength + IsLessOrEqual, + OutSize: ArraySize + IsLessOrEqual, LeEq: NonZero, { #[inline] @@ -141,7 +141,7 @@ where impl AlgorithmName for CtVariableCoreWrapper where T: VariableOutputCore + AlgorithmName, - OutSize: ArrayLength + IsLessOrEqual, + OutSize: ArraySize + IsLessOrEqual, LeEq: NonZero, { fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -157,7 +157,7 @@ impl AssociatedOid for CtVariableCoreWrapper where T: VariableOutputCore, O: AssociatedOid, - OutSize: ArrayLength + IsLessOrEqual, + OutSize: ArraySize + IsLessOrEqual, LeEq: NonZero, { const OID: ObjectIdentifier = O::OID; diff --git a/digest/src/digest.rs b/digest/src/digest.rs index 9373550ca..1a332505d 100644 --- a/digest/src/digest.rs +++ b/digest/src/digest.rs @@ -196,21 +196,15 @@ impl DynDigest for D { } fn finalize_into(self, buf: &mut [u8]) -> Result<(), InvalidBufferSize> { - if buf.len() == self.output_size() { - FixedOutput::finalize_into(self, Output::::from_mut_slice(buf)); - Ok(()) - } else { - Err(InvalidBufferSize) - } + buf.try_into() + .map_err(|_| InvalidBufferSize) + .map(|buf| FixedOutput::finalize_into(self, buf)) } fn finalize_into_reset(&mut self, buf: &mut [u8]) -> Result<(), InvalidBufferSize> { - if buf.len() == self.output_size() { - FixedOutputReset::finalize_into_reset(self, Output::::from_mut_slice(buf)); - Ok(()) - } else { - Err(InvalidBufferSize) - } + let buf = <&mut Output>::try_from(buf).map_err(|_| InvalidBufferSize)?; + FixedOutputReset::finalize_into_reset(self, buf); + Ok(()) } fn reset(&mut self) { diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 04ea98931..911133d7e 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -65,7 +65,7 @@ pub use const_oid; pub use crypto_common; pub use crate::digest::{Digest, DynDigest, HashMarker}; -pub use crypto_common::{generic_array, typenum, typenum::consts, Output, OutputSizeUser, Reset}; +pub use crypto_common::{array, typenum, typenum::consts, Output, OutputSizeUser, Reset}; #[cfg(feature = "mac")] pub use crypto_common::{InnerInit, InvalidLength, Key, KeyInit}; #[cfg(feature = "mac")] From 2a1016f47e379fdca6a213b07625d1d440506d96 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 27 Oct 2023 12:48:44 -0600 Subject: [PATCH 1055/1461] cipher: remove needless lifetimes (#1368) One of the lifetimes is unused, but we couldn't remove it before because it would be a breaking change. Closes #1336 --- cipher/src/block.rs | 16 ++++++++-------- cipher/src/lib.rs | 3 +-- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/cipher/src/block.rs b/cipher/src/block.rs index 7b8c99cf9..297d4a1bf 100644 --- a/cipher/src/block.rs +++ b/cipher/src/block.rs @@ -135,9 +135,9 @@ pub trait BlockEncrypt: BlockSizeUser + Sized { #[cfg(feature = "block-padding")] #[cfg_attr(docsrs, doc(cfg(feature = "block-padding")))] #[inline] - fn encrypt_padded_inout<'inp, 'out, P: Padding>( + fn encrypt_padded_inout<'out, P: Padding>( &self, - data: InOutBufReserved<'inp, 'out, u8>, + data: InOutBufReserved<'_, 'out, u8>, ) -> Result<&'out [u8], PadError> { let mut buf = data.into_padded_blocks::()?; self.encrypt_blocks_inout(buf.get_blocks()); @@ -251,9 +251,9 @@ pub trait BlockDecrypt: BlockSizeUser { #[cfg(feature = "block-padding")] #[cfg_attr(docsrs, doc(cfg(feature = "block-padding")))] #[inline] - fn decrypt_padded_inout<'inp, 'out, P: Padding>( + fn decrypt_padded_inout<'out, P: Padding>( &self, - data: InOutBuf<'inp, 'out, u8>, + data: InOutBuf<'_, 'out, u8>, ) -> Result<&'out [u8], UnpadError> { let (mut blocks, tail) = data.into_chunks(); if !tail.is_empty() { @@ -380,9 +380,9 @@ pub trait BlockEncryptMut: BlockSizeUser + Sized { #[cfg(feature = "block-padding")] #[cfg_attr(docsrs, doc(cfg(feature = "block-padding")))] #[inline] - fn encrypt_padded_inout_mut<'inp, 'out, P: Padding>( + fn encrypt_padded_inout_mut<'out, P: Padding>( mut self, - data: InOutBufReserved<'inp, 'out, u8>, + data: InOutBufReserved<'_, 'out, u8>, ) -> Result<&'out [u8], PadError> { let mut buf = data.into_padded_blocks::()?; self.encrypt_blocks_inout_mut(buf.get_blocks()); @@ -500,9 +500,9 @@ pub trait BlockDecryptMut: BlockSizeUser + Sized { #[cfg(feature = "block-padding")] #[cfg_attr(docsrs, doc(cfg(feature = "block-padding")))] #[inline] - fn decrypt_padded_inout_mut<'inp, 'out, P: Padding>( + fn decrypt_padded_inout_mut<'out, P: Padding>( mut self, - data: InOutBuf<'inp, 'out, u8>, + data: InOutBuf<'_, 'out, u8>, ) -> Result<&'out [u8], UnpadError> { let (mut blocks, tail) = data.into_chunks(); if !tail.is_empty() { diff --git a/cipher/src/lib.rs b/cipher/src/lib.rs index a8af951b8..fc476b626 100644 --- a/cipher/src/lib.rs +++ b/cipher/src/lib.rs @@ -11,8 +11,7 @@ html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg" )] -#![warn(missing_docs, rust_2018_idioms)] -#![allow(clippy::needless_lifetimes)] +#![warn(missing_docs, rust_2018_idioms, unused_lifetimes)] pub use crypto_common; pub use inout; From bbcb9c2306cf02a6a7812787de44680dd227336b Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 31 Oct 2023 08:42:52 -0600 Subject: [PATCH 1056/1461] Migrate to `doc_auto_cfg` (#1370) Migrates the `aead`, `cipher`, `crypto-common`, `digest`, and `universal-hash` crates to use the `doc_auto_cfg` feature which automatically generates documentation for `cfg`-gated code, which in our uses is almost exclusively gated on crate features. This allows the previous manual `doc_cfg` annotations to be removed, which is nice as they otherwise duplicate work whenever `cfg`-gated code is used. --- aead/src/dev.rs | 1 - aead/src/lib.rs | 13 +------------ aead/src/stream.rs | 4 ---- cipher/src/block.rs | 16 ---------------- cipher/src/dev/block.rs | 6 ------ cipher/src/dev/stream.rs | 3 --- cipher/src/errors.rs | 2 -- cipher/src/lib.rs | 5 +---- crypto-common/src/lib.rs | 7 +------ digest/src/core_api/ct_variable.rs | 1 - digest/src/core_api/rt_variable.rs | 2 -- digest/src/core_api/wrapper.rs | 3 --- digest/src/core_api/xof_reader.rs | 1 - digest/src/dev.rs | 2 -- digest/src/dev/mac.rs | 2 -- digest/src/digest.rs | 4 ---- digest/src/lib.rs | 13 +------------ digest/src/mac.rs | 4 ---- kem/src/lib.rs | 2 +- universal-hash/src/lib.rs | 3 +-- 20 files changed, 6 insertions(+), 88 deletions(-) diff --git a/aead/src/dev.rs b/aead/src/dev.rs index a0fc7db2f..37688262b 100644 --- a/aead/src/dev.rs +++ b/aead/src/dev.rs @@ -3,7 +3,6 @@ pub use blobby; /// Define AEAD test #[macro_export] -#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] macro_rules! new_test { ($name:ident, $test_name:expr, $cipher:ty $(,)?) => { #[test] diff --git a/aead/src/lib.rs b/aead/src/lib.rs index 700667998..df9bf1262 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -14,7 +14,7 @@ //! [RustCrypto/AEADs]: https://github.com/RustCrypto/AEADs #![no_std] -#![cfg_attr(docsrs, feature(doc_cfg))] +#![cfg_attr(docsrs, feature(doc_auto_cfg))] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg" @@ -29,34 +29,27 @@ extern crate alloc; extern crate std; #[cfg(feature = "dev")] -#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] pub mod dev; #[cfg(feature = "stream")] -#[cfg_attr(docsrs, doc(cfg(feature = "stream")))] pub mod stream; pub use crypto_common::{Key, KeyInit, KeySizeUser}; pub use generic_array::{self, typenum::consts}; #[cfg(feature = "arrayvec")] -#[cfg_attr(docsrs, doc(cfg(feature = "arrayvec")))] pub use arrayvec; #[cfg(feature = "bytes")] -#[cfg_attr(docsrs, doc(cfg(feature = "bytes")))] pub use bytes; #[cfg(feature = "getrandom")] -#[cfg_attr(docsrs, doc(cfg(feature = "getrandom")))] pub use crypto_common::rand_core::OsRng; #[cfg(feature = "heapless")] -#[cfg_attr(docsrs, doc(cfg(feature = "heapless")))] pub use heapless; #[cfg(feature = "rand_core")] -#[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] pub use crypto_common::rand_core; use core::fmt; @@ -147,7 +140,6 @@ pub trait AeadCore { /// /// [NIST SP 800-38D]: https://csrc.nist.gov/publications/detail/sp/800-38d/final #[cfg(feature = "rand_core")] - #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] fn generate_nonce(mut rng: impl CryptoRng + RngCore) -> Nonce where Nonce: Default, @@ -163,7 +155,6 @@ pub trait AeadCore { /// This trait is intended for use with stateless AEAD algorithms. The /// [`AeadMut`] trait provides a stateful interface. #[cfg(feature = "alloc")] -#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] pub trait Aead: AeadCore { /// Encrypt the given plaintext payload, and return the resulting /// ciphertext as a vector of bytes. @@ -220,7 +211,6 @@ pub trait Aead: AeadCore { /// Stateful Authenticated Encryption with Associated Data algorithm. #[cfg(feature = "alloc")] -#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] pub trait AeadMut: AeadCore { /// Encrypt the given plaintext slice, and return the resulting ciphertext /// as a vector of bytes. @@ -480,7 +470,6 @@ impl AeadMutInPlace for Alg { /// If you don't care about AAD, you can pass a `&[u8]` as the payload to /// `encrypt`/`decrypt` and it will automatically be coerced to this type. #[cfg(feature = "alloc")] -#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] pub struct Payload<'msg, 'aad> { /// Message to be encrypted/decrypted pub msg: &'msg [u8], diff --git a/aead/src/stream.rs b/aead/src/stream.rs index 6b38d43fd..a5c3c6586 100644 --- a/aead/src/stream.rs +++ b/aead/src/stream.rs @@ -131,7 +131,6 @@ where /// Encrypt the given plaintext payload, and return the resulting /// ciphertext as a vector of bytes. #[cfg(feature = "alloc")] - #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] fn encrypt<'msg, 'aad>( &self, position: Self::Counter, @@ -148,7 +147,6 @@ where /// Decrypt the given ciphertext slice, and return the resulting plaintext /// as a vector of bytes. #[cfg(feature = "alloc")] - #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] fn decrypt<'msg, 'aad>( &self, position: Self::Counter, @@ -259,7 +257,6 @@ macro_rules! impl_stream_object { #[doc = "the next AEAD message in this STREAM, returning the"] #[doc = "result as a [`Vec`]."] #[cfg(feature = "alloc")] - #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] pub fn $next_method<'msg, 'aad>( &mut self, payload: impl Into>, @@ -308,7 +305,6 @@ macro_rules! impl_stream_object { #[doc = $obj_desc] #[doc = "object in order to prevent further use."] #[cfg(feature = "alloc")] - #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] pub fn $last_method<'msg, 'aad>( self, payload: impl Into>, diff --git a/cipher/src/block.rs b/cipher/src/block.rs index 297d4a1bf..f6925ee25 100644 --- a/cipher/src/block.rs +++ b/cipher/src/block.rs @@ -133,7 +133,6 @@ pub trait BlockEncrypt: BlockSizeUser + Sized { /// /// Returns [`PadError`] if length of output buffer is not sufficient. #[cfg(feature = "block-padding")] - #[cfg_attr(docsrs, doc(cfg(feature = "block-padding")))] #[inline] fn encrypt_padded_inout<'out, P: Padding>( &self, @@ -151,7 +150,6 @@ pub trait BlockEncrypt: BlockSizeUser + Sized { /// /// Returns [`PadError`] if length of output buffer is not sufficient. #[cfg(feature = "block-padding")] - #[cfg_attr(docsrs, doc(cfg(feature = "block-padding")))] #[inline] fn encrypt_padded<'a, P: Padding>( &self, @@ -166,7 +164,6 @@ pub trait BlockEncrypt: BlockSizeUser + Sized { /// /// Returns [`PadError`] if length of output buffer is not sufficient. #[cfg(feature = "block-padding")] - #[cfg_attr(docsrs, doc(cfg(feature = "block-padding")))] #[inline] fn encrypt_padded_b2b<'a, P: Padding>( &self, @@ -179,7 +176,6 @@ pub trait BlockEncrypt: BlockSizeUser + Sized { /// Pad input and encrypt into a newly allocated Vec. Returns resulting ciphertext Vec. #[cfg(all(feature = "block-padding", feature = "alloc"))] - #[cfg_attr(docsrs, doc(cfg(all(feature = "block-padding", feature = "alloc"))))] #[inline] fn encrypt_padded_vec>(&self, msg: &[u8]) -> Vec { let mut out = allocate_out_vec::(msg.len()); @@ -249,7 +245,6 @@ pub trait BlockDecrypt: BlockSizeUser { /// Returns [`UnpadError`] if padding is malformed or if input length is /// not multiple of `Self::BlockSize`. #[cfg(feature = "block-padding")] - #[cfg_attr(docsrs, doc(cfg(feature = "block-padding")))] #[inline] fn decrypt_padded_inout<'out, P: Padding>( &self, @@ -268,7 +263,6 @@ pub trait BlockDecrypt: BlockSizeUser { /// Returns [`UnpadError`] if padding is malformed or if input length is /// not multiple of `Self::BlockSize`. #[cfg(feature = "block-padding")] - #[cfg_attr(docsrs, doc(cfg(feature = "block-padding")))] #[inline] fn decrypt_padded<'a, P: Padding>( &self, @@ -283,7 +277,6 @@ pub trait BlockDecrypt: BlockSizeUser { /// Returns [`UnpadError`] if padding is malformed or if input length is /// not multiple of `Self::BlockSize`. #[cfg(feature = "block-padding")] - #[cfg_attr(docsrs, doc(cfg(feature = "block-padding")))] #[inline] fn decrypt_padded_b2b<'a, P: Padding>( &self, @@ -305,7 +298,6 @@ pub trait BlockDecrypt: BlockSizeUser { /// Returns [`UnpadError`] if padding is malformed or if input length is /// not multiple of `Self::BlockSize`. #[cfg(all(feature = "block-padding", feature = "alloc"))] - #[cfg_attr(docsrs, doc(cfg(all(feature = "block-padding", feature = "alloc"))))] #[inline] fn decrypt_padded_vec>( &self, @@ -378,7 +370,6 @@ pub trait BlockEncryptMut: BlockSizeUser + Sized { /// /// Returns [`PadError`] if length of output buffer is not sufficient. #[cfg(feature = "block-padding")] - #[cfg_attr(docsrs, doc(cfg(feature = "block-padding")))] #[inline] fn encrypt_padded_inout_mut<'out, P: Padding>( mut self, @@ -396,7 +387,6 @@ pub trait BlockEncryptMut: BlockSizeUser + Sized { /// /// Returns [`PadError`] if length of output buffer is not sufficient. #[cfg(feature = "block-padding")] - #[cfg_attr(docsrs, doc(cfg(feature = "block-padding")))] #[inline] fn encrypt_padded_mut>( self, @@ -411,7 +401,6 @@ pub trait BlockEncryptMut: BlockSizeUser + Sized { /// /// Returns [`PadError`] if length of output buffer is not sufficient. #[cfg(feature = "block-padding")] - #[cfg_attr(docsrs, doc(cfg(feature = "block-padding")))] #[inline] fn encrypt_padded_b2b_mut<'a, P: Padding>( self, @@ -424,7 +413,6 @@ pub trait BlockEncryptMut: BlockSizeUser + Sized { /// Pad input and encrypt into a newly allocated Vec. Returns resulting ciphertext Vec. #[cfg(all(feature = "block-padding", feature = "alloc"))] - #[cfg_attr(docsrs, doc(cfg(all(feature = "block-padding", feature = "alloc"))))] #[inline] fn encrypt_padded_vec_mut>(self, msg: &[u8]) -> Vec { let mut out = allocate_out_vec::(msg.len()); @@ -498,7 +486,6 @@ pub trait BlockDecryptMut: BlockSizeUser + Sized { /// Returns [`UnpadError`] if padding is malformed or if input length is /// not multiple of `Self::BlockSize`. #[cfg(feature = "block-padding")] - #[cfg_attr(docsrs, doc(cfg(feature = "block-padding")))] #[inline] fn decrypt_padded_inout_mut<'out, P: Padding>( mut self, @@ -517,7 +504,6 @@ pub trait BlockDecryptMut: BlockSizeUser + Sized { /// Returns [`UnpadError`] if padding is malformed or if input length is /// not multiple of `Self::BlockSize`. #[cfg(feature = "block-padding")] - #[cfg_attr(docsrs, doc(cfg(feature = "block-padding")))] #[inline] fn decrypt_padded_mut>( self, @@ -532,7 +518,6 @@ pub trait BlockDecryptMut: BlockSizeUser + Sized { /// Returns [`UnpadError`] if padding is malformed or if input length is /// not multiple of `Self::BlockSize`. #[cfg(feature = "block-padding")] - #[cfg_attr(docsrs, doc(cfg(feature = "block-padding")))] #[inline] fn decrypt_padded_b2b_mut<'a, P: Padding>( self, @@ -554,7 +539,6 @@ pub trait BlockDecryptMut: BlockSizeUser + Sized { /// Returns [`UnpadError`] if padding is malformed or if input length is /// not multiple of `Self::BlockSize`. #[cfg(all(feature = "block-padding", feature = "alloc"))] - #[cfg_attr(docsrs, doc(cfg(all(feature = "block-padding", feature = "alloc"))))] #[inline] fn decrypt_padded_vec_mut>( self, diff --git a/cipher/src/dev/block.rs b/cipher/src/dev/block.rs index ee0995dba..101d5af84 100644 --- a/cipher/src/dev/block.rs +++ b/cipher/src/dev/block.rs @@ -4,7 +4,6 @@ pub use blobby; /// Define block cipher test #[macro_export] -#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] macro_rules! block_cipher_test { ($name:ident, $test_name:expr, $cipher:ty $(,)?) => { #[test] @@ -99,7 +98,6 @@ macro_rules! block_cipher_test { /// Define block mode encryption test #[macro_export] -#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] macro_rules! block_mode_enc_test { ($name:ident, $test_name:expr, $cipher:ty $(,)?) => { #[test] @@ -158,7 +156,6 @@ macro_rules! block_mode_enc_test { /// Define block mode decryption test #[macro_export] -#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] macro_rules! block_mode_dec_test { ($name:ident, $test_name:expr, $cipher:ty $(,)?) => { #[test] @@ -217,7 +214,6 @@ macro_rules! block_mode_dec_test { /// Define `IvState` test #[macro_export] -#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] macro_rules! iv_state_test { ($name:ident, $cipher:ty, encrypt $(,)?) => { $crate::iv_state_test!($name, $cipher, encrypt_blocks_mut); @@ -266,7 +262,6 @@ macro_rules! iv_state_test { /// Define block encryptor benchmark #[macro_export] -#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] macro_rules! block_encryptor_bench { (Key: $cipher:ty, $block_name:ident, $blocks_name:ident $(,)? ) => { $crate::block_encryptor_bench!( @@ -328,7 +323,6 @@ macro_rules! block_encryptor_bench { /// Define block decryptor benchmark #[macro_export] -#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] macro_rules! block_decryptor_bench { (Key: $cipher:ty, $block_name:ident, $blocks_name:ident $(,)? ) => { $crate::block_decryptor_bench!( diff --git a/cipher/src/dev/stream.rs b/cipher/src/dev/stream.rs index d65f80c70..5502b7fe8 100644 --- a/cipher/src/dev/stream.rs +++ b/cipher/src/dev/stream.rs @@ -2,7 +2,6 @@ /// Test core functionality of synchronous stream cipher #[macro_export] -#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] macro_rules! stream_cipher_test { ($name:ident, $test_name:expr, $cipher:ty $(,)?) => { #[test] @@ -38,7 +37,6 @@ macro_rules! stream_cipher_test { /// Test stream synchronous stream cipher seeking capabilities #[macro_export] -#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] macro_rules! stream_cipher_seek_test { ($name:ident, $cipher:ty) => { #[test] @@ -91,7 +89,6 @@ macro_rules! stream_cipher_seek_test { /// Create stream cipher benchmarks #[macro_export] -#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] macro_rules! stream_cipher_bench { ( $cipher:ty; diff --git a/cipher/src/errors.rs b/cipher/src/errors.rs index 0dc32740e..acd2f488a 100644 --- a/cipher/src/errors.rs +++ b/cipher/src/errors.rs @@ -18,7 +18,6 @@ impl fmt::Display for StreamCipherError { } #[cfg(feature = "std")] -#[cfg_attr(docsrs, doc(cfg(feature = "std")))] impl std::error::Error for StreamCipherError {} /// The error type returned when a cipher position can not be represented @@ -39,5 +38,4 @@ impl From for StreamCipherError { } #[cfg(feature = "std")] -#[cfg_attr(docsrs, doc(cfg(feature = "std")))] impl std::error::Error for OverflowError {} diff --git a/cipher/src/lib.rs b/cipher/src/lib.rs index fc476b626..7554690ea 100644 --- a/cipher/src/lib.rs +++ b/cipher/src/lib.rs @@ -6,7 +6,7 @@ //! [3]: https://en.wikipedia.org/wiki/Stream_cipher #![no_std] -#![cfg_attr(docsrs, feature(doc_cfg))] +#![cfg_attr(docsrs, feature(doc_auto_cfg))] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg" @@ -23,15 +23,12 @@ extern crate alloc; extern crate std; #[cfg(feature = "rand_core")] -#[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] pub use crypto_common::rand_core; #[cfg(feature = "block-padding")] -#[cfg_attr(docsrs, doc(cfg(feature = "block-padding")))] pub use inout::block_padding; #[cfg(feature = "zeroize")] -#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] pub use zeroize; #[cfg(feature = "dev")] diff --git a/crypto-common/src/lib.rs b/crypto-common/src/lib.rs index 420bb7a59..570586050 100644 --- a/crypto-common/src/lib.rs +++ b/crypto-common/src/lib.rs @@ -1,7 +1,7 @@ //! Common cryptographic traits. #![no_std] -#![cfg_attr(docsrs, feature(doc_cfg))] +#![cfg_attr(docsrs, feature(doc_auto_cfg))] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg" @@ -158,7 +158,6 @@ pub trait KeyInit: KeySizeUser + Sized { /// Generate random key using the provided [`CryptoRngCore`]. #[cfg(feature = "rand_core")] - #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] #[inline] fn generate_key(mut rng: impl CryptoRngCore) -> Key { let mut key = Key::::default(); @@ -182,7 +181,6 @@ pub trait KeyIvInit: KeySizeUser + IvSizeUser + Sized { /// Generate random key using the provided [`CryptoRngCore`]. #[cfg(feature = "rand_core")] - #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] #[inline] fn generate_key(mut rng: impl CryptoRngCore) -> Key { let mut key = Key::::default(); @@ -192,7 +190,6 @@ pub trait KeyIvInit: KeySizeUser + IvSizeUser + Sized { /// Generate random IV using the provided [`CryptoRngCore`]. #[cfg(feature = "rand_core")] - #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] #[inline] fn generate_iv(mut rng: impl CryptoRngCore) -> Iv { let mut iv = Iv::::default(); @@ -202,7 +199,6 @@ pub trait KeyIvInit: KeySizeUser + IvSizeUser + Sized { /// Generate random key and nonce using the provided [`CryptoRngCore`]. #[cfg(feature = "rand_core")] - #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] #[inline] fn generate_key_iv(mut rng: impl CryptoRngCore) -> (Key, Iv) { (Self::generate_key(&mut rng), Self::generate_iv(&mut rng)) @@ -234,7 +230,6 @@ pub trait InnerIvInit: InnerUser + IvSizeUser + Sized { /// Generate random IV using the provided [`CryptoRngCore`]. #[cfg(feature = "rand_core")] - #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] #[inline] fn generate_iv(mut rng: impl CryptoRngCore) -> Iv { let mut iv = Iv::::default(); diff --git a/digest/src/core_api/ct_variable.rs b/digest/src/core_api/ct_variable.rs index c06f13904..b93e7ea77 100644 --- a/digest/src/core_api/ct_variable.rs +++ b/digest/src/core_api/ct_variable.rs @@ -152,7 +152,6 @@ where } #[cfg(feature = "oid")] -#[cfg_attr(docsrs, doc(cfg(feature = "oid")))] impl AssociatedOid for CtVariableCoreWrapper where T: VariableOutputCore, diff --git a/digest/src/core_api/rt_variable.rs b/digest/src/core_api/rt_variable.rs index 94708ee77..c58021f89 100644 --- a/digest/src/core_api/rt_variable.rs +++ b/digest/src/core_api/rt_variable.rs @@ -48,7 +48,6 @@ where impl HashMarker for RtVariableCoreWrapper where T: VariableOutputCore + HashMarker {} #[cfg(feature = "mac")] -#[cfg_attr(docsrs, doc(cfg(feature = "mac")))] impl MacMarker for RtVariableCoreWrapper where T: VariableOutputCore + MacMarker {} impl Reset for RtVariableCoreWrapper @@ -120,7 +119,6 @@ where } #[cfg(feature = "std")] -#[cfg_attr(docsrs, doc(cfg(feature = "std")))] impl std::io::Write for RtVariableCoreWrapper where T: VariableOutputCore + UpdateCore, diff --git a/digest/src/core_api/wrapper.rs b/digest/src/core_api/wrapper.rs index af77b11c8..c0b25f428 100644 --- a/digest/src/core_api/wrapper.rs +++ b/digest/src/core_api/wrapper.rs @@ -29,7 +29,6 @@ where impl HashMarker for CoreWrapper where T: BufferKindUser + HashMarker {} #[cfg(feature = "mac")] -#[cfg_attr(docsrs, doc(cfg(feature = "mac")))] impl MacMarker for CoreWrapper where T: BufferKindUser + MacMarker {} // this blanket impl is needed for HMAC @@ -185,7 +184,6 @@ where } #[cfg(feature = "oid")] -#[cfg_attr(docsrs, doc(cfg(feature = "oid")))] impl AssociatedOid for CoreWrapper where T: BufferKindUser + AssociatedOid, @@ -194,7 +192,6 @@ where } #[cfg(feature = "std")] -#[cfg_attr(docsrs, doc(cfg(feature = "std")))] impl std::io::Write for CoreWrapper where T: BufferKindUser + UpdateCore, diff --git a/digest/src/core_api/xof_reader.rs b/digest/src/core_api/xof_reader.rs index 665e2a76d..8c92f3d15 100644 --- a/digest/src/core_api/xof_reader.rs +++ b/digest/src/core_api/xof_reader.rs @@ -37,7 +37,6 @@ where } #[cfg(feature = "std")] -#[cfg_attr(docsrs, doc(cfg(feature = "std")))] impl std::io::Read for XofReaderCoreWrapper where T: XofReaderCore, diff --git a/digest/src/dev.rs b/digest/src/dev.rs index 438089574..e300bda32 100644 --- a/digest/src/dev.rs +++ b/digest/src/dev.rs @@ -15,7 +15,6 @@ pub use xof::*; /// Define hash function test #[macro_export] -#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] macro_rules! new_test { ($name:ident, $test_name:expr, $hasher:ty, $test_func:ident $(,)?) => { #[test] @@ -41,7 +40,6 @@ macro_rules! new_test { /// Define [`Update`][crate::Update] impl benchmark #[macro_export] -#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] macro_rules! bench_update { ( $init:expr; diff --git a/digest/src/dev/mac.rs b/digest/src/dev/mac.rs index 18f985471..969a18b03 100644 --- a/digest/src/dev/mac.rs +++ b/digest/src/dev/mac.rs @@ -1,7 +1,6 @@ /// Define MAC test #[macro_export] #[cfg(feature = "mac")] -#[cfg_attr(docsrs, doc(cfg(all(feature = "dev", feature = "mac"))))] macro_rules! new_mac_test { ($name:ident, $test_name:expr, $mac:ty $(,)?) => { digest::new_mac_test!($name, $test_name, $mac, ""); @@ -76,7 +75,6 @@ macro_rules! new_mac_test { /// Define resettable MAC test #[macro_export] #[cfg(feature = "mac")] -#[cfg_attr(docsrs, doc(cfg(all(feature = "dev", feature = "mac"))))] macro_rules! new_resettable_mac_test { ($name:ident, $test_name:expr, $mac:ty $(,)?) => { digest::new_resettable_mac_test!($name, $test_name, $mac, ""); diff --git a/digest/src/digest.rs b/digest/src/digest.rs index 1a332505d..0642af43c 100644 --- a/digest/src/digest.rs +++ b/digest/src/digest.rs @@ -137,7 +137,6 @@ pub trait DynDigest { /// Retrieve result and reset hasher instance #[cfg(feature = "alloc")] - #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] fn finalize_reset(&mut self) -> Box<[u8]> { let mut result = vec![0; self.output_size()]; self.finalize_into_reset(&mut result).unwrap(); @@ -146,7 +145,6 @@ pub trait DynDigest { /// Retrieve result and consume boxed hasher instance #[cfg(feature = "alloc")] - #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] #[allow(clippy::boxed_local)] fn finalize(mut self: Box) -> Box<[u8]> { let mut result = vec![0; self.output_size()]; @@ -172,7 +170,6 @@ pub trait DynDigest { /// Clone hasher state into a boxed trait object #[cfg(feature = "alloc")] - #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] fn box_clone(&self) -> Box; } @@ -222,7 +219,6 @@ impl DynDigest for D { } #[cfg(feature = "alloc")] -#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] impl Clone for Box { fn clone(&self) -> Self { self.box_clone() diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 911133d7e..b076853b8 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -23,7 +23,7 @@ //! by hash implementation crates. #![no_std] -#![cfg_attr(docsrs, feature(doc_cfg))] +#![cfg_attr(docsrs, feature(doc_auto_cfg))] #![forbid(unsafe_code)] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", @@ -39,28 +39,23 @@ extern crate alloc; extern crate std; #[cfg(feature = "rand_core")] -#[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] pub use crypto_common::rand_core; #[cfg(feature = "alloc")] use alloc::boxed::Box; #[cfg(feature = "dev")] -#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] pub mod dev; #[cfg(feature = "core-api")] -#[cfg_attr(docsrs, doc(cfg(feature = "core-api")))] pub mod core_api; mod digest; #[cfg(feature = "mac")] mod mac; #[cfg(feature = "core-api")] -#[cfg_attr(docsrs, doc(cfg(feature = "core-api")))] pub use block_buffer; #[cfg(feature = "oid")] -#[cfg_attr(docsrs, doc(cfg(feature = "oid")))] pub use const_oid; pub use crypto_common; @@ -130,7 +125,6 @@ pub trait XofReader { /// `Box<[u8]>` is used instead of `Vec` to save stack space, since /// they have size of 2 and 3 words respectively. #[cfg(feature = "alloc")] - #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] fn read_boxed(&mut self, n: usize) -> Box<[u8]> { let mut buf = vec![0u8; n].into_boxed_slice(); self.read(&mut buf); @@ -167,7 +161,6 @@ pub trait ExtendableOutput: Sized + Update { /// `Box<[u8]>` is used instead of `Vec` to save stack space, since /// they have size of 2 and 3 words respectively. #[cfg(feature = "alloc")] - #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] fn finalize_boxed(self, output_size: usize) -> Box<[u8]> { let mut buf = vec![0u8; output_size].into_boxed_slice(); self.finalize_xof().read(&mut buf); @@ -191,7 +184,6 @@ pub trait ExtendableOutputReset: ExtendableOutput + Reset { /// `Box<[u8]>` is used instead of `Vec` to save stack space, since /// they have size of 2 and 3 words respectively. #[cfg(feature = "alloc")] - #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] fn finalize_boxed_reset(&mut self, output_size: usize) -> Box<[u8]> { let mut buf = vec![0u8; output_size].into_boxed_slice(); self.finalize_xof_reset().read(&mut buf); @@ -240,7 +232,6 @@ pub trait VariableOutput: Sized + Update { /// `Box<[u8]>` is used instead of `Vec` to save stack space, since /// they have size of 2 and 3 words respectively. #[cfg(feature = "alloc")] - #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] fn finalize_boxed(self) -> Box<[u8]> { let n = self.output_size(); let mut buf = vec![0u8; n].into_boxed_slice(); @@ -263,7 +254,6 @@ pub trait VariableOutputReset: VariableOutput + Reset { /// `Box<[u8]>` is used instead of `Vec` to save stack space, since /// they have size of 2 and 3 words respectively. #[cfg(feature = "alloc")] - #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] fn finalize_boxed_reset(&mut self) -> Box<[u8]> { let n = self.output_size(); let mut buf = vec![0u8; n].into_boxed_slice(); @@ -284,7 +274,6 @@ impl fmt::Display for InvalidOutputSize { } #[cfg(feature = "std")] -#[cfg_attr(docsrs, doc(cfg(feature = "std")))] impl std::error::Error for InvalidOutputSize {} /// Buffer length is not equal to hash output size. diff --git a/digest/src/mac.rs b/digest/src/mac.rs index 9e91b8ef7..f39e9e32a 100644 --- a/digest/src/mac.rs +++ b/digest/src/mac.rs @@ -6,14 +6,12 @@ use crypto_common::typenum::Unsigned; use subtle::{Choice, ConstantTimeEq}; /// Marker trait for Message Authentication algorithms. -#[cfg_attr(docsrs, doc(cfg(feature = "mac")))] pub trait MacMarker {} /// Convenience wrapper trait covering functionality of Message Authentication algorithms. /// /// This trait wraps [`Update`], [`FixedOutput`], and [`MacMarker`] traits /// and provides additional convenience methods. -#[cfg_attr(docsrs, doc(cfg(feature = "mac")))] pub trait Mac: OutputSizeUser + Sized { /// Update state using the provided data. fn update(&mut self, data: &[u8]); @@ -195,7 +193,6 @@ impl Mac for T { /// /// It is useful for implementing Message Authentication Codes (MACs). #[derive(Clone)] -#[cfg_attr(docsrs, doc(cfg(feature = "mac")))] pub struct CtOutput { bytes: Output, } @@ -247,7 +244,6 @@ impl Eq for CtOutput {} /// Error type for when the [`Output`] of a [`Mac`] /// is not equal to the expected value. #[derive(Default, Debug, Copy, Clone, Eq, PartialEq)] -#[cfg_attr(docsrs, doc(cfg(feature = "mac")))] pub struct MacError; impl fmt::Display for MacError { diff --git a/kem/src/lib.rs b/kem/src/lib.rs index 8ba35a1ed..5230bc663 100644 --- a/kem/src/lib.rs +++ b/kem/src/lib.rs @@ -1,6 +1,6 @@ #![doc = include_str!("../README.md")] #![no_std] -#![cfg_attr(docsrs, feature(doc_cfg))] +#![cfg_attr(docsrs, feature(doc_auto_cfg))] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", diff --git a/universal-hash/src/lib.rs b/universal-hash/src/lib.rs index f11e48fb1..87c963a4f 100644 --- a/universal-hash/src/lib.rs +++ b/universal-hash/src/lib.rs @@ -22,7 +22,7 @@ html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg" )] -#![cfg_attr(docsrs, feature(doc_cfg))] +#![cfg_attr(docsrs, feature(doc_auto_cfg))] #![deny(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] @@ -172,7 +172,6 @@ impl core::fmt::Display for Error { } #[cfg(feature = "std")] -#[cfg_attr(docsrs, doc(cfg(feature = "std")))] impl std::error::Error for Error {} /// Split message into slice of blocks and leftover tail. From 128d4e6df73f9ec528e0b0a6dd88a9e6917aa221 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 31 Oct 2023 13:19:58 -0600 Subject: [PATCH 1057/1461] crypto-common: change `generate_*` to support getrandom (#1371) This commit splits the existing `generate_*` functions into two different variants: - `fn generate_*`: accepts no parameters and uses `OsRng` automatically. Gated on the `getrandom` feature. - `fn generate_*_with_rng`: accepts a `&mut impl CryptoRngCore` parameter. Gated on the `rand_core`. Previously all of the `generate_*` methods were parameterized on a `CryptoRngCore`. Splitting them up like this makes it very easy for users to do the right thing, which is use `getrandom`/`OsRng`, but without the need to document how to import `OsRng` into their code everywhere. Retaining the parameterized versions as `*_with_rng` allows users to pass a custom RNG where it makes sense, for example `rand::thread_rng`, or potentially an embedded peripheral/entropy pool. --- crypto-common/src/lib.rs | 55 +++++++++++++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 7 deletions(-) diff --git a/crypto-common/src/lib.rs b/crypto-common/src/lib.rs index 570586050..d3303ca45 100644 --- a/crypto-common/src/lib.rs +++ b/crypto-common/src/lib.rs @@ -20,8 +20,11 @@ pub use hybrid_array::typenum; use core::fmt; use hybrid_array::{typenum::Unsigned, Array, ArraySize, ByteArray}; + #[cfg(feature = "rand_core")] use rand_core::CryptoRngCore; +#[cfg(feature = "getrandom")] +use rand_core::OsRng; /// Block on which [`BlockSizeUser`] implementors operate. pub type Block = ByteArray<::BlockSize>; @@ -156,10 +159,17 @@ pub trait KeyInit: KeySizeUser + Sized { .map_err(|_| InvalidLength) } + /// Generate random key using the operating system's secure RNG. + #[cfg(feature = "getrandom")] + #[inline] + fn generate_key() -> Key { + Self::generate_key_with_rng(&mut OsRng) + } + /// Generate random key using the provided [`CryptoRngCore`]. #[cfg(feature = "rand_core")] #[inline] - fn generate_key(mut rng: impl CryptoRngCore) -> Key { + fn generate_key_with_rng(rng: &mut impl CryptoRngCore) -> Key { let mut key = Key::::default(); rng.fill_bytes(&mut key); key @@ -179,29 +189,53 @@ pub trait KeyIvInit: KeySizeUser + IvSizeUser + Sized { Ok(Self::new(key, iv)) } + /// Generate random key using the operating system's secure RNG. + #[cfg(feature = "getrandom")] + #[inline] + fn generate_key() -> Key { + Self::generate_key_with_rng(&mut OsRng) + } + /// Generate random key using the provided [`CryptoRngCore`]. #[cfg(feature = "rand_core")] #[inline] - fn generate_key(mut rng: impl CryptoRngCore) -> Key { + fn generate_key_with_rng(rng: &mut impl CryptoRngCore) -> Key { let mut key = Key::::default(); rng.fill_bytes(&mut key); key } + /// Generate random IV using the operating system's secure RNG. + #[cfg(feature = "getrandom")] + #[inline] + fn generate_iv() -> Iv { + Self::generate_iv_with_rng(&mut OsRng) + } + /// Generate random IV using the provided [`CryptoRngCore`]. #[cfg(feature = "rand_core")] #[inline] - fn generate_iv(mut rng: impl CryptoRngCore) -> Iv { + fn generate_iv_with_rng(rng: &mut impl CryptoRngCore) -> Iv { let mut iv = Iv::::default(); rng.fill_bytes(&mut iv); iv } - /// Generate random key and nonce using the provided [`CryptoRngCore`]. + /// Generate random key and IV using the operating system's secure RNG. + #[cfg(feature = "getrandom")] + #[inline] + fn generate_key_iv() -> (Key, Iv) { + Self::generate_key_iv_with_rng(&mut OsRng) + } + + /// Generate random key and IV using the provided [`CryptoRngCore`]. #[cfg(feature = "rand_core")] #[inline] - fn generate_key_iv(mut rng: impl CryptoRngCore) -> (Key, Iv) { - (Self::generate_key(&mut rng), Self::generate_iv(&mut rng)) + fn generate_key_iv_with_rng(rng: &mut impl CryptoRngCore) -> (Key, Iv) { + ( + Self::generate_key_with_rng(rng), + Self::generate_iv_with_rng(rng), + ) } } @@ -228,10 +262,17 @@ pub trait InnerIvInit: InnerUser + IvSizeUser + Sized { Ok(Self::inner_iv_init(inner, iv)) } + /// Generate random IV using the operating system's secure RNG. + #[cfg(feature = "getrandom")] + #[inline] + fn generate_iv() -> Iv { + Self::generate_iv_with_rng(&mut OsRng) + } + /// Generate random IV using the provided [`CryptoRngCore`]. #[cfg(feature = "rand_core")] #[inline] - fn generate_iv(mut rng: impl CryptoRngCore) -> Iv { + fn generate_iv_with_rng(rng: &mut impl CryptoRngCore) -> Iv { let mut iv = Iv::::default(); rng.fill_bytes(&mut iv); iv From 6497790f8e11a8c2d0f2897bc448b2b40aab1f9d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 11 Nov 2023 14:08:25 -0700 Subject: [PATCH 1058/1461] crypto-common: add fallible `try_generate_*_with_rng` (#1377) Adds a fallible `try_*` variant to each `generate_*_with_rng` function, changing usages of `fill_bytes` to `try_fill_bytes`, and returning a `Result` with `rand_core::Error` in the event an RNG error has occurred. --- crypto-common/src/lib.rs | 69 +++++++++++++++++++++++++++++++++------- 1 file changed, 57 insertions(+), 12 deletions(-) diff --git a/crypto-common/src/lib.rs b/crypto-common/src/lib.rs index d3303ca45..6fd536b49 100644 --- a/crypto-common/src/lib.rs +++ b/crypto-common/src/lib.rs @@ -170,9 +170,18 @@ pub trait KeyInit: KeySizeUser + Sized { #[cfg(feature = "rand_core")] #[inline] fn generate_key_with_rng(rng: &mut impl CryptoRngCore) -> Key { + Self::try_generate_key_with_rng(rng).expect("RNG failure") + } + + /// Generate random key using the provided [`CryptoRngCore`], returning an error on RNG failure. + #[cfg(feature = "rand_core")] + #[inline] + fn try_generate_key_with_rng( + rng: &mut impl CryptoRngCore, + ) -> Result, rand_core::Error> { let mut key = Key::::default(); - rng.fill_bytes(&mut key); - key + rng.try_fill_bytes(&mut key)?; + Ok(key) } } @@ -200,9 +209,18 @@ pub trait KeyIvInit: KeySizeUser + IvSizeUser + Sized { #[cfg(feature = "rand_core")] #[inline] fn generate_key_with_rng(rng: &mut impl CryptoRngCore) -> Key { + Self::try_generate_key_with_rng(rng).expect("RNG failure") + } + + /// Generate random key using the provided [`CryptoRngCore`], returning an error on RNG failure. + #[cfg(feature = "rand_core")] + #[inline] + fn try_generate_key_with_rng( + rng: &mut impl CryptoRngCore, + ) -> Result, rand_core::Error> { let mut key = Key::::default(); - rng.fill_bytes(&mut key); - key + rng.try_fill_bytes(&mut key)?; + Ok(key) } /// Generate random IV using the operating system's secure RNG. @@ -216,9 +234,18 @@ pub trait KeyIvInit: KeySizeUser + IvSizeUser + Sized { #[cfg(feature = "rand_core")] #[inline] fn generate_iv_with_rng(rng: &mut impl CryptoRngCore) -> Iv { + Self::try_generate_iv_with_rng(rng).expect("RNG failure") + } + + /// Generate random IV using the provided [`CryptoRngCore`], returning an error on RNG failure. + #[cfg(feature = "rand_core")] + #[inline] + fn try_generate_iv_with_rng( + rng: &mut impl CryptoRngCore, + ) -> Result, rand_core::Error> { let mut iv = Iv::::default(); - rng.fill_bytes(&mut iv); - iv + rng.try_fill_bytes(&mut iv)?; + Ok(iv) } /// Generate random key and IV using the operating system's secure RNG. @@ -232,10 +259,19 @@ pub trait KeyIvInit: KeySizeUser + IvSizeUser + Sized { #[cfg(feature = "rand_core")] #[inline] fn generate_key_iv_with_rng(rng: &mut impl CryptoRngCore) -> (Key, Iv) { - ( - Self::generate_key_with_rng(rng), - Self::generate_iv_with_rng(rng), - ) + Self::try_generate_key_iv_with_rng(rng).expect("RNG failure") + } + + /// Generate random key and IV using the provided [`CryptoRngCore`], returning an error on RNG + /// failure. + #[cfg(feature = "rand_core")] + #[inline] + fn try_generate_key_iv_with_rng( + rng: &mut impl CryptoRngCore, + ) -> Result<(Key, Iv), rand_core::Error> { + let key = Self::try_generate_key_with_rng(rng)?; + let iv = Self::try_generate_iv_with_rng(rng)?; + Ok((key, iv)) } } @@ -273,9 +309,18 @@ pub trait InnerIvInit: InnerUser + IvSizeUser + Sized { #[cfg(feature = "rand_core")] #[inline] fn generate_iv_with_rng(rng: &mut impl CryptoRngCore) -> Iv { + Self::try_generate_iv_with_rng(rng).expect("RNG failure") + } + + /// Generate random IV using the provided [`CryptoRngCore`], returning an error on RNG failure. + #[cfg(feature = "rand_core")] + #[inline] + fn try_generate_iv_with_rng( + rng: &mut impl CryptoRngCore, + ) -> Result, rand_core::Error> { let mut iv = Iv::::default(); - rng.fill_bytes(&mut iv); - iv + rng.try_fill_bytes(&mut iv)?; + Ok(iv) } } From eb07d10930162842f3466e5f728ef12cd9f56409 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Sun, 12 Nov 2023 02:46:19 +0300 Subject: [PATCH 1059/1461] Return `Result` from all `generate_*` methods (#1379) --- crypto-common/Cargo.toml | 4 +- crypto-common/src/lib.rs | 90 ++++++++++++---------------------------- 2 files changed, 29 insertions(+), 65 deletions(-) diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index beb671fa4..38496ad54 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -6,7 +6,7 @@ authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" edition = "2021" -rust-version = "1.56" +rust-version = "1.65" documentation = "https://docs.rs/crypto-common" repository = "https://github.com/RustCrypto/traits" keywords = ["crypto", "traits"] @@ -17,10 +17,10 @@ hybrid-array = "=0.2.0-pre.5" # optional dependencies rand_core = { version = "0.6.4", optional = true } +getrandom = { version = "0.2", optional = true } [features] std = [] -getrandom = ["rand_core/getrandom"] [package.metadata.docs.rs] all-features = true diff --git a/crypto-common/src/lib.rs b/crypto-common/src/lib.rs index 6fd536b49..5fb3a814a 100644 --- a/crypto-common/src/lib.rs +++ b/crypto-common/src/lib.rs @@ -23,8 +23,6 @@ use hybrid_array::{typenum::Unsigned, Array, ArraySize, ByteArray}; #[cfg(feature = "rand_core")] use rand_core::CryptoRngCore; -#[cfg(feature = "getrandom")] -use rand_core::OsRng; /// Block on which [`BlockSizeUser`] implementors operate. pub type Block = ByteArray<::BlockSize>; @@ -162,23 +160,16 @@ pub trait KeyInit: KeySizeUser + Sized { /// Generate random key using the operating system's secure RNG. #[cfg(feature = "getrandom")] #[inline] - fn generate_key() -> Key { - Self::generate_key_with_rng(&mut OsRng) + fn generate_key() -> Result, getrandom::Error> { + let mut key = Key::::default(); + getrandom::getrandom(&mut key)?; + Ok(key) } /// Generate random key using the provided [`CryptoRngCore`]. #[cfg(feature = "rand_core")] #[inline] - fn generate_key_with_rng(rng: &mut impl CryptoRngCore) -> Key { - Self::try_generate_key_with_rng(rng).expect("RNG failure") - } - - /// Generate random key using the provided [`CryptoRngCore`], returning an error on RNG failure. - #[cfg(feature = "rand_core")] - #[inline] - fn try_generate_key_with_rng( - rng: &mut impl CryptoRngCore, - ) -> Result, rand_core::Error> { + fn generate_key_with_rng(rng: &mut impl CryptoRngCore) -> Result, rand_core::Error> { let mut key = Key::::default(); rng.try_fill_bytes(&mut key)?; Ok(key) @@ -201,23 +192,16 @@ pub trait KeyIvInit: KeySizeUser + IvSizeUser + Sized { /// Generate random key using the operating system's secure RNG. #[cfg(feature = "getrandom")] #[inline] - fn generate_key() -> Key { - Self::generate_key_with_rng(&mut OsRng) + fn generate_key() -> Result, getrandom::Error> { + let mut key = Key::::default(); + getrandom::getrandom(&mut key)?; + Ok(key) } /// Generate random key using the provided [`CryptoRngCore`]. #[cfg(feature = "rand_core")] #[inline] - fn generate_key_with_rng(rng: &mut impl CryptoRngCore) -> Key { - Self::try_generate_key_with_rng(rng).expect("RNG failure") - } - - /// Generate random key using the provided [`CryptoRngCore`], returning an error on RNG failure. - #[cfg(feature = "rand_core")] - #[inline] - fn try_generate_key_with_rng( - rng: &mut impl CryptoRngCore, - ) -> Result, rand_core::Error> { + fn generate_key_with_rng(rng: &mut impl CryptoRngCore) -> Result, rand_core::Error> { let mut key = Key::::default(); rng.try_fill_bytes(&mut key)?; Ok(key) @@ -226,23 +210,16 @@ pub trait KeyIvInit: KeySizeUser + IvSizeUser + Sized { /// Generate random IV using the operating system's secure RNG. #[cfg(feature = "getrandom")] #[inline] - fn generate_iv() -> Iv { - Self::generate_iv_with_rng(&mut OsRng) + fn generate_iv() -> Result, getrandom::Error> { + let mut iv = Iv::::default(); + getrandom::getrandom(&mut iv)?; + Ok(iv) } /// Generate random IV using the provided [`CryptoRngCore`]. #[cfg(feature = "rand_core")] #[inline] - fn generate_iv_with_rng(rng: &mut impl CryptoRngCore) -> Iv { - Self::try_generate_iv_with_rng(rng).expect("RNG failure") - } - - /// Generate random IV using the provided [`CryptoRngCore`], returning an error on RNG failure. - #[cfg(feature = "rand_core")] - #[inline] - fn try_generate_iv_with_rng( - rng: &mut impl CryptoRngCore, - ) -> Result, rand_core::Error> { + fn generate_iv_with_rng(rng: &mut impl CryptoRngCore) -> Result, rand_core::Error> { let mut iv = Iv::::default(); rng.try_fill_bytes(&mut iv)?; Ok(iv) @@ -251,26 +228,20 @@ pub trait KeyIvInit: KeySizeUser + IvSizeUser + Sized { /// Generate random key and IV using the operating system's secure RNG. #[cfg(feature = "getrandom")] #[inline] - fn generate_key_iv() -> (Key, Iv) { - Self::generate_key_iv_with_rng(&mut OsRng) + fn generate_key_iv() -> Result<(Key, Iv), getrandom::Error> { + let key = Self::generate_key()?; + let iv = Self::generate_iv()?; + Ok((key, iv)) } /// Generate random key and IV using the provided [`CryptoRngCore`]. #[cfg(feature = "rand_core")] #[inline] - fn generate_key_iv_with_rng(rng: &mut impl CryptoRngCore) -> (Key, Iv) { - Self::try_generate_key_iv_with_rng(rng).expect("RNG failure") - } - - /// Generate random key and IV using the provided [`CryptoRngCore`], returning an error on RNG - /// failure. - #[cfg(feature = "rand_core")] - #[inline] - fn try_generate_key_iv_with_rng( + fn generate_key_iv_with_rng( rng: &mut impl CryptoRngCore, ) -> Result<(Key, Iv), rand_core::Error> { - let key = Self::try_generate_key_with_rng(rng)?; - let iv = Self::try_generate_iv_with_rng(rng)?; + let key = Self::generate_key_with_rng(rng)?; + let iv = Self::generate_iv_with_rng(rng)?; Ok((key, iv)) } } @@ -301,23 +272,16 @@ pub trait InnerIvInit: InnerUser + IvSizeUser + Sized { /// Generate random IV using the operating system's secure RNG. #[cfg(feature = "getrandom")] #[inline] - fn generate_iv() -> Iv { - Self::generate_iv_with_rng(&mut OsRng) + fn generate_iv() -> Result, getrandom::Error> { + let mut iv = Iv::::default(); + getrandom::getrandom(&mut iv)?; + Ok(iv) } /// Generate random IV using the provided [`CryptoRngCore`]. #[cfg(feature = "rand_core")] #[inline] - fn generate_iv_with_rng(rng: &mut impl CryptoRngCore) -> Iv { - Self::try_generate_iv_with_rng(rng).expect("RNG failure") - } - - /// Generate random IV using the provided [`CryptoRngCore`], returning an error on RNG failure. - #[cfg(feature = "rand_core")] - #[inline] - fn try_generate_iv_with_rng( - rng: &mut impl CryptoRngCore, - ) -> Result, rand_core::Error> { + fn generate_iv_with_rng(rng: &mut impl CryptoRngCore) -> Result, rand_core::Error> { let mut iv = Iv::::default(); rng.try_fill_bytes(&mut iv)?; Ok(iv) From 1d0810dbe9951167a805033e11871416e0f0bac6 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 11 Nov 2023 18:01:35 -0700 Subject: [PATCH 1060/1461] Exclude pre-1.60 crates from workspace (#1380) Pre-1.60 crates can't be used in workspaces with other crates that use namespaced/weak features. This commit places all MSRV 1.60+ crates into `members` and moves the ones with earlier MSRVs into `exclude`. --- .github/workflows/async-signature.yml | 7 +- .github/workflows/crypto.yml | 11 - .github/workflows/universal-hash.yml | 4 - Cargo.lock | 369 ++++++++++------- Cargo.toml | 12 +- aead/Cargo.lock | 151 +++++++ crypto/Cargo.lock | 290 ------------- elliptic-curve/Cargo.lock | 380 ------------------ elliptic-curve/src/dev.rs | 1 - .../hash2curve/hash2field/expand_msg/xmd.rs | 3 - elliptic-curve/src/hash2curve/isogeny.rs | 1 - elliptic-curve/src/lib.rs | 1 - elliptic-curve/src/public_key.rs | 3 +- elliptic-curve/src/sec1.rs | 2 +- elliptic-curve/src/secret_key.rs | 4 +- signature/Cargo.lock | 189 +++++++++ signature/Cargo.toml | 4 + universal-hash/Cargo.lock | 49 +++ 18 files changed, 640 insertions(+), 841 deletions(-) create mode 100644 aead/Cargo.lock delete mode 100644 crypto/Cargo.lock delete mode 100644 elliptic-curve/Cargo.lock create mode 100644 signature/Cargo.lock create mode 100644 universal-hash/Cargo.lock diff --git a/.github/workflows/async-signature.yml b/.github/workflows/async-signature.yml index 4ae365481..497530a18 100644 --- a/.github/workflows/async-signature.yml +++ b/.github/workflows/async-signature.yml @@ -39,10 +39,9 @@ jobs: steps: - uses: actions/checkout@v4 - uses: RustCrypto/actions/cargo-cache@master - - uses: dtolnay/rust-toolchain@master - with: - toolchain: nightly + - uses: dtolnay/rust-toolchain@nightly + - run: cargo update -Z minimal-versions + - uses: dtolnay/rust-toolchain@stable - uses: RustCrypto/actions/cargo-hack-install@master - run: rm ../../Cargo.toml - - run: cargo update -Z minimal-versions - run: cargo hack test --release --feature-powerset diff --git a/.github/workflows/crypto.yml b/.github/workflows/crypto.yml index c0294947a..d3ec5fa81 100644 --- a/.github/workflows/crypto.yml +++ b/.github/workflows/crypto.yml @@ -67,14 +67,3 @@ jobs: - run: cargo test --no-default-features --release - run: cargo test --release - run: cargo test --all-features --release - - clippy: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: RustCrypto/actions/cargo-cache@master - - uses: dtolnay/rust-toolchain@master - with: - toolchain: 1.65.0 - components: clippy - - run: cargo clippy --all --all-features -- -D warnings diff --git a/.github/workflows/universal-hash.yml b/.github/workflows/universal-hash.yml index c87c3909c..f00cfe0f8 100644 --- a/.github/workflows/universal-hash.yml +++ b/.github/workflows/universal-hash.yml @@ -34,8 +34,6 @@ jobs: with: toolchain: ${{ matrix.rust }} targets: ${{ matrix.target }} - # Isolate this crate from workspace which is otherwise MSRV 1.56 due to 2021 edition crates - - run: rm ../Cargo.toml - run: cargo build --no-default-features --release --target ${{ matrix.target }} minimal-versions: @@ -56,8 +54,6 @@ jobs: - uses: dtolnay/rust-toolchain@master with: toolchain: ${{ matrix.rust }} - # Isolate this crate from workspace which is otherwise MSRV 1.56 due to 2021 edition crates - - run: rm ../Cargo.toml - run: cargo check --all-features - run: cargo test --no-default-features --release - run: cargo test --release diff --git a/Cargo.lock b/Cargo.lock index cc4f6fb2b..b9bfc7bbf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6,12 +6,8 @@ version = 3 name = "aead" version = "0.5.2" dependencies = [ - "arrayvec", - "blobby", - "bytes", "crypto-common 0.1.6", "generic-array", - "heapless", ] [[package]] @@ -50,56 +46,22 @@ dependencies = [ ] [[package]] -name = "arrayvec" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" - -[[package]] -name = "async-signature" -version = "0.3.0" -dependencies = [ - "async-trait", - "signature 2.1.0", -] - -[[package]] -name = "async-trait" -version = "0.1.74" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "atomic-polyfill" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ff7eb3f316534d83a8a2c3d1674ace8a5a71198eba31e2e2b597833f699b28" -dependencies = [ - "critical-section", -] - -[[package]] -name = "autocfg" -version = "1.1.0" +name = "base16ct" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" [[package]] name = "base16ct" -version = "0.1.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" [[package]] name = "base64ct" -version = "1.1.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6b4d9b1225d28d360ec6a231d65af1fd99a2a095154c8040689617290569c5c" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "bincode" @@ -110,6 +72,18 @@ dependencies = [ "serde", ] +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + [[package]] name = "blobby" version = "0.3.1" @@ -142,6 +116,15 @@ dependencies = [ "crypto-common 0.2.0-pre", ] +[[package]] +name = "block-padding" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" +dependencies = [ + "generic-array", +] + [[package]] name = "block-padding" version = "0.4.0-pre" @@ -156,12 +139,6 @@ version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" -[[package]] -name = "bytes" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" - [[package]] name = "cc" version = "1.0.83" @@ -245,10 +222,18 @@ dependencies = [ ] [[package]] -name = "critical-section" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216" +name = "crypto" +version = "0.5.1" +dependencies = [ + "aead 0.5.2", + "cipher 0.4.4", + "crypto-common 0.1.6", + "digest 0.10.7", + "elliptic-curve 0.13.6", + "password-hash", + "signature 2.1.0", + "universal-hash 0.5.1", +] [[package]] name = "crypto-bigint" @@ -274,6 +259,18 @@ dependencies = [ "zeroize", ] +[[package]] +name = "crypto-bigint" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + [[package]] name = "crypto-common" version = "0.1.6" @@ -343,6 +340,17 @@ dependencies = [ "const-oid 0.9.5", ] +[[package]] +name = "der" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +dependencies = [ + "const-oid 0.9.5", + "pem-rfc7468 0.7.0", + "zeroize", +] + [[package]] name = "digest" version = "0.9.0" @@ -402,7 +410,7 @@ dependencies = [ "ff 0.10.1", "generic-array", "group 0.10.0", - "pkcs8", + "pkcs8 0.7.6", "rand_core 0.6.4", "subtle", "zeroize", @@ -414,7 +422,7 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" dependencies = [ - "base16ct", + "base16ct 0.1.1", "crypto-bigint 0.4.9", "der 0.6.1", "digest 0.10.7", @@ -423,8 +431,34 @@ dependencies = [ "group 0.12.1", "hkdf 0.12.3", "rand_core 0.6.4", - "sec1", + "sec1 0.3.0", + "subtle", + "zeroize", +] + +[[package]] +name = "elliptic-curve" +version = "0.13.6" +dependencies = [ + "base16ct 0.2.0", + "base64ct", + "crypto-bigint 0.5.3", + "digest 0.10.7", + "ff 0.13.0", + "generic-array", + "group 0.13.0", + "hex-literal", + "hkdf 0.12.3", + "pem-rfc7468 0.7.0", + "pkcs8 0.10.2", + "rand_core 0.6.4", + "sec1 0.7.3", + "serde_json", + "serdect", + "sha2 0.10.8", + "sha3", "subtle", + "tap", "zeroize", ] @@ -448,6 +482,23 @@ dependencies = [ "subtle", ] +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "bitvec", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + [[package]] name = "generic-array" version = "0.14.7" @@ -456,6 +507,7 @@ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] @@ -508,32 +560,21 @@ dependencies = [ ] [[package]] -name = "hash32" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" -dependencies = [ - "byteorder", -] - -[[package]] -name = "heapless" -version = "0.7.16" +name = "group" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db04bc24a18b9ea980628ecf00e6c0264f3c1426dac36c00cb49b6fbad8b0743" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ - "atomic-polyfill", - "hash32", - "rustc_version", - "spin", - "stable_deref_trait", + "ff 0.13.0", + "rand_core 0.6.4", + "subtle", ] [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "hkdf" @@ -609,6 +650,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" dependencies = [ + "block-padding 0.3.3", "generic-array", ] @@ -617,10 +659,16 @@ name = "inout" version = "0.2.0-pre" source = "git+https://github.com/RustCrypto/utils.git#b755f1a29b074d8b0a6fc5fda5744312a11632c7" dependencies = [ - "block-padding", + "block-padding 0.4.0-pre", "hybrid-array", ] +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + [[package]] name = "jobserver" version = "0.1.26" @@ -630,6 +678,15 @@ dependencies = [ "libc", ] +[[package]] +name = "keccak" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +dependencies = [ + "cpufeatures", +] + [[package]] name = "kem" version = "0.2.0" @@ -651,16 +708,6 @@ version = "0.2.149" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" -[[package]] -name = "lock_api" -version = "0.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" -dependencies = [ - "autocfg", - "scopeguard", -] - [[package]] name = "opaque-debug" version = "0.3.0" @@ -698,9 +745,18 @@ dependencies = [ [[package]] name = "pem-rfc7468" -version = "0.2.4" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f22eb0e3c593294a99e9ff4b24cf6b752d43f193aa4415fe5077c159996d497" +dependencies = [ + "base64ct", +] + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84e93a3b1cc0510b03020f33f21e62acdde3dcaef432edc95bea377fbd4c2cd4" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" dependencies = [ "base64ct", ] @@ -712,11 +768,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee3ef9b64d26bad0536099c816c6734379e45bbd5f14798def6809e5cc350447" dependencies = [ "der 0.4.5", - "pem-rfc7468", - "spki", + "pem-rfc7468 0.2.3", + "spki 0.4.1", "zeroize", ] +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der 0.7.8", + "spki 0.7.2", +] + [[package]] name = "poly1305" version = "0.8.0" @@ -805,6 +871,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + [[package]] name = "rand" version = "0.8.5" @@ -842,19 +914,10 @@ dependencies = [ ] [[package]] -name = "rustc_version" -version = "0.4.0" +name = "ryu" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" -dependencies = [ - "semver", -] - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "sec1" @@ -862,7 +925,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" dependencies = [ - "base16ct", + "base16ct 0.1.1", "der 0.6.1", "generic-array", "subtle", @@ -870,10 +933,19 @@ dependencies = [ ] [[package]] -name = "semver" -version = "1.0.20" +name = "sec1" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct 0.2.0", + "der 0.7.8", + "generic-array", + "pkcs8 0.10.2", + "serdect", + "subtle", + "zeroize", +] [[package]] name = "serde" @@ -904,6 +976,27 @@ dependencies = [ "syn", ] +[[package]] +name = "serde_json" +version = "1.0.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serdect" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a84f14a19e9a014bb9f4512488d9829a68e04ecabffb0f9904cd1ace94598177" +dependencies = [ + "base16ct 0.2.0", + "serde", +] + [[package]] name = "sha2" version = "0.9.9" @@ -928,6 +1021,16 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + [[package]] name = "signature" version = "1.3.2" @@ -941,31 +1044,6 @@ dependencies = [ [[package]] name = "signature" version = "2.1.0" -dependencies = [ - "digest 0.10.7", - "hex-literal", - "rand_core 0.6.4", - "sha2 0.10.8", - "signature_derive", -] - -[[package]] -name = "signature_derive" -version = "2.0.1" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" -dependencies = [ - "lock_api", -] [[package]] name = "spki" @@ -977,10 +1055,14 @@ dependencies = [ ] [[package]] -name = "stable_deref_trait" -version = "1.2.0" +name = "spki" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +dependencies = [ + "base64ct", + "der 0.7.8", +] [[package]] name = "subtle" @@ -999,6 +1081,12 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + [[package]] name = "typenum" version = "1.17.0" @@ -1041,6 +1129,15 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + [[package]] name = "x25519-dalek" version = "2.0.0-pre.1" diff --git a/Cargo.toml b/Cargo.toml index 59dd5ff5d..436bc20fc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,21 +1,21 @@ [workspace] resolver = "2" members = [ - "aead", "cipher", + "crypto", "crypto-common", "digest", + "elliptic-curve", "kem", "password-hash", +] +# TODO: re-add to `members` when MSRV has been bumped to 1.60+ +exclude = [ + "aead", "signature", "signature/async", "universal-hash", ] -# re-add when all crates are MSRV 1.60+ -exclude = [ - "crypto", - "elliptic-curve" -] [patch.crates-io] block-buffer = { git = "https://github.com/RustCrypto/utils.git" } diff --git a/aead/Cargo.lock b/aead/Cargo.lock new file mode 100644 index 000000000..6fb255ac7 --- /dev/null +++ b/aead/Cargo.lock @@ -0,0 +1,151 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aead" +version = "0.5.2" +dependencies = [ + "arrayvec", + "blobby", + "bytes", + "crypto-common", + "generic-array", + "heapless", +] + +[[package]] +name = "arrayvec" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a2f58b0bb10c380af2b26e57212856b8c9a59e0925b4c20f4a174a49734eaf7" + +[[package]] +name = "atomic-polyfill" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3ff7eb3f316534d83a8a2c3d1674ace8a5a71198eba31e2e2b597833f699b28" +dependencies = [ + "critical-section", +] + +[[package]] +name = "blobby" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc52553543ecb104069b0ff9e0fcc5c739ad16202935528a112d974e8f1a4ee8" + +[[package]] +name = "byteorder" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73b5bdfe7ee3ad0b99c9801d58807a9dbc9e09196365b0203853b99889ab3c87" + +[[package]] +name = "bytes" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad1f8e949d755f9d79112b5bb46938e0ef9d3804a0b16dfab13aafcaa5f0fa72" + +[[package]] +name = "cfg-if" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" + +[[package]] +name = "critical-section" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d02ba51481d019be9c74a831d1133c364d78831b75c833478f3a21e1fd91e01a" + +[[package]] +name = "crypto-common" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5999502d32b9c48d492abe66392408144895020ec4709e549e840799f3bb74c0" +dependencies = [ + "generic-array", + "rand_core", + "typenum", +] + +[[package]] +name = "generic-array" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee8025cf36f917e6a52cce185b7c7177689b838b7ec138364e50cc2277a56cf4" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "hash32" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +dependencies = [ + "byteorder", +] + +[[package]] +name = "heapless" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94c13b78b595d2adbd708bce276664f1047f98fc32ddbf463b4c191158334a6" +dependencies = [ + "atomic-polyfill", + "hash32", + "stable_deref_trait", +] + +[[package]] +name = "libc" +version = "0.2.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74dfca3d9957906e8d1e6a0b641dc9a59848e793f1da2165889fd4f62d10d79c" + +[[package]] +name = "rand_core" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" +dependencies = [ + "getrandom", +] + +[[package]] +name = "stable_deref_trait" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b" + +[[package]] +name = "typenum" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" + +[[package]] +name = "version_check" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45d3d553fd9413fffe7147a20171d640eda0ad4c070acd7d0c885a21bcd2e8b7" + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" diff --git a/crypto/Cargo.lock b/crypto/Cargo.lock deleted file mode 100644 index 8fa3352f6..000000000 --- a/crypto/Cargo.lock +++ /dev/null @@ -1,290 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "aead" -version = "0.5.2" -dependencies = [ - "crypto-common", - "generic-array", -] - -[[package]] -name = "base16ct" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" - -[[package]] -name = "base64ct" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "block-padding" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" -dependencies = [ - "generic-array", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "cipher" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" -dependencies = [ - "crypto-common", - "inout", -] - -[[package]] -name = "const-oid" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" - -[[package]] -name = "crypto" -version = "0.5.1" -dependencies = [ - "aead", - "cipher", - "crypto-common", - "digest", - "elliptic-curve", - "password-hash", - "signature", - "universal-hash", -] - -[[package]] -name = "crypto-bigint" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c2538c4e68e52548bacb3e83ac549f903d44f011ac9d5abb5e132e67d0808f7" -dependencies = [ - "generic-array", - "rand_core", - "subtle", - "zeroize", -] - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "rand_core", - "typenum", -] - -[[package]] -name = "der" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b10af9f9f9f2134a42d3f8aa74658660f2e0234b0eb81bd171df8aa32779ed" -dependencies = [ - "const-oid", - "zeroize", -] - -[[package]] -name = "digest" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" -dependencies = [ - "block-buffer", - "crypto-common", - "subtle", -] - -[[package]] -name = "elliptic-curve" -version = "0.13.5" -dependencies = [ - "base16ct", - "crypto-bigint", - "ff", - "generic-array", - "group", - "pkcs8", - "rand_core", - "sec1", - "subtle", - "zeroize", -] - -[[package]] -name = "ff" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" -dependencies = [ - "rand_core", - "subtle", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", - "zeroize", -] - -[[package]] -name = "getrandom" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "group" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" -dependencies = [ - "ff", - "rand_core", - "subtle", -] - -[[package]] -name = "inout" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" -dependencies = [ - "block-padding", - "generic-array", -] - -[[package]] -name = "libc" -version = "0.2.141" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5" - -[[package]] -name = "password-hash" -version = "0.5.0" -dependencies = [ - "base64ct", - "rand_core", - "subtle", -] - -[[package]] -name = "pkcs8" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" -dependencies = [ - "der", - "spki", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - -[[package]] -name = "sec1" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0aec48e813d6b90b15f0b8948af3c63483992dee44c03e9930b3eebdabe046e" -dependencies = [ - "base16ct", - "der", - "generic-array", - "pkcs8", - "subtle", - "zeroize", -] - -[[package]] -name = "signature" -version = "2.1.0" - -[[package]] -name = "spki" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37a5be806ab6f127c3da44b7378837ebf01dadca8510a0e572460216b228bd0e" -dependencies = [ - "base64ct", - "der", -] - -[[package]] -name = "subtle" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" - -[[package]] -name = "typenum" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" - -[[package]] -name = "universal-hash" -version = "0.5.1" -dependencies = [ - "crypto-common", - "subtle", -] - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "zeroize" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock deleted file mode 100644 index 827b3abe9..000000000 --- a/elliptic-curve/Cargo.lock +++ /dev/null @@ -1,380 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "base16ct" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" - -[[package]] -name = "base64ct" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" - -[[package]] -name = "bitvec" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" -dependencies = [ - "funty", - "radium", - "tap", - "wyz", -] - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "const-oid" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" - -[[package]] -name = "cpufeatures" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "280a9f2d8b3a38871a3c8a46fb80db65e5e5ed97da80c4d08bf27fb63e35e181" -dependencies = [ - "libc", -] - -[[package]] -name = "crypto-bigint" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c2538c4e68e52548bacb3e83ac549f903d44f011ac9d5abb5e132e67d0808f7" -dependencies = [ - "generic-array", - "rand_core", - "subtle", - "zeroize", -] - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "der" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19c5cb402c5c958281c7c0702edea7b780d03b86b606497ca3a10fcd3fc393ac" -dependencies = [ - "const-oid", - "pem-rfc7468", - "zeroize", -] - -[[package]] -name = "digest" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" -dependencies = [ - "block-buffer", - "crypto-common", - "subtle", -] - -[[package]] -name = "elliptic-curve" -version = "0.13.6" -dependencies = [ - "base16ct", - "base64ct", - "crypto-bigint", - "digest", - "ff", - "generic-array", - "group", - "hex-literal", - "hkdf", - "pem-rfc7468", - "pkcs8", - "rand_core", - "sec1", - "serde_json", - "serdect", - "sha2", - "sha3", - "subtle", - "tap", - "zeroize", -] - -[[package]] -name = "ff" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" -dependencies = [ - "bitvec", - "rand_core", - "subtle", -] - -[[package]] -name = "funty" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", - "zeroize", -] - -[[package]] -name = "getrandom" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "group" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" -dependencies = [ - "ff", - "rand_core", - "subtle", -] - -[[package]] -name = "hex-literal" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" - -[[package]] -name = "hkdf" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" -dependencies = [ - "hmac", -] - -[[package]] -name = "hmac" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" -dependencies = [ - "digest", -] - -[[package]] -name = "itoa" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" - -[[package]] -name = "keccak" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3afef3b6eff9ce9d8ff9b3601125eec7f0c8cbac7abd14f355d053fa56c98768" -dependencies = [ - "cpufeatures", -] - -[[package]] -name = "libc" -version = "0.2.141" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5" - -[[package]] -name = "pem-rfc7468" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" -dependencies = [ - "base64ct", -] - -[[package]] -name = "pkcs8" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" -dependencies = [ - "der", - "spki", -] - -[[package]] -name = "radium" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - -[[package]] -name = "ryu" -version = "1.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" - -[[package]] -name = "sec1" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48518a2b5775ba8ca5b46596aae011caa431e6ce7e4a67ead66d92f08884220e" -dependencies = [ - "base16ct", - "der", - "generic-array", - "pkcs8", - "serdect", - "subtle", - "zeroize", -] - -[[package]] -name = "serde" -version = "1.0.159" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c04e8343c3daeec41f58990b9d77068df31209f2af111e059e9fe9646693065" - -[[package]] -name = "serde_json" -version = "1.0.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d721eca97ac802aa7777b701877c8004d950fc142651367300d21c1cc0194744" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "serdect" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a84f14a19e9a014bb9f4512488d9829a68e04ecabffb0f9904cd1ace94598177" -dependencies = [ - "base16ct", - "serde", -] - -[[package]] -name = "sha2" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "sha3" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdf0c33fae925bdc080598b84bc15c55e7b9a4a43b3c704da051f977469691c9" -dependencies = [ - "digest", - "keccak", -] - -[[package]] -name = "spki" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37a5be806ab6f127c3da44b7378837ebf01dadca8510a0e572460216b228bd0e" -dependencies = [ - "base64ct", - "der", -] - -[[package]] -name = "subtle" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" - -[[package]] -name = "tap" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" - -[[package]] -name = "typenum" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wyz" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" -dependencies = [ - "tap", -] - -[[package]] -name = "zeroize" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 36c684ad4..a2659f1b8 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -335,7 +335,6 @@ impl Invert for Scalar { impl Reduce for Scalar { type Bytes = FieldBytes; - #[allow(clippy::integer_arithmetic)] fn reduce(w: U256) -> Self { let (r, underflow) = w.sbb(&MockCurve::ORDER, Limb::ZERO); let underflow = Choice::from((underflow.0 >> (Limb::BITS - 1)) as u8); diff --git a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs index 50edb648b..baf6f31b2 100644 --- a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs +++ b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs @@ -1,8 +1,5 @@ //! `expand_message_xmd` based on a hash function. -// TODO(tarcieri): checked arithmetic -#![allow(clippy::integer_arithmetic)] - use core::marker::PhantomData; use super::{Domain, ExpandMsg, Expander}; diff --git a/elliptic-curve/src/hash2curve/isogeny.rs b/elliptic-curve/src/hash2curve/isogeny.rs index 7a28983dd..fc870d010 100644 --- a/elliptic-curve/src/hash2curve/isogeny.rs +++ b/elliptic-curve/src/hash2curve/isogeny.rs @@ -26,7 +26,6 @@ pub trait Isogeny: Field + AddAssign + Mul { const COEFFICIENTS: IsogenyCoefficients; /// Map from the isogeny points to the main curve - #[allow(clippy::integer_arithmetic)] fn isogeny(x: Self, y: Self) -> (Self, Self) { let mut xs = GenericArray::::default(); xs[0] = Self::ONE; diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 5f2a6c62e..b0ad188de 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -14,7 +14,6 @@ clippy::cast_sign_loss, clippy::checked_conversions, clippy::implicit_saturating_sub, - clippy::integer_arithmetic, clippy::mod_module_files, clippy::panic, clippy::panic_in_result_fn, diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index 485b0ecfd..d2fe6065b 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -231,7 +231,8 @@ where /// Initialize [`PublicKey`] from an [`EncodedPoint`] fn from_encoded_point(encoded_point: &EncodedPoint) -> CtOption { AffinePoint::::from_encoded_point(encoded_point).and_then(|point| { - let is_identity = Choice::from(encoded_point.is_identity() as u8); + // Defeating the point of `subtle`, but the use case is specifically a public key + let is_identity = Choice::from(u8::from(encoded_point.is_identity())); CtOption::new(PublicKey { point }, !is_identity) }) } diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index 7673386b8..5e1c07f96 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -93,7 +93,7 @@ where } } -#[cfg(all(feature = "arithmetic"))] +#[cfg(feature = "arithmetic")] impl ValidatePublicKey for C where C: CurveArithmetic, diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 607589a75..502f8153b 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -184,7 +184,7 @@ where } /// Deserialize secret key encoded in the SEC1 ASN.1 DER `ECPrivateKey` format. - #[cfg(all(feature = "sec1"))] + #[cfg(feature = "sec1")] pub fn from_sec1_der(der_bytes: &[u8]) -> Result where C: Curve + ValidatePublicKey, @@ -344,7 +344,7 @@ where } } -#[cfg(all(feature = "sec1"))] +#[cfg(feature = "sec1")] impl TryFrom> for SecretKey where C: Curve + ValidatePublicKey, diff --git a/signature/Cargo.lock b/signature/Cargo.lock new file mode 100644 index 000000000..470272724 --- /dev/null +++ b/signature/Cargo.lock @@ -0,0 +1,189 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "async-signature" +version = "0.3.0" +dependencies = [ + "async-trait", + "signature", +] + +[[package]] +name = "async-trait" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62d042b64fd281d31d58e80ac29426e114ae8eead17beb12fbd396a1d04eee84" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.0", +] + +[[package]] +name = "block-buffer" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03588e54c62ae6d763e2a80090d50353b785795361b4ff5b3bf0a5097fc31c0b" +dependencies = [ + "generic-array", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cpufeatures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-common" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "digest" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "generic-array" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "hex-literal" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc38ca401ca1b8d89ff1185e39a132e5c4f86d844c0cf6364251576f2d7fa0c1" + +[[package]] +name = "libc" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "789da6d93f1b866ffe175afc5322a4d76c038605a1c3319bb57b06967ca98a36" + +[[package]] +name = "proc-macro2" +version = "1.0.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d0e1ae9e836cc3beddd63db0df682593d7e2d3d891ae8c9083d2113e1744224" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" + +[[package]] +name = "sha2" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99c3bd8169c58782adad9290a9af5939994036b76187f7b4f0e6de91dbbfc0ec" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "signature" +version = "2.1.0" +dependencies = [ + "digest", + "hex-literal", + "rand_core", + "sha2", + "signature_derive", +] + +[[package]] +name = "signature_derive" +version = "2.0.1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.0", +] + +[[package]] +name = "syn" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f8c8eab7d9f493cd89d4068085651d81ac7d39c56eb64f7158ea514b156e280" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "syn" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cff13bb1732bccfe3b246f3fdb09edfd51c01d6f5299b7ccd9457c2e4e37774" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "typenum" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" + +[[package]] +name = "unicode-ident" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee" + +[[package]] +name = "unicode-xid" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" + +[[package]] +name = "version_check" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45d3d553fd9413fffe7147a20171d640eda0ad4c070acd7d0c885a21bcd2e8b7" diff --git a/signature/Cargo.toml b/signature/Cargo.toml index e8fec5988..0b1427dd5 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -28,3 +28,7 @@ std = ["alloc"] [package.metadata.docs.rs] all-features = true rustdoc-args = ["--cfg", "docsrs"] + +# TODO(tarcieri): remove when these crates are added to toplevel `members` +[workspace] +members = [".", "async"] diff --git a/universal-hash/Cargo.lock b/universal-hash/Cargo.lock new file mode 100644 index 000000000..2542bc3d6 --- /dev/null +++ b/universal-hash/Cargo.lock @@ -0,0 +1,49 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "generic-array" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "subtle" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e81da0851ada1f3e9d4312c704aa4f8806f0f9d69faaf8df2f3464b4a9437c2" + +[[package]] +name = "typenum" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" + +[[package]] +name = "universal-hash" +version = "0.5.1" +dependencies = [ + "crypto-common", + "subtle", +] + +[[package]] +name = "version_check" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45d3d553fd9413fffe7147a20171d640eda0ad4c070acd7d0c885a21bcd2e8b7" From b6b591ef197b227954fd1f0baef964bb40f03575 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 11 Nov 2023 18:41:50 -0700 Subject: [PATCH 1061/1461] crypto-common: weakly activate `rand_core/getrandom` (#1381) When both `getrandom` and `rand_core` are enabled, activates the `rand_core/getrandom` feature, which makes `OsRng` available as `crypto_common::rand_core::OsRng`. --- Cargo.lock | 1 + crypto-common/Cargo.toml | 1 + crypto-common/src/lib.rs | 2 ++ 3 files changed, 4 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index b9bfc7bbf..c8aae2089 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -286,6 +286,7 @@ dependencies = [ name = "crypto-common" version = "0.2.0-pre" dependencies = [ + "getrandom", "hybrid-array", "rand_core 0.6.4", ] diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index 38496ad54..e0e7dd090 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -20,6 +20,7 @@ rand_core = { version = "0.6.4", optional = true } getrandom = { version = "0.2", optional = true } [features] +getrandom = ["dep:getrandom", "rand_core?/getrandom"] std = [] [package.metadata.docs.rs] diff --git a/crypto-common/src/lib.rs b/crypto-common/src/lib.rs index 5fb3a814a..247746a64 100644 --- a/crypto-common/src/lib.rs +++ b/crypto-common/src/lib.rs @@ -12,6 +12,8 @@ #[cfg(feature = "std")] extern crate std; +#[cfg(feature = "getrandom")] +pub use getrandom; #[cfg(feature = "rand_core")] pub use rand_core; From 137a26f017f01340ea68e860fada96705e2c6c87 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 11 Nov 2023 20:19:54 -0700 Subject: [PATCH 1062/1461] crypto-common: weakly activate `std` features for RNG crates (#1383) --- crypto-common/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index e0e7dd090..27a3e4fe9 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -21,7 +21,7 @@ getrandom = { version = "0.2", optional = true } [features] getrandom = ["dep:getrandom", "rand_core?/getrandom"] -std = [] +std = ["getrandom?/std", "rand_core?/std"] [package.metadata.docs.rs] all-features = true From 8b24dd9194472bfe812e1fd1c26b1ba92f5cd451 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 11 Nov 2023 21:26:25 -0700 Subject: [PATCH 1063/1461] aead: bump `crypto-common` to v0.2.0-pre; MSRV 1.65 (#1384) Replaces `generic-array` with `hybrid-array`, which is built on a combination of `typenum` and const generics, providing a degree of interoperability between the two systems. --- .github/workflows/aead.yml | 13 ++-- Cargo.lock | 120 +++++++++++++++++++++++++++-- Cargo.toml | 2 +- aead/Cargo.lock | 151 ------------------------------------- aead/Cargo.toml | 9 +-- aead/README.md | 4 +- aead/src/lib.rs | 68 +++++++++-------- aead/src/stream.rs | 36 ++++----- crypto/Cargo.toml | 2 +- 9 files changed, 180 insertions(+), 225 deletions(-) delete mode 100644 aead/Cargo.lock diff --git a/.github/workflows/aead.yml b/.github/workflows/aead.yml index 409b6bd58..462108e7a 100644 --- a/.github/workflows/aead.yml +++ b/.github/workflows/aead.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.65.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -42,17 +42,18 @@ jobs: - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features rand_core - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features stream - minimal-versions: - uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master - with: - working-directory: ${{ github.workflow }} + # TODO(tarcieri): re-enable after next `crypto-common` release + # minimal-versions: + # uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master + # with: + # working-directory: ${{ github.workflow }} test: runs-on: ubuntu-latest strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.65.0 # MSRV - stable steps: - uses: actions/checkout@v4 diff --git a/Cargo.lock b/Cargo.lock index c8aae2089..a9cbef675 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5,6 +5,8 @@ version = 3 [[package]] name = "aead" version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" dependencies = [ "crypto-common 0.1.6", "generic-array", @@ -12,12 +14,13 @@ dependencies = [ [[package]] name = "aead" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +version = "0.6.0-pre" dependencies = [ - "crypto-common 0.1.6", - "generic-array", + "arrayvec", + "blobby", + "bytes", + "crypto-common 0.2.0-pre", + "heapless", ] [[package]] @@ -37,7 +40,7 @@ version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" dependencies = [ - "aead 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "aead 0.5.2", "aes", "cipher 0.4.4", "ctr", @@ -45,6 +48,27 @@ dependencies = [ "subtle", ] +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "atomic-polyfill" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3ff7eb3f316534d83a8a2c3d1674ace8a5a71198eba31e2e2b597833f699b28" +dependencies = [ + "critical-section", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + [[package]] name = "base16ct" version = "0.1.1" @@ -139,6 +163,12 @@ version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + [[package]] name = "cc" version = "1.0.83" @@ -172,7 +202,7 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" dependencies = [ - "aead 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "aead 0.5.2", "chacha20", "cipher 0.4.4", "poly1305", @@ -221,6 +251,12 @@ dependencies = [ "libc", ] +[[package]] +name = "critical-section" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216" + [[package]] name = "crypto" version = "0.5.1" @@ -571,6 +607,28 @@ dependencies = [ "subtle", ] +[[package]] +name = "hash32" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +dependencies = [ + "byteorder", +] + +[[package]] +name = "heapless" +version = "0.7.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db04bc24a18b9ea980628ecf00e6c0264f3c1426dac36c00cb49b6fbad8b0743" +dependencies = [ + "atomic-polyfill", + "hash32", + "rustc_version", + "spin", + "stable_deref_trait", +] + [[package]] name = "hex-literal" version = "0.4.1" @@ -621,7 +679,7 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf39e5461bfdc6ad0fbc97067519fcaf96a7a2e67f24cc0eb8a1e7c0c45af792" dependencies = [ - "aead 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "aead 0.5.2", "aes-gcm", "byteorder", "chacha20poly1305", @@ -709,6 +767,16 @@ version = "0.2.149" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + [[package]] name = "opaque-debug" version = "0.3.0" @@ -914,12 +982,27 @@ dependencies = [ "getrandom", ] +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + [[package]] name = "ryu" version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + [[package]] name = "sec1" version = "0.3.0" @@ -948,6 +1031,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "semver" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" + [[package]] name = "serde" version = "1.0.189" @@ -1046,6 +1135,15 @@ dependencies = [ name = "signature" version = "2.1.0" +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + [[package]] name = "spki" version = "0.4.1" @@ -1065,6 +1163,12 @@ dependencies = [ "der 0.7.8", ] +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + [[package]] name = "subtle" version = "2.5.0" diff --git a/Cargo.toml b/Cargo.toml index 436bc20fc..e4cda3420 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,7 @@ [workspace] resolver = "2" members = [ + "aead", "cipher", "crypto", "crypto-common", @@ -11,7 +12,6 @@ members = [ ] # TODO: re-add to `members` when MSRV has been bumped to 1.60+ exclude = [ - "aead", "signature", "signature/async", "universal-hash", diff --git a/aead/Cargo.lock b/aead/Cargo.lock deleted file mode 100644 index 6fb255ac7..000000000 --- a/aead/Cargo.lock +++ /dev/null @@ -1,151 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "aead" -version = "0.5.2" -dependencies = [ - "arrayvec", - "blobby", - "bytes", - "crypto-common", - "generic-array", - "heapless", -] - -[[package]] -name = "arrayvec" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a2f58b0bb10c380af2b26e57212856b8c9a59e0925b4c20f4a174a49734eaf7" - -[[package]] -name = "atomic-polyfill" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ff7eb3f316534d83a8a2c3d1674ace8a5a71198eba31e2e2b597833f699b28" -dependencies = [ - "critical-section", -] - -[[package]] -name = "blobby" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc52553543ecb104069b0ff9e0fcc5c739ad16202935528a112d974e8f1a4ee8" - -[[package]] -name = "byteorder" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73b5bdfe7ee3ad0b99c9801d58807a9dbc9e09196365b0203853b99889ab3c87" - -[[package]] -name = "bytes" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad1f8e949d755f9d79112b5bb46938e0ef9d3804a0b16dfab13aafcaa5f0fa72" - -[[package]] -name = "cfg-if" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" - -[[package]] -name = "critical-section" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d02ba51481d019be9c74a831d1133c364d78831b75c833478f3a21e1fd91e01a" - -[[package]] -name = "crypto-common" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5999502d32b9c48d492abe66392408144895020ec4709e549e840799f3bb74c0" -dependencies = [ - "generic-array", - "rand_core", - "typenum", -] - -[[package]] -name = "generic-array" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee8025cf36f917e6a52cce185b7c7177689b838b7ec138364e50cc2277a56cf4" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "hash32" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" -dependencies = [ - "byteorder", -] - -[[package]] -name = "heapless" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94c13b78b595d2adbd708bce276664f1047f98fc32ddbf463b4c191158334a6" -dependencies = [ - "atomic-polyfill", - "hash32", - "stable_deref_trait", -] - -[[package]] -name = "libc" -version = "0.2.64" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74dfca3d9957906e8d1e6a0b641dc9a59848e793f1da2165889fd4f62d10d79c" - -[[package]] -name = "rand_core" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" -dependencies = [ - "getrandom", -] - -[[package]] -name = "stable_deref_trait" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b" - -[[package]] -name = "typenum" -version = "1.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" - -[[package]] -name = "version_check" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45d3d553fd9413fffe7147a20171d640eda0ad4c070acd7d0c885a21bcd2e8b7" - -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" diff --git a/aead/Cargo.toml b/aead/Cargo.toml index 29eb0bf26..dd424eb0c 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aead" -version = "0.5.2" +version = "0.6.0-pre" description = """ Traits for Authenticated Encryption with Associated Data (AEAD) algorithms, such as AES-GCM as ChaCha20Poly1305, which provide a high-level API @@ -13,11 +13,10 @@ documentation = "https://docs.rs/aead" repository = "https://github.com/RustCrypto/traits" keywords = ["crypto", "encryption"] categories = ["cryptography", "no-std"] -rust-version = "1.56" +rust-version = "1.65" [dependencies] -crypto-common = "0.1.4" -generic-array = { version = "0.14", default-features = false } +crypto-common = "=0.2.0-pre" # optional dependencies arrayvec = { version = "0.7", optional = true, default-features = false } @@ -30,7 +29,7 @@ default = ["rand_core"] alloc = [] std = ["alloc", "crypto-common/std"] dev = ["blobby"] -getrandom = ["crypto-common/getrandom", "rand_core"] +getrandom = ["crypto-common/getrandom"] rand_core = ["crypto-common/rand_core"] stream = [] diff --git a/aead/README.md b/aead/README.md index ff1a580a2..b481f9c37 100644 --- a/aead/README.md +++ b/aead/README.md @@ -19,7 +19,7 @@ See [RustCrypto/AEADs] for cipher implementations which use this trait. ## Minimum Supported Rust Version -Rust **1.56** or higher. +Rust **1.65** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -51,7 +51,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/aead/badge.svg [docs-link]: https://docs.rs/aead/ [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.65+-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/traits/workflows/aead/badge.svg?branch=master&event=push diff --git a/aead/src/lib.rs b/aead/src/lib.rs index df9bf1262..62cf29dbb 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -1,20 +1,6 @@ -//! [Authenticated Encryption with Associated Data] (AEAD) traits -//! -//! This crate provides an abstract interface for AEAD ciphers, which guarantee -//! both confidentiality and integrity, even from a powerful attacker who is -//! able to execute [chosen-ciphertext attacks]. The resulting security property, -//! [ciphertext indistinguishability], is considered a basic requirement for -//! modern cryptographic implementations. -//! -//! See [RustCrypto/AEADs] for cipher implementations which use this trait. -//! -//! [Authenticated Encryption with Associated Data]: https://en.wikipedia.org/wiki/Authenticated_encryption -//! [chosen-ciphertext attacks]: https://en.wikipedia.org/wiki/Chosen-ciphertext_attack -//! [ciphertext indistinguishability]: https://en.wikipedia.org/wiki/Ciphertext_indistinguishability -//! [RustCrypto/AEADs]: https://github.com/RustCrypto/AEADs - #![no_std] #![cfg_attr(docsrs, feature(doc_auto_cfg))] +#![doc = include_str!("../README.md")] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg" @@ -34,18 +20,17 @@ pub mod dev; #[cfg(feature = "stream")] pub mod stream; -pub use crypto_common::{Key, KeyInit, KeySizeUser}; -pub use generic_array::{self, typenum::consts}; +pub use crypto_common::{ + array::{self, typenum::consts}, + Key, KeyInit, KeySizeUser, +}; #[cfg(feature = "arrayvec")] pub use arrayvec; - #[cfg(feature = "bytes")] pub use bytes; - #[cfg(feature = "getrandom")] pub use crypto_common::rand_core::OsRng; - #[cfg(feature = "heapless")] pub use heapless; @@ -53,16 +38,16 @@ pub use heapless; pub use crypto_common::rand_core; use core::fmt; -use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; +use crypto_common::array::{typenum::Unsigned, ArraySize, ByteArray}; #[cfg(feature = "alloc")] use alloc::vec::Vec; - #[cfg(feature = "bytes")] use bytes::BytesMut; - +#[cfg(feature = "getrandom")] +use crypto_common::getrandom; #[cfg(feature = "rand_core")] -use rand_core::{CryptoRng, RngCore}; +use rand_core::CryptoRngCore; /// Error type. /// @@ -84,10 +69,10 @@ impl fmt::Display for Error { impl std::error::Error for Error {} /// Nonce: single-use value for ensuring ciphertexts are unique -pub type Nonce = GenericArray::NonceSize>; +pub type Nonce = ByteArray<::NonceSize>; /// Tag: authentication code which ensures ciphertexts are authentic -pub type Tag = GenericArray::TagSize>; +pub type Tag = ByteArray<::TagSize>; /// Authenticated Encryption with Associated Data (AEAD) algorithm core trait. /// @@ -95,14 +80,14 @@ pub type Tag = GenericArray::TagSize>; /// `Aead*` traits. pub trait AeadCore { /// The length of a nonce. - type NonceSize: ArrayLength; + type NonceSize: ArraySize; /// The maximum length of the tag. - type TagSize: ArrayLength; + type TagSize: ArraySize; /// The upper bound amount of additional space required to support a /// ciphertext vs. a plaintext. - type CiphertextOverhead: ArrayLength + Unsigned; + type CiphertextOverhead: ArraySize + Unsigned; /// Generate a random nonce for this AEAD algorithm. /// @@ -139,14 +124,31 @@ pub trait AeadCore { /// See the [`stream`] module for a ready-made implementation of the latter. /// /// [NIST SP 800-38D]: https://csrc.nist.gov/publications/detail/sp/800-38d/final + #[cfg(feature = "getrandom")] + fn generate_nonce() -> core::result::Result, getrandom::Error> + where + Nonce: Default, + { + let mut nonce = Nonce::::default(); + getrandom::getrandom(&mut nonce)?; + Ok(nonce) + } + + /// Generate a random nonce for this AEAD algorithm using the specified + /// [`CryptoRngCore`]. + /// + /// See [`AeadCore::generate_nonce`] documentation for requirements for + /// random nonces. #[cfg(feature = "rand_core")] - fn generate_nonce(mut rng: impl CryptoRng + RngCore) -> Nonce + fn generate_nonce_with_rng( + rng: &mut impl CryptoRngCore, + ) -> core::result::Result, rand_core::Error> where Nonce: Default, { let mut nonce = Nonce::::default(); - rng.fill_bytes(&mut nonce); - nonce + rng.try_fill_bytes(&mut nonce)?; + Ok(nonce) } } @@ -248,7 +250,7 @@ macro_rules! impl_decrypt_in_place { let tag_pos = $buffer.len() - Self::TagSize::to_usize(); let (msg, tag) = $buffer.as_mut().split_at_mut(tag_pos); - $aead.decrypt_in_place_detached($nonce, $aad, msg, Tag::::from_slice(tag))?; + $aead.decrypt_in_place_detached($nonce, $aad, msg, Tag::::ref_from_slice(tag))?; $buffer.truncate(tag_pos); Ok(()) }}; diff --git a/aead/src/stream.rs b/aead/src/stream.rs index a5c3c6586..13aa593ef 100644 --- a/aead/src/stream.rs +++ b/aead/src/stream.rs @@ -34,16 +34,16 @@ use crate::{AeadCore, AeadInPlace, Buffer, Error, Key, KeyInit, Result}; use core::ops::{AddAssign, Sub}; -use generic_array::{ +use crypto_common::array::{ typenum::{Unsigned, U4, U5}, - ArrayLength, GenericArray, + ArraySize, ByteArray, }; #[cfg(feature = "alloc")] use {crate::Payload, alloc::vec::Vec}; /// Nonce as used by a given AEAD construction and STREAM primitive. -pub type Nonce = GenericArray>; +pub type Nonce = ByteArray>; /// Size of a nonce as used by a STREAM construction, sans the overhead of /// the STREAM protocol itself. @@ -71,7 +71,7 @@ pub trait NewStream: StreamPrimitive where A: AeadInPlace, A::NonceSize: Sub, - NonceSize: ArrayLength, + NonceSize: ArraySize, { /// Create a new STREAM with the given key and nonce. fn new(key: &Key, nonce: &Nonce) -> Self @@ -96,10 +96,10 @@ pub trait StreamPrimitive where A: AeadInPlace, A::NonceSize: Sub, - NonceSize: ArrayLength, + NonceSize: ArraySize, { /// Number of bytes this STREAM primitive requires from the nonce. - type NonceOverhead: ArrayLength; + type NonceOverhead: ArraySize; /// Type used as the STREAM counter. type Counter: AddAssign + Copy + Default + Eq; @@ -204,7 +204,7 @@ macro_rules! impl_stream_object { A: AeadInPlace, S: StreamPrimitive, A::NonceSize: Sub<>::NonceOverhead>, - NonceSize: ArrayLength, + NonceSize: ArraySize, { /// Underlying STREAM primitive. stream: S, @@ -218,7 +218,7 @@ macro_rules! impl_stream_object { A: AeadInPlace, S: StreamPrimitive, A::NonceSize: Sub<>::NonceOverhead>, - NonceSize: ArrayLength, + NonceSize: ArraySize, { #[doc = "Create a"] #[doc = $obj_desc] @@ -365,7 +365,7 @@ pub struct StreamBE32 where A: AeadInPlace, A::NonceSize: Sub, - <::NonceSize as Sub>::Output: ArrayLength, + <::NonceSize as Sub>::Output: ArraySize, { /// Underlying AEAD cipher aead: A, @@ -378,7 +378,7 @@ impl NewStream for StreamBE32 where A: AeadInPlace, A::NonceSize: Sub, - <::NonceSize as Sub>::Output: ArrayLength, + <::NonceSize as Sub>::Output: ArraySize, { fn from_aead(aead: A, nonce: &Nonce) -> Self { Self { @@ -392,7 +392,7 @@ impl StreamPrimitive for StreamBE32 where A: AeadInPlace, A::NonceSize: Sub, - <::NonceSize as Sub>::Output: ArrayLength, + <::NonceSize as Sub>::Output: ArraySize, { type NonceOverhead = U5; type Counter = u32; @@ -426,12 +426,12 @@ impl StreamBE32 where A: AeadInPlace, A::NonceSize: Sub, - <::NonceSize as Sub>::Output: ArrayLength, + <::NonceSize as Sub>::Output: ArraySize, { /// Compute the full AEAD nonce including the STREAM counter and last /// block flag. fn aead_nonce(&self, position: u32, last_block: bool) -> crate::Nonce { - let mut result = GenericArray::default(); + let mut result = ByteArray::default(); // TODO(tarcieri): use `generic_array::sequence::Concat` (or const generics) let (prefix, tail) = result.split_at_mut(NonceSize::::to_usize()); @@ -454,7 +454,7 @@ pub struct StreamLE31 where A: AeadInPlace, A::NonceSize: Sub, - <::NonceSize as Sub>::Output: ArrayLength, + <::NonceSize as Sub>::Output: ArraySize, { /// Underlying AEAD cipher aead: A, @@ -467,7 +467,7 @@ impl NewStream for StreamLE31 where A: AeadInPlace, A::NonceSize: Sub, - <::NonceSize as Sub>::Output: ArrayLength, + <::NonceSize as Sub>::Output: ArraySize, { fn from_aead(aead: A, nonce: &Nonce) -> Self { Self { @@ -481,7 +481,7 @@ impl StreamPrimitive for StreamLE31 where A: AeadInPlace, A::NonceSize: Sub, - <::NonceSize as Sub>::Output: ArrayLength, + <::NonceSize as Sub>::Output: ArraySize, { type NonceOverhead = U4; type Counter = u32; @@ -515,7 +515,7 @@ impl StreamLE31 where A: AeadInPlace, A::NonceSize: Sub, - <::NonceSize as Sub>::Output: ArrayLength, + <::NonceSize as Sub>::Output: ArraySize, { /// Compute the full AEAD nonce including the STREAM counter and last /// block flag. @@ -524,7 +524,7 @@ where return Err(Error); } - let mut result = GenericArray::default(); + let mut result = ByteArray::default(); // TODO(tarcieri): use `generic_array::sequence::Concat` (or const generics) let (prefix, tail) = result.split_at_mut(NonceSize::::to_usize()); diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index ede350b70..c3968eda1 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -16,7 +16,7 @@ rust-version = "1.65" crypto-common = { version = "0.1", default-features = false } # optional dependencies -aead = { version = "0.5", optional = true, path = "../aead" } +aead = { version = "0.5", optional = true } cipher = { version = "0.4", optional = true } digest = { version = "0.10", optional = true, features = ["mac"] } elliptic-curve = { version = "0.13", optional = true, path = "../elliptic-curve" } From ddbbc90088106c2a2027498c630b832a20c31435 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Sun, 12 Nov 2023 08:40:01 +0300 Subject: [PATCH 1064/1461] Apply Clippy to tests and fix some lints (#1386) --- .github/workflows/workspace.yml | 4 ++-- .../src/hash2curve/hash2field/expand_msg/xmd.rs | 1 + .../src/hash2curve/hash2field/expand_msg/xof.rs | 10 +++------- elliptic-curve/src/jwk.rs | 3 ++- 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index b70dad454..30a0da8f8 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -26,9 +26,9 @@ jobs: - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: - toolchain: 1.71.0 + toolchain: 1.73.0 components: clippy - - run: cargo clippy --all --all-features -- -D warnings + - run: cargo clippy --all --all-features --tests -- -D warnings rustfmt: runs-on: ubuntu-latest diff --git a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs index baf6f31b2..9cbd69832 100644 --- a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs +++ b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs @@ -199,6 +199,7 @@ mod test { } impl TestVector { + #[allow(clippy::panic_in_result_fn)] fn assert>( &self, dst: &'static [u8], diff --git a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs index 9a5ff19e9..7ffed126b 100644 --- a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs +++ b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs @@ -71,12 +71,7 @@ mod test { use hex_literal::hex; use sha3::Shake128; - fn assert_message( - msg: &[u8], - domain: &Domain<'_, U32>, - len_in_bytes: u16, - bytes: &[u8], - ) { + fn assert_message(msg: &[u8], domain: &Domain<'_, U32>, len_in_bytes: u16, bytes: &[u8]) { let msg_len = msg.len(); assert_eq!(msg, &bytes[..msg_len]); @@ -102,12 +97,13 @@ mod test { } impl TestVector { + #[allow(clippy::panic_in_result_fn)] fn assert(&self, dst: &'static [u8], domain: &Domain<'_, U32>) -> Result<()> where HashT: Default + ExtendableOutput + Update, L: ArrayLength, { - assert_message::(self.msg, domain, L::to_u16(), self.msg_prime); + assert_message(self.msg, domain, L::to_u16(), self.msg_prime); let mut expander = ExpandMsgXof::::expand_message(&[self.msg], &[dst], L::to_usize())?; diff --git a/elliptic-curve/src/jwk.rs b/elliptic-curve/src/jwk.rs index e0233cc00..58a9e3812 100644 --- a/elliptic-curve/src/jwk.rs +++ b/elliptic-curve/src/jwk.rs @@ -565,6 +565,7 @@ fn decode_base64url_fe(s: &str) -> Result> { #[cfg(test)] mod tests { + #![allow(clippy::unwrap_used, clippy::panic)] use super::*; #[cfg(feature = "dev")] @@ -656,7 +657,7 @@ mod tests { let point = jwk.to_encoded_point::().unwrap(); let (x, y) = match point.coordinates() { Coordinates::Uncompressed { x, y } => (x, y), - other => panic!("unexpected coordinates: {:?}", other), + other => panic!("unexpected coordinates: {other:?}"), }; assert_eq!(&decode_base64url_fe::(&jwk.x).unwrap(), x); From 8f77112b2c07db000dfb7d7172abc9a7ed50d709 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 11 Nov 2023 22:41:07 -0700 Subject: [PATCH 1065/1461] universal-hash: bump crypto-common to v0.2.0-pre; MSRV 1.65 (#1385) Replaces `generic-array` with `hybrid-array`, which is built on a combination of `typenum` and const generics, providing a degree of interoperability between the two systems. --- .github/workflows/universal-hash.yml | 13 ++++--- Cargo.lock | 20 +++++----- Cargo.toml | 2 +- crypto/Cargo.toml | 2 +- universal-hash/Cargo.lock | 49 ------------------------ universal-hash/Cargo.toml | 6 +-- universal-hash/README.md | 4 +- universal-hash/src/lib.rs | 57 ++++++---------------------- 8 files changed, 36 insertions(+), 117 deletions(-) delete mode 100644 universal-hash/Cargo.lock diff --git a/.github/workflows/universal-hash.yml b/.github/workflows/universal-hash.yml index f00cfe0f8..76a17285f 100644 --- a/.github/workflows/universal-hash.yml +++ b/.github/workflows/universal-hash.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.65.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -36,17 +36,18 @@ jobs: targets: ${{ matrix.target }} - run: cargo build --no-default-features --release --target ${{ matrix.target }} - minimal-versions: - uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master - with: - working-directory: ${{ github.workflow }} + # TODO(tarcieri): re-enable after next `crypto-common` release + # minimal-versions: + # uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master + # with: + # working-directory: ${{ github.workflow }} test: runs-on: ubuntu-latest strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.65.0 # MSRV - stable steps: - uses: actions/checkout@v4 diff --git a/Cargo.lock b/Cargo.lock index a9cbef675..363715652 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -135,7 +135,7 @@ dependencies = [ [[package]] name = "block-buffer" version = "0.11.0-pre" -source = "git+https://github.com/RustCrypto/utils.git#b755f1a29b074d8b0a6fc5fda5744312a11632c7" +source = "git+https://github.com/RustCrypto/utils.git#708aa72b9ebde06a02e862368e890fb3ddcb2fb9" dependencies = [ "crypto-common 0.2.0-pre", ] @@ -152,7 +152,7 @@ dependencies = [ [[package]] name = "block-padding" version = "0.4.0-pre" -source = "git+https://github.com/RustCrypto/utils.git#b755f1a29b074d8b0a6fc5fda5744312a11632c7" +source = "git+https://github.com/RustCrypto/utils.git#708aa72b9ebde06a02e862368e890fb3ddcb2fb9" dependencies = [ "hybrid-array", ] @@ -698,7 +698,7 @@ dependencies = [ [[package]] name = "hybrid-array" version = "0.2.0-pre.5" -source = "git+https://github.com/RustCrypto/utils.git#b755f1a29b074d8b0a6fc5fda5744312a11632c7" +source = "git+https://github.com/RustCrypto/utils.git#708aa72b9ebde06a02e862368e890fb3ddcb2fb9" dependencies = [ "typenum", ] @@ -716,7 +716,7 @@ dependencies = [ [[package]] name = "inout" version = "0.2.0-pre" -source = "git+https://github.com/RustCrypto/utils.git#b755f1a29b074d8b0a6fc5fda5744312a11632c7" +source = "git+https://github.com/RustCrypto/utils.git#708aa72b9ebde06a02e862368e890fb3ddcb2fb9" dependencies = [ "block-padding 0.4.0-pre", "hybrid-array", @@ -860,7 +860,7 @@ checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" dependencies = [ "cpufeatures", "opaque-debug", - "universal-hash 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "universal-hash 0.5.1", ] [[package]] @@ -872,7 +872,7 @@ dependencies = [ "cfg-if", "cpufeatures", "opaque-debug", - "universal-hash 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "universal-hash 0.5.1", ] [[package]] @@ -1207,6 +1207,8 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "universal-hash" version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" dependencies = [ "crypto-common 0.1.6", "subtle", @@ -1214,11 +1216,9 @@ dependencies = [ [[package]] name = "universal-hash" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +version = "0.6.0-pre" dependencies = [ - "crypto-common 0.1.6", + "crypto-common 0.2.0-pre", "subtle", ] diff --git a/Cargo.toml b/Cargo.toml index e4cda3420..90727b25a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,12 +9,12 @@ members = [ "elliptic-curve", "kem", "password-hash", + "universal-hash", ] # TODO: re-add to `members` when MSRV has been bumped to 1.60+ exclude = [ "signature", "signature/async", - "universal-hash", ] [patch.crates-io] diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index c3968eda1..95db1199a 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -22,7 +22,7 @@ digest = { version = "0.10", optional = true, features = ["mac"] } elliptic-curve = { version = "0.13", optional = true, path = "../elliptic-curve" } password-hash = { version = "0.5", optional = true, path = "../password-hash" } signature = { version = "2", optional = true, default-features = false, path = "../signature" } -universal-hash = { version = "0.5", optional = true, path = "../universal-hash" } +universal-hash = { version = "0.5", optional = true } [features] std = [ diff --git a/universal-hash/Cargo.lock b/universal-hash/Cargo.lock deleted file mode 100644 index 2542bc3d6..000000000 --- a/universal-hash/Cargo.lock +++ /dev/null @@ -1,49 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "generic-array" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "subtle" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e81da0851ada1f3e9d4312c704aa4f8806f0f9d69faaf8df2f3464b4a9437c2" - -[[package]] -name = "typenum" -version = "1.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" - -[[package]] -name = "universal-hash" -version = "0.5.1" -dependencies = [ - "crypto-common", - "subtle", -] - -[[package]] -name = "version_check" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45d3d553fd9413fffe7147a20171d640eda0ad4c070acd7d0c885a21bcd2e8b7" diff --git a/universal-hash/Cargo.toml b/universal-hash/Cargo.toml index 2cae13be1..a2786ecc9 100644 --- a/universal-hash/Cargo.toml +++ b/universal-hash/Cargo.toml @@ -1,11 +1,11 @@ [package] name = "universal-hash" -version = "0.5.1" +version = "0.6.0-pre" description = "Traits which describe the functionality of universal hash functions (UHFs)" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" edition = "2021" -rust-version = "1.56" +rust-version = "1.65" readme = "README.md" documentation = "https://docs.rs/universal-hash" repository = "https://github.com/RustCrypto/traits" @@ -13,7 +13,7 @@ keywords = ["crypto", "mac"] categories = ["cryptography", "no-std"] [dependencies] -crypto-common = "0.1.6" +crypto-common = "=0.2.0-pre" subtle = { version = "2.4", default-features = false } [features] diff --git a/universal-hash/README.md b/universal-hash/README.md index 9fd55a0cf..3bc9d0977 100644 --- a/universal-hash/README.md +++ b/universal-hash/README.md @@ -15,7 +15,7 @@ See [RustCrypto/universal-hashes] for implementations which use this trait. ## Minimum Supported Rust Version -Rust **1.56** or higher. +Rust **1.65** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -47,7 +47,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/universal-hash/badge.svg [docs-link]: https://docs.rs/universal-hash/ [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.65+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260051-universal-hashes [build-image]: https://github.com/RustCrypto/traits/workflows/universal-hash/badge.svg?branch=master&event=push diff --git a/universal-hash/src/lib.rs b/universal-hash/src/lib.rs index 87c963a4f..5fef8a6b4 100644 --- a/universal-hash/src/lib.rs +++ b/universal-hash/src/lib.rs @@ -1,43 +1,24 @@ -//! Traits for [Universal Hash Functions]. -//! -//! # About universal hashes -//! -//! Universal hash functions provide a "universal family" of possible -//! hash functions where a given member of a family is selected by a key. -//! -//! They are well suited to the purpose of "one time authenticators" for a -//! sequence of bytestring inputs, as their construction has a number of -//! desirable properties such as pairwise independence as well as amenability -//! to efficient implementations, particularly when implemented using SIMD -//! instructions. -//! -//! When combined with a cipher, such as in Galois/Counter Mode (GCM) or the -//! Salsa20 family AEAD constructions, they can provide the core functionality -//! for a Message Authentication Code (MAC). -//! -//! [Universal Hash Functions]: https://en.wikipedia.org/wiki/Universal_hashing - #![no_std] +#![cfg_attr(docsrs, feature(doc_auto_cfg))] +#![doc = include_str!("../README.md")] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg" )] -#![cfg_attr(docsrs, feature(doc_auto_cfg))] -#![deny(unsafe_code)] +#![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] #[cfg(feature = "std")] extern crate std; pub use crypto_common::{ - self, generic_array, + self, array, typenum::{self, consts}, Block, Key, KeyInit, ParBlocks, Reset, }; use core::slice; -use crypto_common::{BlockSizeUser, ParBlocksSizeUser}; -use generic_array::{ArrayLength, GenericArray}; +use crypto_common::{array::Array, BlockSizeUser, BlockSizes, ParBlocksSizeUser}; use subtle::ConstantTimeEq; use typenum::Unsigned; @@ -79,20 +60,20 @@ pub trait UniversalHash: BlockSizeUser + Sized { /// Update hash function state with the provided block. #[inline] fn update(&mut self, blocks: &[Block]) { - struct Ctx<'a, BS: ArrayLength> { + struct Ctx<'a, BS: BlockSizes> { blocks: &'a [Block], } - impl<'a, BS: ArrayLength> BlockSizeUser for Ctx<'a, BS> { + impl<'a, BS: BlockSizes> BlockSizeUser for Ctx<'a, BS> { type BlockSize = BS; } - impl<'a, BS: ArrayLength> UhfClosure for Ctx<'a, BS> { + impl<'a, BS: BlockSizes> UhfClosure for Ctx<'a, BS> { #[inline(always)] fn call>(self, backend: &mut B) { let pb = B::ParBlocksSize::USIZE; if pb > 1 { - let (par_blocks, tail) = to_blocks(self.blocks); + let (par_blocks, tail) = array::slice_as_chunks(self.blocks); for par_block in par_blocks { backend.proc_par_blocks(par_block); } @@ -118,12 +99,12 @@ pub trait UniversalHash: BlockSizeUser + Sized { /// Message Authentication Codes (MACs) based on universal hashing. #[inline] fn update_padded(&mut self, data: &[u8]) { - let (blocks, tail) = to_blocks(data); + let (blocks, tail) = array::slice_as_chunks(data); self.update(blocks); if !tail.is_empty() { - let mut padded_block = GenericArray::default(); + let mut padded_block = Array::default(); padded_block[..tail.len()].copy_from_slice(tail); self.update(slice::from_ref(&padded_block)); } @@ -132,7 +113,7 @@ pub trait UniversalHash: BlockSizeUser + Sized { /// Retrieve result and consume hasher instance. fn finalize(self) -> Block; - /// Obtain the [`Output`] of a [`UniversalHash`] computation and reset it back + /// Obtain the output of a [`UniversalHash`] computation and reset it back /// to its initial state. #[inline] fn finalize_reset(&mut self) -> Block @@ -173,17 +154,3 @@ impl core::fmt::Display for Error { #[cfg(feature = "std")] impl std::error::Error for Error {} - -/// Split message into slice of blocks and leftover tail. -// TODO: replace with `slice::as_chunks` on migration to const generics -#[inline(always)] -fn to_blocks>(data: &[T]) -> (&[GenericArray], &[T]) { - let nb = data.len() / N::USIZE; - let (left, right) = data.split_at(nb * N::USIZE); - let p = left.as_ptr() as *const GenericArray; - // SAFETY: we guarantee that `blocks` does not point outside of `data` - // and `p` is valid for reads - #[allow(unsafe_code)] - let blocks = unsafe { slice::from_raw_parts(p, nb) }; - (blocks, right) -} From 8e1df19d77283056c8e12e3ae1bc19ccdaaf0b94 Mon Sep 17 00:00:00 2001 From: Quinn Wilton Date: Sun, 12 Nov 2023 05:44:24 -0800 Subject: [PATCH 1066/1461] async-signature: remove mandatory Send + Sync bounds (#1375) See: https://github.com/RustCrypto/traits/issues/1373 --- signature/async/src/lib.rs | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/signature/async/src/lib.rs b/signature/async/src/lib.rs index 8a1cd6415..736bcdf46 100644 --- a/signature/async/src/lib.rs +++ b/signature/async/src/lib.rs @@ -18,12 +18,8 @@ use async_trait::async_trait; /// (e.g. client for a Cloud KMS or HSM), returning a digital signature. /// /// This trait is an async equivalent of the [`signature::Signer`] trait. -#[async_trait] -pub trait AsyncSigner -where - Self: Send + Sync, - S: Send + 'static, -{ +#[async_trait(?Send)] +pub trait AsyncSigner { /// Attempt to sign the given message, returning a digital signature on /// success, or an error if something went wrong. /// @@ -32,11 +28,11 @@ where async fn sign_async(&self, msg: &[u8]) -> Result; } -#[async_trait] +#[async_trait(?Send)] impl AsyncSigner for T where - S: Send + 'static, - T: signature::Signer + Send + Sync, + S: 'static, + T: signature::Signer, { async fn sign_async(&self, msg: &[u8]) -> Result { self.try_sign(msg) @@ -47,11 +43,10 @@ where /// /// This trait is an async equivalent of the [`signature::DigestSigner`] trait. #[cfg(feature = "digest")] -#[async_trait] +#[async_trait(?Send)] pub trait AsyncDigestSigner where - Self: Send + Sync, - D: Digest + Send + 'static, + D: Digest + 'static, S: 'static, { /// Attempt to sign the given prehashed message [`Digest`], returning a @@ -60,12 +55,12 @@ where } #[cfg(feature = "digest")] -#[async_trait] +#[async_trait(?Send)] impl AsyncDigestSigner for T where - D: Digest + Send + 'static, - S: Send + 'static, - T: signature::DigestSigner + Send + Sync, + D: Digest + 'static, + S: 'static, + T: signature::DigestSigner, { async fn sign_digest_async(&self, digest: D) -> Result { self.try_sign_digest(digest) From b3313d9a9594cf1df727668e7fa9da9eace30c8a Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Sun, 12 Nov 2023 16:54:06 +0300 Subject: [PATCH 1067/1461] digest: add DynDigestWithOid wrapper trait (#1390) --- digest/src/digest.rs | 9 +++++++++ digest/src/lib.rs | 2 ++ 2 files changed, 11 insertions(+) diff --git a/digest/src/digest.rs b/digest/src/digest.rs index 0642af43c..c8d1ca87e 100644 --- a/digest/src/digest.rs +++ b/digest/src/digest.rs @@ -3,6 +3,8 @@ use crypto_common::{typenum::Unsigned, Output, OutputSizeUser}; #[cfg(feature = "alloc")] use alloc::boxed::Box; +#[cfg(feature = "const-oid")] +use const_oid::DynAssociatedOid; /// Marker trait for cryptographic hash functions. pub trait HashMarker {} @@ -224,3 +226,10 @@ impl Clone for Box { self.box_clone() } } + +/// Convenience wrapper trait around [DynDigest] and [DynAssociatedOid]. +#[cfg(feature = "const-oid")] +pub trait DynDigestWithOid: DynDigest + DynAssociatedOid {} + +#[cfg(feature = "const-oid")] +impl DynDigestWithOid for T {} diff --git a/digest/src/lib.rs b/digest/src/lib.rs index b076853b8..1bb0d5325 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -59,6 +59,8 @@ pub use block_buffer; pub use const_oid; pub use crypto_common; +#[cfg(feature = "const-oid")] +pub use crate::digest::DynDigestWithOid; pub use crate::digest::{Digest, DynDigest, HashMarker}; pub use crypto_common::{array, typenum, typenum::consts, Output, OutputSizeUser, Reset}; #[cfg(feature = "mac")] From c4cd5eb72260ec6c432980005a128fbb0064fc00 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 12 Nov 2023 07:09:39 -0700 Subject: [PATCH 1068/1461] (async-)signature: MSRV 1.60 (#1387) To simplify the workspace, which contains weak/namespaced features, this bumps both `async-signature` and `signature` to MSRV 1.60. So as for the bump to have some justification, it adds weak feature activation for `rand_core?/std`, and uses this impl to write a `From` conversion which can preserve the original error as the boxed source. --- .github/workflows/async-signature.yml | 2 +- .github/workflows/signature.yml | 6 +- Cargo.lock | 49 ++++++- Cargo.toml | 5 +- crypto/Cargo.toml | 2 +- signature/Cargo.lock | 189 -------------------------- signature/Cargo.toml | 10 +- signature/README.md | 4 +- signature/async/Cargo.toml | 6 +- signature/async/README.md | 4 +- signature/src/error.rs | 13 ++ 11 files changed, 77 insertions(+), 213 deletions(-) delete mode 100644 signature/Cargo.lock diff --git a/.github/workflows/async-signature.yml b/.github/workflows/async-signature.yml index 497530a18..9d7da9f11 100644 --- a/.github/workflows/async-signature.yml +++ b/.github/workflows/async-signature.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.60.0 # MSRV - stable steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/signature.yml b/.github/workflows/signature.yml index 4816bd0e8..43cd3651e 100644 --- a/.github/workflows/signature.yml +++ b/.github/workflows/signature.yml @@ -23,7 +23,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.60.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -51,7 +51,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.60.0 # MSRV - stable steps: - uses: actions/checkout@v4 @@ -69,7 +69,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.60.0 # MSRV - stable steps: - uses: actions/checkout@v4 diff --git a/Cargo.lock b/Cargo.lock index 363715652..8509c494b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -54,6 +54,25 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +[[package]] +name = "async-signature" +version = "0.4.0-pre" +dependencies = [ + "async-trait", + "signature 2.2.0-pre", +] + +[[package]] +name = "async-trait" +version = "0.1.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "atomic-polyfill" version = "0.1.11" @@ -484,7 +503,7 @@ dependencies = [ "ff 0.13.0", "generic-array", "group 0.13.0", - "hex-literal", + "hex-literal 0.4.1", "hkdf 0.12.3", "pem-rfc7468 0.7.0", "pkcs8 0.10.2", @@ -629,6 +648,12 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "hex-literal" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" + [[package]] name = "hex-literal" version = "0.4.1" @@ -1134,6 +1159,28 @@ dependencies = [ [[package]] name = "signature" version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" + +[[package]] +name = "signature" +version = "2.2.0-pre" +dependencies = [ + "digest 0.10.7", + "hex-literal 0.3.4", + "rand_core 0.6.4", + "sha2 0.10.8", + "signature_derive", +] + +[[package]] +name = "signature_derive" +version = "2.0.1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] name = "spin" diff --git a/Cargo.toml b/Cargo.toml index 90727b25a..01eb142f8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,12 +9,9 @@ members = [ "elliptic-curve", "kem", "password-hash", - "universal-hash", -] -# TODO: re-add to `members` when MSRV has been bumped to 1.60+ -exclude = [ "signature", "signature/async", + "universal-hash", ] [patch.crates-io] diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 95db1199a..8f31c6e17 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -21,7 +21,7 @@ cipher = { version = "0.4", optional = true } digest = { version = "0.10", optional = true, features = ["mac"] } elliptic-curve = { version = "0.13", optional = true, path = "../elliptic-curve" } password-hash = { version = "0.5", optional = true, path = "../password-hash" } -signature = { version = "2", optional = true, default-features = false, path = "../signature" } +signature = { version = "2", optional = true, default-features = false } universal-hash = { version = "0.5", optional = true } [features] diff --git a/signature/Cargo.lock b/signature/Cargo.lock deleted file mode 100644 index 470272724..000000000 --- a/signature/Cargo.lock +++ /dev/null @@ -1,189 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "async-signature" -version = "0.3.0" -dependencies = [ - "async-trait", - "signature", -] - -[[package]] -name = "async-trait" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62d042b64fd281d31d58e80ac29426e114ae8eead17beb12fbd396a1d04eee84" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.0", -] - -[[package]] -name = "block-buffer" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03588e54c62ae6d763e2a80090d50353b785795361b4ff5b3bf0a5097fc31c0b" -dependencies = [ - "generic-array", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "cpufeatures" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" -dependencies = [ - "libc", -] - -[[package]] -name = "crypto-common" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "digest" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" -dependencies = [ - "block-buffer", - "crypto-common", -] - -[[package]] -name = "generic-array" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "hex-literal" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc38ca401ca1b8d89ff1185e39a132e5c4f86d844c0cf6364251576f2d7fa0c1" - -[[package]] -name = "libc" -version = "0.2.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "789da6d93f1b866ffe175afc5322a4d76c038605a1c3319bb57b06967ca98a36" - -[[package]] -name = "proc-macro2" -version = "1.0.52" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d0e1ae9e836cc3beddd63db0df682593d7e2d3d891ae8c9083d2113e1744224" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" - -[[package]] -name = "sha2" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99c3bd8169c58782adad9290a9af5939994036b76187f7b4f0e6de91dbbfc0ec" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "signature" -version = "2.1.0" -dependencies = [ - "digest", - "hex-literal", - "rand_core", - "sha2", - "signature_derive", -] - -[[package]] -name = "signature_derive" -version = "2.0.1" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.0", -] - -[[package]] -name = "syn" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f8c8eab7d9f493cd89d4068085651d81ac7d39c56eb64f7158ea514b156e280" -dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] - -[[package]] -name = "syn" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cff13bb1732bccfe3b246f3fdb09edfd51c01d6f5299b7ccd9457c2e4e37774" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "typenum" -version = "1.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" - -[[package]] -name = "unicode-ident" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee" - -[[package]] -name = "unicode-xid" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" - -[[package]] -name = "version_check" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45d3d553fd9413fffe7147a20171d640eda0ad4c070acd7d0c885a21bcd2e8b7" diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 0b1427dd5..b88f034c9 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "2.1.0" +version = "2.2.0-pre" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/signature" @@ -10,7 +10,7 @@ readme = "README.md" keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"] categories = ["cryptography", "no-std"] edition = "2021" -rust-version = "1.56" +rust-version = "1.60" [dependencies] derive = { package = "signature_derive", version = "2", optional = true, path = "derive" } @@ -23,12 +23,8 @@ sha2 = { version = "0.10", default-features = false } [features] alloc = [] -std = ["alloc"] +std = ["alloc", "rand_core?/std"] [package.metadata.docs.rs] all-features = true rustdoc-args = ["--cfg", "docsrs"] - -# TODO(tarcieri): remove when these crates are added to toplevel `members` -[workspace] -members = [".", "async"] diff --git a/signature/README.md b/signature/README.md index 6f205d603..5e1100301 100644 --- a/signature/README.md +++ b/signature/README.md @@ -17,7 +17,7 @@ the [RustCrypto] organization, as well as [`ed25519-dalek`]. ## Minimum Supported Rust Version -Rust **1.56** or higher. +Rust **1.60** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -56,7 +56,7 @@ dual licensed as above, without any additional terms or conditions. [build-image]: https://github.com/RustCrypto/traits/actions/workflows/signature.yml/badge.svg [build-link]: https://github.com/RustCrypto/traits/actions/workflows/signature.yml [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/260048-signatures diff --git a/signature/async/Cargo.toml b/signature/async/Cargo.toml index 2fa5df953..260e540b1 100644 --- a/signature/async/Cargo.toml +++ b/signature/async/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "async-signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "0.3.0" +version = "0.4.0-pre" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/async-signature" @@ -10,11 +10,11 @@ readme = "README.md" keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"] categories = ["cryptography", "no-std"] edition = "2021" -rust-version = "1.56" +rust-version = "1.60" [dependencies] async-trait = "0.1.9" -signature = { version = "2.0, <2.2", path = ".." } +signature = { version = "=2.2.0-pre", path = ".." } [features] digest = ["signature/digest"] diff --git a/signature/async/README.md b/signature/async/README.md index 135e6241a..55b6e64c1 100644 --- a/signature/async/README.md +++ b/signature/async/README.md @@ -9,7 +9,7 @@ ## Minimum Supported Rust Version -Rust **1.56** or higher. +Rust **1.60** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -36,7 +36,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/async-signature/badge.svg [docs-link]: https://docs.rs/async-signature/ [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/260048-signatures [build-image]: https://github.com/RustCrypto/traits/workflows/async-signature/badge.svg?branch=master&event=push diff --git a/signature/src/error.rs b/signature/src/error.rs index 1bfaf33bf..6518f17b8 100644 --- a/signature/src/error.rs +++ b/signature/src/error.rs @@ -93,6 +93,19 @@ impl From> for Error { } } +#[cfg(feature = "rand_core")] +impl From for Error { + #[cfg(not(feature = "std"))] + fn from(_source: rand_core::Error) -> Error { + Error::new() + } + + #[cfg(feature = "std")] + fn from(source: rand_core::Error) -> Error { + Error::from_source(source) + } +} + #[cfg(feature = "std")] impl std::error::Error for Error { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { From 5b2f9cb26633bc11ab923e463dba305207d10856 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 12 Nov 2023 08:29:16 -0700 Subject: [PATCH 1069/1461] Move `async-signature` and `signature-derive` to toplevel (#1391) These crates were previously nested under `signature/async` and `signature/derive`, which complicates tooling that expects crates to be in toplevel directories, and as things currently stand also meant that releases of the `signature` crate accidentally included stale copies of the other two crates. This commit moves them to toplevel `async-signature` and `signature-derive` directories. --- .github/workflows/async-signature.yml | 5 +++-- .github/workflows/signature.yml | 3 ++- Cargo.lock | 5 ++++- Cargo.toml | 3 ++- {signature/async => async-signature}/CHANGELOG.md | 0 {signature/async => async-signature}/Cargo.toml | 4 ++-- {signature/async => async-signature}/LICENSE-APACHE | 0 {signature/async => async-signature}/LICENSE-MIT | 0 {signature/async => async-signature}/README.md | 0 {signature/async => async-signature}/src/lib.rs | 0 {signature/derive => signature-derive}/CHANGELOG.md | 0 {signature/derive => signature-derive}/Cargo.toml | 2 +- {signature/derive => signature-derive}/LICENSE-APACHE | 0 {signature/derive => signature-derive}/LICENSE-MIT | 0 {signature/derive => signature-derive}/README.md | 0 {signature/derive => signature-derive}/src/lib.rs | 0 signature/Cargo.toml | 2 +- 17 files changed, 15 insertions(+), 9 deletions(-) rename {signature/async => async-signature}/CHANGELOG.md (100%) rename {signature/async => async-signature}/Cargo.toml (90%) rename {signature/async => async-signature}/LICENSE-APACHE (100%) rename {signature/async => async-signature}/LICENSE-MIT (100%) rename {signature/async => async-signature}/README.md (100%) rename {signature/async => async-signature}/src/lib.rs (100%) rename {signature/derive => signature-derive}/CHANGELOG.md (100%) rename {signature/derive => signature-derive}/Cargo.toml (96%) rename {signature/derive => signature-derive}/LICENSE-APACHE (100%) rename {signature/derive => signature-derive}/LICENSE-MIT (100%) rename {signature/derive => signature-derive}/README.md (100%) rename {signature/derive => signature-derive}/src/lib.rs (100%) diff --git a/.github/workflows/async-signature.yml b/.github/workflows/async-signature.yml index 9d7da9f11..41aba9707 100644 --- a/.github/workflows/async-signature.yml +++ b/.github/workflows/async-signature.yml @@ -3,6 +3,7 @@ name: async-signature on: pull_request: paths: + - "async-signature/**" - "signature/**" - "Cargo.*" push: @@ -10,7 +11,7 @@ on: defaults: run: - working-directory: signature/async + working-directory: async-signature env: CARGO_INCREMENTAL: 0 @@ -43,5 +44,5 @@ jobs: - run: cargo update -Z minimal-versions - uses: dtolnay/rust-toolchain@stable - uses: RustCrypto/actions/cargo-hack-install@master - - run: rm ../../Cargo.toml + - run: rm ../Cargo.toml - run: cargo hack test --release --feature-powerset diff --git a/.github/workflows/signature.yml b/.github/workflows/signature.yml index 43cd3651e..335d3516d 100644 --- a/.github/workflows/signature.yml +++ b/.github/workflows/signature.yml @@ -4,6 +4,7 @@ on: pull_request: paths: - "signature/**" + - "signature-derive/**" - "Cargo.*" push: branches: master @@ -78,7 +79,7 @@ jobs: with: toolchain: ${{ matrix.rust }} - run: cargo test --release - working-directory: signature/derive + working-directory: signature-derive doc: runs-on: ubuntu-latest diff --git a/Cargo.lock b/Cargo.lock index 8509c494b..02129cfd4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -59,7 +59,7 @@ name = "async-signature" version = "0.4.0-pre" dependencies = [ "async-trait", - "signature 2.2.0-pre", + "signature 2.1.0", ] [[package]] @@ -1161,6 +1161,9 @@ name = "signature" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +dependencies = [ + "digest 0.10.7", +] [[package]] name = "signature" diff --git a/Cargo.toml b/Cargo.toml index 01eb142f8..01ab3016c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,6 +2,7 @@ resolver = "2" members = [ "aead", + "async-signature", "cipher", "crypto", "crypto-common", @@ -10,7 +11,7 @@ members = [ "kem", "password-hash", "signature", - "signature/async", + "signature-derive", "universal-hash", ] diff --git a/signature/async/CHANGELOG.md b/async-signature/CHANGELOG.md similarity index 100% rename from signature/async/CHANGELOG.md rename to async-signature/CHANGELOG.md diff --git a/signature/async/Cargo.toml b/async-signature/Cargo.toml similarity index 90% rename from signature/async/Cargo.toml rename to async-signature/Cargo.toml index 260e540b1..098a390aa 100644 --- a/signature/async/Cargo.toml +++ b/async-signature/Cargo.toml @@ -5,7 +5,7 @@ version = "0.4.0-pre" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/async-signature" -repository = "https://github.com/RustCrypto/traits/tree/master/signature/async" +repository = "https://github.com/RustCrypto/traits/tree/master/async-signature" readme = "README.md" keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"] categories = ["cryptography", "no-std"] @@ -14,7 +14,7 @@ rust-version = "1.60" [dependencies] async-trait = "0.1.9" -signature = { version = "=2.2.0-pre", path = ".." } +signature = ">= 2.0, <2.3" [features] digest = ["signature/digest"] diff --git a/signature/async/LICENSE-APACHE b/async-signature/LICENSE-APACHE similarity index 100% rename from signature/async/LICENSE-APACHE rename to async-signature/LICENSE-APACHE diff --git a/signature/async/LICENSE-MIT b/async-signature/LICENSE-MIT similarity index 100% rename from signature/async/LICENSE-MIT rename to async-signature/LICENSE-MIT diff --git a/signature/async/README.md b/async-signature/README.md similarity index 100% rename from signature/async/README.md rename to async-signature/README.md diff --git a/signature/async/src/lib.rs b/async-signature/src/lib.rs similarity index 100% rename from signature/async/src/lib.rs rename to async-signature/src/lib.rs diff --git a/signature/derive/CHANGELOG.md b/signature-derive/CHANGELOG.md similarity index 100% rename from signature/derive/CHANGELOG.md rename to signature-derive/CHANGELOG.md diff --git a/signature/derive/Cargo.toml b/signature-derive/Cargo.toml similarity index 96% rename from signature/derive/Cargo.toml rename to signature-derive/Cargo.toml index 35a1e8488..e12d1e084 100644 --- a/signature/derive/Cargo.toml +++ b/signature-derive/Cargo.toml @@ -5,7 +5,7 @@ authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" description = "Custom derive support for the 'signature' crate" documentation = "https://docs.rs/signature" -repository = "https://github.com/RustCrypto/traits/tree/master/signature/derive" +repository = "https://github.com/RustCrypto/traits/tree/master/signature-derive" readme = "README.md" edition = "2021" rust-version = "1.56" diff --git a/signature/derive/LICENSE-APACHE b/signature-derive/LICENSE-APACHE similarity index 100% rename from signature/derive/LICENSE-APACHE rename to signature-derive/LICENSE-APACHE diff --git a/signature/derive/LICENSE-MIT b/signature-derive/LICENSE-MIT similarity index 100% rename from signature/derive/LICENSE-MIT rename to signature-derive/LICENSE-MIT diff --git a/signature/derive/README.md b/signature-derive/README.md similarity index 100% rename from signature/derive/README.md rename to signature-derive/README.md diff --git a/signature/derive/src/lib.rs b/signature-derive/src/lib.rs similarity index 100% rename from signature/derive/src/lib.rs rename to signature-derive/src/lib.rs diff --git a/signature/Cargo.toml b/signature/Cargo.toml index b88f034c9..8790e28c3 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -13,7 +13,7 @@ edition = "2021" rust-version = "1.60" [dependencies] -derive = { package = "signature_derive", version = "2", optional = true, path = "derive" } +derive = { package = "signature_derive", version = "2", optional = true, path = "../signature-derive" } digest = { version = "0.10.6", optional = true, default-features = false } rand_core = { version = "0.6.4", optional = true, default-features = false } From 2b4f64886fd3d5ceaffcde8c3bed3ff632472a66 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 12 Nov 2023 08:49:20 -0700 Subject: [PATCH 1070/1461] async-signature: re-add 'static bound (#1392) Accidentally removed in #1375 --- async-signature/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/async-signature/src/lib.rs b/async-signature/src/lib.rs index 736bcdf46..fde8ca241 100644 --- a/async-signature/src/lib.rs +++ b/async-signature/src/lib.rs @@ -19,7 +19,7 @@ use async_trait::async_trait; /// /// This trait is an async equivalent of the [`signature::Signer`] trait. #[async_trait(?Send)] -pub trait AsyncSigner { +pub trait AsyncSigner { /// Attempt to sign the given message, returning a digital signature on /// success, or an error if something went wrong. /// From 6e7ee07546ad42b9aba395ba15092199f0025545 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Sun, 12 Nov 2023 19:23:52 +0300 Subject: [PATCH 1071/1461] cipher: stream cipher improvements (#1388) --- cipher/src/stream.rs | 26 ++-- cipher/src/stream_core.rs | 25 +--- cipher/src/stream_wrapper.rs | 254 +++++++++++++++++------------------ 3 files changed, 137 insertions(+), 168 deletions(-) diff --git a/cipher/src/stream.rs b/cipher/src/stream.rs index 3ac454e6d..2de826332 100644 --- a/cipher/src/stream.rs +++ b/cipher/src/stream.rs @@ -202,21 +202,21 @@ macro_rules! impl_seek_num { {$($t:ty )*} => { $( impl SeekNum for $t { - fn from_block_byte(block: T, byte: u8, bs: u8) -> Result { - debug_assert!(byte < bs); - let mut block: Self = block.try_into().map_err(|_| OverflowError)?; - if byte != 0 { - block -= 1; - } - let pos = block.checked_mul(bs as Self).ok_or(OverflowError)? + (byte as Self); - Ok(pos) + fn from_block_byte(block: T, byte: u8, block_size: u8) -> Result { + debug_assert!(byte != 0); + let rem = block_size.checked_sub(byte).ok_or(OverflowError)?; + let block: Self = block.try_into().map_err(|_| OverflowError)?; + block + .checked_mul(block_size.into()) + .and_then(|v| v.checked_sub(rem.into())) + .ok_or(OverflowError) } - fn into_block_byte(self, bs: u8) -> Result<(T, u8), OverflowError> { - let bs = bs as Self; - let byte = self % bs; - let block = T::try_from(self/bs).map_err(|_| OverflowError)?; - Ok((block, byte as u8)) + fn into_block_byte(self, block_size: u8) -> Result<(T, u8), OverflowError> { + let bs: Self = block_size.into(); + let byte = (self % bs) as u8; + let block = T::try_from(self / bs).map_err(|_| OverflowError)?; + Ok((block, byte)) } } )* diff --git a/cipher/src/stream_core.rs b/cipher/src/stream_core.rs index 5a9232dbe..84d21350c 100644 --- a/cipher/src/stream_core.rs +++ b/cipher/src/stream_core.rs @@ -1,6 +1,6 @@ use crate::{ParBlocks, ParBlocksSizeUser, StreamCipherError}; use crypto_common::{ - array::{Array, ArraySize}, + array::{slice_as_chunks_mut, Array}, typenum::Unsigned, Block, BlockSizeUser, BlockSizes, }; @@ -190,27 +190,6 @@ macro_rules! impl_counter { impl_counter! { u32 u64 u128 } -/// Partition buffer into 2 parts: buffer of arrays and tail. -/// -/// In case if `N` is less or equal to 1, buffer of arrays has length -/// of zero and tail is equal to `self`. -#[inline] -fn into_chunks(buf: &mut [T]) -> (&mut [Array], &mut [T]) { - use core::slice; - if N::USIZE <= 1 { - return (&mut [], buf); - } - let chunks_len = buf.len() / N::USIZE; - let tail_pos = N::USIZE * chunks_len; - let tail_len = buf.len() - tail_pos; - unsafe { - let ptr = buf.as_mut_ptr(); - let chunks = slice::from_raw_parts_mut(ptr as *mut Array, chunks_len); - let tail = slice::from_raw_parts_mut(ptr.add(tail_pos), tail_len); - (chunks, tail) - } -} - struct WriteBlockCtx<'a, BS: BlockSizes> { block: &'a mut Block, } @@ -234,7 +213,7 @@ impl<'a, BS: BlockSizes> StreamClosure for WriteBlocksCtx<'a, BS> { #[inline(always)] fn call>(self, backend: &mut B) { if B::ParBlocksSize::USIZE > 1 { - let (chunks, tail) = into_chunks::<_, B::ParBlocksSize>(self.blocks); + let (chunks, tail) = slice_as_chunks_mut(self.blocks); for chunk in chunks { backend.gen_par_ks_blocks(chunk); } diff --git a/cipher/src/stream_wrapper.rs b/cipher/src/stream_wrapper.rs index fb128389f..1002ced0f 100644 --- a/cipher/src/stream_wrapper.rs +++ b/cipher/src/stream_wrapper.rs @@ -2,33 +2,50 @@ use crate::{ errors::StreamCipherError, Block, OverflowError, SeekNum, StreamCipher, StreamCipherCore, StreamCipherSeek, StreamCipherSeekCore, }; -use crypto_common::{ - typenum::{IsLess, Le, NonZero, Unsigned, U256}, - BlockSizeUser, Iv, IvSizeUser, Key, KeyInit, KeyIvInit, KeySizeUser, -}; +use core::fmt; +use crypto_common::{typenum::Unsigned, Iv, IvSizeUser, Key, KeyInit, KeyIvInit, KeySizeUser}; use inout::InOutBuf; #[cfg(feature = "zeroize")] use zeroize::{Zeroize, ZeroizeOnDrop}; -/// Wrapper around [`StreamCipherCore`] implementations. +/// Buffering wrapper around a [`StreamCipherCore`] implementation. /// /// It handles data buffering and implements the slice-based traits. -#[derive(Clone, Default)] -pub struct StreamCipherCoreWrapper -where - T::BlockSize: IsLess, - Le: NonZero, -{ +pub struct StreamCipherCoreWrapper { core: T, + // First byte is used as position buffer: Block, - pos: u8, } -impl StreamCipherCoreWrapper -where - T::BlockSize: IsLess, - Le: NonZero, -{ +impl Default for StreamCipherCoreWrapper { + #[inline] + fn default() -> Self { + Self::from_core(T::default()) + } +} + +impl Clone for StreamCipherCoreWrapper { + #[inline] + fn clone(&self) -> Self { + Self { + core: self.core.clone(), + buffer: self.buffer.clone(), + } + } +} + +impl fmt::Debug for StreamCipherCoreWrapper { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let pos = self.get_pos().into(); + let buf_data = &self.buffer[pos..]; + f.debug_struct("StreamCipherCoreWrapper") + .field("core", &self.core) + .field("buffer_data", &buf_data) + .finish() + } +} + +impl StreamCipherCoreWrapper { /// Return reference to the core type. pub fn get_core(&self) -> &T { &self.core @@ -36,73 +53,61 @@ where /// Return reference to the core type. pub fn from_core(core: T) -> Self { - Self { - core, - buffer: Default::default(), - pos: 0, - } + let mut buffer: Block = Default::default(); + buffer[0] = T::BlockSize::U8; + Self { core, buffer } } /// Return current cursor position. #[inline] - fn get_pos(&self) -> usize { - let pos = self.pos as usize; - if T::BlockSize::USIZE == 0 { - panic!("Block size can not be equal to zero"); - } - if pos >= T::BlockSize::USIZE { + fn get_pos(&self) -> u8 { + let pos = self.buffer[0]; + if pos == 0 || pos > T::BlockSize::U8 { debug_assert!(false); - // SAFETY: `pos` is set only to values smaller than block size - unsafe { core::hint::unreachable_unchecked() } + // SAFETY: `pos` never breaks the invariant + unsafe { + core::hint::unreachable_unchecked(); + } } - self.pos as usize - } - - /// Return size of the internal buffer in bytes. - #[inline] - fn size(&self) -> usize { - T::BlockSize::USIZE + pos } /// Set buffer position without checking that it's smaller /// than buffer size. /// /// # Safety - /// `pos` MUST be smaller than `T::BlockSize::USIZE`. + /// `pos` MUST be bigger than zero and smaller or equal to `T::BlockSize::USIZE`. #[inline] unsafe fn set_pos_unchecked(&mut self, pos: usize) { - debug_assert!(pos < T::BlockSize::USIZE); - self.pos = pos as u8; + debug_assert!(pos != 0 && pos <= T::BlockSize::USIZE); + // Block size is always smaller than 256 because of the `BlockSizes` bound, + // so if the safety condition is satisfied, the `as` cast does not truncate + // any non-zero bits. + self.buffer[0] = pos as u8; } /// Return number of remaining bytes in the internal buffer. #[inline] - fn remaining(&self) -> usize { - self.size() - self.get_pos() + fn remaining(&self) -> u8 { + // This never underflows because of the safety invariant + T::BlockSize::U8 - self.get_pos() } - fn check_remaining(&self, dlen: usize) -> Result<(), StreamCipherError> { + fn check_remaining(&self, data_len: usize) -> Result<(), StreamCipherError> { let rem_blocks = match self.core.remaining_blocks() { Some(v) => v, None => return Ok(()), }; - let bytes = if self.pos == 0 { - dlen - } else { - let rem = self.remaining(); - if dlen > rem { - dlen - rem - } else { - return Ok(()); - } + let buf_rem = usize::from(self.remaining()); + let data_len = match data_len.checked_sub(buf_rem) { + Some(0) | None => return Ok(()), + Some(res) => res, }; + let bs = T::BlockSize::USIZE; - let blocks = if bytes % bs == 0 { - bytes / bs - } else { - bytes / bs + 1 - }; + // TODO: use div_ceil on 1.73+ MSRV bump + let blocks = (data_len + bs - 1) / bs; if blocks > rem_blocks { Err(StreamCipherError) } else { @@ -111,11 +116,7 @@ where } } -impl StreamCipher for StreamCipherCoreWrapper -where - T::BlockSize: IsLess, - Le: NonZero, -{ +impl StreamCipher for StreamCipherCoreWrapper { #[inline] fn try_apply_keystream_inout( &mut self, @@ -123,136 +124,125 @@ where ) -> Result<(), StreamCipherError> { self.check_remaining(data.len())?; - let pos = self.get_pos(); - if pos != 0 { - let rem = &self.buffer[pos..]; - let n = data.len(); - if n < rem.len() { - data.xor_in2out(&rem[..n]); - // SAFETY: we have checked that `n` is less than length of `rem`, - // which is equal to buffer length minus `pos`, thus `pos + n` is - // less than buffer length and satisfies the `set_pos_unchecked` - // safety condition + let pos = usize::from(self.get_pos()); + let rem = usize::from(self.remaining()); + let data_len = data.len(); + + if rem != 0 { + if data_len <= rem { + data.xor_in2out(&self.buffer[pos..][..data_len]); + // SAFETY: we have checked that `data_len` is less or equal to length + // of remaining keystream data, thus `pos + data_len` can not be bigger + // than block size. Since `pos` is never zero, `pos + data_len` can not + // be zero. Thus `pos + data_len` satisfies the safety invariant required + // by `set_pos_unchecked`. unsafe { - self.set_pos_unchecked(pos + n); + self.set_pos_unchecked(pos + data_len); } return Ok(()); } - let (mut left, right) = data.split_at(rem.len()); + let (mut left, right) = data.split_at(rem); data = right; - left.xor_in2out(rem); + left.xor_in2out(&self.buffer[pos..]); } - let (blocks, mut leftover) = data.into_chunks(); + let (blocks, mut tail) = data.into_chunks(); self.core.apply_keystream_blocks_inout(blocks); - let n = leftover.len(); - if n != 0 { + let new_pos = if tail.is_empty() { + T::BlockSize::USIZE + } else { + // Note that we temporarily write a pseudo-random byte into + // the first byte of `self.buffer`. It may break the safety invariant, + // but after XORing keystream block with `tail`, we immediately + // overwrite the first byte with a correct value. self.core.write_keystream_block(&mut self.buffer); - leftover.xor_in2out(&self.buffer[..n]); - } + tail.xor_in2out(&self.buffer[..data_len]); + tail.len() + }; + // SAFETY: `into_chunks` always returns tail with size - // less than buffer length, thus `n` satisfies the `set_pos_unchecked` - // safety condition + // less than block size. If `tail.len()` is zero, we replace + // it with block size. Thus the invariant required by + // `set_pos_unchecked` is satisfied. unsafe { - self.set_pos_unchecked(n); + self.set_pos_unchecked(new_pos); } Ok(()) } } -impl StreamCipherSeek for StreamCipherCoreWrapper -where - T::BlockSize: IsLess, - Le: NonZero, -{ +impl StreamCipherSeek for StreamCipherCoreWrapper { fn try_current_pos(&self) -> Result { - let Self { core, pos, .. } = self; - SN::from_block_byte(core.get_block_pos(), *pos, T::BlockSize::U8) + let pos = self.get_pos(); + SN::from_block_byte(self.core.get_block_pos(), pos, T::BlockSize::U8) } fn try_seek(&mut self, new_pos: SN) -> Result<(), StreamCipherError> { - let Self { core, buffer, pos } = self; let (block_pos, byte_pos) = new_pos.into_block_byte(T::BlockSize::U8)?; - core.set_block_pos(block_pos); - if byte_pos != 0 { - self.core.write_keystream_block(buffer); + // For correct implementations of `SeekNum` compiler should be able to + // eliminate this assert + assert!(byte_pos < T::BlockSize::U8); + + self.core.set_block_pos(block_pos); + let new_pos = if byte_pos != 0 { + // See comment in `try_apply_keystream_inout` for use of `write_keystream_block` + self.core.write_keystream_block(&mut self.buffer); + byte_pos.into() + } else { + T::BlockSize::USIZE + }; + // SAFETY: we assert that `byte_pos` is always smaller than block size. + // If `byte_pos` is zero, we replace it with block size. Thus the invariant + // required by `set_pos_unchecked` is satisfied. + unsafe { + self.set_pos_unchecked(new_pos); } - *pos = byte_pos; Ok(()) } } // Note: ideally we would only implement the InitInner trait and everything -// else would be handled by blanket impls, but unfortunately it will +// else would be handled by blanket impls, but, unfortunately, it will // not work properly without mutually exclusive traits, see: // https://github.com/rust-lang/rfcs/issues/1053 -impl KeySizeUser for StreamCipherCoreWrapper -where - T::BlockSize: IsLess, - Le: NonZero, -{ +impl KeySizeUser for StreamCipherCoreWrapper { type KeySize = T::KeySize; } -impl IvSizeUser for StreamCipherCoreWrapper -where - T::BlockSize: IsLess, - Le: NonZero, -{ +impl IvSizeUser for StreamCipherCoreWrapper { type IvSize = T::IvSize; } -impl KeyIvInit for StreamCipherCoreWrapper -where - T::BlockSize: IsLess, - Le: NonZero, -{ +impl KeyIvInit for StreamCipherCoreWrapper { #[inline] fn new(key: &Key, iv: &Iv) -> Self { Self { core: T::new(key, iv), buffer: Default::default(), - pos: 0, } } } -impl KeyInit for StreamCipherCoreWrapper -where - T::BlockSize: IsLess, - Le: NonZero, -{ +impl KeyInit for StreamCipherCoreWrapper { #[inline] fn new(key: &Key) -> Self { Self { core: T::new(key), buffer: Default::default(), - pos: 0, } } } #[cfg(feature = "zeroize")] -impl Drop for StreamCipherCoreWrapper -where - T: BlockSizeUser, - T::BlockSize: IsLess, - Le: NonZero, -{ +impl Drop for StreamCipherCoreWrapper { fn drop(&mut self) { + // If present, `core` will be zeroized by its own `Drop`. self.buffer.zeroize(); - self.pos.zeroize(); } } #[cfg(feature = "zeroize")] -impl ZeroizeOnDrop for StreamCipherCoreWrapper -where - T: BlockSizeUser + ZeroizeOnDrop, - T::BlockSize: IsLess, - Le: NonZero, -{ -} +impl ZeroizeOnDrop for StreamCipherCoreWrapper {} From c85a5b815b3705fb5040307c3f5a4e06316b4c95 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 12 Nov 2023 09:46:56 -0700 Subject: [PATCH 1072/1461] async-signature v0.4.0 (#1393) --- Cargo.lock | 2 +- async-signature/CHANGELOG.md | 12 +++++++++++- async-signature/Cargo.toml | 2 +- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 02129cfd4..a43231f39 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -56,7 +56,7 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "async-signature" -version = "0.4.0-pre" +version = "0.4.0" dependencies = [ "async-trait", "signature 2.1.0", diff --git a/async-signature/CHANGELOG.md b/async-signature/CHANGELOG.md index ae44dcb7b..861489b28 100644 --- a/async-signature/CHANGELOG.md +++ b/async-signature/CHANGELOG.md @@ -4,7 +4,17 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 0.3.0 (2022-01-15) +## 0.4.0 (2023-11-12) +### Changed +- MSRV 1.60 ([#1387]) + +### Removed +- Mandatory `Send` + `Sync` bounds ([#1375]) + +[#1375]: https://github.com/RustCrypto/traits/pull/1375 +[#1387]: https://github.com/RustCrypto/traits/pull/1387 + +## 0.3.0 (2023-01-15) ### Changed - Bump `signature` to v2 ([#1141], [#1211]) diff --git a/async-signature/Cargo.toml b/async-signature/Cargo.toml index 098a390aa..753f62944 100644 --- a/async-signature/Cargo.toml +++ b/async-signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "async-signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "0.4.0-pre" +version = "0.4.0" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/async-signature" From 11e7c7361167de9bb89fb1f7103f0013d36ebcd7 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 12 Nov 2023 10:39:25 -0700 Subject: [PATCH 1073/1461] signature_derive: match directory name with crate (#1394) The crate name contains an underscore, not a hyphen, but #1391 accidentally used `signature-derive` instead --- .github/workflows/signature.yml | 2 +- Cargo.toml | 2 +- signature/Cargo.toml | 2 +- {signature-derive => signature_derive}/CHANGELOG.md | 0 {signature-derive => signature_derive}/Cargo.toml | 2 +- {signature-derive => signature_derive}/LICENSE-APACHE | 0 {signature-derive => signature_derive}/LICENSE-MIT | 0 {signature-derive => signature_derive}/README.md | 0 {signature-derive => signature_derive}/src/lib.rs | 0 9 files changed, 4 insertions(+), 4 deletions(-) rename {signature-derive => signature_derive}/CHANGELOG.md (100%) rename {signature-derive => signature_derive}/Cargo.toml (96%) rename {signature-derive => signature_derive}/LICENSE-APACHE (100%) rename {signature-derive => signature_derive}/LICENSE-MIT (100%) rename {signature-derive => signature_derive}/README.md (100%) rename {signature-derive => signature_derive}/src/lib.rs (100%) diff --git a/.github/workflows/signature.yml b/.github/workflows/signature.yml index 335d3516d..73a6571dd 100644 --- a/.github/workflows/signature.yml +++ b/.github/workflows/signature.yml @@ -79,7 +79,7 @@ jobs: with: toolchain: ${{ matrix.rust }} - run: cargo test --release - working-directory: signature-derive + working-directory: signature_derive doc: runs-on: ubuntu-latest diff --git a/Cargo.toml b/Cargo.toml index 01ab3016c..56fd5a9aa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ members = [ "kem", "password-hash", "signature", - "signature-derive", + "signature_derive", "universal-hash", ] diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 8790e28c3..193aa1108 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -13,7 +13,7 @@ edition = "2021" rust-version = "1.60" [dependencies] -derive = { package = "signature_derive", version = "2", optional = true, path = "../signature-derive" } +derive = { package = "signature_derive", version = "2", optional = true, path = "../signature_derive" } digest = { version = "0.10.6", optional = true, default-features = false } rand_core = { version = "0.6.4", optional = true, default-features = false } diff --git a/signature-derive/CHANGELOG.md b/signature_derive/CHANGELOG.md similarity index 100% rename from signature-derive/CHANGELOG.md rename to signature_derive/CHANGELOG.md diff --git a/signature-derive/Cargo.toml b/signature_derive/Cargo.toml similarity index 96% rename from signature-derive/Cargo.toml rename to signature_derive/Cargo.toml index e12d1e084..05ccbe841 100644 --- a/signature-derive/Cargo.toml +++ b/signature_derive/Cargo.toml @@ -8,7 +8,7 @@ documentation = "https://docs.rs/signature" repository = "https://github.com/RustCrypto/traits/tree/master/signature-derive" readme = "README.md" edition = "2021" -rust-version = "1.56" +rust-version = "1.60" keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"] categories = ["cryptography", "no-std"] diff --git a/signature-derive/LICENSE-APACHE b/signature_derive/LICENSE-APACHE similarity index 100% rename from signature-derive/LICENSE-APACHE rename to signature_derive/LICENSE-APACHE diff --git a/signature-derive/LICENSE-MIT b/signature_derive/LICENSE-MIT similarity index 100% rename from signature-derive/LICENSE-MIT rename to signature_derive/LICENSE-MIT diff --git a/signature-derive/README.md b/signature_derive/README.md similarity index 100% rename from signature-derive/README.md rename to signature_derive/README.md diff --git a/signature-derive/src/lib.rs b/signature_derive/src/lib.rs similarity index 100% rename from signature-derive/src/lib.rs rename to signature_derive/src/lib.rs From c2a8466861381a4a1b5911cefa54c705bb752027 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 12 Nov 2023 11:49:52 -0700 Subject: [PATCH 1074/1461] signature_derive v2.1.0 (#1395) --- Cargo.lock | 2 +- signature_derive/CHANGELOG.md | 6 ++++++ signature_derive/Cargo.toml | 4 ++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a43231f39..244df6c8b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1178,7 +1178,7 @@ dependencies = [ [[package]] name = "signature_derive" -version = "2.0.1" +version = "2.1.0" dependencies = [ "proc-macro2", "quote", diff --git a/signature_derive/CHANGELOG.md b/signature_derive/CHANGELOG.md index 4e0656283..0edb20cdb 100644 --- a/signature_derive/CHANGELOG.md +++ b/signature_derive/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 2.1.0 (2023-11-12) +### Changed +- MSRV 1.60 ([#1387]) + +[#1387]: https://github.com/RustCrypto/traits/pull/1387 + ## 2.0.1 (2023-04-17) ### Changed - Bump `syn` to v2 ([#1299]) diff --git a/signature_derive/Cargo.toml b/signature_derive/Cargo.toml index 05ccbe841..ba1e7d53c 100644 --- a/signature_derive/Cargo.toml +++ b/signature_derive/Cargo.toml @@ -1,11 +1,11 @@ [package] name = "signature_derive" -version = "2.0.1" +version = "2.1.0" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" description = "Custom derive support for the 'signature' crate" documentation = "https://docs.rs/signature" -repository = "https://github.com/RustCrypto/traits/tree/master/signature-derive" +repository = "https://github.com/RustCrypto/traits/tree/master/signature_derive" readme = "README.md" edition = "2021" rust-version = "1.60" From 7716a995ec5e6e70959732d7fa9c2d6bfdf4bbdc Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 12 Nov 2023 13:09:22 -0700 Subject: [PATCH 1075/1461] signature: bump `hex-literal` to v0.4 (#1396) --- Cargo.lock | 10 ++-------- signature/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 244df6c8b..970e15937 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -503,7 +503,7 @@ dependencies = [ "ff 0.13.0", "generic-array", "group 0.13.0", - "hex-literal 0.4.1", + "hex-literal", "hkdf 0.12.3", "pem-rfc7468 0.7.0", "pkcs8 0.10.2", @@ -648,12 +648,6 @@ dependencies = [ "stable_deref_trait", ] -[[package]] -name = "hex-literal" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" - [[package]] name = "hex-literal" version = "0.4.1" @@ -1170,7 +1164,7 @@ name = "signature" version = "2.2.0-pre" dependencies = [ "digest 0.10.7", - "hex-literal 0.3.4", + "hex-literal", "rand_core 0.6.4", "sha2 0.10.8", "signature_derive", diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 193aa1108..655e3cf75 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -18,7 +18,7 @@ digest = { version = "0.10.6", optional = true, default-features = false } rand_core = { version = "0.6.4", optional = true, default-features = false } [dev-dependencies] -hex-literal = "0.3" +hex-literal = "0.4" sha2 = { version = "0.10", default-features = false } [features] From be7598fa15d5a64aef12290cef3cada5913d3896 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 12 Nov 2023 13:50:32 -0700 Subject: [PATCH 1076/1461] signature v2.2.0 (#1397) --- Cargo.lock | 2 +- signature/CHANGELOG.md | 10 ++++++++++ signature/Cargo.toml | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 970e15937..c426ea1b0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1161,7 +1161,7 @@ dependencies = [ [[package]] name = "signature" -version = "2.2.0-pre" +version = "2.2.0" dependencies = [ "digest 0.10.7", "hex-literal", diff --git a/signature/CHANGELOG.md b/signature/CHANGELOG.md index 4f999de55..3f9d8cd08 100644 --- a/signature/CHANGELOG.md +++ b/signature/CHANGELOG.md @@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 2.2.0 (2023-11-12) +### Changed +- MSRV 1.60 ([#1387]) + +### Fixed +- No longer vendoring async/derive crates unintentionally ([#1391]) + +[#1387]: https://github.com/RustCrypto/traits/pull/1387 +[#1391]: https://github.com/RustCrypto/traits/pull/1391 + ## 2.1.0 (2023-04-01) ### Added - `SignatureEncoding::encoded_len` ([#1283]) diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 655e3cf75..29353f6c4 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "2.2.0-pre" +version = "2.2.0" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/signature" From 7a0272d7aeffddebe3474b99551958606873664a Mon Sep 17 00:00:00 2001 From: Alex Martens Date: Sun, 12 Nov 2023 18:56:23 -0800 Subject: [PATCH 1077/1461] Bump `heapless` dependency to v0.8 (#1398) --- Cargo.lock | 72 +++---------------------------------------------- aead/Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 69 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c426ea1b0..ca3f2d640 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -73,21 +73,6 @@ dependencies = [ "syn", ] -[[package]] -name = "atomic-polyfill" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ff7eb3f316534d83a8a2c3d1674ace8a5a71198eba31e2e2b597833f699b28" -dependencies = [ - "critical-section", -] - -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - [[package]] name = "base16ct" version = "0.1.1" @@ -270,12 +255,6 @@ dependencies = [ "libc", ] -[[package]] -name = "critical-section" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216" - [[package]] name = "crypto" version = "0.5.1" @@ -628,23 +607,20 @@ dependencies = [ [[package]] name = "hash32" -version = "0.2.1" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" dependencies = [ "byteorder", ] [[package]] name = "heapless" -version = "0.7.16" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db04bc24a18b9ea980628ecf00e6c0264f3c1426dac36c00cb49b6fbad8b0743" +checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" dependencies = [ - "atomic-polyfill", "hash32", - "rustc_version", - "spin", "stable_deref_trait", ] @@ -786,16 +762,6 @@ version = "0.2.149" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" -[[package]] -name = "lock_api" -version = "0.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" -dependencies = [ - "autocfg", - "scopeguard", -] - [[package]] name = "opaque-debug" version = "0.3.0" @@ -1001,27 +967,12 @@ dependencies = [ "getrandom", ] -[[package]] -name = "rustc_version" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" -dependencies = [ - "semver", -] - [[package]] name = "ryu" version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - [[package]] name = "sec1" version = "0.3.0" @@ -1050,12 +1001,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "semver" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" - [[package]] name = "serde" version = "1.0.189" @@ -1179,15 +1124,6 @@ dependencies = [ "syn", ] -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" -dependencies = [ - "lock_api", -] - [[package]] name = "spki" version = "0.4.1" diff --git a/aead/Cargo.toml b/aead/Cargo.toml index dd424eb0c..75f112b52 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -22,7 +22,7 @@ crypto-common = "=0.2.0-pre" arrayvec = { version = "0.7", optional = true, default-features = false } blobby = { version = "0.3", optional = true } bytes = { version = "1", optional = true, default-features = false } -heapless = { version = "0.7", optional = true, default-features = false } +heapless = { version = "0.8", optional = true, default-features = false } [features] default = ["rand_core"] From d74348293e87903b9cf50428ae7d6137467d4ae4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Tue, 14 Nov 2023 16:36:56 +0300 Subject: [PATCH 1078/1461] Update Cargo.lock --- Cargo.lock | 61 +++++++++++++++++++++++------------------------------- 1 file changed, 26 insertions(+), 35 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ca3f2d640..c16d6ce47 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -59,7 +59,7 @@ name = "async-signature" version = "0.4.0" dependencies = [ "async-trait", - "signature 2.1.0", + "signature 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -175,11 +175,10 @@ checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "cc" -version = "1.0.83" +version = "1.0.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +checksum = "0f8e7c90afad890484a21653d08b6e209ae34770fb5ee298f9c699fcc1e5c856" dependencies = [ - "jobserver", "libc", ] @@ -248,9 +247,9 @@ checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" [[package]] name = "cpufeatures" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fbc60abd742b35f2492f808e1abbb83d45f72db402e14c55057edc9c7b1e9e4" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" dependencies = [ "libc", ] @@ -265,7 +264,7 @@ dependencies = [ "digest 0.10.7", "elliptic-curve 0.13.6", "password-hash", - "signature 2.1.0", + "signature 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "universal-hash 0.5.1", ] @@ -295,9 +294,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" +checksum = "28f85c3514d2a6e64160359b45a3918c3b4178bcbf4ae5d03ab2d02e521c479a" dependencies = [ "generic-array", "rand_core 0.6.4", @@ -477,7 +476,7 @@ version = "0.13.6" dependencies = [ "base16ct 0.2.0", "base64ct", - "crypto-bigint 0.5.3", + "crypto-bigint 0.5.4", "digest 0.10.7", "ff 0.13.0", "generic-array", @@ -547,9 +546,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" dependencies = [ "cfg-if", "libc", @@ -723,15 +722,6 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" -[[package]] -name = "jobserver" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" -dependencies = [ - "libc", -] - [[package]] name = "keccak" version = "0.1.4" @@ -758,9 +748,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.149" +version = "0.2.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" [[package]] name = "opaque-debug" @@ -1003,9 +993,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.189" +version = "1.0.192" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e422a44e74ad4001bdc8eede9a4570ab52f71190e9c076d14369f38b9200537" +checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001" dependencies = [ "serde_derive", ] @@ -1021,9 +1011,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.189" +version = "1.0.192" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" +checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1" dependencies = [ "proc-macro2", "quote", @@ -1097,22 +1087,23 @@ dependencies = [ [[package]] name = "signature" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +version = "2.2.0" dependencies = [ "digest 0.10.7", + "hex-literal", + "rand_core 0.6.4", + "sha2 0.10.8", + "signature_derive", ] [[package]] name = "signature" version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ "digest 0.10.7", - "hex-literal", "rand_core 0.6.4", - "sha2 0.10.8", - "signature_derive", ] [[package]] @@ -1157,9 +1148,9 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "syn" -version = "2.0.38" +version = "2.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" dependencies = [ "proc-macro2", "quote", From 2af0350bc87ca95679653e78db1e184fc4a99d81 Mon Sep 17 00:00:00 2001 From: Yehonatan Cohen Scaly Date: Wed, 15 Nov 2023 00:39:58 +0200 Subject: [PATCH 1079/1461] elliptic_curve: add `BatchInvert` and `BatchNormalize` traits (#1376) --- elliptic-curve/src/arithmetic.rs | 11 +++ elliptic-curve/src/lib.rs | 2 +- elliptic-curve/src/ops.rs | 120 +++++++++++++++++++++++++++++++ 3 files changed, 132 insertions(+), 1 deletion(-) diff --git a/elliptic-curve/src/arithmetic.rs b/elliptic-curve/src/arithmetic.rs index 7ef7fc53d..de9ff6b3c 100644 --- a/elliptic-curve/src/arithmetic.rs +++ b/elliptic-curve/src/arithmetic.rs @@ -84,3 +84,14 @@ pub trait PrimeCurveArithmetic: /// Prime order elliptic curve group. type CurveGroup: group::prime::PrimeCurve::AffinePoint>; } + +/// Normalize point(s) in projective representation by converting them to their affine ones. +pub trait BatchNormalize: group::Curve { + /// The output of the batch normalization; a container of affine points. + type Output: AsRef<[Self::AffineRepr]>; + + /// Perform a batched conversion to affine representation on a sequence of projective points + /// at an amortized cost that should be practically as efficient as a single conversion. + /// Internally, implementors should rely upon `InvertBatch`. + fn batch_normalize(points: Points) -> >::Output; +} diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index b0ad188de..389d9713d 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -127,7 +127,7 @@ pub use zeroize; #[cfg(feature = "arithmetic")] pub use { crate::{ - arithmetic::{CurveArithmetic, PrimeCurveArithmetic}, + arithmetic::{BatchNormalize, CurveArithmetic, PrimeCurveArithmetic}, point::{AffinePoint, ProjectivePoint}, public_key::PublicKey, scalar::{NonZeroScalar, Scalar}, diff --git a/elliptic-curve/src/ops.rs b/elliptic-curve/src/ops.rs index b7e9e3d46..5edddc4ee 100644 --- a/elliptic-curve/src/ops.rs +++ b/elliptic-curve/src/ops.rs @@ -4,6 +4,10 @@ pub use core::ops::{Add, AddAssign, Mul, Neg, Shr, ShrAssign, Sub, SubAssign}; use crypto_bigint::Integer; use group::Group; +use subtle::{Choice, ConditionallySelectable, CtOption}; + +#[cfg(feature = "alloc")] +use alloc::vec::Vec; /// Perform an inversion on a field element (i.e. base field element or scalar) pub trait Invert { @@ -25,6 +29,122 @@ pub trait Invert { } } +/// Perform a batched inversion on a sequence of field elements (i.e. base field elements or scalars) +/// at an amortized cost that should be practically as efficient as a single inversion. +pub trait BatchInvert: Invert { + /// The output of batch inversion. A container of field elements. + type Output; + + /// Invert a batch of field elements. + fn batch_invert(field_elements: FieldElements) -> >::Output; +} + +impl BatchInvert<&[T; N]> for T +where + T: Invert> + + Mul + + Copy + + Default + + ConditionallySelectable, +{ + type Output = CtOption<[Self; N]>; + + fn batch_invert(field_elements: &[Self; N]) -> >::Output { + let mut field_elements_multiples = [Self::default(); N]; + let mut field_elements_multiples_inverses = [Self::default(); N]; + let mut field_elements_inverses = [Self::default(); N]; + + let inversion_succeeded = invert_batch_internal( + field_elements, + &mut field_elements_multiples, + &mut field_elements_multiples_inverses, + &mut field_elements_inverses, + ); + + CtOption::new(field_elements_inverses, inversion_succeeded) + } +} + +#[cfg(feature = "alloc")] +impl BatchInvert<&[T]> for T +where + T: Invert> + + Mul + + Copy + + Default + + ConditionallySelectable, +{ + type Output = CtOption>; + + fn batch_invert(field_elements: &[Self]) -> >::Output { + let mut field_elements_multiples: Vec = vec![Self::default(); field_elements.len()]; + let mut field_elements_multiples_inverses: Vec = + vec![Self::default(); field_elements.len()]; + let mut field_elements_inverses: Vec = vec![Self::default(); field_elements.len()]; + + let inversion_succeeded = invert_batch_internal( + field_elements, + field_elements_multiples.as_mut(), + field_elements_multiples_inverses.as_mut(), + field_elements_inverses.as_mut(), + ); + + CtOption::new( + field_elements_inverses.into_iter().collect(), + inversion_succeeded, + ) + } +} + +/// Implements "Montgomery's trick", a trick for computing many modular inverses at once. +/// +/// "Montgomery's trick" works by reducing the problem of computing `n` inverses +/// to computing a single inversion, plus some storage and `O(n)` extra multiplications. +/// +/// See: https://iacr.org/archive/pkc2004/29470042/29470042.pdf section 2.2. +fn invert_batch_internal< + T: Invert> + Mul + Default + ConditionallySelectable, +>( + field_elements: &[T], + field_elements_multiples: &mut [T], + field_elements_multiples_inverses: &mut [T], + field_elements_inverses: &mut [T], +) -> Choice { + let batch_size = field_elements.len(); + if batch_size == 0 + || batch_size != field_elements_multiples.len() + || batch_size != field_elements_multiples_inverses.len() + { + return Choice::from(0); + } + + field_elements_multiples[0] = field_elements[0]; + for i in 1..batch_size { + // $ a_n = a_{n-1}*x_n $ + field_elements_multiples[i] = field_elements_multiples[i - 1] * field_elements[i]; + } + + field_elements_multiples[batch_size - 1] + .invert() + .map(|multiple_of_inverses_of_all_field_elements| { + field_elements_multiples_inverses[batch_size - 1] = + multiple_of_inverses_of_all_field_elements; + for i in (1..batch_size).rev() { + // $ a_{n-1} = {a_n}^{-1}*x_n $ + field_elements_multiples_inverses[i - 1] = + field_elements_multiples_inverses[i] * field_elements[i]; + } + + field_elements_inverses[0] = field_elements_multiples_inverses[0]; + for i in 1..batch_size { + // $ {x_n}^{-1} = a_{n}^{-1}*a_{n-1} $ + field_elements_inverses[i] = + field_elements_multiples_inverses[i] * field_elements_multiples[i - 1]; + } + }) + .is_some() +} + /// Linear combination. /// /// This trait enables crates to provide an optimized implementation of From 4a663341473273c73fd2ca7e37dadd9ba7013fd2 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 14 Nov 2023 17:51:52 -0700 Subject: [PATCH 1080/1461] elliptic-curve: remove references from batch generic params (#1403) Previously the traits were generic around a reference type. The problem with that is reference types have lifetimes, which requires notating them in generic code, in this case requiring an HRTB per generic parameter. HRTBs work because the output has no lifetime dependencies on the input, but if that's the case we can just explicitly borrow in the trait, which means no HRTB is needed in generic code, which makes notating the trait bounds significantly simpler. --- elliptic-curve/src/arithmetic.rs | 4 ++-- elliptic-curve/src/ops.rs | 20 +++++++++++--------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/elliptic-curve/src/arithmetic.rs b/elliptic-curve/src/arithmetic.rs index de9ff6b3c..2c6b55abb 100644 --- a/elliptic-curve/src/arithmetic.rs +++ b/elliptic-curve/src/arithmetic.rs @@ -86,12 +86,12 @@ pub trait PrimeCurveArithmetic: } /// Normalize point(s) in projective representation by converting them to their affine ones. -pub trait BatchNormalize: group::Curve { +pub trait BatchNormalize: group::Curve { /// The output of the batch normalization; a container of affine points. type Output: AsRef<[Self::AffineRepr]>; /// Perform a batched conversion to affine representation on a sequence of projective points /// at an amortized cost that should be practically as efficient as a single conversion. /// Internally, implementors should rely upon `InvertBatch`. - fn batch_normalize(points: Points) -> >::Output; + fn batch_normalize(points: &Points) -> >::Output; } diff --git a/elliptic-curve/src/ops.rs b/elliptic-curve/src/ops.rs index 5edddc4ee..57280f187 100644 --- a/elliptic-curve/src/ops.rs +++ b/elliptic-curve/src/ops.rs @@ -31,15 +31,17 @@ pub trait Invert { /// Perform a batched inversion on a sequence of field elements (i.e. base field elements or scalars) /// at an amortized cost that should be practically as efficient as a single inversion. -pub trait BatchInvert: Invert { +pub trait BatchInvert: Invert + Sized { /// The output of batch inversion. A container of field elements. - type Output; + type Output: AsRef<[Self]>; /// Invert a batch of field elements. - fn batch_invert(field_elements: FieldElements) -> >::Output; + fn batch_invert( + field_elements: &FieldElements, + ) -> CtOption<>::Output>; } -impl BatchInvert<&[T; N]> for T +impl BatchInvert<[T; N]> for T where T: Invert> + Mul @@ -47,9 +49,9 @@ where + Default + ConditionallySelectable, { - type Output = CtOption<[Self; N]>; + type Output = [Self; N]; - fn batch_invert(field_elements: &[Self; N]) -> >::Output { + fn batch_invert(field_elements: &[Self; N]) -> CtOption<[Self; N]> { let mut field_elements_multiples = [Self::default(); N]; let mut field_elements_multiples_inverses = [Self::default(); N]; let mut field_elements_inverses = [Self::default(); N]; @@ -66,7 +68,7 @@ where } #[cfg(feature = "alloc")] -impl BatchInvert<&[T]> for T +impl BatchInvert<[T]> for T where T: Invert> + Mul @@ -74,9 +76,9 @@ where + Default + ConditionallySelectable, { - type Output = CtOption>; + type Output = Vec; - fn batch_invert(field_elements: &[Self]) -> >::Output { + fn batch_invert(field_elements: &[Self]) -> CtOption> { let mut field_elements_multiples: Vec = vec![Self::default(); field_elements.len()]; let mut field_elements_multiples_inverses: Vec = vec![Self::default(); field_elements.len()]; From ce2dc02121e28ebda185e6f18e56cf7906ae4006 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 14 Nov 2023 19:46:16 -0700 Subject: [PATCH 1081/1461] elliptic-curve: move `BatchNormalize` trait under `point` (#1404) Since it's functionality related to elliptic curve points, put it under the corresponding module. --- elliptic-curve/src/arithmetic.rs | 11 ----------- elliptic-curve/src/lib.rs | 4 ++-- elliptic-curve/src/point.rs | 12 ++++++++++++ 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/elliptic-curve/src/arithmetic.rs b/elliptic-curve/src/arithmetic.rs index 2c6b55abb..7ef7fc53d 100644 --- a/elliptic-curve/src/arithmetic.rs +++ b/elliptic-curve/src/arithmetic.rs @@ -84,14 +84,3 @@ pub trait PrimeCurveArithmetic: /// Prime order elliptic curve group. type CurveGroup: group::prime::PrimeCurve::AffinePoint>; } - -/// Normalize point(s) in projective representation by converting them to their affine ones. -pub trait BatchNormalize: group::Curve { - /// The output of the batch normalization; a container of affine points. - type Output: AsRef<[Self::AffineRepr]>; - - /// Perform a batched conversion to affine representation on a sequence of projective points - /// at an amortized cost that should be practically as efficient as a single conversion. - /// Internally, implementors should rely upon `InvertBatch`. - fn batch_normalize(points: &Points) -> >::Output; -} diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 389d9713d..f387d2896 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -127,8 +127,8 @@ pub use zeroize; #[cfg(feature = "arithmetic")] pub use { crate::{ - arithmetic::{BatchNormalize, CurveArithmetic, PrimeCurveArithmetic}, - point::{AffinePoint, ProjectivePoint}, + arithmetic::{CurveArithmetic, PrimeCurveArithmetic}, + point::{AffinePoint, BatchNormalize, ProjectivePoint}, public_key::PublicKey, scalar::{NonZeroScalar, Scalar}, }, diff --git a/elliptic-curve/src/point.rs b/elliptic-curve/src/point.rs index 25b872a0e..ee4eded44 100644 --- a/elliptic-curve/src/point.rs +++ b/elliptic-curve/src/point.rs @@ -32,6 +32,18 @@ pub trait AffineCoordinates { fn y_is_odd(&self) -> Choice; } +/// Normalize point(s) in projective representation by converting them to their affine ones. +#[cfg(feature = "arithmetic")] +pub trait BatchNormalize: group::Curve { + /// The output of the batch normalization; a container of affine points. + type Output: AsRef<[Self::AffineRepr]>; + + /// Perform a batched conversion to affine representation on a sequence of projective points + /// at an amortized cost that should be practically as efficient as a single conversion. + /// Internally, implementors should rely upon `InvertBatch`. + fn batch_normalize(points: &Points) -> >::Output; +} + /// Double a point (i.e. add it to itself) pub trait Double { /// Double this point. From 37507fd8a1314398f9e0d7bbdf25467071b2c72e Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 15 Nov 2023 06:21:29 -0700 Subject: [PATCH 1082/1461] elliptic-curve: add `LinearCombinationExt` trait (#1405) Adds a trait which is generic around its input parameters for computing linear combinations. This allows for different strategies depending on the input parameter type, for example using stack-allocated intermediates sized to match an input array, which works on `no_std` targets. Or, if a slice is passed, intermediate `Vec`s can be used when the `alloc` feature is available. Also adds a blanket impl for the old `LinearCombination` trait which calls the new trait. --- elliptic-curve/src/ops.rs | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/elliptic-curve/src/ops.rs b/elliptic-curve/src/ops.rs index 57280f187..5931d59fa 100644 --- a/elliptic-curve/src/ops.rs +++ b/elliptic-curve/src/ops.rs @@ -160,6 +160,34 @@ pub trait LinearCombination: Group { } } +/// Linear combination (extended version). +/// +/// This trait enables providing an optimized implementation of +/// linear combinations (e.g. Shamir's Trick). +// TODO(tarcieri): replace the current `LinearCombination` with this in the next release +pub trait LinearCombinationExt: group::Curve +where + PointsAndScalars: AsRef<[(Self, Self::Scalar)]>, +{ + /// Calculates `x1 * k1 + ... + xn * kn`. + fn lincomb_ext(points_and_scalars: &PointsAndScalars) -> Self { + points_and_scalars + .as_ref() + .iter() + .copied() + .map(|(point, scalar)| point * scalar) + .sum() + } +} + +/// Blanket impl of the legacy [`LinearCombination`] trait for types which impl the new +/// [`LinearCombinationExt`] trait for 2-element arrays. +impl> LinearCombination for P { + fn lincomb(x: &Self, k: &Self::Scalar, y: &Self, l: &Self::Scalar) -> Self { + Self::lincomb_ext(&[(*x, *k), (*y, *l)]) + } +} + /// Multiplication by the generator. /// /// May use optimizations (e.g. precomputed tables) when available. From 723a1a309c4d987ec54c4c1f7bfe3686dc8d5a29 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 15 Nov 2023 09:42:41 -0700 Subject: [PATCH 1083/1461] elliptic-curve: have `LinearCombinationExt` allow `?Sized` (#1406) ...as the `PointsAndScalars` generic parameter, so we can accept slices --- elliptic-curve/src/ops.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elliptic-curve/src/ops.rs b/elliptic-curve/src/ops.rs index 5931d59fa..9043b29c7 100644 --- a/elliptic-curve/src/ops.rs +++ b/elliptic-curve/src/ops.rs @@ -167,7 +167,7 @@ pub trait LinearCombination: Group { // TODO(tarcieri): replace the current `LinearCombination` with this in the next release pub trait LinearCombinationExt: group::Curve where - PointsAndScalars: AsRef<[(Self, Self::Scalar)]>, + PointsAndScalars: AsRef<[(Self, Self::Scalar)]> + ?Sized, { /// Calculates `x1 * k1 + ... + xn * kn`. fn lincomb_ext(points_and_scalars: &PointsAndScalars) -> Self { From 38e898b1b975b0d155348fd44aa968b83174aa97 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Wed, 15 Nov 2023 21:07:46 +0300 Subject: [PATCH 1084/1461] Fix `missing_debug_implementations` for some crates (#1407) --- async-signature/src/lib.rs | 7 ++++++- cipher/src/lib.rs | 7 ++++++- crypto-common/src/lib.rs | 2 +- crypto/src/lib.rs | 2 +- digest/src/core_api/ct_variable.rs | 11 +++++++++++ digest/src/lib.rs | 2 +- digest/src/mac.rs | 6 ++++++ kem/src/kem.rs | 10 ++++++++-- kem/src/lib.rs | 2 +- password-hash/src/lib.rs | 7 ++++++- password-hash/src/params.rs | 1 + signature/src/lib.rs | 1 + signature_derive/src/lib.rs | 1 + universal-hash/src/lib.rs | 2 +- 14 files changed, 51 insertions(+), 10 deletions(-) diff --git a/async-signature/src/lib.rs b/async-signature/src/lib.rs index fde8ca241..8c59952ca 100644 --- a/async-signature/src/lib.rs +++ b/async-signature/src/lib.rs @@ -5,7 +5,12 @@ )] #![cfg_attr(docsrs, feature(doc_auto_cfg))] #![forbid(unsafe_code)] -#![warn(missing_docs, rust_2018_idioms, unused_qualifications)] +#![warn( + missing_docs, + rust_2018_idioms, + unused_qualifications, + missing_debug_implementations +)] pub use signature::{self, Error}; diff --git a/cipher/src/lib.rs b/cipher/src/lib.rs index 7554690ea..ba485aa5a 100644 --- a/cipher/src/lib.rs +++ b/cipher/src/lib.rs @@ -11,7 +11,12 @@ html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg" )] -#![warn(missing_docs, rust_2018_idioms, unused_lifetimes)] +#![warn( + missing_docs, + rust_2018_idioms, + unused_lifetimes, + missing_debug_implementations +)] pub use crypto_common; pub use inout; diff --git a/crypto-common/src/lib.rs b/crypto-common/src/lib.rs index 247746a64..2c2cb8dc9 100644 --- a/crypto-common/src/lib.rs +++ b/crypto-common/src/lib.rs @@ -7,7 +7,7 @@ html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg" )] #![forbid(unsafe_code)] -#![warn(missing_docs, rust_2018_idioms)] +#![warn(missing_docs, rust_2018_idioms, missing_debug_implementations)] #[cfg(feature = "std")] extern crate std; diff --git a/crypto/src/lib.rs b/crypto/src/lib.rs index c28db6fce..3839e2fc8 100644 --- a/crypto/src/lib.rs +++ b/crypto/src/lib.rs @@ -6,7 +6,7 @@ html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg" )] #![forbid(unsafe_code)] -#![warn(rust_2018_idioms)] +#![warn(rust_2018_idioms, missing_debug_implementations)] pub use crypto_common as common; diff --git a/digest/src/core_api/ct_variable.rs b/digest/src/core_api/ct_variable.rs index b93e7ea77..20df390e7 100644 --- a/digest/src/core_api/ct_variable.rs +++ b/digest/src/core_api/ct_variable.rs @@ -162,6 +162,17 @@ where const OID: ObjectIdentifier = O::OID; } +impl fmt::Debug for CtVariableCoreWrapper +where + T: VariableOutputCore + AlgorithmName, + OutSize: ArraySize + IsLessOrEqual, + LeEq: NonZero, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + Self::write_alg_name(f) + } +} + /// Implement dummy type with hidden docs which is used to "carry" hasher /// OID for [`CtVariableCoreWrapper`]. #[macro_export] diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 1bb0d5325..5f9f56f71 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -29,7 +29,7 @@ html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg" )] -#![warn(missing_docs, rust_2018_idioms)] +#![warn(missing_docs, rust_2018_idioms, missing_debug_implementations)] #[cfg(feature = "alloc")] #[macro_use] diff --git a/digest/src/mac.rs b/digest/src/mac.rs index f39e9e32a..25c0c550d 100644 --- a/digest/src/mac.rs +++ b/digest/src/mac.rs @@ -241,6 +241,12 @@ impl PartialEq for CtOutput { impl Eq for CtOutput {} +impl fmt::Debug for CtOutput { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("CtOutput { ... }") + } +} + /// Error type for when the [`Output`] of a [`Mac`] /// is not equal to the expected value. #[derive(Default, Debug, Copy, Clone, Eq, PartialEq)] diff --git a/kem/src/kem.rs b/kem/src/kem.rs index 4e7853672..1963883ef 100644 --- a/kem/src/kem.rs +++ b/kem/src/kem.rs @@ -2,7 +2,7 @@ use crate::errors::Error; -use core::fmt::Debug; +use core::fmt; use generic_array::{ArrayLength, GenericArray}; use rand_core::{CryptoRng, RngCore}; @@ -10,7 +10,7 @@ use zeroize::{Zeroize, ZeroizeOnDrop}; /// Trait impl'd by concrete types that represent an encapsulated key. This is intended to be, in /// essence, a bag of bytes. -pub trait EncappedKey: AsRef<[u8]> + Debug + Sized { +pub trait EncappedKey: AsRef<[u8]> + fmt::Debug + Sized { /// The size, in bytes, of an encapsulated key. type EncappedKeySize: ArrayLength; @@ -38,6 +38,12 @@ pub trait EncappedKey: AsRef<[u8]> + Debug + Sized { /// The shared secret that results from key exchange. pub struct SharedSecret(GenericArray); +impl fmt::Debug for SharedSecret { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("SharedSecret { ... }") + } +} + // Zero the secret on drop impl Drop for SharedSecret { fn drop(&mut self) { diff --git a/kem/src/lib.rs b/kem/src/lib.rs index 5230bc663..7faf1d05c 100644 --- a/kem/src/lib.rs +++ b/kem/src/lib.rs @@ -7,7 +7,7 @@ html_root_url = "https://docs.rs/kem" )] #![forbid(unsafe_code)] -#![warn(missing_docs, unused_qualifications)] +#![warn(missing_docs, unused_qualifications, missing_debug_implementations)] #[cfg(feature = "std")] extern crate std; diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index 4ba94a099..8b8f62ba1 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -6,7 +6,12 @@ html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg" )] #![forbid(unsafe_code)] -#![warn(missing_docs, rust_2018_idioms, unused_lifetimes)] +#![warn( + missing_docs, + rust_2018_idioms, + unused_lifetimes, + missing_debug_implementations +)] //! //! # Usage diff --git a/password-hash/src/params.rs b/password-hash/src/params.rs index 68648777e..c9d89caee 100644 --- a/password-hash/src/params.rs +++ b/password-hash/src/params.rs @@ -239,6 +239,7 @@ impl fmt::Debug for ParamsString { } /// Iterator over algorithm parameters stored in a [`ParamsString`] struct. +#[derive(Debug)] pub struct Iter<'a> { inner: Option>, } diff --git a/signature/src/lib.rs b/signature/src/lib.rs index c90f5cc8a..902499fe8 100644 --- a/signature/src/lib.rs +++ b/signature/src/lib.rs @@ -12,6 +12,7 @@ missing_docs, rust_2018_idioms, unused_lifetimes, + missing_debug_implementations, unused_qualifications )] diff --git a/signature_derive/src/lib.rs b/signature_derive/src/lib.rs index 1afb0aaa2..14930789b 100644 --- a/signature_derive/src/lib.rs +++ b/signature_derive/src/lib.rs @@ -6,6 +6,7 @@ rust_2018_idioms, trivial_casts, unused_import_braces, + missing_debug_implementations, unused_qualifications )] diff --git a/universal-hash/src/lib.rs b/universal-hash/src/lib.rs index 5fef8a6b4..0cfa03a5a 100644 --- a/universal-hash/src/lib.rs +++ b/universal-hash/src/lib.rs @@ -6,7 +6,7 @@ html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg" )] #![forbid(unsafe_code)] -#![warn(missing_docs, rust_2018_idioms)] +#![warn(missing_docs, rust_2018_idioms, missing_debug_implementations)] #[cfg(feature = "std")] extern crate std; From cc4ffe9d67f13eba9d3f6eb91925f1e7671dc2d3 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 15 Nov 2023 14:57:45 -0700 Subject: [PATCH 1085/1461] elliptic-curve v0.13.7 (#1408) --- Cargo.lock | 4 ++-- elliptic-curve/CHANGELOG.md | 8 ++++++++ elliptic-curve/Cargo.toml | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c16d6ce47..2bde6aedd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -262,7 +262,7 @@ dependencies = [ "cipher 0.4.4", "crypto-common 0.1.6", "digest 0.10.7", - "elliptic-curve 0.13.6", + "elliptic-curve 0.13.7", "password-hash", "signature 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "universal-hash 0.5.1", @@ -472,7 +472,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.13.6" +version = "0.13.7" dependencies = [ "base16ct 0.2.0", "base64ct", diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index 1e5a5529e..e95a04fc6 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.13.7 (2023-11-15) +### Added +- `BatchInvert` and `BatchNormalize` traits ([#1376]) +- `LinearCombinationExt` trait ([#1405]) + +[#1376]: https://github.com/RustCrypto/traits/pull/1376 +[#1405]: https://github.com/RustCrypto/traits/pull/1405 + ## 0.13.6 (2023-10-02) ### Fixed - Minimum supported `hkdf` version is v0.12.1 ([#1353]) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index c6cc181fa..924ca39c8 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.13.6" +version = "0.13.7" description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, From 43d620d92bbe7d583c97c7c89153067dfa2de84b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Nov 2023 17:00:52 -0700 Subject: [PATCH 1086/1461] build(deps): bump zeroize from 1.6.0 to 1.7.0 (#1410) Bumps [zeroize](https://github.com/RustCrypto/utils) from 1.6.0 to 1.7.0. - [Commits](https://github.com/RustCrypto/utils/commits) --- updated-dependencies: - dependency-name: zeroize dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- cipher/Cargo.toml | 2 +- elliptic-curve/Cargo.toml | 2 +- kem/Cargo.toml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2bde6aedd..27d5f005f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1245,9 +1245,9 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" dependencies = [ "zeroize_derive", ] diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index 60e9426f0..1fb08c1e3 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -18,7 +18,7 @@ inout = "=0.2.0-pre" # optional dependencies blobby = { version = "0.3", optional = true } -zeroize = { version = "1.6", optional = true, default-features = false } +zeroize = { version = "1.7", optional = true, default-features = false } [features] alloc = [] diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 924ca39c8..becaab7a8 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -21,7 +21,7 @@ crypto-bigint = { version = "0.5", default-features = false, features = ["rand_c generic-array = { version = "0.14.6", default-features = false, features = ["zeroize"] } rand_core = { version = "0.6.4", default-features = false } subtle = { version = "2", default-features = false } -zeroize = { version = "1.5", default-features = false } +zeroize = { version = "1.7", default-features = false } # optional dependencies base64ct = { version = "1", optional = true, default-features = false, features = ["alloc"] } diff --git a/kem/Cargo.toml b/kem/Cargo.toml index 78a074619..5b8dece78 100644 --- a/kem/Cargo.toml +++ b/kem/Cargo.toml @@ -15,7 +15,7 @@ rust-version = "1.60" [dependencies] rand_core = "0.6" generic-array = "0.14" -zeroize = { version = "1.6", default-features = false } +zeroize = { version = "1.7", default-features = false } [dev-dependencies] hpke = "0.10" From 20ae48b8577286a3b1d6e501c342801492400c2d Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Fri, 17 Nov 2023 19:43:07 +0300 Subject: [PATCH 1087/1461] aead: enable `missing_debug_implementations` lint and add `Debug` impls (#1411) --- aead/src/lib.rs | 8 +++++++- aead/src/stream.rs | 3 +++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/aead/src/lib.rs b/aead/src/lib.rs index 62cf29dbb..0a6f2aff1 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -6,7 +6,12 @@ html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg" )] #![forbid(unsafe_code)] -#![warn(clippy::unwrap_used, missing_docs, rust_2018_idioms)] +#![warn( + clippy::unwrap_used, + missing_docs, + rust_2018_idioms, + missing_debug_implementations +)] #[cfg(feature = "alloc")] extern crate alloc; @@ -472,6 +477,7 @@ impl AeadMutInPlace for Alg { /// If you don't care about AAD, you can pass a `&[u8]` as the payload to /// `encrypt`/`decrypt` and it will automatically be coerced to this type. #[cfg(feature = "alloc")] +#[derive(Debug)] pub struct Payload<'msg, 'aad> { /// Message to be encrypted/decrypted pub msg: &'msg [u8], diff --git a/aead/src/stream.rs b/aead/src/stream.rs index 13aa593ef..cbed91a6f 100644 --- a/aead/src/stream.rs +++ b/aead/src/stream.rs @@ -199,6 +199,7 @@ macro_rules! impl_stream_object { #[doc = "[Online Authenticated-Encryption and its Nonce-Reuse Misuse-Resistance][1]."] #[doc = ""] #[doc = "[1]: https://eprint.iacr.org/2015/189.pdf"] + #[derive(Debug)] pub struct $name where A: AeadInPlace, @@ -361,6 +362,7 @@ impl_stream_object!( /// the last 5-bytes of the AEAD nonce. /// /// [1]: https://eprint.iacr.org/2015/189.pdf +#[derive(Debug)] pub struct StreamBE32 where A: AeadInPlace, @@ -450,6 +452,7 @@ where /// when interpreted as a 32-bit integer. /// /// The 31-bit + 1-bit value is stored as the last 4 bytes of the AEAD nonce. +#[derive(Debug)] pub struct StreamLE31 where A: AeadInPlace, From dcae306c068ab2e43d4c3d70ca9cb0ba2cb3cb90 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 18 Nov 2023 11:59:56 -0700 Subject: [PATCH 1088/1461] elliptic-curve: `SecretKey::from_slice` allows >=24-bytes (#1412) To address the concerns in #1330, sets a global minimum elliptic curve key size of 24-bytes (192-bits), which provides the equivalent of 96-bit symmetric security. --- elliptic-curve/src/secret_key.rs | 39 ++++++++++++------------------ elliptic-curve/tests/secret_key.rs | 6 ++--- 2 files changed, 19 insertions(+), 26 deletions(-) diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 502f8153b..198fd66e0 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -12,7 +12,7 @@ use crate::{Curve, Error, FieldBytes, Result, ScalarPrimitive}; use core::fmt::{self, Debug}; use generic_array::typenum::Unsigned; use subtle::{Choice, ConstantTimeEq}; -use zeroize::{Zeroize, ZeroizeOnDrop}; +use zeroize::{Zeroize, ZeroizeOnDrop, Zeroizing}; #[cfg(feature = "arithmetic")] use crate::{rand_core::CryptoRngCore, CurveArithmetic, NonZeroScalar, PublicKey}; @@ -40,7 +40,6 @@ use { }, alloc::vec::Vec, sec1::der::Encode, - zeroize::Zeroizing, }; #[cfg(all(feature = "arithmetic", any(feature = "jwk", feature = "pem")))] @@ -85,6 +84,11 @@ impl SecretKey where C: Curve, { + /// Minimum allowed size of an elliptic curve secret key in bytes. + /// + /// This provides the equivalent of 96-bits of symmetric security. + const MIN_SIZE: usize = 24; + /// Generate a random [`SecretKey`]. #[cfg(feature = "arithmetic")] pub fn random(rng: &mut impl CryptoRngCore) -> Self @@ -148,31 +152,20 @@ where Ok(Self { inner }) } - /// Deserialize secret key from an encoded secret scalar passed as a - /// byte slice. + /// Deserialize secret key from an encoded secret scalar passed as a byte slice. + /// + /// The slice is expected to be a minimum of 24-bytes (192-byts) and at most `C::FieldBytesSize` + /// bytes in length. /// - /// The slice is expected to be at most `C::FieldBytesSize` bytes in - /// length but may be up to 4-bytes shorter than that, which is handled by - /// zero-padding the value. + /// Byte slices shorter than the field size are handled by zero padding the input. pub fn from_slice(slice: &[u8]) -> Result { - if slice.len() > C::FieldBytesSize::USIZE { - return Err(Error); - } - - /// Maximum number of "missing" bytes to interpret as zeroes. - const MAX_LEADING_ZEROES: usize = 4; - - let offset = C::FieldBytesSize::USIZE.saturating_sub(slice.len()); - - if offset == 0 { + if slice.len() == C::FieldBytesSize::USIZE { Self::from_bytes(FieldBytes::::from_slice(slice)) - } else if offset <= MAX_LEADING_ZEROES { - let mut bytes = FieldBytes::::default(); + } else if (Self::MIN_SIZE..C::FieldBytesSize::USIZE).contains(&slice.len()) { + let mut bytes = Zeroizing::new(FieldBytes::::default()); + let offset = C::FieldBytesSize::USIZE.saturating_sub(slice.len()); bytes[offset..].copy_from_slice(slice); - - let ret = Self::from_bytes(&bytes); - bytes.zeroize(); - ret + Self::from_bytes(&bytes) } else { Err(Error) } diff --git a/elliptic-curve/tests/secret_key.rs b/elliptic-curve/tests/secret_key.rs index a01de9067..7be475143 100644 --- a/elliptic-curve/tests/secret_key.rs +++ b/elliptic-curve/tests/secret_key.rs @@ -5,7 +5,7 @@ use elliptic_curve::dev::SecretKey; #[test] -fn from_slice_undersize() { +fn from_empty_slice() { assert!(SecretKey::from_slice(&[]).is_err()); } @@ -17,12 +17,12 @@ fn from_slice_expected_size() { #[test] fn from_slice_allowed_short() { - let bytes = [1u8; 28]; + let bytes = [1u8; 24]; assert!(SecretKey::from_slice(&bytes).is_ok()); } #[test] fn from_slice_too_short() { - let bytes = [1u8; 27]; + let bytes = [1u8; 23]; // min 24-bytes assert!(SecretKey::from_slice(&bytes).is_err()); } From 9fbd4f902fad4c5381b888e8938f52f3e1d41caa Mon Sep 17 00:00:00 2001 From: Ruslan Piasetskyi Date: Sat, 18 Nov 2023 20:01:48 +0100 Subject: [PATCH 1089/1461] crypto-common: add SerializableState trait (#1369) This trait is used for saving the internal state of the object and restoring the object from the serialized state. --- crypto-common/src/lib.rs | 17 +- crypto-common/src/serializable_state.rs | 351 ++++++++++++++++++++++++ digest/src/core_api/ct_variable.rs | 53 +++- digest/src/core_api/rt_variable.rs | 78 +++++- digest/src/core_api/wrapper.rs | 55 +++- digest/src/dev.rs | 71 +++++ 6 files changed, 615 insertions(+), 10 deletions(-) create mode 100644 crypto-common/src/serializable_state.rs diff --git a/crypto-common/src/lib.rs b/crypto-common/src/lib.rs index 2c2cb8dc9..6a9c9a4c6 100644 --- a/crypto-common/src/lib.rs +++ b/crypto-common/src/lib.rs @@ -21,11 +21,20 @@ pub use hybrid_array as array; pub use hybrid_array::typenum; use core::fmt; -use hybrid_array::{typenum::Unsigned, Array, ArraySize, ByteArray}; +use hybrid_array::{ + typenum::{Diff, Sum, Unsigned}, + Array, ArraySize, ByteArray, +}; #[cfg(feature = "rand_core")] use rand_core::CryptoRngCore; +mod serializable_state; +pub use serializable_state::{ + AddSerializedStateSize, DeserializeStateError, SerializableState, SerializedState, + SubSerializedStateSize, +}; + /// Block on which [`BlockSizeUser`] implementors operate. pub type Block = ByteArray<::BlockSize>; @@ -41,6 +50,12 @@ pub type Key = ByteArray<::KeySize>; /// Initialization vector (nonce) used by [`IvSizeUser`] implementors. pub type Iv = ByteArray<::IvSize>; +/// Alias for `AddBlockSize = Sum` +pub type AddBlockSize = Sum::BlockSize>; + +/// Alias for `SubBlockSize = Diff` +pub type SubBlockSize = Diff::BlockSize>; + /// Types which process data in blocks. pub trait BlockSizeUser { /// Size of the block in bytes. diff --git a/crypto-common/src/serializable_state.rs b/crypto-common/src/serializable_state.rs new file mode 100644 index 000000000..fa72d13c8 --- /dev/null +++ b/crypto-common/src/serializable_state.rs @@ -0,0 +1,351 @@ +use crate::array::{ + self, + typenum::{Diff, Prod, Sum, Unsigned, U1, U16, U2, U4, U8}, + ArraySize, ByteArray, +}; +use core::{convert::TryInto, default::Default, fmt}; + +/// Serialized internal state. +pub type SerializedState = ByteArray<::SerializedStateSize>; + +/// Alias for `AddSerializedStateSize = Sum` +pub type AddSerializedStateSize = Sum::SerializedStateSize>; + +/// Alias for `SubSerializedStateSize = Diff` +pub type SubSerializedStateSize = Diff::SerializedStateSize>; + +/// The error type returned when an object cannot be deserialized from the state. +#[derive(Copy, Clone, Eq, PartialEq, Debug)] +pub struct DeserializeStateError; + +impl fmt::Display for DeserializeStateError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + f.write_str("Deserialization error") + } +} + +#[cfg(feature = "std")] +impl std::error::Error for DeserializeStateError {} + +/// Types which can serialize the internal state and be restored from it. +/// +/// # SECURITY WARNING +/// +/// Serialized state may contain sensitive data. +pub trait SerializableState +where + Self: Sized, +{ + /// Size of serialized internal state. + type SerializedStateSize: ArraySize; + + /// Serialize and return internal state. + fn serialize(&self) -> SerializedState; + /// Create an object from serialized internal state. + fn deserialize(serialized_state: &SerializedState) + -> Result; +} + +macro_rules! impl_seializable_state_unsigned { + ($type: ty, $type_size: ty) => { + impl SerializableState for $type { + type SerializedStateSize = $type_size; + + fn serialize(&self) -> SerializedState { + self.to_le_bytes().into() + } + + fn deserialize( + serialized_state: &SerializedState, + ) -> Result { + Ok(<$type>::from_le_bytes((*serialized_state).into())) + } + } + }; +} + +impl_seializable_state_unsigned!(u8, U1); +impl_seializable_state_unsigned!(u16, U2); +impl_seializable_state_unsigned!(u32, U4); +impl_seializable_state_unsigned!(u64, U8); +impl_seializable_state_unsigned!(u128, U16); + +macro_rules! impl_serializable_state_u8_array { + ($($n: ty),*) => { + $( + impl SerializableState for [u8; <$n>::USIZE] { + type SerializedStateSize = $n; + + fn serialize(&self) -> SerializedState { + (*self).into() + } + + fn deserialize( + serialized_state: &SerializedState, + ) -> Result { + Ok((*serialized_state).into()) + } + } + )* + }; +} + +macro_rules! impl_serializable_state_type_array { + ($type: ty, $type_size: ty, $n: ty) => { + impl SerializableState for [$type; <$n>::USIZE] { + type SerializedStateSize = Prod<$n, $type_size>; + + fn serialize(&self) -> SerializedState { + let mut serialized_state = SerializedState::::default(); + for (val, chunk) in self + .iter() + .zip(serialized_state.chunks_exact_mut(<$type_size>::USIZE)) + { + chunk.copy_from_slice(&val.to_le_bytes()); + } + + serialized_state + } + + fn deserialize( + serialized_state: &SerializedState, + ) -> Result { + let mut array = [0; <$n>::USIZE]; + for (val, chunk) in array + .iter_mut() + .zip(serialized_state.chunks_exact(<$type_size>::USIZE)) + { + *val = <$type>::from_le_bytes(chunk.try_into().unwrap()); + } + Ok(array) + } + } + }; +} + +macro_rules! impl_serializable_state_u16_array { + ($($n: ty),*) => { + $( + impl_serializable_state_type_array!(u16, U2, $n); + )* + }; +} + +macro_rules! impl_serializable_state_u32_array { + ($($n: ty),*) => { + $( + impl_serializable_state_type_array!(u32, U4, $n); + )* + }; +} + +macro_rules! impl_serializable_state_u64_array { + ($($n: ty),*) => { + $( + impl_serializable_state_type_array!(u64, U8, $n); + )* + }; +} + +macro_rules! impl_serializable_state_u128_array { + ($($n: ty),*) => { + $( + impl_serializable_state_type_array!(u128, U8, $n); + )* + }; +} + +impl_serializable_state_u8_array! { + array::typenum::U1, + array::typenum::U2, + array::typenum::U3, + array::typenum::U4, + array::typenum::U5, + array::typenum::U6, + array::typenum::U7, + array::typenum::U8, + array::typenum::U9, + array::typenum::U10, + array::typenum::U11, + array::typenum::U12, + array::typenum::U13, + array::typenum::U14, + array::typenum::U15, + array::typenum::U16, + array::typenum::U17, + array::typenum::U18, + array::typenum::U19, + array::typenum::U20, + array::typenum::U21, + array::typenum::U22, + array::typenum::U23, + array::typenum::U24, + array::typenum::U25, + array::typenum::U26, + array::typenum::U27, + array::typenum::U28, + array::typenum::U29, + array::typenum::U30, + array::typenum::U31, + array::typenum::U32, + array::typenum::U33, + array::typenum::U34, + array::typenum::U35, + array::typenum::U36, + array::typenum::U37, + array::typenum::U38, + array::typenum::U39, + array::typenum::U40, + array::typenum::U41, + array::typenum::U42, + array::typenum::U43, + array::typenum::U44, + array::typenum::U45, + array::typenum::U46, + array::typenum::U47, + array::typenum::U48, + array::typenum::U49, + array::typenum::U50, + array::typenum::U51, + array::typenum::U52, + array::typenum::U53, + array::typenum::U54, + array::typenum::U55, + array::typenum::U56, + array::typenum::U57, + array::typenum::U58, + array::typenum::U59, + array::typenum::U60, + array::typenum::U61, + array::typenum::U62, + array::typenum::U63, + array::typenum::U64, + array::typenum::U96, + array::typenum::U128, + array::typenum::U192, + array::typenum::U256, + array::typenum::U384, + array::typenum::U448, + array::typenum::U512, + array::typenum::U768, + array::typenum::U896, + array::typenum::U1024, + array::typenum::U2048, + array::typenum::U4096, + array::typenum::U8192 +} + +impl_serializable_state_u16_array! { + array::typenum::U1, + array::typenum::U2, + array::typenum::U3, + array::typenum::U4, + array::typenum::U5, + array::typenum::U6, + array::typenum::U7, + array::typenum::U8, + array::typenum::U9, + array::typenum::U10, + array::typenum::U11, + array::typenum::U12, + array::typenum::U13, + array::typenum::U14, + array::typenum::U15, + array::typenum::U16, + array::typenum::U17, + array::typenum::U18, + array::typenum::U19, + array::typenum::U20, + array::typenum::U21, + array::typenum::U22, + array::typenum::U23, + array::typenum::U24, + array::typenum::U25, + array::typenum::U26, + array::typenum::U27, + array::typenum::U28, + array::typenum::U29, + array::typenum::U30, + array::typenum::U31, + array::typenum::U32, + array::typenum::U48, + array::typenum::U96, + array::typenum::U128, + array::typenum::U192, + array::typenum::U256, + array::typenum::U384, + array::typenum::U448, + array::typenum::U512, + array::typenum::U2048, + array::typenum::U4096 +} + +impl_serializable_state_u32_array! { + array::typenum::U1, + array::typenum::U2, + array::typenum::U3, + array::typenum::U4, + array::typenum::U5, + array::typenum::U6, + array::typenum::U7, + array::typenum::U8, + array::typenum::U9, + array::typenum::U10, + array::typenum::U11, + array::typenum::U12, + array::typenum::U13, + array::typenum::U14, + array::typenum::U15, + array::typenum::U16, + array::typenum::U24, + array::typenum::U32, + array::typenum::U48, + array::typenum::U64, + array::typenum::U96, + array::typenum::U128, + array::typenum::U192, + array::typenum::U256, + array::typenum::U512, + array::typenum::U1024, + array::typenum::U2048 +} + +impl_serializable_state_u64_array! { + array::typenum::U1, + array::typenum::U2, + array::typenum::U3, + array::typenum::U4, + array::typenum::U5, + array::typenum::U6, + array::typenum::U7, + array::typenum::U8, + array::typenum::U12, + array::typenum::U16, + array::typenum::U24, + array::typenum::U32, + array::typenum::U48, + array::typenum::U64, + array::typenum::U96, + array::typenum::U128, + array::typenum::U256, + array::typenum::U512, + array::typenum::U1024 +} + +impl_serializable_state_u128_array! { + array::typenum::U1, + array::typenum::U2, + array::typenum::U3, + array::typenum::U4, + array::typenum::U6, + array::typenum::U8, + array::typenum::U12, + array::typenum::U16, + array::typenum::U24, + array::typenum::U32, + array::typenum::U48, + array::typenum::U64, + array::typenum::U128, + array::typenum::U256, + array::typenum::U512 +} diff --git a/digest/src/core_api/ct_variable.rs b/digest/src/core_api/ct_variable.rs index 20df390e7..080081a14 100644 --- a/digest/src/core_api/ct_variable.rs +++ b/digest/src/core_api/ct_variable.rs @@ -7,11 +7,16 @@ use crate::HashMarker; use crate::MacMarker; #[cfg(feature = "oid")] use const_oid::{AssociatedOid, ObjectIdentifier}; -use core::{fmt, marker::PhantomData}; +use core::{ + fmt, + marker::PhantomData, + ops::{Add, Sub}, +}; use crypto_common::{ - array::{Array, ArraySize}, - typenum::{IsLessOrEqual, LeEq, NonZero}, - Block, BlockSizeUser, OutputSizeUser, + array::{Array, ArraySize, ByteArray}, + typenum::{IsLess, IsLessOrEqual, Le, LeEq, NonZero, Sum, U1, U256}, + Block, BlockSizeUser, DeserializeStateError, OutputSizeUser, SerializableState, + SerializedState, SubSerializedStateSize, }; /// Dummy type used with [`CtVariableCoreWrapper`] in cases when @@ -188,3 +193,43 @@ macro_rules! impl_oid_carrier { } }; } + +type CtVariableCoreWrapperSerializedStateSize = + Sum<::SerializedStateSize, U1>; + +impl SerializableState for CtVariableCoreWrapper +where + T: VariableOutputCore + SerializableState, + OutSize: ArraySize + IsLessOrEqual, + LeEq: NonZero, + T::BlockSize: IsLess, + Le: NonZero, + T::SerializedStateSize: Add, + CtVariableCoreWrapperSerializedStateSize: Sub + ArraySize, + SubSerializedStateSize, T>: ArraySize, +{ + type SerializedStateSize = CtVariableCoreWrapperSerializedStateSize; + + fn serialize(&self) -> SerializedState { + let serialized_inner = self.inner.serialize(); + let serialized_outsize = ByteArray::::clone_from_slice(&[OutSize::U8]); + + serialized_inner.concat(serialized_outsize) + } + + fn deserialize( + serialized_state: &SerializedState, + ) -> Result { + let (serialized_inner, serialized_outsize) = + serialized_state.split_ref::(); + + if serialized_outsize[0] != OutSize::U8 { + return Err(DeserializeStateError); + } + + Ok(Self { + inner: T::deserialize(serialized_inner)?, + _out: PhantomData, + }) + } +} diff --git a/digest/src/core_api/rt_variable.rs b/digest/src/core_api/rt_variable.rs index c58021f89..491b91fac 100644 --- a/digest/src/core_api/rt_variable.rs +++ b/digest/src/core_api/rt_variable.rs @@ -1,11 +1,20 @@ -use super::{AlgorithmName, TruncSide, UpdateCore, VariableOutputCore}; +use super::{AlgorithmName, BlockSizeUser, TruncSide, UpdateCore, VariableOutputCore}; #[cfg(feature = "mac")] use crate::MacMarker; use crate::{HashMarker, InvalidBufferSize}; use crate::{InvalidOutputSize, Reset, Update, VariableOutput, VariableOutputReset}; use block_buffer::BlockBuffer; -use core::fmt; -use crypto_common::typenum::Unsigned; +use core::{ + convert::TryInto, + fmt, + ops::{Add, Sub}, +}; +use crypto_common::SubSerializedStateSize; +use crypto_common::{ + array::{ArraySize, ByteArray}, + typenum::{Diff, IsLess, Le, NonZero, Sum, Unsigned, U1, U256}, + AddBlockSize, DeserializeStateError, SerializableState, SerializedState, SubBlockSize, +}; /// Wrapper around [`VariableOutputCore`] which selects output size /// at run time. @@ -50,6 +59,15 @@ impl HashMarker for RtVariableCoreWrapper where T: VariableOutputCore + Ha #[cfg(feature = "mac")] impl MacMarker for RtVariableCoreWrapper where T: VariableOutputCore + MacMarker {} +impl BlockSizeUser for RtVariableCoreWrapper +where + T: VariableOutputCore, + T::BlockSize: IsLess, + Le: NonZero, +{ + type BlockSize = T::BlockSize; +} + impl Reset for RtVariableCoreWrapper where T: VariableOutputCore + UpdateCore + Reset, @@ -118,6 +136,60 @@ where } } +type RtVariableCoreWrapperSerializedStateSize = + Sum::SerializedStateSize, U1>, T>, U1>; + +impl SerializableState for RtVariableCoreWrapper +where + T: VariableOutputCore + UpdateCore + SerializableState, + T::BlockSize: IsLess, + Le: NonZero, + T::SerializedStateSize: Add, + Sum: Add + ArraySize, + AddBlockSize, T>: Add + ArraySize, + RtVariableCoreWrapperSerializedStateSize: Sub + ArraySize, + SubSerializedStateSize, T>: Sub + ArraySize, + Diff, T>, U1>: + Sub + ArraySize, + SubBlockSize< + Diff, T>, U1>, + T, + >: ArraySize, +{ + type SerializedStateSize = RtVariableCoreWrapperSerializedStateSize; + + fn serialize(&self) -> SerializedState { + let serialized_core = self.core.serialize(); + let serialized_pos = + ByteArray::::clone_from_slice(&[self.buffer.get_pos().try_into().unwrap()]); + let serialized_data = self.buffer.clone().pad_with_zeros(); + let serialized_output_size = + ByteArray::::clone_from_slice(&[self.output_size.try_into().unwrap()]); + + serialized_core + .concat(serialized_pos) + .concat(serialized_data) + .concat(serialized_output_size) + } + + fn deserialize( + serialized_state: &SerializedState, + ) -> Result { + let (serialized_core, remaining_buffer) = + serialized_state.split_ref::(); + let (serialized_pos, remaining_buffer) = remaining_buffer.split_ref::(); + let (serialized_data, serialized_output_size) = + remaining_buffer.split_ref::(); + + Ok(Self { + core: T::deserialize(serialized_core)?, + buffer: BlockBuffer::try_new(&serialized_data[..serialized_pos[0].into()]) + .map_err(|_| DeserializeStateError)?, + output_size: serialized_output_size[0].into(), + }) + } +} + #[cfg(feature = "std")] impl std::io::Write for RtVariableCoreWrapper where diff --git a/digest/src/core_api/wrapper.rs b/digest/src/core_api/wrapper.rs index c0b25f428..5765285f0 100644 --- a/digest/src/core_api/wrapper.rs +++ b/digest/src/core_api/wrapper.rs @@ -6,8 +6,17 @@ use crate::{ ExtendableOutput, ExtendableOutputReset, FixedOutput, FixedOutputReset, HashMarker, Update, }; use block_buffer::BlockBuffer; -use core::fmt; -use crypto_common::{BlockSizeUser, InvalidLength, Key, KeyInit, KeySizeUser, Output}; +use core::{ + convert::TryInto, + fmt, + ops::{Add, Sub}, +}; +use crypto_common::{ + array::{ArraySize, ByteArray}, + typenum::{Diff, IsLess, Le, NonZero, Sum, U1, U256}, + BlockSizeUser, DeserializeStateError, InvalidLength, Key, KeyInit, KeySizeUser, Output, + SerializableState, SerializedState, SubSerializedStateSize, +}; #[cfg(feature = "mac")] use crate::MacMarker; @@ -191,6 +200,48 @@ where const OID: ObjectIdentifier = T::OID; } +type CoreWrapperSerializedStateSize = + Sum::SerializedStateSize, U1>, ::BlockSize>; + +impl SerializableState for CoreWrapper +where + T: BufferKindUser + SerializableState, + T::BlockSize: IsLess, + Le: NonZero, + T::SerializedStateSize: Add, + Sum: Add + ArraySize, + CoreWrapperSerializedStateSize: Sub + ArraySize, + SubSerializedStateSize, T>: Sub + ArraySize, + Diff, T>, U1>: ArraySize, +{ + type SerializedStateSize = CoreWrapperSerializedStateSize; + + fn serialize(&self) -> SerializedState { + let serialized_core = self.core.serialize(); + let serialized_pos = + ByteArray::::clone_from_slice(&[self.buffer.get_pos().try_into().unwrap()]); + let serialized_data = self.buffer.clone().pad_with_zeros(); + + serialized_core + .concat(serialized_pos) + .concat(serialized_data) + } + + fn deserialize( + serialized_state: &SerializedState, + ) -> Result { + let (serialized_core, remaining_buffer) = + serialized_state.split_ref::(); + let (serialized_pos, serialized_data) = remaining_buffer.split_ref::(); + + Ok(Self { + core: T::deserialize(serialized_core)?, + buffer: BlockBuffer::try_new(&serialized_data[..serialized_pos[0].into()]) + .map_err(|_| DeserializeStateError)?, + }) + } +} + #[cfg(feature = "std")] impl std::io::Write for CoreWrapper where diff --git a/digest/src/dev.rs b/digest/src/dev.rs index e300bda32..db0f67be3 100644 --- a/digest/src/dev.rs +++ b/digest/src/dev.rs @@ -38,6 +38,77 @@ macro_rules! new_test { }; } +/// Define hash function serialization test +#[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] +macro_rules! hash_serialization_test { + ($name:ident, $hasher:ty, $expected_serialized_state:expr) => { + #[test] + fn $name() { + use digest::{ + crypto_common::{BlockSizeUser, SerializableState}, + typenum::Unsigned, + Digest, + }; + + let mut h = <$hasher>::new(); + + h.update(&[0x13; <$hasher as BlockSizeUser>::BlockSize::USIZE + 1]); + + let serialized_state = h.serialize(); + assert_eq!(serialized_state.as_slice(), $expected_serialized_state); + + let mut h = <$hasher>::deserialize(&serialized_state).unwrap(); + + h.update(&[0x13; <$hasher as BlockSizeUser>::BlockSize::USIZE + 1]); + let output1 = h.finalize(); + + let mut h = <$hasher>::new(); + h.update(&[0x13; 2 * (<$hasher as BlockSizeUser>::BlockSize::USIZE + 1)]); + let output2 = h.finalize(); + + assert_eq!(output1, output2); + } + }; +} + +/// Define hash function serialization test +#[macro_export] +#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] +macro_rules! hash_rt_outsize_serialization_test { + ($name:ident, $hasher:ty, $expected_serialized_state:expr) => { + #[test] + fn $name() { + use digest::{ + crypto_common::{BlockSizeUser, SerializableState}, + typenum::Unsigned, + Digest, Update, VariableOutput, + }; + const HASH_OUTPUT_SIZE: usize = <$hasher>::MAX_OUTPUT_SIZE - 1; + + let mut h = <$hasher>::new(HASH_OUTPUT_SIZE).unwrap(); + + h.update(&[0x13; <$hasher as BlockSizeUser>::BlockSize::USIZE + 1]); + + let serialized_state = h.serialize(); + assert_eq!(serialized_state.as_slice(), $expected_serialized_state); + + let mut h = <$hasher>::deserialize(&serialized_state).unwrap(); + + h.update(&[0x13; <$hasher as BlockSizeUser>::BlockSize::USIZE + 1]); + let mut output1 = [0; HASH_OUTPUT_SIZE]; + h.finalize_variable(&mut output1).unwrap(); + + let mut h = <$hasher>::new(HASH_OUTPUT_SIZE).unwrap(); + h.update(&[0x13; 2 * (<$hasher as BlockSizeUser>::BlockSize::USIZE + 1)]); + let mut output2 = [0; HASH_OUTPUT_SIZE]; + h.finalize_variable(&mut output2).unwrap(); + + assert_eq!(output1, output2); + } + }; +} + /// Define [`Update`][crate::Update] impl benchmark #[macro_export] macro_rules! bench_update { From caac4e1fbb5a300c84df30cab2d4593b18cd7ab6 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 19 Nov 2023 11:34:44 -0700 Subject: [PATCH 1090/1461] elliptic-curve v0.13.8 (#1413) --- Cargo.lock | 4 ++-- elliptic-curve/CHANGELOG.md | 6 ++++++ elliptic-curve/Cargo.toml | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 27d5f005f..8d7cc1c4e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -262,7 +262,7 @@ dependencies = [ "cipher 0.4.4", "crypto-common 0.1.6", "digest 0.10.7", - "elliptic-curve 0.13.7", + "elliptic-curve 0.13.8", "password-hash", "signature 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "universal-hash 0.5.1", @@ -472,7 +472,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.13.7" +version = "0.13.8" dependencies = [ "base16ct 0.2.0", "base64ct", diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index e95a04fc6..3f47710eb 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.13.8 (2023-11-18) +### Changed +- `SecretKey::from_slice` now allows >=24-bytes ([#1412]) + +[#1412]: https://github.com/RustCrypto/traits/pull/1412 + ## 0.13.7 (2023-11-15) ### Added - `BatchInvert` and `BatchNormalize` traits ([#1376]) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index becaab7a8..1bcafd0bf 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.13.7" +version = "0.13.8" description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, From a54b18d9f29d78468421437f69add46e88279476 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Nov 2023 16:41:56 -0700 Subject: [PATCH 1091/1461] build(deps): bump crypto-bigint from 0.5.4 to 0.5.5 (#1414) Bumps [crypto-bigint](https://github.com/RustCrypto/crypto-bigint) from 0.5.4 to 0.5.5. - [Changelog](https://github.com/RustCrypto/crypto-bigint/blob/master/CHANGELOG.md) - [Commits](https://github.com/RustCrypto/crypto-bigint/compare/v0.5.4...v0.5.5) --- updated-dependencies: - dependency-name: crypto-bigint dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8d7cc1c4e..7e1f56177 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -294,9 +294,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.5.4" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28f85c3514d2a6e64160359b45a3918c3b4178bcbf4ae5d03ab2d02e521c479a" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ "generic-array", "rand_core 0.6.4", @@ -476,7 +476,7 @@ version = "0.13.8" dependencies = [ "base16ct 0.2.0", "base64ct", - "crypto-bigint 0.5.4", + "crypto-bigint 0.5.5", "digest 0.10.7", "ff 0.13.0", "generic-array", From c20194efc5572ed1100b928aaf9770cd7aa560f2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 15 Dec 2023 20:22:52 -0700 Subject: [PATCH 1092/1461] build(deps): bump const-oid from 0.9.5 to 0.9.6 (#1420) Bumps [const-oid](https://github.com/RustCrypto/formats) from 0.9.5 to 0.9.6. - [Commits](https://github.com/RustCrypto/formats/compare/const-oid/v0.9.5...const-oid/v0.9.6) --- updated-dependencies: - dependency-name: const-oid dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7e1f56177..f3771b0d9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -241,9 +241,9 @@ checksum = "9d6f2aa4d0537bcc1c74df8755072bd31c1ef1a3a1b85a68e8404a8c353b7b8b" [[package]] name = "const-oid" -version = "0.9.5" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "cpufeatures" @@ -371,7 +371,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" dependencies = [ - "const-oid 0.9.5", + "const-oid 0.9.6", ] [[package]] @@ -380,7 +380,7 @@ version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" dependencies = [ - "const-oid 0.9.5", + "const-oid 0.9.6", "pem-rfc7468 0.7.0", "zeroize", ] @@ -411,7 +411,7 @@ version = "0.11.0-pre" dependencies = [ "blobby", "block-buffer 0.11.0-pre", - "const-oid 0.9.5", + "const-oid 0.9.6", "crypto-common 0.2.0-pre", "subtle", ] From 25f5da79761745fe4f10fbac09bad4c8384ad152 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 15 Dec 2023 20:23:02 -0700 Subject: [PATCH 1093/1461] build(deps): bump hkdf from 0.12.3 to 0.12.4 (#1417) Bumps [hkdf](https://github.com/RustCrypto/KDFs) from 0.12.3 to 0.12.4. - [Commits](https://github.com/RustCrypto/KDFs/compare/hkdf-v0.12.3...hkdf-v0.12.4) --- updated-dependencies: - dependency-name: hkdf dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 10 +++++----- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f3771b0d9..929996508 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -463,7 +463,7 @@ dependencies = [ "ff 0.12.1", "generic-array", "group 0.12.1", - "hkdf 0.12.3", + "hkdf 0.12.4", "rand_core 0.6.4", "sec1 0.3.0", "subtle", @@ -482,7 +482,7 @@ dependencies = [ "generic-array", "group 0.13.0", "hex-literal", - "hkdf 0.12.3", + "hkdf 0.12.4", "pem-rfc7468 0.7.0", "pkcs8 0.10.2", "rand_core 0.6.4", @@ -641,9 +641,9 @@ dependencies = [ [[package]] name = "hkdf" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" dependencies = [ "hmac 0.12.1", ] @@ -679,7 +679,7 @@ dependencies = [ "chacha20poly1305", "digest 0.10.7", "generic-array", - "hkdf 0.12.3", + "hkdf 0.12.4", "hmac 0.12.1", "p256 0.11.1", "rand_core 0.6.4", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 1bcafd0bf..7cd47e35e 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -28,7 +28,7 @@ base64ct = { version = "1", optional = true, default-features = false, features digest = { version = "0.10", optional = true } ff = { version = "0.13", optional = true, default-features = false } group = { version = "0.13", optional = true, default-features = false } -hkdf = { version = "0.12.1", optional = true, default-features = false } +hkdf = { version = "0.12.4", optional = true, default-features = false } hex-literal = { version = "0.4", optional = true } pem-rfc7468 = { version = "0.7", optional = true, features = ["alloc"] } pkcs8 = { version = "0.10.2", optional = true, default-features = false } From 3a44a3e5582aa5c0c512c93a470ef8f1a581f7f7 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 28 Dec 2023 10:36:05 -0700 Subject: [PATCH 1094/1461] Remove unused imports (#1426) These are breaking the build on the latest `stable` --- cipher/src/dev/block.rs | 2 -- digest/src/dev.rs | 1 - 2 files changed, 3 deletions(-) diff --git a/cipher/src/dev/block.rs b/cipher/src/dev/block.rs index 101d5af84..70594755c 100644 --- a/cipher/src/dev/block.rs +++ b/cipher/src/dev/block.rs @@ -1,7 +1,5 @@ //! Development-related functionality -pub use blobby; - /// Define block cipher test #[macro_export] macro_rules! block_cipher_test { diff --git a/digest/src/dev.rs b/digest/src/dev.rs index db0f67be3..5ceae41b4 100644 --- a/digest/src/dev.rs +++ b/digest/src/dev.rs @@ -9,7 +9,6 @@ mod variable; mod xof; pub use fixed::*; -pub use mac::*; pub use variable::*; pub use xof::*; From 1c06a1e09dade7df1b108805fea30efba783f5a8 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 28 Dec 2023 10:44:46 -0700 Subject: [PATCH 1095/1461] Cargo.lock: bump dependencies (#1425) Upgrades the following dependencies: $ cargo update Updating git repository `https://github.com/RustCrypto/utils.git` 708aa72..cc77203 -> origin/HEAD Updating crates.io index Updating async-trait v0.1.74 -> v0.1.75 Updating block-buffer v0.11.0-pre (https://github.com/RustCrypto/utils.git#708aa72b) -> #cc772039 Updating block-padding v0.4.0-pre (https://github.com/RustCrypto/utils.git#708aa72b) -> #cc772039 Updating byteorder v1.4.3 -> v1.5.0 Downgrading cc v1.0.84 -> v1.0.83 Updating hybrid-array v0.2.0-pre.5 (https://github.com/RustCrypto/utils.git#708aa72b) -> #cc772039 Updating inout v0.2.0-pre (https://github.com/RustCrypto/utils.git#708aa72b) -> #cc772039 Updating itoa v1.0.9 -> v1.0.10 Adding jobserver v0.1.27 Updating libc v0.2.150 -> v0.2.151 Updating proc-macro2 v1.0.69 -> v1.0.71 Updating ryu v1.0.15 -> v1.0.16 Updating serde v1.0.192 -> v1.0.193 Updating serde_bytes v0.11.12 -> v0.11.13 Updating serde_derive v1.0.192 -> v1.0.193 Updating spki v0.7.2 -> v0.7.3 Updating syn v2.0.39 -> v2.0.43 --- .github/workflows/kem.yml | 30 ++--------------- Cargo.lock | 70 ++++++++++++++++++++++----------------- kem/Cargo.toml | 4 +-- kem/README.md | 4 +-- 4 files changed, 46 insertions(+), 62 deletions(-) diff --git a/.github/workflows/kem.yml b/.github/workflows/kem.yml index 8f70e5644..70d1608f1 100644 --- a/.github/workflows/kem.yml +++ b/.github/workflows/kem.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.61.0 # Next MSRV candidate + - 1.66.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -36,26 +36,12 @@ jobs: targets: ${{ matrix.target }} - run: cargo build --no-default-features --release --target ${{ matrix.target }} - # TODO: use the reusable workflow after this crate will be part of the - # toot workspace - # minimal-versions: - # runs-on: ubuntu-latest - # steps: - # - uses: actions/checkout@v4 - # - uses: RustCrypto/actions/cargo-cache@master - # - uses: dtolnay/rust-toolchain@master - # with: - # toolchain: nightly - # - uses: RustCrypto/actions/cargo-hack-install@master - # - run: cargo update -Z minimal-versions - # - run: cargo hack test --release --feature-powerset - test: runs-on: ubuntu-latest strategy: matrix: rust: - - 1.61.0 # Next MSRV candidate + - 1.66.0 # MSRV - stable steps: - uses: actions/checkout@v4 @@ -67,15 +53,3 @@ jobs: - run: cargo test --no-default-features --release - run: cargo test --release - run: cargo test --all-features --release - - # build-only test of MSRV - # TODO: remove on MSRV bump higher than MSRV of `cc` - test-msrv: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: RustCrypto/actions/cargo-cache@master - - uses: dtolnay/rust-toolchain@master - with: - toolchain: 1.60.0 - - run: cargo check --all-features diff --git a/Cargo.lock b/Cargo.lock index 929996508..4456a4a23 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -64,9 +64,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.74" +version = "0.1.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" +checksum = "fdf6721fb0140e4f897002dd086c06f6c27775df19cfe1fccb21181a48fd2c98" dependencies = [ "proc-macro2", "quote", @@ -139,7 +139,7 @@ dependencies = [ [[package]] name = "block-buffer" version = "0.11.0-pre" -source = "git+https://github.com/RustCrypto/utils.git#708aa72b9ebde06a02e862368e890fb3ddcb2fb9" +source = "git+https://github.com/RustCrypto/utils.git#cc772039c62a0a2f4761b28df796d8b2dbda12e6" dependencies = [ "crypto-common 0.2.0-pre", ] @@ -156,16 +156,16 @@ dependencies = [ [[package]] name = "block-padding" version = "0.4.0-pre" -source = "git+https://github.com/RustCrypto/utils.git#708aa72b9ebde06a02e862368e890fb3ddcb2fb9" +source = "git+https://github.com/RustCrypto/utils.git#cc772039c62a0a2f4761b28df796d8b2dbda12e6" dependencies = [ "hybrid-array", ] [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" @@ -175,10 +175,11 @@ checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "cc" -version = "1.0.84" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f8e7c90afad890484a21653d08b6e209ae34770fb5ee298f9c699fcc1e5c856" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" dependencies = [ + "jobserver", "libc", ] @@ -692,7 +693,7 @@ dependencies = [ [[package]] name = "hybrid-array" version = "0.2.0-pre.5" -source = "git+https://github.com/RustCrypto/utils.git#708aa72b9ebde06a02e862368e890fb3ddcb2fb9" +source = "git+https://github.com/RustCrypto/utils.git#cc772039c62a0a2f4761b28df796d8b2dbda12e6" dependencies = [ "typenum", ] @@ -710,7 +711,7 @@ dependencies = [ [[package]] name = "inout" version = "0.2.0-pre" -source = "git+https://github.com/RustCrypto/utils.git#708aa72b9ebde06a02e862368e890fb3ddcb2fb9" +source = "git+https://github.com/RustCrypto/utils.git#cc772039c62a0a2f4761b28df796d8b2dbda12e6" dependencies = [ "block-padding 0.4.0-pre", "hybrid-array", @@ -718,9 +719,18 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" + +[[package]] +name = "jobserver" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" +dependencies = [ + "libc", +] [[package]] name = "keccak" @@ -733,7 +743,7 @@ dependencies = [ [[package]] name = "kem" -version = "0.2.0" +version = "0.3.0-pre" dependencies = [ "generic-array", "hpke", @@ -748,9 +758,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.150" +version = "0.2.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" +checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" [[package]] name = "opaque-debug" @@ -824,7 +834,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ "der 0.7.8", - "spki 0.7.2", + "spki 0.7.3", ] [[package]] @@ -899,9 +909,9 @@ checksum = "94e851c7654eed9e68d7d27164c454961a616cf8c203d500607ef22c737b51bb" [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "75cb1540fadbd5b8fbccc4dddad2734eba435053f725621c070711a14bb5f4b8" dependencies = [ "unicode-ident", ] @@ -959,9 +969,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.15" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" [[package]] name = "sec1" @@ -993,27 +1003,27 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.192" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001" +checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" dependencies = [ "serde_derive", ] [[package]] name = "serde_bytes" -version = "0.11.12" +version = "0.11.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab33ec92f677585af6d88c65593ae2375adde54efdbf16d597f2cbc7a6d368ff" +checksum = "8bb1879ea93538b78549031e2d54da3e901fd7e75f2e4dc758d760937b123d10" dependencies = [ "serde", ] [[package]] name = "serde_derive" -version = "1.0.192" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1" +checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" dependencies = [ "proc-macro2", "quote", @@ -1126,9 +1136,9 @@ dependencies = [ [[package]] name = "spki" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", "der 0.7.8", @@ -1148,9 +1158,9 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "syn" -version = "2.0.39" +version = "2.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +checksum = "ee659fb5f3d355364e1f3e5bc10fb82068efbf824a1e9d1c9504244a6469ad53" dependencies = [ "proc-macro2", "quote", diff --git a/kem/Cargo.toml b/kem/Cargo.toml index 5b8dece78..23f9fba14 100644 --- a/kem/Cargo.toml +++ b/kem/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "kem" description = "Traits for key encapsulation mechanisms" -version = "0.2.0" +version = "0.3.0-pre" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/kem" @@ -10,7 +10,7 @@ readme = "README.md" edition = "2021" keywords = ["crypto"] categories = ["cryptography", "no-std"] -rust-version = "1.60" +rust-version = "1.66" [dependencies] rand_core = "0.6" diff --git a/kem/README.md b/kem/README.md index f9a933329..51be87890 100644 --- a/kem/README.md +++ b/kem/README.md @@ -15,7 +15,7 @@ The crate exposes four traits, `Encapsulator`, `Decapsulator`, `AuthEncapsulator ## Minimum Supported Rust Version -Rust **1.60** or higher. +Rust **1.66** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -47,7 +47,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/kem/badge.svg [docs-link]: https://docs.rs/kem/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.60+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.66+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260048-signatures [build-image]: https://github.com/RustCrypto/traits/workflows/kem/badge.svg?branch=master&event=push From 05a23aa2eb5511398ded3b63b6cfb7bab3b801f6 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 28 Dec 2023 10:46:57 -0700 Subject: [PATCH 1096/1461] Bump `clippy` version to 1.75.0 (#1427) --- .github/workflows/workspace.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index 30a0da8f8..d0840aed0 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -26,7 +26,7 @@ jobs: - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: - toolchain: 1.73.0 + toolchain: 1.75.0 components: clippy - run: cargo clippy --all --all-features --tests -- -D warnings From 9224b6b9088d062452fa5b7dec0d63fa97d1cb6d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 29 Dec 2023 11:02:15 -0700 Subject: [PATCH 1097/1461] async-signature: move to AFIT; MSRV 1.75 (#1428) `AFIT` was stabilized in Rust 1.75. `#[allow(async_fn_in_trait)]` is required until a solution to RPITIT is merged in rust. This put responsability on the implementor of `async_signature::AsyncSigner` to make sure their future is `Send`able. see https://github.com/rust-lang/rust/pull/115822#issuecomment-1731149475 for more context. Also introduces an `AsyncRandomizedSigner` trait. Co-authored-by: Arthur Gautier --- .github/workflows/async-signature.yml | 2 +- Cargo.lock | 12 ------- async-signature/Cargo.toml | 4 +-- async-signature/README.md | 4 +-- async-signature/src/lib.rs | 47 ++++++++++++++++++++++++--- 5 files changed, 47 insertions(+), 22 deletions(-) diff --git a/.github/workflows/async-signature.yml b/.github/workflows/async-signature.yml index 41aba9707..589fc27f9 100644 --- a/.github/workflows/async-signature.yml +++ b/.github/workflows/async-signature.yml @@ -23,7 +23,7 @@ jobs: strategy: matrix: rust: - - 1.60.0 # MSRV + - 1.75.0 # MSRV - stable steps: - uses: actions/checkout@v4 diff --git a/Cargo.lock b/Cargo.lock index 4456a4a23..e573a449d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -58,21 +58,9 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" name = "async-signature" version = "0.4.0" dependencies = [ - "async-trait", "signature 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "async-trait" -version = "0.1.75" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdf6721fb0140e4f897002dd086c06f6c27775df19cfe1fccb21181a48fd2c98" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "base16ct" version = "0.1.1" diff --git a/async-signature/Cargo.toml b/async-signature/Cargo.toml index 753f62944..14fc45ebb 100644 --- a/async-signature/Cargo.toml +++ b/async-signature/Cargo.toml @@ -10,14 +10,14 @@ readme = "README.md" keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"] categories = ["cryptography", "no-std"] edition = "2021" -rust-version = "1.60" +rust-version = "1.75" [dependencies] -async-trait = "0.1.9" signature = ">= 2.0, <2.3" [features] digest = ["signature/digest"] +rand_core = ["signature/rand_core"] [package.metadata.docs.rs] all-features = true diff --git a/async-signature/README.md b/async-signature/README.md index 55b6e64c1..1a5b5be9b 100644 --- a/async-signature/README.md +++ b/async-signature/README.md @@ -9,7 +9,7 @@ ## Minimum Supported Rust Version -Rust **1.60** or higher. +Rust **1.75** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -36,7 +36,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/async-signature/badge.svg [docs-link]: https://docs.rs/async-signature/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.60+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.75+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260048-signatures [build-image]: https://github.com/RustCrypto/traits/workflows/async-signature/badge.svg?branch=master&event=push diff --git a/async-signature/src/lib.rs b/async-signature/src/lib.rs index 8c59952ca..1dcd2b199 100644 --- a/async-signature/src/lib.rs +++ b/async-signature/src/lib.rs @@ -17,13 +17,14 @@ pub use signature::{self, Error}; #[cfg(feature = "digest")] pub use signature::digest::{self, Digest}; -use async_trait::async_trait; +#[cfg(feature = "rand_core")] +use signature::rand_core::CryptoRngCore; /// Asynchronously sign the provided message bytestring using `Self` /// (e.g. client for a Cloud KMS or HSM), returning a digital signature. /// /// This trait is an async equivalent of the [`signature::Signer`] trait. -#[async_trait(?Send)] +#[allow(async_fn_in_trait)] pub trait AsyncSigner { /// Attempt to sign the given message, returning a digital signature on /// success, or an error if something went wrong. @@ -33,7 +34,6 @@ pub trait AsyncSigner { async fn sign_async(&self, msg: &[u8]) -> Result; } -#[async_trait(?Send)] impl AsyncSigner for T where S: 'static, @@ -48,7 +48,7 @@ where /// /// This trait is an async equivalent of the [`signature::DigestSigner`] trait. #[cfg(feature = "digest")] -#[async_trait(?Send)] +#[allow(async_fn_in_trait)] pub trait AsyncDigestSigner where D: Digest + 'static, @@ -60,7 +60,6 @@ where } #[cfg(feature = "digest")] -#[async_trait(?Send)] impl AsyncDigestSigner for T where D: Digest + 'static, @@ -71,3 +70,41 @@ where self.try_sign_digest(digest) } } + +/// Sign the given message using the provided external randomness source. +#[cfg(feature = "rand_core")] +#[allow(async_fn_in_trait)] +pub trait AsyncRandomizedSigner { + /// Sign the given message and return a digital signature + async fn sign_with_rng_async(&self, rng: &mut impl CryptoRngCore, msg: &[u8]) -> S { + self.try_sign_with_rng_async(rng, msg) + .await + .expect("signature operation failed") + } + + /// Attempt to sign the given message, returning a digital signature on + /// success, or an error if something went wrong. + /// + /// The main intended use case for signing errors is when communicating + /// with external signers, e.g. cloud KMS, HSMs, or other hardware tokens. + async fn try_sign_with_rng_async( + &self, + rng: &mut impl CryptoRngCore, + msg: &[u8], + ) -> Result; +} + +#[cfg(feature = "rand_core")] +impl AsyncRandomizedSigner for T +where + S: 'static, + T: signature::RandomizedSigner, +{ + async fn try_sign_with_rng_async( + &self, + rng: &mut impl CryptoRngCore, + msg: &[u8], + ) -> Result { + self.try_sign_with_rng(rng, msg) + } +} From bd53cc9c9989cf657f20306d3f2d633bad7cbff8 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 29 Dec 2023 11:11:52 -0700 Subject: [PATCH 1098/1461] async-signature: bump version to v0.5.0-pre (#1429) NOTE: this is not a release, but just to denote that the current `master` contains breaking changes, which were introduced in #1428 --- Cargo.lock | 2 +- async-signature/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e573a449d..31e260031 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -56,7 +56,7 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "async-signature" -version = "0.4.0" +version = "0.5.0-pre" dependencies = [ "signature 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/async-signature/Cargo.toml b/async-signature/Cargo.toml index 14fc45ebb..3b4014905 100644 --- a/async-signature/Cargo.toml +++ b/async-signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "async-signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "0.4.0" +version = "0.5.0-pre" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/async-signature" From 15b8e95c24f03d8108a91d945559fece917ff5be Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 29 Dec 2023 11:17:35 -0700 Subject: [PATCH 1099/1461] async-signature: remove 'static bounds (#1430) As discussed in #1375. These bounds don't add value: it requires notating them even when unnecessary, and when necessary they still need to be notated anyway. --- async-signature/src/lib.rs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/async-signature/src/lib.rs b/async-signature/src/lib.rs index 1dcd2b199..08633dce8 100644 --- a/async-signature/src/lib.rs +++ b/async-signature/src/lib.rs @@ -25,7 +25,7 @@ use signature::rand_core::CryptoRngCore; /// /// This trait is an async equivalent of the [`signature::Signer`] trait. #[allow(async_fn_in_trait)] -pub trait AsyncSigner { +pub trait AsyncSigner { /// Attempt to sign the given message, returning a digital signature on /// success, or an error if something went wrong. /// @@ -36,7 +36,6 @@ pub trait AsyncSigner { impl AsyncSigner for T where - S: 'static, T: signature::Signer, { async fn sign_async(&self, msg: &[u8]) -> Result { @@ -51,8 +50,7 @@ where #[allow(async_fn_in_trait)] pub trait AsyncDigestSigner where - D: Digest + 'static, - S: 'static, + D: Digest, { /// Attempt to sign the given prehashed message [`Digest`], returning a /// digital signature on success, or an error if something went wrong. @@ -62,8 +60,7 @@ where #[cfg(feature = "digest")] impl AsyncDigestSigner for T where - D: Digest + 'static, - S: 'static, + D: Digest, T: signature::DigestSigner, { async fn sign_digest_async(&self, digest: D) -> Result { @@ -97,7 +94,6 @@ pub trait AsyncRandomizedSigner { #[cfg(feature = "rand_core")] impl AsyncRandomizedSigner for T where - S: 'static, T: signature::RandomizedSigner, { async fn try_sign_with_rng_async( From a17da800956ef3f52ee1afa9818907234283459d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 29 Dec 2023 11:36:38 -0700 Subject: [PATCH 1100/1461] async-signature v0.5.0-pre.0 (#1431) --- Cargo.lock | 2 +- async-signature/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 31e260031..1742c042e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -56,7 +56,7 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "async-signature" -version = "0.5.0-pre" +version = "0.5.0-pre.0" dependencies = [ "signature 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/async-signature/Cargo.toml b/async-signature/Cargo.toml index 3b4014905..eea5ab4ba 100644 --- a/async-signature/Cargo.toml +++ b/async-signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "async-signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "0.5.0-pre" +version = "0.5.0-pre.0" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/async-signature" From 9b40ddf1f1cd7aed1834c1b86660f29c8074ebdb Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 29 Dec 2023 17:58:00 -0700 Subject: [PATCH 1101/1461] Bump `hybrid-array` to v0.2.0-pre.6 (#1432) This removes the `ByteArray` type alias. Updates the following crates: - `aead` - `crypto-common` - `digest` --- Cargo.lock | 11 ++++++----- Cargo.toml | 1 - aead/src/lib.rs | 6 +++--- aead/src/stream.rs | 8 ++++---- crypto-common/Cargo.toml | 2 +- crypto-common/src/lib.rs | 10 +++++----- crypto-common/src/serializable_state.rs | 4 ++-- digest/src/core_api/ct_variable.rs | 4 ++-- digest/src/core_api/rt_variable.rs | 6 +++--- digest/src/core_api/wrapper.rs | 4 ++-- 10 files changed, 28 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1742c042e..2e5c16071 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -127,7 +127,7 @@ dependencies = [ [[package]] name = "block-buffer" version = "0.11.0-pre" -source = "git+https://github.com/RustCrypto/utils.git#cc772039c62a0a2f4761b28df796d8b2dbda12e6" +source = "git+https://github.com/RustCrypto/utils.git#314938fe8e16d55979e70d777f90a475abcfb7f4" dependencies = [ "crypto-common 0.2.0-pre", ] @@ -144,7 +144,7 @@ dependencies = [ [[package]] name = "block-padding" version = "0.4.0-pre" -source = "git+https://github.com/RustCrypto/utils.git#cc772039c62a0a2f4761b28df796d8b2dbda12e6" +source = "git+https://github.com/RustCrypto/utils.git#314938fe8e16d55979e70d777f90a475abcfb7f4" dependencies = [ "hybrid-array", ] @@ -680,8 +680,9 @@ dependencies = [ [[package]] name = "hybrid-array" -version = "0.2.0-pre.5" -source = "git+https://github.com/RustCrypto/utils.git#cc772039c62a0a2f4761b28df796d8b2dbda12e6" +version = "0.2.0-pre.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f148d5add3c53ebf18452f556b0437d3d5c4540f34eb7b80c5ad4b54632c4e2" dependencies = [ "typenum", ] @@ -699,7 +700,7 @@ dependencies = [ [[package]] name = "inout" version = "0.2.0-pre" -source = "git+https://github.com/RustCrypto/utils.git#cc772039c62a0a2f4761b28df796d8b2dbda12e6" +source = "git+https://github.com/RustCrypto/utils.git#314938fe8e16d55979e70d777f90a475abcfb7f4" dependencies = [ "block-padding 0.4.0-pre", "hybrid-array", diff --git a/Cargo.toml b/Cargo.toml index 56fd5a9aa..d668c3eda 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,5 +18,4 @@ members = [ [patch.crates-io] block-buffer = { git = "https://github.com/RustCrypto/utils.git" } crypto-common = { path = "crypto-common" } -hybrid-array = { git = "https://github.com/RustCrypto/utils.git" } inout = { git = "https://github.com/RustCrypto/utils.git" } diff --git a/aead/src/lib.rs b/aead/src/lib.rs index 0a6f2aff1..8448e40f7 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -43,7 +43,7 @@ pub use heapless; pub use crypto_common::rand_core; use core::fmt; -use crypto_common::array::{typenum::Unsigned, ArraySize, ByteArray}; +use crypto_common::array::{typenum::Unsigned, Array, ArraySize}; #[cfg(feature = "alloc")] use alloc::vec::Vec; @@ -74,10 +74,10 @@ impl fmt::Display for Error { impl std::error::Error for Error {} /// Nonce: single-use value for ensuring ciphertexts are unique -pub type Nonce = ByteArray<::NonceSize>; +pub type Nonce = Array::NonceSize>; /// Tag: authentication code which ensures ciphertexts are authentic -pub type Tag = ByteArray<::TagSize>; +pub type Tag = Array::TagSize>; /// Authenticated Encryption with Associated Data (AEAD) algorithm core trait. /// diff --git a/aead/src/stream.rs b/aead/src/stream.rs index cbed91a6f..27ff31281 100644 --- a/aead/src/stream.rs +++ b/aead/src/stream.rs @@ -36,14 +36,14 @@ use crate::{AeadCore, AeadInPlace, Buffer, Error, Key, KeyInit, Result}; use core::ops::{AddAssign, Sub}; use crypto_common::array::{ typenum::{Unsigned, U4, U5}, - ArraySize, ByteArray, + Array, ArraySize, }; #[cfg(feature = "alloc")] use {crate::Payload, alloc::vec::Vec}; /// Nonce as used by a given AEAD construction and STREAM primitive. -pub type Nonce = ByteArray>; +pub type Nonce = Array>; /// Size of a nonce as used by a STREAM construction, sans the overhead of /// the STREAM protocol itself. @@ -433,7 +433,7 @@ where /// Compute the full AEAD nonce including the STREAM counter and last /// block flag. fn aead_nonce(&self, position: u32, last_block: bool) -> crate::Nonce { - let mut result = ByteArray::default(); + let mut result = Array::default(); // TODO(tarcieri): use `generic_array::sequence::Concat` (or const generics) let (prefix, tail) = result.split_at_mut(NonceSize::::to_usize()); @@ -527,7 +527,7 @@ where return Err(Error); } - let mut result = ByteArray::default(); + let mut result = Array::default(); // TODO(tarcieri): use `generic_array::sequence::Concat` (or const generics) let (prefix, tail) = result.split_at_mut(NonceSize::::to_usize()); diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index 27a3e4fe9..0e1e8fd31 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -13,7 +13,7 @@ keywords = ["crypto", "traits"] categories = ["cryptography", "no-std"] [dependencies] -hybrid-array = "=0.2.0-pre.5" +hybrid-array = "=0.2.0-pre.6" # optional dependencies rand_core = { version = "0.6.4", optional = true } diff --git a/crypto-common/src/lib.rs b/crypto-common/src/lib.rs index 6a9c9a4c6..bdaff2cdd 100644 --- a/crypto-common/src/lib.rs +++ b/crypto-common/src/lib.rs @@ -23,7 +23,7 @@ pub use hybrid_array::typenum; use core::fmt; use hybrid_array::{ typenum::{Diff, Sum, Unsigned}, - Array, ArraySize, ByteArray, + Array, ArraySize, }; #[cfg(feature = "rand_core")] @@ -36,19 +36,19 @@ pub use serializable_state::{ }; /// Block on which [`BlockSizeUser`] implementors operate. -pub type Block = ByteArray<::BlockSize>; +pub type Block = Array::BlockSize>; /// Parallel blocks on which [`ParBlocksSizeUser`] implementors operate. pub type ParBlocks = Array, ::ParBlocksSize>; /// Output array of [`OutputSizeUser`] implementors. -pub type Output = ByteArray<::OutputSize>; +pub type Output = Array::OutputSize>; /// Key used by [`KeySizeUser`] implementors. -pub type Key = ByteArray<::KeySize>; +pub type Key = Array::KeySize>; /// Initialization vector (nonce) used by [`IvSizeUser`] implementors. -pub type Iv = ByteArray<::IvSize>; +pub type Iv = Array::IvSize>; /// Alias for `AddBlockSize = Sum` pub type AddBlockSize = Sum::BlockSize>; diff --git a/crypto-common/src/serializable_state.rs b/crypto-common/src/serializable_state.rs index fa72d13c8..735f485e2 100644 --- a/crypto-common/src/serializable_state.rs +++ b/crypto-common/src/serializable_state.rs @@ -1,12 +1,12 @@ use crate::array::{ self, typenum::{Diff, Prod, Sum, Unsigned, U1, U16, U2, U4, U8}, - ArraySize, ByteArray, + Array, ArraySize, }; use core::{convert::TryInto, default::Default, fmt}; /// Serialized internal state. -pub type SerializedState = ByteArray<::SerializedStateSize>; +pub type SerializedState = Array::SerializedStateSize>; /// Alias for `AddSerializedStateSize = Sum` pub type AddSerializedStateSize = Sum::SerializedStateSize>; diff --git a/digest/src/core_api/ct_variable.rs b/digest/src/core_api/ct_variable.rs index 080081a14..b863fd747 100644 --- a/digest/src/core_api/ct_variable.rs +++ b/digest/src/core_api/ct_variable.rs @@ -13,7 +13,7 @@ use core::{ ops::{Add, Sub}, }; use crypto_common::{ - array::{Array, ArraySize, ByteArray}, + array::{Array, ArraySize}, typenum::{IsLess, IsLessOrEqual, Le, LeEq, NonZero, Sum, U1, U256}, Block, BlockSizeUser, DeserializeStateError, OutputSizeUser, SerializableState, SerializedState, SubSerializedStateSize, @@ -212,7 +212,7 @@ where fn serialize(&self) -> SerializedState { let serialized_inner = self.inner.serialize(); - let serialized_outsize = ByteArray::::clone_from_slice(&[OutSize::U8]); + let serialized_outsize = Array::::clone_from_slice(&[OutSize::U8]); serialized_inner.concat(serialized_outsize) } diff --git a/digest/src/core_api/rt_variable.rs b/digest/src/core_api/rt_variable.rs index 491b91fac..0fe3e15a5 100644 --- a/digest/src/core_api/rt_variable.rs +++ b/digest/src/core_api/rt_variable.rs @@ -11,7 +11,7 @@ use core::{ }; use crypto_common::SubSerializedStateSize; use crypto_common::{ - array::{ArraySize, ByteArray}, + array::{Array, ArraySize}, typenum::{Diff, IsLess, Le, NonZero, Sum, Unsigned, U1, U256}, AddBlockSize, DeserializeStateError, SerializableState, SerializedState, SubBlockSize, }; @@ -161,10 +161,10 @@ where fn serialize(&self) -> SerializedState { let serialized_core = self.core.serialize(); let serialized_pos = - ByteArray::::clone_from_slice(&[self.buffer.get_pos().try_into().unwrap()]); + Array::::clone_from_slice(&[self.buffer.get_pos().try_into().unwrap()]); let serialized_data = self.buffer.clone().pad_with_zeros(); let serialized_output_size = - ByteArray::::clone_from_slice(&[self.output_size.try_into().unwrap()]); + Array::::clone_from_slice(&[self.output_size.try_into().unwrap()]); serialized_core .concat(serialized_pos) diff --git a/digest/src/core_api/wrapper.rs b/digest/src/core_api/wrapper.rs index 5765285f0..38d348a34 100644 --- a/digest/src/core_api/wrapper.rs +++ b/digest/src/core_api/wrapper.rs @@ -12,7 +12,7 @@ use core::{ ops::{Add, Sub}, }; use crypto_common::{ - array::{ArraySize, ByteArray}, + array::{Array, ArraySize}, typenum::{Diff, IsLess, Le, NonZero, Sum, U1, U256}, BlockSizeUser, DeserializeStateError, InvalidLength, Key, KeyInit, KeySizeUser, Output, SerializableState, SerializedState, SubSerializedStateSize, @@ -219,7 +219,7 @@ where fn serialize(&self) -> SerializedState { let serialized_core = self.core.serialize(); let serialized_pos = - ByteArray::::clone_from_slice(&[self.buffer.get_pos().try_into().unwrap()]); + Array::::clone_from_slice(&[self.buffer.get_pos().try_into().unwrap()]); let serialized_data = self.buffer.clone().pad_with_zeros(); serialized_core From 43cec2c212e74495ff439c8b5eb232e03fb5e61f Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 29 Dec 2023 18:10:55 -0700 Subject: [PATCH 1102/1461] crypto-common v0.2.0-pre.1 (#1433) --- Cargo.lock | 12 ++++++------ aead/Cargo.toml | 2 +- cipher/Cargo.toml | 2 +- crypto-common/Cargo.toml | 2 +- digest/Cargo.toml | 2 +- universal-hash/Cargo.toml | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2e5c16071..9d3b3e312 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,7 +19,7 @@ dependencies = [ "arrayvec", "blobby", "bytes", - "crypto-common 0.2.0-pre", + "crypto-common 0.2.0-pre.1", "heapless", ] @@ -129,7 +129,7 @@ name = "block-buffer" version = "0.11.0-pre" source = "git+https://github.com/RustCrypto/utils.git#314938fe8e16d55979e70d777f90a475abcfb7f4" dependencies = [ - "crypto-common 0.2.0-pre", + "crypto-common 0.2.0-pre.1", ] [[package]] @@ -217,7 +217,7 @@ name = "cipher" version = "0.5.0-pre" dependencies = [ "blobby", - "crypto-common 0.2.0-pre", + "crypto-common 0.2.0-pre.1", "inout 0.2.0-pre", "zeroize", ] @@ -306,7 +306,7 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.2.0-pre" +version = "0.2.0-pre.1" dependencies = [ "getrandom", "hybrid-array", @@ -401,7 +401,7 @@ dependencies = [ "blobby", "block-buffer 0.11.0-pre", "const-oid 0.9.6", - "crypto-common 0.2.0-pre", + "crypto-common 0.2.0-pre.1", "subtle", ] @@ -1188,7 +1188,7 @@ dependencies = [ name = "universal-hash" version = "0.6.0-pre" dependencies = [ - "crypto-common 0.2.0-pre", + "crypto-common 0.2.0-pre.1", "subtle", ] diff --git a/aead/Cargo.toml b/aead/Cargo.toml index 75f112b52..bb4b0be1c 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -16,7 +16,7 @@ categories = ["cryptography", "no-std"] rust-version = "1.65" [dependencies] -crypto-common = "=0.2.0-pre" +crypto-common = "=0.2.0-pre.1" # optional dependencies arrayvec = { version = "0.7", optional = true, default-features = false } diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index 1fb08c1e3..03b10c425 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -13,7 +13,7 @@ keywords = ["crypto", "block-cipher", "stream-cipher", "trait"] categories = ["cryptography", "no-std"] [dependencies] -crypto-common = "=0.2.0-pre" +crypto-common = "=0.2.0-pre.1" inout = "=0.2.0-pre" # optional dependencies diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index 0e1e8fd31..bb82334cc 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crypto-common" description = "Common cryptographic traits" -version = "0.2.0-pre" +version = "0.2.0-pre.1" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 261494a01..01be4dd81 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -13,7 +13,7 @@ keywords = ["digest", "crypto", "hash"] categories = ["cryptography", "no-std"] [dependencies] -crypto-common = "=0.2.0-pre" +crypto-common = "=0.2.0-pre.1" # optional dependencies block-buffer = { version = "=0.11.0-pre", optional = true } diff --git a/universal-hash/Cargo.toml b/universal-hash/Cargo.toml index a2786ecc9..e1173e1f1 100644 --- a/universal-hash/Cargo.toml +++ b/universal-hash/Cargo.toml @@ -13,7 +13,7 @@ keywords = ["crypto", "mac"] categories = ["cryptography", "no-std"] [dependencies] -crypto-common = "=0.2.0-pre" +crypto-common = "=0.2.0-pre.1" subtle = { version = "2.4", default-features = false } [features] From ea9f8a3ded8137ce3d8729b165bc4d413cc52486 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 29 Dec 2023 19:59:20 -0700 Subject: [PATCH 1103/1461] Use util crate prereleases (#1434) Switches to the following prereleases: - `block-buffer` v0.11.0-pre.1 - `inout` v0.4.0-pre.1 --- Cargo.lock | 42 ++++++++++++++++++++++++++++-------------- Cargo.toml | 5 ----- cipher/Cargo.toml | 2 +- digest/Cargo.toml | 2 +- 4 files changed, 30 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9d3b3e312..cf1a6572b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,7 +19,7 @@ dependencies = [ "arrayvec", "blobby", "bytes", - "crypto-common 0.2.0-pre.1", + "crypto-common 0.2.0-pre.1 (registry+https://github.com/rust-lang/crates.io-index)", "heapless", ] @@ -126,10 +126,11 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.11.0-pre" -source = "git+https://github.com/RustCrypto/utils.git#314938fe8e16d55979e70d777f90a475abcfb7f4" +version = "0.11.0-pre.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1333cbcd5375733783541e609d067fdfc8285c13b2f0363c878091a4abe7fa5f" dependencies = [ - "crypto-common 0.2.0-pre.1", + "crypto-common 0.2.0-pre.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -143,8 +144,9 @@ dependencies = [ [[package]] name = "block-padding" -version = "0.4.0-pre" -source = "git+https://github.com/RustCrypto/utils.git#314938fe8e16d55979e70d777f90a475abcfb7f4" +version = "0.4.0-pre.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6567958fbc0870d817afa281e82d557ce2c7ccc5c056cbf71ff3558a6e5a2a08" dependencies = [ "hybrid-array", ] @@ -217,8 +219,8 @@ name = "cipher" version = "0.5.0-pre" dependencies = [ "blobby", - "crypto-common 0.2.0-pre.1", - "inout 0.2.0-pre", + "crypto-common 0.2.0-pre.1 (registry+https://github.com/rust-lang/crates.io-index)", + "inout 0.2.0-pre.1", "zeroize", ] @@ -313,6 +315,17 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "crypto-common" +version = "0.2.0-pre.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47bf010313404f942f7da6931d00bd455bb4c36c36c9d4dd9497b5ac316f6fe1" +dependencies = [ + "getrandom", + "hybrid-array", + "rand_core 0.6.4", +] + [[package]] name = "crypto-mac" version = "0.11.0" @@ -399,9 +412,9 @@ name = "digest" version = "0.11.0-pre" dependencies = [ "blobby", - "block-buffer 0.11.0-pre", + "block-buffer 0.11.0-pre.1", "const-oid 0.9.6", - "crypto-common 0.2.0-pre.1", + "crypto-common 0.2.0-pre.1 (registry+https://github.com/rust-lang/crates.io-index)", "subtle", ] @@ -699,10 +712,11 @@ dependencies = [ [[package]] name = "inout" -version = "0.2.0-pre" -source = "git+https://github.com/RustCrypto/utils.git#314938fe8e16d55979e70d777f90a475abcfb7f4" +version = "0.2.0-pre.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eed415a0622334b6e89f6361616b133f5ca2a8a31c5007ca594d9180e5930ec8" dependencies = [ - "block-padding 0.4.0-pre", + "block-padding 0.4.0-pre.1", "hybrid-array", ] @@ -1188,7 +1202,7 @@ dependencies = [ name = "universal-hash" version = "0.6.0-pre" dependencies = [ - "crypto-common 0.2.0-pre.1", + "crypto-common 0.2.0-pre.1 (registry+https://github.com/rust-lang/crates.io-index)", "subtle", ] diff --git a/Cargo.toml b/Cargo.toml index d668c3eda..a15d8c30d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,8 +14,3 @@ members = [ "signature_derive", "universal-hash", ] - -[patch.crates-io] -block-buffer = { git = "https://github.com/RustCrypto/utils.git" } -crypto-common = { path = "crypto-common" } -inout = { git = "https://github.com/RustCrypto/utils.git" } diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index 03b10c425..4111bacff 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -14,7 +14,7 @@ categories = ["cryptography", "no-std"] [dependencies] crypto-common = "=0.2.0-pre.1" -inout = "=0.2.0-pre" +inout = "=0.2.0-pre.1" # optional dependencies blobby = { version = "0.3", optional = true } diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 01be4dd81..07d535ac0 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -16,7 +16,7 @@ categories = ["cryptography", "no-std"] crypto-common = "=0.2.0-pre.1" # optional dependencies -block-buffer = { version = "=0.11.0-pre", optional = true } +block-buffer = { version = "=0.11.0-pre.1", optional = true } subtle = { version = "2.4", default-features = false, optional = true } blobby = { version = "0.3", optional = true } const-oid = { version = "0.9", optional = true } From d64c0fddcf765ace0eb4ed766366868372b7233d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 30 Dec 2023 21:02:30 -0700 Subject: [PATCH 1104/1461] Bump `hybrid-array` to v0.2.0-pre.7 (#1435) --- Cargo.lock | 31 +++++++++---------------------- Cargo.toml | 4 ++++ crypto-common/Cargo.toml | 2 +- 3 files changed, 14 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cf1a6572b..53bb6be52 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,7 +19,7 @@ dependencies = [ "arrayvec", "blobby", "bytes", - "crypto-common 0.2.0-pre.1 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.2.0-pre.1", "heapless", ] @@ -130,7 +130,7 @@ version = "0.11.0-pre.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1333cbcd5375733783541e609d067fdfc8285c13b2f0363c878091a4abe7fa5f" dependencies = [ - "crypto-common 0.2.0-pre.1 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.2.0-pre.1", ] [[package]] @@ -145,8 +145,7 @@ dependencies = [ [[package]] name = "block-padding" version = "0.4.0-pre.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6567958fbc0870d817afa281e82d557ce2c7ccc5c056cbf71ff3558a6e5a2a08" +source = "git+https://github.com/RustCrypto/utils.git#5144cec5a1bbe34616d6c08a7775088fa56cace5" dependencies = [ "hybrid-array", ] @@ -219,7 +218,7 @@ name = "cipher" version = "0.5.0-pre" dependencies = [ "blobby", - "crypto-common 0.2.0-pre.1 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.2.0-pre.1", "inout 0.2.0-pre.1", "zeroize", ] @@ -315,17 +314,6 @@ dependencies = [ "rand_core 0.6.4", ] -[[package]] -name = "crypto-common" -version = "0.2.0-pre.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47bf010313404f942f7da6931d00bd455bb4c36c36c9d4dd9497b5ac316f6fe1" -dependencies = [ - "getrandom", - "hybrid-array", - "rand_core 0.6.4", -] - [[package]] name = "crypto-mac" version = "0.11.0" @@ -414,7 +402,7 @@ dependencies = [ "blobby", "block-buffer 0.11.0-pre.1", "const-oid 0.9.6", - "crypto-common 0.2.0-pre.1 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.2.0-pre.1", "subtle", ] @@ -693,9 +681,9 @@ dependencies = [ [[package]] name = "hybrid-array" -version = "0.2.0-pre.6" +version = "0.2.0-pre.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f148d5add3c53ebf18452f556b0437d3d5c4540f34eb7b80c5ad4b54632c4e2" +checksum = "c23513baf3d4dec43f51f0d5793d9f3058d909040a0130f86c53c4a340fcad05" dependencies = [ "typenum", ] @@ -713,8 +701,7 @@ dependencies = [ [[package]] name = "inout" version = "0.2.0-pre.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eed415a0622334b6e89f6361616b133f5ca2a8a31c5007ca594d9180e5930ec8" +source = "git+https://github.com/RustCrypto/utils.git#5144cec5a1bbe34616d6c08a7775088fa56cace5" dependencies = [ "block-padding 0.4.0-pre.1", "hybrid-array", @@ -1202,7 +1189,7 @@ dependencies = [ name = "universal-hash" version = "0.6.0-pre" dependencies = [ - "crypto-common 0.2.0-pre.1 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.2.0-pre.1", "subtle", ] diff --git a/Cargo.toml b/Cargo.toml index a15d8c30d..9d04852c9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,3 +14,7 @@ members = [ "signature_derive", "universal-hash", ] + +[patch.crates-io] +crypto-common = { path = "crypto-common" } +inout = { git = "https://github.com/RustCrypto/utils.git" } diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index bb82334cc..591583b99 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -13,7 +13,7 @@ keywords = ["crypto", "traits"] categories = ["cryptography", "no-std"] [dependencies] -hybrid-array = "=0.2.0-pre.6" +hybrid-array = "=0.2.0-pre.7" # optional dependencies rand_core = { version = "0.6.4", optional = true } From 48c2c120ca45b497c0bfcfa05069d32a7202ea75 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 30 Dec 2023 21:16:34 -0700 Subject: [PATCH 1105/1461] crypto-common v0.2.0-pre.2 (#1436) --- Cargo.lock | 19 +++++++++---------- Cargo.toml | 3 ++- aead/Cargo.toml | 2 +- cipher/Cargo.toml | 2 +- crypto-common/Cargo.toml | 2 +- digest/Cargo.toml | 2 +- universal-hash/Cargo.toml | 2 +- 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 53bb6be52..e4a7c2129 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,7 +19,7 @@ dependencies = [ "arrayvec", "blobby", "bytes", - "crypto-common 0.2.0-pre.1", + "crypto-common 0.2.0-pre.2", "heapless", ] @@ -127,10 +127,9 @@ dependencies = [ [[package]] name = "block-buffer" version = "0.11.0-pre.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1333cbcd5375733783541e609d067fdfc8285c13b2f0363c878091a4abe7fa5f" +source = "git+https://github.com/RustCrypto/utils.git?branch=crypto-common/v0.2.0-pre.2#1bf05ff2cf2019684be6c1478fb56d5efb21f5e1" dependencies = [ - "crypto-common 0.2.0-pre.1", + "crypto-common 0.2.0-pre.2", ] [[package]] @@ -145,7 +144,7 @@ dependencies = [ [[package]] name = "block-padding" version = "0.4.0-pre.1" -source = "git+https://github.com/RustCrypto/utils.git#5144cec5a1bbe34616d6c08a7775088fa56cace5" +source = "git+https://github.com/RustCrypto/utils.git?branch=crypto-common/v0.2.0-pre.2#1bf05ff2cf2019684be6c1478fb56d5efb21f5e1" dependencies = [ "hybrid-array", ] @@ -218,7 +217,7 @@ name = "cipher" version = "0.5.0-pre" dependencies = [ "blobby", - "crypto-common 0.2.0-pre.1", + "crypto-common 0.2.0-pre.2", "inout 0.2.0-pre.1", "zeroize", ] @@ -307,7 +306,7 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.2.0-pre.1" +version = "0.2.0-pre.2" dependencies = [ "getrandom", "hybrid-array", @@ -402,7 +401,7 @@ dependencies = [ "blobby", "block-buffer 0.11.0-pre.1", "const-oid 0.9.6", - "crypto-common 0.2.0-pre.1", + "crypto-common 0.2.0-pre.2", "subtle", ] @@ -701,7 +700,7 @@ dependencies = [ [[package]] name = "inout" version = "0.2.0-pre.1" -source = "git+https://github.com/RustCrypto/utils.git#5144cec5a1bbe34616d6c08a7775088fa56cace5" +source = "git+https://github.com/RustCrypto/utils.git?branch=crypto-common/v0.2.0-pre.2#1bf05ff2cf2019684be6c1478fb56d5efb21f5e1" dependencies = [ "block-padding 0.4.0-pre.1", "hybrid-array", @@ -1189,7 +1188,7 @@ dependencies = [ name = "universal-hash" version = "0.6.0-pre" dependencies = [ - "crypto-common 0.2.0-pre.1", + "crypto-common 0.2.0-pre.2", "subtle", ] diff --git a/Cargo.toml b/Cargo.toml index 9d04852c9..5a71244de 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,5 +16,6 @@ members = [ ] [patch.crates-io] +block-buffer = { git = "https://github.com/RustCrypto/utils.git", branch = "crypto-common/v0.2.0-pre.2" } crypto-common = { path = "crypto-common" } -inout = { git = "https://github.com/RustCrypto/utils.git" } +inout = { git = "https://github.com/RustCrypto/utils.git", branch = "crypto-common/v0.2.0-pre.2" } diff --git a/aead/Cargo.toml b/aead/Cargo.toml index bb4b0be1c..2549c40da 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -16,7 +16,7 @@ categories = ["cryptography", "no-std"] rust-version = "1.65" [dependencies] -crypto-common = "=0.2.0-pre.1" +crypto-common = "=0.2.0-pre.2" # optional dependencies arrayvec = { version = "0.7", optional = true, default-features = false } diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index 4111bacff..11959cd51 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -13,7 +13,7 @@ keywords = ["crypto", "block-cipher", "stream-cipher", "trait"] categories = ["cryptography", "no-std"] [dependencies] -crypto-common = "=0.2.0-pre.1" +crypto-common = "=0.2.0-pre.2" inout = "=0.2.0-pre.1" # optional dependencies diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index 591583b99..8fe78d37e 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crypto-common" description = "Common cryptographic traits" -version = "0.2.0-pre.1" +version = "0.2.0-pre.2" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 07d535ac0..1102dfd44 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -13,7 +13,7 @@ keywords = ["digest", "crypto", "hash"] categories = ["cryptography", "no-std"] [dependencies] -crypto-common = "=0.2.0-pre.1" +crypto-common = "=0.2.0-pre.2" # optional dependencies block-buffer = { version = "=0.11.0-pre.1", optional = true } diff --git a/universal-hash/Cargo.toml b/universal-hash/Cargo.toml index e1173e1f1..fac9f06ee 100644 --- a/universal-hash/Cargo.toml +++ b/universal-hash/Cargo.toml @@ -13,7 +13,7 @@ keywords = ["crypto", "mac"] categories = ["cryptography", "no-std"] [dependencies] -crypto-common = "=0.2.0-pre.1" +crypto-common = "=0.2.0-pre.2" subtle = { version = "2.4", default-features = false } [features] From 6810dc1dcfe9949f2f2e8e6f3e077737b97c06f1 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 30 Dec 2023 21:48:18 -0700 Subject: [PATCH 1106/1461] Bump RustCrypto/utils crate dependencies (#1437) Bumps the following crate dependencies: - `block-buffer` v0.11.0-pre.2 - `inout` v0.2.0-pre.2 --- Cargo.lock | 42 ++++++++++++++++++++++++++++-------------- Cargo.toml | 5 ----- cipher/Cargo.toml | 2 +- digest/Cargo.toml | 2 +- 4 files changed, 30 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e4a7c2129..f8a6fb656 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,7 +19,7 @@ dependencies = [ "arrayvec", "blobby", "bytes", - "crypto-common 0.2.0-pre.2", + "crypto-common 0.2.0-pre.2 (registry+https://github.com/rust-lang/crates.io-index)", "heapless", ] @@ -126,10 +126,11 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.11.0-pre.1" -source = "git+https://github.com/RustCrypto/utils.git?branch=crypto-common/v0.2.0-pre.2#1bf05ff2cf2019684be6c1478fb56d5efb21f5e1" +version = "0.11.0-pre.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a601d94c4c47c51a046b82b883fe236e5750c0da327dd1427c8b4416296418a" dependencies = [ - "crypto-common 0.2.0-pre.2", + "crypto-common 0.2.0-pre.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -143,8 +144,9 @@ dependencies = [ [[package]] name = "block-padding" -version = "0.4.0-pre.1" -source = "git+https://github.com/RustCrypto/utils.git?branch=crypto-common/v0.2.0-pre.2#1bf05ff2cf2019684be6c1478fb56d5efb21f5e1" +version = "0.4.0-pre.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3ca9ee1904d68460570331f2a93a099ee16b234cfc44ce1908717c5f2c8d3c6" dependencies = [ "hybrid-array", ] @@ -217,8 +219,8 @@ name = "cipher" version = "0.5.0-pre" dependencies = [ "blobby", - "crypto-common 0.2.0-pre.2", - "inout 0.2.0-pre.1", + "crypto-common 0.2.0-pre.2 (registry+https://github.com/rust-lang/crates.io-index)", + "inout 0.2.0-pre.2", "zeroize", ] @@ -313,6 +315,17 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "crypto-common" +version = "0.2.0-pre.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "102f7900795d54e3b8566857762a2977c267ab5952e4117283017ee1d5c9ae88" +dependencies = [ + "getrandom", + "hybrid-array", + "rand_core 0.6.4", +] + [[package]] name = "crypto-mac" version = "0.11.0" @@ -399,9 +412,9 @@ name = "digest" version = "0.11.0-pre" dependencies = [ "blobby", - "block-buffer 0.11.0-pre.1", + "block-buffer 0.11.0-pre.2", "const-oid 0.9.6", - "crypto-common 0.2.0-pre.2", + "crypto-common 0.2.0-pre.2 (registry+https://github.com/rust-lang/crates.io-index)", "subtle", ] @@ -699,10 +712,11 @@ dependencies = [ [[package]] name = "inout" -version = "0.2.0-pre.1" -source = "git+https://github.com/RustCrypto/utils.git?branch=crypto-common/v0.2.0-pre.2#1bf05ff2cf2019684be6c1478fb56d5efb21f5e1" +version = "0.2.0-pre.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25049cbfd794227f26a7d3c7f2cfc2a9737a229993799bfca1138242964886ee" dependencies = [ - "block-padding 0.4.0-pre.1", + "block-padding 0.4.0-pre.2", "hybrid-array", ] @@ -1188,7 +1202,7 @@ dependencies = [ name = "universal-hash" version = "0.6.0-pre" dependencies = [ - "crypto-common 0.2.0-pre.2", + "crypto-common 0.2.0-pre.2 (registry+https://github.com/rust-lang/crates.io-index)", "subtle", ] diff --git a/Cargo.toml b/Cargo.toml index 5a71244de..a15d8c30d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,8 +14,3 @@ members = [ "signature_derive", "universal-hash", ] - -[patch.crates-io] -block-buffer = { git = "https://github.com/RustCrypto/utils.git", branch = "crypto-common/v0.2.0-pre.2" } -crypto-common = { path = "crypto-common" } -inout = { git = "https://github.com/RustCrypto/utils.git", branch = "crypto-common/v0.2.0-pre.2" } diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index 11959cd51..c611dce96 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -14,7 +14,7 @@ categories = ["cryptography", "no-std"] [dependencies] crypto-common = "=0.2.0-pre.2" -inout = "=0.2.0-pre.1" +inout = "=0.2.0-pre.2" # optional dependencies blobby = { version = "0.3", optional = true } diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 1102dfd44..503224f54 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -16,7 +16,7 @@ categories = ["cryptography", "no-std"] crypto-common = "=0.2.0-pre.2" # optional dependencies -block-buffer = { version = "=0.11.0-pre.1", optional = true } +block-buffer = { version = "=0.11.0-pre.2", optional = true } subtle = { version = "2.4", default-features = false, optional = true } blobby = { version = "0.3", optional = true } const-oid = { version = "0.9", optional = true } From e36243ee7624243a668ec7f233adccb216afcc41 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 31 Dec 2023 16:14:46 -0700 Subject: [PATCH 1107/1461] Bump `hybrid-array` to v0.2.0-pre.8 (#1438) --- Cargo.lock | 38 +++++++++++------------ aead/Cargo.toml | 2 +- cipher/Cargo.toml | 4 +-- crypto-common/Cargo.lock | 64 +++++++++++++++++++++++++++++++++++++++ crypto-common/Cargo.toml | 4 +-- digest/Cargo.toml | 4 +-- universal-hash/Cargo.toml | 2 +- 7 files changed, 91 insertions(+), 27 deletions(-) create mode 100644 crypto-common/Cargo.lock diff --git a/Cargo.lock b/Cargo.lock index f8a6fb656..8d73c825b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,7 +19,7 @@ dependencies = [ "arrayvec", "blobby", "bytes", - "crypto-common 0.2.0-pre.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.2.0-pre.3 (registry+https://github.com/rust-lang/crates.io-index)", "heapless", ] @@ -126,11 +126,11 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.11.0-pre.2" +version = "0.11.0-pre.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a601d94c4c47c51a046b82b883fe236e5750c0da327dd1427c8b4416296418a" +checksum = "72bc448e41b30773616b4f51a23f1a51634d41ce0d06a9bf6c3065ee85e227a1" dependencies = [ - "crypto-common 0.2.0-pre.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.2.0-pre.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -144,9 +144,9 @@ dependencies = [ [[package]] name = "block-padding" -version = "0.4.0-pre.2" +version = "0.4.0-pre.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3ca9ee1904d68460570331f2a93a099ee16b234cfc44ce1908717c5f2c8d3c6" +checksum = "d07a359e2b51a0e9b9d6a6d4582b7b62723e4a25f4e5ca6be70a6a00050202ab" dependencies = [ "hybrid-array", ] @@ -219,8 +219,8 @@ name = "cipher" version = "0.5.0-pre" dependencies = [ "blobby", - "crypto-common 0.2.0-pre.2 (registry+https://github.com/rust-lang/crates.io-index)", - "inout 0.2.0-pre.2", + "crypto-common 0.2.0-pre.3 (registry+https://github.com/rust-lang/crates.io-index)", + "inout 0.2.0-pre.3", "zeroize", ] @@ -308,7 +308,7 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.2.0-pre.2" +version = "0.2.0-pre.3" dependencies = [ "getrandom", "hybrid-array", @@ -317,9 +317,9 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.2.0-pre.2" +version = "0.2.0-pre.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "102f7900795d54e3b8566857762a2977c267ab5952e4117283017ee1d5c9ae88" +checksum = "cc17eb697364b18256ec92675ebe6b7b153d2f1041e568d74533c5d0fc1ca162" dependencies = [ "getrandom", "hybrid-array", @@ -412,9 +412,9 @@ name = "digest" version = "0.11.0-pre" dependencies = [ "blobby", - "block-buffer 0.11.0-pre.2", + "block-buffer 0.11.0-pre.3", "const-oid 0.9.6", - "crypto-common 0.2.0-pre.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.2.0-pre.3 (registry+https://github.com/rust-lang/crates.io-index)", "subtle", ] @@ -693,9 +693,9 @@ dependencies = [ [[package]] name = "hybrid-array" -version = "0.2.0-pre.7" +version = "0.2.0-pre.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c23513baf3d4dec43f51f0d5793d9f3058d909040a0130f86c53c4a340fcad05" +checksum = "27fbaf242418fe980caf09ed348d5a6aeabe71fc1bd8bebad641f4591ae0a46d" dependencies = [ "typenum", ] @@ -712,11 +712,11 @@ dependencies = [ [[package]] name = "inout" -version = "0.2.0-pre.2" +version = "0.2.0-pre.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25049cbfd794227f26a7d3c7f2cfc2a9737a229993799bfca1138242964886ee" +checksum = "96ea9986e1fde8d177cd039f00f9f316d3bfce9ebc2787c1267d4414adf3acb3" dependencies = [ - "block-padding 0.4.0-pre.2", + "block-padding 0.4.0-pre.3", "hybrid-array", ] @@ -1202,7 +1202,7 @@ dependencies = [ name = "universal-hash" version = "0.6.0-pre" dependencies = [ - "crypto-common 0.2.0-pre.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.2.0-pre.3 (registry+https://github.com/rust-lang/crates.io-index)", "subtle", ] diff --git a/aead/Cargo.toml b/aead/Cargo.toml index 2549c40da..e69d1df0e 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -16,7 +16,7 @@ categories = ["cryptography", "no-std"] rust-version = "1.65" [dependencies] -crypto-common = "=0.2.0-pre.2" +crypto-common = "=0.2.0-pre.3" # optional dependencies arrayvec = { version = "0.7", optional = true, default-features = false } diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index c611dce96..7f3f5dbb6 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -13,8 +13,8 @@ keywords = ["crypto", "block-cipher", "stream-cipher", "trait"] categories = ["cryptography", "no-std"] [dependencies] -crypto-common = "=0.2.0-pre.2" -inout = "=0.2.0-pre.2" +crypto-common = "=0.2.0-pre.3" +inout = "=0.2.0-pre.3" # optional dependencies blobby = { version = "0.3", optional = true } diff --git a/crypto-common/Cargo.lock b/crypto-common/Cargo.lock new file mode 100644 index 000000000..cf1f569a7 --- /dev/null +++ b/crypto-common/Cargo.lock @@ -0,0 +1,64 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "crypto-common" +version = "0.2.0-pre.3" +dependencies = [ + "getrandom", + "hybrid-array", + "rand_core", +] + +[[package]] +name = "getrandom" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "hybrid-array" +version = "0.2.0-pre.8" +source = "git+https://github.com/RustCrypto/utils.git?branch=hybrid-array/v0.2.0-pre.8#eac3be7a9c959152b37d6c51e1aaf2f44e9c2c40" +dependencies = [ + "typenum", +] + +[[package]] +name = "libc" +version = "0.2.151" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index 8fe78d37e..d66059f05 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crypto-common" description = "Common cryptographic traits" -version = "0.2.0-pre.2" +version = "0.2.0-pre.3" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" @@ -13,7 +13,7 @@ keywords = ["crypto", "traits"] categories = ["cryptography", "no-std"] [dependencies] -hybrid-array = "=0.2.0-pre.7" +hybrid-array = "=0.2.0-pre.8" # optional dependencies rand_core = { version = "0.6.4", optional = true } diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 503224f54..00b1e0aa6 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -13,10 +13,10 @@ keywords = ["digest", "crypto", "hash"] categories = ["cryptography", "no-std"] [dependencies] -crypto-common = "=0.2.0-pre.2" +crypto-common = "=0.2.0-pre.3" # optional dependencies -block-buffer = { version = "=0.11.0-pre.2", optional = true } +block-buffer = { version = "=0.11.0-pre.3", optional = true } subtle = { version = "2.4", default-features = false, optional = true } blobby = { version = "0.3", optional = true } const-oid = { version = "0.9", optional = true } diff --git a/universal-hash/Cargo.toml b/universal-hash/Cargo.toml index fac9f06ee..9ddc4c06b 100644 --- a/universal-hash/Cargo.toml +++ b/universal-hash/Cargo.toml @@ -13,7 +13,7 @@ keywords = ["crypto", "mac"] categories = ["cryptography", "no-std"] [dependencies] -crypto-common = "=0.2.0-pre.2" +crypto-common = "=0.2.0-pre.3" subtle = { version = "2.4", default-features = false } [features] From 0c0c3ef9afd75f60cfd725f0b65dd7ceaacd588d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 2 Jan 2024 17:01:08 -0700 Subject: [PATCH 1108/1461] digest v0.11.0-pre.1 (#1447) --- Cargo.lock | 2 +- digest/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8d73c825b..8cbe283dc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -409,7 +409,7 @@ dependencies = [ [[package]] name = "digest" -version = "0.11.0-pre" +version = "0.11.0-pre.1" dependencies = [ "blobby", "block-buffer 0.11.0-pre.3", diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 00b1e0aa6..1e082df6b 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "digest" description = "Traits for cryptographic hash functions and message authentication codes" -version = "0.11.0-pre" +version = "0.11.0-pre.1" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" From 3dc7c13cfd7211e345436caf88d8a109a923300f Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 2 Jan 2024 18:34:41 -0700 Subject: [PATCH 1109/1461] async-signature v0.5.0 (#1449) --- Cargo.lock | 2 +- async-signature/CHANGELOG.md | 14 ++++++++++++++ async-signature/Cargo.toml | 2 +- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8cbe283dc..b6e5339d1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -56,7 +56,7 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "async-signature" -version = "0.5.0-pre.0" +version = "0.5.0" dependencies = [ "signature 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/async-signature/CHANGELOG.md b/async-signature/CHANGELOG.md index 861489b28..b7d7aac4f 100644 --- a/async-signature/CHANGELOG.md +++ b/async-signature/CHANGELOG.md @@ -4,6 +4,20 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.5.0 (2024-01-02) +### Added +- Debug impls ([#1407]) + +### Changed +- Move to AFIT; MSRV 1.75 ([#1428]) + +### Removed +- `'static` bounds ([#1430]) + +[#1407]: https://github.com/RustCrypto/traits/pull/1407 +[#1428]: https://github.com/RustCrypto/traits/pull/1428 +[#1430]: https://github.com/RustCrypto/traits/pull/1430 + ## 0.4.0 (2023-11-12) ### Changed - MSRV 1.60 ([#1387]) diff --git a/async-signature/Cargo.toml b/async-signature/Cargo.toml index eea5ab4ba..e78488d29 100644 --- a/async-signature/Cargo.toml +++ b/async-signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "async-signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "0.5.0-pre.0" +version = "0.5.0" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/async-signature" From afb9092d1f79c88a1cb1769fd61b9ac386445840 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 3 Jan 2024 15:31:53 -0700 Subject: [PATCH 1110/1461] digest: bump `const-oid` dependency to v0.10.0-pre.1 (#1450) --- Cargo.lock | 8 +++++++- digest/Cargo.toml | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b6e5339d1..33e439d7f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -236,6 +236,12 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +[[package]] +name = "const-oid" +version = "0.10.0-pre.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841f6ba1e33a9397e31342ace4d3ba1c9a16493d0f4c7d1e7d56fc146f7e147a" + [[package]] name = "cpufeatures" version = "0.2.11" @@ -413,7 +419,7 @@ version = "0.11.0-pre.1" dependencies = [ "blobby", "block-buffer 0.11.0-pre.3", - "const-oid 0.9.6", + "const-oid 0.10.0-pre.1", "crypto-common 0.2.0-pre.3 (registry+https://github.com/rust-lang/crates.io-index)", "subtle", ] diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 1e082df6b..e677406f0 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -19,7 +19,7 @@ crypto-common = "=0.2.0-pre.3" block-buffer = { version = "=0.11.0-pre.3", optional = true } subtle = { version = "2.4", default-features = false, optional = true } blobby = { version = "0.3", optional = true } -const-oid = { version = "0.9", optional = true } +const-oid = { version = "=0.10.0-pre.1", optional = true } [features] default = ["core-api"] From a897f41b8310125394b523e4e8b0e5bfdd584fcf Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 3 Jan 2024 15:42:01 -0700 Subject: [PATCH 1111/1461] digest v0.11.0-pre.2 (#1451) --- Cargo.lock | 2 +- digest/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 33e439d7f..3cd4a8df4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -415,7 +415,7 @@ dependencies = [ [[package]] name = "digest" -version = "0.11.0-pre.1" +version = "0.11.0-pre.2" dependencies = [ "blobby", "block-buffer 0.11.0-pre.3", diff --git a/digest/Cargo.toml b/digest/Cargo.toml index e677406f0..bd4eb4a08 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "digest" description = "Traits for cryptographic hash functions and message authentication codes" -version = "0.11.0-pre.1" +version = "0.11.0-pre.2" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" From 77445d19af181989c394c68cdad992b2dd62a86d Mon Sep 17 00:00:00 2001 From: lmaotrigine <57328245+lmaotrigine@users.noreply.github.com> Date: Fri, 5 Jan 2024 01:54:21 +0530 Subject: [PATCH 1112/1461] cipher: fix bugs in `StreamCipherCoreWrapper` trait implementaitons (#1421) --- cipher/src/stream_wrapper.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/cipher/src/stream_wrapper.rs b/cipher/src/stream_wrapper.rs index 1002ced0f..626b4e3d0 100644 --- a/cipher/src/stream_wrapper.rs +++ b/cipher/src/stream_wrapper.rs @@ -157,7 +157,7 @@ impl StreamCipher for StreamCipherCoreWrapper { // but after XORing keystream block with `tail`, we immediately // overwrite the first byte with a correct value. self.core.write_keystream_block(&mut self.buffer); - tail.xor_in2out(&self.buffer[..data_len]); + tail.xor_in2out(&self.buffer[..tail.len()]); tail.len() }; @@ -219,9 +219,11 @@ impl IvSizeUser for StreamCipherCoreWrapper impl KeyIvInit for StreamCipherCoreWrapper { #[inline] fn new(key: &Key, iv: &Iv) -> Self { + let mut buffer = Block::::default(); + buffer[0] = T::BlockSize::U8; Self { core: T::new(key, iv), - buffer: Default::default(), + buffer, } } } @@ -229,9 +231,11 @@ impl KeyIvInit for StreamCipherCoreWrapper { impl KeyInit for StreamCipherCoreWrapper { #[inline] fn new(key: &Key) -> Self { + let mut buffer = Block::::default(); + buffer[0] = T::BlockSize::U8; Self { core: T::new(key), - buffer: Default::default(), + buffer, } } } From 14ff0597110a5ba81ba7c663df7cc42d6d6d7580 Mon Sep 17 00:00:00 2001 From: Tjaden Hess Date: Fri, 5 Jan 2024 10:47:29 -0600 Subject: [PATCH 1113/1461] signature: define a `RandomizedSignerMut` trait (#1448) This is useful for e.g. LMS / LM-OTS signatures, which are stateful and randomized. --- signature/CHANGELOG.md | 6 ++++++ signature/src/signer.rs | 27 +++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/signature/CHANGELOG.md b/signature/CHANGELOG.md index 3f9d8cd08..554e0f5fd 100644 --- a/signature/CHANGELOG.md +++ b/signature/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased +### Added +- `RandomizedSignerMut` trait + +[#1448](https://github.com/RustCrypto/traits/pull/1448) + ## 2.2.0 (2023-11-12) ### Changed - MSRV 1.60 ([#1387]) diff --git a/signature/src/signer.rs b/signature/src/signer.rs index b339ddf59..488f7da67 100644 --- a/signature/src/signer.rs +++ b/signature/src/signer.rs @@ -116,3 +116,30 @@ pub trait RandomizedDigestSigner { fn try_sign_digest_with_rng(&self, rng: &mut impl CryptoRngCore, digest: D) -> Result; } + +/// Sign the provided message bytestring using `&mut Self` (e.g. an evolving +/// cryptographic key such as a stateful hash-based signature), and a per-signature +/// randomizer, returning a digital signature. +#[cfg(feature = "rand_core")] +pub trait RandomizedSignerMut { + /// Sign the given message, update the state, and return a digital signature. + fn sign_with_rng(&mut self, rng: &mut impl CryptoRngCore, msg: &[u8]) -> S { + self.try_sign_with_rng(rng, msg) + .expect("signature operation failed") + } + + /// Attempt to sign the given message, updating the state, and returning a + /// digital signature on success, or an error if something went wrong. + /// + /// Signing can fail, e.g., if the number of time periods allowed by the + /// current key is exceeded. + fn try_sign_with_rng(&mut self, rng: &mut impl CryptoRngCore, msg: &[u8]) -> Result; +} + +/// Blanket impl of [`RandomizedSignerMut`] for all [`RandomizedSigner`] types. +#[cfg(feature = "rand_core")] +impl> RandomizedSignerMut for T { + fn try_sign_with_rng(&mut self, rng: &mut impl CryptoRngCore, msg: &[u8]) -> Result { + T::try_sign_with_rng(self, rng, msg) + } +} From 3dee5c77507e04ec4022aafac1baaf1de12070e5 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 5 Jan 2024 19:44:37 -0800 Subject: [PATCH 1114/1461] digest: bump `const-oid` dependency to v0.10.0-pre.2 (#1455) Also bumps MSRV to 1.71 to match --- .github/workflows/digest.yml | 4 ++-- Cargo.lock | 6 +++--- digest/Cargo.toml | 4 ++-- digest/README.md | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/digest.yml b/.github/workflows/digest.yml index 3535a1172..be157840c 100644 --- a/.github/workflows/digest.yml +++ b/.github/workflows/digest.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.65.0 # MSRV + - 1.71.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -47,7 +47,7 @@ jobs: strategy: matrix: rust: - - 1.65.0 # MSRV + - 1.71.0 # MSRV - stable steps: - uses: actions/checkout@v4 diff --git a/Cargo.lock b/Cargo.lock index 3cd4a8df4..aaf22291d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -238,9 +238,9 @@ checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "const-oid" -version = "0.10.0-pre.1" +version = "0.10.0-pre.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841f6ba1e33a9397e31342ace4d3ba1c9a16493d0f4c7d1e7d56fc146f7e147a" +checksum = "f7e3352a27098ba6b09546e5f13b15165e6a88b5c2723afecb3ea9576b27e3ea" [[package]] name = "cpufeatures" @@ -419,7 +419,7 @@ version = "0.11.0-pre.2" dependencies = [ "blobby", "block-buffer 0.11.0-pre.3", - "const-oid 0.10.0-pre.1", + "const-oid 0.10.0-pre.2", "crypto-common 0.2.0-pre.3 (registry+https://github.com/rust-lang/crates.io-index)", "subtle", ] diff --git a/digest/Cargo.toml b/digest/Cargo.toml index bd4eb4a08..c7399efaa 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -6,7 +6,7 @@ authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" edition = "2021" -rust-version = "1.65" +rust-version = "1.71" documentation = "https://docs.rs/digest" repository = "https://github.com/RustCrypto/traits" keywords = ["digest", "crypto", "hash"] @@ -19,7 +19,7 @@ crypto-common = "=0.2.0-pre.3" block-buffer = { version = "=0.11.0-pre.3", optional = true } subtle = { version = "2.4", default-features = false, optional = true } blobby = { version = "0.3", optional = true } -const-oid = { version = "=0.10.0-pre.1", optional = true } +const-oid = { version = "=0.10.0-pre.2", optional = true } [features] default = ["core-api"] diff --git a/digest/README.md b/digest/README.md index 3748879a6..479d5c7ed 100644 --- a/digest/README.md +++ b/digest/README.md @@ -16,7 +16,7 @@ See [RustCrypto/hashes][1] for implementations which use this trait. ## Minimum Supported Rust Version -Rust **1.65** or higher. +Rust **1.71** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -147,7 +147,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/digest/badge.svg [docs-link]: https://docs.rs/digest/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.65+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.71+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260041-hashes [build-image]: https://github.com/RustCrypto/traits/workflows/digest/badge.svg?branch=master&event=push From c4101dee17284b8c7788ce8c414e6385c1eadc0d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 5 Jan 2024 19:54:49 -0800 Subject: [PATCH 1115/1461] digest 0.11.0-pre.3 (#1457) --- digest/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/digest/Cargo.toml b/digest/Cargo.toml index c7399efaa..36c62e2ee 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "digest" description = "Traits for cryptographic hash functions and message authentication codes" -version = "0.11.0-pre.2" +version = "0.11.0-pre.3" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" From 9bc2c9be276612ad4c0245fb96569d2071ab142e Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 6 Jan 2024 08:23:42 -0800 Subject: [PATCH 1116/1461] cipher v0.5.0-pre.1 (#1458) --- Cargo.lock | 4 ++-- cipher/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aaf22291d..0a986a077 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -216,7 +216,7 @@ dependencies = [ [[package]] name = "cipher" -version = "0.5.0-pre" +version = "0.5.0-pre.1" dependencies = [ "blobby", "crypto-common 0.2.0-pre.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -415,7 +415,7 @@ dependencies = [ [[package]] name = "digest" -version = "0.11.0-pre.2" +version = "0.11.0-pre.3" dependencies = [ "blobby", "block-buffer 0.11.0-pre.3", diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index 7f3f5dbb6..1968148f4 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "cipher" description = "Traits for describing block ciphers and stream ciphers" -version = "0.5.0-pre" +version = "0.5.0-pre.1" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" From 3a7f39d2a6f4a3f0d7597962e41aa14d5978ea4a Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 6 Jan 2024 09:15:27 -0800 Subject: [PATCH 1117/1461] Cargo.lock: update dependencies (#1459) Updates the following dependencies: $ cargo update Updating crates.io index Updating cpufeatures v0.2.11 -> v0.2.12 Updating proc-macro2 v1.0.71 -> v1.0.76 Updating quote v1.0.33 -> v1.0.35 Updating serde v1.0.193 -> v1.0.195 Updating serde_bytes v0.11.13 -> v0.11.14 Updating serde_derive v1.0.193 -> v1.0.195 Updating serde_json v1.0.108 -> v1.0.111 Updating syn v2.0.43 -> v2.0.48 --- Cargo.lock | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0a986a077..9b64fd972 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -244,9 +244,9 @@ checksum = "f7e3352a27098ba6b09546e5f13b15165e6a88b5c2723afecb3ea9576b27e3ea" [[package]] name = "cpufeatures" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" dependencies = [ "libc", ] @@ -918,18 +918,18 @@ checksum = "94e851c7654eed9e68d7d27164c454961a616cf8c203d500607ef22c737b51bb" [[package]] name = "proc-macro2" -version = "1.0.71" +version = "1.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75cb1540fadbd5b8fbccc4dddad2734eba435053f725621c070711a14bb5f4b8" +checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -1012,27 +1012,27 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.193" +version = "1.0.195" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" dependencies = [ "serde_derive", ] [[package]] name = "serde_bytes" -version = "0.11.13" +version = "0.11.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bb1879ea93538b78549031e2d54da3e901fd7e75f2e4dc758d760937b123d10" +checksum = "8b8497c313fd43ab992087548117643f6fcd935cbf36f176ffda0aacf9591734" dependencies = [ "serde", ] [[package]] name = "serde_derive" -version = "1.0.193" +version = "1.0.195" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" dependencies = [ "proc-macro2", "quote", @@ -1041,9 +1041,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.108" +version = "1.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" dependencies = [ "itoa", "ryu", @@ -1167,9 +1167,9 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "syn" -version = "2.0.43" +version = "2.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee659fb5f3d355364e1f3e5bc10fb82068efbf824a1e9d1c9504244a6469ad53" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" dependencies = [ "proc-macro2", "quote", From a005ddb17051c18f227e3f198117eda5d432893a Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 8 Jan 2024 12:35:00 -0700 Subject: [PATCH 1118/1461] digest: remove lingering `docsrs` attrs (#1460) These were leftover from the migration to `doc_auto_cfg` in #1370. They're breaking the doc build. --- digest/src/dev.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/digest/src/dev.rs b/digest/src/dev.rs index 5ceae41b4..7018e8549 100644 --- a/digest/src/dev.rs +++ b/digest/src/dev.rs @@ -39,7 +39,6 @@ macro_rules! new_test { /// Define hash function serialization test #[macro_export] -#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] macro_rules! hash_serialization_test { ($name:ident, $hasher:ty, $expected_serialized_state:expr) => { #[test] @@ -73,7 +72,6 @@ macro_rules! hash_serialization_test { /// Define hash function serialization test #[macro_export] -#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] macro_rules! hash_rt_outsize_serialization_test { ($name:ident, $hasher:ty, $expected_serialized_state:expr) => { #[test] From cbfdf1dc9be3ac680e92085341c9bedfedbf2bb6 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 8 Jan 2024 15:42:29 -0700 Subject: [PATCH 1119/1461] Bump `password-hash` to v0.6.0-pre (#1461) This is not-for-release, but to signal that we are about to begin making breaking changes. Notably it would be nice to finally land #1352, which adds `ShaCrypt` support and makes the `Encoding` enum `non_exhaustive` so we could potentially add additional encodings in the future without it being a breaking change. --- Cargo.lock | 13 ++++++++++++- crypto/Cargo.toml | 2 +- password-hash/Cargo.toml | 2 +- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9b64fd972..ad9187b0b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -260,7 +260,7 @@ dependencies = [ "crypto-common 0.1.6", "digest 0.10.7", "elliptic-curve 0.13.8", - "password-hash", + "password-hash 0.5.0", "signature 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "universal-hash 0.5.1", ] @@ -800,6 +800,17 @@ dependencies = [ [[package]] name = "password-hash" version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" +dependencies = [ + "base64ct", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "password-hash" +version = "0.6.0-pre" dependencies = [ "base64ct", "rand_core 0.6.4", diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 8f31c6e17..0353295ed 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -20,7 +20,7 @@ aead = { version = "0.5", optional = true } cipher = { version = "0.4", optional = true } digest = { version = "0.10", optional = true, features = ["mac"] } elliptic-curve = { version = "0.13", optional = true, path = "../elliptic-curve" } -password-hash = { version = "0.5", optional = true, path = "../password-hash" } +password-hash = { version = "0.5", optional = true } signature = { version = "2", optional = true, default-features = false } universal-hash = { version = "0.5", optional = true } diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index e98b5ad0c..45ee2f20e 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -5,7 +5,7 @@ Traits which describe the functionality of password hashing algorithms, as well as a `no_std`-friendly implementation of the PHC string format (a well-defined subset of the Modular Crypt Format a.k.a. MCF) """ -version = "0.5.0" +version = "0.6.0-pre" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" From fd48936174e0012aae3e7c99f575e409c0ec6b23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Acier?= Date: Mon, 8 Jan 2024 23:54:04 +0100 Subject: [PATCH 1120/1461] password-hash: add `Encoding::ShaCrypt` (#1352) Adds support for a Base64 variant used by `sha1_crypt`, `sha256_crypt`, `sha512_crypt`, and `md5_crypt`. Uses `base64ct::Base64ShaCrypt` as the backing implementation. Also marks the `Encoding` enum as `#[non_exhaustive]` to allow future additions in a non-breaking manner. --------- Co-authored-by: Tony Arcieri --- password-hash/Cargo.toml | 2 +- password-hash/src/encoding.rs | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index 45ee2f20e..ba2a0feb9 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -17,7 +17,7 @@ edition = "2021" rust-version = "1.60" [dependencies] -base64ct = "1" +base64ct = "1.6" subtle = { version = "2", default-features = false } # optional dependencies diff --git a/password-hash/src/encoding.rs b/password-hash/src/encoding.rs index a2689999c..7e7938f4d 100644 --- a/password-hash/src/encoding.rs +++ b/password-hash/src/encoding.rs @@ -1,11 +1,13 @@ //! Base64 encoding variants. use base64ct::{ - Base64Bcrypt, Base64Crypt, Base64Unpadded as B64, Encoding as _, Error as B64Error, + Base64Bcrypt, Base64Crypt, Base64ShaCrypt, Base64Unpadded as B64, Encoding as _, + Error as B64Error, }; /// Base64 encoding variants. #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] +#[non_exhaustive] pub enum Encoding { /// "B64" encoding: standard Base64 without padding. /// @@ -31,6 +33,15 @@ pub enum Encoding { /// 0x2e-0x39, 0x41-0x5a, 0x61-0x7a /// ``` Crypt, + + /// `crypt(3)` Base64 encoding for the following schemes. + /// - sha1_crypt, + /// - sha256_crypt, + /// - sha512_crypt, + /// - md5_crypt + /// [.-9] [A-Z] [a-z] + /// 0x2e-0x39, 0x41-0x5a, 0x61-0x7a + ShaCrypt, } impl Default for Encoding { @@ -46,6 +57,7 @@ impl Encoding { Self::B64 => B64::decode(src, dst), Self::Bcrypt => Base64Bcrypt::decode(src, dst), Self::Crypt => Base64Crypt::decode(src, dst), + Self::ShaCrypt => Base64ShaCrypt::decode(src, dst), } } @@ -58,6 +70,7 @@ impl Encoding { Self::B64 => B64::encode(src, dst), Self::Bcrypt => Base64Bcrypt::encode(src, dst), Self::Crypt => Base64Crypt::encode(src, dst), + Self::ShaCrypt => Base64ShaCrypt::encode(src, dst), } .map_err(Into::into) } @@ -68,6 +81,7 @@ impl Encoding { Self::B64 => B64::encoded_len(bytes), Self::Bcrypt => Base64Bcrypt::encoded_len(bytes), Self::Crypt => Base64Crypt::encoded_len(bytes), + Self::ShaCrypt => Base64ShaCrypt::encoded_len(bytes), } } } From 1ac412b3d0a1b7b9c8ae2b370a57c097fe13c949 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 9 Jan 2024 07:58:32 -0700 Subject: [PATCH 1121/1461] elliptic-curve: migrate to hybrid-array; MSRV 1.71 (#1462) Migrates from `generic-array` to the `hybrid-array` crate, which provides an `Array` newtype for a public inner core array type, and significantly less unsafe code. Also bumps `digest` and the encoding format crates (`pem-rfc7468`, `pkcs8`, `sec1`), which have also received similar `hybrid-array` upgrades. --- .github/workflows/elliptic-curve.yml | 4 +- Cargo.lock | 132 ++++++++++++++++-- crypto/Cargo.toml | 2 +- elliptic-curve/Cargo.toml | 22 +-- elliptic-curve/README.md | 4 +- elliptic-curve/src/dev.rs | 2 +- elliptic-curve/src/field.rs | 4 +- elliptic-curve/src/hash2curve/hash2field.rs | 8 +- .../src/hash2curve/hash2field/expand_msg.rs | 12 +- .../hash2curve/hash2field/expand_msg/xmd.rs | 26 ++-- .../hash2curve/hash2field/expand_msg/xof.rs | 12 +- elliptic-curve/src/hash2curve/isogeny.rs | 6 +- elliptic-curve/src/lib.rs | 6 +- elliptic-curve/src/scalar/nonzero.rs | 7 +- elliptic-curve/src/scalar/primitive.rs | 9 +- elliptic-curve/src/sec1.rs | 6 +- elliptic-curve/src/secret_key.rs | 8 +- 17 files changed, 184 insertions(+), 86 deletions(-) diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index b99fddd5a..4c8147768 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -24,7 +24,7 @@ jobs: strategy: matrix: rust: - - 1.65.0 # MSRV + - 1.71.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -74,7 +74,7 @@ jobs: strategy: matrix: rust: - - 1.65.0 # MSRV + - 1.71.0 # MSRV - stable - nightly steps: diff --git a/Cargo.lock b/Cargo.lock index ad9187b0b..f4ef242c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -389,7 +389,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" dependencies = [ "const-oid 0.9.6", - "pem-rfc7468 0.7.0", + "zeroize", +] + +[[package]] +name = "der" +version = "0.8.0-pre.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b489fd2221710c1dd46637d66b984161fb66134f81437a8489800306bcc2ecea" +dependencies = [ + "const-oid 0.10.0-pre.2", + "pem-rfc7468 1.0.0-pre.0", "zeroize", ] @@ -424,6 +434,18 @@ dependencies = [ "subtle", ] +[[package]] +name = "digest" +version = "0.11.0-pre.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb3be3c52e023de5662dc05a32f747d09a1d6024fdd1f64b0850e373269efb43" +dependencies = [ + "block-buffer 0.11.0-pre.3", + "const-oid 0.10.0-pre.2", + "crypto-common 0.2.0-pre.3 (registry+https://github.com/rust-lang/crates.io-index)", + "subtle", +] + [[package]] name = "dunce" version = "1.0.4" @@ -481,23 +503,41 @@ dependencies = [ [[package]] name = "elliptic-curve" version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ "base16ct 0.2.0", - "base64ct", "crypto-bigint 0.5.5", - "digest 0.10.7", "ff 0.13.0", "generic-array", "group 0.13.0", - "hex-literal", - "hkdf 0.12.4", - "pem-rfc7468 0.7.0", "pkcs8 0.10.2", "rand_core 0.6.4", "sec1 0.7.3", + "subtle", + "zeroize", +] + +[[package]] +name = "elliptic-curve" +version = "0.14.0-pre" +dependencies = [ + "base16ct 0.2.0", + "base64ct", + "crypto-bigint 0.5.5", + "digest 0.11.0-pre.3 (registry+https://github.com/rust-lang/crates.io-index)", + "ff 0.13.0", + "group 0.13.0", + "hex-literal", + "hkdf 0.13.0-pre.0", + "hybrid-array", + "pem-rfc7468 1.0.0-pre.0", + "pkcs8 0.11.0-pre.0", + "rand_core 0.6.4", + "sec1 0.8.0-pre.0", "serde_json", "serdect", - "sha2 0.10.8", + "sha2 0.11.0-pre.0", "sha3", "subtle", "tap", @@ -656,6 +696,15 @@ dependencies = [ "hmac 0.12.1", ] +[[package]] +name = "hkdf" +version = "0.13.0-pre.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f3bed625061d9ed27cd87356cb46c3c8269a585be23d56c6f179c722bbea471" +dependencies = [ + "hmac 0.13.0-pre.0", +] + [[package]] name = "hmac" version = "0.11.0" @@ -675,6 +724,15 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "hmac" +version = "0.13.0-pre.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e22cb0183a745c3444af57c24aa1293e1f3e538717acce39a9d3b271c999b24f" +dependencies = [ + "digest 0.11.0-pre.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "hpke" version = "0.10.0" @@ -704,6 +762,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "27fbaf242418fe980caf09ed348d5a6aeabe71fc1bd8bebad641f4591ae0a46d" dependencies = [ "typenum", + "zeroize", ] [[package]] @@ -828,9 +887,9 @@ dependencies = [ [[package]] name = "pem-rfc7468" -version = "0.7.0" +version = "1.0.0-pre.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +checksum = "76a65e1c27d1680f8805b3f8c9949f08d6aa5d6cbd088c9896e64a53821dc27d" dependencies = [ "base64ct", ] @@ -857,6 +916,16 @@ dependencies = [ "spki 0.7.3", ] +[[package]] +name = "pkcs8" +version = "0.11.0-pre.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "935c09e0aecb0cb8f8907b57438b19a068cb74a25189b06724f061170b2465ff" +dependencies = [ + "der 0.8.0-pre.0", + "spki 0.8.0-pre.0", +] + [[package]] name = "poly1305" version = "0.8.0" @@ -1016,6 +1085,20 @@ dependencies = [ "der 0.7.8", "generic-array", "pkcs8 0.10.2", + "subtle", + "zeroize", +] + +[[package]] +name = "sec1" +version = "0.8.0-pre.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ccf9d914303f6606a4fa47933f65b92ce13991573a3c61118a458ec5b5ca6cb" +dependencies = [ + "base16ct 0.2.0", + "der 0.8.0-pre.0", + "hybrid-array", + "pkcs8 0.11.0-pre.0", "serdect", "subtle", "zeroize", @@ -1063,9 +1146,9 @@ dependencies = [ [[package]] name = "serdect" -version = "0.2.0" +version = "0.3.0-pre.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a84f14a19e9a014bb9f4512488d9829a68e04ecabffb0f9904cd1ace94598177" +checksum = "791ef964bfaba6be28a5c3f0c56836e17cb711ac009ca1074b9c735a3ebf240a" dependencies = [ "base16ct 0.2.0", "serde", @@ -1095,13 +1178,24 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "sha2" +version = "0.11.0-pre.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de0628cd6fd8219612c2d71ad52ab8c2014a18cbdbedbde17de04d400df65997" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.11.0-pre.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "sha3" -version = "0.10.8" +version = "0.11.0-pre.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +checksum = "ab80aa0f8ab215182f50d06bf13ed44929975b0f57ec4f2ddf97f01a4f6a41ab" dependencies = [ - "digest 0.10.7", + "digest 0.11.0-pre.3 (registry+https://github.com/rust-lang/crates.io-index)", "keccak", ] @@ -1164,6 +1258,16 @@ dependencies = [ "der 0.7.8", ] +[[package]] +name = "spki" +version = "0.8.0-pre.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb2b56670f5ef52934c97efad30bf42585de0c33ec3e2a886e38b80d2db67243" +dependencies = [ + "base64ct", + "der 0.8.0-pre.0", +] + [[package]] name = "stable_deref_trait" version = "1.2.0" diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 0353295ed..24eb941cc 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -19,7 +19,7 @@ crypto-common = { version = "0.1", default-features = false } aead = { version = "0.5", optional = true } cipher = { version = "0.4", optional = true } digest = { version = "0.10", optional = true, features = ["mac"] } -elliptic-curve = { version = "0.13", optional = true, path = "../elliptic-curve" } +elliptic-curve = { version = "0.13", optional = true } password-hash = { version = "0.5", optional = true } signature = { version = "2", optional = true, default-features = false } universal-hash = { version = "0.5", optional = true } diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 7cd47e35e..81e117ea0 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.13.8" +version = "0.14.0-pre" description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, @@ -13,34 +13,34 @@ readme = "README.md" categories = ["cryptography", "no-std"] keywords = ["crypto", "ecc", "elliptic", "weierstrass"] edition = "2021" -rust-version = "1.65" +rust-version = "1.71" [dependencies] base16ct = "0.2" crypto-bigint = { version = "0.5", default-features = false, features = ["rand_core", "generic-array", "zeroize"] } -generic-array = { version = "0.14.6", default-features = false, features = ["zeroize"] } +hybrid-array = { version = "=0.2.0-pre.8", default-features = false, features = ["zeroize"] } rand_core = { version = "0.6.4", default-features = false } subtle = { version = "2", default-features = false } zeroize = { version = "1.7", default-features = false } # optional dependencies base64ct = { version = "1", optional = true, default-features = false, features = ["alloc"] } -digest = { version = "0.10", optional = true } +digest = { version = "=0.11.0-pre.3", optional = true } ff = { version = "0.13", optional = true, default-features = false } group = { version = "0.13", optional = true, default-features = false } -hkdf = { version = "0.12.4", optional = true, default-features = false } +hkdf = { version = "=0.13.0-pre.0", optional = true, default-features = false } hex-literal = { version = "0.4", optional = true } -pem-rfc7468 = { version = "0.7", optional = true, features = ["alloc"] } -pkcs8 = { version = "0.10.2", optional = true, default-features = false } -sec1 = { version = "0.7.1", optional = true, features = ["subtle", "zeroize"] } -serdect = { version = "0.2", optional = true, default-features = false, features = ["alloc"] } +pem-rfc7468 = { version = "=1.0.0-pre.0", optional = true, features = ["alloc"] } +pkcs8 = { version = "=0.11.0-pre.0", optional = true, default-features = false } +sec1 = { version = "=0.8.0-pre.0", optional = true, features = ["subtle", "zeroize"] } +serdect = { version = "=0.3.0-pre.0", optional = true, default-features = false, features = ["alloc"] } serde_json = { version = "1.0.47", optional = true, default-features = false, features = ["alloc"] } tap = { version = "1.0.1", optional = true, default-features = false } # hack for minimal-versions support for `bits` [dev-dependencies] hex-literal = "0.4" -sha2 = "0.10" -sha3 = "0.10" +sha2 = "=0.11.0-pre.0" +sha3 = "=0.11.0-pre.0" [features] default = ["arithmetic"] diff --git a/elliptic-curve/README.md b/elliptic-curve/README.md index 37163a775..4e4f5e47a 100644 --- a/elliptic-curve/README.md +++ b/elliptic-curve/README.md @@ -15,7 +15,7 @@ and public/secret keys composed thereof. ## Minimum Supported Rust Version -Requires Rust **1.65** or higher. +Requires Rust **1.71** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -49,6 +49,6 @@ dual licensed as above, without any additional terms or conditions. [build-image]: https://github.com/RustCrypto/traits/actions/workflows/elliptic-curve.yml/badge.svg [build-link]: https://github.com/RustCrypto/traits/actions/workflows/elliptic-curve.yml [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.65+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.71+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260040-elliptic-curves diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index a2659f1b8..63597f90d 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -6,7 +6,7 @@ use crate::{ bigint::{Limb, U256}, error::{Error, Result}, - generic_array::typenum::U32, + hybrid_array::typenum::U32, ops::{Invert, LinearCombination, MulByGenerator, Reduce, ShrAssign}, pkcs8, point::AffineCoordinates, diff --git a/elliptic-curve/src/field.rs b/elliptic-curve/src/field.rs index 66055abc2..2884e241a 100644 --- a/elliptic-curve/src/field.rs +++ b/elliptic-curve/src/field.rs @@ -4,13 +4,13 @@ use crate::{ bigint::{ArrayEncoding, ByteArray, Integer}, Curve, }; -use generic_array::{typenum::Unsigned, GenericArray}; +use hybrid_array::{typenum::Unsigned, Array}; /// Size of serialized field elements of this elliptic curve. pub type FieldBytesSize = ::FieldBytesSize; /// Byte representation of a base/scalar field element of a given curve. -pub type FieldBytes = GenericArray>; +pub type FieldBytes = Array>; /// Trait for decoding/encoding `Curve::Uint` from/to [`FieldBytes`] using /// curve-specific rules. diff --git a/elliptic-curve/src/hash2curve/hash2field.rs b/elliptic-curve/src/hash2curve/hash2field.rs index 67ede111c..c9a980c1a 100644 --- a/elliptic-curve/src/hash2curve/hash2field.rs +++ b/elliptic-curve/src/hash2curve/hash2field.rs @@ -7,15 +7,15 @@ mod expand_msg; pub use expand_msg::{xmd::*, xof::*, *}; use crate::{Error, Result}; -use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; +use hybrid_array::{typenum::Unsigned, Array, ArraySize}; /// The trait for helping to convert to a field element. pub trait FromOkm { /// The number of bytes needed to convert to a field element. - type Length: ArrayLength; + type Length: ArraySize; /// Convert a byte sequence into a field element. - fn from_okm(data: &GenericArray) -> Self; + fn from_okm(data: &Array) -> Self; } /// Convert an arbitrary byte sequence into a field element. @@ -38,7 +38,7 @@ where T: FromOkm + Default, { let len_in_bytes = T::Length::to_usize().checked_mul(out.len()).ok_or(Error)?; - let mut tmp = GenericArray::::Length>::default(); + let mut tmp = Array::::Length>::default(); let mut expander = E::expand_message(data, domain, len_in_bytes)?; for o in out.iter_mut() { expander.fill_bytes(&mut tmp); diff --git a/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs b/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs index 96a659b9a..58d3c36e5 100644 --- a/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs +++ b/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs @@ -5,8 +5,8 @@ pub(super) mod xof; use crate::{Error, Result}; use digest::{Digest, ExtendableOutput, Update, XofReader}; -use generic_array::typenum::{IsLess, U256}; -use generic_array::{ArrayLength, GenericArray}; +use hybrid_array::typenum::{IsLess, U256}; +use hybrid_array::{Array, ArraySize}; /// Salt when the DST is too long const OVERSIZE_DST_SALT: &[u8] = b"H2C-OVERSIZE-DST-"; @@ -45,17 +45,17 @@ pub trait Expander { /// [dst]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-13#section-5.4.3 pub(crate) enum Domain<'a, L> where - L: ArrayLength + IsLess, + L: ArraySize + IsLess, { /// > 255 - Hashed(GenericArray), + Hashed(Array), /// <= 255 Array(&'a [&'a [u8]]), } impl<'a, L> Domain<'a, L> where - L: ArrayLength + IsLess, + L: ArraySize + IsLess, { pub fn xof(dsts: &'a [&'a [u8]]) -> Result where @@ -64,7 +64,7 @@ where if dsts.is_empty() { Err(Error) } else if dsts.iter().map(|dst| dst.len()).sum::() > MAX_DST_LEN { - let mut data = GenericArray::::default(); + let mut data = Array::::default(); let mut hash = X::default(); hash.update(OVERSIZE_DST_SALT); diff --git a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs index 9cbd69832..e34133a1a 100644 --- a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs +++ b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs @@ -5,11 +5,11 @@ use core::marker::PhantomData; use super::{Domain, ExpandMsg, Expander}; use crate::{Error, Result}; use digest::{ - core_api::BlockSizeUser, - generic_array::{ + array::{ typenum::{IsLess, IsLessOrEqual, Unsigned, U256}, - GenericArray, + Array, }, + core_api::BlockSizeUser, FixedOutput, HashMarker, }; @@ -56,7 +56,7 @@ where let domain = Domain::xmd::(dsts)?; let mut b_0 = HashT::default(); - b_0.update(&GenericArray::::default()); + b_0.update(&Array::::default()); for msg in msgs { b_0.update(msg); @@ -93,8 +93,8 @@ where HashT::OutputSize: IsLess, HashT::OutputSize: IsLessOrEqual, { - b_0: GenericArray, - b_vals: GenericArray, + b_0: Array, + b_vals: Array, domain: Domain<'a, HashT::OutputSize>, index: u8, offset: usize, @@ -112,7 +112,7 @@ where self.index += 1; self.offset = 0; // b_0 XOR b_(idx - 1) - let mut tmp = GenericArray::::default(); + let mut tmp = Array::::default(); self.b_0 .iter() .zip(&self.b_vals[..]) @@ -152,11 +152,11 @@ where mod test { use super::*; use core::mem; - use generic_array::{ + use hex_literal::hex; + use hybrid_array::{ typenum::{U128, U32}, - ArrayLength, + ArraySize, }; - use hex_literal::hex; use sha2::Sha256; fn assert_message( @@ -170,7 +170,7 @@ mod test { { let block = HashT::BlockSize::to_usize(); assert_eq!( - GenericArray::::default().as_slice(), + Array::::default().as_slice(), &bytes[..block] ); @@ -200,7 +200,7 @@ mod test { impl TestVector { #[allow(clippy::panic_in_result_fn)] - fn assert>( + fn assert( &self, dst: &'static [u8], domain: &Domain<'_, HashT::OutputSize>, @@ -215,7 +215,7 @@ mod test { let mut expander = ExpandMsgXmd::::expand_message(&[self.msg], &dst, L::to_usize())?; - let mut uniform_bytes = GenericArray::::default(); + let mut uniform_bytes = Array::::default(); expander.fill_bytes(&mut uniform_bytes); assert_eq!(uniform_bytes.as_slice(), self.uniform_bytes); diff --git a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs index 7ffed126b..a3081a5f7 100644 --- a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs +++ b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs @@ -3,7 +3,7 @@ use super::{Domain, ExpandMsg, Expander}; use crate::{Error, Result}; use digest::{ExtendableOutput, Update, XofReader}; -use generic_array::typenum::U32; +use hybrid_array::typenum::U32; /// Placeholder type for implementing `expand_message_xof` based on an extendable output function /// @@ -64,11 +64,11 @@ where mod test { use super::*; use core::mem; - use generic_array::{ + use hex_literal::hex; + use hybrid_array::{ typenum::{U128, U32}, - ArrayLength, GenericArray, + Array, ArraySize, }; - use hex_literal::hex; use sha3::Shake128; fn assert_message(msg: &[u8], domain: &Domain<'_, U32>, len_in_bytes: u16, bytes: &[u8]) { @@ -101,14 +101,14 @@ mod test { fn assert(&self, dst: &'static [u8], domain: &Domain<'_, U32>) -> Result<()> where HashT: Default + ExtendableOutput + Update, - L: ArrayLength, + L: ArraySize, { assert_message(self.msg, domain, L::to_u16(), self.msg_prime); let mut expander = ExpandMsgXof::::expand_message(&[self.msg], &[dst], L::to_usize())?; - let mut uniform_bytes = GenericArray::::default(); + let mut uniform_bytes = Array::::default(); expander.fill_bytes(&mut uniform_bytes); assert_eq!(uniform_bytes.as_slice(), self.uniform_bytes); diff --git a/elliptic-curve/src/hash2curve/isogeny.rs b/elliptic-curve/src/hash2curve/isogeny.rs index fc870d010..6f49f427b 100644 --- a/elliptic-curve/src/hash2curve/isogeny.rs +++ b/elliptic-curve/src/hash2curve/isogeny.rs @@ -4,7 +4,7 @@ use core::ops::{AddAssign, Mul}; use ff::Field; -use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; +use hybrid_array::{typenum::Unsigned, Array, ArraySize}; /// The coefficients for mapping from one isogenous curve to another pub struct IsogenyCoefficients> { @@ -21,13 +21,13 @@ pub struct IsogenyCoefficients> { /// The [`Isogeny`] methods to map to another curve. pub trait Isogeny: Field + AddAssign + Mul { /// The maximum number of coefficients - type Degree: ArrayLength; + type Degree: ArraySize; /// The isogeny coefficients const COEFFICIENTS: IsogenyCoefficients; /// Map from the isogeny points to the main curve fn isogeny(x: Self, y: Self) -> (Self, Self) { - let mut xs = GenericArray::::default(); + let mut xs = Array::::default(); xs[0] = Self::ONE; xs[1] = x; xs[2] = x.square(); diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index f387d2896..4a73c3f0a 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -119,7 +119,7 @@ pub use crate::{ secret_key::SecretKey, }; pub use crypto_bigint as bigint; -pub use generic_array::{self, typenum::consts}; +pub use hybrid_array::{self, typenum::consts}; pub use rand_core; pub use subtle; pub use zeroize; @@ -149,7 +149,7 @@ use core::{ fmt::Debug, ops::{Add, ShrAssign}, }; -use generic_array::ArrayLength; +use hybrid_array::ArraySize; /// Algorithm [`ObjectIdentifier`][`pkcs8::ObjectIdentifier`] for elliptic /// curve public key cryptography (`id-ecPublicKey`). @@ -172,7 +172,7 @@ pub trait Curve: 'static + Copy + Clone + Debug + Default + Eq + Ord + Send + Sy /// /// This is typically the same as `Self::Uint::ByteSize` but for curves /// with an unusual field modulus (e.g. P-224, P-521) it may be different. - type FieldBytesSize: ArrayLength + Add + Eq; + type FieldBytesSize: ArraySize + Add + Eq; /// Integer type used to represent field elements of this elliptic curve. type Uint: bigint::ArrayEncoding diff --git a/elliptic-curve/src/scalar/nonzero.rs b/elliptic-curve/src/scalar/nonzero.rs index c0e45740f..7b81a6053 100644 --- a/elliptic-curve/src/scalar/nonzero.rs +++ b/elliptic-curve/src/scalar/nonzero.rs @@ -13,7 +13,7 @@ use core::{ }; use crypto_bigint::{ArrayEncoding, Integer}; use ff::{Field, PrimeField}; -use generic_array::{typenum::Unsigned, GenericArray}; +use hybrid_array::{typenum::Unsigned, Array}; use rand_core::CryptoRngCore; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; use zeroize::Zeroize; @@ -286,10 +286,7 @@ where fn try_from(bytes: &[u8]) -> Result { if bytes.len() == C::FieldBytesSize::USIZE { - Option::from(NonZeroScalar::from_repr(GenericArray::clone_from_slice( - bytes, - ))) - .ok_or(Error) + Option::from(NonZeroScalar::from_repr(Array::clone_from_slice(bytes))).ok_or(Error) } else { Err(Error) } diff --git a/elliptic-curve/src/scalar/primitive.rs b/elliptic-curve/src/scalar/primitive.rs index a4f64cb58..30fcbde92 100644 --- a/elliptic-curve/src/scalar/primitive.rs +++ b/elliptic-curve/src/scalar/primitive.rs @@ -13,7 +13,7 @@ use core::{ ops::{Add, AddAssign, Neg, ShrAssign, Sub, SubAssign}, str, }; -use generic_array::{typenum::Unsigned, GenericArray}; +use hybrid_array::Array; use rand_core::CryptoRngCore; use subtle::{ Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeGreater, ConstantTimeLess, @@ -83,11 +83,8 @@ where /// Decode [`ScalarPrimitive`] from a big endian byte slice. pub fn from_slice(slice: &[u8]) -> Result { - if slice.len() == C::FieldBytesSize::USIZE { - Option::from(Self::from_bytes(GenericArray::from_slice(slice))).ok_or(Error) - } else { - Err(Error) - } + let bytes = Array::try_from(slice).map_err(|_| Error)?; + Option::from(Self::from_bytes(&bytes)).ok_or(Error) } /// Borrow the inner `C::Uint`. diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index 5e1c07f96..77417cd82 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -5,14 +5,14 @@ pub use sec1::point::{Coordinates, ModulusSize, Tag}; use crate::{Curve, FieldBytesSize, Result, SecretKey}; -use generic_array::GenericArray; +use hybrid_array::Array; use subtle::CtOption; #[cfg(feature = "arithmetic")] use crate::{AffinePoint, CurveArithmetic, Error}; /// Encoded elliptic curve point with point compression. -pub type CompressedPoint = GenericArray>; +pub type CompressedPoint = Array>; /// Size of a compressed elliptic curve point. pub type CompressedPointSize = as ModulusSize>::CompressedPointSize; @@ -21,7 +21,7 @@ pub type CompressedPointSize = as ModulusSize>::Compressed pub type EncodedPoint = sec1::point::EncodedPoint>; /// Encoded elliptic curve point *without* point compression. -pub type UncompressedPoint = GenericArray>; +pub type UncompressedPoint = Array>; /// Size of an uncompressed elliptic curve point. pub type UncompressedPointSize = as ModulusSize>::UncompressedPointSize; diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 198fd66e0..05b4f4cf0 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -10,7 +10,7 @@ mod pkcs8; use crate::{Curve, Error, FieldBytes, Result, ScalarPrimitive}; use core::fmt::{self, Debug}; -use generic_array::typenum::Unsigned; +use hybrid_array::typenum::Unsigned; use subtle::{Choice, ConstantTimeEq}; use zeroize::{Zeroize, ZeroizeOnDrop, Zeroizing}; @@ -154,13 +154,13 @@ where /// Deserialize secret key from an encoded secret scalar passed as a byte slice. /// - /// The slice is expected to be a minimum of 24-bytes (192-byts) and at most `C::FieldBytesSize` - /// bytes in length. + /// The slice is expected to be a minimum of 24-bytes (192-bytes) and at most + /// `C::FieldBytesSize` bytes in length. /// /// Byte slices shorter than the field size are handled by zero padding the input. pub fn from_slice(slice: &[u8]) -> Result { if slice.len() == C::FieldBytesSize::USIZE { - Self::from_bytes(FieldBytes::::from_slice(slice)) + Self::from_bytes(FieldBytes::::ref_from_slice(slice)) } else if (Self::MIN_SIZE..C::FieldBytesSize::USIZE).contains(&slice.len()) { let mut bytes = Zeroizing::new(FieldBytes::::default()); let offset = C::FieldBytesSize::USIZE.saturating_sub(slice.len()); From ace5ceb6ed8bd5730154d883669e215a8b100ad3 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 9 Jan 2024 08:37:06 -0700 Subject: [PATCH 1122/1461] elliptic-curve: bump `crypto-bigint` to v0.6.0-pre.8; MSRV 1.73 (#1463) The latest prerelease of `crypto-bigint` includes changes necessary to also support heap-backed integers (not that we're planning on using them), but also includes expanded modular arithmetic support including an implementation of the Bernstein-Yang modular inversion algorithm. It also includes a migration to `hybrid-array` which will be necessary for everything to work together correctly. --- .github/workflows/elliptic-curve.yml | 6 ++++-- Cargo.lock | 30 +++++++++++++++++++++++++- elliptic-curve/Cargo.toml | 4 ++-- elliptic-curve/README.md | 4 ++-- elliptic-curve/src/dev.rs | 2 +- elliptic-curve/src/lib.rs | 5 +++-- elliptic-curve/src/scalar.rs | 1 + elliptic-curve/src/scalar/primitive.rs | 4 ++-- 8 files changed, 44 insertions(+), 12 deletions(-) diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index 4c8147768..5c6bc098b 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -24,7 +24,7 @@ jobs: strategy: matrix: rust: - - 1.71.0 # MSRV + - 1.73.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -58,6 +58,8 @@ jobs: - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,digest,ecdh,hazmat,hash2curve,jwk,pem,pkcs8,sec1,serde,voprf minimal-versions: + # Temporarily disabled until elliptic-curve 0.13.0-pre.0 is published + if: false runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -74,7 +76,7 @@ jobs: strategy: matrix: rust: - - 1.71.0 # MSRV + - 1.73.0 # MSRV - stable - nightly steps: diff --git a/Cargo.lock b/Cargo.lock index f4ef242c7..c51aad3cb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -61,6 +61,12 @@ dependencies = [ "signature 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + [[package]] name = "base16ct" version = "0.1.1" @@ -301,6 +307,19 @@ dependencies = [ "zeroize", ] +[[package]] +name = "crypto-bigint" +version = "0.6.0-pre.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f83f24a157ad881f072a0ba6b4950dc0d1fbbea38df4dcc271d9a4a1501b96e" +dependencies = [ + "hybrid-array", + "num-traits", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + [[package]] name = "crypto-common" version = "0.1.6" @@ -524,7 +543,7 @@ version = "0.14.0-pre" dependencies = [ "base16ct 0.2.0", "base64ct", - "crypto-bigint 0.5.5", + "crypto-bigint 0.6.0-pre.8", "digest 0.11.0-pre.3 (registry+https://github.com/rust-lang/crates.io-index)", "ff 0.13.0", "group 0.13.0", @@ -830,6 +849,15 @@ version = "0.2.151" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" +[[package]] +name = "num-traits" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +dependencies = [ + "autocfg", +] + [[package]] name = "opaque-debug" version = "0.3.0" diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 81e117ea0..c5bad4bcb 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -13,11 +13,11 @@ readme = "README.md" categories = ["cryptography", "no-std"] keywords = ["crypto", "ecc", "elliptic", "weierstrass"] edition = "2021" -rust-version = "1.71" +rust-version = "1.73" [dependencies] base16ct = "0.2" -crypto-bigint = { version = "0.5", default-features = false, features = ["rand_core", "generic-array", "zeroize"] } +crypto-bigint = { version = "=0.6.0-pre.8", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } hybrid-array = { version = "=0.2.0-pre.8", default-features = false, features = ["zeroize"] } rand_core = { version = "0.6.4", default-features = false } subtle = { version = "2", default-features = false } diff --git a/elliptic-curve/README.md b/elliptic-curve/README.md index 4e4f5e47a..0824685c9 100644 --- a/elliptic-curve/README.md +++ b/elliptic-curve/README.md @@ -15,7 +15,7 @@ and public/secret keys composed thereof. ## Minimum Supported Rust Version -Requires Rust **1.71** or higher. +Requires Rust **1.73** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -49,6 +49,6 @@ dual licensed as above, without any additional terms or conditions. [build-image]: https://github.com/RustCrypto/traits/actions/workflows/elliptic-curve.yml/badge.svg [build-link]: https://github.com/RustCrypto/traits/actions/workflows/elliptic-curve.yml [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.71+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.73+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260040-elliptic-curves diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 63597f90d..6031150e5 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -4,9 +4,9 @@ //! the traits in this crate. use crate::{ + array::typenum::U32, bigint::{Limb, U256}, error::{Error, Result}, - hybrid_array::typenum::U32, ops::{Invert, LinearCombination, MulByGenerator, Reduce, ShrAssign}, pkcs8, point::AffineCoordinates, diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 4a73c3f0a..32ce2fa1a 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -119,7 +119,8 @@ pub use crate::{ secret_key::SecretKey, }; pub use crypto_bigint as bigint; -pub use hybrid_array::{self, typenum::consts}; +pub use hybrid_array as array; +pub use hybrid_array::typenum::consts; pub use rand_core; pub use subtle; pub use zeroize; @@ -178,7 +179,7 @@ pub trait Curve: 'static + Copy + Clone + Debug + Default + Eq + Ord + Send + Sy type Uint: bigint::ArrayEncoding + bigint::AddMod + bigint::Encoding - + bigint::Integer + + bigint::FixedInteger + bigint::NegMod + bigint::Random + bigint::RandomMod diff --git a/elliptic-curve/src/scalar.rs b/elliptic-curve/src/scalar.rs index eb992493a..a53b93e12 100644 --- a/elliptic-curve/src/scalar.rs +++ b/elliptic-curve/src/scalar.rs @@ -7,6 +7,7 @@ mod nonzero; mod primitive; pub use self::primitive::ScalarPrimitive; + #[cfg(feature = "arithmetic")] pub use self::{blinded::BlindedScalar, nonzero::NonZeroScalar}; diff --git a/elliptic-curve/src/scalar/primitive.rs b/elliptic-curve/src/scalar/primitive.rs index 30fcbde92..877bacb61 100644 --- a/elliptic-curve/src/scalar/primitive.rs +++ b/elliptic-curve/src/scalar/primitive.rs @@ -1,6 +1,7 @@ //! Generic scalar type with primitive functionality. use crate::{ + array::Array, bigint::{prelude::*, Limb, NonZero}, scalar::FromUintUnchecked, scalar::IsHigh, @@ -13,7 +14,6 @@ use core::{ ops::{Add, AddAssign, Neg, ShrAssign, Sub, SubAssign}, str, }; -use hybrid_array::Array; use rand_core::CryptoRngCore; use subtle::{ Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeGreater, ConstantTimeLess, @@ -357,7 +357,7 @@ where C: Curve, { fn is_high(&self) -> Choice { - let n_2 = C::ORDER >> 1; + let n_2 = C::ORDER >> 1u32; self.inner.ct_gt(&n_2) } } From 39137561171484cf4fe0168aa0e27f6431bb4002 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 9 Jan 2024 08:50:57 -0700 Subject: [PATCH 1123/1461] elliptic-curve v0.14.0-pre.0 (#1464) --- Cargo.lock | 2 +- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c51aad3cb..d480f78f3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -539,7 +539,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.14.0-pre" +version = "0.14.0-pre.0" dependencies = [ "base16ct 0.2.0", "base64ct", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index c5bad4bcb..695eb2162 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.14.0-pre" +version = "0.14.0-pre.0" description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, From 0cd55a3f810f6ce61f22631366e1fc4385d1ee8c Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 9 Jan 2024 09:54:36 -0700 Subject: [PATCH 1124/1461] signature: bump `digest` to v0.11.0-pre.3; MSRV 1.71 (#1465) Per our SemVer policy, this is exempt as a SemVer breaking change. However, per the same policy, this bumps the version to v2.3.0-pre as a minor version bump is required. --- .github/workflows/signature.yml | 6 +++--- Cargo.lock | 18 +++++++++--------- signature/Cargo.toml | 8 ++++---- signature/README.md | 4 ++-- signature/tests/derive.rs | 6 +++--- 5 files changed, 21 insertions(+), 21 deletions(-) diff --git a/.github/workflows/signature.yml b/.github/workflows/signature.yml index 73a6571dd..40e4bc0a1 100644 --- a/.github/workflows/signature.yml +++ b/.github/workflows/signature.yml @@ -24,7 +24,7 @@ jobs: strategy: matrix: rust: - - 1.60.0 # MSRV + - 1.71.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -52,7 +52,7 @@ jobs: strategy: matrix: rust: - - 1.60.0 # MSRV + - 1.71.0 # MSRV - stable steps: - uses: actions/checkout@v4 @@ -70,7 +70,7 @@ jobs: strategy: matrix: rust: - - 1.60.0 # MSRV + - 1.71.0 # MSRV - stable steps: - uses: actions/checkout@v4 diff --git a/Cargo.lock b/Cargo.lock index d480f78f3..73e4caf94 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -58,7 +58,7 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" name = "async-signature" version = "0.5.0" dependencies = [ - "signature 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "signature 2.2.0", ] [[package]] @@ -267,7 +267,7 @@ dependencies = [ "digest 0.10.7", "elliptic-curve 0.13.8", "password-hash 0.5.0", - "signature 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "signature 2.2.0", "universal-hash 0.5.1", ] @@ -1240,22 +1240,22 @@ dependencies = [ [[package]] name = "signature" version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ "digest 0.10.7", - "hex-literal", "rand_core 0.6.4", - "sha2 0.10.8", - "signature_derive", ] [[package]] name = "signature" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +version = "2.3.0" dependencies = [ - "digest 0.10.7", + "digest 0.11.0-pre.3 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal", "rand_core 0.6.4", + "sha2 0.11.0-pre.0", + "signature_derive", ] [[package]] diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 29353f6c4..4b7f9bd2a 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "2.2.0" +version = "2.3.0-pre" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/signature" @@ -10,16 +10,16 @@ readme = "README.md" keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"] categories = ["cryptography", "no-std"] edition = "2021" -rust-version = "1.60" +rust-version = "1.71" [dependencies] derive = { package = "signature_derive", version = "2", optional = true, path = "../signature_derive" } -digest = { version = "0.10.6", optional = true, default-features = false } +digest = { version = "=0.11.0-pre.3", optional = true, default-features = false } rand_core = { version = "0.6.4", optional = true, default-features = false } [dev-dependencies] hex-literal = "0.4" -sha2 = { version = "0.10", default-features = false } +sha2 = { version = "=0.11.0-pre.0", default-features = false } [features] alloc = [] diff --git a/signature/README.md b/signature/README.md index 5e1100301..0b9802105 100644 --- a/signature/README.md +++ b/signature/README.md @@ -17,7 +17,7 @@ the [RustCrypto] organization, as well as [`ed25519-dalek`]. ## Minimum Supported Rust Version -Rust **1.60** or higher. +Rust **1.71** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -56,7 +56,7 @@ dual licensed as above, without any additional terms or conditions. [build-image]: https://github.com/RustCrypto/traits/actions/workflows/signature.yml/badge.svg [build-link]: https://github.com/RustCrypto/traits/actions/workflows/signature.yml [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.60+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.71+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260048-signatures diff --git a/signature/tests/derive.rs b/signature/tests/derive.rs index b54eec823..a3b7b0fac 100644 --- a/signature/tests/derive.rs +++ b/signature/tests/derive.rs @@ -2,7 +2,7 @@ #![cfg(all(feature = "derive", feature = "digest"))] -use digest::{generic_array::GenericArray, Digest, OutputSizeUser}; +use digest::{array::Array, Digest, OutputSizeUser}; use hex_literal::hex; use sha2::Sha256; use signature::{ @@ -17,7 +17,7 @@ const INPUT_STRING: &[u8] = b"abc"; const INPUT_STRING_DIGEST: [u8; 32] = hex!("ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad"); -type Repr = GenericArray::OutputSize>; +type Repr = Array::OutputSize>; /// Dummy signature which just contains a digest output #[derive(Clone, Debug)] @@ -35,7 +35,7 @@ impl TryFrom<&[u8]> for DummySignature { type Error = Error; fn try_from(bytes: &[u8]) -> Result { - Ok(DummySignature(GenericArray::clone_from_slice(bytes))) + Ok(DummySignature(Array::clone_from_slice(bytes))) } } From 4f4ca9dac72d1b1eccbe6a5fd0440925008d74e8 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 9 Jan 2024 11:11:24 -0700 Subject: [PATCH 1125/1461] signature v2.3.0-pre.0 (#1466) --- Cargo.lock | 2 +- signature/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 73e4caf94..1cf6f957b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1249,7 +1249,7 @@ dependencies = [ [[package]] name = "signature" -version = "2.3.0" +version = "2.3.0-pre.0" dependencies = [ "digest 0.11.0-pre.3 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal", diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 4b7f9bd2a..898a26cd8 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "2.3.0-pre" +version = "2.3.0-pre.0" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/signature" From c501254368a080c0da607763192c4f390d80754b Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 10 Jan 2024 09:57:16 -0700 Subject: [PATCH 1126/1461] crypto-common: bump `hybrid-array` to v0.2.0-rc.0 (#1468) Relaxes the `hybrid-array` requirement so we can release additional compatible versions without having to upgrade `crypto-common` each time. Also bumps `crypto-common` to v0.2.0-pre.4 (for release) --- Cargo.lock | 21 ++++++--------------- Cargo.toml | 3 ++- crypto-common/Cargo.lock | 5 +++-- crypto-common/Cargo.toml | 4 ++-- 4 files changed, 13 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1cf6f957b..ae66c6a19 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,7 +19,7 @@ dependencies = [ "arrayvec", "blobby", "bytes", - "crypto-common 0.2.0-pre.3 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.2.0-pre.3", "heapless", ] @@ -136,7 +136,7 @@ version = "0.11.0-pre.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72bc448e41b30773616b4f51a23f1a51634d41ce0d06a9bf6c3065ee85e227a1" dependencies = [ - "crypto-common 0.2.0-pre.3 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.2.0-pre.3", ] [[package]] @@ -225,7 +225,7 @@ name = "cipher" version = "0.5.0-pre.1" dependencies = [ "blobby", - "crypto-common 0.2.0-pre.3 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.2.0-pre.3", "inout 0.2.0-pre.3", "zeroize", ] @@ -331,15 +331,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "crypto-common" -version = "0.2.0-pre.3" -dependencies = [ - "getrandom", - "hybrid-array", - "rand_core 0.6.4", -] - [[package]] name = "crypto-common" version = "0.2.0-pre.3" @@ -449,7 +440,7 @@ dependencies = [ "blobby", "block-buffer 0.11.0-pre.3", "const-oid 0.10.0-pre.2", - "crypto-common 0.2.0-pre.3 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.2.0-pre.3", "subtle", ] @@ -461,7 +452,7 @@ checksum = "eb3be3c52e023de5662dc05a32f747d09a1d6024fdd1f64b0850e373269efb43" dependencies = [ "block-buffer 0.11.0-pre.3", "const-oid 0.10.0-pre.2", - "crypto-common 0.2.0-pre.3 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.2.0-pre.3", "subtle", ] @@ -1351,7 +1342,7 @@ dependencies = [ name = "universal-hash" version = "0.6.0-pre" dependencies = [ - "crypto-common 0.2.0-pre.3 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.2.0-pre.3", "subtle", ] diff --git a/Cargo.toml b/Cargo.toml index a15d8c30d..43e1e3c82 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ members = [ "async-signature", "cipher", "crypto", - "crypto-common", +# "crypto-common", "digest", "elliptic-curve", "kem", @@ -14,3 +14,4 @@ members = [ "signature_derive", "universal-hash", ] +exclude = ["crypto-common"] diff --git a/crypto-common/Cargo.lock b/crypto-common/Cargo.lock index cf1f569a7..05f61c215 100644 --- a/crypto-common/Cargo.lock +++ b/crypto-common/Cargo.lock @@ -30,8 +30,9 @@ dependencies = [ [[package]] name = "hybrid-array" -version = "0.2.0-pre.8" -source = "git+https://github.com/RustCrypto/utils.git?branch=hybrid-array/v0.2.0-pre.8#eac3be7a9c959152b37d6c51e1aaf2f44e9c2c40" +version = "0.2.0-rc.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8c5517ac29f08e88170b9647d85cc5f21c2596de177b4867232e20b214b8da1" dependencies = [ "typenum", ] diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index d66059f05..86bd2f045 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crypto-common" description = "Common cryptographic traits" -version = "0.2.0-pre.3" +version = "0.2.0-pre.4" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" @@ -13,7 +13,7 @@ keywords = ["crypto", "traits"] categories = ["cryptography", "no-std"] [dependencies] -hybrid-array = "=0.2.0-pre.8" +hybrid-array = "0.2.0-rc.0" # optional dependencies rand_core = { version = "0.6.4", optional = true } From eb25268083b222fda13de24b03f44f3e3e5ffc58 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 10 Jan 2024 10:42:02 -0700 Subject: [PATCH 1127/1461] Bump `crypto-common` and `hybrid-array` (#1469) Bumps the following dependencies: - `block-buffer` => v0.11.0-pre.4 - `block-padding` => v0.4.0-pre.4 - `crypto-common` => v0.2.0-pre.4 - `hybrid-array` => v0.2.0-rc.0 - `inout` => v0.2.0-pre.4 Also prepares the following releases: - `cipher` v0.5.0-pre.2 - `digest` v0.11.0-pre.4 --- Cargo.lock | 309 ++++---------------------------------- Cargo.toml | 8 +- aead/Cargo.toml | 2 +- aead/src/lib.rs | 2 +- cipher/Cargo.toml | 6 +- digest/Cargo.toml | 6 +- universal-hash/Cargo.toml | 2 +- 7 files changed, 42 insertions(+), 293 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ae66c6a19..075f27568 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,7 +19,7 @@ dependencies = [ "arrayvec", "blobby", "bytes", - "crypto-common 0.2.0-pre.3", + "crypto-common 0.2.0-pre.4 (registry+https://github.com/rust-lang/crates.io-index)", "heapless", ] @@ -61,12 +61,6 @@ dependencies = [ "signature 2.2.0", ] -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - [[package]] name = "base16ct" version = "0.1.1" @@ -94,18 +88,6 @@ dependencies = [ "serde", ] -[[package]] -name = "bitvec" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" -dependencies = [ - "funty", - "radium", - "tap", - "wyz", -] - [[package]] name = "blobby" version = "0.3.1" @@ -132,11 +114,11 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.11.0-pre.3" +version = "0.11.0-pre.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72bc448e41b30773616b4f51a23f1a51634d41ce0d06a9bf6c3065ee85e227a1" +checksum = "0edadbde8e0243b49d434f9a23ec0590af201f400a34d7d51049284e4a77c568" dependencies = [ - "crypto-common 0.2.0-pre.3", + "crypto-common 0.2.0-pre.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -150,9 +132,9 @@ dependencies = [ [[package]] name = "block-padding" -version = "0.4.0-pre.3" +version = "0.4.0-pre.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d07a359e2b51a0e9b9d6a6d4582b7b62723e4a25f4e5ca6be70a6a00050202ab" +checksum = "e8ab21a8964437caf2e83a92a1221ce65e356a2a9b8b52d58bece04005fe114e" dependencies = [ "hybrid-array", ] @@ -222,11 +204,11 @@ dependencies = [ [[package]] name = "cipher" -version = "0.5.0-pre.1" +version = "0.5.0-pre.2" dependencies = [ "blobby", - "crypto-common 0.2.0-pre.3", - "inout 0.2.0-pre.3", + "crypto-common 0.2.0-pre.4 (registry+https://github.com/rust-lang/crates.io-index)", + "inout 0.2.0-pre.4", "zeroize", ] @@ -308,34 +290,30 @@ dependencies = [ ] [[package]] -name = "crypto-bigint" -version = "0.6.0-pre.8" +name = "crypto-common" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f83f24a157ad881f072a0ba6b4950dc0d1fbbea38df4dcc271d9a4a1501b96e" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ - "hybrid-array", - "num-traits", + "generic-array", "rand_core 0.6.4", - "subtle", - "zeroize", + "typenum", ] [[package]] name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +version = "0.2.0-pre.4" dependencies = [ - "generic-array", + "getrandom", + "hybrid-array", "rand_core 0.6.4", - "typenum", ] [[package]] name = "crypto-common" -version = "0.2.0-pre.3" +version = "0.2.0-pre.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc17eb697364b18256ec92675ebe6b7b153d2f1041e568d74533c5d0fc1ca162" +checksum = "806e4e3731d44f1340b069551225b44c2056c105cad9e67f0c46266db8a3a6b9" dependencies = [ "getrandom", "hybrid-array", @@ -402,17 +380,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "der" -version = "0.8.0-pre.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b489fd2221710c1dd46637d66b984161fb66134f81437a8489800306bcc2ecea" -dependencies = [ - "const-oid 0.10.0-pre.2", - "pem-rfc7468 1.0.0-pre.0", - "zeroize", -] - [[package]] name = "digest" version = "0.9.0" @@ -435,24 +402,12 @@ dependencies = [ [[package]] name = "digest" -version = "0.11.0-pre.3" +version = "0.11.0-pre.4" dependencies = [ "blobby", - "block-buffer 0.11.0-pre.3", + "block-buffer 0.11.0-pre.4", "const-oid 0.10.0-pre.2", - "crypto-common 0.2.0-pre.3", - "subtle", -] - -[[package]] -name = "digest" -version = "0.11.0-pre.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3be3c52e023de5662dc05a32f747d09a1d6024fdd1f64b0850e373269efb43" -dependencies = [ - "block-buffer 0.11.0-pre.3", - "const-oid 0.10.0-pre.2", - "crypto-common 0.2.0-pre.3", + "crypto-common 0.2.0-pre.4 (registry+https://github.com/rust-lang/crates.io-index)", "subtle", ] @@ -528,32 +483,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "elliptic-curve" -version = "0.14.0-pre.0" -dependencies = [ - "base16ct 0.2.0", - "base64ct", - "crypto-bigint 0.6.0-pre.8", - "digest 0.11.0-pre.3 (registry+https://github.com/rust-lang/crates.io-index)", - "ff 0.13.0", - "group 0.13.0", - "hex-literal", - "hkdf 0.13.0-pre.0", - "hybrid-array", - "pem-rfc7468 1.0.0-pre.0", - "pkcs8 0.11.0-pre.0", - "rand_core 0.6.4", - "sec1 0.8.0-pre.0", - "serde_json", - "serdect", - "sha2 0.11.0-pre.0", - "sha3", - "subtle", - "tap", - "zeroize", -] - [[package]] name = "ff" version = "0.10.1" @@ -580,17 +509,10 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ - "bitvec", "rand_core 0.6.4", "subtle", ] -[[package]] -name = "funty" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" - [[package]] name = "generic-array" version = "0.14.7" @@ -681,12 +603,6 @@ dependencies = [ "stable_deref_trait", ] -[[package]] -name = "hex-literal" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" - [[package]] name = "hkdf" version = "0.11.0" @@ -706,15 +622,6 @@ dependencies = [ "hmac 0.12.1", ] -[[package]] -name = "hkdf" -version = "0.13.0-pre.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f3bed625061d9ed27cd87356cb46c3c8269a585be23d56c6f179c722bbea471" -dependencies = [ - "hmac 0.13.0-pre.0", -] - [[package]] name = "hmac" version = "0.11.0" @@ -734,15 +641,6 @@ dependencies = [ "digest 0.10.7", ] -[[package]] -name = "hmac" -version = "0.13.0-pre.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e22cb0183a745c3444af57c24aa1293e1f3e538717acce39a9d3b271c999b24f" -dependencies = [ - "digest 0.11.0-pre.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "hpke" version = "0.10.0" @@ -767,12 +665,11 @@ dependencies = [ [[package]] name = "hybrid-array" -version = "0.2.0-pre.8" +version = "0.2.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27fbaf242418fe980caf09ed348d5a6aeabe71fc1bd8bebad641f4591ae0a46d" +checksum = "b8c5517ac29f08e88170b9647d85cc5f21c2596de177b4867232e20b214b8da1" dependencies = [ "typenum", - "zeroize", ] [[package]] @@ -787,20 +684,14 @@ dependencies = [ [[package]] name = "inout" -version = "0.2.0-pre.3" +version = "0.2.0-pre.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96ea9986e1fde8d177cd039f00f9f316d3bfce9ebc2787c1267d4414adf3acb3" +checksum = "0a2cc35b920cc3b344af824e64e508ffc2c819fc2368ed4d253244446194d2fe" dependencies = [ - "block-padding 0.4.0-pre.3", + "block-padding 0.4.0-pre.4", "hybrid-array", ] -[[package]] -name = "itoa" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" - [[package]] name = "jobserver" version = "0.1.27" @@ -810,15 +701,6 @@ dependencies = [ "libc", ] -[[package]] -name = "keccak" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" -dependencies = [ - "cpufeatures", -] - [[package]] name = "kem" version = "0.3.0-pre" @@ -840,15 +722,6 @@ version = "0.2.151" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" -[[package]] -name = "num-traits" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" -dependencies = [ - "autocfg", -] - [[package]] name = "opaque-debug" version = "0.3.0" @@ -904,15 +777,6 @@ dependencies = [ "base64ct", ] -[[package]] -name = "pem-rfc7468" -version = "1.0.0-pre.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76a65e1c27d1680f8805b3f8c9949f08d6aa5d6cbd088c9896e64a53821dc27d" -dependencies = [ - "base64ct", -] - [[package]] name = "pkcs8" version = "0.7.6" @@ -920,7 +784,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee3ef9b64d26bad0536099c816c6734379e45bbd5f14798def6809e5cc350447" dependencies = [ "der 0.4.5", - "pem-rfc7468 0.2.3", + "pem-rfc7468", "spki 0.4.1", "zeroize", ] @@ -935,16 +799,6 @@ dependencies = [ "spki 0.7.3", ] -[[package]] -name = "pkcs8" -version = "0.11.0-pre.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "935c09e0aecb0cb8f8907b57438b19a068cb74a25189b06724f061170b2465ff" -dependencies = [ - "der 0.8.0-pre.0", - "spki 0.8.0-pre.0", -] - [[package]] name = "poly1305" version = "0.8.0" @@ -1033,12 +887,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "radium" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" - [[package]] name = "rand" version = "0.8.5" @@ -1075,12 +923,6 @@ dependencies = [ "getrandom", ] -[[package]] -name = "ryu" -version = "1.0.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" - [[package]] name = "sec1" version = "0.3.0" @@ -1108,21 +950,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "sec1" -version = "0.8.0-pre.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ccf9d914303f6606a4fa47933f65b92ce13991573a3c61118a458ec5b5ca6cb" -dependencies = [ - "base16ct 0.2.0", - "der 0.8.0-pre.0", - "hybrid-array", - "pkcs8 0.11.0-pre.0", - "serdect", - "subtle", - "zeroize", -] - [[package]] name = "serde" version = "1.0.195" @@ -1152,27 +979,6 @@ dependencies = [ "syn", ] -[[package]] -name = "serde_json" -version = "1.0.111" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "serdect" -version = "0.3.0-pre.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "791ef964bfaba6be28a5c3f0c56836e17cb711ac009ca1074b9c735a3ebf240a" -dependencies = [ - "base16ct 0.2.0", - "serde", -] - [[package]] name = "sha2" version = "0.9.9" @@ -1197,27 +1003,6 @@ dependencies = [ "digest 0.10.7", ] -[[package]] -name = "sha2" -version = "0.11.0-pre.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de0628cd6fd8219612c2d71ad52ab8c2014a18cbdbedbde17de04d400df65997" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest 0.11.0-pre.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "sha3" -version = "0.11.0-pre.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab80aa0f8ab215182f50d06bf13ed44929975b0f57ec4f2ddf97f01a4f6a41ab" -dependencies = [ - "digest 0.11.0-pre.3 (registry+https://github.com/rust-lang/crates.io-index)", - "keccak", -] - [[package]] name = "signature" version = "1.3.2" @@ -1238,17 +1023,6 @@ dependencies = [ "rand_core 0.6.4", ] -[[package]] -name = "signature" -version = "2.3.0-pre.0" -dependencies = [ - "digest 0.11.0-pre.3 (registry+https://github.com/rust-lang/crates.io-index)", - "hex-literal", - "rand_core 0.6.4", - "sha2 0.11.0-pre.0", - "signature_derive", -] - [[package]] name = "signature_derive" version = "2.1.0" @@ -1277,16 +1051,6 @@ dependencies = [ "der 0.7.8", ] -[[package]] -name = "spki" -version = "0.8.0-pre.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb2b56670f5ef52934c97efad30bf42585de0c33ec3e2a886e38b80d2db67243" -dependencies = [ - "base64ct", - "der 0.8.0-pre.0", -] - [[package]] name = "stable_deref_trait" version = "1.2.0" @@ -1310,12 +1074,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "tap" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" - [[package]] name = "typenum" version = "1.17.0" @@ -1342,7 +1100,7 @@ dependencies = [ name = "universal-hash" version = "0.6.0-pre" dependencies = [ - "crypto-common 0.2.0-pre.3", + "crypto-common 0.2.0-pre.4 (registry+https://github.com/rust-lang/crates.io-index)", "subtle", ] @@ -1358,15 +1116,6 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" -[[package]] -name = "wyz" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" -dependencies = [ - "tap", -] - [[package]] name = "x25519-dalek" version = "2.0.0-pre.1" diff --git a/Cargo.toml b/Cargo.toml index 43e1e3c82..c61ac8267 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,13 +5,13 @@ members = [ "async-signature", "cipher", "crypto", -# "crypto-common", + "crypto-common", "digest", - "elliptic-curve", +# "elliptic-curve", "kem", "password-hash", - "signature", +# "signature", "signature_derive", "universal-hash", ] -exclude = ["crypto-common"] +exclude = ["elliptic-curve", "signature"] diff --git a/aead/Cargo.toml b/aead/Cargo.toml index e69d1df0e..f92036811 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -16,7 +16,7 @@ categories = ["cryptography", "no-std"] rust-version = "1.65" [dependencies] -crypto-common = "=0.2.0-pre.3" +crypto-common = "=0.2.0-pre.4" # optional dependencies arrayvec = { version = "0.7", optional = true, default-features = false } diff --git a/aead/src/lib.rs b/aead/src/lib.rs index 8448e40f7..157401f14 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -255,7 +255,7 @@ macro_rules! impl_decrypt_in_place { let tag_pos = $buffer.len() - Self::TagSize::to_usize(); let (msg, tag) = $buffer.as_mut().split_at_mut(tag_pos); - $aead.decrypt_in_place_detached($nonce, $aad, msg, Tag::::ref_from_slice(tag))?; + $aead.decrypt_in_place_detached($nonce, $aad, msg, Tag::::from_slice(tag))?; $buffer.truncate(tag_pos); Ok(()) }}; diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index 1968148f4..b998b22a5 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "cipher" description = "Traits for describing block ciphers and stream ciphers" -version = "0.5.0-pre.1" +version = "0.5.0-pre.2" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" @@ -13,8 +13,8 @@ keywords = ["crypto", "block-cipher", "stream-cipher", "trait"] categories = ["cryptography", "no-std"] [dependencies] -crypto-common = "=0.2.0-pre.3" -inout = "=0.2.0-pre.3" +crypto-common = "=0.2.0-pre.4" +inout = "=0.2.0-pre.4" # optional dependencies blobby = { version = "0.3", optional = true } diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 36c62e2ee..fe639df5a 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "digest" description = "Traits for cryptographic hash functions and message authentication codes" -version = "0.11.0-pre.3" +version = "0.11.0-pre.4" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" @@ -13,10 +13,10 @@ keywords = ["digest", "crypto", "hash"] categories = ["cryptography", "no-std"] [dependencies] -crypto-common = "=0.2.0-pre.3" +crypto-common = "=0.2.0-pre.4" # optional dependencies -block-buffer = { version = "=0.11.0-pre.3", optional = true } +block-buffer = { version = "=0.11.0-pre.4", optional = true } subtle = { version = "2.4", default-features = false, optional = true } blobby = { version = "0.3", optional = true } const-oid = { version = "=0.10.0-pre.2", optional = true } diff --git a/universal-hash/Cargo.toml b/universal-hash/Cargo.toml index 9ddc4c06b..dafe0fd36 100644 --- a/universal-hash/Cargo.toml +++ b/universal-hash/Cargo.toml @@ -13,7 +13,7 @@ keywords = ["crypto", "mac"] categories = ["cryptography", "no-std"] [dependencies] -crypto-common = "=0.2.0-pre.3" +crypto-common = "=0.2.0-pre.4" subtle = { version = "2.4", default-features = false } [features] From 4e3abf3a38e8a41502003e2002c4dea34c227529 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 10 Jan 2024 11:17:05 -0700 Subject: [PATCH 1128/1461] Bump `crypto-common` and `hybrid-array` (#1469) Bumps the following dependencies: - `block-buffer` => v0.11.0-pre.4 - `block-padding` => v0.4.0-pre.4 - `crypto-common` => v0.2.0-pre.4 - `hybrid-array` => v0.2.0-rc.0 - `inout` => v0.2.0-pre.4 Also prepares the following releases: - `cipher` v0.5.0-pre.2 - `digest` v0.11.0-pre.4 From f96b7d2937323ddfe09cef39a4466702946196b7 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 10 Jan 2024 13:17:33 -0700 Subject: [PATCH 1129/1461] elliptic-curve,signature: bump deps; add back to workspace (#1470) Also cuts v0.14.0-pre.1 and v2.3.0-pre.1 releases respectively --- Cargo.lock | 262 ++++++++++++++++++++++++++++++- Cargo.toml | 5 +- elliptic-curve/Cargo.toml | 16 +- elliptic-curve/src/secret_key.rs | 2 +- signature/Cargo.toml | 6 +- 5 files changed, 275 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 075f27568..b288e2245 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -61,6 +61,12 @@ dependencies = [ "signature 2.2.0", ] +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + [[package]] name = "base16ct" version = "0.1.1" @@ -88,6 +94,18 @@ dependencies = [ "serde", ] +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + [[package]] name = "blobby" version = "0.3.1" @@ -289,6 +307,19 @@ dependencies = [ "zeroize", ] +[[package]] +name = "crypto-bigint" +version = "0.6.0-pre.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ccdf8183c2226b057661e7d89624e75108e67b28306c898581fee700ff2d992" +dependencies = [ + "hybrid-array", + "num-traits", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + [[package]] name = "crypto-common" version = "0.1.6" @@ -380,6 +411,17 @@ dependencies = [ "zeroize", ] +[[package]] +name = "der" +version = "0.8.0-pre.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b489fd2221710c1dd46637d66b984161fb66134f81437a8489800306bcc2ecea" +dependencies = [ + "const-oid 0.10.0-pre.2", + "pem-rfc7468 1.0.0-pre.0", + "zeroize", +] + [[package]] name = "digest" version = "0.9.0" @@ -411,6 +453,18 @@ dependencies = [ "subtle", ] +[[package]] +name = "digest" +version = "0.11.0-pre.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b429fb535b92bad18c86f1d7ee7584a175c2810800c7ac5b75b9408b13981979" +dependencies = [ + "block-buffer 0.11.0-pre.4", + "const-oid 0.10.0-pre.2", + "crypto-common 0.2.0-pre.4 (registry+https://github.com/rust-lang/crates.io-index)", + "subtle", +] + [[package]] name = "dunce" version = "1.0.4" @@ -483,6 +537,32 @@ dependencies = [ "zeroize", ] +[[package]] +name = "elliptic-curve" +version = "0.14.0-pre.0" +dependencies = [ + "base16ct 0.2.0", + "base64ct", + "crypto-bigint 0.6.0-pre.9", + "digest 0.11.0-pre.4 (registry+https://github.com/rust-lang/crates.io-index)", + "ff 0.13.0", + "group 0.13.0", + "hex-literal", + "hkdf 0.13.0-pre.1", + "hybrid-array", + "pem-rfc7468 1.0.0-pre.0", + "pkcs8 0.11.0-pre.0", + "rand_core 0.6.4", + "sec1 0.8.0-pre.1", + "serde_json", + "serdect", + "sha2 0.11.0-pre.1", + "sha3", + "subtle", + "tap", + "zeroize", +] + [[package]] name = "ff" version = "0.10.1" @@ -509,10 +589,17 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ + "bitvec", "rand_core 0.6.4", "subtle", ] +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + [[package]] name = "generic-array" version = "0.14.7" @@ -603,6 +690,12 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "hex-literal" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" + [[package]] name = "hkdf" version = "0.11.0" @@ -622,6 +715,15 @@ dependencies = [ "hmac 0.12.1", ] +[[package]] +name = "hkdf" +version = "0.13.0-pre.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8030479f3be0f2d183d7fcb5a8bb3c08c31ba40c49a1af5780544272ab8494fb" +dependencies = [ + "hmac 0.13.0-pre.1", +] + [[package]] name = "hmac" version = "0.11.0" @@ -641,6 +743,15 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "hmac" +version = "0.13.0-pre.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad9bdb2c4daa57033321e5e64c7a8cab02086ee130f8702f72b5c164893026a" +dependencies = [ + "digest 0.11.0-pre.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "hpke" version = "0.10.0" @@ -670,6 +781,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8c5517ac29f08e88170b9647d85cc5f21c2596de177b4867232e20b214b8da1" dependencies = [ "typenum", + "zeroize", ] [[package]] @@ -692,6 +804,12 @@ dependencies = [ "hybrid-array", ] +[[package]] +name = "itoa" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" + [[package]] name = "jobserver" version = "0.1.27" @@ -701,6 +819,15 @@ dependencies = [ "libc", ] +[[package]] +name = "keccak" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +dependencies = [ + "cpufeatures", +] + [[package]] name = "kem" version = "0.3.0-pre" @@ -722,6 +849,15 @@ version = "0.2.151" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" +[[package]] +name = "num-traits" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +dependencies = [ + "autocfg", +] + [[package]] name = "opaque-debug" version = "0.3.0" @@ -777,6 +913,15 @@ dependencies = [ "base64ct", ] +[[package]] +name = "pem-rfc7468" +version = "1.0.0-pre.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a65e1c27d1680f8805b3f8c9949f08d6aa5d6cbd088c9896e64a53821dc27d" +dependencies = [ + "base64ct", +] + [[package]] name = "pkcs8" version = "0.7.6" @@ -784,7 +929,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee3ef9b64d26bad0536099c816c6734379e45bbd5f14798def6809e5cc350447" dependencies = [ "der 0.4.5", - "pem-rfc7468", + "pem-rfc7468 0.2.3", "spki 0.4.1", "zeroize", ] @@ -799,6 +944,16 @@ dependencies = [ "spki 0.7.3", ] +[[package]] +name = "pkcs8" +version = "0.11.0-pre.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "935c09e0aecb0cb8f8907b57438b19a068cb74a25189b06724f061170b2465ff" +dependencies = [ + "der 0.8.0-pre.0", + "spki 0.8.0-pre.0", +] + [[package]] name = "poly1305" version = "0.8.0" @@ -887,6 +1042,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + [[package]] name = "rand" version = "0.8.5" @@ -923,6 +1084,12 @@ dependencies = [ "getrandom", ] +[[package]] +name = "ryu" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" + [[package]] name = "sec1" version = "0.3.0" @@ -950,6 +1117,21 @@ dependencies = [ "zeroize", ] +[[package]] +name = "sec1" +version = "0.8.0-pre.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02dc081ed777a3bab68583b52ffb8221677b6e90d483b320963a247e2c07f328" +dependencies = [ + "base16ct 0.2.0", + "der 0.8.0-pre.0", + "hybrid-array", + "pkcs8 0.11.0-pre.0", + "serdect", + "subtle", + "zeroize", +] + [[package]] name = "serde" version = "1.0.195" @@ -979,6 +1161,27 @@ dependencies = [ "syn", ] +[[package]] +name = "serde_json" +version = "1.0.111" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serdect" +version = "0.3.0-pre.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791ef964bfaba6be28a5c3f0c56836e17cb711ac009ca1074b9c735a3ebf240a" +dependencies = [ + "base16ct 0.2.0", + "serde", +] + [[package]] name = "sha2" version = "0.9.9" @@ -1003,6 +1206,27 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "sha2" +version = "0.11.0-pre.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9daa731ca112bb569b34b41775363a461422813d8ed1ea6dba352eb58ec4e684" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.11.0-pre.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "sha3" +version = "0.11.0-pre.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23f5da8ebbbfc6bd857bb4d209bb42109772703b118ea137d57352c2a95b3322" +dependencies = [ + "digest 0.11.0-pre.4 (registry+https://github.com/rust-lang/crates.io-index)", + "keccak", +] + [[package]] name = "signature" version = "1.3.2" @@ -1023,6 +1247,17 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "signature" +version = "2.3.0-pre.0" +dependencies = [ + "digest 0.11.0-pre.4 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal", + "rand_core 0.6.4", + "sha2 0.11.0-pre.1", + "signature_derive", +] + [[package]] name = "signature_derive" version = "2.1.0" @@ -1051,6 +1286,16 @@ dependencies = [ "der 0.7.8", ] +[[package]] +name = "spki" +version = "0.8.0-pre.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb2b56670f5ef52934c97efad30bf42585de0c33ec3e2a886e38b80d2db67243" +dependencies = [ + "base64ct", + "der 0.8.0-pre.0", +] + [[package]] name = "stable_deref_trait" version = "1.2.0" @@ -1074,6 +1319,12 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + [[package]] name = "typenum" version = "1.17.0" @@ -1116,6 +1367,15 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + [[package]] name = "x25519-dalek" version = "2.0.0-pre.1" diff --git a/Cargo.toml b/Cargo.toml index c61ac8267..a15d8c30d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,11 +7,10 @@ members = [ "crypto", "crypto-common", "digest", -# "elliptic-curve", + "elliptic-curve", "kem", "password-hash", -# "signature", + "signature", "signature_derive", "universal-hash", ] -exclude = ["elliptic-curve", "signature"] diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 695eb2162..9bc35593f 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.14.0-pre.0" +version = "0.14.0-pre.1" description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, @@ -17,30 +17,30 @@ rust-version = "1.73" [dependencies] base16ct = "0.2" -crypto-bigint = { version = "=0.6.0-pre.8", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } -hybrid-array = { version = "=0.2.0-pre.8", default-features = false, features = ["zeroize"] } +crypto-bigint = { version = "=0.6.0-pre.9", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } +hybrid-array = { version = "0.2.0-rc.0", default-features = false, features = ["zeroize"] } rand_core = { version = "0.6.4", default-features = false } subtle = { version = "2", default-features = false } zeroize = { version = "1.7", default-features = false } # optional dependencies base64ct = { version = "1", optional = true, default-features = false, features = ["alloc"] } -digest = { version = "=0.11.0-pre.3", optional = true } +digest = { version = "=0.11.0-pre.4", optional = true } ff = { version = "0.13", optional = true, default-features = false } group = { version = "0.13", optional = true, default-features = false } -hkdf = { version = "=0.13.0-pre.0", optional = true, default-features = false } +hkdf = { version = "=0.13.0-pre.1", optional = true, default-features = false } hex-literal = { version = "0.4", optional = true } pem-rfc7468 = { version = "=1.0.0-pre.0", optional = true, features = ["alloc"] } pkcs8 = { version = "=0.11.0-pre.0", optional = true, default-features = false } -sec1 = { version = "=0.8.0-pre.0", optional = true, features = ["subtle", "zeroize"] } +sec1 = { version = "=0.8.0-pre.1", optional = true, features = ["subtle", "zeroize"] } serdect = { version = "=0.3.0-pre.0", optional = true, default-features = false, features = ["alloc"] } serde_json = { version = "1.0.47", optional = true, default-features = false, features = ["alloc"] } tap = { version = "1.0.1", optional = true, default-features = false } # hack for minimal-versions support for `bits` [dev-dependencies] hex-literal = "0.4" -sha2 = "=0.11.0-pre.0" -sha3 = "=0.11.0-pre.0" +sha2 = "=0.11.0-pre.1" +sha3 = "=0.11.0-pre.1" [features] default = ["arithmetic"] diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 05b4f4cf0..722f0197f 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -160,7 +160,7 @@ where /// Byte slices shorter than the field size are handled by zero padding the input. pub fn from_slice(slice: &[u8]) -> Result { if slice.len() == C::FieldBytesSize::USIZE { - Self::from_bytes(FieldBytes::::ref_from_slice(slice)) + Self::from_bytes(FieldBytes::::from_slice(slice)) } else if (Self::MIN_SIZE..C::FieldBytesSize::USIZE).contains(&slice.len()) { let mut bytes = Zeroizing::new(FieldBytes::::default()); let offset = C::FieldBytesSize::USIZE.saturating_sub(slice.len()); diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 898a26cd8..3bb3728d0 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "2.3.0-pre.0" +version = "2.3.0-pre.1" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/signature" @@ -14,12 +14,12 @@ rust-version = "1.71" [dependencies] derive = { package = "signature_derive", version = "2", optional = true, path = "../signature_derive" } -digest = { version = "=0.11.0-pre.3", optional = true, default-features = false } +digest = { version = "=0.11.0-pre.4", optional = true, default-features = false } rand_core = { version = "0.6.4", optional = true, default-features = false } [dev-dependencies] hex-literal = "0.4" -sha2 = { version = "=0.11.0-pre.0", default-features = false } +sha2 = { version = "=0.11.0-pre.1", default-features = false } [features] alloc = [] From b49ccf5061e4b31244d7b53f77eff6f580e83e8d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 10 Jan 2024 17:38:58 -0700 Subject: [PATCH 1130/1461] elliptic-curve: bump `crypto-bigint` to v0.6.0-pre.10 (#1471) Also cuts a v0.14.0-pre.2 release of `elliptic-curve` --- Cargo.lock | 10 +++++----- elliptic-curve/Cargo.toml | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b288e2245..1aef763db 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -309,9 +309,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.6.0-pre.9" +version = "0.6.0-pre.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ccdf8183c2226b057661e7d89624e75108e67b28306c898581fee700ff2d992" +checksum = "12979c1e0771d68f02c2fb93fb0ad54e597f82d608fb569db792d99ebd0bb3c5" dependencies = [ "hybrid-array", "num-traits", @@ -539,11 +539,11 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.14.0-pre.0" +version = "0.14.0-pre.2" dependencies = [ "base16ct 0.2.0", "base64ct", - "crypto-bigint 0.6.0-pre.9", + "crypto-bigint 0.6.0-pre.10", "digest 0.11.0-pre.4 (registry+https://github.com/rust-lang/crates.io-index)", "ff 0.13.0", "group 0.13.0", @@ -1249,7 +1249,7 @@ dependencies = [ [[package]] name = "signature" -version = "2.3.0-pre.0" +version = "2.3.0-pre.1" dependencies = [ "digest 0.11.0-pre.4 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 9bc35593f..af9dff339 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.14.0-pre.1" +version = "0.14.0-pre.2" description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, @@ -17,7 +17,7 @@ rust-version = "1.73" [dependencies] base16ct = "0.2" -crypto-bigint = { version = "=0.6.0-pre.9", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } +crypto-bigint = { version = "=0.6.0-pre.10", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } hybrid-array = { version = "0.2.0-rc.0", default-features = false, features = ["zeroize"] } rand_core = { version = "0.6.4", default-features = false } subtle = { version = "2", default-features = false } From 49d2620075a300481087552c67319a69fb0db00e Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Thu, 11 Jan 2024 04:38:42 +0300 Subject: [PATCH 1131/1461] digest: add zeroize support (#1472) --- Cargo.lock | 28 +++---- digest/Cargo.toml | 4 +- digest/src/core_api/ct_variable.rs | 9 +++ digest/src/core_api/rt_variable.rs | 91 ++++++++++------------ digest/src/core_api/wrapper.rs | 121 ++++++++++------------------- digest/src/core_api/xof_reader.rs | 14 ++++ digest/src/mac.rs | 18 ++++- 7 files changed, 139 insertions(+), 146 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1aef763db..e742ad658 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -137,6 +137,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0edadbde8e0243b49d434f9a23ec0590af201f400a34d7d51049284e4a77c568" dependencies = [ "crypto-common 0.2.0-pre.4 (registry+https://github.com/rust-lang/crates.io-index)", + "zeroize", ] [[package]] @@ -445,8 +446,9 @@ dependencies = [ [[package]] name = "digest" version = "0.11.0-pre.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b429fb535b92bad18c86f1d7ee7584a175c2810800c7ac5b75b9408b13981979" dependencies = [ - "blobby", "block-buffer 0.11.0-pre.4", "const-oid 0.10.0-pre.2", "crypto-common 0.2.0-pre.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -455,14 +457,14 @@ dependencies = [ [[package]] name = "digest" -version = "0.11.0-pre.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b429fb535b92bad18c86f1d7ee7584a175c2810800c7ac5b75b9408b13981979" +version = "0.11.0-pre.5" dependencies = [ + "blobby", "block-buffer 0.11.0-pre.4", "const-oid 0.10.0-pre.2", "crypto-common 0.2.0-pre.4 (registry+https://github.com/rust-lang/crates.io-index)", "subtle", + "zeroize", ] [[package]] @@ -544,7 +546,7 @@ dependencies = [ "base16ct 0.2.0", "base64ct", "crypto-bigint 0.6.0-pre.10", - "digest 0.11.0-pre.4 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.11.0-pre.4", "ff 0.13.0", "group 0.13.0", "hex-literal", @@ -613,9 +615,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" dependencies = [ "cfg-if", "libc", @@ -749,7 +751,7 @@ version = "0.13.0-pre.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ad9bdb2c4daa57033321e5e64c7a8cab02086ee130f8702f72b5c164893026a" dependencies = [ - "digest 0.11.0-pre.4 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.11.0-pre.4", ] [[package]] @@ -845,9 +847,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.151" +version = "0.2.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" +checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" [[package]] name = "num-traits" @@ -1214,7 +1216,7 @@ checksum = "9daa731ca112bb569b34b41775363a461422813d8ed1ea6dba352eb58ec4e684" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.11.0-pre.4 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.11.0-pre.4", ] [[package]] @@ -1223,7 +1225,7 @@ version = "0.11.0-pre.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23f5da8ebbbfc6bd857bb4d209bb42109772703b118ea137d57352c2a95b3322" dependencies = [ - "digest 0.11.0-pre.4 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.11.0-pre.4", "keccak", ] @@ -1251,7 +1253,7 @@ dependencies = [ name = "signature" version = "2.3.0-pre.1" dependencies = [ - "digest 0.11.0-pre.4 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.11.0-pre.4", "hex-literal", "rand_core 0.6.4", "sha2 0.11.0-pre.1", diff --git a/digest/Cargo.toml b/digest/Cargo.toml index fe639df5a..ae5913c0e 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "digest" description = "Traits for cryptographic hash functions and message authentication codes" -version = "0.11.0-pre.4" +version = "0.11.0-pre.5" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" @@ -20,6 +20,7 @@ block-buffer = { version = "=0.11.0-pre.4", optional = true } subtle = { version = "2.4", default-features = false, optional = true } blobby = { version = "0.3", optional = true } const-oid = { version = "=0.10.0-pre.2", optional = true } +zeroize = { version = "1.4", optional = true, default-features = false } [features] default = ["core-api"] @@ -27,6 +28,7 @@ core-api = ["block-buffer"] # Enable Core API traits mac = ["subtle"] # Enable MAC traits rand_core = ["crypto-common/rand_core"] # Enable random key generation methods oid = ["const-oid"] +zeroize = ["dep:zeroize", "block-buffer?/zeroize"] alloc = [] std = ["alloc", "crypto-common/std"] dev = ["blobby"] diff --git a/digest/src/core_api/ct_variable.rs b/digest/src/core_api/ct_variable.rs index b863fd747..fe3aa86c1 100644 --- a/digest/src/core_api/ct_variable.rs +++ b/digest/src/core_api/ct_variable.rs @@ -167,6 +167,15 @@ where const OID: ObjectIdentifier = O::OID; } +#[cfg(feature = "zeroize")] +impl zeroize::ZeroizeOnDrop for CtVariableCoreWrapper +where + T: VariableOutputCore + zeroize::ZeroizeOnDrop, + OutSize: ArraySize + IsLessOrEqual, + LeEq: NonZero, +{ +} + impl fmt::Debug for CtVariableCoreWrapper where T: VariableOutputCore + AlgorithmName, diff --git a/digest/src/core_api/rt_variable.rs b/digest/src/core_api/rt_variable.rs index 0fe3e15a5..c9631e922 100644 --- a/digest/src/core_api/rt_variable.rs +++ b/digest/src/core_api/rt_variable.rs @@ -1,4 +1,4 @@ -use super::{AlgorithmName, BlockSizeUser, TruncSide, UpdateCore, VariableOutputCore}; +use super::{AlgorithmName, BlockSizeUser, TruncSide, VariableOutputCore}; #[cfg(feature = "mac")] use crate::MacMarker; use crate::{HashMarker, InvalidBufferSize}; @@ -15,23 +15,19 @@ use crypto_common::{ typenum::{Diff, IsLess, Le, NonZero, Sum, Unsigned, U1, U256}, AddBlockSize, DeserializeStateError, SerializableState, SerializedState, SubBlockSize, }; +#[cfg(feature = "zeroize")] +use zeroize::ZeroizeOnDrop; /// Wrapper around [`VariableOutputCore`] which selects output size /// at run time. #[derive(Clone)] -pub struct RtVariableCoreWrapper -where - T: VariableOutputCore, -{ +pub struct RtVariableCoreWrapper { core: T, buffer: BlockBuffer, - output_size: usize, + output_size: u8, } -impl RtVariableCoreWrapper -where - T: VariableOutputCore, -{ +impl RtVariableCoreWrapper { #[inline] fn finalize_dirty(&mut self, out: &mut [u8]) -> Result<(), InvalidBufferSize> { let Self { @@ -39,7 +35,8 @@ where buffer, output_size, } = self; - if out.len() != *output_size || out.len() > Self::MAX_OUTPUT_SIZE { + let size_u8 = u8::try_from(out.len()).map_err(|_| InvalidBufferSize)?; + if out.len() > Self::MAX_OUTPUT_SIZE || size_u8 != *output_size { return Err(InvalidBufferSize); } let mut full_res = Default::default(); @@ -54,24 +51,16 @@ where } } -impl HashMarker for RtVariableCoreWrapper where T: VariableOutputCore + HashMarker {} +impl HashMarker for RtVariableCoreWrapper {} #[cfg(feature = "mac")] -impl MacMarker for RtVariableCoreWrapper where T: VariableOutputCore + MacMarker {} +impl MacMarker for RtVariableCoreWrapper {} -impl BlockSizeUser for RtVariableCoreWrapper -where - T: VariableOutputCore, - T::BlockSize: IsLess, - Le: NonZero, -{ +impl BlockSizeUser for RtVariableCoreWrapper { type BlockSize = T::BlockSize; } -impl Reset for RtVariableCoreWrapper -where - T: VariableOutputCore + UpdateCore + Reset, -{ +impl Reset for RtVariableCoreWrapper { #[inline] fn reset(&mut self) { self.buffer.reset(); @@ -79,10 +68,7 @@ where } } -impl Update for RtVariableCoreWrapper -where - T: VariableOutputCore + UpdateCore, -{ +impl Update for RtVariableCoreWrapper { #[inline] fn update(&mut self, input: &[u8]) { let Self { core, buffer, .. } = self; @@ -90,34 +76,33 @@ where } } -impl VariableOutput for RtVariableCoreWrapper -where - T: VariableOutputCore + UpdateCore, -{ +impl VariableOutput for RtVariableCoreWrapper { const MAX_OUTPUT_SIZE: usize = T::OutputSize::USIZE; + #[inline] fn new(output_size: usize) -> Result { + let output_size = u8::try_from(output_size).map_err(|_| InvalidOutputSize)?; let buffer = Default::default(); - T::new(output_size).map(|core| Self { + T::new(output_size.into()).map(|core| Self { core, buffer, output_size, }) } + #[inline] fn output_size(&self) -> usize { - self.output_size + self.output_size.into() } + #[inline] fn finalize_variable(mut self, out: &mut [u8]) -> Result<(), InvalidBufferSize> { self.finalize_dirty(out) } } -impl VariableOutputReset for RtVariableCoreWrapper -where - T: VariableOutputCore + UpdateCore + Reset, -{ +impl VariableOutputReset for RtVariableCoreWrapper { + #[inline] fn finalize_variable_reset(&mut self, out: &mut [u8]) -> Result<(), InvalidBufferSize> { self.finalize_dirty(out)?; self.core.reset(); @@ -126,10 +111,22 @@ where } } -impl fmt::Debug for RtVariableCoreWrapper -where - T: VariableOutputCore + UpdateCore + AlgorithmName, -{ +impl Drop for RtVariableCoreWrapper { + #[inline] + fn drop(&mut self) { + #[cfg(feature = "zeroize")] + { + use zeroize::Zeroize; + self.buffer.zeroize(); + self.output_size.zeroize(); + } + } +} + +#[cfg(feature = "zeroize")] +impl ZeroizeOnDrop for RtVariableCoreWrapper {} + +impl fmt::Debug for RtVariableCoreWrapper { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { T::write_alg_name(f)?; f.write_str(" { .. }") @@ -141,7 +138,7 @@ type RtVariableCoreWrapperSerializedStateSize = impl SerializableState for RtVariableCoreWrapper where - T: VariableOutputCore + UpdateCore + SerializableState, + T: VariableOutputCore + SerializableState, T::BlockSize: IsLess, Le: NonZero, T::SerializedStateSize: Add, @@ -163,8 +160,7 @@ where let serialized_pos = Array::::clone_from_slice(&[self.buffer.get_pos().try_into().unwrap()]); let serialized_data = self.buffer.clone().pad_with_zeros(); - let serialized_output_size = - Array::::clone_from_slice(&[self.output_size.try_into().unwrap()]); + let serialized_output_size = Array::::clone_from_slice(&[self.output_size]); serialized_core .concat(serialized_pos) @@ -185,16 +181,13 @@ where core: T::deserialize(serialized_core)?, buffer: BlockBuffer::try_new(&serialized_data[..serialized_pos[0].into()]) .map_err(|_| DeserializeStateError)?, - output_size: serialized_output_size[0].into(), + output_size: serialized_output_size[0], }) } } #[cfg(feature = "std")] -impl std::io::Write for RtVariableCoreWrapper -where - T: VariableOutputCore + UpdateCore, -{ +impl std::io::Write for RtVariableCoreWrapper { #[inline] fn write(&mut self, buf: &[u8]) -> std::io::Result { Update::update(self, buf); diff --git a/digest/src/core_api/wrapper.rs b/digest/src/core_api/wrapper.rs index 38d348a34..fc3ca9d90 100644 --- a/digest/src/core_api/wrapper.rs +++ b/digest/src/core_api/wrapper.rs @@ -1,6 +1,6 @@ use super::{ - AlgorithmName, Buffer, BufferKindUser, ExtendableOutputCore, FixedOutputCore, OutputSizeUser, - Reset, UpdateCore, XofReaderCoreWrapper, + AlgorithmName, BufferKindUser, ExtendableOutputCore, FixedOutputCore, OutputSizeUser, Reset, + UpdateCore, XofReaderCoreWrapper, }; use crate::{ ExtendableOutput, ExtendableOutputReset, FixedOutput, FixedOutputReset, HashMarker, Update, @@ -27,57 +27,35 @@ use const_oid::{AssociatedOid, ObjectIdentifier}; /// /// It handles data buffering and implements the slice-based traits. #[derive(Clone, Default)] -pub struct CoreWrapper -where - T: BufferKindUser, -{ +pub struct CoreWrapper { core: T, buffer: BlockBuffer, } -impl HashMarker for CoreWrapper where T: BufferKindUser + HashMarker {} +impl HashMarker for CoreWrapper {} #[cfg(feature = "mac")] -impl MacMarker for CoreWrapper where T: BufferKindUser + MacMarker {} +impl MacMarker for CoreWrapper {} // this blanket impl is needed for HMAC -impl BlockSizeUser for CoreWrapper -where - T: BufferKindUser + HashMarker, -{ +impl BlockSizeUser for CoreWrapper { type BlockSize = T::BlockSize; } -impl CoreWrapper -where - T: BufferKindUser, -{ +impl CoreWrapper { /// Create new wrapper from `core`. #[inline] pub fn from_core(core: T) -> Self { let buffer = Default::default(); Self { core, buffer } } - - /// Decompose wrapper into inner parts. - #[inline] - pub fn decompose(self) -> (T, Buffer) { - let Self { core, buffer } = self; - (core, buffer) - } } -impl KeySizeUser for CoreWrapper -where - T: BufferKindUser + KeySizeUser, -{ +impl KeySizeUser for CoreWrapper { type KeySize = T::KeySize; } -impl KeyInit for CoreWrapper -where - T: BufferKindUser + KeyInit, -{ +impl KeyInit for CoreWrapper { #[inline] fn new(key: &Key) -> Self { Self { @@ -95,10 +73,7 @@ where } } -impl fmt::Debug for CoreWrapper -where - T: BufferKindUser + AlgorithmName, -{ +impl fmt::Debug for CoreWrapper { #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { T::write_alg_name(f)?; @@ -106,10 +81,7 @@ where } } -impl Reset for CoreWrapper -where - T: BufferKindUser + Reset, -{ +impl Reset for CoreWrapper { #[inline] fn reset(&mut self) { self.core.reset(); @@ -117,10 +89,7 @@ where } } -impl Update for CoreWrapper -where - T: BufferKindUser + UpdateCore, -{ +impl Update for CoreWrapper { #[inline] fn update(&mut self, input: &[u8]) { let Self { core, buffer } = self; @@ -128,17 +97,11 @@ where } } -impl OutputSizeUser for CoreWrapper -where - T: BufferKindUser + OutputSizeUser, -{ +impl OutputSizeUser for CoreWrapper { type OutputSize = T::OutputSize; } -impl FixedOutput for CoreWrapper -where - T: FixedOutputCore, -{ +impl FixedOutput for CoreWrapper { #[inline] fn finalize_into(mut self, out: &mut Output) { let Self { core, buffer } = &mut self; @@ -146,10 +109,7 @@ where } } -impl FixedOutputReset for CoreWrapper -where - T: FixedOutputCore + Reset, -{ +impl FixedOutputReset for CoreWrapper { #[inline] fn finalize_into_reset(&mut self, out: &mut Output) { let Self { core, buffer } = self; @@ -159,25 +119,19 @@ where } } -impl ExtendableOutput for CoreWrapper -where - T: ExtendableOutputCore, -{ +impl ExtendableOutput for CoreWrapper { type Reader = XofReaderCoreWrapper; #[inline] - fn finalize_xof(self) -> Self::Reader { - let (mut core, mut buffer) = self.decompose(); - let core = core.finalize_xof_core(&mut buffer); - let buffer = Default::default(); - Self::Reader { core, buffer } + fn finalize_xof(mut self) -> Self::Reader { + Self::Reader { + core: self.core.finalize_xof_core(&mut self.buffer), + buffer: Default::default(), + } } } -impl ExtendableOutputReset for CoreWrapper -where - T: ExtendableOutputCore + Reset, -{ +impl ExtendableOutputReset for CoreWrapper { #[inline] fn finalize_xof_reset(&mut self) -> Self::Reader { let Self { core, buffer } = self; @@ -192,11 +146,22 @@ where } } +impl Drop for CoreWrapper { + #[inline] + fn drop(&mut self) { + #[cfg(feature = "zeroize")] + { + use zeroize::Zeroize; + self.buffer.zeroize(); + } + } +} + +#[cfg(feature = "zeroize")] +impl zeroize::ZeroizeOnDrop for CoreWrapper {} + #[cfg(feature = "oid")] -impl AssociatedOid for CoreWrapper -where - T: BufferKindUser + AssociatedOid, -{ +impl AssociatedOid for CoreWrapper { const OID: ObjectIdentifier = T::OID; } @@ -243,10 +208,7 @@ where } #[cfg(feature = "std")] -impl std::io::Write for CoreWrapper -where - T: BufferKindUser + UpdateCore, -{ +impl std::io::Write for CoreWrapper { #[inline] fn write(&mut self, buf: &[u8]) -> std::io::Result { Update::update(self, buf); @@ -271,11 +233,8 @@ mod sealed { pub trait Sealed {} } -impl sealed::Sealed for CoreWrapper where T: BufferKindUser {} +impl sealed::Sealed for CoreWrapper {} -impl CoreProxy for CoreWrapper -where - T: BufferKindUser, -{ +impl CoreProxy for CoreWrapper { type Core = T; } diff --git a/digest/src/core_api/xof_reader.rs b/digest/src/core_api/xof_reader.rs index 8c92f3d15..0c832df0c 100644 --- a/digest/src/core_api/xof_reader.rs +++ b/digest/src/core_api/xof_reader.rs @@ -47,3 +47,17 @@ where Ok(buf.len()) } } + +impl Drop for XofReaderCoreWrapper { + #[inline] + fn drop(&mut self) { + #[cfg(feature = "zeroize")] + { + use zeroize::Zeroize; + self.buffer.zeroize(); + } + } +} + +#[cfg(feature = "zeroize")] +impl zeroize::ZeroizeOnDrop for XofReaderCoreWrapper {} diff --git a/digest/src/mac.rs b/digest/src/mac.rs index 25c0c550d..4f07d0db7 100644 --- a/digest/src/mac.rs +++ b/digest/src/mac.rs @@ -206,8 +206,8 @@ impl CtOutput { /// Get the inner [`Output`] array this type wraps. #[inline(always)] - pub fn into_bytes(self) -> Output { - self.bytes + pub fn as_bytes(&self) -> &Output { + &self.bytes } } @@ -247,6 +247,20 @@ impl fmt::Debug for CtOutput { } } +impl Drop for CtOutput { + #[inline] + fn drop(&mut self) { + #[cfg(feature = "zeroize")] + { + use zeroize::Zeroize; + self.bytes.zeroize() + } + } +} + +#[cfg(feature = "zeroize")] +impl zeroize::ZeroizeOnDrop for CtOutput {} + /// Error type for when the [`Output`] of a [`Mac`] /// is not equal to the expected value. #[derive(Default, Debug, Copy, Clone, Eq, PartialEq)] From 6a999bea747bee5aa68525ff78624e0949697b70 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Thu, 11 Jan 2024 15:01:21 +0300 Subject: [PATCH 1132/1461] digest: return CtOutput::into_bytes method (#1473) --- Cargo.lock | 2 +- digest/Cargo.toml | 2 +- digest/src/mac.rs | 8 +++++++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e742ad658..5a7556057 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -457,7 +457,7 @@ dependencies = [ [[package]] name = "digest" -version = "0.11.0-pre.5" +version = "0.11.0-pre.6" dependencies = [ "blobby", "block-buffer 0.11.0-pre.4", diff --git a/digest/Cargo.toml b/digest/Cargo.toml index ae5913c0e..286df8bdb 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "digest" description = "Traits for cryptographic hash functions and message authentication codes" -version = "0.11.0-pre.5" +version = "0.11.0-pre.6" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/digest/src/mac.rs b/digest/src/mac.rs index 4f07d0db7..d34648633 100644 --- a/digest/src/mac.rs +++ b/digest/src/mac.rs @@ -204,11 +204,17 @@ impl CtOutput { Self { bytes } } - /// Get the inner [`Output`] array this type wraps. + /// Get reference to the inner [`Output`] array this type wraps. #[inline(always)] pub fn as_bytes(&self) -> &Output { &self.bytes } + + /// Get the inner [`Output`] array this type wraps. + #[inline(always)] + pub fn into_bytes(&self) -> Output { + self.bytes.clone() + } } impl From> for CtOutput { From b4ec63b0e6b94fad7c311b6b77ae0b59d3c3b18e Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Thu, 11 Jan 2024 18:33:48 +0300 Subject: [PATCH 1133/1461] digest: re-export zeroize (#1474) --- digest/Cargo.toml | 2 +- digest/src/lib.rs | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 286df8bdb..257d0977f 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -20,7 +20,7 @@ block-buffer = { version = "=0.11.0-pre.4", optional = true } subtle = { version = "2.4", default-features = false, optional = true } blobby = { version = "0.3", optional = true } const-oid = { version = "=0.10.0-pre.2", optional = true } -zeroize = { version = "1.4", optional = true, default-features = false } +zeroize = { version = "1.7", optional = true, default-features = false } [features] default = ["core-api"] diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 5f9f56f71..29fd0863e 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -41,6 +41,9 @@ extern crate std; #[cfg(feature = "rand_core")] pub use crypto_common::rand_core; +#[cfg(feature = "zeroize")] +pub use zeroize; + #[cfg(feature = "alloc")] use alloc::boxed::Box; From d94278d4b331f02f25dcdc80cb861ba5f033ce71 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 16 Jan 2024 23:56:51 +0000 Subject: [PATCH 1134/1461] elliptic-curve: bump `crypto-bigint` to v0.6.0-pre.11 (#1475) --- Cargo.lock | 6 +++--- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5a7556057..6783e0d34 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -310,9 +310,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.6.0-pre.10" +version = "0.6.0-pre.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12979c1e0771d68f02c2fb93fb0ad54e597f82d608fb569db792d99ebd0bb3c5" +checksum = "066d29f71af86716a9d917b2655e06326b25e1323bb598a583d5aaa38da20f1d" dependencies = [ "hybrid-array", "num-traits", @@ -545,7 +545,7 @@ version = "0.14.0-pre.2" dependencies = [ "base16ct 0.2.0", "base64ct", - "crypto-bigint 0.6.0-pre.10", + "crypto-bigint 0.6.0-pre.11", "digest 0.11.0-pre.4", "ff 0.13.0", "group 0.13.0", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index af9dff339..dfc30ec7d 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -17,7 +17,7 @@ rust-version = "1.73" [dependencies] base16ct = "0.2" -crypto-bigint = { version = "=0.6.0-pre.10", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } +crypto-bigint = { version = "=0.6.0-pre.11", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } hybrid-array = { version = "0.2.0-rc.0", default-features = false, features = ["zeroize"] } rand_core = { version = "0.6.4", default-features = false } subtle = { version = "2", default-features = false } From c9781332c4dd1b6fcfe6c2a74f56c1f1b3635777 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 17 Jan 2024 14:48:49 +0000 Subject: [PATCH 1135/1461] elliptic-curve: bump `crypto-bigint` to v0.6.0-pre.12 (#1476) Notably this also includes a bump to `hybrid-array` v0.2.0-rc.1 --- Cargo.lock | 10 +++++----- elliptic-curve/Cargo.toml | 2 +- signature/tests/derive.rs | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6783e0d34..235fda445 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -310,9 +310,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.6.0-pre.11" +version = "0.6.0-pre.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "066d29f71af86716a9d917b2655e06326b25e1323bb598a583d5aaa38da20f1d" +checksum = "1943d7beadd9ce2b25f3bae73b9e9336fccc1edf38bdec1ed58d3aa183989e11" dependencies = [ "hybrid-array", "num-traits", @@ -545,7 +545,7 @@ version = "0.14.0-pre.2" dependencies = [ "base16ct 0.2.0", "base64ct", - "crypto-bigint 0.6.0-pre.11", + "crypto-bigint 0.6.0-pre.12", "digest 0.11.0-pre.4", "ff 0.13.0", "group 0.13.0", @@ -778,9 +778,9 @@ dependencies = [ [[package]] name = "hybrid-array" -version = "0.2.0-rc.0" +version = "0.2.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8c5517ac29f08e88170b9647d85cc5f21c2596de177b4867232e20b214b8da1" +checksum = "7b700a69c9d992339e82b6cda619873ee17768be06e80ed5ef07c50c50d499ab" dependencies = [ "typenum", "zeroize", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index dfc30ec7d..60994e280 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -17,7 +17,7 @@ rust-version = "1.73" [dependencies] base16ct = "0.2" -crypto-bigint = { version = "=0.6.0-pre.11", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } +crypto-bigint = { version = "=0.6.0-pre.12", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } hybrid-array = { version = "0.2.0-rc.0", default-features = false, features = ["zeroize"] } rand_core = { version = "0.6.4", default-features = false } subtle = { version = "2", default-features = false } diff --git a/signature/tests/derive.rs b/signature/tests/derive.rs index a3b7b0fac..da24a21c4 100644 --- a/signature/tests/derive.rs +++ b/signature/tests/derive.rs @@ -72,7 +72,7 @@ impl PrehashVerifier for DummyVerifier { #[test] fn derived_signer_impl() { let sig: DummySignature = DummySigner::default().sign(INPUT_STRING); - assert_eq!(sig.to_bytes().as_slice(), INPUT_STRING_DIGEST.as_ref()) + assert_eq!(sig.to_bytes().as_slice(), INPUT_STRING_DIGEST) } #[test] From 2b442524a2fd6968cb737a64275a7da4ee57db38 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 17 Jan 2024 15:03:34 +0000 Subject: [PATCH 1136/1461] digest v0.11.0-pre.7 (#1477) --- Cargo.lock | 2 +- digest/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 235fda445..042b069e8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -457,7 +457,7 @@ dependencies = [ [[package]] name = "digest" -version = "0.11.0-pre.6" +version = "0.11.0-pre.7" dependencies = [ "blobby", "block-buffer 0.11.0-pre.4", diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 257d0977f..880fe5548 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "digest" description = "Traits for cryptographic hash functions and message authentication codes" -version = "0.11.0-pre.6" +version = "0.11.0-pre.7" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" From 85254f6587149edb4b801eef5fd9dc10f0800dc2 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 17 Jan 2024 16:35:31 +0000 Subject: [PATCH 1137/1461] elliptic-curve+signature: bump `digest` to v0.11.0-pre.7 (#1478) These crates have some circular dependencies on other repos which consume `digest` and needed to be updated first (e.g. `hkdf`, `sha2`). This also cuts the following prereleases: - `elliptic-curve` v0.14.0-pre.3 - `signature` v2.3.0-pre.2 Also bumps `signature` MSRV to 1.72. --- .github/workflows/signature.yml | 6 ++-- Cargo.lock | 52 ++++++++++++++++----------------- elliptic-curve/Cargo.toml | 10 +++---- signature/Cargo.toml | 8 ++--- signature/README.md | 4 +-- 5 files changed, 40 insertions(+), 40 deletions(-) diff --git a/.github/workflows/signature.yml b/.github/workflows/signature.yml index 40e4bc0a1..2a9e1af3c 100644 --- a/.github/workflows/signature.yml +++ b/.github/workflows/signature.yml @@ -24,7 +24,7 @@ jobs: strategy: matrix: rust: - - 1.71.0 # MSRV + - 1.72.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -52,7 +52,7 @@ jobs: strategy: matrix: rust: - - 1.71.0 # MSRV + - 1.72.0 # MSRV - stable steps: - uses: actions/checkout@v4 @@ -70,7 +70,7 @@ jobs: strategy: matrix: rust: - - 1.71.0 # MSRV + - 1.72.0 # MSRV - stable steps: - uses: actions/checkout@v4 diff --git a/Cargo.lock b/Cargo.lock index 042b069e8..1e745bdd8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -445,26 +445,26 @@ dependencies = [ [[package]] name = "digest" -version = "0.11.0-pre.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b429fb535b92bad18c86f1d7ee7584a175c2810800c7ac5b75b9408b13981979" +version = "0.11.0-pre.7" dependencies = [ + "blobby", "block-buffer 0.11.0-pre.4", "const-oid 0.10.0-pre.2", "crypto-common 0.2.0-pre.4 (registry+https://github.com/rust-lang/crates.io-index)", "subtle", + "zeroize", ] [[package]] name = "digest" version = "0.11.0-pre.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "957713a19ffdda287c63772e607f848512f67ba948f17d8e42cb8d50fd98a786" dependencies = [ - "blobby", "block-buffer 0.11.0-pre.4", "const-oid 0.10.0-pre.2", "crypto-common 0.2.0-pre.4 (registry+https://github.com/rust-lang/crates.io-index)", "subtle", - "zeroize", ] [[package]] @@ -541,16 +541,16 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.14.0-pre.2" +version = "0.14.0-pre.3" dependencies = [ "base16ct 0.2.0", "base64ct", "crypto-bigint 0.6.0-pre.12", - "digest 0.11.0-pre.4", + "digest 0.11.0-pre.7 (registry+https://github.com/rust-lang/crates.io-index)", "ff 0.13.0", "group 0.13.0", "hex-literal", - "hkdf 0.13.0-pre.1", + "hkdf 0.13.0-pre.2", "hybrid-array", "pem-rfc7468 1.0.0-pre.0", "pkcs8 0.11.0-pre.0", @@ -558,7 +558,7 @@ dependencies = [ "sec1 0.8.0-pre.1", "serde_json", "serdect", - "sha2 0.11.0-pre.1", + "sha2 0.11.0-pre.2", "sha3", "subtle", "tap", @@ -719,11 +719,11 @@ dependencies = [ [[package]] name = "hkdf" -version = "0.13.0-pre.1" +version = "0.13.0-pre.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8030479f3be0f2d183d7fcb5a8bb3c08c31ba40c49a1af5780544272ab8494fb" +checksum = "c524b31a8b37d9561e29293b5931461f0bb72a75101f3916e1480525113da8e9" dependencies = [ - "hmac 0.13.0-pre.1", + "hmac 0.13.0-pre.2", ] [[package]] @@ -747,11 +747,11 @@ dependencies = [ [[package]] name = "hmac" -version = "0.13.0-pre.1" +version = "0.13.0-pre.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad9bdb2c4daa57033321e5e64c7a8cab02086ee130f8702f72b5c164893026a" +checksum = "1fac01891f12d968a2737928c9af2532abdc750e56a890fdbcafdfff17017678" dependencies = [ - "digest 0.11.0-pre.4", + "digest 0.11.0-pre.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -823,9 +823,9 @@ dependencies = [ [[package]] name = "keccak" -version = "0.1.4" +version = "0.2.0-pre.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +checksum = "a7cdd4f0dc5807b9a2b25dd48a3f58e862606fe7bd47f41ecde36e97422d7e90" dependencies = [ "cpufeatures", ] @@ -1210,22 +1210,22 @@ dependencies = [ [[package]] name = "sha2" -version = "0.11.0-pre.1" +version = "0.11.0-pre.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9daa731ca112bb569b34b41775363a461422813d8ed1ea6dba352eb58ec4e684" +checksum = "e18b939d4051b69874cbdb8f55de6a14ae44b357ccb94bdbd0a2122f8f875a46" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.11.0-pre.4", + "digest 0.11.0-pre.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "sha3" -version = "0.11.0-pre.1" +version = "0.11.0-pre.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23f5da8ebbbfc6bd857bb4d209bb42109772703b118ea137d57352c2a95b3322" +checksum = "9cecb44e361133b3304a1b3e325a1d8c999339fec8c19762b55e1509a17d6806" dependencies = [ - "digest 0.11.0-pre.4", + "digest 0.11.0-pre.7 (registry+https://github.com/rust-lang/crates.io-index)", "keccak", ] @@ -1251,12 +1251,12 @@ dependencies = [ [[package]] name = "signature" -version = "2.3.0-pre.1" +version = "2.3.0-pre.2" dependencies = [ - "digest 0.11.0-pre.4", + "digest 0.11.0-pre.7 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal", "rand_core 0.6.4", - "sha2 0.11.0-pre.1", + "sha2 0.11.0-pre.2", "signature_derive", ] diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 60994e280..8cb5b5995 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.14.0-pre.2" +version = "0.14.0-pre.3" description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, @@ -25,10 +25,10 @@ zeroize = { version = "1.7", default-features = false } # optional dependencies base64ct = { version = "1", optional = true, default-features = false, features = ["alloc"] } -digest = { version = "=0.11.0-pre.4", optional = true } +digest = { version = "=0.11.0-pre.7", optional = true } ff = { version = "0.13", optional = true, default-features = false } group = { version = "0.13", optional = true, default-features = false } -hkdf = { version = "=0.13.0-pre.1", optional = true, default-features = false } +hkdf = { version = "=0.13.0-pre.2", optional = true, default-features = false } hex-literal = { version = "0.4", optional = true } pem-rfc7468 = { version = "=1.0.0-pre.0", optional = true, features = ["alloc"] } pkcs8 = { version = "=0.11.0-pre.0", optional = true, default-features = false } @@ -39,8 +39,8 @@ tap = { version = "1.0.1", optional = true, default-features = false } # hack fo [dev-dependencies] hex-literal = "0.4" -sha2 = "=0.11.0-pre.1" -sha3 = "=0.11.0-pre.1" +sha2 = "=0.11.0-pre.2" +sha3 = "=0.11.0-pre.2" [features] default = ["arithmetic"] diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 3bb3728d0..5045802e0 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "2.3.0-pre.1" +version = "2.3.0-pre.2" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/signature" @@ -10,16 +10,16 @@ readme = "README.md" keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"] categories = ["cryptography", "no-std"] edition = "2021" -rust-version = "1.71" +rust-version = "1.72" [dependencies] derive = { package = "signature_derive", version = "2", optional = true, path = "../signature_derive" } -digest = { version = "=0.11.0-pre.4", optional = true, default-features = false } +digest = { version = "=0.11.0-pre.7", optional = true, default-features = false } rand_core = { version = "0.6.4", optional = true, default-features = false } [dev-dependencies] hex-literal = "0.4" -sha2 = { version = "=0.11.0-pre.1", default-features = false } +sha2 = { version = "=0.11.0-pre.2", default-features = false } [features] alloc = [] diff --git a/signature/README.md b/signature/README.md index 0b9802105..838d131b6 100644 --- a/signature/README.md +++ b/signature/README.md @@ -17,7 +17,7 @@ the [RustCrypto] organization, as well as [`ed25519-dalek`]. ## Minimum Supported Rust Version -Rust **1.71** or higher. +Rust **1.72** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -56,7 +56,7 @@ dual licensed as above, without any additional terms or conditions. [build-image]: https://github.com/RustCrypto/traits/actions/workflows/signature.yml/badge.svg [build-link]: https://github.com/RustCrypto/traits/actions/workflows/signature.yml [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.71+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.72+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260048-signatures From 07bf35a6c3f276b5f746284032f7604d5c216c91 Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Sat, 20 Jan 2024 15:14:16 +0000 Subject: [PATCH 1138/1461] async-signature: bump `signature` to v2.3.0-pre.2 (#1479) --- Cargo.lock | 5 ++--- Cargo.toml | 3 +++ async-signature/Cargo.toml | 4 ++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1e745bdd8..79faf45a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -56,9 +56,9 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "async-signature" -version = "0.5.0" +version = "0.6.0-pre.0" dependencies = [ - "signature 2.2.0", + "signature 2.3.0-pre.2", ] [[package]] @@ -1245,7 +1245,6 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ - "digest 0.10.7", "rand_core 0.6.4", ] diff --git a/Cargo.toml b/Cargo.toml index a15d8c30d..e1fa03b81 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,3 +14,6 @@ members = [ "signature_derive", "universal-hash", ] + +[patch.crates-io] +signature = { path = "./signature" } diff --git a/async-signature/Cargo.toml b/async-signature/Cargo.toml index e78488d29..8e69d112d 100644 --- a/async-signature/Cargo.toml +++ b/async-signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "async-signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "0.5.0" +version = "0.6.0-pre.0" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/async-signature" @@ -13,7 +13,7 @@ edition = "2021" rust-version = "1.75" [dependencies] -signature = ">= 2.0, <2.3" +signature = "=2.3.0-pre.2" [features] digest = ["signature/digest"] From e5f09700e4ed098182ef28b264ba52951ca33625 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 21 Jan 2024 21:34:45 +0000 Subject: [PATCH 1139/1461] elliptic-curve: `SecretKey::from_slice` timing note (#1480) Adds a note to the documentation that `SecretKey::from_slice` is variable-time with respect to the input size. --- elliptic-curve/src/secret_key.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 722f0197f..02ba9d092 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -158,6 +158,9 @@ where /// `C::FieldBytesSize` bytes in length. /// /// Byte slices shorter than the field size are handled by zero padding the input. + /// + /// NOTE: this function is variable-time with respect to the input length. To avoid a timing + /// sidechannel, always ensure that the input has been pre-padded to `C::FieldBytesSize`. pub fn from_slice(slice: &[u8]) -> Result { if slice.len() == C::FieldBytesSize::USIZE { Self::from_bytes(FieldBytes::::from_slice(slice)) From 7ae1519e7dfcb5557e16f4a5e8c91a08b9db1eb1 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 21 Jan 2024 23:30:42 +0000 Subject: [PATCH 1140/1461] cipher: rename `BlockCipher*`/`BlockMode*` (#1482) Renames the following traits: - `BlockEncrypt` => `BlockCipherEncrypt` - `BlockDecrypt` => `BlockCipherDecrypt` - `BlockEncryptMut` => `BlockModeEncrypt` - `BlockDecryptMut` => `BlockModeDecrypt` As originally suggested in this comment: https://github.com/RustCrypto/block-modes/pull/14#issuecomment-1073304690 This better reflects how these traits are actually used, i.e. `BlockCipher*` is used by ciphers, and `BlockMode*` is used by their modes of operation. Also removes the `*_mut` suffixes from `BlockMode*` methods. --- cipher/src/block.rs | 114 +++++++++++++++++++------------------------ cipher/src/stream.rs | 22 ++++----- 2 files changed, 62 insertions(+), 74 deletions(-) diff --git a/cipher/src/block.rs b/cipher/src/block.rs index f6925ee25..7a691b0e6 100644 --- a/cipher/src/block.rs +++ b/cipher/src/block.rs @@ -78,7 +78,7 @@ pub trait BlockClosure: BlockSizeUser { } /// Encrypt-only functionality for block ciphers. -pub trait BlockEncrypt: BlockSizeUser + Sized { +pub trait BlockCipherEncrypt: BlockSizeUser + Sized { /// Encrypt data using backend provided to the rank-2 closure. fn encrypt_with_backend(&self, f: impl BlockClosure); @@ -189,7 +189,7 @@ pub trait BlockEncrypt: BlockSizeUser + Sized { } /// Decrypt-only functionality for block ciphers. -pub trait BlockDecrypt: BlockSizeUser { +pub trait BlockCipherDecrypt: BlockSizeUser { /// Decrypt data using backend provided to the rank-2 closure. fn decrypt_with_backend(&self, f: impl BlockClosure); @@ -315,41 +315,41 @@ pub trait BlockDecrypt: BlockSizeUser { /// The main use case for this trait is blocks modes, but it also can be used /// for hardware cryptographic engines which require `&mut self` access to an /// underlying hardware peripheral. -pub trait BlockEncryptMut: BlockSizeUser + Sized { +pub trait BlockModeEncrypt: BlockSizeUser + Sized { /// Encrypt data using backend provided to the rank-2 closure. - fn encrypt_with_backend_mut(&mut self, f: impl BlockClosure); + fn encrypt_with_backend(&mut self, f: impl BlockClosure); /// Encrypt single `inout` block. #[inline] - fn encrypt_block_inout_mut(&mut self, block: InOut<'_, '_, Block>) { - self.encrypt_with_backend_mut(BlockCtx { block }); + fn encrypt_block_inout(&mut self, block: InOut<'_, '_, Block>) { + self.encrypt_with_backend(BlockCtx { block }); } /// Encrypt `inout` blocks. #[inline] - fn encrypt_blocks_inout_mut(&mut self, blocks: InOutBuf<'_, '_, Block>) { - self.encrypt_with_backend_mut(BlocksCtx { blocks }); + fn encrypt_blocks_inout(&mut self, blocks: InOutBuf<'_, '_, Block>) { + self.encrypt_with_backend(BlocksCtx { blocks }); } /// Encrypt single block in-place. #[inline] - fn encrypt_block_mut(&mut self, block: &mut Block) { + fn encrypt_block(&mut self, block: &mut Block) { let block = block.into(); - self.encrypt_with_backend_mut(BlockCtx { block }); + self.encrypt_with_backend(BlockCtx { block }); } /// Encrypt `in_block` and write result to `out_block`. #[inline] - fn encrypt_block_b2b_mut(&mut self, in_block: &Block, out_block: &mut Block) { + fn encrypt_block_b2b(&mut self, in_block: &Block, out_block: &mut Block) { let block = (in_block, out_block).into(); - self.encrypt_with_backend_mut(BlockCtx { block }); + self.encrypt_with_backend(BlockCtx { block }); } /// Encrypt blocks in-place. #[inline] - fn encrypt_blocks_mut(&mut self, blocks: &mut [Block]) { + fn encrypt_blocks(&mut self, blocks: &mut [Block]) { let blocks = blocks.into(); - self.encrypt_with_backend_mut(BlocksCtx { blocks }); + self.encrypt_with_backend(BlocksCtx { blocks }); } /// Encrypt blocks buffer-to-buffer. @@ -357,13 +357,13 @@ pub trait BlockEncryptMut: BlockSizeUser + Sized { /// Returns [`NotEqualError`] if provided `in_blocks` and `out_blocks` /// have different lengths. #[inline] - fn encrypt_blocks_b2b_mut( + fn encrypt_blocks_b2b( &mut self, in_blocks: &[Block], out_blocks: &mut [Block], ) -> Result<(), NotEqualError> { InOutBuf::new(in_blocks, out_blocks) - .map(|blocks| self.encrypt_with_backend_mut(BlocksCtx { blocks })) + .map(|blocks| self.encrypt_with_backend(BlocksCtx { blocks })) } /// Pad input and encrypt. Returns resulting ciphertext slice. @@ -371,14 +371,14 @@ pub trait BlockEncryptMut: BlockSizeUser + Sized { /// Returns [`PadError`] if length of output buffer is not sufficient. #[cfg(feature = "block-padding")] #[inline] - fn encrypt_padded_inout_mut<'out, P: Padding>( + fn encrypt_padded_inout<'out, P: Padding>( mut self, data: InOutBufReserved<'_, 'out, u8>, ) -> Result<&'out [u8], PadError> { let mut buf = data.into_padded_blocks::()?; - self.encrypt_blocks_inout_mut(buf.get_blocks()); + self.encrypt_blocks_inout(buf.get_blocks()); if let Some(block) = buf.get_tail_block() { - self.encrypt_block_inout_mut(block); + self.encrypt_block_inout(block); } Ok(buf.into_out()) } @@ -388,13 +388,13 @@ pub trait BlockEncryptMut: BlockSizeUser + Sized { /// Returns [`PadError`] if length of output buffer is not sufficient. #[cfg(feature = "block-padding")] #[inline] - fn encrypt_padded_mut>( + fn encrypt_padded>( self, buf: &mut [u8], msg_len: usize, ) -> Result<&[u8], PadError> { let buf = InOutBufReserved::from_mut_slice(buf, msg_len).map_err(|_| PadError)?; - self.encrypt_padded_inout_mut::

(buf) + self.encrypt_padded_inout::

(buf) } /// Pad input and encrypt buffer-to-buffer. Returns resulting ciphertext slice. @@ -402,22 +402,22 @@ pub trait BlockEncryptMut: BlockSizeUser + Sized { /// Returns [`PadError`] if length of output buffer is not sufficient. #[cfg(feature = "block-padding")] #[inline] - fn encrypt_padded_b2b_mut<'a, P: Padding>( + fn encrypt_padded_b2b<'a, P: Padding>( self, msg: &[u8], out_buf: &'a mut [u8], ) -> Result<&'a [u8], PadError> { let buf = InOutBufReserved::from_slices(msg, out_buf).map_err(|_| PadError)?; - self.encrypt_padded_inout_mut::

(buf) + self.encrypt_padded_inout::

(buf) } /// Pad input and encrypt into a newly allocated Vec. Returns resulting ciphertext Vec. #[cfg(all(feature = "block-padding", feature = "alloc"))] #[inline] - fn encrypt_padded_vec_mut>(self, msg: &[u8]) -> Vec { + fn encrypt_padded_vec>(self, msg: &[u8]) -> Vec { let mut out = allocate_out_vec::(msg.len()); let len = self - .encrypt_padded_b2b_mut::

(msg, &mut out) + .encrypt_padded_b2b::

(msg, &mut out) .expect("enough space for encrypting is allocated") .len(); out.truncate(len); @@ -430,41 +430,41 @@ pub trait BlockEncryptMut: BlockSizeUser + Sized { /// The main use case for this trait is blocks modes, but it also can be used /// for hardware cryptographic engines which require `&mut self` access to an /// underlying hardware peripheral. -pub trait BlockDecryptMut: BlockSizeUser + Sized { +pub trait BlockModeDecrypt: BlockSizeUser + Sized { /// Decrypt data using backend provided to the rank-2 closure. - fn decrypt_with_backend_mut(&mut self, f: impl BlockClosure); + fn decrypt_with_backend(&mut self, f: impl BlockClosure); /// Decrypt single `inout` block. #[inline] - fn decrypt_block_inout_mut(&mut self, block: InOut<'_, '_, Block>) { - self.decrypt_with_backend_mut(BlockCtx { block }); + fn decrypt_block_inout(&mut self, block: InOut<'_, '_, Block>) { + self.decrypt_with_backend(BlockCtx { block }); } /// Decrypt `inout` blocks. #[inline] - fn decrypt_blocks_inout_mut(&mut self, blocks: InOutBuf<'_, '_, Block>) { - self.decrypt_with_backend_mut(BlocksCtx { blocks }); + fn decrypt_blocks_inout(&mut self, blocks: InOutBuf<'_, '_, Block>) { + self.decrypt_with_backend(BlocksCtx { blocks }); } /// Decrypt single block in-place. #[inline] - fn decrypt_block_mut(&mut self, block: &mut Block) { + fn decrypt_block(&mut self, block: &mut Block) { let block = block.into(); - self.decrypt_with_backend_mut(BlockCtx { block }); + self.decrypt_with_backend(BlockCtx { block }); } /// Decrypt `in_block` and write result to `out_block`. #[inline] - fn decrypt_block_b2b_mut(&mut self, in_block: &Block, out_block: &mut Block) { + fn decrypt_block_b2b(&mut self, in_block: &Block, out_block: &mut Block) { let block = (in_block, out_block).into(); - self.decrypt_with_backend_mut(BlockCtx { block }); + self.decrypt_with_backend(BlockCtx { block }); } /// Decrypt blocks in-place. #[inline] - fn decrypt_blocks_mut(&mut self, blocks: &mut [Block]) { + fn decrypt_blocks(&mut self, blocks: &mut [Block]) { let blocks = blocks.into(); - self.decrypt_with_backend_mut(BlocksCtx { blocks }); + self.decrypt_with_backend(BlocksCtx { blocks }); } /// Decrypt blocks buffer-to-buffer. @@ -472,13 +472,13 @@ pub trait BlockDecryptMut: BlockSizeUser + Sized { /// Returns [`NotEqualError`] if provided `in_blocks` and `out_blocks` /// have different lengths. #[inline] - fn decrypt_blocks_b2b_mut( + fn decrypt_blocks_b2b( &mut self, in_blocks: &[Block], out_blocks: &mut [Block], ) -> Result<(), NotEqualError> { InOutBuf::new(in_blocks, out_blocks) - .map(|blocks| self.decrypt_with_backend_mut(BlocksCtx { blocks })) + .map(|blocks| self.decrypt_with_backend(BlocksCtx { blocks })) } /// Decrypt input and unpad it. Returns resulting ciphertext slice. @@ -487,7 +487,7 @@ pub trait BlockDecryptMut: BlockSizeUser + Sized { /// not multiple of `Self::BlockSize`. #[cfg(feature = "block-padding")] #[inline] - fn decrypt_padded_inout_mut<'out, P: Padding>( + fn decrypt_padded_inout<'out, P: Padding>( mut self, data: InOutBuf<'_, 'out, u8>, ) -> Result<&'out [u8], UnpadError> { @@ -495,7 +495,7 @@ pub trait BlockDecryptMut: BlockSizeUser + Sized { if !tail.is_empty() { return Err(UnpadError); } - self.decrypt_blocks_inout_mut(blocks.reborrow()); + self.decrypt_blocks_inout(blocks.reborrow()); P::unpad_blocks(blocks.into_out()) } @@ -505,11 +505,11 @@ pub trait BlockDecryptMut: BlockSizeUser + Sized { /// not multiple of `Self::BlockSize`. #[cfg(feature = "block-padding")] #[inline] - fn decrypt_padded_mut>( + fn decrypt_padded>( self, buf: &mut [u8], ) -> Result<&[u8], UnpadError> { - self.decrypt_padded_inout_mut::

(buf.into()) + self.decrypt_padded_inout::

(buf.into()) } /// Decrypt input and unpad it buffer-to-buffer. Returns resulting @@ -519,7 +519,7 @@ pub trait BlockDecryptMut: BlockSizeUser + Sized { /// not multiple of `Self::BlockSize`. #[cfg(feature = "block-padding")] #[inline] - fn decrypt_padded_b2b_mut<'a, P: Padding>( + fn decrypt_padded_b2b<'a, P: Padding>( self, in_buf: &[u8], out_buf: &'a mut [u8], @@ -530,7 +530,7 @@ pub trait BlockDecryptMut: BlockSizeUser + Sized { let n = in_buf.len(); // note: `new` always returns `Ok` here let buf = InOutBuf::new(in_buf, &mut out_buf[..n]).map_err(|_| UnpadError)?; - self.decrypt_padded_inout_mut::

(buf) + self.decrypt_padded_inout::

(buf) } /// Decrypt input and unpad it in a newly allocated Vec. Returns resulting @@ -540,38 +540,26 @@ pub trait BlockDecryptMut: BlockSizeUser + Sized { /// not multiple of `Self::BlockSize`. #[cfg(all(feature = "block-padding", feature = "alloc"))] #[inline] - fn decrypt_padded_vec_mut>( + fn decrypt_padded_vec>( self, buf: &[u8], ) -> Result, UnpadError> { let mut out = vec![0; buf.len()]; - let len = self.decrypt_padded_b2b_mut::

(buf, &mut out)?.len(); + let len = self.decrypt_padded_b2b::

(buf, &mut out)?.len(); out.truncate(len); Ok(out) } } -impl BlockEncryptMut for Alg { - fn encrypt_with_backend_mut(&mut self, f: impl BlockClosure) { - self.encrypt_with_backend(f); - } -} - -impl BlockDecryptMut for Alg { - fn decrypt_with_backend_mut(&mut self, f: impl BlockClosure) { - self.decrypt_with_backend(f); - } -} - impl BlockCipher for &Alg {} -impl BlockEncrypt for &Alg { +impl BlockCipherEncrypt for &Alg { fn encrypt_with_backend(&self, f: impl BlockClosure) { Alg::encrypt_with_backend(self, f); } } -impl BlockDecrypt for &Alg { +impl BlockCipherDecrypt for &Alg { fn decrypt_with_backend(&self, f: impl BlockClosure) { Alg::decrypt_with_backend(self, f); } @@ -638,7 +626,7 @@ macro_rules! impl_simple_block_encdec { type BlockSize = $block_size; } - impl<$($N$(:$b0$(+$b)*)?),*> $crate::BlockEncrypt for $cipher<$($N),*> { + impl<$($N$(:$b0$(+$b)*)?),*> $crate:BlockEncryptt for $cipher<$($N),*> { fn encrypt_with_backend(&self, f: impl $crate::BlockClosure) { struct EncBack<'a, $($N$(:$b0$(+$b)*)?),* >(&'a $cipher<$($N),*>); @@ -665,7 +653,7 @@ macro_rules! impl_simple_block_encdec { } } - impl<$($N$(:$b0$(+$b)*)?),*> $crate::BlockDecrypt for $cipher<$($N),*> { + impl<$($N$(:$b0$(+$b)*)?),*> $crate:BlockDecryptt for $cipher<$($N),*> { fn decrypt_with_backend(&self, f: impl $crate::BlockClosure) { struct DecBack<'a, $($N$(:$b0$(+$b)*)?),* >(&'a $cipher<$($N),*>); diff --git a/cipher/src/stream.rs b/cipher/src/stream.rs index 2de826332..ac7a2fe5d 100644 --- a/cipher/src/stream.rs +++ b/cipher/src/stream.rs @@ -5,7 +5,7 @@ use crate::errors::{OverflowError, StreamCipherError}; use crate::stream_core::Counter; -use crate::{Block, BlockDecryptMut, BlockEncryptMut}; +use crate::{Block, BlockModeDecrypt, BlockModeEncrypt}; use inout::{InOutBuf, NotEqualError}; /// Marker trait for block-level asynchronous stream ciphers @@ -13,15 +13,15 @@ pub trait AsyncStreamCipher: Sized { /// Encrypt data using `InOutBuf`. fn encrypt_inout(mut self, data: InOutBuf<'_, '_, u8>) where - Self: BlockEncryptMut, + Self: BlockModeEncrypt, { let (blocks, mut tail) = data.into_chunks(); - self.encrypt_blocks_inout_mut(blocks); + self.encrypt_blocks_inout(blocks); let n = tail.len(); if n != 0 { let mut block = Block::::default(); block[..n].copy_from_slice(tail.get_in()); - self.encrypt_block_mut(&mut block); + self.encrypt_block(&mut block); tail.get_out().copy_from_slice(&block[..n]); } } @@ -29,22 +29,22 @@ pub trait AsyncStreamCipher: Sized { /// Decrypt data using `InOutBuf`. fn decrypt_inout(mut self, data: InOutBuf<'_, '_, u8>) where - Self: BlockDecryptMut, + Self: BlockModeDecrypt, { let (blocks, mut tail) = data.into_chunks(); - self.decrypt_blocks_inout_mut(blocks); + self.decrypt_blocks_inout(blocks); let n = tail.len(); if n != 0 { let mut block = Block::::default(); block[..n].copy_from_slice(tail.get_in()); - self.decrypt_block_mut(&mut block); + self.decrypt_block(&mut block); tail.get_out().copy_from_slice(&block[..n]); } } /// Encrypt data in place. fn encrypt(self, buf: &mut [u8]) where - Self: BlockEncryptMut, + Self: BlockModeEncrypt, { self.encrypt_inout(buf.into()); } @@ -52,7 +52,7 @@ pub trait AsyncStreamCipher: Sized { /// Decrypt data in place. fn decrypt(self, buf: &mut [u8]) where - Self: BlockDecryptMut, + Self: BlockModeDecrypt, { self.decrypt_inout(buf.into()); } @@ -60,7 +60,7 @@ pub trait AsyncStreamCipher: Sized { /// Encrypt data from buffer to buffer. fn encrypt_b2b(self, in_buf: &[u8], out_buf: &mut [u8]) -> Result<(), NotEqualError> where - Self: BlockEncryptMut, + Self: BlockModeEncrypt, { InOutBuf::new(in_buf, out_buf).map(|b| self.encrypt_inout(b)) } @@ -68,7 +68,7 @@ pub trait AsyncStreamCipher: Sized { /// Decrypt data from buffer to buffer. fn decrypt_b2b(self, in_buf: &[u8], out_buf: &mut [u8]) -> Result<(), NotEqualError> where - Self: BlockDecryptMut, + Self: BlockModeDecrypt, { InOutBuf::new(in_buf, out_buf).map(|b| self.decrypt_inout(b)) } From 4459f6012afda093816e6a592828a57a8fc366ed Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 22 Jan 2024 00:06:13 +0000 Subject: [PATCH 1141/1461] cipher: followups to #1482 (#1483) The branch was never tested against the block ciphers repo located at https://github.com/rustcrypto/block-ciphers There were various errors and missed changes in macros which were required to get everything to compile. This includes fixes and has been tested against the downstream repo. --- cipher/src/block.rs | 4 ++-- cipher/src/dev/block.rs | 40 ++++++++++++++++++++-------------------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/cipher/src/block.rs b/cipher/src/block.rs index 7a691b0e6..bc0ac183f 100644 --- a/cipher/src/block.rs +++ b/cipher/src/block.rs @@ -626,7 +626,7 @@ macro_rules! impl_simple_block_encdec { type BlockSize = $block_size; } - impl<$($N$(:$b0$(+$b)*)?),*> $crate:BlockEncryptt for $cipher<$($N),*> { + impl<$($N$(:$b0$(+$b)*)?),*> $crate::BlockCipherEncrypt for $cipher<$($N),*> { fn encrypt_with_backend(&self, f: impl $crate::BlockClosure) { struct EncBack<'a, $($N$(:$b0$(+$b)*)?),* >(&'a $cipher<$($N),*>); @@ -653,7 +653,7 @@ macro_rules! impl_simple_block_encdec { } } - impl<$($N$(:$b0$(+$b)*)?),*> $crate:BlockDecryptt for $cipher<$($N),*> { + impl<$($N$(:$b0$(+$b)*)?),*> $crate::BlockCipherDecrypt for $cipher<$($N),*> { fn decrypt_with_backend(&self, f: impl $crate::BlockClosure) { struct DecBack<'a, $($N$(:$b0$(+$b)*)?),* >(&'a $cipher<$($N),*>); diff --git a/cipher/src/dev/block.rs b/cipher/src/dev/block.rs index 70594755c..a05886dc3 100644 --- a/cipher/src/dev/block.rs +++ b/cipher/src/dev/block.rs @@ -7,20 +7,20 @@ macro_rules! block_cipher_test { #[test] fn $name() { use cipher::{ - array::Array, blobby::Blob3Iterator, typenum::Unsigned, BlockDecryptMut, - BlockEncryptMut, BlockSizeUser, KeyInit, + array::Array, blobby::Blob3Iterator, typenum::Unsigned, BlockCipherDecrypt, + BlockCipherEncrypt, BlockSizeUser, KeyInit, }; fn run_test(key: &[u8], pt: &[u8], ct: &[u8]) -> bool { let mut state = <$cipher as KeyInit>::new_from_slice(key).unwrap(); let mut block = Array::clone_from_slice(pt); - state.encrypt_block_mut(&mut block); + state.encrypt_block(&mut block); if ct != block.as_slice() { return false; } - state.decrypt_block_mut(&mut block); + state.decrypt_block(&mut block); if pt != block.as_slice() { return false; } @@ -43,9 +43,9 @@ macro_rules! block_cipher_test { // check that `encrypt_blocks` and `encrypt_block` // result in the same ciphertext - state.encrypt_blocks_mut(&mut blocks1); + state.encrypt_blocks(&mut blocks1); for b in blocks2.iter_mut() { - state.encrypt_block_mut(b); + state.encrypt_block(b); } if blocks1 != blocks2 { return false; @@ -53,9 +53,9 @@ macro_rules! block_cipher_test { // check that `encrypt_blocks` and `encrypt_block` // result in the same plaintext - state.decrypt_blocks_mut(&mut blocks1); + state.decrypt_blocks(&mut blocks1); for b in blocks2.iter_mut() { - state.decrypt_block_mut(b); + state.decrypt_block(b); } if blocks1 != blocks2 { return false; @@ -102,7 +102,7 @@ macro_rules! block_mode_enc_test { fn $name() { use cipher::{ array::Array, blobby::Blob4Iterator, inout::InOutBuf, typenum::Unsigned, - BlockEncryptMut, BlockSizeUser, KeyIvInit, + BlockCipherEncrypt, BlockSizeUser, KeyIvInit, }; fn run_test(key: &[u8], iv: &[u8], pt: &[u8], ct: &[u8]) -> bool { @@ -160,7 +160,7 @@ macro_rules! block_mode_dec_test { fn $name() { use cipher::{ array::Array, blobby::Blob4Iterator, inout::InOutBuf, typenum::Unsigned, - BlockDecryptMut, BlockSizeUser, KeyIvInit, + BlockCipherDecrypt, BlockSizeUser, KeyIvInit, }; fn run_test(key: &[u8], iv: &[u8], pt: &[u8], ct: &[u8]) -> bool { @@ -214,10 +214,10 @@ macro_rules! block_mode_dec_test { #[macro_export] macro_rules! iv_state_test { ($name:ident, $cipher:ty, encrypt $(,)?) => { - $crate::iv_state_test!($name, $cipher, encrypt_blocks_mut); + $crate::iv_state_test!($name, $cipher, encrypt_blocks); }; ($name:ident, $cipher:ty, decrypt $(,)?) => { - $crate::iv_state_test!($name, $cipher, decrypt_blocks_mut); + $crate::iv_state_test!($name, $cipher, decrypt_blocks); }; ($name:ident, $cipher:ty, apply_ks $(,)?) => { $crate::iv_state_test!($name, $cipher, apply_keystream_blocks); @@ -289,14 +289,14 @@ macro_rules! block_encryptor_bench { ($init:block, $cipher:ty, $block_name:ident, $blocks_name:ident $(,)? ) => { #[bench] pub fn $block_name(bh: &mut test::Bencher) { - use cipher::BlockEncryptMut; + use cipher::BlockCipherEncrypt; let mut cipher = $init; let mut blocks = vec![Default::default(); 1024]; bh.iter(|| { for block in blocks.iter_mut() { - cipher.encrypt_block_mut(block); + cipher.encrypt_block(block); } test::black_box(&blocks); }); @@ -305,13 +305,13 @@ macro_rules! block_encryptor_bench { #[bench] pub fn $blocks_name(bh: &mut test::Bencher) { - use cipher::BlockEncryptMut; + use cipher::BlockCipherEncrypt; let mut cipher = $init; let mut blocks = vec![Default::default(); 1024]; bh.iter(|| { - cipher.encrypt_blocks_mut(&mut blocks); + cipher.encrypt_blocks(&mut blocks); test::black_box(&blocks); }); bh.bytes = (blocks.len() * blocks[0].len()) as u64; @@ -350,14 +350,14 @@ macro_rules! block_decryptor_bench { ($init:block, $cipher:ty, $block_name:ident, $blocks_name:ident $(,)? ) => { #[bench] pub fn $block_name(bh: &mut test::Bencher) { - use cipher::BlockDecryptMut; + use cipher::BlockCipherDecrypt; let mut cipher = $init; let mut blocks = vec![Default::default(); 1024]; bh.iter(|| { for block in blocks.iter_mut() { - cipher.decrypt_block_mut(block); + cipher.decrypt_block(block); } test::black_box(&blocks); }); @@ -366,13 +366,13 @@ macro_rules! block_decryptor_bench { #[bench] pub fn $blocks_name(bh: &mut test::Bencher) { - use cipher::BlockDecryptMut; + use cipher::BlockCipherDecrypt; let mut cipher = $init; let mut blocks = vec![Default::default(); 1024]; bh.iter(|| { - cipher.decrypt_blocks_mut(&mut blocks); + cipher.decrypt_blocks(&mut blocks); test::black_box(&blocks); }); bh.bytes = (blocks.len() * blocks[0].len()) as u64; From 260e3e54aac5500b122030554f8afc3265427a78 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jan 2024 15:15:49 -0700 Subject: [PATCH 1142/1461] build(deps): bump actions/cache from 3 to 4 (#1485) Bumps [actions/cache](https://github.com/actions/cache) from 3 to 4. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/security-audit.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/security-audit.yml b/.github/workflows/security-audit.yml index 8dd60ff37..6eaf0e52b 100644 --- a/.github/workflows/security-audit.yml +++ b/.github/workflows/security-audit.yml @@ -15,7 +15,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Cache cargo bin - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ~/.cargo/bin key: ${{ runner.os }}-cargo-audit-v0.12.0 @@ -32,7 +32,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Cache cargo bin - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ~/.cargo/bin key: ${{ runner.os }}-cargo-audit-v0.12.0 @@ -49,7 +49,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Cache cargo bin - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ~/.cargo/bin key: ${{ runner.os }}-cargo-audit-v0.12.0 @@ -66,7 +66,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Cache cargo bin - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ~/.cargo/bin key: ${{ runner.os }}-cargo-audit-v0.12.0 @@ -83,7 +83,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Cache cargo bin - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ~/.cargo/bin key: ${{ runner.os }}-cargo-audit-v0.12.0 From 3e13141067d149b92535e5a8654f1f07119b7f42 Mon Sep 17 00:00:00 2001 From: Krysztal112233 Date: Wed, 24 Jan 2024 01:40:57 +0800 Subject: [PATCH 1143/1461] Fix typo in `password-hash/src/errors.rs` (#1486) Expecrted -> Expected --- password-hash/src/errors.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/password-hash/src/errors.rs b/password-hash/src/errors.rs index e43350617..c48a28dfe 100644 --- a/password-hash/src/errors.rs +++ b/password-hash/src/errors.rs @@ -32,7 +32,7 @@ pub enum Error { /// Expected output size in relation to `provided`. /// /// - [`Ordering::Less`]: Minimum size. - /// - [`Ordering::Equal`]: Expecrted size. + /// - [`Ordering::Equal`]: Expected size. /// - [`Ordering::Greater`]: Maximum size. expected: usize, }, From 1568df82f28545a4ec02fe71abf793bed6302e80 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 27 Jan 2024 01:53:01 +0000 Subject: [PATCH 1144/1461] CI: move `doc` job to workspace level (#1489) This should fix the error we're encountering in #1487, and at the same time also check all crates have valid documentation, rather than just `elliptic-curve` and `signature`. --- .github/workflows/elliptic-curve.yml | 9 --------- .github/workflows/signature.yml | 9 --------- .github/workflows/workspace.yml | 11 +++++++++-- 3 files changed, 9 insertions(+), 20 deletions(-) diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index 5c6bc098b..6161f6b80 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -89,12 +89,3 @@ jobs: - run: cargo test --no-default-features - run: cargo test - run: cargo test --all-features - - doc: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@master - with: - toolchain: stable - - run: cargo doc --all-features diff --git a/.github/workflows/signature.yml b/.github/workflows/signature.yml index 2a9e1af3c..fba9726b3 100644 --- a/.github/workflows/signature.yml +++ b/.github/workflows/signature.yml @@ -80,12 +80,3 @@ jobs: toolchain: ${{ matrix.rust }} - run: cargo test --release working-directory: signature_derive - - doc: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@master - with: - toolchain: stable - - run: cargo doc --all-features diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index d0840aed0..1bffd0413 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -5,13 +5,11 @@ on: paths-ignore: - '**/README.md' - '**/CHANGELOG.md' - - .github/** push: branches: master paths-ignore: - '**/README.md' - '**/CHANGELOG.md' - - .github/** env: CARGO_INCREMENTAL: 0 @@ -30,6 +28,15 @@ jobs: components: clippy - run: cargo clippy --all --all-features --tests -- -D warnings + doc: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@master + with: + toolchain: stable + - run: cargo doc --all-features + rustfmt: runs-on: ubuntu-latest steps: From d622f977922546fa8a80f315b8766cfa4d0452a2 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 27 Jan 2024 02:04:26 +0000 Subject: [PATCH 1145/1461] crypto-common: rename `serializable_state` module to `hazmat` (#1487) Also removes the toplevel re-exports for the traits, forcing users to go through the now `pub hazmat` module. There's a lot of misuse potential with these traits, which are intended to make it possible to serialize/deserialize the internal state of hash functions. However previously they were presented side-by-side with other traits, which made that unclear. This commit deliberately doesn't make other changes to the file so git will preserve its history: diff --git a/crypto-common/src/serializable_state.rs b/crypto-common/src/hazmat.rs similarity index 100% rename from crypto-common/src/serializable_state.rs rename to crypto-common/src/hazmat.rs It would be very good for a followup commit to massively expand the documentation around both the module and the traits, especially to spell out the various ways they can be misused. --- Cargo.lock | 43 +++++-------------- Cargo.toml | 2 + .../src/{serializable_state.rs => hazmat.rs} | 0 crypto-common/src/lib.rs | 9 ++-- digest/src/core_api/ct_variable.rs | 4 +- digest/src/core_api/rt_variable.rs | 4 +- digest/src/core_api/wrapper.rs | 4 +- 7 files changed, 21 insertions(+), 45 deletions(-) rename crypto-common/src/{serializable_state.rs => hazmat.rs} (100%) diff --git a/Cargo.lock b/Cargo.lock index 79faf45a6..2ecedf269 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,7 +19,7 @@ dependencies = [ "arrayvec", "blobby", "bytes", - "crypto-common 0.2.0-pre.4 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.2.0-pre.4", "heapless", ] @@ -136,7 +136,7 @@ version = "0.11.0-pre.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0edadbde8e0243b49d434f9a23ec0590af201f400a34d7d51049284e4a77c568" dependencies = [ - "crypto-common 0.2.0-pre.4 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.2.0-pre.4", "zeroize", ] @@ -226,7 +226,7 @@ name = "cipher" version = "0.5.0-pre.2" dependencies = [ "blobby", - "crypto-common 0.2.0-pre.4 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.2.0-pre.4", "inout 0.2.0-pre.4", "zeroize", ] @@ -341,17 +341,6 @@ dependencies = [ "rand_core 0.6.4", ] -[[package]] -name = "crypto-common" -version = "0.2.0-pre.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "806e4e3731d44f1340b069551225b44c2056c105cad9e67f0c46266db8a3a6b9" -dependencies = [ - "getrandom", - "hybrid-array", - "rand_core 0.6.4", -] - [[package]] name = "crypto-mac" version = "0.11.0" @@ -450,23 +439,11 @@ dependencies = [ "blobby", "block-buffer 0.11.0-pre.4", "const-oid 0.10.0-pre.2", - "crypto-common 0.2.0-pre.4 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.2.0-pre.4", "subtle", "zeroize", ] -[[package]] -name = "digest" -version = "0.11.0-pre.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "957713a19ffdda287c63772e607f848512f67ba948f17d8e42cb8d50fd98a786" -dependencies = [ - "block-buffer 0.11.0-pre.4", - "const-oid 0.10.0-pre.2", - "crypto-common 0.2.0-pre.4 (registry+https://github.com/rust-lang/crates.io-index)", - "subtle", -] - [[package]] name = "dunce" version = "1.0.4" @@ -546,7 +523,7 @@ dependencies = [ "base16ct 0.2.0", "base64ct", "crypto-bigint 0.6.0-pre.12", - "digest 0.11.0-pre.7 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.11.0-pre.7", "ff 0.13.0", "group 0.13.0", "hex-literal", @@ -751,7 +728,7 @@ version = "0.13.0-pre.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fac01891f12d968a2737928c9af2532abdc750e56a890fdbcafdfff17017678" dependencies = [ - "digest 0.11.0-pre.7 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.11.0-pre.7", ] [[package]] @@ -1216,7 +1193,7 @@ checksum = "e18b939d4051b69874cbdb8f55de6a14ae44b357ccb94bdbd0a2122f8f875a46" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.11.0-pre.7 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.11.0-pre.7", ] [[package]] @@ -1225,7 +1202,7 @@ version = "0.11.0-pre.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9cecb44e361133b3304a1b3e325a1d8c999339fec8c19762b55e1509a17d6806" dependencies = [ - "digest 0.11.0-pre.7 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.11.0-pre.7", "keccak", ] @@ -1252,7 +1229,7 @@ dependencies = [ name = "signature" version = "2.3.0-pre.2" dependencies = [ - "digest 0.11.0-pre.7 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.11.0-pre.7", "hex-literal", "rand_core 0.6.4", "sha2 0.11.0-pre.2", @@ -1352,7 +1329,7 @@ dependencies = [ name = "universal-hash" version = "0.6.0-pre" dependencies = [ - "crypto-common 0.2.0-pre.4 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.2.0-pre.4", "subtle", ] diff --git a/Cargo.toml b/Cargo.toml index e1fa03b81..354080ca9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,4 +16,6 @@ members = [ ] [patch.crates-io] +crypto-common = { path = "./crypto-common" } +digest = { path = "./digest" } signature = { path = "./signature" } diff --git a/crypto-common/src/serializable_state.rs b/crypto-common/src/hazmat.rs similarity index 100% rename from crypto-common/src/serializable_state.rs rename to crypto-common/src/hazmat.rs diff --git a/crypto-common/src/lib.rs b/crypto-common/src/lib.rs index bdaff2cdd..45ee05534 100644 --- a/crypto-common/src/lib.rs +++ b/crypto-common/src/lib.rs @@ -12,6 +12,9 @@ #[cfg(feature = "std")] extern crate std; +/// Hazardous materials. +pub mod hazmat; + #[cfg(feature = "getrandom")] pub use getrandom; #[cfg(feature = "rand_core")] @@ -29,12 +32,6 @@ use hybrid_array::{ #[cfg(feature = "rand_core")] use rand_core::CryptoRngCore; -mod serializable_state; -pub use serializable_state::{ - AddSerializedStateSize, DeserializeStateError, SerializableState, SerializedState, - SubSerializedStateSize, -}; - /// Block on which [`BlockSizeUser`] implementors operate. pub type Block = Array::BlockSize>; diff --git a/digest/src/core_api/ct_variable.rs b/digest/src/core_api/ct_variable.rs index fe3aa86c1..fe917bfd8 100644 --- a/digest/src/core_api/ct_variable.rs +++ b/digest/src/core_api/ct_variable.rs @@ -14,9 +14,9 @@ use core::{ }; use crypto_common::{ array::{Array, ArraySize}, + hazmat::{DeserializeStateError, SerializableState, SerializedState, SubSerializedStateSize}, typenum::{IsLess, IsLessOrEqual, Le, LeEq, NonZero, Sum, U1, U256}, - Block, BlockSizeUser, DeserializeStateError, OutputSizeUser, SerializableState, - SerializedState, SubSerializedStateSize, + Block, BlockSizeUser, OutputSizeUser, }; /// Dummy type used with [`CtVariableCoreWrapper`] in cases when diff --git a/digest/src/core_api/rt_variable.rs b/digest/src/core_api/rt_variable.rs index c9631e922..ccbb563aa 100644 --- a/digest/src/core_api/rt_variable.rs +++ b/digest/src/core_api/rt_variable.rs @@ -9,11 +9,11 @@ use core::{ fmt, ops::{Add, Sub}, }; -use crypto_common::SubSerializedStateSize; use crypto_common::{ array::{Array, ArraySize}, + hazmat::{DeserializeStateError, SerializableState, SerializedState, SubSerializedStateSize}, typenum::{Diff, IsLess, Le, NonZero, Sum, Unsigned, U1, U256}, - AddBlockSize, DeserializeStateError, SerializableState, SerializedState, SubBlockSize, + AddBlockSize, SubBlockSize, }; #[cfg(feature = "zeroize")] use zeroize::ZeroizeOnDrop; diff --git a/digest/src/core_api/wrapper.rs b/digest/src/core_api/wrapper.rs index fc3ca9d90..32b8a5a1c 100644 --- a/digest/src/core_api/wrapper.rs +++ b/digest/src/core_api/wrapper.rs @@ -13,9 +13,9 @@ use core::{ }; use crypto_common::{ array::{Array, ArraySize}, + hazmat::{DeserializeStateError, SerializableState, SerializedState, SubSerializedStateSize}, typenum::{Diff, IsLess, Le, NonZero, Sum, U1, U256}, - BlockSizeUser, DeserializeStateError, InvalidLength, Key, KeyInit, KeySizeUser, Output, - SerializableState, SerializedState, SubSerializedStateSize, + BlockSizeUser, InvalidLength, Key, KeyInit, KeySizeUser, Output, }; #[cfg(feature = "mac")] From 02c85e1b9ad36a193af120869bc5e9012ac50d69 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 27 Jan 2024 15:35:31 +0000 Subject: [PATCH 1146/1461] Bump `hybrid-array` to v0.2.0-rc.2 (#1490) Mostly to spot regressions. Seems like this should be compatible. --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2ecedf269..9bfc7a4b5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -755,9 +755,9 @@ dependencies = [ [[package]] name = "hybrid-array" -version = "0.2.0-rc.1" +version = "0.2.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b700a69c9d992339e82b6cda619873ee17768be06e80ed5ef07c50c50d499ab" +checksum = "662b1e7b4a15dc889bf687cdd5dc4291b278ad0cf546424a87721dcb54ff1d82" dependencies = [ "typenum", "zeroize", From 8ff7c6fdf0774326f6e06fc01f5173def9e17ea5 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 28 Jan 2024 19:00:12 -0700 Subject: [PATCH 1147/1461] Bump `hybrid-array` to v0.2.0-rc.3 (#1491) --- Cargo.lock | 7 +++---- Cargo.toml | 1 + 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9bfc7a4b5..0368ee654 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -755,9 +755,9 @@ dependencies = [ [[package]] name = "hybrid-array" -version = "0.2.0-rc.2" +version = "0.2.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "662b1e7b4a15dc889bf687cdd5dc4291b278ad0cf546424a87721dcb54ff1d82" +checksum = "d8856b3db5eb76328f03589feb25c7a3166bfa0ae3b38b1408d546b097fa7947" dependencies = [ "typenum", "zeroize", @@ -1188,8 +1188,7 @@ dependencies = [ [[package]] name = "sha2" version = "0.11.0-pre.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e18b939d4051b69874cbdb8f55de6a14ae44b357ccb94bdbd0a2122f8f875a46" +source = "git+https://github.com/RustCrypto/hashes.git#9130e96e88908905e2c1b6afbbd34c27f85adac6" dependencies = [ "cfg-if", "cpufeatures", diff --git a/Cargo.toml b/Cargo.toml index 354080ca9..6f405fee2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,3 +19,4 @@ members = [ crypto-common = { path = "./crypto-common" } digest = { path = "./digest" } signature = { path = "./signature" } +sha2 = { git = "https://github.com/RustCrypto/hashes.git" } From 39a78209b3a4b180df1d0f6c994ce5cac7f16dcc Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 31 Jan 2024 09:54:23 -0700 Subject: [PATCH 1148/1461] Bump `hybrid-array` to v0.2.0-rc.4 (#1493) --- Cargo.lock | 4 ++-- cipher/src/stream_core.rs | 8 ++------ crypto-common/Cargo.toml | 2 +- universal-hash/src/lib.rs | 4 ++-- 4 files changed, 7 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0368ee654..3d895f0e9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -755,9 +755,9 @@ dependencies = [ [[package]] name = "hybrid-array" -version = "0.2.0-rc.3" +version = "0.2.0-rc.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8856b3db5eb76328f03589feb25c7a3166bfa0ae3b38b1408d546b097fa7947" +checksum = "18e63b66aee2df5599ba69b17a48113dfc68d2e143ea387ef836509e433bbd7e" dependencies = [ "typenum", "zeroize", diff --git a/cipher/src/stream_core.rs b/cipher/src/stream_core.rs index 84d21350c..c121ca46a 100644 --- a/cipher/src/stream_core.rs +++ b/cipher/src/stream_core.rs @@ -1,9 +1,5 @@ use crate::{ParBlocks, ParBlocksSizeUser, StreamCipherError}; -use crypto_common::{ - array::{slice_as_chunks_mut, Array}, - typenum::Unsigned, - Block, BlockSizeUser, BlockSizes, -}; +use crypto_common::{array::Array, typenum::Unsigned, Block, BlockSizeUser, BlockSizes}; use inout::{InOut, InOutBuf}; /// Trait implemented by stream cipher backends. @@ -213,7 +209,7 @@ impl<'a, BS: BlockSizes> StreamClosure for WriteBlocksCtx<'a, BS> { #[inline(always)] fn call>(self, backend: &mut B) { if B::ParBlocksSize::USIZE > 1 { - let (chunks, tail) = slice_as_chunks_mut(self.blocks); + let (chunks, tail) = Array::slice_as_chunks_mut(self.blocks); for chunk in chunks { backend.gen_par_ks_blocks(chunk); } diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index 86bd2f045..36de6fc9e 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -13,7 +13,7 @@ keywords = ["crypto", "traits"] categories = ["cryptography", "no-std"] [dependencies] -hybrid-array = "0.2.0-rc.0" +hybrid-array = "0.2.0-rc.4" # optional dependencies rand_core = { version = "0.6.4", optional = true } diff --git a/universal-hash/src/lib.rs b/universal-hash/src/lib.rs index 0cfa03a5a..44b59686c 100644 --- a/universal-hash/src/lib.rs +++ b/universal-hash/src/lib.rs @@ -73,7 +73,7 @@ pub trait UniversalHash: BlockSizeUser + Sized { fn call>(self, backend: &mut B) { let pb = B::ParBlocksSize::USIZE; if pb > 1 { - let (par_blocks, tail) = array::slice_as_chunks(self.blocks); + let (par_blocks, tail) = Array::slice_as_chunks(self.blocks); for par_block in par_blocks { backend.proc_par_blocks(par_block); } @@ -99,7 +99,7 @@ pub trait UniversalHash: BlockSizeUser + Sized { /// Message Authentication Codes (MACs) based on universal hashing. #[inline] fn update_padded(&mut self, data: &[u8]) { - let (blocks, tail) = array::slice_as_chunks(data); + let (blocks, tail) = Array::slice_as_chunks(data); self.update(blocks); From 4646f4559be8c7e0f95e815ddd9f9fa998749299 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 1 Feb 2024 10:59:45 -0700 Subject: [PATCH 1149/1461] crypto-common v0.2.0-pre.5 (#1496) --- Cargo.lock | 29 ++++++++++++++++++++--------- Cargo.toml | 1 - aead/Cargo.toml | 2 +- cipher/Cargo.toml | 2 +- crypto-common/Cargo.toml | 2 +- digest/Cargo.toml | 4 ++-- universal-hash/Cargo.toml | 2 +- 7 files changed, 26 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3d895f0e9..7037e181e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,7 +19,7 @@ dependencies = [ "arrayvec", "blobby", "bytes", - "crypto-common 0.2.0-pre.4", + "crypto-common 0.2.0-pre.5 (registry+https://github.com/rust-lang/crates.io-index)", "heapless", ] @@ -132,11 +132,11 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.11.0-pre.4" +version = "0.11.0-pre.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0edadbde8e0243b49d434f9a23ec0590af201f400a34d7d51049284e4a77c568" +checksum = "3ded684142010808eb980d9974ef794da2bcf97d13396143b1515e9f0fb4a10e" dependencies = [ - "crypto-common 0.2.0-pre.4", + "crypto-common 0.2.0-pre.5 (registry+https://github.com/rust-lang/crates.io-index)", "zeroize", ] @@ -226,7 +226,7 @@ name = "cipher" version = "0.5.0-pre.2" dependencies = [ "blobby", - "crypto-common 0.2.0-pre.4", + "crypto-common 0.2.0-pre.5 (registry+https://github.com/rust-lang/crates.io-index)", "inout 0.2.0-pre.4", "zeroize", ] @@ -334,7 +334,18 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.2.0-pre.4" +version = "0.2.0-pre.5" +dependencies = [ + "getrandom", + "hybrid-array", + "rand_core 0.6.4", +] + +[[package]] +name = "crypto-common" +version = "0.2.0-pre.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7aa2ec04f5120b830272a481e8d9d8ba4dda140d2cda59b0f1110d5eb93c38e" dependencies = [ "getrandom", "hybrid-array", @@ -437,9 +448,9 @@ name = "digest" version = "0.11.0-pre.7" dependencies = [ "blobby", - "block-buffer 0.11.0-pre.4", + "block-buffer 0.11.0-pre.5", "const-oid 0.10.0-pre.2", - "crypto-common 0.2.0-pre.4", + "crypto-common 0.2.0-pre.5 (registry+https://github.com/rust-lang/crates.io-index)", "subtle", "zeroize", ] @@ -1328,7 +1339,7 @@ dependencies = [ name = "universal-hash" version = "0.6.0-pre" dependencies = [ - "crypto-common 0.2.0-pre.4", + "crypto-common 0.2.0-pre.5 (registry+https://github.com/rust-lang/crates.io-index)", "subtle", ] diff --git a/Cargo.toml b/Cargo.toml index 6f405fee2..632ba9fd6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,6 @@ members = [ ] [patch.crates-io] -crypto-common = { path = "./crypto-common" } digest = { path = "./digest" } signature = { path = "./signature" } sha2 = { git = "https://github.com/RustCrypto/hashes.git" } diff --git a/aead/Cargo.toml b/aead/Cargo.toml index f92036811..184ac4107 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -16,7 +16,7 @@ categories = ["cryptography", "no-std"] rust-version = "1.65" [dependencies] -crypto-common = "=0.2.0-pre.4" +crypto-common = "=0.2.0-pre.5" # optional dependencies arrayvec = { version = "0.7", optional = true, default-features = false } diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index b998b22a5..638e6f18f 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -13,7 +13,7 @@ keywords = ["crypto", "block-cipher", "stream-cipher", "trait"] categories = ["cryptography", "no-std"] [dependencies] -crypto-common = "=0.2.0-pre.4" +crypto-common = "=0.2.0-pre.5" inout = "=0.2.0-pre.4" # optional dependencies diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index 36de6fc9e..199e7f0d5 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crypto-common" description = "Common cryptographic traits" -version = "0.2.0-pre.4" +version = "0.2.0-pre.5" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 880fe5548..bed94be7d 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -13,10 +13,10 @@ keywords = ["digest", "crypto", "hash"] categories = ["cryptography", "no-std"] [dependencies] -crypto-common = "=0.2.0-pre.4" +crypto-common = "=0.2.0-pre.5" # optional dependencies -block-buffer = { version = "=0.11.0-pre.4", optional = true } +block-buffer = { version = "=0.11.0-pre.5", optional = true } subtle = { version = "2.4", default-features = false, optional = true } blobby = { version = "0.3", optional = true } const-oid = { version = "=0.10.0-pre.2", optional = true } diff --git a/universal-hash/Cargo.toml b/universal-hash/Cargo.toml index dafe0fd36..e61fb1e2e 100644 --- a/universal-hash/Cargo.toml +++ b/universal-hash/Cargo.toml @@ -13,7 +13,7 @@ keywords = ["crypto", "mac"] categories = ["cryptography", "no-std"] [dependencies] -crypto-common = "=0.2.0-pre.4" +crypto-common = "=0.2.0-pre.5" subtle = { version = "2.4", default-features = false } [features] From 59d12275849f63301df965050c1907836ae12f5a Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 1 Feb 2024 11:16:38 -0700 Subject: [PATCH 1150/1461] cipher v0.5.0-pre.3 (#1497) --- Cargo.lock | 2 +- cipher/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7037e181e..33bb3515b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -223,7 +223,7 @@ dependencies = [ [[package]] name = "cipher" -version = "0.5.0-pre.2" +version = "0.5.0-pre.3" dependencies = [ "blobby", "crypto-common 0.2.0-pre.5 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index 638e6f18f..99661986d 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "cipher" description = "Traits for describing block ciphers and stream ciphers" -version = "0.5.0-pre.2" +version = "0.5.0-pre.3" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" From d627c598e5ac1ec3232c38198d1ab25c39a4c799 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 1 Feb 2024 15:01:26 -0700 Subject: [PATCH 1151/1461] digest v0.11.0-pre.8 (#1498) --- Cargo.lock | 49 +++++++++++++++++++++++++-------------- Cargo.toml | 2 -- digest/Cargo.toml | 2 +- elliptic-curve/Cargo.toml | 8 +++---- signature/Cargo.toml | 4 ++-- 5 files changed, 38 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 33bb3515b..8f2926aff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -445,7 +445,7 @@ dependencies = [ [[package]] name = "digest" -version = "0.11.0-pre.7" +version = "0.11.0-pre.8" dependencies = [ "blobby", "block-buffer 0.11.0-pre.5", @@ -455,6 +455,18 @@ dependencies = [ "zeroize", ] +[[package]] +name = "digest" +version = "0.11.0-pre.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "065d93ead7c220b85d5b4be4795d8398eac4ff68b5ee63895de0a3c1fb6edf25" +dependencies = [ + "block-buffer 0.11.0-pre.5", + "const-oid 0.10.0-pre.2", + "crypto-common 0.2.0-pre.5 (registry+https://github.com/rust-lang/crates.io-index)", + "subtle", +] + [[package]] name = "dunce" version = "1.0.4" @@ -534,11 +546,11 @@ dependencies = [ "base16ct 0.2.0", "base64ct", "crypto-bigint 0.6.0-pre.12", - "digest 0.11.0-pre.7", + "digest 0.11.0-pre.8 (registry+https://github.com/rust-lang/crates.io-index)", "ff 0.13.0", "group 0.13.0", "hex-literal", - "hkdf 0.13.0-pre.2", + "hkdf 0.13.0-pre.3", "hybrid-array", "pem-rfc7468 1.0.0-pre.0", "pkcs8 0.11.0-pre.0", @@ -546,7 +558,7 @@ dependencies = [ "sec1 0.8.0-pre.1", "serde_json", "serdect", - "sha2 0.11.0-pre.2", + "sha2 0.11.0-pre.3", "sha3", "subtle", "tap", @@ -707,11 +719,11 @@ dependencies = [ [[package]] name = "hkdf" -version = "0.13.0-pre.2" +version = "0.13.0-pre.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c524b31a8b37d9561e29293b5931461f0bb72a75101f3916e1480525113da8e9" +checksum = "fd5d615ab5c462f96c309b3a00b19f373025a4981312f717f9df5bbd0201530c" dependencies = [ - "hmac 0.13.0-pre.2", + "hmac 0.13.0-pre.3", ] [[package]] @@ -735,11 +747,11 @@ dependencies = [ [[package]] name = "hmac" -version = "0.13.0-pre.2" +version = "0.13.0-pre.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fac01891f12d968a2737928c9af2532abdc750e56a890fdbcafdfff17017678" +checksum = "ffd790a0795ee332ed3e8959e5b177beb70d7112eb7d345428ec17427897d5ce" dependencies = [ - "digest 0.11.0-pre.7", + "digest 0.11.0-pre.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1198,21 +1210,22 @@ dependencies = [ [[package]] name = "sha2" -version = "0.11.0-pre.2" -source = "git+https://github.com/RustCrypto/hashes.git#9130e96e88908905e2c1b6afbbd34c27f85adac6" +version = "0.11.0-pre.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f33549bf3064b62478926aa89cbfc7c109aab66ae8f0d5d2ef839e482cc30d6" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.11.0-pre.7", + "digest 0.11.0-pre.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "sha3" -version = "0.11.0-pre.2" +version = "0.11.0-pre.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cecb44e361133b3304a1b3e325a1d8c999339fec8c19762b55e1509a17d6806" +checksum = "f32c02b9987a647a3d6af14c3e88df86594e4283050d9d8ee3a035df247785b9" dependencies = [ - "digest 0.11.0-pre.7", + "digest 0.11.0-pre.8 (registry+https://github.com/rust-lang/crates.io-index)", "keccak", ] @@ -1239,10 +1252,10 @@ dependencies = [ name = "signature" version = "2.3.0-pre.2" dependencies = [ - "digest 0.11.0-pre.7", + "digest 0.11.0-pre.8 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal", "rand_core 0.6.4", - "sha2 0.11.0-pre.2", + "sha2 0.11.0-pre.3", "signature_derive", ] diff --git a/Cargo.toml b/Cargo.toml index 632ba9fd6..e1fa03b81 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,4 @@ members = [ ] [patch.crates-io] -digest = { path = "./digest" } signature = { path = "./signature" } -sha2 = { git = "https://github.com/RustCrypto/hashes.git" } diff --git a/digest/Cargo.toml b/digest/Cargo.toml index bed94be7d..848216478 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "digest" description = "Traits for cryptographic hash functions and message authentication codes" -version = "0.11.0-pre.7" +version = "0.11.0-pre.8" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 8cb5b5995..a940521eb 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -25,10 +25,10 @@ zeroize = { version = "1.7", default-features = false } # optional dependencies base64ct = { version = "1", optional = true, default-features = false, features = ["alloc"] } -digest = { version = "=0.11.0-pre.7", optional = true } +digest = { version = "=0.11.0-pre.8", optional = true } ff = { version = "0.13", optional = true, default-features = false } group = { version = "0.13", optional = true, default-features = false } -hkdf = { version = "=0.13.0-pre.2", optional = true, default-features = false } +hkdf = { version = "=0.13.0-pre.3", optional = true, default-features = false } hex-literal = { version = "0.4", optional = true } pem-rfc7468 = { version = "=1.0.0-pre.0", optional = true, features = ["alloc"] } pkcs8 = { version = "=0.11.0-pre.0", optional = true, default-features = false } @@ -39,8 +39,8 @@ tap = { version = "1.0.1", optional = true, default-features = false } # hack fo [dev-dependencies] hex-literal = "0.4" -sha2 = "=0.11.0-pre.2" -sha3 = "=0.11.0-pre.2" +sha2 = "=0.11.0-pre.3" +sha3 = "=0.11.0-pre.3" [features] default = ["arithmetic"] diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 5045802e0..602c61555 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -14,12 +14,12 @@ rust-version = "1.72" [dependencies] derive = { package = "signature_derive", version = "2", optional = true, path = "../signature_derive" } -digest = { version = "=0.11.0-pre.7", optional = true, default-features = false } +digest = { version = "=0.11.0-pre.8", optional = true, default-features = false } rand_core = { version = "0.6.4", optional = true, default-features = false } [dev-dependencies] hex-literal = "0.4" -sha2 = { version = "=0.11.0-pre.2", default-features = false } +sha2 = { version = "=0.11.0-pre.3", default-features = false } [features] alloc = [] From e71c4fa44cb52a0edaec7b081c2d51bcfacf5755 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 1 Feb 2024 15:20:35 -0700 Subject: [PATCH 1152/1461] elliptic-curve v0.14.0-pre.4 (#1499) --- Cargo.lock | 2 +- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8f2926aff..1fa16f794 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -541,7 +541,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.14.0-pre.3" +version = "0.14.0-pre.4" dependencies = [ "base16ct 0.2.0", "base64ct", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index a940521eb..2faa78b3b 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.14.0-pre.3" +version = "0.14.0-pre.4" description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, From 70b43f3d403e104aa4093c8e694a81ba1f928647 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 1 Feb 2024 16:00:50 -0700 Subject: [PATCH 1153/1461] signature v2.3.0-pre.3 (#1500) --- .github/workflows/async-signature.yml | 1 + Cargo.lock | 6 +++--- async-signature/Cargo.toml | 4 ++-- signature/Cargo.toml | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/workflows/async-signature.yml b/.github/workflows/async-signature.yml index 589fc27f9..775f402fc 100644 --- a/.github/workflows/async-signature.yml +++ b/.github/workflows/async-signature.yml @@ -36,6 +36,7 @@ jobs: - run: cargo test --all-features --release minimal-versions: + if: false # Temporarily disabled until signature v2.3.0 is published runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 diff --git a/Cargo.lock b/Cargo.lock index 1fa16f794..386d7c60c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -56,9 +56,9 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "async-signature" -version = "0.6.0-pre.0" +version = "0.6.0-pre.1" dependencies = [ - "signature 2.3.0-pre.2", + "signature 2.3.0-pre.3", ] [[package]] @@ -1250,7 +1250,7 @@ dependencies = [ [[package]] name = "signature" -version = "2.3.0-pre.2" +version = "2.3.0-pre.3" dependencies = [ "digest 0.11.0-pre.8 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal", diff --git a/async-signature/Cargo.toml b/async-signature/Cargo.toml index 8e69d112d..41308f438 100644 --- a/async-signature/Cargo.toml +++ b/async-signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "async-signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "0.6.0-pre.0" +version = "0.6.0-pre.1" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/async-signature" @@ -13,7 +13,7 @@ edition = "2021" rust-version = "1.75" [dependencies] -signature = "=2.3.0-pre.2" +signature = "=2.3.0-pre.3" [features] digest = ["signature/digest"] diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 602c61555..f5e9c27e0 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "2.3.0-pre.2" +version = "2.3.0-pre.3" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/signature" From 784e0d22ce7f72b548ef5d6dbe8beae82f928caf Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 1 Feb 2024 17:37:19 -0700 Subject: [PATCH 1154/1461] elliptic-curve: `LinearCombinationExt` => `LinearCombination` (#1501) Replaces the old, significantly less flexible `LinearCombination` trait with the newer `LinearCombinationExt` trait, removing the old trait completely and renaming the new one. The bounds for `CurveArithmetic::ProjectivePoint` have also been updated accordingly. --- elliptic-curve/src/arithmetic.rs | 3 ++- elliptic-curve/src/dev.rs | 3 ++- elliptic-curve/src/ops.rs | 30 +++++------------------------- 3 files changed, 9 insertions(+), 27 deletions(-) diff --git a/elliptic-curve/src/arithmetic.rs b/elliptic-curve/src/arithmetic.rs index 7ef7fc53d..150d8a9eb 100644 --- a/elliptic-curve/src/arithmetic.rs +++ b/elliptic-curve/src/arithmetic.rs @@ -44,7 +44,8 @@ pub trait CurveArithmetic: Curve { + DefaultIsZeroes + From + Into - + LinearCombination + + LinearCombination<[(Self::ProjectivePoint, Self::Scalar)]> + + LinearCombination<[(Self::ProjectivePoint, Self::Scalar); 2]> + MulByGenerator + group::Curve + group::Group; diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 6031150e5..9b105ea80 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -661,7 +661,8 @@ impl group::Curve for ProjectivePoint { } } -impl LinearCombination for ProjectivePoint {} +impl LinearCombination<[(ProjectivePoint, Scalar)]> for ProjectivePoint {} +impl LinearCombination<[(ProjectivePoint, Scalar); N]> for ProjectivePoint {} impl Add for ProjectivePoint { type Output = ProjectivePoint; diff --git a/elliptic-curve/src/ops.rs b/elliptic-curve/src/ops.rs index 9043b29c7..46bde0b87 100644 --- a/elliptic-curve/src/ops.rs +++ b/elliptic-curve/src/ops.rs @@ -149,28 +149,16 @@ fn invert_batch_internal< /// Linear combination. /// -/// This trait enables crates to provide an optimized implementation of -/// linear combinations (e.g. Shamir's Trick), or otherwise provides a default -/// non-optimized implementation. -// TODO(tarcieri): replace this with a trait from the `group` crate? (see zkcrypto/group#25) -pub trait LinearCombination: Group { - /// Calculates `x * k + y * l`. - fn lincomb(x: &Self, k: &Self::Scalar, y: &Self, l: &Self::Scalar) -> Self { - (*x * k) + (*y * l) - } -} - -/// Linear combination (extended version). +/// This trait enables optimized implementations of linear combinations (e.g. Shamir's Trick). /// -/// This trait enables providing an optimized implementation of -/// linear combinations (e.g. Shamir's Trick). -// TODO(tarcieri): replace the current `LinearCombination` with this in the next release -pub trait LinearCombinationExt: group::Curve +/// It's generic around `PointsAndScalars` to allow overlapping impls. For example, const generic +/// impls can use the input size to determine the size needed to store temporary variables. +pub trait LinearCombination: group::Curve where PointsAndScalars: AsRef<[(Self, Self::Scalar)]> + ?Sized, { /// Calculates `x1 * k1 + ... + xn * kn`. - fn lincomb_ext(points_and_scalars: &PointsAndScalars) -> Self { + fn lincomb(points_and_scalars: &PointsAndScalars) -> Self { points_and_scalars .as_ref() .iter() @@ -180,14 +168,6 @@ where } } -/// Blanket impl of the legacy [`LinearCombination`] trait for types which impl the new -/// [`LinearCombinationExt`] trait for 2-element arrays. -impl> LinearCombination for P { - fn lincomb(x: &Self, k: &Self::Scalar, y: &Self, l: &Self::Scalar) -> Self { - Self::lincomb_ext(&[(*x, *k), (*y, *l)]) - } -} - /// Multiplication by the generator. /// /// May use optimizations (e.g. precomputed tables) when available. From 13144ff78ea304fb6bd3ed59adb15db94d7505de Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 1 Feb 2024 18:48:47 -0700 Subject: [PATCH 1155/1461] elliptic-curve v0.14.0-pre.5 (#1502) --- Cargo.lock | 2 +- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 386d7c60c..a2d22bc39 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -541,7 +541,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.14.0-pre.4" +version = "0.14.0-pre.5" dependencies = [ "base16ct 0.2.0", "base64ct", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 2faa78b3b..cdc7d5416 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.14.0-pre.4" +version = "0.14.0-pre.5" description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, From 4620e89bd34fb840b457a051c0d1a52bfb17012a Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 6 Feb 2024 14:12:21 -0700 Subject: [PATCH 1156/1461] Cargo.lock: update dependencies (#1503) Updates the following dependencies: $ cargo update Updating crates.io index Updating hybrid-array v0.2.0-rc.4 -> v0.2.0-rc.5 Updating libc v0.2.152 -> v0.2.153 Updating proc-macro2 v1.0.76 -> v1.0.78 Updating serde v1.0.195 -> v1.0.196 Updating serde_derive v1.0.195 -> v1.0.196 Updating serde_json v1.0.111 -> v1.0.113 --- Cargo.lock | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a2d22bc39..906aa5752 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -778,9 +778,9 @@ dependencies = [ [[package]] name = "hybrid-array" -version = "0.2.0-rc.4" +version = "0.2.0-rc.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18e63b66aee2df5599ba69b17a48113dfc68d2e143ea387ef836509e433bbd7e" +checksum = "dcda354500b318c287a6b91c1cfbc42edd53d52d259a80783ceb5e3986fca2b2" dependencies = [ "typenum", "zeroize", @@ -847,9 +847,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.152" +version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "num-traits" @@ -1028,9 +1028,9 @@ checksum = "94e851c7654eed9e68d7d27164c454961a616cf8c203d500607ef22c737b51bb" [[package]] name = "proc-macro2" -version = "1.0.76" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" dependencies = [ "unicode-ident", ] @@ -1136,9 +1136,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.195" +version = "1.0.196" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" +checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" dependencies = [ "serde_derive", ] @@ -1154,9 +1154,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.195" +version = "1.0.196" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" +checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" dependencies = [ "proc-macro2", "quote", @@ -1165,9 +1165,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.111" +version = "1.0.113" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" +checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79" dependencies = [ "itoa", "ryu", From 16f091dd13a2d7133010c28ff3ddcb4227da83a2 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 8 Feb 2024 17:46:30 -0700 Subject: [PATCH 1157/1461] password-hash v0.6.0-pre.0 (#1504) --- Cargo.lock | 2 +- password-hash/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 906aa5752..7b77d7b5d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -899,7 +899,7 @@ dependencies = [ [[package]] name = "password-hash" -version = "0.6.0-pre" +version = "0.6.0-pre.0" dependencies = [ "base64ct", "rand_core 0.6.4", diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index ba2a0feb9..86b136ca7 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -5,7 +5,7 @@ Traits which describe the functionality of password hashing algorithms, as well as a `no_std`-friendly implementation of the PHC string format (a well-defined subset of the Modular Crypt Format a.k.a. MCF) """ -version = "0.6.0-pre" +version = "0.6.0-pre.0" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" From e2ef02fb84f3e10127360657a7f7e429514c43c9 Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Tue, 20 Feb 2024 06:42:58 -0800 Subject: [PATCH 1158/1461] cipher: fixup macro `block_mode_{dec,enc}_test` (#1511) --- cipher/src/dev/block.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cipher/src/dev/block.rs b/cipher/src/dev/block.rs index a05886dc3..7cbfb04a2 100644 --- a/cipher/src/dev/block.rs +++ b/cipher/src/dev/block.rs @@ -102,7 +102,7 @@ macro_rules! block_mode_enc_test { fn $name() { use cipher::{ array::Array, blobby::Blob4Iterator, inout::InOutBuf, typenum::Unsigned, - BlockCipherEncrypt, BlockSizeUser, KeyIvInit, + BlockCipherEncrypt, BlockModeEncrypt, BlockSizeUser, KeyIvInit, }; fn run_test(key: &[u8], iv: &[u8], pt: &[u8], ct: &[u8]) -> bool { @@ -115,7 +115,7 @@ macro_rules! block_mode_enc_test { let (blocks, tail) = buf.reborrow().into_chunks(); assert_eq!(tail.len(), 0); for block in blocks { - state.encrypt_block_inout_mut(block); + state.encrypt_block_inout(block); } if buf.get_out() != ct { return false; @@ -125,7 +125,7 @@ macro_rules! block_mode_enc_test { let mut state = <$cipher as KeyIvInit>::new_from_slices(key, iv).unwrap(); buf.get_out().iter_mut().for_each(|b| *b = 0); let (blocks, _) = buf.reborrow().into_chunks(); - state.encrypt_blocks_inout_mut(blocks); + state.encrypt_blocks_inout(blocks); if buf.get_out() != ct { return false; } @@ -160,7 +160,7 @@ macro_rules! block_mode_dec_test { fn $name() { use cipher::{ array::Array, blobby::Blob4Iterator, inout::InOutBuf, typenum::Unsigned, - BlockCipherDecrypt, BlockSizeUser, KeyIvInit, + BlockCipherDecrypt, BlockModeDecrypt, BlockSizeUser, KeyIvInit, }; fn run_test(key: &[u8], iv: &[u8], pt: &[u8], ct: &[u8]) -> bool { @@ -173,7 +173,7 @@ macro_rules! block_mode_dec_test { let (blocks, tail) = buf.reborrow().into_chunks(); assert_eq!(tail.len(), 0); for block in blocks { - state.decrypt_block_inout_mut(block); + state.decrypt_block_inout(block); } if buf.get_out() != pt { return false; @@ -183,7 +183,7 @@ macro_rules! block_mode_dec_test { let mut state = <$cipher as KeyIvInit>::new_from_slices(key, iv).unwrap(); buf.get_out().iter_mut().for_each(|b| *b = 0); let (blocks, _) = buf.reborrow().into_chunks(); - state.decrypt_blocks_inout_mut(blocks); + state.decrypt_blocks_inout(blocks); if buf.get_out() != pt { return false; } From cce3b05861fe851b3ab2c57d8c14cfa27fee814e Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Wed, 21 Feb 2024 08:57:01 -0800 Subject: [PATCH 1159/1461] cipher: fixup `block_{encryptor,decryptor}_bench` (#1512) Those benchmark macros are reused for both `block-ciphers` and `block-modes`. We need to import both `BlockMode` and `BlockCipher` for them to work. --- cipher/src/dev/block.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/cipher/src/dev/block.rs b/cipher/src/dev/block.rs index 7cbfb04a2..81b111808 100644 --- a/cipher/src/dev/block.rs +++ b/cipher/src/dev/block.rs @@ -289,7 +289,8 @@ macro_rules! block_encryptor_bench { ($init:block, $cipher:ty, $block_name:ident, $blocks_name:ident $(,)? ) => { #[bench] pub fn $block_name(bh: &mut test::Bencher) { - use cipher::BlockCipherEncrypt; + #[allow(unused)] + use cipher::{BlockCipherEncrypt, BlockModeEncrypt}; let mut cipher = $init; let mut blocks = vec![Default::default(); 1024]; @@ -305,7 +306,8 @@ macro_rules! block_encryptor_bench { #[bench] pub fn $blocks_name(bh: &mut test::Bencher) { - use cipher::BlockCipherEncrypt; + #[allow(unused)] + use cipher::{BlockCipherEncrypt, BlockModeEncrypt}; let mut cipher = $init; let mut blocks = vec![Default::default(); 1024]; @@ -350,7 +352,8 @@ macro_rules! block_decryptor_bench { ($init:block, $cipher:ty, $block_name:ident, $blocks_name:ident $(,)? ) => { #[bench] pub fn $block_name(bh: &mut test::Bencher) { - use cipher::BlockCipherDecrypt; + #[allow(unused)] + use cipher::{BlockCipherDecrypt, BlockModeDecrypt}; let mut cipher = $init; let mut blocks = vec![Default::default(); 1024]; @@ -366,7 +369,8 @@ macro_rules! block_decryptor_bench { #[bench] pub fn $blocks_name(bh: &mut test::Bencher) { - use cipher::BlockCipherDecrypt; + #[allow(unused)] + use cipher::{BlockCipherDecrypt, BlockModeDecrypt}; let mut cipher = $init; let mut blocks = vec![Default::default(); 1024]; From 60297e6f799d040415c96d85152d3affad255738 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 25 Feb 2024 09:36:58 -0700 Subject: [PATCH 1160/1461] Remove redundant imports (#1522) Recent nightlies warn for items which are imported redundantly, of which there were a few in the `elliptic-curve` and `password-hash` crates --- elliptic-curve/src/dev.rs | 1 - elliptic-curve/src/error.rs | 3 --- elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs | 5 +---- elliptic-curve/src/public_key.rs | 5 +---- elliptic-curve/src/secret_key/pkcs8.rs | 2 +- password-hash/src/output.rs | 6 +----- password-hash/src/params.rs | 3 +-- 7 files changed, 5 insertions(+), 20 deletions(-) diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 9b105ea80..5a5c38ede 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -8,7 +8,6 @@ use crate::{ bigint::{Limb, U256}, error::{Error, Result}, ops::{Invert, LinearCombination, MulByGenerator, Reduce, ShrAssign}, - pkcs8, point::AffineCoordinates, rand_core::RngCore, scalar::{FromUintUnchecked, IsHigh}, diff --git a/elliptic-curve/src/error.rs b/elliptic-curve/src/error.rs index 53f5b1773..f4463fa4d 100644 --- a/elliptic-curve/src/error.rs +++ b/elliptic-curve/src/error.rs @@ -2,9 +2,6 @@ use core::fmt::{self, Display}; -#[cfg(feature = "pkcs8")] -use crate::pkcs8; - /// Result type with the `elliptic-curve` crate's [`Error`] type. pub type Result = core::result::Result; diff --git a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs index a3081a5f7..be6cefc52 100644 --- a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs +++ b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs @@ -65,10 +65,7 @@ mod test { use super::*; use core::mem; use hex_literal::hex; - use hybrid_array::{ - typenum::{U128, U32}, - Array, ArraySize, - }; + use hybrid_array::{typenum::U128, Array, ArraySize}; use sha3::Shake128; fn assert_message(msg: &[u8], domain: &Domain<'_, U32>, len_in_bytes: u16, bytes: &[u8]) { diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index d2fe6065b..4242c8c11 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -43,10 +43,7 @@ use pkcs8::DecodePublicKey; #[cfg(all(feature = "sec1", feature = "pkcs8"))] use { - crate::{ - pkcs8::{self, AssociatedOid}, - ALGORITHM_OID, - }, + crate::{pkcs8::AssociatedOid, ALGORITHM_OID}, pkcs8::der, }; diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs index 92c81f18a..a1c37aa36 100644 --- a/elliptic-curve/src/secret_key/pkcs8.rs +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -2,7 +2,7 @@ use super::SecretKey; use crate::{ - pkcs8::{self, der::Decode, AssociatedOid}, + pkcs8::{der::Decode, AssociatedOid}, sec1::{ModulusSize, ValidatePublicKey}, Curve, FieldBytesSize, ALGORITHM_OID, }; diff --git a/password-hash/src/output.rs b/password-hash/src/output.rs index d988b55d8..7f1998fc7 100644 --- a/password-hash/src/output.rs +++ b/password-hash/src/output.rs @@ -1,11 +1,7 @@ //! Outputs from password hashing functions. use crate::{Encoding, Error, Result}; -use core::{ - cmp::{Ordering, PartialEq}, - fmt, - str::FromStr, -}; +use core::{cmp::Ordering, fmt, str::FromStr}; use subtle::{Choice, ConstantTimeEq}; /// Output from password hashing functions, i.e. the "hash" or "digest" diff --git a/password-hash/src/params.rs b/password-hash/src/params.rs index c9d89caee..d23d279fe 100644 --- a/password-hash/src/params.rs +++ b/password-hash/src/params.rs @@ -7,7 +7,6 @@ use crate::{ }; use core::{ fmt::{self, Debug, Write}, - iter::FromIterator, str::{self, FromStr}, }; @@ -328,7 +327,7 @@ impl Write for Buffer { #[cfg(test)] mod tests { - use super::{Error, FromIterator, Ident, ParamsString, Value}; + use super::{Error, Ident, ParamsString, Value}; #[cfg(feature = "alloc")] use alloc::string::ToString; From 0ace747bdf358f6269cae17dd8a7c3403f6bdbf4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 3 Mar 2024 17:41:49 -0700 Subject: [PATCH 1161/1461] build(deps): bump hybrid-array from 0.2.0-rc.5 to 0.2.0-rc.7 (#1529) Bumps [hybrid-array](https://github.com/RustCrypto/hybrid-array) from 0.2.0-rc.5 to 0.2.0-rc.7. - [Changelog](https://github.com/RustCrypto/hybrid-array/blob/master/CHANGELOG.md) - [Commits](https://github.com/RustCrypto/hybrid-array/compare/v0.2.0-rc.5...v0.2.0-rc.7) --- updated-dependencies: - dependency-name: hybrid-array dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- crypto-common/Cargo.toml | 2 +- elliptic-curve/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7b77d7b5d..ba326ca62 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -778,9 +778,9 @@ dependencies = [ [[package]] name = "hybrid-array" -version = "0.2.0-rc.5" +version = "0.2.0-rc.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcda354500b318c287a6b91c1cfbc42edd53d52d259a80783ceb5e3986fca2b2" +checksum = "87c2311a0adecbffff284aabcf1249b1485193b16e685f9ef171b1ba82979cff" dependencies = [ "typenum", "zeroize", diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index 199e7f0d5..c80573223 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -13,7 +13,7 @@ keywords = ["crypto", "traits"] categories = ["cryptography", "no-std"] [dependencies] -hybrid-array = "0.2.0-rc.4" +hybrid-array = "0.2.0-rc.7" # optional dependencies rand_core = { version = "0.6.4", optional = true } diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index cdc7d5416..c765cf42f 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -18,7 +18,7 @@ rust-version = "1.73" [dependencies] base16ct = "0.2" crypto-bigint = { version = "=0.6.0-pre.12", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } -hybrid-array = { version = "0.2.0-rc.0", default-features = false, features = ["zeroize"] } +hybrid-array = { version = "0.2.0-rc.7", default-features = false, features = ["zeroize"] } rand_core = { version = "0.6.4", default-features = false } subtle = { version = "2", default-features = false } zeroize = { version = "1.7", default-features = false } From b2e31d8df293026390b6315c10844eed8b54a185 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 3 Mar 2024 19:37:23 -0700 Subject: [PATCH 1162/1461] cipher v0.5.0-pre.4 (#1530) --- Cargo.lock | 2 +- cipher/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ba326ca62..e8084600a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -223,7 +223,7 @@ dependencies = [ [[package]] name = "cipher" -version = "0.5.0-pre.3" +version = "0.5.0-pre.4" dependencies = [ "blobby", "crypto-common 0.2.0-pre.5 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index 99661986d..d853d1f87 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "cipher" description = "Traits for describing block ciphers and stream ciphers" -version = "0.5.0-pre.3" +version = "0.5.0-pre.4" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" From ea334c2f9927fcd94f7307fdd2b19b019f116af2 Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Mon, 4 Mar 2024 06:50:01 -0800 Subject: [PATCH 1163/1461] aead: fixup `hybrid-array` migration (#1531) This macro is pulled from `AEADs.git` crates. --- aead/src/dev.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aead/src/dev.rs b/aead/src/dev.rs index 37688262b..b7edf89cb 100644 --- a/aead/src/dev.rs +++ b/aead/src/dev.rs @@ -8,8 +8,8 @@ macro_rules! new_test { #[test] fn $name() { use aead::{ + array::{typenum::Unsigned, Array}, dev::blobby::Blob6Iterator, - generic_array::{typenum::Unsigned, GenericArray}, Aead, KeyInit, Payload, }; From de12a156b23f020bc93497e5024e70aa3283f589 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Mar 2024 16:58:13 -0700 Subject: [PATCH 1164/1461] build(deps): bump syn from 2.0.48 to 2.0.52 (#1524) Bumps [syn](https://github.com/dtolnay/syn) from 2.0.48 to 2.0.52. - [Release notes](https://github.com/dtolnay/syn/releases) - [Commits](https://github.com/dtolnay/syn/compare/2.0.48...2.0.52) --- updated-dependencies: - dependency-name: syn dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e8084600a..a507091ea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1311,9 +1311,9 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "syn" -version = "2.0.48" +version = "2.0.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" dependencies = [ "proc-macro2", "quote", From ceaa93fa4f7b0183c953260b008b39b41382a7f1 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 5 Mar 2024 17:20:30 -0700 Subject: [PATCH 1165/1461] elliptic-curve: fix unknown qualifications (#1532) Recent nightlies started picking up on these --- elliptic-curve/src/jwk.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elliptic-curve/src/jwk.rs b/elliptic-curve/src/jwk.rs index 58a9e3812..6e59d9fae 100644 --- a/elliptic-curve/src/jwk.rs +++ b/elliptic-curve/src/jwk.rs @@ -552,7 +552,7 @@ impl Serialize for JwkEcKey { state.serialize_field("d", d)?; } - ser::SerializeStruct::end(state) + SerializeStruct::end(state) } } From b6bd0428f658eb02876f570db917fb83d417d8c9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Mar 2024 18:01:43 -0700 Subject: [PATCH 1166/1461] build(deps): bump serde_json from 1.0.113 to 1.0.114 (#1513) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.113 to 1.0.114. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.113...v1.0.114) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a507091ea..5985cf2ae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1165,9 +1165,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.113" +version = "1.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79" +checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" dependencies = [ "itoa", "ryu", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index c765cf42f..5edc9bc78 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -34,7 +34,7 @@ pem-rfc7468 = { version = "=1.0.0-pre.0", optional = true, features = ["alloc"] pkcs8 = { version = "=0.11.0-pre.0", optional = true, default-features = false } sec1 = { version = "=0.8.0-pre.1", optional = true, features = ["subtle", "zeroize"] } serdect = { version = "=0.3.0-pre.0", optional = true, default-features = false, features = ["alloc"] } -serde_json = { version = "1.0.47", optional = true, default-features = false, features = ["alloc"] } +serde_json = { version = "1.0.114", optional = true, default-features = false, features = ["alloc"] } tap = { version = "1.0.1", optional = true, default-features = false } # hack for minimal-versions support for `bits` [dev-dependencies] From f7d1dd2823aa1022ac5197d53fe414e1e903e549 Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Fri, 8 Mar 2024 05:25:31 -0800 Subject: [PATCH 1167/1461] aead v0.6.0-pre.0 (#1534) --- Cargo.lock | 2 +- aead/CHANGELOG.md | 35 +++++++++++++++++++++++++++++++++++ aead/Cargo.toml | 2 +- 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5985cf2ae..4cdf2f778 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,7 +14,7 @@ dependencies = [ [[package]] name = "aead" -version = "0.6.0-pre" +version = "0.6.0-pre.0" dependencies = [ "arrayvec", "blobby", diff --git a/aead/CHANGELOG.md b/aead/CHANGELOG.md index d5413f8e2..64c3f094b 100644 --- a/aead/CHANGELOG.md +++ b/aead/CHANGELOG.md @@ -5,6 +5,41 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased +### Fixed +- minor documentation error in `AeadCore::TagSize` ([#1351]) +- fixup `hybrid-array` migration ([#1531]) + +### Changed +- Migrate to `doc_auto_cfg` ([#1370]) +- Exclude pre-1.60 crates from workspace ([#1380]) +- bump `crypto-common` to v0.2.0-pre; MSRV 1.65 ([#1384]) +- Bump `heapless` dependency to v0.8 ([#1398]) +- Bump `hybrid-array` to v0.2.0-pre.6 ([#1432]) +- Bump `crypto-common` to v0.2.0-pre.1 ([#1433]) +- Bump `crypto-common` to v0.2.0-pre.2 ([#1436]) +- Bump `hybrid-array` to v0.2.0-pre.8 ([#1438]) +- Bump `crypto-common` and `hybrid-array` ([#1469]) +- Bump `crypto-common` to v0.2.0-pre.5 ([#1496]) + +### Added +- enable `missing_debug_implementations` lint and add `Debug` impls ([#1411]) + + +[#1351]: https://github.com/RustCrypto/traits/pull/1351 +[#1370]: https://github.com/RustCrypto/traits/pull/1370 +[#1380]: https://github.com/RustCrypto/traits/pull/1380 +[#1384]: https://github.com/RustCrypto/traits/pull/1384 +[#1398]: https://github.com/RustCrypto/traits/pull/1398 +[#1411]: https://github.com/RustCrypto/traits/pull/1411 +[#1432]: https://github.com/RustCrypto/traits/pull/1432 +[#1433]: https://github.com/RustCrypto/traits/pull/1433 +[#1436]: https://github.com/RustCrypto/traits/pull/1436 +[#1438]: https://github.com/RustCrypto/traits/pull/1438 +[#1469]: https://github.com/RustCrypto/traits/pull/1469 +[#1496]: https://github.com/RustCrypto/traits/pull/1496 +[#1531]: https://github.com/RustCrypto/traits/pull/1531 + ## 0.5.2 (2023-04-02) ### Added - `arrayvec` feature ([#1219]) diff --git a/aead/Cargo.toml b/aead/Cargo.toml index 184ac4107..89182e148 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aead" -version = "0.6.0-pre" +version = "0.6.0-pre.0" description = """ Traits for Authenticated Encryption with Associated Data (AEAD) algorithms, such as AES-GCM as ChaCha20Poly1305, which provide a high-level API From 7f4f84b9b2a6e9da7275ee7064f5701c244f7cfc Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Fri, 8 Mar 2024 05:27:23 -0800 Subject: [PATCH 1168/1461] universal-hash: v0.6.0-pre.0 (#1535) --- Cargo.lock | 2 +- universal-hash/CHANGELOG.md | 26 ++++++++++++++++++++++++++ universal-hash/Cargo.toml | 2 +- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4cdf2f778..4730d30dd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1350,7 +1350,7 @@ dependencies = [ [[package]] name = "universal-hash" -version = "0.6.0-pre" +version = "0.6.0-pre.0" dependencies = [ "crypto-common 0.2.0-pre.5 (registry+https://github.com/rust-lang/crates.io-index)", "subtle", diff --git a/universal-hash/CHANGELOG.md b/universal-hash/CHANGELOG.md index e495d3d56..3ff8bb0fa 100644 --- a/universal-hash/CHANGELOG.md +++ b/universal-hash/CHANGELOG.md @@ -5,6 +5,32 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased +### Changed +- Migrate to `doc_auto_cfg` ([#1370]) +- Exclude pre-1.60 crates from workspace ([#1380]) +- bump crypto-common to v0.2.0-pre; MSRV 1.65 ([#1385]) +- bump crypto-common to v0.2.0-pre.1 ([#1433]) +- bump crypto-common to v0.2.0-pre.2 ([#1436]) +- Bump `hybrid-array` to v0.2.0-pre.8 ([#1438]) +- Bump `crypto-common` and `hybrid-array` ([#1469]) +- Bump `hybrid-array` to v0.2.0-rc.4 ([#1493]) +- bump crypto-common to v0.2.0-pre.5 ([#1496]) + +### Fixed +- Fix `missing_debug_implementations` for some crates ([#1407]) + +[#1370]: https://github.com/RustCrypto/traits/pull/1370 +[#1380]: https://github.com/RustCrypto/traits/pull/1380 +[#1385]: https://github.com/RustCrypto/traits/pull/1385 +[#1407]: https://github.com/RustCrypto/traits/pull/1407 +[#1433]: https://github.com/RustCrypto/traits/pull/1433 +[#1436]: https://github.com/RustCrypto/traits/pull/1436 +[#1438]: https://github.com/RustCrypto/traits/pull/1438 +[#1469]: https://github.com/RustCrypto/traits/pull/1469 +[#1493]: https://github.com/RustCrypto/traits/pull/1493 +[#1496]: https://github.com/RustCrypto/traits/pull/1496 + ## 0.5.1 (2023-05-19) ### Changed - Loosen `subtle` version requirement to `^2.4` ([#1260]) diff --git a/universal-hash/Cargo.toml b/universal-hash/Cargo.toml index e61fb1e2e..c0003386c 100644 --- a/universal-hash/Cargo.toml +++ b/universal-hash/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "universal-hash" -version = "0.6.0-pre" +version = "0.6.0-pre.0" description = "Traits which describe the functionality of universal hash functions (UHFs)" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" From 6c5f56e206ff0bbf6ac8b51a6cf4730d278d7c8b Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Wed, 13 Mar 2024 13:56:27 -0700 Subject: [PATCH 1169/1461] crypto-common: adds an `OutputSize` type alias (#1533) --- crypto-common/src/lib.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/crypto-common/src/lib.rs b/crypto-common/src/lib.rs index 45ee05534..712fcf49b 100644 --- a/crypto-common/src/lib.rs +++ b/crypto-common/src/lib.rs @@ -39,7 +39,10 @@ pub type Block = Array::BlockSize>; pub type ParBlocks = Array, ::ParBlocksSize>; /// Output array of [`OutputSizeUser`] implementors. -pub type Output = Array::OutputSize>; +pub type Output = Array>; + +/// Alias for the output size of [`OutputSizeUser`] implementors. +pub type OutputSize = ::OutputSize; /// Key used by [`KeySizeUser`] implementors. pub type Key = Array::KeySize>; From c2ff5eecd20691c586295c37ac2b7dd20081f085 Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Sun, 17 Mar 2024 18:47:32 +0000 Subject: [PATCH 1170/1461] digest: fixup imports for `hash_serialization_test` macro (#1537) This fixes #1487 --- digest/src/dev.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/digest/src/dev.rs b/digest/src/dev.rs index 7018e8549..00b93859b 100644 --- a/digest/src/dev.rs +++ b/digest/src/dev.rs @@ -44,7 +44,7 @@ macro_rules! hash_serialization_test { #[test] fn $name() { use digest::{ - crypto_common::{BlockSizeUser, SerializableState}, + crypto_common::{hazmat::SerializableState, BlockSizeUser}, typenum::Unsigned, Digest, }; @@ -77,7 +77,7 @@ macro_rules! hash_rt_outsize_serialization_test { #[test] fn $name() { use digest::{ - crypto_common::{BlockSizeUser, SerializableState}, + crypto_common::{hazmat::SerializableState, BlockSizeUser}, typenum::Unsigned, Digest, Update, VariableOutput, }; From 7c7a0d2a2caa60e286835051e6ad5fd10a9a9554 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 17 Mar 2024 12:49:58 -0600 Subject: [PATCH 1171/1461] build(deps): bump proc-macro2 from 1.0.78 to 1.0.79 (#1536) Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.78 to 1.0.79. - [Release notes](https://github.com/dtolnay/proc-macro2/releases) - [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.78...1.0.79) --- updated-dependencies: - dependency-name: proc-macro2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4730d30dd..edb1d162f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1028,9 +1028,9 @@ checksum = "94e851c7654eed9e68d7d27164c454961a616cf8c203d500607ef22c737b51bb" [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" dependencies = [ "unicode-ident", ] From 32e9857c25beead25bb02467b75896941c2c9f3f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Mar 2024 08:07:14 -0600 Subject: [PATCH 1172/1461] build(deps): bump hybrid-array from 0.2.0-rc.7 to 0.2.0-rc.8 (#1539) Bumps [hybrid-array](https://github.com/RustCrypto/hybrid-array) from 0.2.0-rc.7 to 0.2.0-rc.8. - [Changelog](https://github.com/RustCrypto/hybrid-array/blob/master/CHANGELOG.md) - [Commits](https://github.com/RustCrypto/hybrid-array/compare/v0.2.0-rc.7...v0.2.0-rc.8) --- updated-dependencies: - dependency-name: hybrid-array dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- crypto-common/Cargo.toml | 2 +- elliptic-curve/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index edb1d162f..a688751ac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -778,9 +778,9 @@ dependencies = [ [[package]] name = "hybrid-array" -version = "0.2.0-rc.7" +version = "0.2.0-rc.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87c2311a0adecbffff284aabcf1249b1485193b16e685f9ef171b1ba82979cff" +checksum = "53668f5da5a41d9eaf4bf7064be46d1ebe6a4e1ceed817f387587b18f2b51047" dependencies = [ "typenum", "zeroize", diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index c80573223..f1ac4e986 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -13,7 +13,7 @@ keywords = ["crypto", "traits"] categories = ["cryptography", "no-std"] [dependencies] -hybrid-array = "0.2.0-rc.7" +hybrid-array = "0.2.0-rc.8" # optional dependencies rand_core = { version = "0.6.4", optional = true } diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 5edc9bc78..388c12a1a 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -18,7 +18,7 @@ rust-version = "1.73" [dependencies] base16ct = "0.2" crypto-bigint = { version = "=0.6.0-pre.12", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } -hybrid-array = { version = "0.2.0-rc.7", default-features = false, features = ["zeroize"] } +hybrid-array = { version = "0.2.0-rc.8", default-features = false, features = ["zeroize"] } rand_core = { version = "0.6.4", default-features = false } subtle = { version = "2", default-features = false } zeroize = { version = "1.7", default-features = false } From 84b4dc19e5dce192404dda098b27b7d996013919 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 Mar 2024 16:18:24 -0600 Subject: [PATCH 1173/1461] build(deps): bump bytes from 1.5.0 to 1.6.0 (#1540) Bumps [bytes](https://github.com/tokio-rs/bytes) from 1.5.0 to 1.6.0. - [Release notes](https://github.com/tokio-rs/bytes/releases) - [Changelog](https://github.com/tokio-rs/bytes/blob/master/CHANGELOG.md) - [Commits](https://github.com/tokio-rs/bytes/compare/v1.5.0...v1.6.0) --- updated-dependencies: - dependency-name: bytes dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a688751ac..31812c324 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -166,9 +166,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" [[package]] name = "cc" From 59c34d2459214dca25abc8ca252a834acc2c654f Mon Sep 17 00:00:00 2001 From: Michael Rosenberg Date: Tue, 2 Apr 2024 13:01:24 -0400 Subject: [PATCH 1174/1461] kem: simplify API (#1509) * Simplified API significantly; updated HPKE test * Updated all the tests * Deleted cruft; Updated docs * Removed std feature * Made clippy happy * kem: Made rng input a mut ref; made Error assoc type impl Debug --- Cargo.lock | 1 - kem/Cargo.toml | 38 +++++------ kem/README.md | 61 ++++++++++++++++- kem/src/errors.rs | 17 ----- kem/src/kem.rs | 100 --------------------------- kem/src/lib.rs | 28 ++++++-- kem/tests/hpke.rs | 166 ++++++++------------------------------------- kem/tests/saber.rs | 104 +++++++++------------------- kem/tests/x3dh.rs | 134 +++++++++++++----------------------- 9 files changed, 210 insertions(+), 439 deletions(-) delete mode 100644 kem/src/errors.rs delete mode 100644 kem/src/kem.rs diff --git a/Cargo.lock b/Cargo.lock index 31812c324..8f099192e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -834,7 +834,6 @@ dependencies = [ name = "kem" version = "0.3.0-pre" dependencies = [ - "generic-array", "hpke", "p256 0.9.0", "pqcrypto", diff --git a/kem/Cargo.toml b/kem/Cargo.toml index 23f9fba14..d306ea4c2 100644 --- a/kem/Cargo.toml +++ b/kem/Cargo.toml @@ -1,34 +1,34 @@ [package] -name = "kem" -description = "Traits for key encapsulation mechanisms" -version = "0.3.0-pre" -authors = ["RustCrypto Developers"] -license = "Apache-2.0 OR MIT" +name = "kem" +description = "Traits for key encapsulation mechanisms" +version = "0.3.0-pre" +authors = ["RustCrypto Developers"] +license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/kem" -repository = "https://github.com/RustCrypto/traits/tree/master/kem" -readme = "README.md" -edition = "2021" -keywords = ["crypto"] -categories = ["cryptography", "no-std"] -rust-version = "1.66" +repository = "https://github.com/RustCrypto/traits/tree/master/kem" +readme = "README.md" +edition = "2021" +keywords = ["crypto"] +categories = ["cryptography", "no-std"] +rust-version = "1.66" [dependencies] rand_core = "0.6" -generic-array = "0.14" zeroize = { version = "1.7", default-features = false } [dev-dependencies] hpke = "0.10" -p256 = { version = "0.9", features = [ "ecdsa" ] } -pqcrypto = { version = "0.15", default-features = false, features = [ "pqcrypto-saber" ] } +p256 = { version = "0.9", features = ["ecdsa"] } +pqcrypto = { version = "0.15", default-features = false, features = [ + "pqcrypto-saber", +] } pqcrypto-traits = "0.3" -rand = { version = "0.8", features = [ "getrandom" ] } +rand = { version = "0.8" } x3dh-ke = "0.1" -[features] -default = [] -std = [] - [package.metadata.docs.rs] all-features = true rustdoc-args = ["--cfg", "docsrs"] + +[lib] +doctest = false diff --git a/kem/README.md b/kem/README.md index 51be87890..8ca46b4ed 100644 --- a/kem/README.md +++ b/kem/README.md @@ -9,7 +9,66 @@ This crate provides a common set of traits for [key encapsulation mechanisms][1]—algorithms for non-interactively establishing secrets between peers. This is intended to be implemented by libraries which produce or contain implementations of key encapsulation mechanisms, and used by libraries which want to produce or consume encapsulated secrets while generically supporting any compatible backend. -The crate exposes four traits, `Encapsulator`, `Decapsulator`, `AuthEncapsulator`, and `AuthDecapsulator`. These traits represent the ability to initiate a key exchange and complete a key exchange, in the case where the sender is authenticated to the receiver and in the case where the sender is not. +The crate exposes two traits, `Encapsulate` and `Decapsulate`, which are both generic over the encapsulated key type and the shared secret type. They are also agnostic about the structure of `Self`. For example, a simple Saber implementation may just impl `Encapsulate` for a single public key: +```rust +// Must make a newtype to implement the trait +struct MyPubkey(SaberPublicKey); + +impl Encapsulate for MyPubkey { + // Encapsulation is infallible + type Error = !; + + fn encapsulate( + &self, + csprng: impl CryptoRngCore, + ) -> Result<(SaberEncappedKey, SaberSharedSecret), !> { + let (ss, ek) = saber_encapsulate(&csprng, &self.0); + Ok((ek, ss)) + } +} +``` +And on the other end of complexity, an [X3DH](https://www.signal.org/docs/specifications/x3dh/) implementation might impl `Encapsulate` for a public key bundle plus a sender identity key: +```rust +struct PubkeyBundle { + ik: IdentityPubkey, + spk: SignedPrePubkey, + sig: Signature, + opk: OneTimePrePubkey, +} + +// Encap context is the recipient's pubkeys and the sender's identity key +struct EncapContext(PubkeyBundle, IdentityPrivkey); + +impl Encapsulate for EncapContext { + // Encapsulation fails if signature verification fails + type Error = SigError; + + fn encapsulate( + &self, + csprng: impl CryptoRngCore, + ) -> Result<(EphemeralKey, SharedSecret), Self::Error> { + // Make a new ephemeral key. This will be the encapped key + let ek = EphemeralKey::gen(&mut csprng); + + // Deconstruct the recipient's pubkey bundle + let PubkeyBundle { + ref ik, + ref spk, + ref sig, + ref opk, + } = self.0; + let my_ik = &self.1; + + // Verify the signature + self.0.verify(&sig, &some_sig_pubkey)?; + + // Do the X3DH operation to get the shared secret + let shared_secret = x3dh_a(sig, my_ik, spk, &ek, ik, opk)?; + + Ok((ek, shared_secret)) + } +} +``` [Documentation][docs-link] diff --git a/kem/src/errors.rs b/kem/src/errors.rs deleted file mode 100644 index 1cef35add..000000000 --- a/kem/src/errors.rs +++ /dev/null @@ -1,17 +0,0 @@ -//! KEM error types - -use core::fmt::{Debug, Display}; - -/// Represents KEM errors. This is intentionally opaque to avoid leaking information about private -/// keys through side channels. -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub struct Error; - -impl Display for Error { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - write!(f, "error encapsulating or decapsulating") - } -} - -#[cfg(feature = "std")] -impl std::error::Error for Error {} diff --git a/kem/src/kem.rs b/kem/src/kem.rs deleted file mode 100644 index 1963883ef..000000000 --- a/kem/src/kem.rs +++ /dev/null @@ -1,100 +0,0 @@ -//! KEM Traits - -use crate::errors::Error; - -use core::fmt; - -use generic_array::{ArrayLength, GenericArray}; -use rand_core::{CryptoRng, RngCore}; -use zeroize::{Zeroize, ZeroizeOnDrop}; - -/// Trait impl'd by concrete types that represent an encapsulated key. This is intended to be, in -/// essence, a bag of bytes. -pub trait EncappedKey: AsRef<[u8]> + fmt::Debug + Sized { - /// The size, in bytes, of an encapsulated key. - type EncappedKeySize: ArrayLength; - - /// The size, in bytes, of the shared secret that this KEM produces. - type SharedSecretSize: ArrayLength; - - /// Represents the identity key of an encapsulator. This is used in authenticated - /// decapsulation. - type SenderPublicKey; - - /// The public key of a decapsulator. This is used in encapsulation. - type RecipientPublicKey; - - /// Parses an encapsulated key from its byte representation. - fn from_bytes(bytes: &GenericArray) -> Result; - - /// Borrows a byte slice representing the serialized form of this encapsulated key. - fn as_bytes(&self) -> &GenericArray { - // EncappedKey is already AsRef<[u8]>, so we don't need to do any work. This will panic iff - // the underlying bytestring is not precisely NEnc bytes long. - self.as_ref().into() - } -} - -/// The shared secret that results from key exchange. -pub struct SharedSecret(GenericArray); - -impl fmt::Debug for SharedSecret { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str("SharedSecret { ... }") - } -} - -// Zero the secret on drop -impl Drop for SharedSecret { - fn drop(&mut self) { - self.0.as_mut_slice().zeroize(); - } -} - -impl ZeroizeOnDrop for SharedSecret {} - -impl SharedSecret { - /// Constructs a new `SharedSecret` by wrapping the given bytes - pub fn new(bytes: GenericArray) -> Self { - SharedSecret(bytes) - } - - /// Returns borrowed bytes representing the shared secret of the key exchange - pub fn as_bytes(&self) -> &[u8] { - &self.0 - } -} - -/// Represents the functionality of a key encapsulator. For unauthenticated encapsulation, `Self` -/// can be an empty struct. For authenticated encapsulation, `Self` is a private key. -pub trait Encapsulator { - /// Attempts to encapsulate a fresh shared secret with the given recipient. The resulting - /// shared secret is bound to the identity encoded in `Self` (i.e., authenticated wrt `Self`). - /// If `Self` is empty, then this is equivalent to unauthenticated encapsulation. Returns the - /// shared secret and encapsulated key on success, or an error if something went wrong. - fn try_encap( - &self, - csprng: &mut R, - recip_pubkey: &EK::RecipientPublicKey, - ) -> Result<(EK, SharedSecret), Error>; -} - -/// Represents the functionality of a key decapsulator, where `Self` is a cryptographic key. -pub trait Decapsulator { - /// Attempt to decapsulate the given encapsulated key. Returns the shared secret on success, or - /// an error if something went wrong. - fn try_decap(&self, encapped_key: &EK) -> Result, Error>; -} - -/// Represents the functionality of a authenticated-key decapsulator, where `Self` is a -/// cryptographic key. -pub trait AuthDecapsulator { - /// Attempt to decapsulate the given encapsulated key. The resulting shared secret is bound to - /// the provided sender identity, thus providing authenticity. Returns the shared secret - /// success, or an error if something went wrong. - fn try_auth_decap( - &self, - encapped_key: &EK, - sender_pubkey: &EK::SenderPublicKey, - ) -> Result, Error>; -} diff --git a/kem/src/lib.rs b/kem/src/lib.rs index 7faf1d05c..27dc0aa19 100644 --- a/kem/src/lib.rs +++ b/kem/src/lib.rs @@ -9,11 +9,27 @@ #![forbid(unsafe_code)] #![warn(missing_docs, unused_qualifications, missing_debug_implementations)] -#[cfg(feature = "std")] -extern crate std; +use core::fmt::Debug; +use rand_core::CryptoRngCore; -mod errors; -mod kem; +/// A value that can be encapsulated to. Often, this will just be a public key. However, it can +/// also be a bundle of public keys, or it can include a sender's private key for authenticated +/// encapsulation. +pub trait Encapsulate { + /// Encapsulation error + type Error: Debug; -pub use crate::{errors::*, kem::*}; -pub use generic_array; + /// Encapsulates a fresh shared secret + fn encapsulate(&self, rng: &mut impl CryptoRngCore) -> Result<(EK, SS), Self::Error>; +} + +/// A value that can be used to decapsulate an encapsulated key. Often, this will just be a secret +/// key. But, as with [`Encapsulate`], it can be a bundle of secret keys, or it can include a +/// sender's private key for authenticated encapsulation. +pub trait Decapsulate { + /// Decapsulation error + type Error: Debug; + + /// Decapsulates the given encapsulated key + fn decapsulate(&self, encapsulated_key: &EK) -> Result; +} diff --git a/kem/tests/hpke.rs b/kem/tests/hpke.rs index 43df15cd2..43ad61c9d 100644 --- a/kem/tests/hpke.rs +++ b/kem/tests/hpke.rs @@ -1,163 +1,53 @@ +use kem::{Decapsulate, Encapsulate}; + use hpke::{ kem::{Kem as KemTrait, X25519HkdfSha256}, - Deserializable as HpkeDeserializable, Serializable as HpkeSerializable, -}; -use kem::{ - generic_array::GenericArray, AuthDecapsulator, Decapsulator, EncappedKey, Encapsulator, Error, - SharedSecret, + HpkeError, }; -use rand::rngs::OsRng; -use rand_core::{CryptoRng, RngCore}; +use rand_core::{CryptoRng, CryptoRngCore, RngCore}; -// Define the pubkey type. This has no trait bounds required by the library -#[derive(Clone)] -struct X25519PublicKey(::PublicKey); +type SharedSecret = hpke::kem::SharedSecret; +type EncappedKey = ::EncappedKey; -// Define the encapsulated key type and impl the necessary traits. Since authenticated and -// unauthenticated DHKEMs have the same encapped key type, this will support both types of -// algorithms. In practice, one should use types to distinguish between the two. But this is just -// test code, so whatever. -#[derive(Debug)] -struct X25519EncappedKey( - // It's just an array of bytes - GenericArray::EncappedKey as HpkeSerializable>::OutputSize>, -); -impl EncappedKey for X25519EncappedKey { - type SharedSecretSize = ::NSecret; - type EncappedKeySize = - <::PublicKey as HpkeSerializable>::OutputSize; - // In HPKE the only recipient public key is the identity key - type RecipientPublicKey = X25519PublicKey; - // The sender's pubkey is the identity too - type SenderPublicKey = X25519PublicKey; +// We have to define a newtype for the public and private keys because we're gonna impl +// the Encapsulate and Decapsulate traits for them +struct PublicKey(::PublicKey); +struct PrivateKey(::PrivateKey); - fn from_bytes(bytes: &GenericArray) -> Result { - Ok(X25519EncappedKey(*bytes)) - } -} -impl AsRef<[u8]> for X25519EncappedKey { - fn as_ref(&self) -> &[u8] { - &self.0 - } -} - -// Define some convenience types -type X25519PrivateKey = ::PrivateKey; -type X25519SharedSecret = SharedSecret; - -// Define an authenticated encapsulator. To authenticate, we need a full sender keypair. -struct X25519AuthEncap(X25519PrivateKey, X25519PublicKey); -impl Encapsulator for X25519AuthEncap { - fn try_encap( - &self, - csprng: &mut R, - recip_pubkey: &X25519PublicKey, - ) -> Result<(X25519EncappedKey, X25519SharedSecret), Error> { - ::encap(&recip_pubkey.0, Some((&self.0, &(self.1).0)), csprng) - .map(|(ss, ek)| { - ( - X25519EncappedKey(ek.to_bytes()), - X25519SharedSecret::new(ss.0), - ) - }) - .map_err(|_| Error) - } -} +impl Encapsulate for PublicKey { + type Error = HpkeError; -// Define an unauthenticated encapsulator. This doesn't need any state at all. -struct X25519Encap; -impl Encapsulator for X25519Encap { - fn try_encap( + fn encapsulate( &self, - csprng: &mut R, - recip_pubkey: &X25519PublicKey, - ) -> Result<(X25519EncappedKey, X25519SharedSecret), Error> { - ::encap(&recip_pubkey.0, None, csprng) - .map(|(ss, ek)| { - ( - X25519EncappedKey(ek.to_bytes()), - X25519SharedSecret::new(ss.0), - ) - }) - .map_err(|_| Error) + mut csprng: &mut impl CryptoRngCore, + ) -> Result<(EncappedKey, SharedSecret), HpkeError> { + ::encap(&self.0, None, &mut csprng).map(|(ek, ss)| (ss, ek)) } } -// Define an decapsulator. Since authenticated and unauthenticated encapped keys are represented by -// the same type (which, outside of testing, should not be the case), this can do both auth'd and -// unauth'd decapsulation. -impl Decapsulator for X25519PrivateKey { - fn try_decap(&self, encapped_key: &X25519EncappedKey) -> Result { - // First parse the encapped key, since it's just bytes right now - let deserialized_encapped_key = - <::EncappedKey as HpkeDeserializable>::from_bytes( - &encapped_key.0, - ) - .map_err(|_| Error)?; +impl Decapsulate for PrivateKey { + type Error = HpkeError; - // Now decapsulate - ::decap(self, None, &deserialized_encapped_key) - .map(|ss| SharedSecret::new(ss.0)) - .map_err(|_| Error) - } -} -impl AuthDecapsulator for X25519PrivateKey { - fn try_auth_decap( - &self, - encapped_key: &X25519EncappedKey, - sender_pubkey: &X25519PublicKey, - ) -> Result { - // First parse the encapped key, since it's just bytes right now - let deserialized_encapped_key = - <::EncappedKey as HpkeDeserializable>::from_bytes( - &encapped_key.0, - ) - .map_err(|_| Error)?; - - // Now decapsulate - ::decap( - self, - Some(&sender_pubkey.0), - &deserialized_encapped_key, - ) - .map(|ss| X25519SharedSecret::new(ss.0)) - .map_err(|_| Error) + fn decapsulate(&self, encapped_key: &EncappedKey) -> Result { + ::decap(&self.0, None, encapped_key) } } // A simple wrapper around the keypair generation function -fn gen_keypair(csprng: &mut R) -> (X25519PrivateKey, X25519PublicKey) { +fn gen_keypair(csprng: &mut R) -> (PrivateKey, PublicKey) { let (sk, pk) = X25519HkdfSha256::gen_keypair(csprng); - let wrapped_pk = X25519PublicKey(pk); - - (sk, wrapped_pk) + (PrivateKey(sk), PublicKey(pk)) } #[test] fn test_hpke() { - let mut rng = OsRng; + let mut rng = rand::thread_rng(); - // Make a sender and recipient keypair - let (sk_sender, pk_sender) = gen_keypair(&mut rng); + // Make a recipient's keypair let (sk_recip, pk_recip) = gen_keypair(&mut rng); - // Try an unauthed encap first. Check that the derived shared secrets are equal - let encapper = X25519Encap; - let (ek, ss1) = encapper.try_encap(&mut rng, &pk_recip).unwrap(); - let ss2 = sk_recip.try_decap(&ek).unwrap(); - assert_eq!(ss1.as_bytes(), ss2.as_bytes()); - - // Now do an authenticated encap - let encapper = X25519AuthEncap(sk_sender, pk_sender.clone()); - let (ek, ss1) = encapper.try_encap(&mut rng, &pk_recip).unwrap(); - let ss2 = sk_recip.try_auth_decap(&ek, &pk_sender).unwrap(); - assert_eq!(ss1.as_bytes(), ss2.as_bytes()); - - // Now do an invalid authenticated encap, where the sender uses the wrong private key. This - // should produce unequal shared secrets. - let (rand_sk, _) = gen_keypair(&mut rng); - let encapper = X25519AuthEncap(rand_sk, pk_sender.clone()); - let (ek, ss1) = encapper.try_encap(&mut rng, &pk_recip).unwrap(); - let ss2 = sk_recip.try_auth_decap(&ek, &pk_sender).unwrap(); - assert_ne!(ss1.as_bytes(), ss2.as_bytes()); + // Encapsulate to the recipient. Check that the derived shared secrets are equal + let (ek, ss1) = pk_recip.encapsulate(&mut rng).unwrap(); + let ss2 = sk_recip.decapsulate(&ek).unwrap(); + assert_eq!(ss1.0, ss2.0); } diff --git a/kem/tests/saber.rs b/kem/tests/saber.rs index ce70c47d1..13e85ef6b 100644 --- a/kem/tests/saber.rs +++ b/kem/tests/saber.rs @@ -1,93 +1,53 @@ -use kem::{ - generic_array::{ - typenum::{self, U1000, U32, U472}, - GenericArray, - }, - Decapsulator, EncappedKey, Encapsulator, Error, SharedSecret, -}; +use kem::{Decapsulate, Encapsulate}; + use pqcrypto::kem::firesaber::{ - decapsulate, encapsulate, keypair, Ciphertext, PublicKey, SecretKey, + decapsulate, encapsulate, keypair, Ciphertext as SaberEncappedKey, PublicKey, SecretKey, + SharedSecret as SaberSharedSecret, }; -use pqcrypto_traits::kem::{Ciphertext as CiphertextTrait, SharedSecret as SharedSecretTrait}; -use rand::rngs::OsRng; -use rand_core::{CryptoRng, RngCore}; - -// Define the pubkey type. This has no trait bounds required by the library -type SaberPublicKey = PublicKey; +use rand_core::CryptoRngCore; -// The encapped key type is called "Ciphertext" in Rust's pqcrypto. Impl the necessary traits. -struct SaberEncappedKey(Ciphertext); -impl EncappedKey for SaberEncappedKey { - type SharedSecretSize = U32; - // FireSaber encapped keys are 1472 bytes; - type EncappedKeySize = typenum::op!(U1000 + U472); +// We have to define a newtype for the public and private keys because we're gonna impl +// the Encapsulate and Decapsulate traits for them +struct SaberPublicKey(PublicKey); +struct SaberPrivateKey(SecretKey); - // In HPKE the only recipient public key is the identity key - type RecipientPublicKey = SaberPublicKey; - // The sender's pubkey is the identity too - type SenderPublicKey = SaberPrivateKey; +impl Encapsulate for SaberPublicKey { + // TODO: Encapsulation is infallible. Make this the never type once it's available + type Error = (); - fn from_bytes(bytes: &GenericArray) -> Result { - Ciphertext::from_bytes(bytes.as_slice()) - .map(SaberEncappedKey) - .map_err(|_| Error) - } -} -impl AsRef<[u8]> for SaberEncappedKey { - fn as_ref(&self) -> &[u8] { - self.0.as_bytes() - } -} -impl core::fmt::Debug for SaberEncappedKey { - fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { - write!(f, "{:x?}", self.as_ref()) + fn encapsulate( + &self, + _: &mut impl CryptoRngCore, + ) -> Result<(SaberEncappedKey, SaberSharedSecret), ()> { + let (ss, ek) = encapsulate(&self.0); + Ok((ek, ss)) } } -// Define some convenience types -type SaberSharedSecret = SharedSecret; -type SaberPrivateKey = SecretKey; - -// Define an unauthenticated encapsulator. It holds nothing at all -struct SaberEncapper; -impl Encapsulator for SaberEncapper { - fn try_encap( - &self, - _csprng: &mut R, - recip_pubkey: &SaberPublicKey, - ) -> Result<(SaberEncappedKey, SaberSharedSecret), Error> { - let (ss, ek) = encapsulate(recip_pubkey); - let ss_bytes = SaberSharedSecret::new(GenericArray::clone_from_slice(ss.as_bytes())); +impl Decapsulate for SaberPrivateKey { + // TODO: Decapsulation is infallible. Make this the never type once it's available + type Error = (); - Ok((SaberEncappedKey(ek), ss_bytes)) + fn decapsulate(&self, ek: &SaberEncappedKey) -> Result { + Ok(decapsulate(ek, &self.0)) } } -// Define a decapsulator -impl Decapsulator for SaberPrivateKey { - fn try_decap(&self, encapped_key: &SaberEncappedKey) -> Result { - let ss = decapsulate(&encapped_key.0, self); - Ok(SaberSharedSecret::new(GenericArray::clone_from_slice( - ss.as_bytes(), - ))) - } +fn gen_keypair() -> (SaberPublicKey, SaberPrivateKey) { + let (pk, sk) = keypair(); + (SaberPublicKey(pk), SaberPrivateKey(sk)) } #[test] fn test_saber() { - let mut rng = OsRng; + use pqcrypto_traits::kem::SharedSecret as _; + let mut rng = rand::thread_rng(); // Make a recipient keypair - let (pk_recip, sk_recip) = keypair(); + let (pk_recip, sk_recip) = gen_keypair(); - // Do an unauthed encap. Check that the derived shared secrets are equal - let encapper = SaberEncapper; - let (ek, ss1) = encapper.try_encap(&mut rng, &pk_recip).unwrap(); - let ss2 = sk_recip.try_decap(&ek).unwrap(); + // Encapsulate and decapsulate. Assert that the shared secrets are equal + let (ek, ss1) = pk_recip.encapsulate(&mut rng).unwrap(); + let ss2 = sk_recip.decapsulate(&ek).unwrap(); assert_eq!(ss1.as_bytes(), ss2.as_bytes()); - - // Test serialization/deserialization - let ek_bytes = ek.as_bytes(); - let ek2 = SaberEncappedKey::from_bytes(ek_bytes).unwrap(); - assert_eq!(ek.as_bytes(), ek2.as_bytes()); } diff --git a/kem/tests/x3dh.rs b/kem/tests/x3dh.rs index 0081a7197..b39a5adf8 100644 --- a/kem/tests/x3dh.rs +++ b/kem/tests/x3dh.rs @@ -1,20 +1,12 @@ -use kem::{ - generic_array::{ - typenum::{self, Unsigned}, - GenericArray, - }, - AuthDecapsulator, EncappedKey, Encapsulator, Error, SharedSecret, -}; +use kem::{Decapsulate, Encapsulate}; + use p256::ecdsa::Signature; -use rand::rngs::OsRng; -use rand_core::{CryptoRng, RngCore}; +use rand_core::CryptoRngCore; use x3dh_ke::{x3dh_a, x3dh_b, EphemeralKey, IdentityKey, Key, OneTimePreKey, SignedPreKey}; -// The size of an encapped key. This is the number of bytes in an uncompressed P256 point -type NEnc = typenum::U231; +/// The shared secret type defined by x3dh_ke +type SharedSecret = [u8; 32]; -// Define the sender pubkey type. This is an identity key; -type X3DhSenderPublicKey = IdentityKey; // Define the recipient privkey type. This is a bundle of 3 privkeys of different lifespans struct X3DhPrivkeyBundle { ik: IdentityKey, @@ -22,8 +14,10 @@ struct X3DhPrivkeyBundle { sig: Signature, opk: OneTimePreKey, } + impl X3DhPrivkeyBundle { fn gen() -> X3DhPrivkeyBundle { + // The default() method does actual key generation here let ik = IdentityKey::default(); let spk = SignedPreKey::default(); let sig = ik.sign(&spk.pk_to_bytes()); @@ -39,111 +33,81 @@ impl X3DhPrivkeyBundle { } } } + // The pubkeys keys associated with a privkey bundle. In x3dh-ke, all the keys serve as both // pubkeys and privkeys. This seems dangerous but hey this isn't prod. type X3DhPubkeyBundle = X3DhPrivkeyBundle; -// The encapped key is just the byte repr of an ephemeral key. Impl the appropriate traits -#[derive(Debug)] -struct X3DhEncappedKey([u8; NEnc::USIZE]); -impl EncappedKey for X3DhEncappedKey { - type SharedSecretSize = typenum::U32; - type EncappedKeySize = NEnc; - type SenderPublicKey = X3DhSenderPublicKey; - type RecipientPublicKey = X3DhPubkeyBundle; - - fn from_bytes(bytes: &GenericArray) -> Result { - let mut buf = [0u8; NEnc::USIZE]; - buf.copy_from_slice(bytes); - Ok(X3DhEncappedKey(buf)) - } -} -impl AsRef<[u8]> for X3DhEncappedKey { - fn as_ref(&self) -> &[u8] { - &self.0 - } -} +/// To encap, we need the recipient's public keys and the sender's private key +struct EncapContext(X3DhPubkeyBundle, IdentityKey); -// The private key of an authenticated sender is just their identity key. Again, this is the same -// type as the pubkey. -type X3DhSenderPrivateKey = IdentityKey; -type X3DhSharedSecret = SharedSecret; +/// To decap, we need the recipient's private keys and the sender's public key +struct DecapContext(X3DhPrivkeyBundle, IdentityKey); // Define an authenticated encapsulator. To authenticate, we need a full sender keypair. -impl Encapsulator for X3DhSenderPrivateKey { - fn try_encap( +impl Encapsulate for EncapContext { + type Error = &'static str; + + fn encapsulate( &self, - _csprng: &mut R, - recip_pubkey: &X3DhPubkeyBundle, - ) -> Result<(X3DhEncappedKey, X3DhSharedSecret), Error> { + _: &mut impl CryptoRngCore, + ) -> Result<(EphemeralKey, SharedSecret), Self::Error> { // Make a new ephemeral key. This will be the encapped key let ek = EphemeralKey::default(); // Deconstruct the recipient's pubkey bundle - let X3DhPubkeyBundle { ik, spk, sig, opk } = recip_pubkey; + let X3DhPubkeyBundle { + ref ik, + ref spk, + ref sig, + ref opk, + } = self.0; + let my_ik = &self.1; // Do the X3DH operation to get the shared secret - let shared_secret = x3dh_a(sig, self, spk, &ek, ik, opk) - .map(|ss| X3DhSharedSecret::new(ss.into())) - .map_err(|e| { - println!("err {:?}", e); - Error - })?; - // Serialize the ephemeral key - let encapped_key = X3DhEncappedKey::from_bytes(ek.to_bytes().as_slice().into())?; - - Ok((encapped_key, shared_secret)) + let shared_secret = x3dh_a(sig, my_ik, spk, &ek, ik, opk)?; + + Ok((ek, shared_secret)) } } // Define an decapsulator. Since authenticated and unauthenticated encapped keys are represented by // the same type (which, outside of testing, should not be the case), this can do both auth'd and // unauth'd decapsulation. -impl AuthDecapsulator for X3DhPrivkeyBundle { - fn try_auth_decap( - &self, - encapped_key: &X3DhEncappedKey, - sender_pubkey: &X3DhSenderPublicKey, - ) -> Result { - // First parse the encapped key, since it's just bytes right now - let deserialized_ek = EphemeralKey::from_bytes(&encapped_key.0).map_err(|_| Error)?; +impl Decapsulate for DecapContext { + // TODO: Decapsulation is infallible. Make the Error type `!` when it's stable. + type Error = (); + + fn decapsulate(&self, ek: &EphemeralKey) -> Result { // Deconstruct our private keys bundle - let X3DhPubkeyBundle { - ik, - spk, - sig: _, - opk, - } = self; + let X3DhPrivkeyBundle { + ref ik, + ref spk, + ref opk, + .. + } = self.0; + let sender_pubkey = &self.1; // Now decapsulate - let buf = x3dh_b(sender_pubkey, spk, &deserialized_ek, ik, opk); - Ok(X3DhSharedSecret::new(buf.into())) + Ok(x3dh_b(sender_pubkey, spk, ek, ik, opk)) } } #[test] fn test_x3dh() { - let mut rng = OsRng; + let mut rng = rand::thread_rng(); // We use _a and _b suffixes to denote whether a key belongs to Alice or Bob. Alice is the // sender in this case. - let sk_ident_a = X3DhSenderPrivateKey::default(); + let sk_ident_a = IdentityKey::default(); let pk_ident_a = sk_ident_a.strip(); let sk_bundle_b = X3DhPrivkeyBundle::gen(); let pk_bundle_b = sk_bundle_b.as_pubkeys(); + let encap_context = EncapContext(pk_bundle_b, sk_ident_a); + let decap_context = DecapContext(sk_bundle_b, pk_ident_a); + // Now do an authenticated encap - let (encapped_key, ss1) = sk_ident_a.try_encap(&mut rng, &pk_bundle_b).unwrap(); - let ss2 = sk_bundle_b - .try_auth_decap(&encapped_key, &pk_ident_a) - .unwrap(); - assert_eq!(ss1.as_bytes(), ss2.as_bytes()); - - // Now do an invalid authenticated encap, where the sender uses the wrong private key. This - // should produce unequal shared secrets. - let sk_ident_rando = X3DhSenderPrivateKey::default(); - let (encapped_key, ss1) = sk_ident_rando.try_encap(&mut rng, &pk_bundle_b).unwrap(); - let ss2 = sk_bundle_b - .try_auth_decap(&encapped_key, &pk_ident_a) - .unwrap(); - assert_ne!(ss1.as_bytes(), ss2.as_bytes()); + let (encapped_key, ss1) = encap_context.encapsulate(&mut rng).unwrap(); + let ss2 = decap_context.decapsulate(&encapped_key).unwrap(); + assert_eq!(ss1, ss2); } From 022eb01a518be3e35032e1b4dadbd255e2680b7d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 2 Apr 2024 12:45:09 -0600 Subject: [PATCH 1175/1461] async-signature: `no_std` support (#1544) --- .github/workflows/async-signature.yml | 19 +++++++++++++++++++ async-signature/src/lib.rs | 1 + 2 files changed, 20 insertions(+) diff --git a/.github/workflows/async-signature.yml b/.github/workflows/async-signature.yml index 775f402fc..468c2028f 100644 --- a/.github/workflows/async-signature.yml +++ b/.github/workflows/async-signature.yml @@ -18,6 +18,25 @@ env: RUSTFLAGS: "-Dwarnings" jobs: + no_std: + runs-on: ubuntu-latest + strategy: + matrix: + rust: + - 1.75.0 # MSRV + - stable + target: + - thumbv7em-none-eabi + - wasm32-unknown-unknown + steps: + - uses: actions/checkout@v4 + - uses: RustCrypto/actions/cargo-cache@master + - uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ matrix.rust }} + targets: ${{ matrix.target }} + - run: cargo build --target ${{ matrix.target }} --release --no-default-features + test: runs-on: ubuntu-latest strategy: diff --git a/async-signature/src/lib.rs b/async-signature/src/lib.rs index 08633dce8..cef50e8e5 100644 --- a/async-signature/src/lib.rs +++ b/async-signature/src/lib.rs @@ -1,3 +1,4 @@ +#![no_std] #![doc = include_str!("../README.md")] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", From dadaf3591795ba0820080ca45d0feaabd5303ded Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 2 Apr 2024 12:51:52 -0600 Subject: [PATCH 1176/1461] async-signature: add CHANGELOG.md entry for v0.5.1 (#1545) It contains a packport of #1544. Tagged as https://github.com/RustCrypto/traits/tree/async-signature-v0.5.1 --- async-signature/CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/async-signature/CHANGELOG.md b/async-signature/CHANGELOG.md index b7d7aac4f..70bd82f9e 100644 --- a/async-signature/CHANGELOG.md +++ b/async-signature/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.5.1 (2024-04-02) +### Added +- `no_std` support ([#1544]) + +[#1544]: https://github.com/RustCrypto/traits/pull/1544 + ## 0.5.0 (2024-01-02) ### Added - Debug impls ([#1407]) From a593570835505c0e401ed1dd26a1b6a45c44ab34 Mon Sep 17 00:00:00 2001 From: Sylvain Pelissier Date: Fri, 12 Apr 2024 17:46:49 +0200 Subject: [PATCH 1177/1461] Add hash customization traits (#1334) Some hash function constructions allow to have a customization string to have domain separation in hash functions. This is the case for [CSHAKE](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-185.pdf#page=14) and [Blake2](https://www.blake2.net/blake2.pdf#page=6): With these new traits, the construction of hash functions with customization strings would be simpler. From currently for CSHAKE: ```rust let mut hasher = CShake128::from_core(CShake128Core::new(b"test")); ``` To: ```rust let mut hasher = CShake128:new_personalization(b"test")); ``` --- digest/CHANGELOG.md | 4 ++++ digest/src/core_api/wrapper.rs | 25 +++++++++++++++++++++++-- digest/src/lib.rs | 15 +++++++++++++++ 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/digest/CHANGELOG.md b/digest/CHANGELOG.md index f715b731b..afff142f6 100644 --- a/digest/CHANGELOG.md +++ b/digest/CHANGELOG.md @@ -6,6 +6,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## UNRELEASED +### Added +- `CustomizedInit` trait ([#1334]). + ### Changed - `crypto-common` dependency bumped to v0.2 ([#1173]) - Edition changed to 2021 and MSRV bumped to 1.57 ([#1173]) @@ -14,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `Mac::new`, `Mac::new_from_slice`, and `Mac::generate_key` methods ([#1173]) [#1173]: https://github.com/RustCrypto/traits/pull/1173 +[#1334]: https://github.com/RustCrypto/traits/pull/1334 ## 0.10.7 (2023-05-19) ### Changed diff --git a/digest/src/core_api/wrapper.rs b/digest/src/core_api/wrapper.rs index 32b8a5a1c..9b72e2231 100644 --- a/digest/src/core_api/wrapper.rs +++ b/digest/src/core_api/wrapper.rs @@ -3,7 +3,8 @@ use super::{ UpdateCore, XofReaderCoreWrapper, }; use crate::{ - ExtendableOutput, ExtendableOutputReset, FixedOutput, FixedOutputReset, HashMarker, Update, + CustomizedInit, ExtendableOutput, ExtendableOutputReset, FixedOutput, FixedOutputReset, + HashMarker, Update, }; use block_buffer::BlockBuffer; use core::{ @@ -160,8 +161,28 @@ impl Drop for CoreWrapper { #[cfg(feature = "zeroize")] impl zeroize::ZeroizeOnDrop for CoreWrapper {} +impl CustomizedInit for CoreWrapper +where + T: BufferKindUser + CustomizedInit, +{ + type CustomizedExtArg = T::CustomizedExtArg; + + #[inline] + fn new_customized(customization: &[u8]) -> Self { + Self::from_core(T::new_customized(customization)) + } + + #[inline] + fn new_ext_customized(customization_ext: &Self::CustomizedExtArg) -> Self { + Self::from_core(T::new_ext_customized(customization_ext)) + } +} + #[cfg(feature = "oid")] -impl AssociatedOid for CoreWrapper { +impl AssociatedOid for CoreWrapper +where + T: BufferKindUser + AssociatedOid, +{ const OID: ObjectIdentifier = T::OID; } diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 29fd0863e..e129f4e52 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -268,6 +268,21 @@ pub trait VariableOutputReset: VariableOutput + Reset { } } +/// Trait for hash functions with customization string for domain separation. +pub trait CustomizedInit: Sized { + // TODO: It would be nice to define a default value equal to `[u8]`, but unfortunately + // associated type defaults are currently unstable + + /// Extended customization + type CustomizedExtArg; + + /// Create new hasher instance with the given customization string. + fn new_customized(customization: &[u8]) -> Self; + + /// Create new hasher instance with the given extended customization. + fn new_ext_customized(customization_ext: &Self::CustomizedExtArg) -> Self; +} + /// The error type used in variable hash traits. #[derive(Clone, Copy, Debug, Default)] pub struct InvalidOutputSize; From b5a420e6b47eab72704ba9bf8afab68a5842b43b Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Fri, 12 Apr 2024 18:54:40 +0300 Subject: [PATCH 1178/1461] Update Cargo.lock (#1551) --- Cargo.lock | 74 +++++++++++++++++++++++++++--------------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8f099192e..f37ff6905 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -25,9 +25,9 @@ dependencies = [ [[package]] name = "aes" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if", "cipher 0.4.4", @@ -63,9 +63,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" [[package]] name = "base16ct" @@ -172,9 +172,9 @@ checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" [[package]] name = "cc" -version = "1.0.83" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +checksum = "2678b2e3449475e95b0aa6f9b506a28e61b3dc8996592b983695e8ebb58a8b41" dependencies = [ "jobserver", "libc", @@ -404,9 +404,9 @@ dependencies = [ [[package]] name = "der" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" dependencies = [ "const-oid 0.9.6", "zeroize", @@ -615,9 +615,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.12" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" dependencies = [ "cfg-if", "libc", @@ -626,9 +626,9 @@ dependencies = [ [[package]] name = "ghash" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d930750de5717d2dd0b8c0d42c076c0e884c81a73e6cab859bbd2339c71e3e40" +checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" dependencies = [ "opaque-debug", "polyval", @@ -808,15 +808,15 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jobserver" -version = "0.1.27" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" +checksum = "f08474e32172238f2827bd160c67871cdb2801430f65c3979184dc362e3ca118" dependencies = [ "libc", ] @@ -852,18 +852,18 @@ checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" dependencies = [ "autocfg", ] [[package]] name = "opaque-debug" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "p256" @@ -941,7 +941,7 @@ version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ - "der 0.7.8", + "der 0.7.9", "spki 0.7.3", ] @@ -968,9 +968,9 @@ dependencies = [ [[package]] name = "polyval" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52cff9d1d4dee5fe6d03729099f4a310a41179e0a10dbf542039873f2e826fb" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" dependencies = [ "cfg-if", "cpufeatures", @@ -1036,9 +1036,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -1087,9 +1087,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.16" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" [[package]] name = "sec1" @@ -1111,7 +1111,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct 0.2.0", - "der 0.7.8", + "der 0.7.9", "generic-array", "pkcs8 0.10.2", "subtle", @@ -1135,9 +1135,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.196" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" dependencies = [ "serde_derive", ] @@ -1153,9 +1153,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.196" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", @@ -1164,9 +1164,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.114" +version = "1.0.115" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" +checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" dependencies = [ "itoa", "ryu", @@ -1283,7 +1283,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", - "der 0.7.8", + "der 0.7.9", ] [[package]] @@ -1310,9 +1310,9 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "syn" -version = "2.0.52" +version = "2.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" +checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687" dependencies = [ "proc-macro2", "quote", From 25e5654bb0775d255abd937e3b3320b982f13da1 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 17 Apr 2024 09:01:36 -0600 Subject: [PATCH 1179/1461] kem v0.3.0-pre.0 (#1555) --- Cargo.lock | 2 +- kem/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f37ff6905..1cf9a41f1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -832,7 +832,7 @@ dependencies = [ [[package]] name = "kem" -version = "0.3.0-pre" +version = "0.3.0-pre.0" dependencies = [ "hpke", "p256 0.9.0", diff --git a/kem/Cargo.toml b/kem/Cargo.toml index d306ea4c2..dce5587c1 100644 --- a/kem/Cargo.toml +++ b/kem/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "kem" description = "Traits for key encapsulation mechanisms" -version = "0.3.0-pre" +version = "0.3.0-pre.0" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/kem" From 5acf43b0ca10cfd6d1a6dec02e8af92345049c77 Mon Sep 17 00:00:00 2001 From: Sylvain Pelissier Date: Tue, 30 Apr 2024 04:12:10 +0200 Subject: [PATCH 1180/1461] Add liftime to CustomizedExtArg (#1561) --- digest/src/core_api/wrapper.rs | 4 ++-- digest/src/lib.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/digest/src/core_api/wrapper.rs b/digest/src/core_api/wrapper.rs index 9b72e2231..48f7f9963 100644 --- a/digest/src/core_api/wrapper.rs +++ b/digest/src/core_api/wrapper.rs @@ -165,7 +165,7 @@ impl CustomizedInit for CoreWrapper where T: BufferKindUser + CustomizedInit, { - type CustomizedExtArg = T::CustomizedExtArg; + type CustomizedExtArg<'a> = T::CustomizedExtArg<'a>; #[inline] fn new_customized(customization: &[u8]) -> Self { @@ -173,7 +173,7 @@ where } #[inline] - fn new_ext_customized(customization_ext: &Self::CustomizedExtArg) -> Self { + fn new_ext_customized(customization_ext: &Self::CustomizedExtArg<'_>) -> Self { Self::from_core(T::new_ext_customized(customization_ext)) } } diff --git a/digest/src/lib.rs b/digest/src/lib.rs index e129f4e52..36c1a397b 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -274,13 +274,13 @@ pub trait CustomizedInit: Sized { // associated type defaults are currently unstable /// Extended customization - type CustomizedExtArg; + type CustomizedExtArg<'a>; /// Create new hasher instance with the given customization string. fn new_customized(customization: &[u8]) -> Self; /// Create new hasher instance with the given extended customization. - fn new_ext_customized(customization_ext: &Self::CustomizedExtArg) -> Self; + fn new_ext_customized(customization_ext: &Self::CustomizedExtArg<'_>) -> Self; } /// The error type used in variable hash traits. From f79f286a8536816c240c50810509cbb2fc733341 Mon Sep 17 00:00:00 2001 From: Sylvain Pelissier Date: Sun, 5 May 2024 19:16:25 +0200 Subject: [PATCH 1181/1461] Remove CustomizedExtArg (#1564) --- digest/src/core_api/wrapper.rs | 7 ------- digest/src/lib.rs | 9 --------- 2 files changed, 16 deletions(-) diff --git a/digest/src/core_api/wrapper.rs b/digest/src/core_api/wrapper.rs index 48f7f9963..d366249fe 100644 --- a/digest/src/core_api/wrapper.rs +++ b/digest/src/core_api/wrapper.rs @@ -165,17 +165,10 @@ impl CustomizedInit for CoreWrapper where T: BufferKindUser + CustomizedInit, { - type CustomizedExtArg<'a> = T::CustomizedExtArg<'a>; - #[inline] fn new_customized(customization: &[u8]) -> Self { Self::from_core(T::new_customized(customization)) } - - #[inline] - fn new_ext_customized(customization_ext: &Self::CustomizedExtArg<'_>) -> Self { - Self::from_core(T::new_ext_customized(customization_ext)) - } } #[cfg(feature = "oid")] diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 36c1a397b..b535bc8aa 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -270,17 +270,8 @@ pub trait VariableOutputReset: VariableOutput + Reset { /// Trait for hash functions with customization string for domain separation. pub trait CustomizedInit: Sized { - // TODO: It would be nice to define a default value equal to `[u8]`, but unfortunately - // associated type defaults are currently unstable - - /// Extended customization - type CustomizedExtArg<'a>; - /// Create new hasher instance with the given customization string. fn new_customized(customization: &[u8]) -> Self; - - /// Create new hasher instance with the given extended customization. - fn new_ext_customized(customization_ext: &Self::CustomizedExtArg<'_>) -> Self; } /// The error type used in variable hash traits. From b9d49af5016b95406bae33df6e7808536cadaf44 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 28 May 2024 15:56:41 -0600 Subject: [PATCH 1182/1461] Cargo.lock: bump dependencies (#1580) Updates the following dependencies: $ cargo update Updating crates.io index Updating autocfg v1.2.0 -> v1.3.0 Updating cc v1.0.92 -> v1.0.98 Updating getrandom v0.2.14 -> v0.2.15 Updating jobserver v0.1.29 -> v0.1.31 Updating libc v0.2.153 -> v0.2.155 Updating num-traits v0.2.18 -> v0.2.19 Adding once_cell v1.19.0 Updating proc-macro2 v1.0.79 -> v1.0.84 Updating ryu v1.0.17 -> v1.0.18 Updating serde v1.0.197 -> v1.0.203 Updating serde_derive v1.0.197 -> v1.0.203 Updating serde_json v1.0.115 -> v1.0.117 Updating syn v2.0.58 -> v2.0.66 Updating zeroize v1.7.0 -> v1.8.1 --- Cargo.lock | 59 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 33 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1cf9a41f1..6c3cf733d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -63,9 +63,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "base16ct" @@ -172,12 +172,13 @@ checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" [[package]] name = "cc" -version = "1.0.92" +version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2678b2e3449475e95b0aa6f9b506a28e61b3dc8996592b983695e8ebb58a8b41" +checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f" dependencies = [ "jobserver", "libc", + "once_cell", ] [[package]] @@ -615,9 +616,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", @@ -814,9 +815,9 @@ checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jobserver" -version = "0.1.29" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f08474e32172238f2827bd160c67871cdb2801430f65c3979184dc362e3ca118" +checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" dependencies = [ "libc", ] @@ -846,19 +847,25 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.153" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "num-traits" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + [[package]] name = "opaque-debug" version = "0.3.1" @@ -1027,9 +1034,9 @@ checksum = "94e851c7654eed9e68d7d27164c454961a616cf8c203d500607ef22c737b51bb" [[package]] name = "proc-macro2" -version = "1.0.79" +version = "1.0.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +checksum = "ec96c6a92621310b51366f1e28d05ef11489516e93be030060e5fc12024a49d6" dependencies = [ "unicode-ident", ] @@ -1087,9 +1094,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "sec1" @@ -1135,9 +1142,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.197" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" dependencies = [ "serde_derive", ] @@ -1153,9 +1160,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", @@ -1164,9 +1171,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.115" +version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" +checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" dependencies = [ "itoa", "ryu", @@ -1310,9 +1317,9 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "syn" -version = "2.0.58" +version = "2.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687" +checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" dependencies = [ "proc-macro2", "quote", @@ -1407,9 +1414,9 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" dependencies = [ "zeroize_derive", ] From 96d5c212b6d6fbb1170b07239ecd5def31428305 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 May 2024 16:17:38 -0600 Subject: [PATCH 1183/1461] build(deps): bump hpke from 0.10.0 to 0.11.0 (#1360) Bumps [hpke](https://github.com/rozbb/rust-hpke) from 0.10.0 to 0.11.0. - [Changelog](https://github.com/rozbb/rust-hpke/blob/master/CHANGELOG.md) - [Commits](https://github.com/rozbb/rust-hpke/compare/v0.10.0...v0.11.0) --- updated-dependencies: - dependency-name: hpke dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 222 +++++++++++++++++++++---------------------------- kem/Cargo.toml | 2 +- 2 files changed, 94 insertions(+), 130 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6c3cf733d..c13f5dfe4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -67,12 +67,6 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" -[[package]] -name = "base16ct" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" - [[package]] name = "base16ct" version = "0.2.0" @@ -280,19 +274,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8658c15c5d921ddf980f7fe25b1e82f4b7a4083b2c4985fea4922edb8e43e07d" dependencies = [ "generic-array", - "rand_core 0.6.4", - "subtle", - "zeroize", -] - -[[package]] -name = "crypto-bigint" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" -dependencies = [ - "generic-array", - "rand_core 0.6.4", + "rand_core", "subtle", "zeroize", ] @@ -304,7 +286,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ "generic-array", - "rand_core 0.6.4", + "rand_core", "subtle", "zeroize", ] @@ -317,7 +299,7 @@ checksum = "1943d7beadd9ce2b25f3bae73b9e9336fccc1edf38bdec1ed58d3aa183989e11" dependencies = [ "hybrid-array", "num-traits", - "rand_core 0.6.4", + "rand_core", "subtle", "zeroize", ] @@ -329,7 +311,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", - "rand_core 0.6.4", + "rand_core", "typenum", ] @@ -339,7 +321,7 @@ version = "0.2.0-pre.5" dependencies = [ "getrandom", "hybrid-array", - "rand_core 0.6.4", + "rand_core", ] [[package]] @@ -350,7 +332,7 @@ checksum = "b7aa2ec04f5120b830272a481e8d9d8ba4dda140d2cda59b0f1110d5eb93c38e" dependencies = [ "getrandom", "hybrid-array", - "rand_core 0.6.4", + "rand_core", ] [[package]] @@ -374,33 +356,37 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "3.2.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +checksum = "0a677b8922c94e01bdbb12126b0bc852f00447528dee1782229af9c720c3f348" dependencies = [ - "byteorder", - "digest 0.9.0", - "rand_core 0.5.1", + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "fiat-crypto", + "platforms", + "rustc_version", "subtle", - "zeroize", ] [[package]] -name = "der" -version = "0.4.5" +name = "curve25519-dalek-derive" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79b71cca7d95d7681a4b3b9cdf63c8dbc3730d0584c2c74e31416d64a90493f4" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ - "const-oid 0.6.2", + "proc-macro2", + "quote", + "syn", ] [[package]] name = "der" -version = "0.6.1" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +checksum = "79b71cca7d95d7681a4b3b9cdf63c8dbc3730d0584c2c74e31416d64a90493f4" dependencies = [ - "const-oid 0.9.6", + "const-oid 0.6.2", ] [[package]] @@ -497,27 +483,7 @@ dependencies = [ "generic-array", "group 0.10.0", "pkcs8 0.7.6", - "rand_core 0.6.4", - "subtle", - "zeroize", -] - -[[package]] -name = "elliptic-curve" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" -dependencies = [ - "base16ct 0.1.1", - "crypto-bigint 0.4.9", - "der 0.6.1", - "digest 0.10.7", - "ff 0.12.1", - "generic-array", - "group 0.12.1", - "hkdf 0.12.4", - "rand_core 0.6.4", - "sec1 0.3.0", + "rand_core", "subtle", "zeroize", ] @@ -528,13 +494,15 @@ version = "0.13.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ - "base16ct 0.2.0", + "base16ct", "crypto-bigint 0.5.5", + "digest 0.10.7", "ff 0.13.0", "generic-array", "group 0.13.0", + "hkdf 0.12.4", "pkcs8 0.10.2", - "rand_core 0.6.4", + "rand_core", "sec1 0.7.3", "subtle", "zeroize", @@ -544,7 +512,7 @@ dependencies = [ name = "elliptic-curve" version = "0.14.0-pre.5" dependencies = [ - "base16ct 0.2.0", + "base16ct", "base64ct", "crypto-bigint 0.6.0-pre.12", "digest 0.11.0-pre.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -555,7 +523,7 @@ dependencies = [ "hybrid-array", "pem-rfc7468 1.0.0-pre.0", "pkcs8 0.11.0-pre.0", - "rand_core 0.6.4", + "rand_core", "sec1 0.8.0-pre.1", "serde_json", "serdect", @@ -572,17 +540,7 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0f40b2dcd8bc322217a5f6559ae5f9e9d1de202a2ecee2e9eafcbece7562a4f" dependencies = [ - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "ff" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" -dependencies = [ - "rand_core 0.6.4", + "rand_core", "subtle", ] @@ -593,10 +551,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ "bitvec", - "rand_core 0.6.4", + "rand_core", "subtle", ] +[[package]] +name = "fiat-crypto" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + [[package]] name = "funty" version = "2.0.0" @@ -648,18 +612,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c363a5301b8f153d80747126a04b3c82073b9fe3130571a9d170cacdeaf7912" dependencies = [ "ff 0.10.1", - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "group" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" -dependencies = [ - "ff 0.12.1", - "rand_core 0.6.4", + "rand_core", "subtle", ] @@ -670,7 +623,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff 0.13.0", - "rand_core 0.6.4", + "rand_core", "subtle", ] @@ -757,9 +710,9 @@ dependencies = [ [[package]] name = "hpke" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf39e5461bfdc6ad0fbc97067519fcaf96a7a2e67f24cc0eb8a1e7c0c45af792" +checksum = "e04a5933a381bb81f00b083fce6b4528e16d735dbeecbb2bdb45e0dbbf3f7e17" dependencies = [ "aead 0.5.2", "aes-gcm", @@ -769,8 +722,8 @@ dependencies = [ "generic-array", "hkdf 0.12.4", "hmac 0.12.1", - "p256 0.11.1", - "rand_core 0.6.4", + "p256 0.13.2", + "rand_core", "sha2 0.10.8", "subtle", "x25519-dalek", @@ -840,7 +793,7 @@ dependencies = [ "pqcrypto", "pqcrypto-traits", "rand", - "rand_core 0.6.4", + "rand_core", "x3dh-ke", "zeroize", ] @@ -885,11 +838,12 @@ dependencies = [ [[package]] name = "p256" -version = "0.11.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51f44edd08f51e2ade572f141051021c5af22677e42b7dd28a88155151c33594" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" dependencies = [ - "elliptic-curve 0.12.3", + "elliptic-curve 0.13.8", + "primeorder", ] [[package]] @@ -899,7 +853,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" dependencies = [ "base64ct", - "rand_core 0.6.4", + "rand_core", "subtle", ] @@ -908,7 +862,7 @@ name = "password-hash" version = "0.6.0-pre.0" dependencies = [ "base64ct", - "rand_core 0.6.4", + "rand_core", "subtle", ] @@ -962,6 +916,12 @@ dependencies = [ "spki 0.8.0-pre.0", ] +[[package]] +name = "platforms" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db23d408679286588f4d4644f965003d056e3dd5abcaaa938116871d7ce2fee7" + [[package]] name = "poly1305" version = "0.8.0" @@ -1032,6 +992,15 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94e851c7654eed9e68d7d27164c454961a616cf8c203d500607ef22c737b51bb" +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve 0.13.8", +] + [[package]] name = "proc-macro2" version = "1.0.84" @@ -1064,7 +1033,7 @@ checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha", - "rand_core 0.6.4", + "rand_core", ] [[package]] @@ -1074,15 +1043,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core 0.6.4", + "rand_core", ] -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" - [[package]] name = "rand_core" version = "0.6.4" @@ -1093,23 +1056,19 @@ dependencies = [ ] [[package]] -name = "ryu" -version = "1.0.18" +name = "rustc_version" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] [[package]] -name = "sec1" -version = "0.3.0" +name = "ryu" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" -dependencies = [ - "base16ct 0.1.1", - "der 0.6.1", - "generic-array", - "subtle", - "zeroize", -] +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "sec1" @@ -1117,7 +1076,7 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ - "base16ct 0.2.0", + "base16ct", "der 0.7.9", "generic-array", "pkcs8 0.10.2", @@ -1131,7 +1090,7 @@ version = "0.8.0-pre.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "02dc081ed777a3bab68583b52ffb8221677b6e90d483b320963a247e2c07f328" dependencies = [ - "base16ct 0.2.0", + "base16ct", "der 0.8.0-pre.0", "hybrid-array", "pkcs8 0.11.0-pre.0", @@ -1140,6 +1099,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" + [[package]] name = "serde" version = "1.0.203" @@ -1186,7 +1151,7 @@ version = "0.3.0-pre.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "791ef964bfaba6be28a5c3f0c56836e17cb711ac009ca1074b9c735a3ebf240a" dependencies = [ - "base16ct 0.2.0", + "base16ct", "serde", ] @@ -1242,7 +1207,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2807892cfa58e081aa1f1111391c7a0649d4fa127a4ffbe34bcbfb35a1171a4" dependencies = [ "digest 0.9.0", - "rand_core 0.6.4", + "rand_core", ] [[package]] @@ -1251,7 +1216,7 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ - "rand_core 0.6.4", + "rand_core", ] [[package]] @@ -1260,7 +1225,7 @@ version = "2.3.0-pre.3" dependencies = [ "digest 0.11.0-pre.8 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal", - "rand_core 0.6.4", + "rand_core", "sha2 0.11.0-pre.3", "signature_derive", ] @@ -1385,13 +1350,12 @@ dependencies = [ [[package]] name = "x25519-dalek" -version = "2.0.0-pre.1" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5da623d8af10a62342bcbbb230e33e58a63255a58012f8653c578e54bab48df" +checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277" dependencies = [ "curve25519-dalek", - "rand_core 0.6.4", - "zeroize", + "rand_core", ] [[package]] @@ -1406,7 +1370,7 @@ dependencies = [ "getrandom", "hkdf 0.11.0", "p256 0.9.0", - "rand_core 0.6.4", + "rand_core", "serde", "serde_bytes", "sha2 0.9.9", diff --git a/kem/Cargo.toml b/kem/Cargo.toml index dce5587c1..3739e8368 100644 --- a/kem/Cargo.toml +++ b/kem/Cargo.toml @@ -17,7 +17,7 @@ rand_core = "0.6" zeroize = { version = "1.7", default-features = false } [dev-dependencies] -hpke = "0.10" +hpke = "0.11" p256 = { version = "0.9", features = ["ecdsa"] } pqcrypto = { version = "0.15", default-features = false, features = [ "pqcrypto-saber", From 9136636f4508f76d7a92169d05d29ce18caca24a Mon Sep 17 00:00:00 2001 From: joe <55120843+joebebel@users.noreply.github.com> Date: Fri, 31 May 2024 05:21:01 -0700 Subject: [PATCH 1184/1461] digest: add HashWriter and HashReader structs (#1159) --- digest/src/hashreader.rs | 135 +++++++++++++++++++++++++++++++++++++++ digest/src/hashwriter.rs | 120 ++++++++++++++++++++++++++++++++++ digest/src/lib.rs | 9 +++ 3 files changed, 264 insertions(+) create mode 100644 digest/src/hashreader.rs create mode 100644 digest/src/hashwriter.rs diff --git a/digest/src/hashreader.rs b/digest/src/hashreader.rs new file mode 100644 index 000000000..8c303af2a --- /dev/null +++ b/digest/src/hashreader.rs @@ -0,0 +1,135 @@ +//! Adds hashing to any reader +use super::{Digest, FixedOutputReset, Output, Reset}; +use std::io; + +/// Abstraction over a reader which hashes the data being read +pub struct HashReader { + reader: R, + hasher: D, +} + +impl HashReader { + /// Construct a new `HashReader` given an existing `reader` by value. + pub fn new(reader: R) -> Self { + Self::new_from_parts(D::new(), reader) + } + + /// Construct a new `HashReader` given an existing `hasher` and `reader` by value. + pub fn new_from_parts(hasher: D, reader: R) -> Self { + HashReader { reader, hasher } + } + + /// Replace the reader with another reader + pub fn replace_reader(&mut self, reader: R) { + self.reader = reader; + } + + /// Gets a reference to the underlying hasher + pub fn get_hasher(&self) -> &D { + &self.hasher + } + + /// Gets a reference to the underlying reader + pub fn get_reader(&self) -> &R { + &self.reader + } + + /// Gets a mutable reference to the underlying hasher + pub fn get_hasher_mut(&mut self) -> &mut D { + &mut self.hasher + } + + /// Gets a mutable reference to the underlying reader + /// Direct reads from the underlying reader are not hashed + pub fn get_reader_mut(&mut self) -> &mut R { + &mut self.reader + } + + /// Consume the HashReader and return its hasher + pub fn into_hasher(self) -> D { + self.hasher + } + + /// Consume the HashReader and return its internal reader + pub fn into_inner_reader(self) -> R { + self.reader + } + + /// Consume the HashReader and return its hasher and internal reader + pub fn into_parts(self) -> (D, R) { + (self.hasher, self.reader) + } + + /// Retrieve result and consume HashReader instance. + pub fn finalize(self) -> Output { + self.hasher.finalize() + } + + /// Write result into provided array and consume the HashReader instance. + pub fn finalize_into(self, out: &mut Output) { + self.hasher.finalize_into(out) + } + + /// Get output size of the hasher + pub fn output_size() -> usize { + ::output_size() + } +} + +impl Clone for HashReader { + fn clone(&self) -> HashReader { + HashReader { + reader: self.reader.clone(), + hasher: self.hasher.clone(), + } + } +} + +impl io::Read for HashReader { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + let bytes = self.reader.read(buf)?; + + if bytes > 0 { + self.hasher.update(&buf[0..bytes]); + } + + Ok(bytes) + } +} + +impl HashReader { + /// Retrieve result and reset hasher instance. + pub fn finalize_reset(&mut self) -> Output { + Digest::finalize_reset(&mut self.hasher) + } + + /// Rrite result into provided array and reset the hasher instance. + pub fn finalize_into_reset(&mut self, out: &mut Output) { + Digest::finalize_into_reset(&mut self.hasher, out) + } +} +impl Reset for HashReader { + fn reset(&mut self) { + Digest::reset(&mut self.hasher) + } +} + +impl HashReader { + /// Read and hash all bytes remaining in the reader, discarding the data + /// Based on implementation in b2sum crate, MIT License Copyright (c) 2017 John Downey + pub fn hash_to_end(&mut self) { + loop { + let count = { + let data = self.reader.fill_buf().unwrap(); + if data.is_empty() { + break; + } + + self.hasher.update(data); + data.len() + }; + + self.reader.consume(count); + } + } +} diff --git a/digest/src/hashwriter.rs b/digest/src/hashwriter.rs new file mode 100644 index 000000000..96ebe95a6 --- /dev/null +++ b/digest/src/hashwriter.rs @@ -0,0 +1,120 @@ +//! Adds hashing to any writer. Inspired by implemention in phase2 crate. +use super::{Digest, FixedOutputReset, Output, Reset}; +use std::io; + +/// Abstraction over a writer which hashes the data being written. +pub struct HashWriter { + writer: W, + hasher: D, +} + +impl HashWriter { + /// Construct a new `HashWriter` given an existing `writer` by value. + pub fn new(writer: W) -> Self { + Self::new_from_parts(D::new(), writer) + } + + /// Construct a new `HashWriter` given an existing `hasher` and `writer` by value. + pub fn new_from_parts(hasher: D, writer: W) -> Self { + HashWriter { writer, hasher } + } + + /// Replace the writer with another writer + pub fn replace_writer(&mut self, writer: W) { + self.writer = writer; + } + + /// Gets a reference to the underlying hasher + pub fn get_hasher(&self) -> &D { + &self.hasher + } + + /// Gets a reference to the underlying writer + pub fn get_writer(&self) -> &W { + &self.writer + } + + /// Gets a mutable reference to the underlying hasher + /// Updates to the digest are not written to the underlying writer + pub fn get_hasher_mut(&mut self) -> &mut D { + &mut self.hasher + } + + /// Gets a mutable reference to the underlying writer + /// Direct writes to the underlying writer are not hashed + pub fn get_writer_mut(&mut self) -> &mut W { + &mut self.writer + } + + /// Consume the HashWriter and return its hasher + pub fn into_hasher(self) -> D { + self.hasher + } + + /// Consume the HashWriter and return its internal writer + pub fn into_inner_writer(self) -> W { + self.writer + } + + /// Consume the HashWriter and return its hasher and internal writer + pub fn into_parts(self) -> (D, W) { + (self.hasher, self.writer) + } + + /// Retrieve result and consume HashWriter instance. + pub fn finalize(self) -> Output { + self.hasher.finalize() + } + + /// Write result into provided array and consume the HashWriter instance. + pub fn finalize_into(self, out: &mut Output) { + self.hasher.finalize_into(out) + } + + /// Get output size of the hasher + pub fn output_size() -> usize { + ::output_size() + } +} + +impl Clone for HashWriter { + fn clone(&self) -> HashWriter { + HashWriter { + writer: self.writer.clone(), + hasher: self.hasher.clone(), + } + } +} + +impl io::Write for HashWriter { + fn write(&mut self, buf: &[u8]) -> io::Result { + let bytes = self.writer.write(buf)?; + + if bytes > 0 { + self.hasher.update(&buf[0..bytes]); + } + + Ok(bytes) + } + + fn flush(&mut self) -> io::Result<()> { + self.writer.flush() + } +} + +impl HashWriter { + /// Retrieve result and reset hasher instance. + pub fn finalize_reset(&mut self) -> Output { + Digest::finalize_reset(&mut self.hasher) + } + + /// Write result into provided array and reset the hasher instance. + pub fn finalize_into_reset(&mut self, out: &mut Output) { + Digest::finalize_into_reset(&mut self.hasher, out) + } +} +impl Reset for HashWriter { + fn reset(&mut self) { + Digest::reset(&mut self.hasher) + } +} diff --git a/digest/src/lib.rs b/digest/src/lib.rs index b535bc8aa..a9f5b7a4a 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -299,3 +299,12 @@ impl fmt::Display for InvalidBufferSize { #[cfg(feature = "std")] impl std::error::Error for InvalidBufferSize {} + +#[cfg(feature = "std")] +mod hashwriter; +#[cfg(feature = "std")] +pub use hashwriter::HashWriter; +#[cfg(feature = "std")] +mod hashreader; +#[cfg(feature = "std")] +pub use hashreader::HashReader; From 88c23182866cf4c20275b72f5b47fa49b4134c20 Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Sun, 2 Jun 2024 19:25:45 +0000 Subject: [PATCH 1185/1461] digest: add missing `Debug` impl for `HashReader` and `HashWriter` (#1583) --- digest/src/hashreader.rs | 1 + digest/src/hashwriter.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/digest/src/hashreader.rs b/digest/src/hashreader.rs index 8c303af2a..eaca370b4 100644 --- a/digest/src/hashreader.rs +++ b/digest/src/hashreader.rs @@ -3,6 +3,7 @@ use super::{Digest, FixedOutputReset, Output, Reset}; use std::io; /// Abstraction over a reader which hashes the data being read +#[derive(Debug)] pub struct HashReader { reader: R, hasher: D, diff --git a/digest/src/hashwriter.rs b/digest/src/hashwriter.rs index 96ebe95a6..e3d01f0ff 100644 --- a/digest/src/hashwriter.rs +++ b/digest/src/hashwriter.rs @@ -3,6 +3,7 @@ use super::{Digest, FixedOutputReset, Output, Reset}; use std::io; /// Abstraction over a writer which hashes the data being written. +#[derive(Debug)] pub struct HashWriter { writer: W, hasher: D, From e5da021629c69f94886fa8dddd758ef566d38a24 Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Mon, 3 Jun 2024 17:21:52 +0000 Subject: [PATCH 1186/1461] async-signature: remove `AsyncDigestSigner` blanket implementation (#1584) This introduces a basic check to make sure our blanket implementation would not block manual implementation of the traits in this crate. Before this commit `AsyncDigestSigner` was causing a conflict: ``` --> async-signature/tests/mock_impl.rs:14:1 | 14 | / impl async_signature::AsyncDigestSigner for MockSigner 15 | | where 16 | | D: async_signature::Digest, | |_______________________________^ | = note: conflicting implementation in crate `async_signature`: - impl AsyncDigestSigner for T where D: Digest, T: DigestSigner; = note: downstream crates may implement trait `async_signature::signature::DigestSigner<_, Signature>` for type `MockSigner` ``` --- async-signature/src/lib.rs | 11 --------- async-signature/tests/mock_impl.rs | 38 ++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 11 deletions(-) create mode 100644 async-signature/tests/mock_impl.rs diff --git a/async-signature/src/lib.rs b/async-signature/src/lib.rs index cef50e8e5..20ebd06d6 100644 --- a/async-signature/src/lib.rs +++ b/async-signature/src/lib.rs @@ -58,17 +58,6 @@ where async fn sign_digest_async(&self, digest: D) -> Result; } -#[cfg(feature = "digest")] -impl AsyncDigestSigner for T -where - D: Digest, - T: signature::DigestSigner, -{ - async fn sign_digest_async(&self, digest: D) -> Result { - self.try_sign_digest(digest) - } -} - /// Sign the given message using the provided external randomness source. #[cfg(feature = "rand_core")] #[allow(async_fn_in_trait)] diff --git a/async-signature/tests/mock_impl.rs b/async-signature/tests/mock_impl.rs new file mode 100644 index 000000000..20286a22a --- /dev/null +++ b/async-signature/tests/mock_impl.rs @@ -0,0 +1,38 @@ +#![allow(dead_code)] +//! Check compilation of the various traits exposed by async_signature. +//! +//! This is intended to make sure we can implement those traits without conflict from a blanket +//! implementation. + +use async_signature::{AsyncSigner, Error}; + +struct Signature; + +struct MockSigner; + +impl AsyncSigner for MockSigner { + async fn sign_async(&self, _msg: &[u8]) -> Result { + unimplemented!("just meant to check compilation") + } +} + +#[cfg(feature = "digest")] +impl async_signature::AsyncDigestSigner for MockSigner +where + D: async_signature::Digest, +{ + async fn sign_digest_async(&self, _digest: D) -> Result { + unimplemented!("just meant to check compilation") + } +} + +#[cfg(feature = "rand_core")] +impl async_signature::AsyncRandomizedSigner for MockSigner { + async fn try_sign_with_rng_async( + &self, + _rng: &mut impl async_signature::signature::rand_core::CryptoRngCore, + _msg: &[u8], + ) -> Result { + unimplemented!("just meant to check compilation") + } +} From ab9ea2fa41d76b4a185503414f0524e2c848bf9f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 17:07:08 -0600 Subject: [PATCH 1187/1461] build(deps): bump proc-macro2 from 1.0.84 to 1.0.85 (#1585) Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.84 to 1.0.85. - [Release notes](https://github.com/dtolnay/proc-macro2/releases) - [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.84...1.0.85) --- updated-dependencies: - dependency-name: proc-macro2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c13f5dfe4..efccd76a9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1003,9 +1003,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.84" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec96c6a92621310b51366f1e28d05ef11489516e93be030060e5fc12024a49d6" +checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" dependencies = [ "unicode-ident", ] From d15d165017c3b95c3c0263e9093948196863a1a5 Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Wed, 5 Jun 2024 14:58:18 +0000 Subject: [PATCH 1188/1461] async-signature: forward `std` feature (#1582) `std` gates the From implementation from signature. This allows to enable the feature without importing signature directly. --- async-signature/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/async-signature/Cargo.toml b/async-signature/Cargo.toml index 41308f438..dfd133e63 100644 --- a/async-signature/Cargo.toml +++ b/async-signature/Cargo.toml @@ -17,6 +17,7 @@ signature = "=2.3.0-pre.3" [features] digest = ["signature/digest"] +std = ["signature/std"] rand_core = ["signature/rand_core"] [package.metadata.docs.rs] From f3301d6926ad07ec804cf1e838c3c39341bfde4a Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Thu, 6 Jun 2024 02:57:25 +0400 Subject: [PATCH 1189/1461] cipher: fix documentation for decrypt traits (#1587) --- cipher/src/block.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/cipher/src/block.rs b/cipher/src/block.rs index bc0ac183f..fd69bf570 100644 --- a/cipher/src/block.rs +++ b/cipher/src/block.rs @@ -240,7 +240,7 @@ pub trait BlockCipherDecrypt: BlockSizeUser { .map(|blocks| self.decrypt_with_backend(BlocksCtx { blocks })) } - /// Decrypt input and unpad it. Returns resulting ciphertext slice. + /// Decrypt input and unpad it. Returns resulting plaintext slice. /// /// Returns [`UnpadError`] if padding is malformed or if input length is /// not multiple of `Self::BlockSize`. @@ -258,7 +258,7 @@ pub trait BlockCipherDecrypt: BlockSizeUser { P::unpad_blocks(blocks.into_out()) } - /// Decrypt input and unpad it in-place. Returns resulting ciphertext slice. + /// Decrypt input and unpad it in-place. Returns resulting plaintext slice. /// /// Returns [`UnpadError`] if padding is malformed or if input length is /// not multiple of `Self::BlockSize`. @@ -272,7 +272,7 @@ pub trait BlockCipherDecrypt: BlockSizeUser { } /// Decrypt input and unpad it buffer-to-buffer. Returns resulting - /// ciphertext slice. + /// plaintext slice. /// /// Returns [`UnpadError`] if padding is malformed or if input length is /// not multiple of `Self::BlockSize`. @@ -293,7 +293,7 @@ pub trait BlockCipherDecrypt: BlockSizeUser { } /// Decrypt input and unpad it in a newly allocated Vec. Returns resulting - /// ciphertext Vec. + /// plaintext `Vec`. /// /// Returns [`UnpadError`] if padding is malformed or if input length is /// not multiple of `Self::BlockSize`. @@ -481,7 +481,7 @@ pub trait BlockModeDecrypt: BlockSizeUser + Sized { .map(|blocks| self.decrypt_with_backend(BlocksCtx { blocks })) } - /// Decrypt input and unpad it. Returns resulting ciphertext slice. + /// Decrypt input and unpad it. Returns resulting plaintext slice. /// /// Returns [`UnpadError`] if padding is malformed or if input length is /// not multiple of `Self::BlockSize`. @@ -499,7 +499,7 @@ pub trait BlockModeDecrypt: BlockSizeUser + Sized { P::unpad_blocks(blocks.into_out()) } - /// Decrypt input and unpad it in-place. Returns resulting ciphertext slice. + /// Decrypt input and unpad it in-place. Returns resulting plaintext slice. /// /// Returns [`UnpadError`] if padding is malformed or if input length is /// not multiple of `Self::BlockSize`. @@ -513,7 +513,7 @@ pub trait BlockModeDecrypt: BlockSizeUser + Sized { } /// Decrypt input and unpad it buffer-to-buffer. Returns resulting - /// ciphertext slice. + /// plaintext slice. /// /// Returns [`UnpadError`] if padding is malformed or if input length is /// not multiple of `Self::BlockSize`. @@ -534,7 +534,7 @@ pub trait BlockModeDecrypt: BlockSizeUser + Sized { } /// Decrypt input and unpad it in a newly allocated Vec. Returns resulting - /// ciphertext Vec. + /// plaintext `Vec`. /// /// Returns [`UnpadError`] if padding is malformed or if input length is /// not multiple of `Self::BlockSize`. From 51b19776a6da583957affa84cb9cb789a327a153 Mon Sep 17 00:00:00 2001 From: Luca Bruno Date: Mon, 10 Jun 2024 14:35:34 +0200 Subject: [PATCH 1190/1461] elliptic-curve: fix build failure on nightly (#1589) This tweaks the import of `core::mem::size_of` in order to fix a build failure due to `unused_qualifications` lint, as the function has now been moved to Rust prelude. --- .../src/hash2curve/hash2field/expand_msg/xmd.rs | 8 ++++---- .../src/hash2curve/hash2field/expand_msg/xof.rs | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs index e34133a1a..745e054da 100644 --- a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs +++ b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs @@ -151,7 +151,7 @@ where #[cfg(test)] mod test { use super::*; - use core::mem; + use core::mem::size_of; use hex_literal::hex; use hybrid_array::{ typenum::{U128, U32}, @@ -177,16 +177,16 @@ mod test { let msg_len = block + msg.len(); assert_eq!(msg, &bytes[block..msg_len]); - let l = msg_len + mem::size_of::(); + let l = msg_len + size_of::(); assert_eq!(len_in_bytes.to_be_bytes(), &bytes[msg_len..l]); - let pad = l + mem::size_of::(); + let pad = l + size_of::(); assert_eq!([0], &bytes[l..pad]); let dst = pad + usize::from(domain.len()); domain.assert(&bytes[pad..dst]); - let dst_len = dst + mem::size_of::(); + let dst_len = dst + size_of::(); assert_eq!([domain.len()], &bytes[dst..dst_len]); assert_eq!(dst_len, bytes.len()); diff --git a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs index be6cefc52..bf429071e 100644 --- a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs +++ b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs @@ -63,7 +63,7 @@ where #[cfg(test)] mod test { use super::*; - use core::mem; + use core::mem::size_of; use hex_literal::hex; use hybrid_array::{typenum::U128, Array, ArraySize}; use sha3::Shake128; @@ -72,7 +72,7 @@ mod test { let msg_len = msg.len(); assert_eq!(msg, &bytes[..msg_len]); - let len_in_bytes_len = msg_len + mem::size_of::(); + let len_in_bytes_len = msg_len + size_of::(); assert_eq!( len_in_bytes.to_be_bytes(), &bytes[msg_len..len_in_bytes_len] @@ -81,7 +81,7 @@ mod test { let dst = len_in_bytes_len + usize::from(domain.len()); domain.assert(&bytes[len_in_bytes_len..dst]); - let dst_len = dst + mem::size_of::(); + let dst_len = dst + size_of::(); assert_eq!([domain.len()], &bytes[dst..dst_len]); assert_eq!(dst_len, bytes.len()); From b1f6b1d37ac332b881b41e44f293f6662c98f25f Mon Sep 17 00:00:00 2001 From: Luca Bruno Date: Mon, 10 Jun 2024 18:28:14 +0200 Subject: [PATCH 1191/1461] cargo: point `repository` metadata to clonable URLs (#1588) This tweaks the `repository` fields in Cargo metadata in order to use the correct (i.e. git clonable) URL. The existing GitHub webUI URLs for each package have been retained and moved to `homepage` fields. --- async-signature/Cargo.toml | 3 ++- elliptic-curve/Cargo.toml | 3 ++- kem/Cargo.toml | 3 ++- password-hash/Cargo.toml | 3 ++- signature/Cargo.toml | 3 ++- signature_derive/Cargo.toml | 3 ++- 6 files changed, 12 insertions(+), 6 deletions(-) diff --git a/async-signature/Cargo.toml b/async-signature/Cargo.toml index dfd133e63..b5f5bb9d2 100644 --- a/async-signature/Cargo.toml +++ b/async-signature/Cargo.toml @@ -5,7 +5,8 @@ version = "0.6.0-pre.1" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/async-signature" -repository = "https://github.com/RustCrypto/traits/tree/master/async-signature" +homepage = "https://github.com/RustCrypto/traits/tree/master/async-signature" +repository = "https://github.com/RustCrypto/traits" readme = "README.md" keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"] categories = ["cryptography", "no-std"] diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 388c12a1a..a9258c6ad 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -8,7 +8,8 @@ and public/secret keys composed thereof. """ authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" -repository = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve" +homepage = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve" +repository = "https://github.com/RustCrypto/traits" readme = "README.md" categories = ["cryptography", "no-std"] keywords = ["crypto", "ecc", "elliptic", "weierstrass"] diff --git a/kem/Cargo.toml b/kem/Cargo.toml index 3739e8368..76a47c57b 100644 --- a/kem/Cargo.toml +++ b/kem/Cargo.toml @@ -5,7 +5,8 @@ version = "0.3.0-pre.0" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/kem" -repository = "https://github.com/RustCrypto/traits/tree/master/kem" +homepage = "https://github.com/RustCrypto/traits/tree/master/kem" +repository = "https://github.com/RustCrypto/traits" readme = "README.md" edition = "2021" keywords = ["crypto"] diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index 86b136ca7..a64ef0f2c 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -10,7 +10,8 @@ authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" documentation = "https://docs.rs/password-hash" -repository = "https://github.com/RustCrypto/traits/tree/master/password-hash" +homepage = "https://github.com/RustCrypto/traits/tree/master/password-hash" +repository = "https://github.com/RustCrypto/traits" categories = ["authentication", "cryptography", "no-std"] keywords = ["crypt", "mcf", "password", "pbkdf", "phc"] edition = "2021" diff --git a/signature/Cargo.toml b/signature/Cargo.toml index f5e9c27e0..b5eebd10a 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -5,7 +5,8 @@ version = "2.3.0-pre.3" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/signature" -repository = "https://github.com/RustCrypto/traits/tree/master/signature" +homepage = "https://github.com/RustCrypto/traits/tree/master/signature" +repository = "https://github.com/RustCrypto/traits" readme = "README.md" keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"] categories = ["cryptography", "no-std"] diff --git a/signature_derive/Cargo.toml b/signature_derive/Cargo.toml index ba1e7d53c..3d01b5d0b 100644 --- a/signature_derive/Cargo.toml +++ b/signature_derive/Cargo.toml @@ -5,7 +5,8 @@ authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" description = "Custom derive support for the 'signature' crate" documentation = "https://docs.rs/signature" -repository = "https://github.com/RustCrypto/traits/tree/master/signature_derive" +homepage = "https://github.com/RustCrypto/traits/tree/master/signature_derive" +repository = "https://github.com/RustCrypto/traits" readme = "README.md" edition = "2021" rust-version = "1.60" From 5e6ddf673d83b6e1ae7eea9e61c526f5cf41cd65 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Jun 2024 18:47:41 -0600 Subject: [PATCH 1192/1461] build(deps): bump curve25519-dalek from 4.1.2 to 4.1.3 (#1591) Bumps [curve25519-dalek](https://github.com/dalek-cryptography/curve25519-dalek) from 4.1.2 to 4.1.3. - [Release notes](https://github.com/dalek-cryptography/curve25519-dalek/releases) - [Commits](https://github.com/dalek-cryptography/curve25519-dalek/compare/curve25519-4.1.2...curve25519-4.1.3) --- updated-dependencies: - dependency-name: curve25519-dalek dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index efccd76a9..8180bd50b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -356,15 +356,14 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "4.1.2" +version = "4.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a677b8922c94e01bdbb12126b0bc852f00447528dee1782229af9c720c3f348" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" dependencies = [ "cfg-if", "cpufeatures", "curve25519-dalek-derive", "fiat-crypto", - "platforms", "rustc_version", "subtle", ] @@ -916,12 +915,6 @@ dependencies = [ "spki 0.8.0-pre.0", ] -[[package]] -name = "platforms" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db23d408679286588f4d4644f965003d056e3dd5abcaaa938116871d7ce2fee7" - [[package]] name = "poly1305" version = "0.8.0" From 3e2b5e1fa7e02209606fdf3b5fea4fe06ac1c127 Mon Sep 17 00:00:00 2001 From: Martin Geisler Date: Mon, 24 Jun 2024 17:23:46 +0200 Subject: [PATCH 1193/1461] Remove unused `hazmat` feature (#1599) Fixes #1597. --- .github/workflows/elliptic-curve.yml | 3 +-- elliptic-curve/Cargo.toml | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index 6161f6b80..6bbf9af4e 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -43,7 +43,6 @@ jobs: - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features dev - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features digest - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features ecdh - - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features hazmat - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features hash2curve - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features jwk - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features pem @@ -55,7 +54,7 @@ jobs: - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,arithmetic,pkcs8 - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,serde - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features arithmetic,serde - - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,digest,ecdh,hazmat,hash2curve,jwk,pem,pkcs8,sec1,serde,voprf + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,digest,ecdh,hash2curve,jwk,pem,pkcs8,sec1,serde,voprf minimal-versions: # Temporarily disabled until elliptic-curve 0.13.0-pre.0 is published diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index a9258c6ad..8efb97d4b 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -66,7 +66,6 @@ dev = ["arithmetic", "dep:hex-literal", "pem", "pkcs8"] hash2curve = ["arithmetic", "digest"] ecdh = ["arithmetic", "digest", "dep:hkdf"] group = ["dep:group", "ff"] -hazmat = [] jwk = ["dep:base64ct", "dep:serde_json", "alloc", "serde", "zeroize/alloc"] pkcs8 = ["dep:pkcs8", "sec1"] pem = ["dep:pem-rfc7468", "alloc", "arithmetic", "pkcs8", "sec1/pem"] From bdd58bdb1605582648e154e9be3b5384c248b66c Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Mon, 24 Jun 2024 18:37:20 +0300 Subject: [PATCH 1194/1461] Fix Clippy lints (#1598) --- .github/workflows/workspace.yml | 2 +- aead/src/stream.rs | 2 +- elliptic-curve/src/jwk.rs | 1 + elliptic-curve/src/public_key.rs | 1 + elliptic-curve/src/scalar/nonzero.rs | 6 ++++-- password-hash/src/encoding.rs | 3 +++ 6 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index 1bffd0413..d67061ca5 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -24,7 +24,7 @@ jobs: - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: - toolchain: 1.75.0 + toolchain: 1.79.0 components: clippy - run: cargo clippy --all --all-features --tests -- -D warnings diff --git a/aead/src/stream.rs b/aead/src/stream.rs index 27ff31281..7f735fb2a 100644 --- a/aead/src/stream.rs +++ b/aead/src/stream.rs @@ -399,7 +399,7 @@ where type NonceOverhead = U5; type Counter = u32; const COUNTER_INCR: u32 = 1; - const COUNTER_MAX: u32 = core::u32::MAX; + const COUNTER_MAX: u32 = u32::MAX; fn encrypt_in_place( &self, diff --git a/elliptic-curve/src/jwk.rs b/elliptic-curve/src/jwk.rs index 6e59d9fae..e37cd2769 100644 --- a/elliptic-curve/src/jwk.rs +++ b/elliptic-curve/src/jwk.rs @@ -168,6 +168,7 @@ impl FromStr for JwkEcKey { } } +#[allow(clippy::to_string_trait_impl)] impl ToString for JwkEcKey { fn to_string(&self) -> String { serde_json::to_string(self).expect("JWK encoding error") diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index 4242c8c11..ddad0aa0b 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -503,6 +503,7 @@ where } #[cfg(feature = "pem")] +#[allow(clippy::to_string_trait_impl)] impl ToString for PublicKey where C: AssociatedOid + CurveArithmetic, diff --git a/elliptic-curve/src/scalar/nonzero.rs b/elliptic-curve/src/scalar/nonzero.rs index 7b81a6053..601206ad0 100644 --- a/elliptic-curve/src/scalar/nonzero.rs +++ b/elliptic-curve/src/scalar/nonzero.rs @@ -47,6 +47,8 @@ where // While this method isn't constant-time, the attacker shouldn't learn // anything about unrelated outputs so long as `rng` is a secure `CryptoRng`. loop { + // TODO: remove after `Field::random` switches to `&mut impl RngCore` + #[allow(clippy::needless_borrows_for_generic_args)] if let Some(result) = Self::new(Field::random(&mut rng)).into() { break result; } @@ -270,11 +272,11 @@ where Scalar: Reduce + ReduceNonZero, { fn reduce_nonzero(n: I) -> Self { - Self::reduce(n) + >::reduce(n) } fn reduce_nonzero_bytes(bytes: &Self::Bytes) -> Self { - Self::reduce_bytes(bytes) + >::reduce_bytes(bytes) } } diff --git a/password-hash/src/encoding.rs b/password-hash/src/encoding.rs index 7e7938f4d..8a914cee7 100644 --- a/password-hash/src/encoding.rs +++ b/password-hash/src/encoding.rs @@ -39,8 +39,11 @@ pub enum Encoding { /// - sha256_crypt, /// - sha512_crypt, /// - md5_crypt + /// + /// ```text /// [.-9] [A-Z] [a-z] /// 0x2e-0x39, 0x41-0x5a, 0x61-0x7a + /// ``` ShaCrypt, } From 0a3687b58e59d5d2e196f59ca883a2d46eb76abb Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 24 Jun 2024 12:05:37 -0600 Subject: [PATCH 1195/1461] elliptic-curve: leverage `CtOption::into_option` (#1595) This was added in `subtle` v2.6.0. --- Cargo.lock | 4 ++-- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/error.rs | 6 ++++++ elliptic-curve/src/point/non_identity.rs | 3 ++- elliptic-curve/src/public_key.rs | 2 +- elliptic-curve/src/scalar/nonzero.rs | 14 ++++++-------- elliptic-curve/src/scalar/primitive.rs | 2 +- elliptic-curve/src/secret_key.rs | 5 +++-- 8 files changed, 22 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8180bd50b..079009e4c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1269,9 +1269,9 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "subtle" -version = "2.5.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 8efb97d4b..532dfd522 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -21,7 +21,7 @@ base16ct = "0.2" crypto-bigint = { version = "=0.6.0-pre.12", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } hybrid-array = { version = "0.2.0-rc.8", default-features = false, features = ["zeroize"] } rand_core = { version = "0.6.4", default-features = false } -subtle = { version = "2", default-features = false } +subtle = { version = "2.6", default-features = false } zeroize = { version = "1.7", default-features = false } # optional dependencies diff --git a/elliptic-curve/src/error.rs b/elliptic-curve/src/error.rs index f4463fa4d..ba2d0b368 100644 --- a/elliptic-curve/src/error.rs +++ b/elliptic-curve/src/error.rs @@ -21,6 +21,12 @@ impl From for Error { } } +impl From for Error { + fn from(_: core::array::TryFromSliceError) -> Error { + Error + } +} + #[cfg(feature = "pkcs8")] impl From for Error { fn from(_: pkcs8::Error) -> Error { diff --git a/elliptic-curve/src/point/non_identity.rs b/elliptic-curve/src/point/non_identity.rs index 81c31cd19..436410d7c 100644 --- a/elliptic-curve/src/point/non_identity.rs +++ b/elliptic-curve/src/point/non_identity.rs @@ -188,7 +188,8 @@ where where D: de::Deserializer<'de>, { - Option::from(Self::new(P::deserialize(deserializer)?)) + Self::new(P::deserialize(deserializer)?) + .into_option() .ok_or_else(|| de::Error::custom("expected non-identity point")) } } diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index ddad0aa0b..f0490671c 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -126,7 +126,7 @@ where AffinePoint: FromEncodedPoint + ToEncodedPoint, { let point = EncodedPoint::::from_bytes(bytes).map_err(|_| Error)?; - Option::from(Self::from_encoded_point(&point)).ok_or(Error) + Self::from_encoded_point(&point).into_option().ok_or(Error) } /// Convert this [`PublicKey`] into the diff --git a/elliptic-curve/src/scalar/nonzero.rs b/elliptic-curve/src/scalar/nonzero.rs index 601206ad0..dfcd2e776 100644 --- a/elliptic-curve/src/scalar/nonzero.rs +++ b/elliptic-curve/src/scalar/nonzero.rs @@ -13,7 +13,6 @@ use core::{ }; use crypto_bigint::{ArrayEncoding, Integer}; use ff::{Field, PrimeField}; -use hybrid_array::{typenum::Unsigned, Array}; use rand_core::CryptoRngCore; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; use zeroize::Zeroize; @@ -287,11 +286,9 @@ where type Error = Error; fn try_from(bytes: &[u8]) -> Result { - if bytes.len() == C::FieldBytesSize::USIZE { - Option::from(NonZeroScalar::from_repr(Array::clone_from_slice(bytes))).ok_or(Error) - } else { - Err(Error) - } + NonZeroScalar::from_repr(bytes.try_into()?) + .into_option() + .ok_or(Error) } } @@ -346,7 +343,7 @@ where let mut bytes = FieldBytes::::default(); if base16ct::mixed::decode(hex, &mut bytes)?.len() == bytes.len() { - Option::from(Self::from_repr(bytes)).ok_or(Error) + Self::from_repr(bytes).into_option().ok_or(Error) } else { Err(Error) } @@ -376,7 +373,8 @@ where D: de::Deserializer<'de>, { let scalar = ScalarPrimitive::deserialize(deserializer)?; - Option::from(Self::new(scalar.into())) + Self::new(scalar.into()) + .into_option() .ok_or_else(|| de::Error::custom("expected non-zero scalar")) } } diff --git a/elliptic-curve/src/scalar/primitive.rs b/elliptic-curve/src/scalar/primitive.rs index 877bacb61..a4d31cb3e 100644 --- a/elliptic-curve/src/scalar/primitive.rs +++ b/elliptic-curve/src/scalar/primitive.rs @@ -84,7 +84,7 @@ where /// Decode [`ScalarPrimitive`] from a big endian byte slice. pub fn from_slice(slice: &[u8]) -> Result { let bytes = Array::try_from(slice).map_err(|_| Error)?; - Option::from(Self::from_bytes(&bytes)).ok_or(Error) + Self::from_bytes(&bytes).into_option().ok_or(Error) } /// Borrow the inner `C::Uint`. diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 02ba9d092..b0a5bd458 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -142,8 +142,9 @@ where /// Deserialize secret key from an encoded secret scalar. pub fn from_bytes(bytes: &FieldBytes) -> Result { - let inner: ScalarPrimitive = - Option::from(ScalarPrimitive::from_bytes(bytes)).ok_or(Error)?; + let inner = ScalarPrimitive::::from_bytes(bytes) + .into_option() + .ok_or(Error)?; if inner.is_zero().into() { return Err(Error); From 67a2b2cc31fcb31296c3b43933aa3b963dcfd224 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Jun 2024 16:34:20 -0600 Subject: [PATCH 1196/1461] build(deps): bump crypto-bigint from 0.6.0-pre.12 to 0.6.0-rc.0 (#1602) Bumps [crypto-bigint](https://github.com/RustCrypto/crypto-bigint) from 0.6.0-pre.12 to 0.6.0-rc.0.

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=crypto-bigint&package-manager=cargo&previous-version=0.6.0-pre.12&new-version=0.6.0-rc.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 6 +++--- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 079009e4c..3a5050af2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -293,9 +293,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.6.0-pre.12" +version = "0.6.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1943d7beadd9ce2b25f3bae73b9e9336fccc1edf38bdec1ed58d3aa183989e11" +checksum = "cf4d6fbc60a5516ff886af2c5994fb2bdfa6fbe2168468100bd87e6c09caf08c" dependencies = [ "hybrid-array", "num-traits", @@ -513,7 +513,7 @@ version = "0.14.0-pre.5" dependencies = [ "base16ct", "base64ct", - "crypto-bigint 0.6.0-pre.12", + "crypto-bigint 0.6.0-rc.0", "digest 0.11.0-pre.8 (registry+https://github.com/rust-lang/crates.io-index)", "ff 0.13.0", "group 0.13.0", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 532dfd522..43479d757 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -18,7 +18,7 @@ rust-version = "1.73" [dependencies] base16ct = "0.2" -crypto-bigint = { version = "=0.6.0-pre.12", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } +crypto-bigint = { version = "=0.6.0-rc.0", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } hybrid-array = { version = "0.2.0-rc.8", default-features = false, features = ["zeroize"] } rand_core = { version = "0.6.4", default-features = false } subtle = { version = "2.6", default-features = false } From e8c4823bc8b1068bf27d57525666765fd81aa53b Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 25 Jul 2024 21:02:01 -0600 Subject: [PATCH 1197/1461] crypto-common v0.2.0-rc.0 (#1615) --- Cargo.lock | 18 +++++++++--------- crypto-common/Cargo.toml | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3a5050af2..fe71ed4c9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,7 +19,7 @@ dependencies = [ "arrayvec", "blobby", "bytes", - "crypto-common 0.2.0-pre.5 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.2.0-pre.5", "heapless", ] @@ -130,7 +130,7 @@ version = "0.11.0-pre.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ded684142010808eb980d9974ef794da2bcf97d13396143b1515e9f0fb4a10e" dependencies = [ - "crypto-common 0.2.0-pre.5 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.2.0-pre.5", "zeroize", ] @@ -221,7 +221,7 @@ name = "cipher" version = "0.5.0-pre.4" dependencies = [ "blobby", - "crypto-common 0.2.0-pre.5 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.2.0-pre.5", "inout 0.2.0-pre.4", "zeroize", ] @@ -318,6 +318,8 @@ dependencies = [ [[package]] name = "crypto-common" version = "0.2.0-pre.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7aa2ec04f5120b830272a481e8d9d8ba4dda140d2cda59b0f1110d5eb93c38e" dependencies = [ "getrandom", "hybrid-array", @@ -326,9 +328,7 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.2.0-pre.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7aa2ec04f5120b830272a481e8d9d8ba4dda140d2cda59b0f1110d5eb93c38e" +version = "0.2.0-rc.0" dependencies = [ "getrandom", "hybrid-array", @@ -436,7 +436,7 @@ dependencies = [ "blobby", "block-buffer 0.11.0-pre.5", "const-oid 0.10.0-pre.2", - "crypto-common 0.2.0-pre.5 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.2.0-pre.5", "subtle", "zeroize", ] @@ -449,7 +449,7 @@ checksum = "065d93ead7c220b85d5b4be4795d8398eac4ff68b5ee63895de0a3c1fb6edf25" dependencies = [ "block-buffer 0.11.0-pre.5", "const-oid 0.10.0-pre.2", - "crypto-common 0.2.0-pre.5 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.2.0-pre.5", "subtle", ] @@ -1316,7 +1316,7 @@ dependencies = [ name = "universal-hash" version = "0.6.0-pre.0" dependencies = [ - "crypto-common 0.2.0-pre.5 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.2.0-pre.5", "subtle", ] diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index f1ac4e986..8ccd7ea05 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crypto-common" description = "Common cryptographic traits" -version = "0.2.0-pre.5" +version = "0.2.0-rc.0" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" From 88ab664cefeb520e6f39cbd4b3bb7630f3b82858 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 26 Jul 2024 07:44:09 -0600 Subject: [PATCH 1198/1461] build(deps): bump bytes from 1.6.0 to 1.6.1 (#1612) --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fe71ed4c9..5755006f5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -160,9 +160,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.6.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" +checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952" [[package]] name = "cc" From 5621847ca7183e2f5bd8fb2e21e499e1bac71138 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 26 Jul 2024 08:24:19 -0600 Subject: [PATCH 1199/1461] Bump `hybrid-array` to v0.2.0-rc.9 (#1616) Also fixes the deprecation warnings --- Cargo.lock | 4 ++-- aead/src/lib.rs | 12 +++++++----- digest/src/core_api/ct_variable.rs | 2 +- digest/src/core_api/rt_variable.rs | 5 ++--- digest/src/core_api/wrapper.rs | 3 +-- elliptic-curve/src/public_key.rs | 6 +++++- elliptic-curve/src/secret_key.rs | 4 ++-- signature/tests/derive.rs | 5 ++++- 8 files changed, 24 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5755006f5..13860c87e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -731,9 +731,9 @@ dependencies = [ [[package]] name = "hybrid-array" -version = "0.2.0-rc.8" +version = "0.2.0-rc.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53668f5da5a41d9eaf4bf7064be46d1ebe6a4e1ceed817f387587b18f2b51047" +checksum = "4d306b679262030ad8813a82d4915fc04efff97776e4db7f8eb5137039d56400" dependencies = [ "typenum", "zeroize", diff --git a/aead/src/lib.rs b/aead/src/lib.rs index 157401f14..74ea85353 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -249,13 +249,15 @@ pub trait AeadMut: AeadCore { /// postfix authentication tag will need to define their own implementation. macro_rules! impl_decrypt_in_place { ($aead:expr, $nonce:expr, $aad:expr, $buffer:expr) => {{ - if $buffer.len() < Self::TagSize::to_usize() { - return Err(Error); - } + let tag_pos = $buffer + .len() + .checked_sub(Self::TagSize::to_usize()) + .ok_or(Error)?; - let tag_pos = $buffer.len() - Self::TagSize::to_usize(); let (msg, tag) = $buffer.as_mut().split_at_mut(tag_pos); - $aead.decrypt_in_place_detached($nonce, $aad, msg, Tag::::from_slice(tag))?; + let tag = Tag::::try_from(&*tag).expect("tag length mismatch"); + + $aead.decrypt_in_place_detached($nonce, $aad, msg, &tag)?; $buffer.truncate(tag_pos); Ok(()) }}; diff --git a/digest/src/core_api/ct_variable.rs b/digest/src/core_api/ct_variable.rs index fe917bfd8..b676a352c 100644 --- a/digest/src/core_api/ct_variable.rs +++ b/digest/src/core_api/ct_variable.rs @@ -221,7 +221,7 @@ where fn serialize(&self) -> SerializedState { let serialized_inner = self.inner.serialize(); - let serialized_outsize = Array::::clone_from_slice(&[OutSize::U8]); + let serialized_outsize = Array([OutSize::U8]); serialized_inner.concat(serialized_outsize) } diff --git a/digest/src/core_api/rt_variable.rs b/digest/src/core_api/rt_variable.rs index ccbb563aa..b1a42942f 100644 --- a/digest/src/core_api/rt_variable.rs +++ b/digest/src/core_api/rt_variable.rs @@ -157,10 +157,9 @@ where fn serialize(&self) -> SerializedState { let serialized_core = self.core.serialize(); - let serialized_pos = - Array::::clone_from_slice(&[self.buffer.get_pos().try_into().unwrap()]); + let serialized_pos = Array([self.buffer.get_pos().try_into().unwrap()]); let serialized_data = self.buffer.clone().pad_with_zeros(); - let serialized_output_size = Array::::clone_from_slice(&[self.output_size]); + let serialized_output_size = Array([self.output_size]); serialized_core .concat(serialized_pos) diff --git a/digest/src/core_api/wrapper.rs b/digest/src/core_api/wrapper.rs index d366249fe..5d8f45d4d 100644 --- a/digest/src/core_api/wrapper.rs +++ b/digest/src/core_api/wrapper.rs @@ -197,8 +197,7 @@ where fn serialize(&self) -> SerializedState { let serialized_core = self.core.serialize(); - let serialized_pos = - Array::::clone_from_slice(&[self.buffer.get_pos().try_into().unwrap()]); + let serialized_pos = Array([self.buffer.get_pos().try_into().unwrap()]); let serialized_data = self.buffer.clone().pad_with_zeros(); serialized_core diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index f0490671c..aa728d2f0 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -269,7 +269,11 @@ where FieldBytesSize: ModulusSize, { fn from(public_key: &PublicKey) -> CompressedPoint { - CompressedPoint::::clone_from_slice(public_key.to_encoded_point(true).as_bytes()) + public_key + .to_encoded_point(true) + .as_bytes() + .try_into() + .expect("wrong compressed point size") } } diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index b0a5bd458..87f4b791c 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -163,8 +163,8 @@ where /// NOTE: this function is variable-time with respect to the input length. To avoid a timing /// sidechannel, always ensure that the input has been pre-padded to `C::FieldBytesSize`. pub fn from_slice(slice: &[u8]) -> Result { - if slice.len() == C::FieldBytesSize::USIZE { - Self::from_bytes(FieldBytes::::from_slice(slice)) + if let Ok(field_bytes) = <&FieldBytes>::try_from(slice) { + Self::from_bytes(field_bytes) } else if (Self::MIN_SIZE..C::FieldBytesSize::USIZE).contains(&slice.len()) { let mut bytes = Zeroizing::new(FieldBytes::::default()); let offset = C::FieldBytesSize::USIZE.saturating_sub(slice.len()); diff --git a/signature/tests/derive.rs b/signature/tests/derive.rs index da24a21c4..a63ece5ee 100644 --- a/signature/tests/derive.rs +++ b/signature/tests/derive.rs @@ -35,7 +35,10 @@ impl TryFrom<&[u8]> for DummySignature { type Error = Error; fn try_from(bytes: &[u8]) -> Result { - Ok(DummySignature(Array::clone_from_slice(bytes))) + bytes + .try_into() + .map(DummySignature) + .map_err(|_| Error::new()) } } From 13b2c8ec946dc1daf310f38e8560569a4fec5f3c Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 26 Jul 2024 08:53:43 -0600 Subject: [PATCH 1200/1461] Cargo.lock: bump dependencies (#1617) Updates the following dependencies: $ cargo update Updating crates.io index Locking 9 packages to latest compatible versions Updating cc v1.0.98 -> v1.1.6 Updating jobserver v0.1.31 -> v0.1.32 Removing once_cell v1.19.0 Updating proc-macro2 v1.0.85 -> v1.0.86 Updating serde v1.0.203 -> v1.0.204 Updating serde_bytes v0.11.14 -> v0.11.15 Updating serde_derive v1.0.203 -> v1.0.204 Updating serde_json v1.0.117 -> v1.0.120 Updating syn v2.0.66 -> v2.0.72 Updating version_check v0.9.4 -> v0.9.5 --- Cargo.lock | 43 ++++++++++++++++++------------------------- 1 file changed, 18 insertions(+), 25 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 13860c87e..aa51ef906 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -166,13 +166,12 @@ checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952" [[package]] name = "cc" -version = "1.0.98" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f" +checksum = "2aba8f4e9906c7ce3c73463f62a7f0c65183ada1a2d47e397cc8810827f9694f" dependencies = [ "jobserver", "libc", - "once_cell", ] [[package]] @@ -767,9 +766,9 @@ checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jobserver" -version = "0.1.31" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" dependencies = [ "libc", ] @@ -812,12 +811,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "once_cell" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" - [[package]] name = "opaque-debug" version = "0.3.1" @@ -996,9 +989,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.85" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] @@ -1100,27 +1093,27 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.203" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" dependencies = [ "serde_derive", ] [[package]] name = "serde_bytes" -version = "0.11.14" +version = "0.11.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b8497c313fd43ab992087548117643f6fcd935cbf36f176ffda0aacf9591734" +checksum = "387cc504cb06bb40a96c8e04e951fe01854cf6bc921053c954e4a606d9675c6a" dependencies = [ "serde", ] [[package]] name = "serde_derive" -version = "1.0.203" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", @@ -1129,9 +1122,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.117" +version = "1.0.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" +checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" dependencies = [ "itoa", "ryu", @@ -1275,9 +1268,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.66" +version = "2.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" +checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" dependencies = [ "proc-macro2", "quote", @@ -1322,9 +1315,9 @@ dependencies = [ [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "wasi" From da4d3dcb7cd0bcc2e108785d719368c1d579e681 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 26 Jul 2024 09:53:33 -0600 Subject: [PATCH 1201/1461] build(deps): bump hpke from 0.11.0 to 0.12.0 (#1606) --- Cargo.lock | 5 ++--- kem/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aa51ef906..cffd9e22d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -708,13 +708,12 @@ dependencies = [ [[package]] name = "hpke" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e04a5933a381bb81f00b083fce6b4528e16d735dbeecbb2bdb45e0dbbf3f7e17" +checksum = "4917627a14198c3603282c5158b815ad5534795451d3c074b53cf3cee0960b11" dependencies = [ "aead 0.5.2", "aes-gcm", - "byteorder", "chacha20poly1305", "digest 0.10.7", "generic-array", diff --git a/kem/Cargo.toml b/kem/Cargo.toml index 76a47c57b..e4e1c7fb9 100644 --- a/kem/Cargo.toml +++ b/kem/Cargo.toml @@ -18,7 +18,7 @@ rand_core = "0.6" zeroize = { version = "1.7", default-features = false } [dev-dependencies] -hpke = "0.11" +hpke = "0.12" p256 = { version = "0.9", features = ["ecdsa"] } pqcrypto = { version = "0.15", default-features = false, features = [ "pqcrypto-saber", From 0cf1f5f06b2c5cebfbf15edddb314919a6e9d7d1 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 26 Jul 2024 10:17:35 -0600 Subject: [PATCH 1202/1461] Bump `crypto-common`, `block-buffer`, and `inout` (#1618) Bumps the following versions: - `block-buffer` v0.11.0-rc.0 - `crypto-common` v0.2.0-rc.0 - `inout` v0.2.0-rc.0 --- Cargo.lock | 56 +++++++++++++++------------------------ Cargo.toml | 1 + aead/Cargo.toml | 2 +- cipher/Cargo.toml | 4 +-- digest/Cargo.toml | 4 +-- universal-hash/Cargo.toml | 2 +- 6 files changed, 29 insertions(+), 40 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cffd9e22d..2f0ab5163 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,7 +19,7 @@ dependencies = [ "arrayvec", "blobby", "bytes", - "crypto-common 0.2.0-pre.5", + "crypto-common 0.2.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "heapless", ] @@ -126,11 +126,11 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.11.0-pre.5" +version = "0.11.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ded684142010808eb980d9974ef794da2bcf97d13396143b1515e9f0fb4a10e" +checksum = "17092d478f4fadfb35a7e082f62e49f0907fdf048801d9d706277e34f9df8a78" dependencies = [ - "crypto-common 0.2.0-pre.5", + "crypto-common 0.2.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "zeroize", ] @@ -145,9 +145,9 @@ dependencies = [ [[package]] name = "block-padding" -version = "0.4.0-pre.4" +version = "0.4.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8ab21a8964437caf2e83a92a1221ce65e356a2a9b8b52d58bece04005fe114e" +checksum = "0d7992d59cd95a984bde8833d4d025886eec3718777971ad15c58df0b070254a" dependencies = [ "hybrid-array", ] @@ -220,8 +220,8 @@ name = "cipher" version = "0.5.0-pre.4" dependencies = [ "blobby", - "crypto-common 0.2.0-pre.5", - "inout 0.2.0-pre.4", + "crypto-common 0.2.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "inout 0.2.0-rc.0", "zeroize", ] @@ -316,9 +316,7 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.2.0-pre.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7aa2ec04f5120b830272a481e8d9d8ba4dda140d2cda59b0f1110d5eb93c38e" +version = "0.2.0-rc.0" dependencies = [ "getrandom", "hybrid-array", @@ -328,6 +326,8 @@ dependencies = [ [[package]] name = "crypto-common" version = "0.2.0-rc.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c070b79a496dccd931229780ad5bbedd535ceff6c3565605a8e440e18e1aa2b" dependencies = [ "getrandom", "hybrid-array", @@ -433,25 +433,13 @@ name = "digest" version = "0.11.0-pre.8" dependencies = [ "blobby", - "block-buffer 0.11.0-pre.5", + "block-buffer 0.11.0-rc.0", "const-oid 0.10.0-pre.2", - "crypto-common 0.2.0-pre.5", + "crypto-common 0.2.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "subtle", "zeroize", ] -[[package]] -name = "digest" -version = "0.11.0-pre.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "065d93ead7c220b85d5b4be4795d8398eac4ff68b5ee63895de0a3c1fb6edf25" -dependencies = [ - "block-buffer 0.11.0-pre.5", - "const-oid 0.10.0-pre.2", - "crypto-common 0.2.0-pre.5", - "subtle", -] - [[package]] name = "dunce" version = "1.0.4" @@ -513,7 +501,7 @@ dependencies = [ "base16ct", "base64ct", "crypto-bigint 0.6.0-rc.0", - "digest 0.11.0-pre.8 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.11.0-pre.8", "ff 0.13.0", "group 0.13.0", "hex-literal", @@ -703,7 +691,7 @@ version = "0.13.0-pre.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffd790a0795ee332ed3e8959e5b177beb70d7112eb7d345428ec17427897d5ce" dependencies = [ - "digest 0.11.0-pre.8 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.11.0-pre.8", ] [[package]] @@ -749,11 +737,11 @@ dependencies = [ [[package]] name = "inout" -version = "0.2.0-pre.4" +version = "0.2.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a2cc35b920cc3b344af824e64e508ffc2c819fc2368ed4d253244446194d2fe" +checksum = "bbc33218cf9ce7b927426ee4ad3501bcc5d8c26bf5fb4a82849a083715aca427" dependencies = [ - "block-padding 0.4.0-pre.4", + "block-padding 0.4.0-rc.0", "hybrid-array", ] @@ -1172,7 +1160,7 @@ checksum = "8f33549bf3064b62478926aa89cbfc7c109aab66ae8f0d5d2ef839e482cc30d6" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.11.0-pre.8 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.11.0-pre.8", ] [[package]] @@ -1181,7 +1169,7 @@ version = "0.11.0-pre.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f32c02b9987a647a3d6af14c3e88df86594e4283050d9d8ee3a035df247785b9" dependencies = [ - "digest 0.11.0-pre.8 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.11.0-pre.8", "keccak", ] @@ -1208,7 +1196,7 @@ dependencies = [ name = "signature" version = "2.3.0-pre.3" dependencies = [ - "digest 0.11.0-pre.8 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.11.0-pre.8", "hex-literal", "rand_core", "sha2 0.11.0-pre.3", @@ -1308,7 +1296,7 @@ dependencies = [ name = "universal-hash" version = "0.6.0-pre.0" dependencies = [ - "crypto-common 0.2.0-pre.5", + "crypto-common 0.2.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "subtle", ] diff --git a/Cargo.toml b/Cargo.toml index e1fa03b81..2ca101fbc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,4 +16,5 @@ members = [ ] [patch.crates-io] +digest = { path = "./digest" } signature = { path = "./signature" } diff --git a/aead/Cargo.toml b/aead/Cargo.toml index 89182e148..7ce4b180e 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -16,7 +16,7 @@ categories = ["cryptography", "no-std"] rust-version = "1.65" [dependencies] -crypto-common = "=0.2.0-pre.5" +crypto-common = "0.2.0-rc.0" # optional dependencies arrayvec = { version = "0.7", optional = true, default-features = false } diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index d853d1f87..942d96092 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -13,8 +13,8 @@ keywords = ["crypto", "block-cipher", "stream-cipher", "trait"] categories = ["cryptography", "no-std"] [dependencies] -crypto-common = "=0.2.0-pre.5" -inout = "=0.2.0-pre.4" +crypto-common = "0.2.0-rc.0" +inout = "0.2.0-rc.0" # optional dependencies blobby = { version = "0.3", optional = true } diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 848216478..ef78cd909 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -13,10 +13,10 @@ keywords = ["digest", "crypto", "hash"] categories = ["cryptography", "no-std"] [dependencies] -crypto-common = "=0.2.0-pre.5" +crypto-common = "0.2.0-rc.0" # optional dependencies -block-buffer = { version = "=0.11.0-pre.5", optional = true } +block-buffer = { version = "0.11.0-rc.0", optional = true } subtle = { version = "2.4", default-features = false, optional = true } blobby = { version = "0.3", optional = true } const-oid = { version = "=0.10.0-pre.2", optional = true } diff --git a/universal-hash/Cargo.toml b/universal-hash/Cargo.toml index c0003386c..66113e13f 100644 --- a/universal-hash/Cargo.toml +++ b/universal-hash/Cargo.toml @@ -13,7 +13,7 @@ keywords = ["crypto", "mac"] categories = ["cryptography", "no-std"] [dependencies] -crypto-common = "=0.2.0-pre.5" +crypto-common = "0.2.0-rc.0" subtle = { version = "2.4", default-features = false } [features] From 626cc3fb2a85ce2b72d941ddd7d4822d87277aa4 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 26 Jul 2024 12:56:55 -0600 Subject: [PATCH 1203/1461] digest,elliptic-curve: bump format crate prereleases (#1619) Bumps the following dependencies: - `const-oid` v0.10.0-rc.0 - `der` v0.8.0-rc.0 - `pem-rfc7468` v1.0.0-rc.0 - `pkcs8` v0.11.0-rc.0 - `sec1` v0.8.0-rc.0 - `spki` v0.8.0-rc.0 This also relaxes the version requirements to remove the `=*` pinning to specific versions, now that these crates are closer to completion. --- Cargo.lock | 46 +++++++++++++++++++-------------------- digest/Cargo.toml | 2 +- elliptic-curve/Cargo.toml | 6 ++--- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2f0ab5163..487121fd0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -239,9 +239,9 @@ checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "const-oid" -version = "0.10.0-pre.2" +version = "0.10.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7e3352a27098ba6b09546e5f13b15165e6a88b5c2723afecb3ea9576b27e3ea" +checksum = "9adcf94f05e094fca3005698822ec791cb4433ced416afda1c5ca3b8dfc05a2f" [[package]] name = "cpufeatures" @@ -399,12 +399,12 @@ dependencies = [ [[package]] name = "der" -version = "0.8.0-pre.0" +version = "0.8.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b489fd2221710c1dd46637d66b984161fb66134f81437a8489800306bcc2ecea" +checksum = "05d9c07d3bd80cf0935ce478d07edf7e7a5b158446757f988f3e62082227b700" dependencies = [ - "const-oid 0.10.0-pre.2", - "pem-rfc7468 1.0.0-pre.0", + "const-oid 0.10.0-rc.0", + "pem-rfc7468 1.0.0-rc.0", "zeroize", ] @@ -434,7 +434,7 @@ version = "0.11.0-pre.8" dependencies = [ "blobby", "block-buffer 0.11.0-rc.0", - "const-oid 0.10.0-pre.2", + "const-oid 0.10.0-rc.0", "crypto-common 0.2.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "subtle", "zeroize", @@ -507,10 +507,10 @@ dependencies = [ "hex-literal", "hkdf 0.13.0-pre.3", "hybrid-array", - "pem-rfc7468 1.0.0-pre.0", - "pkcs8 0.11.0-pre.0", + "pem-rfc7468 1.0.0-rc.0", + "pkcs8 0.11.0-rc.0", "rand_core", - "sec1 0.8.0-pre.1", + "sec1 0.8.0-rc.0", "serde_json", "serdect", "sha2 0.11.0-pre.3", @@ -856,9 +856,9 @@ dependencies = [ [[package]] name = "pem-rfc7468" -version = "1.0.0-pre.0" +version = "1.0.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76a65e1c27d1680f8805b3f8c9949f08d6aa5d6cbd088c9896e64a53821dc27d" +checksum = "b2b24c1c4a3b352d47de5ec824193e68317dc0ce041f6279a4771eb550ab7f8c" dependencies = [ "base64ct", ] @@ -887,12 +887,12 @@ dependencies = [ [[package]] name = "pkcs8" -version = "0.11.0-pre.0" +version = "0.11.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "935c09e0aecb0cb8f8907b57438b19a068cb74a25189b06724f061170b2465ff" +checksum = "66180445f1dce533620a7743467ef85fe1c5e80cdaf7c7053609d7a2fbcdae20" dependencies = [ - "der 0.8.0-pre.0", - "spki 0.8.0-pre.0", + "der 0.8.0-rc.0", + "spki 0.8.0-rc.0", ] [[package]] @@ -1059,14 +1059,14 @@ dependencies = [ [[package]] name = "sec1" -version = "0.8.0-pre.1" +version = "0.8.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02dc081ed777a3bab68583b52ffb8221677b6e90d483b320963a247e2c07f328" +checksum = "32c98827dc6ed0ea1707286a3d14b4ad4e25e2643169cbf111568a46ff5b09f5" dependencies = [ "base16ct", - "der 0.8.0-pre.0", + "der 0.8.0-rc.0", "hybrid-array", - "pkcs8 0.11.0-pre.0", + "pkcs8 0.11.0-rc.0", "serdect", "subtle", "zeroize", @@ -1233,12 +1233,12 @@ dependencies = [ [[package]] name = "spki" -version = "0.8.0-pre.0" +version = "0.8.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb2b56670f5ef52934c97efad30bf42585de0c33ec3e2a886e38b80d2db67243" +checksum = "ee3fb1c675852398475928637b3ebbdd7e1d0cc24d27b3bbc81788b4eb51e310" dependencies = [ "base64ct", - "der 0.8.0-pre.0", + "der 0.8.0-rc.0", ] [[package]] diff --git a/digest/Cargo.toml b/digest/Cargo.toml index ef78cd909..10dc08477 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -19,7 +19,7 @@ crypto-common = "0.2.0-rc.0" block-buffer = { version = "0.11.0-rc.0", optional = true } subtle = { version = "2.4", default-features = false, optional = true } blobby = { version = "0.3", optional = true } -const-oid = { version = "=0.10.0-pre.2", optional = true } +const-oid = { version = "0.10.0-rc.0", optional = true } zeroize = { version = "1.7", optional = true, default-features = false } [features] diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 43479d757..7eb26379d 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -31,9 +31,9 @@ ff = { version = "0.13", optional = true, default-features = false } group = { version = "0.13", optional = true, default-features = false } hkdf = { version = "=0.13.0-pre.3", optional = true, default-features = false } hex-literal = { version = "0.4", optional = true } -pem-rfc7468 = { version = "=1.0.0-pre.0", optional = true, features = ["alloc"] } -pkcs8 = { version = "=0.11.0-pre.0", optional = true, default-features = false } -sec1 = { version = "=0.8.0-pre.1", optional = true, features = ["subtle", "zeroize"] } +pem-rfc7468 = { version = "1.0.0-rc.0", optional = true, features = ["alloc"] } +pkcs8 = { version = "0.11.0-rc.0", optional = true, default-features = false } +sec1 = { version = "0.8.0-rc.0", optional = true, features = ["subtle", "zeroize"] } serdect = { version = "=0.3.0-pre.0", optional = true, default-features = false, features = ["alloc"] } serde_json = { version = "1.0.114", optional = true, default-features = false, features = ["alloc"] } tap = { version = "1.0.1", optional = true, default-features = false } # hack for minimal-versions support for `bits` From 47e01e39a9a962b9b726fcba01aead34dbee12f0 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 26 Jul 2024 13:10:00 -0600 Subject: [PATCH 1204/1461] universal-hash v0.6.0-rc.0 (#1620) --- universal-hash/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/universal-hash/Cargo.toml b/universal-hash/Cargo.toml index 66113e13f..d98e8dd91 100644 --- a/universal-hash/Cargo.toml +++ b/universal-hash/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "universal-hash" -version = "0.6.0-pre.0" +version = "0.6.0-rc.0" description = "Traits which describe the functionality of universal hash functions (UHFs)" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" From bbf7d5ab6a722b82d142f21c0b0ef8c542d5df33 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 26 Jul 2024 13:40:20 -0600 Subject: [PATCH 1205/1461] cipher v0.5.0-pre.5 (#1621) Note: leaving this as a `.pre` instead of an `.rc` so we can experiment with newtypes first before doing an `.rc` --- Cargo.lock | 4 ++-- cipher/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 487121fd0..c6c645126 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -217,7 +217,7 @@ dependencies = [ [[package]] name = "cipher" -version = "0.5.0-pre.4" +version = "0.5.0-pre.5" dependencies = [ "blobby", "crypto-common 0.2.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1294,7 +1294,7 @@ dependencies = [ [[package]] name = "universal-hash" -version = "0.6.0-pre.0" +version = "0.6.0-rc.0" dependencies = [ "crypto-common 0.2.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "subtle", diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index 942d96092..85c7605a1 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "cipher" description = "Traits for describing block ciphers and stream ciphers" -version = "0.5.0-pre.4" +version = "0.5.0-pre.5" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" From 2783387f23821b1c33c157092330115cda6212bd Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 26 Jul 2024 13:54:14 -0600 Subject: [PATCH 1206/1461] aead v0.6.0-rc.0 (#1622) --- Cargo.lock | 2 +- aead/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c6c645126..f34deee9c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,7 +14,7 @@ dependencies = [ [[package]] name = "aead" -version = "0.6.0-pre.0" +version = "0.6.0-rc.0" dependencies = [ "arrayvec", "blobby", diff --git a/aead/Cargo.toml b/aead/Cargo.toml index 7ce4b180e..ab3b5e79d 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aead" -version = "0.6.0-pre.0" +version = "0.6.0-rc.0" description = """ Traits for Authenticated Encryption with Associated Data (AEAD) algorithms, such as AES-GCM as ChaCha20Poly1305, which provide a high-level API From 350a3b213bfd1c73f935d6f2d458c9cca8af2c00 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 26 Jul 2024 14:00:06 -0600 Subject: [PATCH 1207/1461] digest v0.11.0-pre.9 (#1623) Due to circular dependencies, it was necessary to temporarily split `elliptic-curve` out of the workspace. It also can't currently resolve a solution for `elliptic-curve`'s Cargo.lock due to `digest`. Excluding `elliptic-curve`, all of the other crates work. The main causes of this are crates like `sha2` and `sha3` which are circular `dev-dependencies` (i.e. between traits and hashes). This will temporarily break the `elliptic-curve` build until we can do new releases of `sha2` and `sha3` as well as crates like `hmac` and `hkdf`. Once these have been released, we can put everything back into a single workspace. --- Cargo.lock | 240 +------------------------------------- Cargo.toml | 3 +- digest/Cargo.toml | 2 +- signature/Cargo.toml | 28 ++--- signature/tests/derive.rs | 163 +++++++++++++------------- 5 files changed, 103 insertions(+), 333 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f34deee9c..b910d5179 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -61,12 +61,6 @@ dependencies = [ "signature 2.3.0-pre.3", ] -[[package]] -name = "autocfg" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" - [[package]] name = "base16ct" version = "0.2.0" @@ -88,18 +82,6 @@ dependencies = [ "serde", ] -[[package]] -name = "bitvec" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" -dependencies = [ - "funty", - "radium", - "tap", - "wyz", -] - [[package]] name = "blobby" version = "0.3.1" @@ -290,19 +272,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "crypto-bigint" -version = "0.6.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4d6fbc60a5516ff886af2c5994fb2bdfa6fbe2168468100bd87e6c09caf08c" -dependencies = [ - "hybrid-array", - "num-traits", - "rand_core", - "subtle", - "zeroize", -] - [[package]] name = "crypto-common" version = "0.1.6" @@ -397,17 +366,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "der" -version = "0.8.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05d9c07d3bd80cf0935ce478d07edf7e7a5b158446757f988f3e62082227b700" -dependencies = [ - "const-oid 0.10.0-rc.0", - "pem-rfc7468 1.0.0-rc.0", - "zeroize", -] - [[package]] name = "digest" version = "0.9.0" @@ -430,7 +388,7 @@ dependencies = [ [[package]] name = "digest" -version = "0.11.0-pre.8" +version = "0.11.0-pre.9" dependencies = [ "blobby", "block-buffer 0.11.0-rc.0", @@ -489,34 +447,8 @@ dependencies = [ "hkdf 0.12.4", "pkcs8 0.10.2", "rand_core", - "sec1 0.7.3", - "subtle", - "zeroize", -] - -[[package]] -name = "elliptic-curve" -version = "0.14.0-pre.5" -dependencies = [ - "base16ct", - "base64ct", - "crypto-bigint 0.6.0-rc.0", - "digest 0.11.0-pre.8", - "ff 0.13.0", - "group 0.13.0", - "hex-literal", - "hkdf 0.13.0-pre.3", - "hybrid-array", - "pem-rfc7468 1.0.0-rc.0", - "pkcs8 0.11.0-rc.0", - "rand_core", - "sec1 0.8.0-rc.0", - "serde_json", - "serdect", - "sha2 0.11.0-pre.3", - "sha3", + "sec1", "subtle", - "tap", "zeroize", ] @@ -536,7 +468,6 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ - "bitvec", "rand_core", "subtle", ] @@ -547,12 +478,6 @@ version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" -[[package]] -name = "funty" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" - [[package]] name = "generic-array" version = "0.14.7" @@ -657,15 +582,6 @@ dependencies = [ "hmac 0.12.1", ] -[[package]] -name = "hkdf" -version = "0.13.0-pre.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd5d615ab5c462f96c309b3a00b19f373025a4981312f717f9df5bbd0201530c" -dependencies = [ - "hmac 0.13.0-pre.3", -] - [[package]] name = "hmac" version = "0.11.0" @@ -685,15 +601,6 @@ dependencies = [ "digest 0.10.7", ] -[[package]] -name = "hmac" -version = "0.13.0-pre.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffd790a0795ee332ed3e8959e5b177beb70d7112eb7d345428ec17427897d5ce" -dependencies = [ - "digest 0.11.0-pre.8", -] - [[package]] name = "hpke" version = "0.12.0" @@ -722,7 +629,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d306b679262030ad8813a82d4915fc04efff97776e4db7f8eb5137039d56400" dependencies = [ "typenum", - "zeroize", ] [[package]] @@ -745,12 +651,6 @@ dependencies = [ "hybrid-array", ] -[[package]] -name = "itoa" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" - [[package]] name = "jobserver" version = "0.1.32" @@ -760,15 +660,6 @@ dependencies = [ "libc", ] -[[package]] -name = "keccak" -version = "0.2.0-pre.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7cdd4f0dc5807b9a2b25dd48a3f58e862606fe7bd47f41ecde36e97422d7e90" -dependencies = [ - "cpufeatures", -] - [[package]] name = "kem" version = "0.3.0-pre.0" @@ -789,15 +680,6 @@ version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - [[package]] name = "opaque-debug" version = "0.3.1" @@ -854,15 +736,6 @@ dependencies = [ "base64ct", ] -[[package]] -name = "pem-rfc7468" -version = "1.0.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2b24c1c4a3b352d47de5ec824193e68317dc0ce041f6279a4771eb550ab7f8c" -dependencies = [ - "base64ct", -] - [[package]] name = "pkcs8" version = "0.7.6" @@ -870,7 +743,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee3ef9b64d26bad0536099c816c6734379e45bbd5f14798def6809e5cc350447" dependencies = [ "der 0.4.5", - "pem-rfc7468 0.2.3", + "pem-rfc7468", "spki 0.4.1", "zeroize", ] @@ -885,16 +758,6 @@ dependencies = [ "spki 0.7.3", ] -[[package]] -name = "pkcs8" -version = "0.11.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66180445f1dce533620a7743467ef85fe1c5e80cdaf7c7053609d7a2fbcdae20" -dependencies = [ - "der 0.8.0-rc.0", - "spki 0.8.0-rc.0", -] - [[package]] name = "poly1305" version = "0.8.0" @@ -992,12 +855,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "radium" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" - [[package]] name = "rand" version = "0.8.5" @@ -1037,12 +894,6 @@ dependencies = [ "semver", ] -[[package]] -name = "ryu" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" - [[package]] name = "sec1" version = "0.7.3" @@ -1057,21 +908,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "sec1" -version = "0.8.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32c98827dc6ed0ea1707286a3d14b4ad4e25e2643169cbf111568a46ff5b09f5" -dependencies = [ - "base16ct", - "der 0.8.0-rc.0", - "hybrid-array", - "pkcs8 0.11.0-rc.0", - "serdect", - "subtle", - "zeroize", -] - [[package]] name = "semver" version = "1.0.23" @@ -1107,27 +943,6 @@ dependencies = [ "syn", ] -[[package]] -name = "serde_json" -version = "1.0.120" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "serdect" -version = "0.3.0-pre.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "791ef964bfaba6be28a5c3f0c56836e17cb711ac009ca1074b9c735a3ebf240a" -dependencies = [ - "base16ct", - "serde", -] - [[package]] name = "sha2" version = "0.9.9" @@ -1152,27 +967,6 @@ dependencies = [ "digest 0.10.7", ] -[[package]] -name = "sha2" -version = "0.11.0-pre.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f33549bf3064b62478926aa89cbfc7c109aab66ae8f0d5d2ef839e482cc30d6" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest 0.11.0-pre.8", -] - -[[package]] -name = "sha3" -version = "0.11.0-pre.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f32c02b9987a647a3d6af14c3e88df86594e4283050d9d8ee3a035df247785b9" -dependencies = [ - "digest 0.11.0-pre.8", - "keccak", -] - [[package]] name = "signature" version = "1.3.2" @@ -1196,10 +990,9 @@ dependencies = [ name = "signature" version = "2.3.0-pre.3" dependencies = [ - "digest 0.11.0-pre.8", + "digest 0.11.0-pre.9", "hex-literal", "rand_core", - "sha2 0.11.0-pre.3", "signature_derive", ] @@ -1231,16 +1024,6 @@ dependencies = [ "der 0.7.9", ] -[[package]] -name = "spki" -version = "0.8.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee3fb1c675852398475928637b3ebbdd7e1d0cc24d27b3bbc81788b4eb51e310" -dependencies = [ - "base64ct", - "der 0.8.0-rc.0", -] - [[package]] name = "stable_deref_trait" version = "1.2.0" @@ -1264,12 +1047,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "tap" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" - [[package]] name = "typenum" version = "1.17.0" @@ -1312,15 +1089,6 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" -[[package]] -name = "wyz" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" -dependencies = [ - "tap", -] - [[package]] name = "x25519-dalek" version = "2.0.1" diff --git a/Cargo.toml b/Cargo.toml index 2ca101fbc..e4169fe5f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,13 +7,14 @@ members = [ "crypto", "crypto-common", "digest", - "elliptic-curve", + #"elliptic-curve", "kem", "password-hash", "signature", "signature_derive", "universal-hash", ] +exclude = ["elliptic-curve"] [patch.crates-io] digest = { path = "./digest" } diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 10dc08477..8f44c7d0a 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "digest" description = "Traits for cryptographic hash functions and message authentication codes" -version = "0.11.0-pre.8" +version = "0.11.0-pre.9" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/signature/Cargo.toml b/signature/Cargo.toml index b5eebd10a..9bb5f8894 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,26 +1,26 @@ [package] -name = "signature" -description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "2.3.0-pre.3" -authors = ["RustCrypto Developers"] -license = "Apache-2.0 OR MIT" +name = "signature" +description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" +version = "2.3.0-pre.3" +authors = ["RustCrypto Developers"] +license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/signature" -homepage = "https://github.com/RustCrypto/traits/tree/master/signature" -repository = "https://github.com/RustCrypto/traits" -readme = "README.md" -keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"] -categories = ["cryptography", "no-std"] -edition = "2021" -rust-version = "1.72" +homepage = "https://github.com/RustCrypto/traits/tree/master/signature" +repository = "https://github.com/RustCrypto/traits" +readme = "README.md" +keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"] +categories = ["cryptography", "no-std"] +edition = "2021" +rust-version = "1.72" [dependencies] derive = { package = "signature_derive", version = "2", optional = true, path = "../signature_derive" } -digest = { version = "=0.11.0-pre.8", optional = true, default-features = false } +digest = { version = "=0.11.0-pre.9", optional = true, default-features = false } rand_core = { version = "0.6.4", optional = true, default-features = false } [dev-dependencies] hex-literal = "0.4" -sha2 = { version = "=0.11.0-pre.3", default-features = false } +#sha2 = { version = "=0.11.0-pre.3", default-features = false } [features] alloc = [] diff --git a/signature/tests/derive.rs b/signature/tests/derive.rs index a63ece5ee..cd1df08cb 100644 --- a/signature/tests/derive.rs +++ b/signature/tests/derive.rs @@ -2,84 +2,85 @@ #![cfg(all(feature = "derive", feature = "digest"))] -use digest::{array::Array, Digest, OutputSizeUser}; -use hex_literal::hex; -use sha2::Sha256; -use signature::{ - hazmat::{PrehashSigner, PrehashVerifier}, - DigestSigner, DigestVerifier, Error, PrehashSignature, SignatureEncoding, Signer, Verifier, -}; - -/// Test vector to compute SHA-256 digest of -const INPUT_STRING: &[u8] = b"abc"; - -/// Expected SHA-256 digest for the input string -const INPUT_STRING_DIGEST: [u8; 32] = - hex!("ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad"); - -type Repr = Array::OutputSize>; - -/// Dummy signature which just contains a digest output -#[derive(Clone, Debug)] -struct DummySignature(Repr); - -impl PrehashSignature for DummySignature { - type Digest = Sha256; -} - -impl SignatureEncoding for DummySignature { - type Repr = Repr; -} - -impl TryFrom<&[u8]> for DummySignature { - type Error = Error; - - fn try_from(bytes: &[u8]) -> Result { - bytes - .try_into() - .map(DummySignature) - .map_err(|_| Error::new()) - } -} - -impl From for Repr { - fn from(sig: DummySignature) -> Repr { - sig.0 - } -} - -/// Dummy signer which just returns the message digest as a `DummySignature` -#[derive(Signer, DigestSigner, Default)] -struct DummySigner {} - -impl PrehashSigner for DummySigner { - fn sign_prehash(&self, prehash: &[u8]) -> signature::Result { - DummySignature::try_from(prehash) - } -} - -/// Dummy verifier which ensures the `DummySignature` digest matches the -/// expected value. -/// -/// Panics (via `assert_eq!`) if the value is not what is expected. -#[derive(Verifier, DigestVerifier, Default)] -struct DummyVerifier {} - -impl PrehashVerifier for DummyVerifier { - fn verify_prehash(&self, prehash: &[u8], signature: &DummySignature) -> signature::Result<()> { - assert_eq!(signature.to_bytes().as_slice(), prehash); - Ok(()) - } -} - -#[test] -fn derived_signer_impl() { - let sig: DummySignature = DummySigner::default().sign(INPUT_STRING); - assert_eq!(sig.to_bytes().as_slice(), INPUT_STRING_DIGEST) -} - -#[test] -fn derived_verifier_impl() { - let sig: DummySignature = DummySigner::default().sign(INPUT_STRING); - assert!(DummyVerifier::default().verify(INPUT_STRING, &sig).is_ok()); -} +// TODO(tarcieri): re-enable when `sha2` has been updated +// use digest::{array::Array, Digest, OutputSizeUser}; +// use hex_literal::hex; +// use sha2::Sha256; +// use signature::{ +// hazmat::{PrehashSigner, PrehashVerifier}, +// DigestSigner, DigestVerifier, Error, PrehashSignature, SignatureEncoding, Signer, Verifier, +// }; +// +// /// Test vector to compute SHA-256 digest of +// const INPUT_STRING: &[u8] = b"abc"; +// +// /// Expected SHA-256 digest for the input string +// const INPUT_STRING_DIGEST: [u8; 32] = +// hex!("ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad"); +// +// type Repr = Array::OutputSize>; +// +// /// Dummy signature which just contains a digest output +// #[derive(Clone, Debug)] +// struct DummySignature(Repr); +// +// impl PrehashSignature for DummySignature { +// type Digest = Sha256; +// } +// +// impl SignatureEncoding for DummySignature { +// type Repr = Repr; +// } +// +// impl TryFrom<&[u8]> for DummySignature { +// type Error = Error; +// +// fn try_from(bytes: &[u8]) -> Result { +// bytes +// .try_into() +// .map(DummySignature) +// .map_err(|_| Error::new()) +// } +// } +// +// impl From for Repr { +// fn from(sig: DummySignature) -> Repr { +// sig.0 +// } +// } +// +// /// Dummy signer which just returns the message digest as a `DummySignature` +// #[derive(Signer, DigestSigner, Default)] +// struct DummySigner {} +// +// impl PrehashSigner for DummySigner { +// fn sign_prehash(&self, prehash: &[u8]) -> signature::Result { +// DummySignature::try_from(prehash) +// } +// } +// +// /// Dummy verifier which ensures the `DummySignature` digest matches the +// /// expected value. +// /// +// /// Panics (via `assert_eq!`) if the value is not what is expected. +// #[derive(Verifier, DigestVerifier, Default)] +// struct DummyVerifier {} +// +// impl PrehashVerifier for DummyVerifier { +// fn verify_prehash(&self, prehash: &[u8], signature: &DummySignature) -> signature::Result<()> { +// assert_eq!(signature.to_bytes().as_slice(), prehash); +// Ok(()) +// } +// } +// +// #[test] +// fn derived_signer_impl() { +// let sig: DummySignature = DummySigner::default().sign(INPUT_STRING); +// assert_eq!(sig.to_bytes().as_slice(), INPUT_STRING_DIGEST) +// } +// +// #[test] +// fn derived_verifier_impl() { +// let sig: DummySignature = DummySigner::default().sign(INPUT_STRING); +// assert!(DummyVerifier::default().verify(INPUT_STRING, &sig).is_ok()); +// } From f1005a309e3c8ecc7900cb202edd89f0bd6fba69 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 26 Jul 2024 15:37:36 -0600 Subject: [PATCH 1208/1461] cipher: fix `hybrid-array` deprecations in macros (#1624) The `block_cipher_test!` macro was using deprecated APIs in `hybrid-array` (i.e. `clone_from_slice`) --- cipher/src/dev/block.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cipher/src/dev/block.rs b/cipher/src/dev/block.rs index 81b111808..80ea55273 100644 --- a/cipher/src/dev/block.rs +++ b/cipher/src/dev/block.rs @@ -14,7 +14,7 @@ macro_rules! block_cipher_test { fn run_test(key: &[u8], pt: &[u8], ct: &[u8]) -> bool { let mut state = <$cipher as KeyInit>::new_from_slice(key).unwrap(); - let mut block = Array::clone_from_slice(pt); + let mut block = Array::try_from(pt).unwrap(); state.encrypt_block(&mut block); if ct != block.as_slice() { return false; @@ -33,7 +33,7 @@ macro_rules! block_cipher_test { let mut state = <$cipher as KeyInit>::new_from_slice(key).unwrap(); - let block = Block::clone_from_slice(pt); + let block = Block::try_from(pt).unwrap(); let mut blocks1 = vec![block; 101]; for (i, b) in blocks1.iter_mut().enumerate() { *b = block; From 77e2ea109f23096c30d90e394ef074783b133933 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 26 Jul 2024 15:53:33 -0600 Subject: [PATCH 1209/1461] cipher v0.5.0-pre.6 (#1625) --- Cargo.lock | 2 +- cipher/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b910d5179..be9550438 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -199,7 +199,7 @@ dependencies = [ [[package]] name = "cipher" -version = "0.5.0-pre.5" +version = "0.5.0-pre.6" dependencies = [ "blobby", "crypto-common 0.2.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index 85c7605a1..044e84b4c 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "cipher" description = "Traits for describing block ciphers and stream ciphers" -version = "0.5.0-pre.5" +version = "0.5.0-pre.6" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" From 12d384f14a1d07f0847129f659963d5e00381422 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 26 Jul 2024 17:21:41 -0600 Subject: [PATCH 1210/1461] Use `digest` v0.11.0-pre.9 crate releases (#1626) Re-unifies the workspace now that the circular dev-dependencies have been updated --- Cargo.lock | 236 +++++++++++++++++++++++++++++++++++++- Cargo.toml | 3 +- elliptic-curve/Cargo.toml | 8 +- signature/Cargo.toml | 2 +- signature/tests/derive.rs | 163 +++++++++++++------------- 5 files changed, 321 insertions(+), 91 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index be9550438..d1bafad48 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -61,6 +61,12 @@ dependencies = [ "signature 2.3.0-pre.3", ] +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + [[package]] name = "base16ct" version = "0.2.0" @@ -82,6 +88,18 @@ dependencies = [ "serde", ] +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + [[package]] name = "blobby" version = "0.3.1" @@ -272,6 +290,19 @@ dependencies = [ "zeroize", ] +[[package]] +name = "crypto-bigint" +version = "0.6.0-rc.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4d6fbc60a5516ff886af2c5994fb2bdfa6fbe2168468100bd87e6c09caf08c" +dependencies = [ + "hybrid-array", + "num-traits", + "rand_core", + "subtle", + "zeroize", +] + [[package]] name = "crypto-common" version = "0.1.6" @@ -366,6 +397,17 @@ dependencies = [ "zeroize", ] +[[package]] +name = "der" +version = "0.8.0-rc.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05d9c07d3bd80cf0935ce478d07edf7e7a5b158446757f988f3e62082227b700" +dependencies = [ + "const-oid 0.10.0-rc.0", + "pem-rfc7468 1.0.0-rc.0", + "zeroize", +] + [[package]] name = "digest" version = "0.9.0" @@ -447,8 +489,34 @@ dependencies = [ "hkdf 0.12.4", "pkcs8 0.10.2", "rand_core", - "sec1", + "sec1 0.7.3", + "subtle", + "zeroize", +] + +[[package]] +name = "elliptic-curve" +version = "0.14.0-pre.5" +dependencies = [ + "base16ct", + "base64ct", + "crypto-bigint 0.6.0-rc.0", + "digest 0.11.0-pre.9", + "ff 0.13.0", + "group 0.13.0", + "hex-literal", + "hkdf 0.13.0-pre.4", + "hybrid-array", + "pem-rfc7468 1.0.0-rc.0", + "pkcs8 0.11.0-rc.0", + "rand_core", + "sec1 0.8.0-rc.0", + "serde_json", + "serdect", + "sha2 0.11.0-pre.4", + "sha3", "subtle", + "tap", "zeroize", ] @@ -468,6 +536,7 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ + "bitvec", "rand_core", "subtle", ] @@ -478,6 +547,12 @@ version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + [[package]] name = "generic-array" version = "0.14.7" @@ -582,6 +657,15 @@ dependencies = [ "hmac 0.12.1", ] +[[package]] +name = "hkdf" +version = "0.13.0-pre.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00176ff81091018d42ff82e8324f8e5adb0b7e0468d1358f653972562dbff031" +dependencies = [ + "hmac 0.13.0-pre.4", +] + [[package]] name = "hmac" version = "0.11.0" @@ -601,6 +685,15 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "hmac" +version = "0.13.0-pre.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4b1fb14e4df79f9406b434b60acef9f45c26c50062cccf1346c6103b8c47d58" +dependencies = [ + "digest 0.11.0-pre.9", +] + [[package]] name = "hpke" version = "0.12.0" @@ -629,6 +722,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d306b679262030ad8813a82d4915fc04efff97776e4db7f8eb5137039d56400" dependencies = [ "typenum", + "zeroize", ] [[package]] @@ -651,6 +745,12 @@ dependencies = [ "hybrid-array", ] +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + [[package]] name = "jobserver" version = "0.1.32" @@ -660,6 +760,15 @@ dependencies = [ "libc", ] +[[package]] +name = "keccak" +version = "0.2.0-pre.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7cdd4f0dc5807b9a2b25dd48a3f58e862606fe7bd47f41ecde36e97422d7e90" +dependencies = [ + "cpufeatures", +] + [[package]] name = "kem" version = "0.3.0-pre.0" @@ -680,6 +789,15 @@ version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + [[package]] name = "opaque-debug" version = "0.3.1" @@ -736,6 +854,15 @@ dependencies = [ "base64ct", ] +[[package]] +name = "pem-rfc7468" +version = "1.0.0-rc.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2b24c1c4a3b352d47de5ec824193e68317dc0ce041f6279a4771eb550ab7f8c" +dependencies = [ + "base64ct", +] + [[package]] name = "pkcs8" version = "0.7.6" @@ -743,7 +870,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee3ef9b64d26bad0536099c816c6734379e45bbd5f14798def6809e5cc350447" dependencies = [ "der 0.4.5", - "pem-rfc7468", + "pem-rfc7468 0.2.3", "spki 0.4.1", "zeroize", ] @@ -758,6 +885,16 @@ dependencies = [ "spki 0.7.3", ] +[[package]] +name = "pkcs8" +version = "0.11.0-rc.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66180445f1dce533620a7743467ef85fe1c5e80cdaf7c7053609d7a2fbcdae20" +dependencies = [ + "der 0.8.0-rc.0", + "spki 0.8.0-rc.0", +] + [[package]] name = "poly1305" version = "0.8.0" @@ -855,6 +992,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + [[package]] name = "rand" version = "0.8.5" @@ -894,6 +1037,12 @@ dependencies = [ "semver", ] +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + [[package]] name = "sec1" version = "0.7.3" @@ -908,6 +1057,21 @@ dependencies = [ "zeroize", ] +[[package]] +name = "sec1" +version = "0.8.0-rc.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32c98827dc6ed0ea1707286a3d14b4ad4e25e2643169cbf111568a46ff5b09f5" +dependencies = [ + "base16ct", + "der 0.8.0-rc.0", + "hybrid-array", + "pkcs8 0.11.0-rc.0", + "serdect", + "subtle", + "zeroize", +] + [[package]] name = "semver" version = "1.0.23" @@ -943,6 +1107,27 @@ dependencies = [ "syn", ] +[[package]] +name = "serde_json" +version = "1.0.120" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serdect" +version = "0.3.0-pre.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791ef964bfaba6be28a5c3f0c56836e17cb711ac009ca1074b9c735a3ebf240a" +dependencies = [ + "base16ct", + "serde", +] + [[package]] name = "sha2" version = "0.9.9" @@ -967,6 +1152,27 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "sha2" +version = "0.11.0-pre.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "540c0893cce56cdbcfebcec191ec8e0f470dd1889b6e7a0b503e310a94a168f5" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.11.0-pre.9", +] + +[[package]] +name = "sha3" +version = "0.11.0-pre.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e485881f388c2818d709796dc883c1ffcadde9d1f0e054f3a5c14974185261a6" +dependencies = [ + "digest 0.11.0-pre.9", + "keccak", +] + [[package]] name = "signature" version = "1.3.2" @@ -993,6 +1199,7 @@ dependencies = [ "digest 0.11.0-pre.9", "hex-literal", "rand_core", + "sha2 0.11.0-pre.4", "signature_derive", ] @@ -1024,6 +1231,16 @@ dependencies = [ "der 0.7.9", ] +[[package]] +name = "spki" +version = "0.8.0-rc.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee3fb1c675852398475928637b3ebbdd7e1d0cc24d27b3bbc81788b4eb51e310" +dependencies = [ + "base64ct", + "der 0.8.0-rc.0", +] + [[package]] name = "stable_deref_trait" version = "1.2.0" @@ -1047,6 +1264,12 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + [[package]] name = "typenum" version = "1.17.0" @@ -1089,6 +1312,15 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + [[package]] name = "x25519-dalek" version = "2.0.1" diff --git a/Cargo.toml b/Cargo.toml index e4169fe5f..2ca101fbc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,14 +7,13 @@ members = [ "crypto", "crypto-common", "digest", - #"elliptic-curve", + "elliptic-curve", "kem", "password-hash", "signature", "signature_derive", "universal-hash", ] -exclude = ["elliptic-curve"] [patch.crates-io] digest = { path = "./digest" } diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 7eb26379d..d2b07303b 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -26,10 +26,10 @@ zeroize = { version = "1.7", default-features = false } # optional dependencies base64ct = { version = "1", optional = true, default-features = false, features = ["alloc"] } -digest = { version = "=0.11.0-pre.8", optional = true } +digest = { version = "=0.11.0-pre.9", optional = true } ff = { version = "0.13", optional = true, default-features = false } group = { version = "0.13", optional = true, default-features = false } -hkdf = { version = "=0.13.0-pre.3", optional = true, default-features = false } +hkdf = { version = "=0.13.0-pre.4", optional = true, default-features = false } hex-literal = { version = "0.4", optional = true } pem-rfc7468 = { version = "1.0.0-rc.0", optional = true, features = ["alloc"] } pkcs8 = { version = "0.11.0-rc.0", optional = true, default-features = false } @@ -40,8 +40,8 @@ tap = { version = "1.0.1", optional = true, default-features = false } # hack fo [dev-dependencies] hex-literal = "0.4" -sha2 = "=0.11.0-pre.3" -sha3 = "=0.11.0-pre.3" +sha2 = "=0.11.0-pre.4" +sha3 = "=0.11.0-pre.4" [features] default = ["arithmetic"] diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 9bb5f8894..77f4884ad 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -20,7 +20,7 @@ rand_core = { version = "0.6.4", optional = true, default-features = false } [dev-dependencies] hex-literal = "0.4" -#sha2 = { version = "=0.11.0-pre.3", default-features = false } +sha2 = { version = "=0.11.0-pre.4", default-features = false } [features] alloc = [] diff --git a/signature/tests/derive.rs b/signature/tests/derive.rs index cd1df08cb..a63ece5ee 100644 --- a/signature/tests/derive.rs +++ b/signature/tests/derive.rs @@ -2,85 +2,84 @@ #![cfg(all(feature = "derive", feature = "digest"))] -// TODO(tarcieri): re-enable when `sha2` has been updated -// use digest::{array::Array, Digest, OutputSizeUser}; -// use hex_literal::hex; -// use sha2::Sha256; -// use signature::{ -// hazmat::{PrehashSigner, PrehashVerifier}, -// DigestSigner, DigestVerifier, Error, PrehashSignature, SignatureEncoding, Signer, Verifier, -// }; -// -// /// Test vector to compute SHA-256 digest of -// const INPUT_STRING: &[u8] = b"abc"; -// -// /// Expected SHA-256 digest for the input string -// const INPUT_STRING_DIGEST: [u8; 32] = -// hex!("ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad"); -// -// type Repr = Array::OutputSize>; -// -// /// Dummy signature which just contains a digest output -// #[derive(Clone, Debug)] -// struct DummySignature(Repr); -// -// impl PrehashSignature for DummySignature { -// type Digest = Sha256; -// } -// -// impl SignatureEncoding for DummySignature { -// type Repr = Repr; -// } -// -// impl TryFrom<&[u8]> for DummySignature { -// type Error = Error; -// -// fn try_from(bytes: &[u8]) -> Result { -// bytes -// .try_into() -// .map(DummySignature) -// .map_err(|_| Error::new()) -// } -// } -// -// impl From for Repr { -// fn from(sig: DummySignature) -> Repr { -// sig.0 -// } -// } -// -// /// Dummy signer which just returns the message digest as a `DummySignature` -// #[derive(Signer, DigestSigner, Default)] -// struct DummySigner {} -// -// impl PrehashSigner for DummySigner { -// fn sign_prehash(&self, prehash: &[u8]) -> signature::Result { -// DummySignature::try_from(prehash) -// } -// } -// -// /// Dummy verifier which ensures the `DummySignature` digest matches the -// /// expected value. -// /// -// /// Panics (via `assert_eq!`) if the value is not what is expected. -// #[derive(Verifier, DigestVerifier, Default)] -// struct DummyVerifier {} -// -// impl PrehashVerifier for DummyVerifier { -// fn verify_prehash(&self, prehash: &[u8], signature: &DummySignature) -> signature::Result<()> { -// assert_eq!(signature.to_bytes().as_slice(), prehash); -// Ok(()) -// } -// } -// -// #[test] -// fn derived_signer_impl() { -// let sig: DummySignature = DummySigner::default().sign(INPUT_STRING); -// assert_eq!(sig.to_bytes().as_slice(), INPUT_STRING_DIGEST) -// } -// -// #[test] -// fn derived_verifier_impl() { -// let sig: DummySignature = DummySigner::default().sign(INPUT_STRING); -// assert!(DummyVerifier::default().verify(INPUT_STRING, &sig).is_ok()); -// } +use digest::{array::Array, Digest, OutputSizeUser}; +use hex_literal::hex; +use sha2::Sha256; +use signature::{ + hazmat::{PrehashSigner, PrehashVerifier}, + DigestSigner, DigestVerifier, Error, PrehashSignature, SignatureEncoding, Signer, Verifier, +}; + +/// Test vector to compute SHA-256 digest of +const INPUT_STRING: &[u8] = b"abc"; + +/// Expected SHA-256 digest for the input string +const INPUT_STRING_DIGEST: [u8; 32] = + hex!("ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad"); + +type Repr = Array::OutputSize>; + +/// Dummy signature which just contains a digest output +#[derive(Clone, Debug)] +struct DummySignature(Repr); + +impl PrehashSignature for DummySignature { + type Digest = Sha256; +} + +impl SignatureEncoding for DummySignature { + type Repr = Repr; +} + +impl TryFrom<&[u8]> for DummySignature { + type Error = Error; + + fn try_from(bytes: &[u8]) -> Result { + bytes + .try_into() + .map(DummySignature) + .map_err(|_| Error::new()) + } +} + +impl From for Repr { + fn from(sig: DummySignature) -> Repr { + sig.0 + } +} + +/// Dummy signer which just returns the message digest as a `DummySignature` +#[derive(Signer, DigestSigner, Default)] +struct DummySigner {} + +impl PrehashSigner for DummySigner { + fn sign_prehash(&self, prehash: &[u8]) -> signature::Result { + DummySignature::try_from(prehash) + } +} + +/// Dummy verifier which ensures the `DummySignature` digest matches the +/// expected value. +/// +/// Panics (via `assert_eq!`) if the value is not what is expected. +#[derive(Verifier, DigestVerifier, Default)] +struct DummyVerifier {} + +impl PrehashVerifier for DummyVerifier { + fn verify_prehash(&self, prehash: &[u8], signature: &DummySignature) -> signature::Result<()> { + assert_eq!(signature.to_bytes().as_slice(), prehash); + Ok(()) + } +} + +#[test] +fn derived_signer_impl() { + let sig: DummySignature = DummySigner::default().sign(INPUT_STRING); + assert_eq!(sig.to_bytes().as_slice(), INPUT_STRING_DIGEST) +} + +#[test] +fn derived_verifier_impl() { + let sig: DummySignature = DummySigner::default().sign(INPUT_STRING); + assert!(DummyVerifier::default().verify(INPUT_STRING, &sig).is_ok()); +} From 0e2b463230762311dbf8d4dfc9383f3c5081bd6b Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 26 Jul 2024 17:44:09 -0600 Subject: [PATCH 1211/1461] elliptic-curve: bump `crypto-bigint` to v0.6.0-rc.2 (#1627) --- Cargo.lock | 6 +++--- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d1bafad48..bf1b5fe99 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -292,9 +292,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.6.0-rc.0" +version = "0.6.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4d6fbc60a5516ff886af2c5994fb2bdfa6fbe2168468100bd87e6c09caf08c" +checksum = "e43027691f1c055da3da4f7d96af09fcec420d435d5616e51f29afd0811c56a7" dependencies = [ "hybrid-array", "num-traits", @@ -500,7 +500,7 @@ version = "0.14.0-pre.5" dependencies = [ "base16ct", "base64ct", - "crypto-bigint 0.6.0-rc.0", + "crypto-bigint 0.6.0-rc.2", "digest 0.11.0-pre.9", "ff 0.13.0", "group 0.13.0", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index d2b07303b..95dd1d0c2 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -18,7 +18,7 @@ rust-version = "1.73" [dependencies] base16ct = "0.2" -crypto-bigint = { version = "=0.6.0-rc.0", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } +crypto-bigint = { version = "0.6.0-rc.2", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } hybrid-array = { version = "0.2.0-rc.8", default-features = false, features = ["zeroize"] } rand_core = { version = "0.6.4", default-features = false } subtle = { version = "2.6", default-features = false } From 532c57167e6a46c2a47927f77e1f81ace113f093 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 26 Jul 2024 17:59:26 -0600 Subject: [PATCH 1212/1461] elliptic-curve v0.14.0-pre.6 (#1628) --- Cargo.lock | 2 +- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bf1b5fe99..c2b9e70fd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -496,7 +496,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.14.0-pre.5" +version = "0.14.0-pre.6" dependencies = [ "base16ct", "base64ct", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 95dd1d0c2..c64574e78 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.14.0-pre.5" +version = "0.14.0-pre.6" description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, From 666d443a3beac63b1168336cae6a638468852466 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 26 Jul 2024 18:15:21 -0600 Subject: [PATCH 1213/1461] signature v2.3.0-pre.4 (#1629) --- Cargo.lock | 4 ++-- async-signature/Cargo.toml | 26 +++++++++++++------------- signature/Cargo.toml | 2 +- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c2b9e70fd..64de1611b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -58,7 +58,7 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" name = "async-signature" version = "0.6.0-pre.1" dependencies = [ - "signature 2.3.0-pre.3", + "signature 2.3.0-pre.4", ] [[package]] @@ -1194,7 +1194,7 @@ dependencies = [ [[package]] name = "signature" -version = "2.3.0-pre.3" +version = "2.3.0-pre.4" dependencies = [ "digest 0.11.0-pre.9", "hex-literal", diff --git a/async-signature/Cargo.toml b/async-signature/Cargo.toml index b5f5bb9d2..d89f8d893 100644 --- a/async-signature/Cargo.toml +++ b/async-signature/Cargo.toml @@ -1,20 +1,20 @@ [package] -name = "async-signature" -description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "0.6.0-pre.1" -authors = ["RustCrypto Developers"] -license = "Apache-2.0 OR MIT" +name = "async-signature" +description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" +version = "0.6.0-pre.1" +authors = ["RustCrypto Developers"] +license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/async-signature" -homepage = "https://github.com/RustCrypto/traits/tree/master/async-signature" -repository = "https://github.com/RustCrypto/traits" -readme = "README.md" -keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"] -categories = ["cryptography", "no-std"] -edition = "2021" -rust-version = "1.75" +homepage = "https://github.com/RustCrypto/traits/tree/master/async-signature" +repository = "https://github.com/RustCrypto/traits" +readme = "README.md" +keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"] +categories = ["cryptography", "no-std"] +edition = "2021" +rust-version = "1.75" [dependencies] -signature = "=2.3.0-pre.3" +signature = "=2.3.0-pre.4" [features] digest = ["signature/digest"] diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 77f4884ad..9b2540b56 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "2.3.0-pre.3" +version = "2.3.0-pre.4" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/signature" From 00945f0633c1ac48980a28a2aa92e639c8e0a523 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 27 Jul 2024 13:59:28 -0600 Subject: [PATCH 1214/1461] password-hash v0.6.0-rc.0 (#1631) --- Cargo.lock | 2 +- password-hash/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 64de1611b..960c1d94e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -838,7 +838,7 @@ dependencies = [ [[package]] name = "password-hash" -version = "0.6.0-pre.0" +version = "0.6.0-rc.0" dependencies = [ "base64ct", "rand_core", diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index a64ef0f2c..543a789fd 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -5,7 +5,7 @@ Traits which describe the functionality of password hashing algorithms, as well as a `no_std`-friendly implementation of the PHC string format (a well-defined subset of the Modular Crypt Format a.k.a. MCF) """ -version = "0.6.0-pre.0" +version = "0.6.0-rc.0" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" From 332267526d98eb107ece2ab79ca8ee480ec1d189 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 27 Jul 2024 15:09:11 -0600 Subject: [PATCH 1215/1461] async-signature v0.6.0-pre.4 (#1632) --- async-signature/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/async-signature/Cargo.toml b/async-signature/Cargo.toml index d89f8d893..50ac9a702 100644 --- a/async-signature/Cargo.toml +++ b/async-signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "async-signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "0.6.0-pre.1" +version = "0.6.0-pre.4" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/async-signature" From 5fbca1a2710197b3c34f2dac1e1a53a328203986 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Jul 2024 17:09:25 -0600 Subject: [PATCH 1216/1461] build(deps): bump pem-rfc7468 from 1.0.0-rc.0 to 1.0.0-rc.1 (#1634) --- Cargo.lock | 10 +++++----- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 960c1d94e..f8420283d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -56,7 +56,7 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "async-signature" -version = "0.6.0-pre.1" +version = "0.6.0-pre.4" dependencies = [ "signature 2.3.0-pre.4", ] @@ -404,7 +404,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05d9c07d3bd80cf0935ce478d07edf7e7a5b158446757f988f3e62082227b700" dependencies = [ "const-oid 0.10.0-rc.0", - "pem-rfc7468 1.0.0-rc.0", + "pem-rfc7468 1.0.0-rc.1", "zeroize", ] @@ -507,7 +507,7 @@ dependencies = [ "hex-literal", "hkdf 0.13.0-pre.4", "hybrid-array", - "pem-rfc7468 1.0.0-rc.0", + "pem-rfc7468 1.0.0-rc.1", "pkcs8 0.11.0-rc.0", "rand_core", "sec1 0.8.0-rc.0", @@ -856,9 +856,9 @@ dependencies = [ [[package]] name = "pem-rfc7468" -version = "1.0.0-rc.0" +version = "1.0.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2b24c1c4a3b352d47de5ec824193e68317dc0ce041f6279a4771eb550ab7f8c" +checksum = "b6c1cde4770761bf6bd336f947b9ac1fe700b0a4ec5867cf66cf08597fe89e8c" dependencies = [ "base64ct", ] diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index c64574e78..330d8d028 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -31,7 +31,7 @@ ff = { version = "0.13", optional = true, default-features = false } group = { version = "0.13", optional = true, default-features = false } hkdf = { version = "=0.13.0-pre.4", optional = true, default-features = false } hex-literal = { version = "0.4", optional = true } -pem-rfc7468 = { version = "1.0.0-rc.0", optional = true, features = ["alloc"] } +pem-rfc7468 = { version = "1.0.0-rc.1", optional = true, features = ["alloc"] } pkcs8 = { version = "0.11.0-rc.0", optional = true, default-features = false } sec1 = { version = "0.8.0-rc.0", optional = true, features = ["subtle", "zeroize"] } serdect = { version = "=0.3.0-pre.0", optional = true, default-features = false, features = ["alloc"] } From e37e0468ee73ccc12f719db69c218bf6cb8499f9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 31 Jul 2024 17:02:46 -0600 Subject: [PATCH 1217/1461] build(deps): bump bytes from 1.6.1 to 1.7.0 (#1637) Bumps [bytes](https://github.com/tokio-rs/bytes) from 1.6.1 to 1.7.0.
Release notes

Sourced from bytes's releases.

Bytes 1.7.0

1.7.0 (July 31, 2024)

Added

  • Add conversion from Bytes to BytesMut (#695, #710)
  • Add reclaim method without additional allocation (#686)

Documented

  • Clarify how BytesMut::zeroed works (#714)
  • Clarify the behavior of Buf::chunk (#717)

Changed

  • Change length condition of BytesMut::truncate
  • Reuse capacity when possible in <BytesMut as Buf>::advance impl (#698)
  • Improve must_use suggestion of BytesMut::split (#699)

Internal changes

  • Use ManuallyDrop instead of mem::forget (#678)
  • Don't set len in BytesMut::reserve (#682)
  • Optimize Bytes::copy_to_bytes (#688)
  • Refactor BytesMut::truncate (#694)
  • Refactor BytesMut::resize (#696)
  • Reorder assertion in Bytes::split_to, Bytes::split_off (#689, #693)
  • Use offset_from in more places (#705)
  • Correct the wrong usage of IntoIter (#707)
Changelog

Sourced from bytes's changelog.

1.7.0 (July 31, 2024)

Added

  • Add conversion from Bytes to BytesMut (#695, #710)
  • Add reclaim method without additional allocation (#686)

Documented

  • Clarify how BytesMut::zeroed works (#714)
  • Clarify the behavior of Buf::chunk (#717)

Changed

  • Change length condition of BytesMut::truncate
  • Reuse capacity when possible in <BytesMut as Buf>::advance impl (#698)
  • Improve must_use suggestion of BytesMut::split (#699)

Internal changes

  • Use ManuallyDrop instead of mem::forget (#678)
  • Don't set len in BytesMut::reserve (#682)
  • Optimize Bytes::copy_to_bytes (#688)
  • Refactor BytesMut::truncate (#694)
  • Refactor BytesMut::resize (#696)
  • Reorder assertion in Bytes::split_to, Bytes::split_off (#689, #693)
  • Use offset_from in more places (#705)
  • Correct the wrong usage of IntoIter (#707)
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=bytes&package-manager=cargo&previous-version=1.6.1&new-version=1.7.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f8420283d..190f6b316 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -160,9 +160,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952" +checksum = "fca2be1d5c43812bae364ee3f30b3afcb7877cf59f4aeb94c66f313a41d2fac9" [[package]] name = "cc" From 5d76e8d95e8e116fa77b771568f6ea67f92410df Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 31 Jul 2024 17:02:56 -0600 Subject: [PATCH 1218/1461] build(deps): bump serde_json from 1.0.120 to 1.0.121 (#1635) --- Cargo.lock | 11 +++++++++-- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 190f6b316..ac9536a6a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -789,6 +789,12 @@ version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + [[package]] name = "num-traits" version = "0.2.19" @@ -1109,11 +1115,12 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.120" +version = "1.0.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" +checksum = "4ab380d7d9f22ef3f21ad3e6c1ebe8e4fc7a2000ccba2e4d71fc96f15b2cb609" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 330d8d028..c5e6627fc 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -35,7 +35,7 @@ pem-rfc7468 = { version = "1.0.0-rc.1", optional = true, features = ["alloc"] } pkcs8 = { version = "0.11.0-rc.0", optional = true, default-features = false } sec1 = { version = "0.8.0-rc.0", optional = true, features = ["subtle", "zeroize"] } serdect = { version = "=0.3.0-pre.0", optional = true, default-features = false, features = ["alloc"] } -serde_json = { version = "1.0.114", optional = true, default-features = false, features = ["alloc"] } +serde_json = { version = "1.0.121", optional = true, default-features = false, features = ["alloc"] } tap = { version = "1.0.1", optional = true, default-features = false } # hack for minimal-versions support for `bits` [dev-dependencies] From f1ae691906681e7399db5a4088c24b4a44faa712 Mon Sep 17 00:00:00 2001 From: riskrose Date: Fri, 2 Aug 2024 11:44:09 +0900 Subject: [PATCH 1219/1461] digest: fix doc comment (#1640) --- digest/src/hashwriter.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/digest/src/hashwriter.rs b/digest/src/hashwriter.rs index e3d01f0ff..354590385 100644 --- a/digest/src/hashwriter.rs +++ b/digest/src/hashwriter.rs @@ -1,4 +1,4 @@ -//! Adds hashing to any writer. Inspired by implemention in phase2 crate. +//! Adds hashing to any writer. Inspired by implementation in phase2 crate. use super::{Digest, FixedOutputReset, Output, Reset}; use std::io; From 3ebd677b37533ebdb6a7cc4efcb980f8197246c7 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Wed, 14 Aug 2024 16:40:30 +0300 Subject: [PATCH 1220/1461] cipher: rework backend traits (#1636) This PR splits `BlockBackend` traits into 4 specific traits: `BlockCipherEncBackend`, `BlockCipherDecBackend`, `BlockModeEncBackend`, and `BlockModeDecBackend`. Same for `BlockClosure`. This allows for cipher backends to remove awkard `&mut &backend` juggling (see https://github.com/RustCrypto/block-ciphers/pull/442), makes code a bit easier to read (i.e. `encrypt_blocks` instead of `proc_blocks`), and allows for one backend type to be used for both encryption and decryption. The `impl_simple_block_encdec` macro is removed since we now can implement the backend traits directly on cipher types, which should make implementation crates slightly easier to understand. Additionally, it moves traits to the `block` and `cipher` modules to reduce clutter in the crate root. Later we can add docs to each module to describe the traits in detail. --- Cargo.lock | 58 +++-- cipher/Cargo.toml | 9 +- cipher/src/block.rs | 233 +++--------------- cipher/src/block/backends.rs | 206 ++++++++++++++++ cipher/src/block/ctx.rs | 120 +++++++++ cipher/src/dev/block.rs | 15 +- cipher/src/lib.rs | 37 +-- cipher/src/stream.rs | 28 ++- .../{stream_core.rs => stream/core_api.rs} | 37 +-- cipher/src/{ => stream}/errors.rs | 0 .../{stream_wrapper.rs => stream/wrapper.rs} | 2 +- crypto-common/Cargo.toml | 2 +- crypto-common/src/lib.rs | 6 + 13 files changed, 472 insertions(+), 281 deletions(-) create mode 100644 cipher/src/block/backends.rs create mode 100644 cipher/src/block/ctx.rs rename cipher/src/{stream_core.rs => stream/core_api.rs} (86%) rename cipher/src/{ => stream}/errors.rs (100%) rename cipher/src/{stream_wrapper.rs => stream/wrapper.rs} (99%) diff --git a/Cargo.lock b/Cargo.lock index ac9536a6a..33d01836f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,7 +19,7 @@ dependencies = [ "arrayvec", "blobby", "bytes", - "crypto-common 0.2.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.2.0-rc.0", "heapless", ] @@ -130,7 +130,7 @@ version = "0.11.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17092d478f4fadfb35a7e082f62e49f0907fdf048801d9d706277e34f9df8a78" dependencies = [ - "crypto-common 0.2.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.2.0-rc.0", "zeroize", ] @@ -160,15 +160,15 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.7.0" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fca2be1d5c43812bae364ee3f30b3afcb7877cf59f4aeb94c66f313a41d2fac9" +checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" [[package]] name = "cc" -version = "1.1.6" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aba8f4e9906c7ce3c73463f62a7f0c65183ada1a2d47e397cc8810827f9694f" +checksum = "26a5c3fd7bfa1ce3897a3a3501d362b2d87b7f2583ebcb4a949ec25911025cbc" dependencies = [ "jobserver", "libc", @@ -217,10 +217,10 @@ dependencies = [ [[package]] name = "cipher" -version = "0.5.0-pre.6" +version = "0.5.0-pre.7" dependencies = [ "blobby", - "crypto-common 0.2.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.2.0-rc.1", "inout 0.2.0-rc.0", "zeroize", ] @@ -317,6 +317,8 @@ dependencies = [ [[package]] name = "crypto-common" version = "0.2.0-rc.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c070b79a496dccd931229780ad5bbedd535ceff6c3565605a8e440e18e1aa2b" dependencies = [ "getrandom", "hybrid-array", @@ -325,9 +327,7 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.2.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c070b79a496dccd931229780ad5bbedd535ceff6c3565605a8e440e18e1aa2b" +version = "0.2.0-rc.1" dependencies = [ "getrandom", "hybrid-array", @@ -435,7 +435,7 @@ dependencies = [ "blobby", "block-buffer 0.11.0-rc.0", "const-oid 0.10.0-rc.0", - "crypto-common 0.2.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.2.0-rc.0", "subtle", "zeroize", ] @@ -926,9 +926,12 @@ dependencies = [ [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "dee4364d9f3b902ef14fab8a1ddffb783a1cb6b4bba3bfc1fa3922732c7de97f" +dependencies = [ + "zerocopy", +] [[package]] name = "pqcrypto" @@ -1115,9 +1118,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.121" +version = "1.0.124" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ab380d7d9f22ef3f21ad3e6c1ebe8e4fc7a2000ccba2e4d71fc96f15b2cb609" +checksum = "66ad62847a56b3dba58cc891acd13884b9c61138d330c0d7b6181713d4fce38d" dependencies = [ "itoa", "memchr", @@ -1303,7 +1306,7 @@ dependencies = [ name = "universal-hash" version = "0.6.0-rc.0" dependencies = [ - "crypto-common 0.2.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.2.0-rc.0", "subtle", ] @@ -1356,6 +1359,27 @@ dependencies = [ "sha2 0.9.9", ] +[[package]] +name = "zerocopy" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "854e949ac82d619ee9a14c66a1b674ac730422372ccb759ce0c39cabcf2bf8e6" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "125139de3f6b9d625c39e2efdd73d41bdac468ccd556556440e322be0e1bbd91" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "zeroize" version = "1.8.1" diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index 044e84b4c..1125a68b4 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "cipher" description = "Traits for describing block ciphers and stream ciphers" -version = "0.5.0-pre.6" +version = "0.5.0-pre.7" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" @@ -13,18 +13,19 @@ keywords = ["crypto", "block-cipher", "stream-cipher", "trait"] categories = ["cryptography", "no-std"] [dependencies] -crypto-common = "0.2.0-rc.0" +crypto-common = { version = "0.2.0-rc.1", path = "../crypto-common/" } inout = "0.2.0-rc.0" # optional dependencies blobby = { version = "0.3", optional = true } -zeroize = { version = "1.7", optional = true, default-features = false } +zeroize = { version = "1.8", optional = true, default-features = false } [features] alloc = [] std = ["alloc", "crypto-common/std", "inout/std"] block-padding = ["inout/block-padding"] -rand_core = ["crypto-common/rand_core"] # Enable random key and IV generation methods +# Enable random key and IV generation methods +rand_core = ["crypto-common/rand_core"] dev = ["blobby"] [package.metadata.docs.rs] diff --git a/cipher/src/block.rs b/cipher/src/block.rs index fd69bf570..3699ebfdb 100644 --- a/cipher/src/block.rs +++ b/cipher/src/block.rs @@ -10,10 +10,9 @@ //! [2]: https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation //! [3]: https://en.wikipedia.org/wiki/Symmetric-key_algorithm -use crate::{ParBlocks, ParBlocksSizeUser}; #[cfg(all(feature = "block-padding", feature = "alloc"))] use alloc::{vec, vec::Vec}; -use crypto_common::BlockSizes; +use crypto_common::{Block, BlockSizeUser}; #[cfg(feature = "block-padding")] use inout::{ block_padding::{Padding, UnpadError}, @@ -21,66 +20,20 @@ use inout::{ }; use inout::{InOut, InOutBuf, NotEqualError}; -pub use crypto_common::{array::ArraySize, typenum::Unsigned, Block, BlockSizeUser}; +mod backends; +mod ctx; -/// Marker trait for block ciphers. -pub trait BlockCipher: BlockSizeUser {} +use ctx::{BlockCtx, BlocksCtx}; -/// Trait implemented by block cipher encryption and decryption backends. -pub trait BlockBackend: ParBlocksSizeUser { - /// Process single inout block. - fn proc_block(&mut self, block: InOut<'_, '_, Block>); - - /// Process inout blocks in parallel. - #[inline(always)] - fn proc_par_blocks(&mut self, mut blocks: InOut<'_, '_, ParBlocks>) { - for i in 0..Self::ParBlocksSize::USIZE { - self.proc_block(blocks.get(i)); - } - } - - /// Process buffer of inout blocks. Length of the buffer MUST be smaller - /// than `Self::ParBlocksSize`. - #[inline(always)] - fn proc_tail_blocks(&mut self, blocks: InOutBuf<'_, '_, Block>) { - assert!(blocks.len() < Self::ParBlocksSize::USIZE); - for block in blocks { - self.proc_block(block); - } - } - - /// Process single block in-place. - #[inline(always)] - fn proc_block_inplace(&mut self, block: &mut Block) { - self.proc_block(block.into()); - } - - /// Process blocks in parallel in-place. - #[inline(always)] - fn proc_par_blocks_inplace(&mut self, blocks: &mut ParBlocks) { - self.proc_par_blocks(blocks.into()); - } - - /// Process buffer of blocks in-place. Length of the buffer MUST be smaller - /// than `Self::ParBlocksSize`. - #[inline(always)] - fn proc_tail_blocks_inplace(&mut self, blocks: &mut [Block]) { - self.proc_tail_blocks(blocks.into()); - } -} - -/// Trait for [`BlockBackend`] users. -/// -/// This trait is used to define rank-2 closures. -pub trait BlockClosure: BlockSizeUser { - /// Execute closure with the provided block cipher backend. - fn call>(self, backend: &mut B); -} +pub use backends::{ + BlockCipherDecBackend, BlockCipherDecClosure, BlockCipherEncBackend, BlockCipherEncClosure, + BlockModeDecBackend, BlockModeDecClosure, BlockModeEncBackend, BlockModeEncClosure, +}; /// Encrypt-only functionality for block ciphers. pub trait BlockCipherEncrypt: BlockSizeUser + Sized { /// Encrypt data using backend provided to the rank-2 closure. - fn encrypt_with_backend(&self, f: impl BlockClosure); + fn encrypt_with_backend(&self, f: impl BlockCipherEncClosure); /// Encrypt single `inout` block. #[inline] @@ -178,7 +131,9 @@ pub trait BlockCipherEncrypt: BlockSizeUser + Sized { #[cfg(all(feature = "block-padding", feature = "alloc"))] #[inline] fn encrypt_padded_vec>(&self, msg: &[u8]) -> Vec { - let mut out = allocate_out_vec::(msg.len()); + use crypto_common::typenum::Unsigned; + let bs = Self::BlockSize::USIZE; + let mut out = vec![0; bs * (msg.len() / bs + 1)]; let len = self .encrypt_padded_b2b::

(msg, &mut out) .expect("enough space for encrypting is allocated") @@ -191,7 +146,7 @@ pub trait BlockCipherEncrypt: BlockSizeUser + Sized { /// Decrypt-only functionality for block ciphers. pub trait BlockCipherDecrypt: BlockSizeUser { /// Decrypt data using backend provided to the rank-2 closure. - fn decrypt_with_backend(&self, f: impl BlockClosure); + fn decrypt_with_backend(&self, f: impl BlockCipherDecClosure); /// Decrypt single `inout` block. #[inline] @@ -310,6 +265,18 @@ pub trait BlockCipherDecrypt: BlockSizeUser { } } +impl BlockCipherEncrypt for &Alg { + fn encrypt_with_backend(&self, f: impl BlockCipherEncClosure) { + Alg::encrypt_with_backend(self, f); + } +} + +impl BlockCipherDecrypt for &Alg { + fn decrypt_with_backend(&self, f: impl BlockCipherDecClosure) { + Alg::decrypt_with_backend(self, f); + } +} + /// Encrypt-only functionality for block ciphers and modes with mutable access to `self`. /// /// The main use case for this trait is blocks modes, but it also can be used @@ -317,7 +284,7 @@ pub trait BlockCipherDecrypt: BlockSizeUser { /// underlying hardware peripheral. pub trait BlockModeEncrypt: BlockSizeUser + Sized { /// Encrypt data using backend provided to the rank-2 closure. - fn encrypt_with_backend(&mut self, f: impl BlockClosure); + fn encrypt_with_backend(&mut self, f: impl BlockModeEncClosure); /// Encrypt single `inout` block. #[inline] @@ -415,7 +382,9 @@ pub trait BlockModeEncrypt: BlockSizeUser + Sized { #[cfg(all(feature = "block-padding", feature = "alloc"))] #[inline] fn encrypt_padded_vec>(self, msg: &[u8]) -> Vec { - let mut out = allocate_out_vec::(msg.len()); + use crypto_common::typenum::Unsigned; + let bs = Self::BlockSize::USIZE; + let mut out = vec![0; bs * (msg.len() / bs + 1)]; let len = self .encrypt_padded_b2b::

(msg, &mut out) .expect("enough space for encrypting is allocated") @@ -432,7 +401,7 @@ pub trait BlockModeEncrypt: BlockSizeUser + Sized { /// underlying hardware peripheral. pub trait BlockModeDecrypt: BlockSizeUser + Sized { /// Decrypt data using backend provided to the rank-2 closure. - fn decrypt_with_backend(&mut self, f: impl BlockClosure); + fn decrypt_with_backend(&mut self, f: impl BlockModeDecClosure); /// Decrypt single `inout` block. #[inline] @@ -550,145 +519,3 @@ pub trait BlockModeDecrypt: BlockSizeUser + Sized { Ok(out) } } - -impl BlockCipher for &Alg {} - -impl BlockCipherEncrypt for &Alg { - fn encrypt_with_backend(&self, f: impl BlockClosure) { - Alg::encrypt_with_backend(self, f); - } -} - -impl BlockCipherDecrypt for &Alg { - fn decrypt_with_backend(&self, f: impl BlockClosure) { - Alg::decrypt_with_backend(self, f); - } -} - -/// Closure used in methods which operate over separate blocks. -struct BlockCtx<'inp, 'out, BS: BlockSizes> { - block: InOut<'inp, 'out, Block>, -} - -impl<'inp, 'out, BS: BlockSizes> BlockSizeUser for BlockCtx<'inp, 'out, BS> { - type BlockSize = BS; -} - -impl<'inp, 'out, BS: BlockSizes> BlockClosure for BlockCtx<'inp, 'out, BS> { - #[inline(always)] - fn call>(self, backend: &mut B) { - backend.proc_block(self.block); - } -} - -/// Closure used in methods which operate over slice of blocks. -struct BlocksCtx<'inp, 'out, BS: BlockSizes> { - blocks: InOutBuf<'inp, 'out, Block>, -} - -impl<'inp, 'out, BS: BlockSizes> BlockSizeUser for BlocksCtx<'inp, 'out, BS> { - type BlockSize = BS; -} - -impl<'inp, 'out, BS: BlockSizes> BlockClosure for BlocksCtx<'inp, 'out, BS> { - #[inline(always)] - fn call>(self, backend: &mut B) { - if B::ParBlocksSize::USIZE > 1 { - let (chunks, tail) = self.blocks.into_chunks(); - for chunk in chunks { - backend.proc_par_blocks(chunk); - } - backend.proc_tail_blocks(tail); - } else { - for block in self.blocks { - backend.proc_block(block); - } - } - } -} - -#[cfg(all(feature = "block-padding", feature = "alloc"))] -fn allocate_out_vec(len: usize) -> Vec { - let bs = BS::BlockSize::USIZE; - vec![0; bs * (len / bs + 1)] -} - -/// Implement simple block backend -#[macro_export] -macro_rules! impl_simple_block_encdec { - ( - <$($N:ident$(:$b0:ident$(+$b:ident)*)?),*> - $cipher:ident, $block_size:ty, $state:ident, $block:ident, - encrypt: $enc_block:block - decrypt: $dec_block:block - ) => { - impl<$($N$(:$b0$(+$b)*)?),*> $crate::BlockSizeUser for $cipher<$($N),*> { - type BlockSize = $block_size; - } - - impl<$($N$(:$b0$(+$b)*)?),*> $crate::BlockCipherEncrypt for $cipher<$($N),*> { - fn encrypt_with_backend(&self, f: impl $crate::BlockClosure) { - struct EncBack<'a, $($N$(:$b0$(+$b)*)?),* >(&'a $cipher<$($N),*>); - - impl<'a, $($N$(:$b0$(+$b)*)?),* > $crate::BlockSizeUser for EncBack<'a, $($N),*> { - type BlockSize = $block_size; - } - - impl<'a, $($N$(:$b0$(+$b)*)?),* > $crate::ParBlocksSizeUser for EncBack<'a, $($N),*> { - type ParBlocksSize = $crate::consts::U1; - } - - impl<'a, $($N$(:$b0$(+$b)*)?),* > $crate::BlockBackend for EncBack<'a, $($N),*> { - #[inline(always)] - fn proc_block( - &mut self, - mut $block: $crate::inout::InOut<'_, '_, $crate::Block> - ) { - let $state: &$cipher<$($N),*> = self.0; - $enc_block - } - } - - f.call(&mut EncBack(self)) - } - } - - impl<$($N$(:$b0$(+$b)*)?),*> $crate::BlockCipherDecrypt for $cipher<$($N),*> { - fn decrypt_with_backend(&self, f: impl $crate::BlockClosure) { - struct DecBack<'a, $($N$(:$b0$(+$b)*)?),* >(&'a $cipher<$($N),*>); - - impl<'a, $($N$(:$b0$(+$b)*)?),* > $crate::BlockSizeUser for DecBack<'a, $($N),*> { - type BlockSize = $block_size; - } - - impl<'a, $($N$(:$b0$(+$b)*)?),* > $crate::ParBlocksSizeUser for DecBack<'a, $($N),*> { - type ParBlocksSize = $crate::consts::U1; - } - - impl<'a, $($N$(:$b0$(+$b)*)?),* > $crate::BlockBackend for DecBack<'a, $($N),*> { - #[inline(always)] - fn proc_block( - &mut self, - mut $block: $crate::inout::InOut<'_, '_, $crate::Block> - ) { - let $state: &$cipher<$($N),*> = self.0; - $dec_block - } - } - - f.call(&mut DecBack(self)) - } - } - }; - ( - $cipher:ident, $block_size:ty, $state:ident, $block:ident, - encrypt: $enc_block:block - decrypt: $dec_block:block - ) => { - $crate::impl_simple_block_encdec!( - <> $cipher, $block_size, $state, $block, - encrypt: $enc_block - decrypt: $dec_block - ); - }; -} diff --git a/cipher/src/block/backends.rs b/cipher/src/block/backends.rs new file mode 100644 index 000000000..e035b3993 --- /dev/null +++ b/cipher/src/block/backends.rs @@ -0,0 +1,206 @@ +use crypto_common::{typenum::Unsigned, Block, BlockSizeUser, ParBlocks, ParBlocksSizeUser}; +use inout::{InOut, InOutBuf}; + +/// Trait implemented by block cipher mode encryption backends. +pub trait BlockCipherEncBackend: ParBlocksSizeUser { + /// Encrypt single inout block. + fn encrypt_block(&self, block: InOut<'_, '_, Block>); + + /// Encrypt inout blocks in parallel. + #[inline(always)] + fn encrypt_par_blocks(&self, mut blocks: InOut<'_, '_, ParBlocks>) { + for i in 0..Self::ParBlocksSize::USIZE { + self.encrypt_block(blocks.get(i)); + } + } + + /// Encrypt buffer of inout blocks. Length of the buffer MUST be smaller + /// than `Self::ParBlocksSize`. + #[inline(always)] + fn encrypt_tail_blocks(&self, blocks: InOutBuf<'_, '_, Block>) { + assert!(blocks.len() < Self::ParBlocksSize::USIZE); + for block in blocks { + self.encrypt_block(block); + } + } + + /// Encrypt single block in-place. + #[inline(always)] + fn encrypt_block_inplace(&self, block: &mut Block) { + self.encrypt_block(block.into()); + } + + /// Encrypt blocks in parallel in-place. + #[inline(always)] + fn encrypt_par_blocks_inplace(&self, blocks: &mut ParBlocks) { + self.encrypt_par_blocks(blocks.into()); + } + + /// Encrypt buffer of blocks in-place. Length of the buffer MUST be smaller + /// than `Self::ParBlocksSize`. + #[inline(always)] + fn encrypt_tail_blocks_inplace(&self, blocks: &mut [Block]) { + self.encrypt_tail_blocks(blocks.into()); + } +} + +/// Trait for [`BlockCipherEncBackend`] users. +/// +/// This trait is used to define rank-2 closures. +pub trait BlockCipherEncClosure: BlockSizeUser { + /// Execute closure with the provided block cipher backend. + fn call>(self, backend: &B); +} + +/// Trait implemented by block cipher decryption backends. +pub trait BlockCipherDecBackend: ParBlocksSizeUser { + /// Decrypt single inout block. + fn decrypt_block(&self, block: InOut<'_, '_, Block>); + + /// Decrypt inout blocks in parallel. + #[inline(always)] + fn decrypt_par_blocks(&self, mut blocks: InOut<'_, '_, ParBlocks>) { + for i in 0..Self::ParBlocksSize::USIZE { + self.decrypt_block(blocks.get(i)); + } + } + + /// Decrypt buffer of inout blocks. Length of the buffer MUST be smaller + /// than `Self::ParBlocksSize`. + #[inline(always)] + fn decrypt_tail_blocks(&self, blocks: InOutBuf<'_, '_, Block>) { + assert!(blocks.len() < Self::ParBlocksSize::USIZE); + for block in blocks { + self.decrypt_block(block); + } + } + + /// Decrypt single block in-place. + #[inline(always)] + fn decrypt_block_inplace(&self, block: &mut Block) { + self.decrypt_block(block.into()); + } + + /// Decrypt blocks in parallel in-place. + #[inline(always)] + fn decrypt_par_blocks_inplace(&self, blocks: &mut ParBlocks) { + self.decrypt_par_blocks(blocks.into()); + } + + /// Decrypt buffer of blocks in-place. Length of the buffer MUST be smaller + /// than `Self::ParBlocksSize`. + #[inline(always)] + fn decrypt_tail_blocks_inplace(&self, blocks: &mut [Block]) { + self.decrypt_tail_blocks(blocks.into()); + } +} + +/// Trait for [`BlockCipherDecBackend`] users. +/// +/// This trait is used to define rank-2 closures. +pub trait BlockCipherDecClosure: BlockSizeUser { + /// Execute closure with the provided block cipher backend. + fn call>(self, backend: &B); +} + +/// Trait implemented by block cipher mode encryption backends. +pub trait BlockModeEncBackend: ParBlocksSizeUser { + /// Encrypt single inout block. + fn encrypt_block(&mut self, block: InOut<'_, '_, Block>); + + /// Encrypt inout blocks in parallel. + #[inline(always)] + fn encrypt_par_blocks(&mut self, mut blocks: InOut<'_, '_, ParBlocks>) { + for i in 0..Self::ParBlocksSize::USIZE { + self.encrypt_block(blocks.get(i)); + } + } + + /// Encrypt buffer of inout blocks. Length of the buffer MUST be smaller + /// than `Self::ParBlocksSize`. + #[inline(always)] + fn encrypt_tail_blocks(&mut self, blocks: InOutBuf<'_, '_, Block>) { + assert!(blocks.len() < Self::ParBlocksSize::USIZE); + for block in blocks { + self.encrypt_block(block); + } + } + + /// Encrypt single block in-place. + #[inline(always)] + fn encrypt_block_inplace(&mut self, block: &mut Block) { + self.encrypt_block(block.into()); + } + + /// Encrypt blocks in parallel in-place. + #[inline(always)] + fn encrypt_par_blocks_inplace(&mut self, blocks: &mut ParBlocks) { + self.encrypt_par_blocks(blocks.into()); + } + + /// Encrypt buffer of blocks in-place. Length of the buffer MUST be smaller + /// than `Self::ParBlocksSize`. + #[inline(always)] + fn encrypt_tail_blocks_inplace(&mut self, blocks: &mut [Block]) { + self.encrypt_tail_blocks(blocks.into()); + } +} + +/// Trait for [`BlockModeEncBackend`] users. +/// +/// This trait is used to define rank-2 closures. +pub trait BlockModeEncClosure: BlockSizeUser { + /// Execute closure with the provided block cipher backend. + fn call>(self, backend: &mut B); +} + +/// Trait implemented by block cipher mode decryption backends. +pub trait BlockModeDecBackend: ParBlocksSizeUser { + /// Decrypt single inout block. + fn decrypt_block(&mut self, block: InOut<'_, '_, Block>); + + /// Decrypt inout blocks in parallel. + #[inline(always)] + fn decrypt_par_blocks(&mut self, mut blocks: InOut<'_, '_, ParBlocks>) { + for i in 0..Self::ParBlocksSize::USIZE { + self.decrypt_block(blocks.get(i)); + } + } + + /// Decrypt buffer of inout blocks. Length of the buffer MUST be smaller + /// than `Self::ParBlocksSize`. + #[inline(always)] + fn decrypt_tail_blocks(&mut self, blocks: InOutBuf<'_, '_, Block>) { + assert!(blocks.len() < Self::ParBlocksSize::USIZE); + for block in blocks { + self.decrypt_block(block); + } + } + + /// Decrypt single block in-place. + #[inline(always)] + fn decrypt_block_inplace(&mut self, block: &mut Block) { + self.decrypt_block(block.into()); + } + + /// Decrypt blocks in parallel in-place. + #[inline(always)] + fn decrypt_par_blocks_inplace(&mut self, blocks: &mut ParBlocks) { + self.decrypt_par_blocks(blocks.into()); + } + + /// Decrypt buffer of blocks in-place. Length of the buffer MUST be smaller + /// than `Self::ParBlocksSize`. + #[inline(always)] + fn decrypt_tail_blocks_inplace(&mut self, blocks: &mut [Block]) { + self.decrypt_tail_blocks(blocks.into()); + } +} + +/// Trait for [`BlockModeDecBackend`] users. +/// +/// This trait is used to define rank-2 closures. +pub trait BlockModeDecClosure: BlockSizeUser { + /// Execute closure with the provided block cipher backend. + fn call>(self, backend: &mut B); +} diff --git a/cipher/src/block/ctx.rs b/cipher/src/block/ctx.rs new file mode 100644 index 000000000..7b0f04632 --- /dev/null +++ b/cipher/src/block/ctx.rs @@ -0,0 +1,120 @@ +use crypto_common::{typenum::Unsigned, Block, BlockSizeUser, BlockSizes}; +use inout::{InOut, InOutBuf}; + +use super::{ + BlockCipherDecBackend, BlockCipherDecClosure, BlockCipherEncBackend, BlockCipherEncClosure, + BlockModeDecBackend, BlockModeDecClosure, BlockModeEncBackend, BlockModeEncClosure, +}; + +/// Closure used in methods which operate over separate blocks. +pub(super) struct BlockCtx<'inp, 'out, BS: BlockSizes> { + pub block: InOut<'inp, 'out, Block>, +} + +impl<'inp, 'out, BS: BlockSizes> BlockSizeUser for BlockCtx<'inp, 'out, BS> { + type BlockSize = BS; +} + +impl<'inp, 'out, BS: BlockSizes> BlockCipherEncClosure for BlockCtx<'inp, 'out, BS> { + #[inline(always)] + fn call>(self, backend: &B) { + backend.encrypt_block(self.block); + } +} + +impl<'inp, 'out, BS: BlockSizes> BlockCipherDecClosure for BlockCtx<'inp, 'out, BS> { + #[inline(always)] + fn call>(self, backend: &B) { + backend.decrypt_block(self.block); + } +} + +impl<'inp, 'out, BS: BlockSizes> BlockModeEncClosure for BlockCtx<'inp, 'out, BS> { + #[inline(always)] + fn call>(self, backend: &mut B) { + backend.encrypt_block(self.block); + } +} + +impl<'inp, 'out, BS: BlockSizes> BlockModeDecClosure for BlockCtx<'inp, 'out, BS> { + #[inline(always)] + fn call>(self, backend: &mut B) { + backend.decrypt_block(self.block); + } +} +/// Closure used in methods which operate over slice of blocks. +pub(super) struct BlocksCtx<'inp, 'out, BS: BlockSizes> { + pub blocks: InOutBuf<'inp, 'out, Block>, +} + +impl<'inp, 'out, BS: BlockSizes> BlockSizeUser for BlocksCtx<'inp, 'out, BS> { + type BlockSize = BS; +} + +impl<'inp, 'out, BS: BlockSizes> BlockCipherEncClosure for BlocksCtx<'inp, 'out, BS> { + #[inline(always)] + fn call>(self, backend: &B) { + if B::ParBlocksSize::USIZE > 1 { + let (chunks, tail) = self.blocks.into_chunks(); + for chunk in chunks { + backend.encrypt_par_blocks(chunk); + } + backend.encrypt_tail_blocks(tail); + } else { + for block in self.blocks { + backend.encrypt_block(block); + } + } + } +} + +impl<'inp, 'out, BS: BlockSizes> BlockCipherDecClosure for BlocksCtx<'inp, 'out, BS> { + #[inline(always)] + fn call>(self, backend: &B) { + if B::ParBlocksSize::USIZE > 1 { + let (chunks, tail) = self.blocks.into_chunks(); + for chunk in chunks { + backend.decrypt_par_blocks(chunk); + } + backend.decrypt_tail_blocks(tail); + } else { + for block in self.blocks { + backend.decrypt_block(block); + } + } + } +} + +impl<'inp, 'out, BS: BlockSizes> BlockModeEncClosure for BlocksCtx<'inp, 'out, BS> { + #[inline(always)] + fn call>(self, backend: &mut B) { + if B::ParBlocksSize::USIZE > 1 { + let (chunks, tail) = self.blocks.into_chunks(); + for chunk in chunks { + backend.encrypt_par_blocks(chunk); + } + backend.encrypt_tail_blocks(tail); + } else { + for block in self.blocks { + backend.encrypt_block(block); + } + } + } +} + +impl<'inp, 'out, BS: BlockSizes> BlockModeDecClosure for BlocksCtx<'inp, 'out, BS> { + #[inline(always)] + fn call>(self, backend: &mut B) { + if B::ParBlocksSize::USIZE > 1 { + let (chunks, tail) = self.blocks.into_chunks(); + for chunk in chunks { + backend.decrypt_par_blocks(chunk); + } + backend.decrypt_tail_blocks(tail); + } else { + for block in self.blocks { + backend.decrypt_block(block); + } + } + } +} diff --git a/cipher/src/dev/block.rs b/cipher/src/dev/block.rs index 80ea55273..42558c561 100644 --- a/cipher/src/dev/block.rs +++ b/cipher/src/dev/block.rs @@ -7,8 +7,11 @@ macro_rules! block_cipher_test { #[test] fn $name() { use cipher::{ - array::Array, blobby::Blob3Iterator, typenum::Unsigned, BlockCipherDecrypt, - BlockCipherEncrypt, BlockSizeUser, KeyInit, + array::Array, + blobby::Blob3Iterator, + block::{BlockCipherDecrypt, BlockCipherEncrypt}, + typenum::Unsigned, + BlockSizeUser, KeyInit, }; fn run_test(key: &[u8], pt: &[u8], ct: &[u8]) -> bool { @@ -290,7 +293,7 @@ macro_rules! block_encryptor_bench { #[bench] pub fn $block_name(bh: &mut test::Bencher) { #[allow(unused)] - use cipher::{BlockCipherEncrypt, BlockModeEncrypt}; + use $crate::{BlockCipherEncrypt, BlockModeEncrypt}; let mut cipher = $init; let mut blocks = vec![Default::default(); 1024]; @@ -307,7 +310,7 @@ macro_rules! block_encryptor_bench { #[bench] pub fn $blocks_name(bh: &mut test::Bencher) { #[allow(unused)] - use cipher::{BlockCipherEncrypt, BlockModeEncrypt}; + use $crate::{BlockCipherEncrypt, BlockModeEncrypt}; let mut cipher = $init; let mut blocks = vec![Default::default(); 1024]; @@ -353,7 +356,7 @@ macro_rules! block_decryptor_bench { #[bench] pub fn $block_name(bh: &mut test::Bencher) { #[allow(unused)] - use cipher::{BlockCipherDecrypt, BlockModeDecrypt}; + use $crate::{BlockCipherDecrypt, BlockModeDecrypt}; let mut cipher = $init; let mut blocks = vec![Default::default(); 1024]; @@ -370,7 +373,7 @@ macro_rules! block_decryptor_bench { #[bench] pub fn $blocks_name(bh: &mut test::Bencher) { #[allow(unused)] - use cipher::{BlockCipherDecrypt, BlockModeDecrypt}; + use $crate::{BlockCipherDecrypt, BlockModeDecrypt}; let mut cipher = $init; let mut blocks = vec![Default::default(); 1024]; diff --git a/cipher/src/lib.rs b/cipher/src/lib.rs index ba485aa5a..1c7ae89ee 100644 --- a/cipher/src/lib.rs +++ b/cipher/src/lib.rs @@ -18,45 +18,34 @@ missing_debug_implementations )] -pub use crypto_common; -pub use inout; - #[cfg(all(feature = "block-padding", feature = "alloc"))] extern crate alloc; - #[cfg(feature = "std")] extern crate std; +#[cfg(feature = "dev")] +pub use blobby; +pub use crypto_common; #[cfg(feature = "rand_core")] pub use crypto_common::rand_core; - +pub use inout; #[cfg(feature = "block-padding")] pub use inout::block_padding; - #[cfg(feature = "zeroize")] pub use zeroize; -#[cfg(feature = "dev")] -pub use blobby; - -mod block; +pub mod block; #[cfg(feature = "dev")] mod dev; -mod errors; -mod stream; -mod stream_core; -mod stream_wrapper; +pub mod stream; + +pub use block::*; +pub use stream::*; -pub use crate::{block::*, errors::*, stream::*, stream_core::*, stream_wrapper::*}; pub use crypto_common::{ - array, + array::{self, Array}, typenum::{self, consts}, - AlgorithmName, Block, InnerIvInit, InvalidLength, Iv, IvSizeUser, Key, KeyInit, KeyIvInit, - KeySizeUser, ParBlocks, ParBlocksSizeUser, + AlgorithmName, Block, BlockSizeUser, InnerIvInit, InvalidLength, Iv, IvSizeUser, IvState, Key, + KeyInit, KeyIvInit, KeySizeUser, ParBlocks, ParBlocksSizeUser, }; - -/// Trait for loading current IV state. -pub trait IvState: IvSizeUser { - /// Returns current IV state. - fn iv_state(&self) -> Iv; -} +pub use inout::{InOut, InOutBuf}; diff --git a/cipher/src/stream.rs b/cipher/src/stream.rs index ac7a2fe5d..520837db5 100644 --- a/cipher/src/stream.rs +++ b/cipher/src/stream.rs @@ -3,11 +3,21 @@ //! See [RustCrypto/stream-ciphers](https://github.com/RustCrypto/stream-ciphers) //! for ciphers implementation. -use crate::errors::{OverflowError, StreamCipherError}; -use crate::stream_core::Counter; -use crate::{Block, BlockModeDecrypt, BlockModeEncrypt}; +use crate::block::{BlockModeDecrypt, BlockModeEncrypt}; +use crypto_common::Block; use inout::{InOutBuf, NotEqualError}; +mod core_api; +mod errors; +mod wrapper; + +pub use core_api::{ + StreamCipherBackend, StreamCipherClosure, StreamCipherCore, StreamCipherCounter, + StreamCipherSeekCore, +}; +pub use errors::{OverflowError, StreamCipherError}; +pub use wrapper::StreamCipherCoreWrapper; + /// Marker trait for block-level asynchronous stream ciphers pub trait AsyncStreamCipher: Sized { /// Encrypt data using `InOutBuf`. @@ -192,17 +202,21 @@ impl StreamCipher for &mut C { pub trait SeekNum: Sized { /// Try to get position for block number `block`, byte position inside /// block `byte`, and block size `bs`. - fn from_block_byte(block: T, byte: u8, bs: u8) -> Result; + fn from_block_byte( + block: T, + byte: u8, + bs: u8, + ) -> Result; /// Try to get block number and bytes position for given block size `bs`. - fn into_block_byte(self, bs: u8) -> Result<(T, u8), OverflowError>; + fn into_block_byte(self, bs: u8) -> Result<(T, u8), OverflowError>; } macro_rules! impl_seek_num { {$($t:ty )*} => { $( impl SeekNum for $t { - fn from_block_byte(block: T, byte: u8, block_size: u8) -> Result { + fn from_block_byte(block: T, byte: u8, block_size: u8) -> Result { debug_assert!(byte != 0); let rem = block_size.checked_sub(byte).ok_or(OverflowError)?; let block: Self = block.try_into().map_err(|_| OverflowError)?; @@ -212,7 +226,7 @@ macro_rules! impl_seek_num { .ok_or(OverflowError) } - fn into_block_byte(self, block_size: u8) -> Result<(T, u8), OverflowError> { + fn into_block_byte(self, block_size: u8) -> Result<(T, u8), OverflowError> { let bs: Self = block_size.into(); let byte = (self % bs) as u8; let block = T::try_from(self / bs).map_err(|_| OverflowError)?; diff --git a/cipher/src/stream_core.rs b/cipher/src/stream/core_api.rs similarity index 86% rename from cipher/src/stream_core.rs rename to cipher/src/stream/core_api.rs index c121ca46a..aab1c32b5 100644 --- a/cipher/src/stream_core.rs +++ b/cipher/src/stream/core_api.rs @@ -1,9 +1,10 @@ -use crate::{ParBlocks, ParBlocksSizeUser, StreamCipherError}; -use crypto_common::{array::Array, typenum::Unsigned, Block, BlockSizeUser, BlockSizes}; +use super::StreamCipherError; +use crate::{array::Array, typenum::Unsigned}; +use crypto_common::{Block, BlockSizeUser, BlockSizes, ParBlocks, ParBlocksSizeUser}; use inout::{InOut, InOutBuf}; /// Trait implemented by stream cipher backends. -pub trait StreamBackend: ParBlocksSizeUser { +pub trait StreamCipherBackend: ParBlocksSizeUser { /// Generate keystream block. fn gen_ks_block(&mut self, block: &mut Block); @@ -26,12 +27,12 @@ pub trait StreamBackend: ParBlocksSizeUser { } } -/// Trait for [`StreamBackend`] users. +/// Trait for [`StreamCipherBackend`] users. /// /// This trait is used to define rank-2 closures. -pub trait StreamClosure: BlockSizeUser { +pub trait StreamCipherClosure: BlockSizeUser { /// Execute closure with the provided stream cipher backend. - fn call>(self, backend: &mut B); + fn call>(self, backend: &mut B); } /// Block-level synchronous stream ciphers. @@ -44,7 +45,7 @@ pub trait StreamCipherCore: BlockSizeUser + Sized { fn remaining_blocks(&self) -> Option; /// Process data using backend provided to the rank-2 closure. - fn process_with_backend(&mut self, f: impl StreamClosure); + fn process_with_backend(&mut self, f: impl StreamCipherClosure); /// Write keystream block. /// @@ -152,7 +153,7 @@ pub trait StreamCipherCore: BlockSizeUser + Sized { /// This trait is implemented for `i32`, `u32`, `u64`, `u128`, and `usize`. /// It's not intended to be implemented in third-party crates, but doing so /// is not forbidden. -pub trait Counter: +pub trait StreamCipherCounter: TryFrom + TryFrom + TryFrom @@ -169,7 +170,7 @@ pub trait Counter: /// Block-level seeking trait for stream ciphers. pub trait StreamCipherSeekCore: StreamCipherCore { /// Counter type used inside stream cipher. - type Counter: Counter; + type Counter: StreamCipherCounter; /// Get current block position. fn get_block_pos(&self) -> Self::Counter; @@ -180,7 +181,7 @@ pub trait StreamCipherSeekCore: StreamCipherCore { macro_rules! impl_counter { {$($t:ty )*} => { - $( impl Counter for $t { } )* + $( impl StreamCipherCounter for $t { } )* }; } @@ -192,9 +193,9 @@ struct WriteBlockCtx<'a, BS: BlockSizes> { impl<'a, BS: BlockSizes> BlockSizeUser for WriteBlockCtx<'a, BS> { type BlockSize = BS; } -impl<'a, BS: BlockSizes> StreamClosure for WriteBlockCtx<'a, BS> { +impl<'a, BS: BlockSizes> StreamCipherClosure for WriteBlockCtx<'a, BS> { #[inline(always)] - fn call>(self, backend: &mut B) { + fn call>(self, backend: &mut B) { backend.gen_ks_block(self.block); } } @@ -205,9 +206,9 @@ struct WriteBlocksCtx<'a, BS: BlockSizes> { impl<'a, BS: BlockSizes> BlockSizeUser for WriteBlocksCtx<'a, BS> { type BlockSize = BS; } -impl<'a, BS: BlockSizes> StreamClosure for WriteBlocksCtx<'a, BS> { +impl<'a, BS: BlockSizes> StreamCipherClosure for WriteBlocksCtx<'a, BS> { #[inline(always)] - fn call>(self, backend: &mut B) { + fn call>(self, backend: &mut B) { if B::ParBlocksSize::USIZE > 1 { let (chunks, tail) = Array::slice_as_chunks_mut(self.blocks); for chunk in chunks { @@ -230,9 +231,9 @@ impl<'inp, 'out, BS: BlockSizes> BlockSizeUser for ApplyBlockCtx<'inp, 'out, BS> type BlockSize = BS; } -impl<'inp, 'out, BS: BlockSizes> StreamClosure for ApplyBlockCtx<'inp, 'out, BS> { +impl<'inp, 'out, BS: BlockSizes> StreamCipherClosure for ApplyBlockCtx<'inp, 'out, BS> { #[inline(always)] - fn call>(mut self, backend: &mut B) { + fn call>(mut self, backend: &mut B) { let mut t = Default::default(); backend.gen_ks_block(&mut t); self.block.xor_in2out(&t); @@ -247,10 +248,10 @@ impl<'inp, 'out, BS: BlockSizes> BlockSizeUser for ApplyBlocksCtx<'inp, 'out, BS type BlockSize = BS; } -impl<'inp, 'out, BS: BlockSizes> StreamClosure for ApplyBlocksCtx<'inp, 'out, BS> { +impl<'inp, 'out, BS: BlockSizes> StreamCipherClosure for ApplyBlocksCtx<'inp, 'out, BS> { #[inline(always)] #[allow(clippy::needless_range_loop)] - fn call>(self, backend: &mut B) { + fn call>(self, backend: &mut B) { if B::ParBlocksSize::USIZE > 1 { let (chunks, mut tail) = self.blocks.into_chunks::(); for mut chunk in chunks { diff --git a/cipher/src/errors.rs b/cipher/src/stream/errors.rs similarity index 100% rename from cipher/src/errors.rs rename to cipher/src/stream/errors.rs diff --git a/cipher/src/stream_wrapper.rs b/cipher/src/stream/wrapper.rs similarity index 99% rename from cipher/src/stream_wrapper.rs rename to cipher/src/stream/wrapper.rs index 626b4e3d0..abf4a9b04 100644 --- a/cipher/src/stream_wrapper.rs +++ b/cipher/src/stream/wrapper.rs @@ -1,4 +1,4 @@ -use crate::{ +use super::{ errors::StreamCipherError, Block, OverflowError, SeekNum, StreamCipher, StreamCipherCore, StreamCipherSeek, StreamCipherSeekCore, }; diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index 8ccd7ea05..52be3f26b 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crypto-common" description = "Common cryptographic traits" -version = "0.2.0-rc.0" +version = "0.2.0-rc.1" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/crypto-common/src/lib.rs b/crypto-common/src/lib.rs index 712fcf49b..bd62fade1 100644 --- a/crypto-common/src/lib.rs +++ b/crypto-common/src/lib.rs @@ -305,6 +305,12 @@ pub trait InnerIvInit: InnerUser + IvSizeUser + Sized { } } +/// Trait for loading current IV state. +pub trait IvState: IvSizeUser { + /// Returns current IV state. + fn iv_state(&self) -> Iv; +} + impl KeySizeUser for T where T: InnerUser, From dff9996dc0526e1aeff81f2b3a46d77e70ca7449 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Fri, 16 Aug 2024 08:43:59 +0300 Subject: [PATCH 1221/1461] digest: fix types in README (#1649) --- digest/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/digest/README.md b/digest/README.md index 479d5c7ed..da44f69e4 100644 --- a/digest/README.md +++ b/digest/README.md @@ -56,8 +56,8 @@ let hash = hasher.finalize(); println!("Result: {:x}", hash); ``` -In this example `hash` has type [`Array`][2], which is a generic -alternative to `[u8; 64]`. +In this example `hash` has type [`Array`][2], which is a generic +alternative to `[u8; 32]`. Alternatively you can use chained approach, which is equivalent to the previous example: From bc109d0fea90d62993fc0cc1afc39cc6880d85ec Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 4 Sep 2024 19:49:44 -0600 Subject: [PATCH 1222/1461] README.md(s): use img.shields.io crate version badges --- elliptic-curve/README.md | 2 +- password-hash/README.md | 2 +- signature/README.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/elliptic-curve/README.md b/elliptic-curve/README.md index 0824685c9..e2c383f22 100644 --- a/elliptic-curve/README.md +++ b/elliptic-curve/README.md @@ -42,7 +42,7 @@ dual licensed as above, without any additional terms or conditions. [//]: # (badges) -[crate-image]: https://buildstats.info/crate/elliptic-curve +[crate-image]: https://img.shields.io/crates/v/elliptic-curve [crate-link]: https://crates.io/crates/elliptic-curve [docs-image]: https://docs.rs/elliptic-curve/badge.svg [docs-link]: https://docs.rs/elliptic-curve/ diff --git a/password-hash/README.md b/password-hash/README.md index a3a91adf4..dd376cd5f 100644 --- a/password-hash/README.md +++ b/password-hash/README.md @@ -56,7 +56,7 @@ dual licensed as above, without any additional terms or conditions. [//]: # (badges) -[crate-image]: https://buildstats.info/crate/password-hash +[crate-image]: https://img.shields.io/crates/v/password-hash [crate-link]: https://crates.io/crates/password-hash [docs-image]: https://docs.rs/password-hash/badge.svg [docs-link]: https://docs.rs/password-hash/ diff --git a/signature/README.md b/signature/README.md index 838d131b6..ce11d14df 100644 --- a/signature/README.md +++ b/signature/README.md @@ -49,7 +49,7 @@ dual licensed as above, without any additional terms or conditions. [//]: # (badges) -[crate-image]: https://buildstats.info/crate/signature +[crate-image]: https://img.shields.io/crates/v/signature [crate-link]: https://crates.io/crates/signature [docs-image]: https://docs.rs/signature/badge.svg [docs-link]: https://docs.rs/signature/ From 7fb782a00eb729ded573f9f635095ce852afe62e Mon Sep 17 00:00:00 2001 From: Luna Saphie Mittelbach Date: Thu, 5 Sep 2024 20:01:40 +0200 Subject: [PATCH 1223/1461] password-hash: Add `Output::with_encoding` method (#1657) Allows `Display`/`Debug` printing `Output` with a specific `Encoding` without needing to go through `encode`/`b64_encode`, if e.g. it was created using `init_with`. Maybe a version of `init_with` that allows specifying an encoding (similar to `new_with_encoding`) would be better, I'm not sure. This is a smaller, more general change. --- password-hash/src/output.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/password-hash/src/output.rs b/password-hash/src/output.rs index 7f1998fc7..65ee3484c 100644 --- a/password-hash/src/output.rs +++ b/password-hash/src/output.rs @@ -182,6 +182,11 @@ impl Output { self.encoding } + /// Creates a copy of this [`Output`] with the specified [`Encoding`]. + pub fn with_encoding(&self, encoding: Encoding) -> Self { + Self { encoding, ..*self } + } + /// Get the length of the output value as a byte slice. pub fn len(&self) -> usize { usize::from(self.length) From 64277691b0abeef47b6a8725939ad90cd1727b7e Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Thu, 5 Sep 2024 14:59:46 -0700 Subject: [PATCH 1224/1461] elliptic-curve: pkcs8 API changes (#1650) see https://github.com/RustCrypto/formats/pull/1483 --- Cargo.lock | 6 ++---- Cargo.toml | 3 +++ elliptic-curve/src/secret_key/pkcs8.rs | 17 +++++++++++------ 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 33d01836f..8a02a6760 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -894,8 +894,7 @@ dependencies = [ [[package]] name = "pkcs8" version = "0.11.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66180445f1dce533620a7743467ef85fe1c5e80cdaf7c7053609d7a2fbcdae20" +source = "git+https://github.com/RustCrypto/formats.git#3fb883b2f445e74f38f51fef63a347ecfe69f623" dependencies = [ "der 0.8.0-rc.0", "spki 0.8.0-rc.0", @@ -1069,8 +1068,7 @@ dependencies = [ [[package]] name = "sec1" version = "0.8.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32c98827dc6ed0ea1707286a3d14b4ad4e25e2643169cbf111568a46ff5b09f5" +source = "git+https://github.com/RustCrypto/formats.git#3fb883b2f445e74f38f51fef63a347ecfe69f623" dependencies = [ "base16ct", "der 0.8.0-rc.0", diff --git a/Cargo.toml b/Cargo.toml index 2ca101fbc..bbea205a0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,3 +18,6 @@ members = [ [patch.crates-io] digest = { path = "./digest" } signature = { path = "./signature" } + +sec1 = { git = "https://github.com/RustCrypto/formats.git" } +pkcs8 = { git = "https://github.com/RustCrypto/formats.git" } diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs index a1c37aa36..6cf1b33e5 100644 --- a/elliptic-curve/src/secret_key/pkcs8.rs +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -16,7 +16,10 @@ use { sec1::{FromEncodedPoint, ToEncodedPoint}, AffinePoint, CurveArithmetic, }, - pkcs8::{der, EncodePrivateKey}, + pkcs8::{ + der::{self, asn1::OctetStringRef}, + EncodePrivateKey, + }, }; // Imports for actual PEM support @@ -39,19 +42,19 @@ where }; } -impl TryFrom> for SecretKey +impl TryFrom> for SecretKey where C: AssociatedOid + Curve + ValidatePublicKey, FieldBytesSize: ModulusSize, { type Error = pkcs8::Error; - fn try_from(private_key_info: pkcs8::PrivateKeyInfo<'_>) -> pkcs8::Result { + fn try_from(private_key_info: pkcs8::PrivateKeyInfoRef<'_>) -> pkcs8::Result { private_key_info .algorithm .assert_oids(ALGORITHM_OID, C::OID)?; - let ec_private_key = EcPrivateKey::from_der(private_key_info.private_key)?; + let ec_private_key = EcPrivateKey::from_der(private_key_info.private_key.as_bytes())?; Ok(Self::try_from(ec_private_key)?) } } @@ -64,14 +67,16 @@ where FieldBytesSize: ModulusSize, { fn to_pkcs8_der(&self) -> pkcs8::Result { - // TODO(tarcieri): make `PrivateKeyInfo` generic around `Params` let algorithm_identifier = pkcs8::AlgorithmIdentifierRef { oid: ALGORITHM_OID, parameters: Some((&C::OID).into()), }; let ec_private_key = self.to_sec1_der()?; - let pkcs8_key = pkcs8::PrivateKeyInfo::new(algorithm_identifier, &ec_private_key); + let pkcs8_key = pkcs8::PrivateKeyInfoRef::new( + algorithm_identifier, + OctetStringRef::new(&ec_private_key)?, + ); Ok(der::SecretDocument::encode_msg(&pkcs8_key)?) } } From 62ee195e59f8870a5bd8459586895ff2c5b3ac79 Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Fri, 6 Sep 2024 10:25:57 -0700 Subject: [PATCH 1225/1461] elliptic-curve: publish pre-release 0.14.0-rc.0 (#1661) --- Cargo.lock | 18 ++++++++++-------- Cargo.toml | 3 --- elliptic-curve/Cargo.toml | 6 +++--- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8a02a6760..50603db6d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -496,7 +496,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.14.0-pre.6" +version = "0.14.0-rc.0" dependencies = [ "base16ct", "base64ct", @@ -508,9 +508,9 @@ dependencies = [ "hkdf 0.13.0-pre.4", "hybrid-array", "pem-rfc7468 1.0.0-rc.1", - "pkcs8 0.11.0-rc.0", + "pkcs8 0.11.0-rc.1", "rand_core", - "sec1 0.8.0-rc.0", + "sec1 0.8.0-rc.1", "serde_json", "serdect", "sha2 0.11.0-pre.4", @@ -893,8 +893,9 @@ dependencies = [ [[package]] name = "pkcs8" -version = "0.11.0-rc.0" -source = "git+https://github.com/RustCrypto/formats.git#3fb883b2f445e74f38f51fef63a347ecfe69f623" +version = "0.11.0-rc.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eacd2c7141f32aef1cfd1ad0defb5287a3d94592d7ab57c1ae20e3f9f1f0db1f" dependencies = [ "der 0.8.0-rc.0", "spki 0.8.0-rc.0", @@ -1067,13 +1068,14 @@ dependencies = [ [[package]] name = "sec1" -version = "0.8.0-rc.0" -source = "git+https://github.com/RustCrypto/formats.git#3fb883b2f445e74f38f51fef63a347ecfe69f623" +version = "0.8.0-rc.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99890e11f8ab873d750adfe2a8e46062d6f8b78431d3ec1e0e7daba10b8ba397" dependencies = [ "base16ct", "der 0.8.0-rc.0", "hybrid-array", - "pkcs8 0.11.0-rc.0", + "pkcs8 0.11.0-rc.1", "serdect", "subtle", "zeroize", diff --git a/Cargo.toml b/Cargo.toml index bbea205a0..2ca101fbc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,3 @@ members = [ [patch.crates-io] digest = { path = "./digest" } signature = { path = "./signature" } - -sec1 = { git = "https://github.com/RustCrypto/formats.git" } -pkcs8 = { git = "https://github.com/RustCrypto/formats.git" } diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index c5e6627fc..bc86e607f 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.14.0-pre.6" +version = "0.14.0-rc.0" description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, @@ -32,8 +32,8 @@ group = { version = "0.13", optional = true, default-features = false } hkdf = { version = "=0.13.0-pre.4", optional = true, default-features = false } hex-literal = { version = "0.4", optional = true } pem-rfc7468 = { version = "1.0.0-rc.1", optional = true, features = ["alloc"] } -pkcs8 = { version = "0.11.0-rc.0", optional = true, default-features = false } -sec1 = { version = "0.8.0-rc.0", optional = true, features = ["subtle", "zeroize"] } +pkcs8 = { version = "0.11.0-rc.1", optional = true, default-features = false } +sec1 = { version = "0.8.0-rc.1", optional = true, features = ["subtle", "zeroize"] } serdect = { version = "=0.3.0-pre.0", optional = true, default-features = false, features = ["alloc"] } serde_json = { version = "1.0.121", optional = true, default-features = false, features = ["alloc"] } tap = { version = "1.0.1", optional = true, default-features = false } # hack for minimal-versions support for `bits` From 59f1a5b7d5c2d34554ed95ca3757b393968cc097 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Sep 2024 16:37:08 -0600 Subject: [PATCH 1226/1461] build(deps): bump bytes from 1.7.1 to 1.7.2 (#1668) Bumps [bytes](https://github.com/tokio-rs/bytes) from 1.7.1 to 1.7.2.

Release notes

Sourced from bytes's releases.

Bytes 1.7.2

1.7.2 (September 17, 2024)

Fixed

  • Fix default impl of Buf::{get_int, get_int_le} (#732)

Documented

  • Fix double spaces in comments and doc comments (#731)

Internal changes

  • Ensure BytesMut::advance reduces capacity (#728)
Changelog

Sourced from bytes's changelog.

1.7.2 (September 17, 2024)

Fixed

  • Fix default impl of Buf::{get_int, get_int_le} (#732)

Documented

  • Fix double spaces in comments and doc comments (#731)

Internal changes

  • Ensure BytesMut::advance reduces capacity (#728)
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=bytes&package-manager=cargo&previous-version=1.7.1&new-version=1.7.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 50603db6d..ea6632b39 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -160,9 +160,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.7.1" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" +checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" [[package]] name = "cc" From 19a3593a2f4cbb6cb26e083929f980e32e0a15b5 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 20 Sep 2024 12:44:00 -0600 Subject: [PATCH 1227/1461] elliptic-curve: bump `serdect` to v0.3.0-rc.0 (#1670) --- Cargo.lock | 10 +++++----- elliptic-curve/Cargo.toml | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ea6632b39..cebf88f69 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -510,7 +510,7 @@ dependencies = [ "pem-rfc7468 1.0.0-rc.1", "pkcs8 0.11.0-rc.1", "rand_core", - "sec1 0.8.0-rc.1", + "sec1 0.8.0-rc.2", "serde_json", "serdect", "sha2 0.11.0-pre.4", @@ -1068,9 +1068,9 @@ dependencies = [ [[package]] name = "sec1" -version = "0.8.0-rc.1" +version = "0.8.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99890e11f8ab873d750adfe2a8e46062d6f8b78431d3ec1e0e7daba10b8ba397" +checksum = "ce9453a41af5251f8439173d21b0ed2ae5d4a7c411abb76661806a44811a9d2c" dependencies = [ "base16ct", "der 0.8.0-rc.0", @@ -1130,9 +1130,9 @@ dependencies = [ [[package]] name = "serdect" -version = "0.3.0-pre.0" +version = "0.3.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "791ef964bfaba6be28a5c3f0c56836e17cb711ac009ca1074b9c735a3ebf240a" +checksum = "2a504c8ee181e3e594d84052f983d60afe023f4d94d050900be18062bbbf7b58" dependencies = [ "base16ct", "serde", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index bc86e607f..1c9b3e1bb 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -33,8 +33,8 @@ hkdf = { version = "=0.13.0-pre.4", optional = true, default-features = false } hex-literal = { version = "0.4", optional = true } pem-rfc7468 = { version = "1.0.0-rc.1", optional = true, features = ["alloc"] } pkcs8 = { version = "0.11.0-rc.1", optional = true, default-features = false } -sec1 = { version = "0.8.0-rc.1", optional = true, features = ["subtle", "zeroize"] } -serdect = { version = "=0.3.0-pre.0", optional = true, default-features = false, features = ["alloc"] } +sec1 = { version = "0.8.0-rc.2", optional = true, features = ["subtle", "zeroize"] } +serdect = { version = "=0.3.0-rc.0", optional = true, default-features = false, features = ["alloc"] } serde_json = { version = "1.0.121", optional = true, default-features = false, features = ["alloc"] } tap = { version = "1.0.1", optional = true, default-features = false } # hack for minimal-versions support for `bits` From 7dfeb9905f2fa01b4dc9710814468b4cdce39f76 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 20 Sep 2024 12:51:52 -0600 Subject: [PATCH 1228/1461] elliptic-curve v0.14.0-rc.1 (#1671) --- elliptic-curve/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 1c9b3e1bb..69dac9200 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.14.0-rc.0" +version = "0.14.0-rc.1" description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, From 181230a5527732a258cf97eb497c04728a032789 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Mon, 23 Sep 2024 20:12:17 +0300 Subject: [PATCH 1229/1461] aead: extract STREAM implementation into `aead-stream` (#1673) Sibling PR: https://github.com/RustCrypto/AEADs/pull/627 Closes #1665 --- .github/workflows/aead.yml | 1 - Cargo.lock | 2 +- aead/Cargo.toml | 1 - aead/src/lib.rs | 1 - aead/src/stream.rs | 238 +------------------------------------ 5 files changed, 5 insertions(+), 238 deletions(-) diff --git a/.github/workflows/aead.yml b/.github/workflows/aead.yml index 462108e7a..11f47906c 100644 --- a/.github/workflows/aead.yml +++ b/.github/workflows/aead.yml @@ -40,7 +40,6 @@ jobs: - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features bytes - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features heapless - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features rand_core - - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features stream # TODO(tarcieri): re-enable after next `crypto-common` release # minimal-versions: diff --git a/Cargo.lock b/Cargo.lock index cebf88f69..b348962b8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -496,7 +496,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.14.0-rc.0" +version = "0.14.0-rc.1" dependencies = [ "base16ct", "base64ct", diff --git a/aead/Cargo.toml b/aead/Cargo.toml index ab3b5e79d..3c9aa01d7 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -31,7 +31,6 @@ std = ["alloc", "crypto-common/std"] dev = ["blobby"] getrandom = ["crypto-common/getrandom"] rand_core = ["crypto-common/rand_core"] -stream = [] [package.metadata.docs.rs] all-features = true diff --git a/aead/src/lib.rs b/aead/src/lib.rs index 74ea85353..468b06762 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -22,7 +22,6 @@ extern crate std; #[cfg(feature = "dev")] pub mod dev; -#[cfg(feature = "stream")] pub mod stream; pub use crypto_common::{ diff --git a/aead/src/stream.rs b/aead/src/stream.rs index 7f735fb2a..5ee90c5f8 100644 --- a/aead/src/stream.rs +++ b/aead/src/stream.rs @@ -1,46 +1,17 @@ //! Streaming AEAD support. //! -//! Implementation of the STREAM online authenticated encryption construction -//! as described in the paper -//! [Online Authenticated-Encryption and its Nonce-Reuse Misuse-Resistance][1]. +//! See the [`aead-stream`] crate for a generic implementation of the STREAM construction. //! -//! ## About -//! -//! The STREAM construction supports encrypting/decrypting sequences of AEAD -//! message segments, which is useful in cases where the overall message is too -//! large to fit in a single buffer and needs to be processed incrementally. -//! -//! STREAM defends against reordering and truncation attacks which are common -//! in naive schemes which attempt to provide these properties, and is proven -//! to meet the security definition of "nonce-based online authenticated -//! encryption" (nOAE) as given in the aforementioned paper. -//! -//! ## Diagram -//! -//! ![STREAM Diagram](https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/img/AEADs/rogaway-stream.svg) -//! -//! Legend: -//! -//! - 𝐄k: AEAD encryption under key `k` -//! - 𝐌: message -//! - 𝐍: nonce -//! - 𝐀: additional associated data -//! - 𝐂: ciphertext -//! - 𝜏: MAC tag -//! -//! [1]: https://eprint.iacr.org/2015/189.pdf +//! [`aead-stream`]: https://docs.rs/aead-stream #![allow(clippy::upper_case_acronyms)] use crate::{AeadCore, AeadInPlace, Buffer, Error, Key, KeyInit, Result}; use core::ops::{AddAssign, Sub}; -use crypto_common::array::{ - typenum::{Unsigned, U4, U5}, - Array, ArraySize, -}; +use crypto_common::array::{Array, ArraySize}; #[cfg(feature = "alloc")] -use {crate::Payload, alloc::vec::Vec}; +use {crate::Payload, alloc::vec::Vec, crypto_common::array::typenum::Unsigned}; /// Nonce as used by a given AEAD construction and STREAM primitive. pub type Nonce = Array>; @@ -50,22 +21,6 @@ pub type Nonce = Array>; pub type NonceSize = <::NonceSize as Sub<>::NonceOverhead>>::Output; -/// STREAM encryptor instantiated with [`StreamBE32`] as the underlying -/// STREAM primitive. -pub type EncryptorBE32 = Encryptor>; - -/// STREAM decryptor instantiated with [`StreamBE32`] as the underlying -/// STREAM primitive. -pub type DecryptorBE32 = Decryptor>; - -/// STREAM encryptor instantiated with [`StreamLE31`] as the underlying -/// STREAM primitive. -pub type EncryptorLE31 = Encryptor>; - -/// STREAM decryptor instantiated with [`StreamLE31`] as the underlying -/// STREAM primitive. -pub type DecryptorLE31 = Decryptor>; - /// Create a new STREAM from the provided AEAD. pub trait NewStream: StreamPrimitive where @@ -354,188 +309,3 @@ impl_stream_object!( "decrypt", "𝒟 STREAM decryptor" ); - -/// The original "Rogaway-flavored" STREAM as described in the paper -/// [Online Authenticated-Encryption and its Nonce-Reuse Misuse-Resistance][1]. -/// -/// Uses a 32-bit big endian counter and 1-byte "last block" flag stored as -/// the last 5-bytes of the AEAD nonce. -/// -/// [1]: https://eprint.iacr.org/2015/189.pdf -#[derive(Debug)] -pub struct StreamBE32 -where - A: AeadInPlace, - A::NonceSize: Sub, - <::NonceSize as Sub>::Output: ArraySize, -{ - /// Underlying AEAD cipher - aead: A, - - /// Nonce (sans STREAM overhead) - nonce: Nonce, -} - -impl NewStream for StreamBE32 -where - A: AeadInPlace, - A::NonceSize: Sub, - <::NonceSize as Sub>::Output: ArraySize, -{ - fn from_aead(aead: A, nonce: &Nonce) -> Self { - Self { - aead, - nonce: nonce.clone(), - } - } -} - -impl StreamPrimitive for StreamBE32 -where - A: AeadInPlace, - A::NonceSize: Sub, - <::NonceSize as Sub>::Output: ArraySize, -{ - type NonceOverhead = U5; - type Counter = u32; - const COUNTER_INCR: u32 = 1; - const COUNTER_MAX: u32 = u32::MAX; - - fn encrypt_in_place( - &self, - position: u32, - last_block: bool, - associated_data: &[u8], - buffer: &mut dyn Buffer, - ) -> Result<()> { - let nonce = self.aead_nonce(position, last_block); - self.aead.encrypt_in_place(&nonce, associated_data, buffer) - } - - fn decrypt_in_place( - &self, - position: Self::Counter, - last_block: bool, - associated_data: &[u8], - buffer: &mut dyn Buffer, - ) -> Result<()> { - let nonce = self.aead_nonce(position, last_block); - self.aead.decrypt_in_place(&nonce, associated_data, buffer) - } -} - -impl StreamBE32 -where - A: AeadInPlace, - A::NonceSize: Sub, - <::NonceSize as Sub>::Output: ArraySize, -{ - /// Compute the full AEAD nonce including the STREAM counter and last - /// block flag. - fn aead_nonce(&self, position: u32, last_block: bool) -> crate::Nonce { - let mut result = Array::default(); - - // TODO(tarcieri): use `generic_array::sequence::Concat` (or const generics) - let (prefix, tail) = result.split_at_mut(NonceSize::::to_usize()); - prefix.copy_from_slice(&self.nonce); - - let (counter, flag) = tail.split_at_mut(4); - counter.copy_from_slice(&position.to_be_bytes()); - flag[0] = last_block as u8; - - result - } -} - -/// STREAM as instantiated with a 31-bit little endian counter and 1-bit -/// "last block" flag stored as the most significant bit of the counter -/// when interpreted as a 32-bit integer. -/// -/// The 31-bit + 1-bit value is stored as the last 4 bytes of the AEAD nonce. -#[derive(Debug)] -pub struct StreamLE31 -where - A: AeadInPlace, - A::NonceSize: Sub, - <::NonceSize as Sub>::Output: ArraySize, -{ - /// Underlying AEAD cipher - aead: A, - - /// Nonce (sans STREAM overhead) - nonce: Nonce, -} - -impl NewStream for StreamLE31 -where - A: AeadInPlace, - A::NonceSize: Sub, - <::NonceSize as Sub>::Output: ArraySize, -{ - fn from_aead(aead: A, nonce: &Nonce) -> Self { - Self { - aead, - nonce: nonce.clone(), - } - } -} - -impl StreamPrimitive for StreamLE31 -where - A: AeadInPlace, - A::NonceSize: Sub, - <::NonceSize as Sub>::Output: ArraySize, -{ - type NonceOverhead = U4; - type Counter = u32; - const COUNTER_INCR: u32 = 1; - const COUNTER_MAX: u32 = 0xfff_ffff; - - fn encrypt_in_place( - &self, - position: u32, - last_block: bool, - associated_data: &[u8], - buffer: &mut dyn Buffer, - ) -> Result<()> { - let nonce = self.aead_nonce(position, last_block)?; - self.aead.encrypt_in_place(&nonce, associated_data, buffer) - } - - fn decrypt_in_place( - &self, - position: Self::Counter, - last_block: bool, - associated_data: &[u8], - buffer: &mut dyn Buffer, - ) -> Result<()> { - let nonce = self.aead_nonce(position, last_block)?; - self.aead.decrypt_in_place(&nonce, associated_data, buffer) - } -} - -impl StreamLE31 -where - A: AeadInPlace, - A::NonceSize: Sub, - <::NonceSize as Sub>::Output: ArraySize, -{ - /// Compute the full AEAD nonce including the STREAM counter and last - /// block flag. - fn aead_nonce(&self, position: u32, last_block: bool) -> Result> { - if position > Self::COUNTER_MAX { - return Err(Error); - } - - let mut result = Array::default(); - - // TODO(tarcieri): use `generic_array::sequence::Concat` (or const generics) - let (prefix, tail) = result.split_at_mut(NonceSize::::to_usize()); - prefix.copy_from_slice(&self.nonce); - - let position_with_flag = position | ((last_block as u32) << 31); - tail.copy_from_slice(&position_with_flag.to_le_bytes()); - - Ok(result) - } -} From 9c7605ae9af2ce9fb1e63e3a07c23609dbf37571 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Fri, 27 Sep 2024 04:49:33 +0300 Subject: [PATCH 1230/1461] kem: fix Clippy lint (#1674) --- .github/workflows/workspace.yml | 2 +- kem/src/lib.rs | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index d67061ca5..f64f6bf99 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -24,7 +24,7 @@ jobs: - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: - toolchain: 1.79.0 + toolchain: 1.81.0 components: clippy - run: cargo clippy --all --all-features --tests -- -D warnings diff --git a/kem/src/lib.rs b/kem/src/lib.rs index 27dc0aa19..dc009d077 100644 --- a/kem/src/lib.rs +++ b/kem/src/lib.rs @@ -23,9 +23,10 @@ pub trait Encapsulate { fn encapsulate(&self, rng: &mut impl CryptoRngCore) -> Result<(EK, SS), Self::Error>; } -/// A value that can be used to decapsulate an encapsulated key. Often, this will just be a secret -/// key. But, as with [`Encapsulate`], it can be a bundle of secret keys, or it can include a -/// sender's private key for authenticated encapsulation. +/// A value that can be used to decapsulate an encapsulated key. +/// +/// Often, this will just be a secret key. But, as with [`Encapsulate`], it can be a bundle +/// of secret keys, or it can include a sender's private key for authenticated encapsulation. pub trait Decapsulate { /// Decapsulation error type Error: Debug; From badd347252b709af3f8042a380bd0c971bb78b6a Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Fri, 27 Sep 2024 18:33:07 +0300 Subject: [PATCH 1231/1461] elliptic-curve: add missing `Debug` impls (#1675) --- elliptic-curve/src/ecdh.rs | 14 +++++++++++++- .../src/hash2curve/hash2field/expand_msg.rs | 1 + .../src/hash2curve/hash2field/expand_msg/xmd.rs | 2 ++ .../src/hash2curve/hash2field/expand_msg/xof.rs | 13 +++++++++++++ elliptic-curve/src/hash2curve/isogeny.rs | 1 + elliptic-curve/src/hash2curve/osswu.rs | 1 + elliptic-curve/src/lib.rs | 1 + elliptic-curve/src/point/non_identity.rs | 2 +- elliptic-curve/src/scalar/blinded.rs | 7 +++++++ elliptic-curve/src/scalar/nonzero.rs | 6 ++++++ 10 files changed, 46 insertions(+), 2 deletions(-) diff --git a/elliptic-curve/src/ecdh.rs b/elliptic-curve/src/ecdh.rs index c64a696aa..243c61789 100644 --- a/elliptic-curve/src/ecdh.rs +++ b/elliptic-curve/src/ecdh.rs @@ -30,7 +30,7 @@ use crate::{ point::AffineCoordinates, AffinePoint, Curve, CurveArithmetic, FieldBytes, NonZeroScalar, ProjectivePoint, PublicKey, }; -use core::borrow::Borrow; +use core::{borrow::Borrow, fmt}; use digest::{crypto_common::BlockSizeUser, Digest}; use group::Curve as _; use hkdf::{hmac::SimpleHmac, Hkdf}; @@ -97,6 +97,12 @@ where scalar: NonZeroScalar, } +impl fmt::Debug for EphemeralSecret { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("EphemeralSecret").finish_non_exhaustive() + } +} + impl EphemeralSecret where C: CurveArithmetic, @@ -157,6 +163,12 @@ pub struct SharedSecret { secret_bytes: FieldBytes, } +impl fmt::Debug for SharedSecret { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("SharedSecret").finish_non_exhaustive() + } +} + impl SharedSecret { /// Create a new [`SharedSecret`] from an [`AffinePoint`] for this curve. #[inline] diff --git a/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs b/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs index 58d3c36e5..510ce5b2f 100644 --- a/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs +++ b/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs @@ -43,6 +43,7 @@ pub trait Expander { /// Implements [section 5.4.3 of `draft-irtf-cfrg-hash-to-curve-13`][dst]. /// /// [dst]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-13#section-5.4.3 +#[derive(Debug)] pub(crate) enum Domain<'a, L> where L: ArraySize + IsLess, diff --git a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs index 745e054da..4d397d4c2 100644 --- a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs +++ b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs @@ -20,6 +20,7 @@ use digest::{ /// - `len_in_bytes == 0` /// - `len_in_bytes > u16::MAX` /// - `len_in_bytes > 255 * HashT::OutputSize` +#[derive(Debug)] pub struct ExpandMsgXmd(PhantomData) where HashT: BlockSizeUser + Default + FixedOutput + HashMarker, @@ -87,6 +88,7 @@ where } /// [`Expander`] type for [`ExpandMsgXmd`]. +#[derive(Debug)] pub struct ExpanderXmd<'a, HashT> where HashT: BlockSizeUser + Default + FixedOutput + HashMarker, diff --git a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs index bf429071e..96eebe1e5 100644 --- a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs +++ b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs @@ -2,6 +2,7 @@ use super::{Domain, ExpandMsg, Expander}; use crate::{Error, Result}; +use core::fmt; use digest::{ExtendableOutput, Update, XofReader}; use hybrid_array::typenum::U32; @@ -18,6 +19,18 @@ where reader: ::Reader, } +impl fmt::Debug for ExpandMsgXof +where + HashT: Default + ExtendableOutput + Update, + ::Reader: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("ExpandMsgXof") + .field("reader", &self.reader) + .finish() + } +} + /// ExpandMsgXof implements `expand_message_xof` for the [`ExpandMsg`] trait impl<'a, HashT> ExpandMsg<'a> for ExpandMsgXof where diff --git a/elliptic-curve/src/hash2curve/isogeny.rs b/elliptic-curve/src/hash2curve/isogeny.rs index 6f49f427b..0d7e0853c 100644 --- a/elliptic-curve/src/hash2curve/isogeny.rs +++ b/elliptic-curve/src/hash2curve/isogeny.rs @@ -7,6 +7,7 @@ use ff::Field; use hybrid_array::{typenum::Unsigned, Array, ArraySize}; /// The coefficients for mapping from one isogenous curve to another +#[derive(Debug)] pub struct IsogenyCoefficients> { /// The coefficients for the x numerator pub xnum: &'static [F], diff --git a/elliptic-curve/src/hash2curve/osswu.rs b/elliptic-curve/src/hash2curve/osswu.rs index 3c3669ac3..dc5d16d57 100644 --- a/elliptic-curve/src/hash2curve/osswu.rs +++ b/elliptic-curve/src/hash2curve/osswu.rs @@ -8,6 +8,7 @@ use subtle::ConditionallySelectable; use subtle::ConstantTimeEq; /// The Optimized Simplified Shallue-van de Woestijne-Ulas parameters +#[derive(Debug)] pub struct OsswuMapParams where F: Field, diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 32ce2fa1a..d98bab692 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -18,6 +18,7 @@ clippy::panic, clippy::panic_in_result_fn, clippy::unwrap_used, + missing_debug_implementations, missing_docs, rust_2018_idioms, unused_lifetimes, diff --git a/elliptic-curve/src/point/non_identity.rs b/elliptic-curve/src/point/non_identity.rs index 436410d7c..a0f1e85ff 100644 --- a/elliptic-curve/src/point/non_identity.rs +++ b/elliptic-curve/src/point/non_identity.rs @@ -17,7 +17,7 @@ use crate::{CurveArithmetic, NonZeroScalar, Scalar}; /// /// In the context of ECC, it's useful for ensuring that certain arithmetic /// cannot result in the identity point. -#[derive(Clone, Copy)] +#[derive(Clone, Copy, Debug)] pub struct NonIdentity

{ point: P, } diff --git a/elliptic-curve/src/scalar/blinded.rs b/elliptic-curve/src/scalar/blinded.rs index 29cfea98c..914427f55 100644 --- a/elliptic-curve/src/scalar/blinded.rs +++ b/elliptic-curve/src/scalar/blinded.rs @@ -2,6 +2,7 @@ use super::Scalar; use crate::{ops::Invert, CurveArithmetic}; +use core::fmt; use group::ff::Field; use rand_core::CryptoRngCore; use subtle::CtOption; @@ -26,6 +27,12 @@ where mask: Scalar, } +impl fmt::Debug for BlindedScalar { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("BlindedScalar").finish_non_exhaustive() + } +} + impl BlindedScalar where C: CurveArithmetic, diff --git a/elliptic-curve/src/scalar/nonzero.rs b/elliptic-curve/src/scalar/nonzero.rs index dfcd2e776..9fd617e2a 100644 --- a/elliptic-curve/src/scalar/nonzero.rs +++ b/elliptic-curve/src/scalar/nonzero.rs @@ -36,6 +36,12 @@ where scalar: Scalar, } +impl fmt::Debug for NonZeroScalar { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("NonZeroScalar").finish_non_exhaustive() + } +} + impl NonZeroScalar where C: CurveArithmetic, From c7a7fa4d2b9c1ae38a522104b0255c7fb33c2a1b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 28 Sep 2024 11:21:22 -0600 Subject: [PATCH 1232/1461] build(deps): bump crypto-bigint from 0.6.0-rc.2 to 0.6.0-rc.5 (#1669) --- Cargo.lock | 6 +++--- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b348962b8..93b3481d8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -292,9 +292,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.6.0-rc.2" +version = "0.6.0-rc.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e43027691f1c055da3da4f7d96af09fcec420d435d5616e51f29afd0811c56a7" +checksum = "040a95c58773f47c92f5f17814702bfd68e8ace9ddce4690c982d0019cac32e2" dependencies = [ "hybrid-array", "num-traits", @@ -500,7 +500,7 @@ version = "0.14.0-rc.1" dependencies = [ "base16ct", "base64ct", - "crypto-bigint 0.6.0-rc.2", + "crypto-bigint 0.6.0-rc.5", "digest 0.11.0-pre.9", "ff 0.13.0", "group 0.13.0", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 69dac9200..77921cfb0 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -18,7 +18,7 @@ rust-version = "1.73" [dependencies] base16ct = "0.2" -crypto-bigint = { version = "0.6.0-rc.2", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } +crypto-bigint = { version = "0.6.0-rc.5", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } hybrid-array = { version = "0.2.0-rc.8", default-features = false, features = ["zeroize"] } rand_core = { version = "0.6.4", default-features = false } subtle = { version = "2.6", default-features = false } From 66ca1510e7a6ce66f2ccaabb17e469f3364bea8f Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 28 Sep 2024 11:21:40 -0600 Subject: [PATCH 1233/1461] crypto-common: use `core::error::Error` trait; MSRV 1.81 (#1660) The `core::error::Error` trait is now stable, meaning we no longer need to gate impls for it on a `std` feature. --- .github/workflows/crypto-common.yml | 12 ++++++------ crypto-common/Cargo.toml | 2 +- crypto-common/README.md | 4 ++-- crypto-common/src/hazmat.rs | 3 +-- crypto-common/src/lib.rs | 6 +----- 5 files changed, 11 insertions(+), 16 deletions(-) diff --git a/.github/workflows/crypto-common.yml b/.github/workflows/crypto-common.yml index efb87ad46..0f53a686b 100644 --- a/.github/workflows/crypto-common.yml +++ b/.github/workflows/crypto-common.yml @@ -2,9 +2,9 @@ name: crypto-common on: pull_request: - paths: - - "crypto-common/**" - - "Cargo.*" + paths: + - "crypto-common/**" + - "Cargo.*" push: branches: master @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.65.0 # MSRV + - 1.81.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -39,14 +39,14 @@ jobs: minimal-versions: uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master with: - working-directory: ${{ github.workflow }} + working-directory: ${{ github.workflow }} test: runs-on: ubuntu-latest strategy: matrix: rust: - - 1.65.0 # MSRV + - 1.81.0 # MSRV - stable steps: - uses: actions/checkout@v4 diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index 52be3f26b..a7ae02d8d 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -6,7 +6,7 @@ authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" edition = "2021" -rust-version = "1.65" +rust-version = "1.81" documentation = "https://docs.rs/crypto-common" repository = "https://github.com/RustCrypto/traits" keywords = ["crypto", "traits"] diff --git a/crypto-common/README.md b/crypto-common/README.md index 21008623a..2197b4091 100644 --- a/crypto-common/README.md +++ b/crypto-common/README.md @@ -14,7 +14,7 @@ higher-level trait crates instead of this one. ## Minimum Supported Rust Version -Rust **1.65** or higher. +Rust **1.81** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -46,7 +46,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/crypto-common/badge.svg [docs-link]: https://docs.rs/crypto-common/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.65+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.81+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260041-hashes [build-image]: https://github.com/RustCrypto/traits/workflows/crypto-common/badge.svg?branch=master&event=push diff --git a/crypto-common/src/hazmat.rs b/crypto-common/src/hazmat.rs index 735f485e2..22672bee5 100644 --- a/crypto-common/src/hazmat.rs +++ b/crypto-common/src/hazmat.rs @@ -24,8 +24,7 @@ impl fmt::Display for DeserializeStateError { } } -#[cfg(feature = "std")] -impl std::error::Error for DeserializeStateError {} +impl core::error::Error for DeserializeStateError {} /// Types which can serialize the internal state and be restored from it. /// diff --git a/crypto-common/src/lib.rs b/crypto-common/src/lib.rs index bd62fade1..7721b86f6 100644 --- a/crypto-common/src/lib.rs +++ b/crypto-common/src/lib.rs @@ -9,9 +9,6 @@ #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms, missing_debug_implementations)] -#[cfg(feature = "std")] -extern crate std; - /// Hazardous materials. pub mod hazmat; @@ -389,5 +386,4 @@ impl fmt::Display for InvalidLength { } } -#[cfg(feature = "std")] -impl std::error::Error for InvalidLength {} +impl core::error::Error for InvalidLength {} From 4284073f0454b9bb2fbbf0a408a1b9345a58e68d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 28 Sep 2024 12:11:22 -0600 Subject: [PATCH 1234/1461] MSRV 1.81 fixups (#1676) The MSRVs for dependent crates did not get bumped before #1660 was merged. This bumps them accordingly. --- .github/workflows/aead.yml | 4 ++-- .github/workflows/async-signature.yml | 3 +-- .github/workflows/cipher.yml | 4 ++-- .github/workflows/digest.yml | 10 +++++----- .github/workflows/elliptic-curve.yml | 4 ++-- .github/workflows/signature.yml | 10 ++++------ .github/workflows/universal-hash.yml | 4 ++-- Cargo.toml | 1 + aead/Cargo.toml | 2 +- aead/README.md | 4 ++-- cipher/Cargo.toml | 4 ++-- cipher/README.md | 4 ++-- digest/Cargo.toml | 2 +- digest/README.md | 4 ++-- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/README.md | 4 ++-- universal-hash/Cargo.toml | 2 +- universal-hash/README.md | 4 ++-- 18 files changed, 35 insertions(+), 37 deletions(-) diff --git a/.github/workflows/aead.yml b/.github/workflows/aead.yml index 11f47906c..dc3476c09 100644 --- a/.github/workflows/aead.yml +++ b/.github/workflows/aead.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.65.0 # MSRV + - 1.81.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -52,7 +52,7 @@ jobs: strategy: matrix: rust: - - 1.65.0 # MSRV + - 1.81.0 # MSRV - stable steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/async-signature.yml b/.github/workflows/async-signature.yml index 468c2028f..dbef8e7bf 100644 --- a/.github/workflows/async-signature.yml +++ b/.github/workflows/async-signature.yml @@ -42,7 +42,7 @@ jobs: strategy: matrix: rust: - - 1.75.0 # MSRV + - 1.81.0 # Minimum Rust version the tests pass on - stable steps: - uses: actions/checkout@v4 @@ -50,7 +50,6 @@ jobs: - uses: dtolnay/rust-toolchain@master with: toolchain: ${{ matrix.rust }} - - run: cargo check --all-features - run: cargo test --release - run: cargo test --all-features --release diff --git a/.github/workflows/cipher.yml b/.github/workflows/cipher.yml index aecc168a2..0c1d3d176 100644 --- a/.github/workflows/cipher.yml +++ b/.github/workflows/cipher.yml @@ -23,7 +23,7 @@ jobs: strategy: matrix: rust: - - 1.65.0 # MSRV + - 1.81.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -57,7 +57,7 @@ jobs: strategy: matrix: rust: - - 1.65.0 # MSRV + - 1.81.0 # MSRV - stable steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/digest.yml b/.github/workflows/digest.yml index be157840c..75a70b20a 100644 --- a/.github/workflows/digest.yml +++ b/.github/workflows/digest.yml @@ -2,9 +2,9 @@ name: digest on: pull_request: - paths: - - "digest/**" - - "Cargo.*" + paths: + - "digest/**" + - "Cargo.*" push: branches: master @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.71.0 # MSRV + - 1.81.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -47,7 +47,7 @@ jobs: strategy: matrix: rust: - - 1.71.0 # MSRV + - 1.81.0 # MSRV - stable steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index 6bbf9af4e..082155f07 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -24,7 +24,7 @@ jobs: strategy: matrix: rust: - - 1.73.0 # MSRV + - 1.81.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -75,7 +75,7 @@ jobs: strategy: matrix: rust: - - 1.73.0 # MSRV + - 1.81.0 # MSRV - stable - nightly steps: diff --git a/.github/workflows/signature.yml b/.github/workflows/signature.yml index fba9726b3..c2dfd14ab 100644 --- a/.github/workflows/signature.yml +++ b/.github/workflows/signature.yml @@ -38,9 +38,8 @@ jobs: targets: ${{ matrix.target }} - run: cargo build --target ${{ matrix.target }} --release --no-default-features - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features derive - - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features digest - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features rand_core - - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features derive,digest,rand_core + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features derive,rand_core minimal-versions: uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master @@ -52,7 +51,7 @@ jobs: strategy: matrix: rust: - - 1.72.0 # MSRV + - 1.81.0 # Minimum Rust version the tests pass on - stable steps: - uses: actions/checkout@v4 @@ -60,10 +59,9 @@ jobs: - uses: dtolnay/rust-toolchain@master with: toolchain: ${{ matrix.rust }} - - run: cargo check --all-features - - run: cargo test --no-default-features --release + - run: cargo test --release --no-default-features - run: cargo test --release - - run: cargo test --all-features --release + - run: cargo test --release --all-features derive: runs-on: ubuntu-latest diff --git a/.github/workflows/universal-hash.yml b/.github/workflows/universal-hash.yml index 76a17285f..25896c2e1 100644 --- a/.github/workflows/universal-hash.yml +++ b/.github/workflows/universal-hash.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.65.0 # MSRV + - 1.81.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -47,7 +47,7 @@ jobs: strategy: matrix: rust: - - 1.65.0 # MSRV + - 1.81.0 # MSRV - stable steps: - uses: actions/checkout@v4 diff --git a/Cargo.toml b/Cargo.toml index 2ca101fbc..354080ca9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,5 +16,6 @@ members = [ ] [patch.crates-io] +crypto-common = { path = "./crypto-common" } digest = { path = "./digest" } signature = { path = "./signature" } diff --git a/aead/Cargo.toml b/aead/Cargo.toml index 3c9aa01d7..f6cccaeaa 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -13,7 +13,7 @@ documentation = "https://docs.rs/aead" repository = "https://github.com/RustCrypto/traits" keywords = ["crypto", "encryption"] categories = ["cryptography", "no-std"] -rust-version = "1.65" +rust-version = "1.81" [dependencies] crypto-common = "0.2.0-rc.0" diff --git a/aead/README.md b/aead/README.md index b481f9c37..0a0dd045a 100644 --- a/aead/README.md +++ b/aead/README.md @@ -19,7 +19,7 @@ See [RustCrypto/AEADs] for cipher implementations which use this trait. ## Minimum Supported Rust Version -Rust **1.65** or higher. +Rust **1.81** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -51,7 +51,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/aead/badge.svg [docs-link]: https://docs.rs/aead/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.65+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.81+-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/traits/workflows/aead/badge.svg?branch=master&event=push diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index 1125a68b4..26fde3abf 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -6,14 +6,14 @@ authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" edition = "2021" -rust-version = "1.65" +rust-version = "1.81" documentation = "https://docs.rs/cipher" repository = "https://github.com/RustCrypto/traits" keywords = ["crypto", "block-cipher", "stream-cipher", "trait"] categories = ["cryptography", "no-std"] [dependencies] -crypto-common = { version = "0.2.0-rc.1", path = "../crypto-common/" } +crypto-common = "0.2.0-rc.1" inout = "0.2.0-rc.0" # optional dependencies diff --git a/cipher/README.md b/cipher/README.md index 716973c1c..350be54bd 100644 --- a/cipher/README.md +++ b/cipher/README.md @@ -16,7 +16,7 @@ implementations which use these traits. ## Minimum Supported Rust Version -Rust **1.65** or higher. +Rust **1.81** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -48,7 +48,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/cipher/badge.svg [docs-link]: https://docs.rs/cipher/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.65+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.81+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260050-traits [build-image]: https://github.com/RustCrypto/traits/workflows/cipher/badge.svg?branch=master&event=push diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 8f44c7d0a..8493bf4ac 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -6,7 +6,7 @@ authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" edition = "2021" -rust-version = "1.71" +rust-version = "1.81" documentation = "https://docs.rs/digest" repository = "https://github.com/RustCrypto/traits" keywords = ["digest", "crypto", "hash"] diff --git a/digest/README.md b/digest/README.md index da44f69e4..dc527f713 100644 --- a/digest/README.md +++ b/digest/README.md @@ -16,7 +16,7 @@ See [RustCrypto/hashes][1] for implementations which use this trait. ## Minimum Supported Rust Version -Rust **1.71** or higher. +Rust **1.81** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -147,7 +147,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/digest/badge.svg [docs-link]: https://docs.rs/digest/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.71+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.81+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260041-hashes [build-image]: https://github.com/RustCrypto/traits/workflows/digest/badge.svg?branch=master&event=push diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 77921cfb0..32c327711 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -14,7 +14,7 @@ readme = "README.md" categories = ["cryptography", "no-std"] keywords = ["crypto", "ecc", "elliptic", "weierstrass"] edition = "2021" -rust-version = "1.73" +rust-version = "1.81" [dependencies] base16ct = "0.2" diff --git a/elliptic-curve/README.md b/elliptic-curve/README.md index e2c383f22..0c8fad474 100644 --- a/elliptic-curve/README.md +++ b/elliptic-curve/README.md @@ -15,7 +15,7 @@ and public/secret keys composed thereof. ## Minimum Supported Rust Version -Requires Rust **1.73** or higher. +Requires Rust **1.81** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -49,6 +49,6 @@ dual licensed as above, without any additional terms or conditions. [build-image]: https://github.com/RustCrypto/traits/actions/workflows/elliptic-curve.yml/badge.svg [build-link]: https://github.com/RustCrypto/traits/actions/workflows/elliptic-curve.yml [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.73+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.81+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260040-elliptic-curves diff --git a/universal-hash/Cargo.toml b/universal-hash/Cargo.toml index d98e8dd91..d330e0679 100644 --- a/universal-hash/Cargo.toml +++ b/universal-hash/Cargo.toml @@ -5,7 +5,7 @@ description = "Traits which describe the functionality of universal hash functio authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" edition = "2021" -rust-version = "1.65" +rust-version = "1.81" readme = "README.md" documentation = "https://docs.rs/universal-hash" repository = "https://github.com/RustCrypto/traits" diff --git a/universal-hash/README.md b/universal-hash/README.md index 3bc9d0977..beaa9e58a 100644 --- a/universal-hash/README.md +++ b/universal-hash/README.md @@ -15,7 +15,7 @@ See [RustCrypto/universal-hashes] for implementations which use this trait. ## Minimum Supported Rust Version -Rust **1.65** or higher. +Rust **1.81** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -47,7 +47,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/universal-hash/badge.svg [docs-link]: https://docs.rs/universal-hash/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.65+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.81+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260051-universal-hashes [build-image]: https://github.com/RustCrypto/traits/workflows/universal-hash/badge.svg?branch=master&event=push From f5de69791160bc2e6518f5d722b4a52bb7f681b9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 28 Sep 2024 12:11:49 -0600 Subject: [PATCH 1235/1461] build(deps): bump arrayvec from 0.7.4 to 0.7.6 (#1651) --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 93b3481d8..d7017df1b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -50,9 +50,9 @@ dependencies = [ [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "async-signature" From e19d4bed9dc152828a8527966fed61533bf1f5d1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 28 Sep 2024 12:24:13 -0600 Subject: [PATCH 1236/1461] build(deps): bump hybrid-array from 0.2.0-rc.9 to 0.2.0-rc.10 (#1667) --- Cargo.lock | 23 ++++++----------------- crypto-common/Cargo.toml | 2 +- elliptic-curve/Cargo.toml | 2 +- 3 files changed, 8 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d7017df1b..b686cb1b0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,7 +19,7 @@ dependencies = [ "arrayvec", "blobby", "bytes", - "crypto-common 0.2.0-rc.0", + "crypto-common 0.2.0-rc.1", "heapless", ] @@ -130,7 +130,7 @@ version = "0.11.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17092d478f4fadfb35a7e082f62e49f0907fdf048801d9d706277e34f9df8a78" dependencies = [ - "crypto-common 0.2.0-rc.0", + "crypto-common 0.2.0-rc.1", "zeroize", ] @@ -314,17 +314,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "crypto-common" -version = "0.2.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c070b79a496dccd931229780ad5bbedd535ceff6c3565605a8e440e18e1aa2b" -dependencies = [ - "getrandom", - "hybrid-array", - "rand_core", -] - [[package]] name = "crypto-common" version = "0.2.0-rc.1" @@ -435,7 +424,7 @@ dependencies = [ "blobby", "block-buffer 0.11.0-rc.0", "const-oid 0.10.0-rc.0", - "crypto-common 0.2.0-rc.0", + "crypto-common 0.2.0-rc.1", "subtle", "zeroize", ] @@ -717,9 +706,9 @@ dependencies = [ [[package]] name = "hybrid-array" -version = "0.2.0-rc.9" +version = "0.2.0-rc.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d306b679262030ad8813a82d4915fc04efff97776e4db7f8eb5137039d56400" +checksum = "bae36f8710514b3e7aab028021733330de6e455e0352e19c6dd4513eecb7aa9a" dependencies = [ "typenum", "zeroize", @@ -1306,7 +1295,7 @@ dependencies = [ name = "universal-hash" version = "0.6.0-rc.0" dependencies = [ - "crypto-common 0.2.0-rc.0", + "crypto-common 0.2.0-rc.1", "subtle", ] diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index a7ae02d8d..8eddb6f91 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -13,7 +13,7 @@ keywords = ["crypto", "traits"] categories = ["cryptography", "no-std"] [dependencies] -hybrid-array = "0.2.0-rc.8" +hybrid-array = "0.2.0-rc.10" # optional dependencies rand_core = { version = "0.6.4", optional = true } diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 32c327711..a5c2091f7 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -19,7 +19,7 @@ rust-version = "1.81" [dependencies] base16ct = "0.2" crypto-bigint = { version = "0.6.0-rc.5", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } -hybrid-array = { version = "0.2.0-rc.8", default-features = false, features = ["zeroize"] } +hybrid-array = { version = "0.2.0-rc.10", default-features = false, features = ["zeroize"] } rand_core = { version = "0.6.4", default-features = false } subtle = { version = "2.6", default-features = false } zeroize = { version = "1.7", default-features = false } From a981f42932b8cfdf7c47f65bdb2e7c9862975143 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 30 Sep 2024 13:09:26 -0600 Subject: [PATCH 1237/1461] digest: bump `block-buffer` to v0.11.0-rc.2 (#1678) Notably this version drops the `crypto-common` dependency --- Cargo.lock | 8 ++++---- digest/Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b686cb1b0..098e8ba41 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -126,11 +126,11 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.11.0-rc.0" +version = "0.11.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17092d478f4fadfb35a7e082f62e49f0907fdf048801d9d706277e34f9df8a78" +checksum = "939c0e62efa052fb0b2db2c0f7c479ad32e364c192c3aab605a7641de265a1a7" dependencies = [ - "crypto-common 0.2.0-rc.1", + "hybrid-array", "zeroize", ] @@ -422,7 +422,7 @@ name = "digest" version = "0.11.0-pre.9" dependencies = [ "blobby", - "block-buffer 0.11.0-rc.0", + "block-buffer 0.11.0-rc.2", "const-oid 0.10.0-rc.0", "crypto-common 0.2.0-rc.1", "subtle", diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 8493bf4ac..32a221b78 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -16,7 +16,7 @@ categories = ["cryptography", "no-std"] crypto-common = "0.2.0-rc.0" # optional dependencies -block-buffer = { version = "0.11.0-rc.0", optional = true } +block-buffer = { version = "0.11.0-rc.2", optional = true } subtle = { version = "2.4", default-features = false, optional = true } blobby = { version = "0.3", optional = true } const-oid = { version = "0.10.0-rc.0", optional = true } From 78662ae561cd5598dfdb21602bfb8ac03cceb9be Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 30 Sep 2024 13:13:15 -0600 Subject: [PATCH 1238/1461] cipher: bump `inout` to v0.2.0-rc.1 (#1679) Notably this version removes the `std` feature, a breaking change from the previous `rc.0` --- Cargo.lock | 12 ++++++------ cipher/Cargo.toml | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 098e8ba41..85cf8c3de 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -145,9 +145,9 @@ dependencies = [ [[package]] name = "block-padding" -version = "0.4.0-rc.0" +version = "0.4.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d7992d59cd95a984bde8833d4d025886eec3718777971ad15c58df0b070254a" +checksum = "8cac2491ec009b98aa75f36cca2b50e3da7d212918fe953886f6a319042f6016" dependencies = [ "hybrid-array", ] @@ -221,7 +221,7 @@ version = "0.5.0-pre.7" dependencies = [ "blobby", "crypto-common 0.2.0-rc.1", - "inout 0.2.0-rc.0", + "inout 0.2.0-rc.1", "zeroize", ] @@ -726,11 +726,11 @@ dependencies = [ [[package]] name = "inout" -version = "0.2.0-rc.0" +version = "0.2.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbc33218cf9ce7b927426ee4ad3501bcc5d8c26bf5fb4a82849a083715aca427" +checksum = "161ac07241f4d11c21b6d82f1fef1c05aec030c0bf568b35281efe453ea450a7" dependencies = [ - "block-padding 0.4.0-rc.0", + "block-padding 0.4.0-rc.1", "hybrid-array", ] diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index 26fde3abf..0afe98fb0 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -14,7 +14,7 @@ categories = ["cryptography", "no-std"] [dependencies] crypto-common = "0.2.0-rc.1" -inout = "0.2.0-rc.0" +inout = "0.2.0-rc.1" # optional dependencies blobby = { version = "0.3", optional = true } @@ -22,7 +22,7 @@ zeroize = { version = "1.8", optional = true, default-features = false } [features] alloc = [] -std = ["alloc", "crypto-common/std", "inout/std"] +std = ["alloc", "crypto-common/std"] block-padding = ["inout/block-padding"] # Enable random key and IV generation methods rand_core = ["crypto-common/rand_core"] From 7bc0952e0b7310eb2949fb8b53ce16e5ff917820 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 30 Sep 2024 13:28:51 -0600 Subject: [PATCH 1239/1461] CI: fix workspace doc build (#1681) The `crypto` crate is linking old versions of the trait crates, and that's causing collisions when building the workspace rustdoc: warning: output filename collision. The lib target `aead` in package `aead v0.6.0-rc.0 (/Users/tony/src/RustCrypto/traits/aead)` has the same output filename as the lib target `aead` in package `aead v0.5.2`. Colliding filename is: /Users/tony/src/RustCrypto/traits/target/doc/aead/index.html The targets should have unique names. This is a known bug where multiple crates with the same name use the same path; see . warning: output filename collision. The lib target `cipher` in package `cipher v0.5.0-pre.7 (/Users/tony/src/RustCrypto/traits/cipher)` has the same output filename as the lib target `cipher` in package `cipher v0.4.4`. Colliding filename is: /Users/tony/src/RustCrypto/traits/target/doc/cipher/index.html The targets should have unique names. This is a known bug where multiple crates with the same name use the same path; see . This changes the CI config to exclude it from the rustdoc build for now, since everything else is on a prerelease series. We should probably bump `crypto` to link the latest prereleases soon, but for now this gets CI green again. --- .github/workflows/workspace.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index f64f6bf99..882d1d4c4 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -35,7 +35,8 @@ jobs: - uses: dtolnay/rust-toolchain@master with: toolchain: stable - - run: cargo doc --all-features + # TODO(tarcieri): remove `--exclude crypto` after new release series + - run: cargo doc --workspace --all-features --no-deps --exclude crypto rustfmt: runs-on: ubuntu-latest From 60779902cd5d8366ccaf79fc388e6aa93d042cea Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 30 Sep 2024 13:55:47 -0600 Subject: [PATCH 1240/1461] crypto-common: remove `std` feature (#1680) As of #1660, the `crypto-common` crate stopped linking `std` entirely by switching to `core::error::Error`. That PR didn't remove the `std` feature however, which was retained to transitively activate the `std` features of `getrandom` and `rand_core` optioinally in the event their corresponding features are enabled. This PR goes ahead and removes it entirely, which also unblocks being able to remove the `std` feature from other crates like `aead`, `cipher`, `digest`, and `universal-hash`. --- .github/workflows/crypto-common.yml | 1 - aead/Cargo.toml | 2 +- cipher/Cargo.toml | 2 +- crypto-common/Cargo.toml | 1 - digest/Cargo.toml | 2 +- universal-hash/Cargo.toml | 2 +- 6 files changed, 4 insertions(+), 6 deletions(-) diff --git a/.github/workflows/crypto-common.yml b/.github/workflows/crypto-common.yml index 0f53a686b..3c4e4edf7 100644 --- a/.github/workflows/crypto-common.yml +++ b/.github/workflows/crypto-common.yml @@ -56,5 +56,4 @@ jobs: toolchain: ${{ matrix.rust }} - run: cargo check --all-features - run: cargo test - - run: cargo test --features std - run: cargo test --all-features diff --git a/aead/Cargo.toml b/aead/Cargo.toml index f6cccaeaa..b0a7bc25b 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -27,7 +27,7 @@ heapless = { version = "0.8", optional = true, default-features = false } [features] default = ["rand_core"] alloc = [] -std = ["alloc", "crypto-common/std"] +std = ["alloc"] dev = ["blobby"] getrandom = ["crypto-common/getrandom"] rand_core = ["crypto-common/rand_core"] diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index 0afe98fb0..c0a87c0d4 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -22,7 +22,7 @@ zeroize = { version = "1.8", optional = true, default-features = false } [features] alloc = [] -std = ["alloc", "crypto-common/std"] +std = ["alloc"] block-padding = ["inout/block-padding"] # Enable random key and IV generation methods rand_core = ["crypto-common/rand_core"] diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index 8eddb6f91..908c4c8d2 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -21,7 +21,6 @@ getrandom = { version = "0.2", optional = true } [features] getrandom = ["dep:getrandom", "rand_core?/getrandom"] -std = ["getrandom?/std", "rand_core?/std"] [package.metadata.docs.rs] all-features = true diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 32a221b78..c0e219fda 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -30,7 +30,7 @@ rand_core = ["crypto-common/rand_core"] # Enable random key generation methods oid = ["const-oid"] zeroize = ["dep:zeroize", "block-buffer?/zeroize"] alloc = [] -std = ["alloc", "crypto-common/std"] +std = ["alloc"] dev = ["blobby"] [package.metadata.docs.rs] diff --git a/universal-hash/Cargo.toml b/universal-hash/Cargo.toml index d330e0679..2b0042572 100644 --- a/universal-hash/Cargo.toml +++ b/universal-hash/Cargo.toml @@ -17,7 +17,7 @@ crypto-common = "0.2.0-rc.0" subtle = { version = "2.4", default-features = false } [features] -std = ["crypto-common/std"] +std = [] [package.metadata.docs.rs] all-features = true From 6c467620dc51fb648d28fcd267b3459c9f1efcef Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Sep 2024 17:47:21 -0600 Subject: [PATCH 1241/1461] build(deps): bump hybrid-array from 0.2.0-rc.10 to 0.2.0-rc.11 (#1682) --- Cargo.lock | 4 ++-- crypto-common/Cargo.toml | 2 +- elliptic-curve/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 85cf8c3de..5675aa4f8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -706,9 +706,9 @@ dependencies = [ [[package]] name = "hybrid-array" -version = "0.2.0-rc.10" +version = "0.2.0-rc.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bae36f8710514b3e7aab028021733330de6e455e0352e19c6dd4513eecb7aa9a" +checksum = "a5a41e5b0754cae5aaf7915f1df1147ba8d316fc6e019cfcc00fbaba96d5e030" dependencies = [ "typenum", "zeroize", diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index 908c4c8d2..958e26fb7 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -13,7 +13,7 @@ keywords = ["crypto", "traits"] categories = ["cryptography", "no-std"] [dependencies] -hybrid-array = "0.2.0-rc.10" +hybrid-array = "0.2.0-rc.11" # optional dependencies rand_core = { version = "0.6.4", optional = true } diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index a5c2091f7..c62533707 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -19,7 +19,7 @@ rust-version = "1.81" [dependencies] base16ct = "0.2" crypto-bigint = { version = "0.6.0-rc.5", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } -hybrid-array = { version = "0.2.0-rc.10", default-features = false, features = ["zeroize"] } +hybrid-array = { version = "0.2.0-rc.11", default-features = false, features = ["zeroize"] } rand_core = { version = "0.6.4", default-features = false } subtle = { version = "2.6", default-features = false } zeroize = { version = "1.7", default-features = false } From f4176fc74b47ca2dcdc9476a0d4a1b26e1c5b31b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 6 Oct 2024 16:39:34 -0600 Subject: [PATCH 1242/1461] build(deps): bump const-oid from 0.10.0-rc.0 to 0.10.0-rc.1 (#1684) Bumps [const-oid](https://github.com/RustCrypto/formats) from 0.10.0-rc.0 to 0.10.0-rc.1.

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=const-oid&package-manager=cargo&previous-version=0.10.0-rc.0&new-version=0.10.0-rc.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- digest/Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5675aa4f8..2e746536b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -239,9 +239,9 @@ checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "const-oid" -version = "0.10.0-rc.0" +version = "0.10.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9adcf94f05e094fca3005698822ec791cb4433ced416afda1c5ca3b8dfc05a2f" +checksum = "610947c93f422f713d1ed0570e7c76307aa3bbfd8db723214fed2045a2e32815" [[package]] name = "cpufeatures" @@ -392,7 +392,7 @@ version = "0.8.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05d9c07d3bd80cf0935ce478d07edf7e7a5b158446757f988f3e62082227b700" dependencies = [ - "const-oid 0.10.0-rc.0", + "const-oid 0.10.0-rc.1", "pem-rfc7468 1.0.0-rc.1", "zeroize", ] @@ -423,7 +423,7 @@ version = "0.11.0-pre.9" dependencies = [ "blobby", "block-buffer 0.11.0-rc.2", - "const-oid 0.10.0-rc.0", + "const-oid 0.10.0-rc.1", "crypto-common 0.2.0-rc.1", "subtle", "zeroize", diff --git a/digest/Cargo.toml b/digest/Cargo.toml index c0e219fda..9b14a3694 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -19,7 +19,7 @@ crypto-common = "0.2.0-rc.0" block-buffer = { version = "0.11.0-rc.2", optional = true } subtle = { version = "2.4", default-features = false, optional = true } blobby = { version = "0.3", optional = true } -const-oid = { version = "0.10.0-rc.0", optional = true } +const-oid = { version = "0.10.0-rc.1", optional = true } zeroize = { version = "1.7", optional = true, default-features = false } [features] From 3fc6dd975105c60ba0636be514d7ab11ea4255d9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 16:36:13 -0600 Subject: [PATCH 1243/1461] build(deps): bump crypto-bigint from 0.6.0-rc.5 to 0.6.0-rc.6 (#1687) --- Cargo.lock | 6 +++--- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2e746536b..3dbc0a20f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -292,9 +292,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.6.0-rc.5" +version = "0.6.0-rc.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "040a95c58773f47c92f5f17814702bfd68e8ace9ddce4690c982d0019cac32e2" +checksum = "d748d1f5b807ee6d0df5a548d0130417295c3aaed1dcbbb3d6a2e7106e11fcca" dependencies = [ "hybrid-array", "num-traits", @@ -489,7 +489,7 @@ version = "0.14.0-rc.1" dependencies = [ "base16ct", "base64ct", - "crypto-bigint 0.6.0-rc.5", + "crypto-bigint 0.6.0-rc.6", "digest 0.11.0-pre.9", "ff 0.13.0", "group 0.13.0", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index c62533707..e622ddf3a 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -18,7 +18,7 @@ rust-version = "1.81" [dependencies] base16ct = "0.2" -crypto-bigint = { version = "0.6.0-rc.5", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } +crypto-bigint = { version = "0.6.0-rc.6", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } hybrid-array = { version = "0.2.0-rc.11", default-features = false, features = ["zeroize"] } rand_core = { version = "0.6.4", default-features = false } subtle = { version = "2.6", default-features = false } From 667a5e0be41e7c1d59de26af66cd6d9e9cfe42ea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 16:36:24 -0600 Subject: [PATCH 1244/1461] build(deps): bump const-oid from 0.10.0-rc.1 to 0.10.0-rc.2 (#1688) --- Cargo.lock | 8 ++++---- digest/Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3dbc0a20f..cf912c331 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -239,9 +239,9 @@ checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "const-oid" -version = "0.10.0-rc.1" +version = "0.10.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "610947c93f422f713d1ed0570e7c76307aa3bbfd8db723214fed2045a2e32815" +checksum = "6a0d96d207edbe5135e55038e79ab9ad6d75ba83b14cdf62326ce5b12bc46ab5" [[package]] name = "cpufeatures" @@ -392,7 +392,7 @@ version = "0.8.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05d9c07d3bd80cf0935ce478d07edf7e7a5b158446757f988f3e62082227b700" dependencies = [ - "const-oid 0.10.0-rc.1", + "const-oid 0.10.0-rc.2", "pem-rfc7468 1.0.0-rc.1", "zeroize", ] @@ -423,7 +423,7 @@ version = "0.11.0-pre.9" dependencies = [ "blobby", "block-buffer 0.11.0-rc.2", - "const-oid 0.10.0-rc.1", + "const-oid 0.10.0-rc.2", "crypto-common 0.2.0-rc.1", "subtle", "zeroize", diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 9b14a3694..4f7c35910 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -19,7 +19,7 @@ crypto-common = "0.2.0-rc.0" block-buffer = { version = "0.11.0-rc.2", optional = true } subtle = { version = "2.4", default-features = false, optional = true } blobby = { version = "0.3", optional = true } -const-oid = { version = "0.10.0-rc.1", optional = true } +const-oid = { version = "0.10.0-rc.2", optional = true } zeroize = { version = "1.7", optional = true, default-features = false } [features] From 5acedcdc2ea6fc629822d465c92df84caa7b0398 Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Mon, 7 Oct 2024 18:08:37 -0700 Subject: [PATCH 1245/1461] Remove signature error source from display message (#1689) Since errors returned by `std::error::Error::source()` are commonly printed separately, this avoids double-printing the source error message. Fixes #1685. --- signature/src/error.rs | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/signature/src/error.rs b/signature/src/error.rs index 6518f17b8..7d716a1de 100644 --- a/signature/src/error.rs +++ b/signature/src/error.rs @@ -73,16 +73,7 @@ impl Debug for Error { impl Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str("signature error")?; - - #[cfg(feature = "std")] - { - if let Some(source) = &self.source { - write!(f, ": {}", source)?; - } - } - - Ok(()) + f.write_str("signature error") } } From 60f5e98001af8fb922cca48cb27438f701357328 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 8 Oct 2024 14:44:31 -0600 Subject: [PATCH 1246/1461] cipher: use `core::error`; remove `std` feature (#1691) Switches from `std::error::Error` to `core::error::Error` which was stabilized in Rust 1.81, which is already the `cipher` crate's current MSRV. Since this was the only usage of `std`, also removes the `std` feature. --- .github/workflows/cipher.yml | 1 - cipher/Cargo.toml | 1 - cipher/src/lib.rs | 2 -- cipher/src/stream/errors.rs | 6 ++---- 4 files changed, 2 insertions(+), 8 deletions(-) diff --git a/.github/workflows/cipher.yml b/.github/workflows/cipher.yml index 0c1d3d176..28e2eb6bf 100644 --- a/.github/workflows/cipher.yml +++ b/.github/workflows/cipher.yml @@ -69,5 +69,4 @@ jobs: - run: cargo test - run: cargo test --features block-padding - run: cargo test --features dev - - run: cargo test --features std - run: cargo test --all-features diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index c0a87c0d4..95c239f7a 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -22,7 +22,6 @@ zeroize = { version = "1.8", optional = true, default-features = false } [features] alloc = [] -std = ["alloc"] block-padding = ["inout/block-padding"] # Enable random key and IV generation methods rand_core = ["crypto-common/rand_core"] diff --git a/cipher/src/lib.rs b/cipher/src/lib.rs index 1c7ae89ee..7e34bba0c 100644 --- a/cipher/src/lib.rs +++ b/cipher/src/lib.rs @@ -20,8 +20,6 @@ #[cfg(all(feature = "block-padding", feature = "alloc"))] extern crate alloc; -#[cfg(feature = "std")] -extern crate std; #[cfg(feature = "dev")] pub use blobby; diff --git a/cipher/src/stream/errors.rs b/cipher/src/stream/errors.rs index acd2f488a..e30576da6 100644 --- a/cipher/src/stream/errors.rs +++ b/cipher/src/stream/errors.rs @@ -17,8 +17,7 @@ impl fmt::Display for StreamCipherError { } } -#[cfg(feature = "std")] -impl std::error::Error for StreamCipherError {} +impl core::error::Error for StreamCipherError {} /// The error type returned when a cipher position can not be represented /// by the requested type. @@ -37,5 +36,4 @@ impl From for StreamCipherError { } } -#[cfg(feature = "std")] -impl std::error::Error for OverflowError {} +impl core::error::Error for OverflowError {} From e78de7510753b34830cbaee43efafbd53b8f6242 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 8 Oct 2024 15:55:02 -0600 Subject: [PATCH 1247/1461] aead: use `core::error`; remove `std` feature (#1692) Switches from `std::error::Error` to `core::error::Error` which was stabilized in Rust 1.81, which is already the `aead` crate's current MSRV. Since this was the only usage of `std`, also removes the `std` feature. --- aead/Cargo.toml | 1 - aead/src/lib.rs | 6 +----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/aead/Cargo.toml b/aead/Cargo.toml index b0a7bc25b..9cfaa2ff9 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -27,7 +27,6 @@ heapless = { version = "0.8", optional = true, default-features = false } [features] default = ["rand_core"] alloc = [] -std = ["alloc"] dev = ["blobby"] getrandom = ["crypto-common/getrandom"] rand_core = ["crypto-common/rand_core"] diff --git a/aead/src/lib.rs b/aead/src/lib.rs index 468b06762..63be73a7d 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -16,9 +16,6 @@ #[cfg(feature = "alloc")] extern crate alloc; -#[cfg(feature = "std")] -extern crate std; - #[cfg(feature = "dev")] pub mod dev; @@ -69,8 +66,7 @@ impl fmt::Display for Error { } } -#[cfg(feature = "std")] -impl std::error::Error for Error {} +impl core::error::Error for Error {} /// Nonce: single-use value for ensuring ciphertexts are unique pub type Nonce = Array::NonceSize>; From e0a048617e03ea592469ebfe7a5c448134736884 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Wed, 9 Oct 2024 15:55:38 +0300 Subject: [PATCH 1248/1461] Add compatibility section to the `SerializableState` docs (#1694) --- crypto-common/src/hazmat.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/crypto-common/src/hazmat.rs b/crypto-common/src/hazmat.rs index 22672bee5..b8df738aa 100644 --- a/crypto-common/src/hazmat.rs +++ b/crypto-common/src/hazmat.rs @@ -28,6 +28,16 @@ impl core::error::Error for DeserializeStateError {} /// Types which can serialize the internal state and be restored from it. /// +/// # Compatibility +/// +/// Serialized state can be assumed to be stable across backwards compatible +/// versions of an implementation crate, i.e. any `0.x.y` version of a crate +/// should be able to decode data serialized with any other `0.x.z` version, +/// but it may not be able to correctly decode data serialized with a non-`x` +/// version. +/// +/// This guarantee is a subject to issues such as security fixes. +/// /// # SECURITY WARNING /// /// Serialized state may contain sensitive data. From 70f66b00813c23ee40ed5b345d06e1bbab7f1262 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 12 Oct 2024 08:19:50 -0600 Subject: [PATCH 1249/1461] CI: bump `cargo-audit` to v0.20 (#1695) --- .github/workflows/security-audit.yml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/.github/workflows/security-audit.yml b/.github/workflows/security-audit.yml index 6eaf0e52b..154937a18 100644 --- a/.github/workflows/security-audit.yml +++ b/.github/workflows/security-audit.yml @@ -1,7 +1,9 @@ name: Security Audit on: pull_request: - paths: '**/Cargo.lock' + paths: + - .github/workflows/security-audit.yml + - '**/Cargo.lock' push: branches: master paths: '**/Cargo.lock' @@ -18,7 +20,7 @@ jobs: uses: actions/cache@v4 with: path: ~/.cargo/bin - key: ${{ runner.os }}-cargo-audit-v0.12.0 + key: ${{ runner.os }}-cargo-audit-v0.20 - uses: actions-rs/audit-check@v1 with: token: ${{ secrets.GITHUB_TOKEN }} @@ -35,7 +37,7 @@ jobs: uses: actions/cache@v4 with: path: ~/.cargo/bin - key: ${{ runner.os }}-cargo-audit-v0.12.0 + key: ${{ runner.os }}-cargo-audit-v0.20 - uses: actions-rs/audit-check@v1 with: token: ${{ secrets.GITHUB_TOKEN }} @@ -52,7 +54,7 @@ jobs: uses: actions/cache@v4 with: path: ~/.cargo/bin - key: ${{ runner.os }}-cargo-audit-v0.12.0 + key: ${{ runner.os }}-cargo-audit-v0.20 - uses: actions-rs/audit-check@v1 with: token: ${{ secrets.GITHUB_TOKEN }} @@ -69,7 +71,7 @@ jobs: uses: actions/cache@v4 with: path: ~/.cargo/bin - key: ${{ runner.os }}-cargo-audit-v0.12.0 + key: ${{ runner.os }}-cargo-audit-v0.20 - uses: actions-rs/audit-check@v1 with: token: ${{ secrets.GITHUB_TOKEN }} @@ -86,7 +88,7 @@ jobs: uses: actions/cache@v4 with: path: ~/.cargo/bin - key: ${{ runner.os }}-cargo-audit-v0.12.0 + key: ${{ runner.os }}-cargo-audit-v0.20 - uses: actions-rs/audit-check@v1 with: token: ${{ secrets.GITHUB_TOKEN }} From 91675deaa12eaae027653791eda53774da975897 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Oct 2024 17:43:35 -0600 Subject: [PATCH 1250/1461] build(deps): bump sec1 from 0.8.0-rc.2 to 0.8.0-rc.3 (#1697) --- Cargo.lock | 6 +++--- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cf912c331..bc867d72e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -499,7 +499,7 @@ dependencies = [ "pem-rfc7468 1.0.0-rc.1", "pkcs8 0.11.0-rc.1", "rand_core", - "sec1 0.8.0-rc.2", + "sec1 0.8.0-rc.3", "serde_json", "serdect", "sha2 0.11.0-pre.4", @@ -1057,9 +1057,9 @@ dependencies = [ [[package]] name = "sec1" -version = "0.8.0-rc.2" +version = "0.8.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce9453a41af5251f8439173d21b0ed2ae5d4a7c411abb76661806a44811a9d2c" +checksum = "d1988446eff153796413a73669dfaa4caa3f5ce8b25fac89e3821a39c611772e" dependencies = [ "base16ct", "der 0.8.0-rc.0", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index e622ddf3a..8a6b4683f 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -33,7 +33,7 @@ hkdf = { version = "=0.13.0-pre.4", optional = true, default-features = false } hex-literal = { version = "0.4", optional = true } pem-rfc7468 = { version = "1.0.0-rc.1", optional = true, features = ["alloc"] } pkcs8 = { version = "0.11.0-rc.1", optional = true, default-features = false } -sec1 = { version = "0.8.0-rc.2", optional = true, features = ["subtle", "zeroize"] } +sec1 = { version = "0.8.0-rc.3", optional = true, features = ["subtle", "zeroize"] } serdect = { version = "=0.3.0-rc.0", optional = true, default-features = false, features = ["alloc"] } serde_json = { version = "1.0.121", optional = true, default-features = false, features = ["alloc"] } tap = { version = "1.0.1", optional = true, default-features = false } # hack for minimal-versions support for `bits` From 4571d7cae4d43ee92850967fae32796dfedbde76 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Oct 2024 17:43:51 -0600 Subject: [PATCH 1251/1461] build(deps): bump pem-rfc7468 from 1.0.0-rc.1 to 1.0.0-rc.2 (#1698) --- Cargo.lock | 8 ++++---- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bc867d72e..d4921e4e9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -393,7 +393,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05d9c07d3bd80cf0935ce478d07edf7e7a5b158446757f988f3e62082227b700" dependencies = [ "const-oid 0.10.0-rc.2", - "pem-rfc7468 1.0.0-rc.1", + "pem-rfc7468 1.0.0-rc.2", "zeroize", ] @@ -496,7 +496,7 @@ dependencies = [ "hex-literal", "hkdf 0.13.0-pre.4", "hybrid-array", - "pem-rfc7468 1.0.0-rc.1", + "pem-rfc7468 1.0.0-rc.2", "pkcs8 0.11.0-rc.1", "rand_core", "sec1 0.8.0-rc.3", @@ -851,9 +851,9 @@ dependencies = [ [[package]] name = "pem-rfc7468" -version = "1.0.0-rc.1" +version = "1.0.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c1cde4770761bf6bd336f947b9ac1fe700b0a4ec5867cf66cf08597fe89e8c" +checksum = "c2dfbfa5c6f0906884269722c5478e72fd4d6c0e24fe600332c6d62359567ce1" dependencies = [ "base64ct", ] diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 8a6b4683f..bd7f327f4 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -31,7 +31,7 @@ ff = { version = "0.13", optional = true, default-features = false } group = { version = "0.13", optional = true, default-features = false } hkdf = { version = "=0.13.0-pre.4", optional = true, default-features = false } hex-literal = { version = "0.4", optional = true } -pem-rfc7468 = { version = "1.0.0-rc.1", optional = true, features = ["alloc"] } +pem-rfc7468 = { version = "1.0.0-rc.2", optional = true, features = ["alloc"] } pkcs8 = { version = "0.11.0-rc.1", optional = true, default-features = false } sec1 = { version = "0.8.0-rc.3", optional = true, features = ["subtle", "zeroize"] } serdect = { version = "=0.3.0-rc.0", optional = true, default-features = false, features = ["alloc"] } From 9bf215e47ee33cb0ea522ebea60dc55c25f0ab28 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 19 Oct 2024 09:31:13 -0600 Subject: [PATCH 1252/1461] CI: security audit fixups (#1700) - Pin to `ubuntu-24.04` until upgrade is complete at the end of October - Re-unify security audit since workspace has been re-unified - Use `rustsec/audit-check@v2` since `actions-rs` is unmaintained --- .github/workflows/security-audit.yml | 76 ++-------------------------- 1 file changed, 4 insertions(+), 72 deletions(-) diff --git a/.github/workflows/security-audit.yml b/.github/workflows/security-audit.yml index 154937a18..ee7be617d 100644 --- a/.github/workflows/security-audit.yml +++ b/.github/workflows/security-audit.yml @@ -11,84 +11,16 @@ on: - cron: "0 0 * * *" jobs: - security_audit_workspace: + security_audit: name: Security Audit Workspace - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 - name: Cache cargo bin uses: actions/cache@v4 with: path: ~/.cargo/bin - key: ${{ runner.os }}-cargo-audit-v0.20 - - uses: actions-rs/audit-check@v1 - with: - token: ${{ secrets.GITHUB_TOKEN }} - - security_audit_crypto: - name: Security Audit crypto - runs-on: ubuntu-latest - defaults: - run: - working-directory: crypto - steps: - - uses: actions/checkout@v4 - - name: Cache cargo bin - uses: actions/cache@v4 - with: - path: ~/.cargo/bin - key: ${{ runner.os }}-cargo-audit-v0.20 - - uses: actions-rs/audit-check@v1 - with: - token: ${{ secrets.GITHUB_TOKEN }} - - security_audit_elliptic-curve: - name: Security Audit elliptic-curve - runs-on: ubuntu-latest - defaults: - run: - working-directory: elliptic-curve - steps: - - uses: actions/checkout@v4 - - name: Cache cargo bin - uses: actions/cache@v4 - with: - path: ~/.cargo/bin - key: ${{ runner.os }}-cargo-audit-v0.20 - - uses: actions-rs/audit-check@v1 - with: - token: ${{ secrets.GITHUB_TOKEN }} - - security_audit_kem: - name: Security Audit kem - runs-on: ubuntu-latest - defaults: - run: - working-directory: kem - steps: - - uses: actions/checkout@v4 - - name: Cache cargo bin - uses: actions/cache@v4 - with: - path: ~/.cargo/bin - key: ${{ runner.os }}-cargo-audit-v0.20 - - uses: actions-rs/audit-check@v1 - with: - token: ${{ secrets.GITHUB_TOKEN }} - - security_audit_password-hash: - name: Security Audit password-hash - runs-on: ubuntu-latest - defaults: - run: - working-directory: password-hash - steps: - - uses: actions/checkout@v4 - - name: Cache cargo bin - uses: actions/cache@v4 - with: - path: ~/.cargo/bin - key: ${{ runner.os }}-cargo-audit-v0.20 - - uses: actions-rs/audit-check@v1 + key: ${{ runner.os }}-cargo-audit-v0.20-ubuntu-v24.04 + - uses: rustsec/audit-check@v1 with: token: ${{ secrets.GITHUB_TOKEN }} From 8a27953d1f725728b1e05bc9fb7e4556cffb8f3c Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 21 Oct 2024 13:58:02 -0600 Subject: [PATCH 1253/1461] Bump `hybrid-array` to v0.2 (final) (#1701) Notably in the `crypto-common` and `elliptic-curve` crates which have direct dependencies on `hybrid-array`. --- Cargo.lock | 109 ++++++++++++++++++++------------------ crypto-common/Cargo.toml | 2 +- elliptic-curve/Cargo.toml | 2 +- 3 files changed, 60 insertions(+), 53 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d4921e4e9..44e41f5e7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -63,9 +63,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "base16ct" @@ -126,9 +126,9 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.11.0-rc.2" +version = "0.11.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "939c0e62efa052fb0b2db2c0f7c479ad32e364c192c3aab605a7641de265a1a7" +checksum = "3fd016a0ddc7cb13661bf5576073ce07330a693f8608a1320b4e20561cc12cdc" dependencies = [ "hybrid-array", "zeroize", @@ -145,9 +145,9 @@ dependencies = [ [[package]] name = "block-padding" -version = "0.4.0-rc.1" +version = "0.4.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cac2491ec009b98aa75f36cca2b50e3da7d212918fe953886f6a319042f6016" +checksum = "6868e23cd7a5b2e18fb2e9a583910b88b8d645dd21017aafc5d0439cf16ae6d6" dependencies = [ "hybrid-array", ] @@ -166,12 +166,13 @@ checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" [[package]] name = "cc" -version = "1.1.7" +version = "1.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26a5c3fd7bfa1ce3897a3a3501d362b2d87b7f2583ebcb4a949ec25911025cbc" +checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f" dependencies = [ "jobserver", "libc", + "shlex", ] [[package]] @@ -221,7 +222,7 @@ version = "0.5.0-pre.7" dependencies = [ "blobby", "crypto-common 0.2.0-rc.1", - "inout 0.2.0-rc.1", + "inout 0.2.0-rc.2", "zeroize", ] @@ -245,9 +246,9 @@ checksum = "6a0d96d207edbe5135e55038e79ab9ad6d75ba83b14cdf62326ce5b12bc46ab5" [[package]] name = "cpufeatures" -version = "0.2.12" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" dependencies = [ "libc", ] @@ -388,9 +389,9 @@ dependencies = [ [[package]] name = "der" -version = "0.8.0-rc.0" +version = "0.8.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05d9c07d3bd80cf0935ce478d07edf7e7a5b158446757f988f3e62082227b700" +checksum = "82db698b33305f0134faf590b9d1259dc171b5481ac41d5c8146c3b3ee7d4319" dependencies = [ "const-oid 0.10.0-rc.2", "pem-rfc7468 1.0.0-rc.2", @@ -422,7 +423,7 @@ name = "digest" version = "0.11.0-pre.9" dependencies = [ "blobby", - "block-buffer 0.11.0-rc.2", + "block-buffer 0.11.0-rc.3", "const-oid 0.10.0-rc.2", "crypto-common 0.2.0-rc.1", "subtle", @@ -431,9 +432,9 @@ dependencies = [ [[package]] name = "dunce" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" [[package]] name = "ecdsa" @@ -706,9 +707,9 @@ dependencies = [ [[package]] name = "hybrid-array" -version = "0.2.0-rc.11" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5a41e5b0754cae5aaf7915f1df1147ba8d316fc6e019cfcc00fbaba96d5e030" +checksum = "45a9a965bb102c1c891fb017c09a05c965186b1265a207640f323ddd009f9deb" dependencies = [ "typenum", "zeroize", @@ -726,11 +727,11 @@ dependencies = [ [[package]] name = "inout" -version = "0.2.0-rc.1" +version = "0.2.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "161ac07241f4d11c21b6d82f1fef1c05aec030c0bf568b35281efe453ea450a7" +checksum = "14db49369b2c3f15deb5806de446e05c7f07a2d778b54b278c994fcd1d686f31" dependencies = [ - "block-padding 0.4.0-rc.1", + "block-padding 0.4.0-rc.2", "hybrid-array", ] @@ -774,9 +775,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.155" +version = "0.2.161" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" [[package]] name = "memchr" @@ -886,8 +887,8 @@ version = "0.11.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eacd2c7141f32aef1cfd1ad0defb5287a3d94592d7ab57c1ae20e3f9f1f0db1f" dependencies = [ - "der 0.8.0-rc.0", - "spki 0.8.0-rc.0", + "der 0.8.0-rc.1", + "spki 0.8.0-rc.1", ] [[package]] @@ -915,9 +916,9 @@ dependencies = [ [[package]] name = "ppv-lite86" -version = "0.2.18" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee4364d9f3b902ef14fab8a1ddffb783a1cb6b4bba3bfc1fa3922732c7de97f" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" dependencies = [ "zerocopy", ] @@ -974,18 +975,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "7c3a7fc5db1e57d5a779a352c8cdb57b29aa4c40cc69c3a68a7fedc815fbf2f9" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -1028,9 +1029,9 @@ dependencies = [ [[package]] name = "rustc_version" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ "semver", ] @@ -1062,7 +1063,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d1988446eff153796413a73669dfaa4caa3f5ce8b25fac89e3821a39c611772e" dependencies = [ "base16ct", - "der 0.8.0-rc.0", + "der 0.8.0-rc.1", "hybrid-array", "pkcs8 0.11.0-rc.1", "serdect", @@ -1078,9 +1079,9 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.204" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] @@ -1096,9 +1097,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.204" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", @@ -1107,9 +1108,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.124" +version = "1.0.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66ad62847a56b3dba58cc891acd13884b9c61138d330c0d7b6181713d4fce38d" +checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" dependencies = [ "itoa", "memchr", @@ -1172,6 +1173,12 @@ dependencies = [ "keccak", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "signature" version = "1.3.2" @@ -1232,12 +1239,12 @@ dependencies = [ [[package]] name = "spki" -version = "0.8.0-rc.0" +version = "0.8.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee3fb1c675852398475928637b3ebbdd7e1d0cc24d27b3bbc81788b4eb51e310" +checksum = "37ac66481418fd7afdc584adcf3be9aa572cf6c2858814494dc2a01755f050bc" dependencies = [ "base64ct", - "der 0.8.0-rc.0", + "der 0.8.0-rc.1", ] [[package]] @@ -1254,9 +1261,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.72" +version = "2.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" +checksum = "83540f837a8afc019423a8edb95b52a8effe46957ee402287f4292fae35be021" dependencies = [ "proc-macro2", "quote", @@ -1277,9 +1284,9 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "universal-hash" @@ -1350,9 +1357,9 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.6.6" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854e949ac82d619ee9a14c66a1b674ac730422372ccb759ce0c39cabcf2bf8e6" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ "byteorder", "zerocopy-derive", @@ -1360,9 +1367,9 @@ dependencies = [ [[package]] name = "zerocopy-derive" -version = "0.6.6" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "125139de3f6b9d625c39e2efdd73d41bdac468ccd556556440e322be0e1bbd91" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index 958e26fb7..29ebe30a6 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -13,7 +13,7 @@ keywords = ["crypto", "traits"] categories = ["cryptography", "no-std"] [dependencies] -hybrid-array = "0.2.0-rc.11" +hybrid-array = "0.2" # optional dependencies rand_core = { version = "0.6.4", optional = true } diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index bd7f327f4..3372f996e 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -19,7 +19,7 @@ rust-version = "1.81" [dependencies] base16ct = "0.2" crypto-bigint = { version = "0.6.0-rc.6", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } -hybrid-array = { version = "0.2.0-rc.11", default-features = false, features = ["zeroize"] } +hybrid-array = { version = "0.2", default-features = false, features = ["zeroize"] } rand_core = { version = "0.6.4", default-features = false } subtle = { version = "2.6", default-features = false } zeroize = { version = "1.7", default-features = false } From 326b60639657a3a5c15fd1e83af38ac404da2de9 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 21 Oct 2024 14:13:29 -0600 Subject: [PATCH 1254/1461] elliptic-curve: leverage `core::error::Error` (#1702) This trait is now stable in `core` --- elliptic-curve/src/error.rs | 5 ++--- elliptic-curve/src/lib.rs | 2 ++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/elliptic-curve/src/error.rs b/elliptic-curve/src/error.rs index ba2d0b368..1944839bc 100644 --- a/elliptic-curve/src/error.rs +++ b/elliptic-curve/src/error.rs @@ -9,6 +9,8 @@ pub type Result = core::result::Result; #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub struct Error; +impl core::error::Error for Error {} + impl Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str("crypto error") @@ -40,6 +42,3 @@ impl From for Error { Error } } - -#[cfg(feature = "std")] -impl std::error::Error for Error {} diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index d98bab692..ff5acd88f 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -17,6 +17,8 @@ clippy::mod_module_files, clippy::panic, clippy::panic_in_result_fn, + clippy::std_instead_of_alloc, + clippy::std_instead_of_core, clippy::unwrap_used, missing_debug_implementations, missing_docs, From c450cb72fe14bbe52f9ca800c2308dbc21ba59f2 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 21 Oct 2024 14:17:34 -0600 Subject: [PATCH 1255/1461] elliptic-curve: clippy fixes (#1703) Runs `cargo clippy --all-features --fix` using 1.83.0-beta.1 --- elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs | 6 +++--- elliptic-curve/src/jwk.rs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs index 4d397d4c2..fdd298c63 100644 --- a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs +++ b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs @@ -53,7 +53,7 @@ where let len_in_bytes_u16 = u16::try_from(len_in_bytes).map_err(|_| Error)?; let b_in_bytes = HashT::OutputSize::to_usize(); - let ell = u8::try_from((len_in_bytes + b_in_bytes - 1) / b_in_bytes).map_err(|_| Error)?; + let ell = u8::try_from(len_in_bytes.div_ceil(b_in_bytes)).map_err(|_| Error)?; let domain = Domain::xmd::(dsts)?; let mut b_0 = HashT::default(); @@ -103,7 +103,7 @@ where ell: u8, } -impl<'a, HashT> ExpanderXmd<'a, HashT> +impl ExpanderXmd<'_, HashT> where HashT: BlockSizeUser + Default + FixedOutput + HashMarker, HashT::OutputSize: IsLess, @@ -133,7 +133,7 @@ where } } -impl<'a, HashT> Expander for ExpanderXmd<'a, HashT> +impl Expander for ExpanderXmd<'_, HashT> where HashT: BlockSizeUser + Default + FixedOutput + HashMarker, HashT::OutputSize: IsLess, diff --git a/elliptic-curve/src/jwk.rs b/elliptic-curve/src/jwk.rs index e37cd2769..581448d71 100644 --- a/elliptic-curve/src/jwk.rs +++ b/elliptic-curve/src/jwk.rs @@ -361,7 +361,7 @@ impl<'de> Deserialize<'de> for JwkEcKey { /// Field visitor struct FieldVisitor; - impl<'de> de::Visitor<'de> for FieldVisitor { + impl de::Visitor<'_> for FieldVisitor { type Value = Field; fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { From 8c7c761d7111c33d6d63fbf8dab16f8dbb9efb32 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Oct 2024 16:41:45 -0600 Subject: [PATCH 1256/1461] build(deps): bump rustsec/audit-check from 1 to 2 (#1705) --- .github/workflows/security-audit.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/security-audit.yml b/.github/workflows/security-audit.yml index ee7be617d..8c535dc00 100644 --- a/.github/workflows/security-audit.yml +++ b/.github/workflows/security-audit.yml @@ -21,6 +21,6 @@ jobs: with: path: ~/.cargo/bin key: ${{ runner.os }}-cargo-audit-v0.20-ubuntu-v24.04 - - uses: rustsec/audit-check@v1 + - uses: rustsec/audit-check@v2 with: token: ${{ secrets.GITHUB_TOKEN }} From a1ade1baa00de8c9f9e76ef673734db8f36d6982 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 22 Oct 2024 08:02:26 -0600 Subject: [PATCH 1257/1461] elliptic-curve: include curve OID in SEC1 private keys (#1707) The OID identifies the particular elliptic curve the key is for. Without it, OpenSSL can't parse these keys. See #1706. --- elliptic-curve/src/secret_key.rs | 24 +++++++++++++++--------- elliptic-curve/src/secret_key/pkcs8.rs | 20 ++++++++++++++++---- 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 87f4b791c..09b6ba5ad 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -29,7 +29,7 @@ use { sec1::{EncodedPoint, ModulusSize, ValidatePublicKey}, FieldBytesSize, }, - sec1::der, + sec1::der::{self, oid::AssociatedOid}, }; #[cfg(all(feature = "alloc", feature = "arithmetic", feature = "sec1"))] @@ -184,7 +184,7 @@ where #[cfg(feature = "sec1")] pub fn from_sec1_der(der_bytes: &[u8]) -> Result where - C: Curve + ValidatePublicKey, + C: AssociatedOid + Curve + ValidatePublicKey, FieldBytesSize: ModulusSize, { sec1::EcPrivateKey::try_from(der_bytes)? @@ -196,17 +196,18 @@ where #[cfg(all(feature = "alloc", feature = "arithmetic", feature = "sec1"))] pub fn to_sec1_der(&self) -> der::Result>> where - C: CurveArithmetic, + C: AssociatedOid + CurveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldBytesSize: ModulusSize, { let private_key_bytes = Zeroizing::new(self.to_bytes()); let public_key_bytes = self.public_key().to_encoded_point(false); + let parameters = sec1::EcParameters::NamedCurve(C::OID); let ec_private_key = Zeroizing::new( sec1::EcPrivateKey { private_key: &private_key_bytes, - parameters: None, + parameters: Some(parameters), public_key: Some(public_key_bytes.as_bytes()), } .to_der()?, @@ -225,7 +226,7 @@ where #[cfg(feature = "pem")] pub fn from_sec1_pem(s: &str) -> Result where - C: Curve + ValidatePublicKey, + C: AssociatedOid + Curve + ValidatePublicKey, FieldBytesSize: ModulusSize, { let (label, der_bytes) = pem::decode_vec(s.as_bytes()).map_err(|_| Error)?; @@ -244,7 +245,7 @@ where #[cfg(feature = "pem")] pub fn to_sec1_pem(&self, line_ending: pem::LineEnding) -> Result> where - C: CurveArithmetic, + C: AssociatedOid + CurveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldBytesSize: ModulusSize, { @@ -344,16 +345,21 @@ where #[cfg(feature = "sec1")] impl TryFrom> for SecretKey where - C: Curve + ValidatePublicKey, + C: AssociatedOid + Curve + ValidatePublicKey, FieldBytesSize: ModulusSize, { type Error = der::Error; fn try_from(sec1_private_key: sec1::EcPrivateKey<'_>) -> der::Result { + if let Some(sec1::EcParameters::NamedCurve(curve_oid)) = sec1_private_key.parameters { + if C::OID != curve_oid { + return Err(der::Tag::ObjectIdentifier.value_error()); + } + } + let secret_key = Self::from_slice(sec1_private_key.private_key) - .map_err(|_| der::Tag::Sequence.value_error())?; + .map_err(|_| der::Tag::OctetString.value_error())?; - // TODO(tarcieri): validate `sec1_private_key.params`? if let Some(pk_bytes) = sec1_private_key.public_key { let pk = EncodedPoint::::from_bytes(pk_bytes) .map_err(|_| der::Tag::BitString.value_error())?; diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs index 6cf1b33e5..433926f55 100644 --- a/elliptic-curve/src/secret_key/pkcs8.rs +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -17,9 +17,10 @@ use { AffinePoint, CurveArithmetic, }, pkcs8::{ - der::{self, asn1::OctetStringRef}, + der::{self, asn1::OctetStringRef, Encode}, EncodePrivateKey, }, + zeroize::Zeroizing, }; // Imports for actual PEM support @@ -54,8 +55,7 @@ where .algorithm .assert_oids(ALGORITHM_OID, C::OID)?; - let ec_private_key = EcPrivateKey::from_der(private_key_info.private_key.as_bytes())?; - Ok(Self::try_from(ec_private_key)?) + Ok(EcPrivateKey::from_der(private_key_info.private_key.as_bytes())?.try_into()?) } } @@ -72,7 +72,19 @@ where parameters: Some((&C::OID).into()), }; - let ec_private_key = self.to_sec1_der()?; + let private_key_bytes = Zeroizing::new(self.to_bytes()); + let public_key_bytes = self.public_key().to_encoded_point(false); + + // TODO(tarcieri): unify with `to_sec1_der()` by building an owned `EcPrivateKey` + let ec_private_key = Zeroizing::new( + EcPrivateKey { + private_key: &private_key_bytes, + parameters: None, + public_key: Some(public_key_bytes.as_bytes()), + } + .to_der()?, + ); + let pkcs8_key = pkcs8::PrivateKeyInfoRef::new( algorithm_identifier, OctetStringRef::new(&ec_private_key)?, From f575f2b9008e25ae94912cf7583013b46e8c1664 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Wed, 13 Nov 2024 19:28:21 +0300 Subject: [PATCH 1258/1461] Fix new Clippy lints (#1710) --- .github/workflows/workspace.yml | 2 +- aead/src/lib.rs | 2 +- cipher/src/block/ctx.rs | 20 ++++++++++---------- cipher/src/stream/core_api.rs | 16 ++++++++-------- cipher/src/stream/wrapper.rs | 3 +-- password-hash/src/ident.rs | 8 ++++---- password-hash/src/lib.rs | 2 +- password-hash/src/salt.rs | 6 +++--- password-hash/src/value.rs | 4 ++-- universal-hash/src/lib.rs | 4 ++-- 10 files changed, 33 insertions(+), 34 deletions(-) diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index 882d1d4c4..17e37767d 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -24,7 +24,7 @@ jobs: - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: - toolchain: 1.81.0 + toolchain: 1.82.0 components: clippy - run: cargo clippy --all --all-features --tests -- -D warnings diff --git a/aead/src/lib.rs b/aead/src/lib.rs index 63be73a7d..2a3560c21 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -487,7 +487,7 @@ pub struct Payload<'msg, 'aad> { } #[cfg(feature = "alloc")] -impl<'msg, 'aad> From<&'msg [u8]> for Payload<'msg, 'aad> { +impl<'msg> From<&'msg [u8]> for Payload<'msg, '_> { fn from(msg: &'msg [u8]) -> Self { Self { msg, aad: b"" } } diff --git a/cipher/src/block/ctx.rs b/cipher/src/block/ctx.rs index 7b0f04632..7a7634120 100644 --- a/cipher/src/block/ctx.rs +++ b/cipher/src/block/ctx.rs @@ -11,32 +11,32 @@ pub(super) struct BlockCtx<'inp, 'out, BS: BlockSizes> { pub block: InOut<'inp, 'out, Block>, } -impl<'inp, 'out, BS: BlockSizes> BlockSizeUser for BlockCtx<'inp, 'out, BS> { +impl BlockSizeUser for BlockCtx<'_, '_, BS> { type BlockSize = BS; } -impl<'inp, 'out, BS: BlockSizes> BlockCipherEncClosure for BlockCtx<'inp, 'out, BS> { +impl BlockCipherEncClosure for BlockCtx<'_, '_, BS> { #[inline(always)] fn call>(self, backend: &B) { backend.encrypt_block(self.block); } } -impl<'inp, 'out, BS: BlockSizes> BlockCipherDecClosure for BlockCtx<'inp, 'out, BS> { +impl BlockCipherDecClosure for BlockCtx<'_, '_, BS> { #[inline(always)] fn call>(self, backend: &B) { backend.decrypt_block(self.block); } } -impl<'inp, 'out, BS: BlockSizes> BlockModeEncClosure for BlockCtx<'inp, 'out, BS> { +impl BlockModeEncClosure for BlockCtx<'_, '_, BS> { #[inline(always)] fn call>(self, backend: &mut B) { backend.encrypt_block(self.block); } } -impl<'inp, 'out, BS: BlockSizes> BlockModeDecClosure for BlockCtx<'inp, 'out, BS> { +impl BlockModeDecClosure for BlockCtx<'_, '_, BS> { #[inline(always)] fn call>(self, backend: &mut B) { backend.decrypt_block(self.block); @@ -47,11 +47,11 @@ pub(super) struct BlocksCtx<'inp, 'out, BS: BlockSizes> { pub blocks: InOutBuf<'inp, 'out, Block>, } -impl<'inp, 'out, BS: BlockSizes> BlockSizeUser for BlocksCtx<'inp, 'out, BS> { +impl BlockSizeUser for BlocksCtx<'_, '_, BS> { type BlockSize = BS; } -impl<'inp, 'out, BS: BlockSizes> BlockCipherEncClosure for BlocksCtx<'inp, 'out, BS> { +impl BlockCipherEncClosure for BlocksCtx<'_, '_, BS> { #[inline(always)] fn call>(self, backend: &B) { if B::ParBlocksSize::USIZE > 1 { @@ -68,7 +68,7 @@ impl<'inp, 'out, BS: BlockSizes> BlockCipherEncClosure for BlocksCtx<'inp, 'out, } } -impl<'inp, 'out, BS: BlockSizes> BlockCipherDecClosure for BlocksCtx<'inp, 'out, BS> { +impl BlockCipherDecClosure for BlocksCtx<'_, '_, BS> { #[inline(always)] fn call>(self, backend: &B) { if B::ParBlocksSize::USIZE > 1 { @@ -85,7 +85,7 @@ impl<'inp, 'out, BS: BlockSizes> BlockCipherDecClosure for BlocksCtx<'inp, 'out, } } -impl<'inp, 'out, BS: BlockSizes> BlockModeEncClosure for BlocksCtx<'inp, 'out, BS> { +impl BlockModeEncClosure for BlocksCtx<'_, '_, BS> { #[inline(always)] fn call>(self, backend: &mut B) { if B::ParBlocksSize::USIZE > 1 { @@ -102,7 +102,7 @@ impl<'inp, 'out, BS: BlockSizes> BlockModeEncClosure for BlocksCtx<'inp, 'out, B } } -impl<'inp, 'out, BS: BlockSizes> BlockModeDecClosure for BlocksCtx<'inp, 'out, BS> { +impl BlockModeDecClosure for BlocksCtx<'_, '_, BS> { #[inline(always)] fn call>(self, backend: &mut B) { if B::ParBlocksSize::USIZE > 1 { diff --git a/cipher/src/stream/core_api.rs b/cipher/src/stream/core_api.rs index aab1c32b5..200c1fee0 100644 --- a/cipher/src/stream/core_api.rs +++ b/cipher/src/stream/core_api.rs @@ -190,10 +190,10 @@ impl_counter! { u32 u64 u128 } struct WriteBlockCtx<'a, BS: BlockSizes> { block: &'a mut Block, } -impl<'a, BS: BlockSizes> BlockSizeUser for WriteBlockCtx<'a, BS> { +impl BlockSizeUser for WriteBlockCtx<'_, BS> { type BlockSize = BS; } -impl<'a, BS: BlockSizes> StreamCipherClosure for WriteBlockCtx<'a, BS> { +impl StreamCipherClosure for WriteBlockCtx<'_, BS> { #[inline(always)] fn call>(self, backend: &mut B) { backend.gen_ks_block(self.block); @@ -203,10 +203,10 @@ impl<'a, BS: BlockSizes> StreamCipherClosure for WriteBlockCtx<'a, BS> { struct WriteBlocksCtx<'a, BS: BlockSizes> { blocks: &'a mut [Block], } -impl<'a, BS: BlockSizes> BlockSizeUser for WriteBlocksCtx<'a, BS> { +impl BlockSizeUser for WriteBlocksCtx<'_, BS> { type BlockSize = BS; } -impl<'a, BS: BlockSizes> StreamCipherClosure for WriteBlocksCtx<'a, BS> { +impl StreamCipherClosure for WriteBlocksCtx<'_, BS> { #[inline(always)] fn call>(self, backend: &mut B) { if B::ParBlocksSize::USIZE > 1 { @@ -227,11 +227,11 @@ struct ApplyBlockCtx<'inp, 'out, BS: BlockSizes> { block: InOut<'inp, 'out, Block>, } -impl<'inp, 'out, BS: BlockSizes> BlockSizeUser for ApplyBlockCtx<'inp, 'out, BS> { +impl BlockSizeUser for ApplyBlockCtx<'_, '_, BS> { type BlockSize = BS; } -impl<'inp, 'out, BS: BlockSizes> StreamCipherClosure for ApplyBlockCtx<'inp, 'out, BS> { +impl StreamCipherClosure for ApplyBlockCtx<'_, '_, BS> { #[inline(always)] fn call>(mut self, backend: &mut B) { let mut t = Default::default(); @@ -244,11 +244,11 @@ struct ApplyBlocksCtx<'inp, 'out, BS: BlockSizes> { blocks: InOutBuf<'inp, 'out, Block>, } -impl<'inp, 'out, BS: BlockSizes> BlockSizeUser for ApplyBlocksCtx<'inp, 'out, BS> { +impl BlockSizeUser for ApplyBlocksCtx<'_, '_, BS> { type BlockSize = BS; } -impl<'inp, 'out, BS: BlockSizes> StreamCipherClosure for ApplyBlocksCtx<'inp, 'out, BS> { +impl StreamCipherClosure for ApplyBlocksCtx<'_, '_, BS> { #[inline(always)] #[allow(clippy::needless_range_loop)] fn call>(self, backend: &mut B) { diff --git a/cipher/src/stream/wrapper.rs b/cipher/src/stream/wrapper.rs index abf4a9b04..16863a42c 100644 --- a/cipher/src/stream/wrapper.rs +++ b/cipher/src/stream/wrapper.rs @@ -106,8 +106,7 @@ impl StreamCipherCoreWrapper { }; let bs = T::BlockSize::USIZE; - // TODO: use div_ceil on 1.73+ MSRV bump - let blocks = (data_len + bs - 1) / bs; + let blocks = data_len.div_ceil(bs); if blocks > rem_blocks { Err(StreamCipherError) } else { diff --git a/password-hash/src/ident.rs b/password-hash/src/ident.rs index ce82b6a99..784270e6d 100644 --- a/password-hash/src/ident.rs +++ b/password-hash/src/ident.rs @@ -91,13 +91,13 @@ impl<'a> Ident<'a> { } } -impl<'a> AsRef for Ident<'a> { +impl AsRef for Ident<'_> { fn as_ref(&self) -> &str { self.as_str() } } -impl<'a> Deref for Ident<'a> { +impl Deref for Ident<'_> { type Target = str; fn deref(&self) -> &str { @@ -115,13 +115,13 @@ impl<'a> TryFrom<&'a str> for Ident<'a> { } } -impl<'a> fmt::Display for Ident<'a> { +impl fmt::Display for Ident<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(self) } } -impl<'a> fmt::Debug for Ident<'a> { +impl fmt::Debug for Ident<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("Ident").field(&self.as_ref()).finish() } diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index 8b8f62ba1..8993cfa43 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -250,7 +250,7 @@ impl<'a> TryFrom<&'a str> for PasswordHash<'a> { } } -impl<'a> fmt::Display for PasswordHash<'a> { +impl fmt::Display for PasswordHash<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}{}", PASSWORD_HASH_SEPARATOR, self.algorithm)?; diff --git a/password-hash/src/salt.rs b/password-hash/src/salt.rs index a73288c3b..8ab8baf99 100644 --- a/password-hash/src/salt.rs +++ b/password-hash/src/salt.rs @@ -163,7 +163,7 @@ impl<'a> Salt<'a> { } } -impl<'a> AsRef for Salt<'a> { +impl AsRef for Salt<'_> { fn as_ref(&self) -> &str { self.as_str() } @@ -177,13 +177,13 @@ impl<'a> TryFrom<&'a str> for Salt<'a> { } } -impl<'a> fmt::Display for Salt<'a> { +impl fmt::Display for Salt<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(self.as_str()) } } -impl<'a> fmt::Debug for Salt<'a> { +impl fmt::Debug for Salt<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "Salt({:?})", self.as_str()) } diff --git a/password-hash/src/value.rs b/password-hash/src/value.rs index 5cac55919..aacc85d53 100644 --- a/password-hash/src/value.rs +++ b/password-hash/src/value.rs @@ -154,7 +154,7 @@ impl<'a> Value<'a> { } } -impl<'a> AsRef for Value<'a> { +impl AsRef for Value<'_> { fn as_ref(&self) -> &str { self.as_str() } @@ -184,7 +184,7 @@ impl<'a> TryFrom<&Value<'a>> for Decimal { } } -impl<'a> fmt::Display for Value<'a> { +impl fmt::Display for Value<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(self.as_str()) } diff --git a/universal-hash/src/lib.rs b/universal-hash/src/lib.rs index 44b59686c..d6d43aff3 100644 --- a/universal-hash/src/lib.rs +++ b/universal-hash/src/lib.rs @@ -64,11 +64,11 @@ pub trait UniversalHash: BlockSizeUser + Sized { blocks: &'a [Block], } - impl<'a, BS: BlockSizes> BlockSizeUser for Ctx<'a, BS> { + impl BlockSizeUser for Ctx<'_, BS> { type BlockSize = BS; } - impl<'a, BS: BlockSizes> UhfClosure for Ctx<'a, BS> { + impl UhfClosure for Ctx<'_, BS> { #[inline(always)] fn call>(self, backend: &mut B) { let pb = B::ParBlocksSize::USIZE; From ba20c6957488e7840340a9b4f58e1d01d755316d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 13 Nov 2024 19:55:18 +0300 Subject: [PATCH 1259/1461] build(deps): bump const-oid from 0.10.0-rc.2 to 0.10.0-rc.3 (#1709) --- Cargo.lock | 8 ++++---- digest/Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 44e41f5e7..8b6ef2a30 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -240,9 +240,9 @@ checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "const-oid" -version = "0.10.0-rc.2" +version = "0.10.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a0d96d207edbe5135e55038e79ab9ad6d75ba83b14cdf62326ce5b12bc46ab5" +checksum = "68ff6be19477a1bd5441f382916a89bc2a0b2c35db6d41e0f6e8538bf6d6463f" [[package]] name = "cpufeatures" @@ -393,7 +393,7 @@ version = "0.8.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "82db698b33305f0134faf590b9d1259dc171b5481ac41d5c8146c3b3ee7d4319" dependencies = [ - "const-oid 0.10.0-rc.2", + "const-oid 0.10.0-rc.3", "pem-rfc7468 1.0.0-rc.2", "zeroize", ] @@ -424,7 +424,7 @@ version = "0.11.0-pre.9" dependencies = [ "blobby", "block-buffer 0.11.0-rc.3", - "const-oid 0.10.0-rc.2", + "const-oid 0.10.0-rc.3", "crypto-common 0.2.0-rc.1", "subtle", "zeroize", diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 4f7c35910..c6d2639f6 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -19,7 +19,7 @@ crypto-common = "0.2.0-rc.0" block-buffer = { version = "0.11.0-rc.2", optional = true } subtle = { version = "2.4", default-features = false, optional = true } blobby = { version = "0.3", optional = true } -const-oid = { version = "0.10.0-rc.2", optional = true } +const-oid = { version = "0.10.0-rc.3", optional = true } zeroize = { version = "1.7", optional = true, default-features = false } [features] From 70d3103b9f681697369a87255e05b96e26f7da89 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Wed, 13 Nov 2024 20:05:24 +0300 Subject: [PATCH 1260/1461] Update Cargo.lock (#1712) --- Cargo.lock | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8b6ef2a30..136d93a91 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -160,15 +160,15 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.7.2" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" +checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" [[package]] name = "cc" -version = "1.1.31" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f" +checksum = "1aeb932158bd710538c73702db6945cb68a8fb08c519e6e12706b94263b36db8" dependencies = [ "jobserver", "libc", @@ -246,9 +246,9 @@ checksum = "68ff6be19477a1bd5441f382916a89bc2a0b2c35db6d41e0f6e8538bf6d6463f" [[package]] name = "cpufeatures" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" +checksum = "0ca741a962e1b0bff6d724a1a0958b686406e853bb14061f218562e1896f95e6" dependencies = [ "libc", ] @@ -775,9 +775,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.161" +version = "0.2.162" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" +checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398" [[package]] name = "memchr" @@ -935,9 +935,9 @@ dependencies = [ [[package]] name = "pqcrypto-internals" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9d34bec6abe2283e6de7748b68b292d1ffa2203397e3e71380ff8418a49fb46" +checksum = "e10cdd9eee50fe65bbd4f40211f1a492f1ee52e97a51100950b6f1fa319ab7cd" dependencies = [ "cc", "dunce", @@ -975,9 +975,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.88" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c3a7fc5db1e57d5a779a352c8cdb57b29aa4c40cc69c3a68a7fedc815fbf2f9" +checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" dependencies = [ "unicode-ident", ] @@ -1079,9 +1079,9 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.210" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" dependencies = [ "serde_derive", ] @@ -1097,9 +1097,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.210" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", @@ -1261,9 +1261,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.82" +version = "2.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83540f837a8afc019423a8edb95b52a8effe46957ee402287f4292fae35be021" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" dependencies = [ "proc-macro2", "quote", From f5266b8737aa71159f1b37ea10d16e4232abb9dd Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Fri, 15 Nov 2024 04:17:29 +0300 Subject: [PATCH 1261/1461] Migrate to `core::error::Error` (#1711) --- .github/workflows/async-signature.yml | 2 +- .github/workflows/password-hash.yml | 4 +-- .github/workflows/signature.yml | 4 +-- async-signature/Cargo.toml | 2 +- async-signature/README.md | 4 +-- digest/src/lib.rs | 6 ++-- digest/src/mac.rs | 3 +- password-hash/Cargo.toml | 3 +- password-hash/README.md | 4 +-- password-hash/src/errors.rs | 11 +++--- password-hash/src/lib.rs | 2 -- signature/Cargo.toml | 3 +- signature/README.md | 4 +-- signature/src/error.rs | 49 +++++++++++++++------------ signature/src/lib.rs | 2 -- universal-hash/Cargo.toml | 3 -- universal-hash/src/lib.rs | 6 +--- 17 files changed, 51 insertions(+), 61 deletions(-) diff --git a/.github/workflows/async-signature.yml b/.github/workflows/async-signature.yml index dbef8e7bf..1846df7c6 100644 --- a/.github/workflows/async-signature.yml +++ b/.github/workflows/async-signature.yml @@ -23,7 +23,7 @@ jobs: strategy: matrix: rust: - - 1.75.0 # MSRV + - 1.81.0 # MSRV - stable target: - thumbv7em-none-eabi diff --git a/.github/workflows/password-hash.yml b/.github/workflows/password-hash.yml index 2a732455f..0b4754a15 100644 --- a/.github/workflows/password-hash.yml +++ b/.github/workflows/password-hash.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.60.0 # MSRV + - 1.81.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -57,7 +57,7 @@ jobs: strategy: matrix: rust: - - 1.60.0 # MSRV + - 1.81.0 # MSRV - stable steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/signature.yml b/.github/workflows/signature.yml index c2dfd14ab..a54fe0478 100644 --- a/.github/workflows/signature.yml +++ b/.github/workflows/signature.yml @@ -24,7 +24,7 @@ jobs: strategy: matrix: rust: - - 1.72.0 # MSRV + - 1.81.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -68,7 +68,7 @@ jobs: strategy: matrix: rust: - - 1.72.0 # MSRV + - 1.81.0 # MSRV - stable steps: - uses: actions/checkout@v4 diff --git a/async-signature/Cargo.toml b/async-signature/Cargo.toml index 50ac9a702..0fe015a43 100644 --- a/async-signature/Cargo.toml +++ b/async-signature/Cargo.toml @@ -11,7 +11,7 @@ readme = "README.md" keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"] categories = ["cryptography", "no-std"] edition = "2021" -rust-version = "1.75" +rust-version = "1.81" [dependencies] signature = "=2.3.0-pre.4" diff --git a/async-signature/README.md b/async-signature/README.md index 1a5b5be9b..838661376 100644 --- a/async-signature/README.md +++ b/async-signature/README.md @@ -9,7 +9,7 @@ ## Minimum Supported Rust Version -Rust **1.75** or higher. +Rust **1.81** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -36,7 +36,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/async-signature/badge.svg [docs-link]: https://docs.rs/async-signature/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.75+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.81+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260048-signatures [build-image]: https://github.com/RustCrypto/traits/workflows/async-signature/badge.svg?branch=master&event=push diff --git a/digest/src/lib.rs b/digest/src/lib.rs index a9f5b7a4a..a3e6fca86 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -284,8 +284,7 @@ impl fmt::Display for InvalidOutputSize { } } -#[cfg(feature = "std")] -impl std::error::Error for InvalidOutputSize {} +impl core::error::Error for InvalidOutputSize {} /// Buffer length is not equal to hash output size. #[derive(Default, Debug, Copy, Clone, Eq, PartialEq)] @@ -297,8 +296,7 @@ impl fmt::Display for InvalidBufferSize { } } -#[cfg(feature = "std")] -impl std::error::Error for InvalidBufferSize {} +impl core::error::Error for InvalidBufferSize {} #[cfg(feature = "std")] mod hashwriter; diff --git a/digest/src/mac.rs b/digest/src/mac.rs index d34648633..395f86e09 100644 --- a/digest/src/mac.rs +++ b/digest/src/mac.rs @@ -278,5 +278,4 @@ impl fmt::Display for MacError { } } -#[cfg(feature = "std")] -impl std::error::Error for MacError {} +impl core::error::Error for MacError {} diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index 543a789fd..ca1d81c48 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -15,7 +15,7 @@ repository = "https://github.com/RustCrypto/traits" categories = ["authentication", "cryptography", "no-std"] keywords = ["crypt", "mcf", "password", "pbkdf", "phc"] edition = "2021" -rust-version = "1.60" +rust-version = "1.81" [dependencies] base64ct = "1.6" @@ -27,7 +27,6 @@ rand_core = { version = "0.6.4", optional = true, default-features = false } [features] default = ["rand_core"] alloc = ["base64ct/alloc"] -std = ["alloc", "base64ct/std", "rand_core/std"] getrandom = ["rand_core/getrandom"] diff --git a/password-hash/README.md b/password-hash/README.md index dd376cd5f..20dffcd56 100644 --- a/password-hash/README.md +++ b/password-hash/README.md @@ -29,7 +29,7 @@ this crate for interoperability: ## Minimum Supported Rust Version -Rust **1.60** or higher. +Rust **1.81** or higher. Minimum supported Rust version may be changed in the future, but it will be accompanied by a minor version bump. @@ -63,7 +63,7 @@ dual licensed as above, without any additional terms or conditions. [build-image]: https://github.com/RustCrypto/traits/workflows/password-hash/badge.svg?branch=master&event=push [build-link]: https://github.com/RustCrypto/traits/actions?query=workflow:password-hash [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.60+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.81+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260046-password-hashes diff --git a/password-hash/src/errors.rs b/password-hash/src/errors.rs index c48a28dfe..11efd67bb 100644 --- a/password-hash/src/errors.rs +++ b/password-hash/src/errors.rs @@ -99,11 +99,11 @@ impl fmt::Display for Error { } } -#[cfg(feature = "std")] -impl std::error::Error for Error { - fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { +impl core::error::Error for Error { + fn source(&self) -> Option<&(dyn core::error::Error + 'static)> { match self { - Self::B64Encoding(err) => Some(err), + // TODO: restore after base64ct will migrate to core::error::Error + // Self::B64Encoding(err) => Some(err), Self::ParamValueInvalid(err) => Some(err), Self::SaltInvalid(err) => Some(err), _ => None, @@ -167,5 +167,4 @@ impl fmt::Display for InvalidValue { } } -#[cfg(feature = "std")] -impl std::error::Error for InvalidValue {} +impl core::error::Error for InvalidValue {} diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index 8993cfa43..7e3f283f1 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -27,8 +27,6 @@ #[cfg(feature = "alloc")] extern crate alloc; -#[cfg(feature = "std")] -extern crate std; #[cfg(feature = "rand_core")] pub use rand_core; diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 9b2540b56..921f0756a 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -11,7 +11,7 @@ readme = "README.md" keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"] categories = ["cryptography", "no-std"] edition = "2021" -rust-version = "1.72" +rust-version = "1.81" [dependencies] derive = { package = "signature_derive", version = "2", optional = true, path = "../signature_derive" } @@ -24,6 +24,7 @@ sha2 = { version = "=0.11.0-pre.4", default-features = false } [features] alloc = [] +# TODO: remove this feature in the next breaking release std = ["alloc", "rand_core?/std"] [package.metadata.docs.rs] diff --git a/signature/README.md b/signature/README.md index ce11d14df..1da58187e 100644 --- a/signature/README.md +++ b/signature/README.md @@ -17,7 +17,7 @@ the [RustCrypto] organization, as well as [`ed25519-dalek`]. ## Minimum Supported Rust Version -Rust **1.72** or higher. +Rust **1.81** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -56,7 +56,7 @@ dual licensed as above, without any additional terms or conditions. [build-image]: https://github.com/RustCrypto/traits/actions/workflows/signature.yml/badge.svg [build-link]: https://github.com/RustCrypto/traits/actions/workflows/signature.yml [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.72+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.81+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260048-signatures diff --git a/signature/src/error.rs b/signature/src/error.rs index 7d716a1de..dc30176ce 100644 --- a/signature/src/error.rs +++ b/signature/src/error.rs @@ -2,8 +2,8 @@ use core::fmt::{self, Debug, Display}; -#[cfg(feature = "std")] -use std::boxed::Box; +#[cfg(feature = "alloc")] +use alloc::boxed::Box; /// Result type. /// @@ -16,17 +16,16 @@ pub type Result = core::result::Result; /// could potentially be used recover signing private keys or forge signatures /// (e.g. [BB'06]). /// -/// When the `std` feature is enabled, it impls [`std::error::Error`] and -/// supports an optional [`std::error::Error::source`], which can be used by -/// things like remote signers (e.g. HSM, KMS) to report I/O or auth errors. +/// When the `alloc` feature is enabled, it supports an optional [`core::error::Error::source`], +/// which can be used by things like remote signers (e.g. HSM, KMS) to report I/O or auth errors. /// /// [BB'06]: https://en.wikipedia.org/wiki/Daniel_Bleichenbacher #[derive(Default)] #[non_exhaustive] pub struct Error { /// Source of the error (if applicable). - #[cfg(feature = "std")] - source: Option>, + #[cfg(feature = "alloc")] + source: Option>, } impl Error { @@ -41,9 +40,9 @@ impl Error { /// errors e.g. signature parsing or verification errors. The intended use /// cases are for propagating errors related to external signers, e.g. /// communication/authentication errors with HSMs, KMS, etc. - #[cfg(feature = "std")] + #[cfg(feature = "alloc")] pub fn from_source( - source: impl Into>, + source: impl Into>, ) -> Self { Self { source: Some(source.into()), @@ -52,12 +51,12 @@ impl Error { } impl Debug for Error { - #[cfg(not(feature = "std"))] + #[cfg(not(feature = "alloc"))] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str("signature::Error {}") } - #[cfg(feature = "std")] + #[cfg(feature = "alloc")] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str("signature::Error { source: ")?; @@ -77,31 +76,37 @@ impl Display for Error { } } -#[cfg(feature = "std")] -impl From> for Error { - fn from(source: Box) -> Error { +#[cfg(feature = "alloc")] +impl From> for Error { + fn from(source: Box) -> Error { Self::from_source(source) } } #[cfg(feature = "rand_core")] impl From for Error { - #[cfg(not(feature = "std"))] + #[cfg(not(feature = "alloc"))] fn from(_source: rand_core::Error) -> Error { Error::new() } - #[cfg(feature = "std")] + #[cfg(feature = "alloc")] fn from(source: rand_core::Error) -> Error { Error::from_source(source) } } -#[cfg(feature = "std")] -impl std::error::Error for Error { - fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - self.source - .as_ref() - .map(|source| source.as_ref() as &(dyn std::error::Error + 'static)) +impl core::error::Error for Error { + fn source(&self) -> Option<&(dyn core::error::Error + 'static)> { + #[cfg(not(feature = "alloc"))] + { + None + } + #[cfg(feature = "alloc")] + { + self.source + .as_ref() + .map(|source| source.as_ref() as &(dyn core::error::Error + 'static)) + } } } diff --git a/signature/src/lib.rs b/signature/src/lib.rs index 902499fe8..a3281f769 100644 --- a/signature/src/lib.rs +++ b/signature/src/lib.rs @@ -130,8 +130,6 @@ #[cfg(feature = "alloc")] extern crate alloc; -#[cfg(feature = "std")] -extern crate std; pub mod hazmat; diff --git a/universal-hash/Cargo.toml b/universal-hash/Cargo.toml index 2b0042572..9068fa16e 100644 --- a/universal-hash/Cargo.toml +++ b/universal-hash/Cargo.toml @@ -16,9 +16,6 @@ categories = ["cryptography", "no-std"] crypto-common = "0.2.0-rc.0" subtle = { version = "2.4", default-features = false } -[features] -std = [] - [package.metadata.docs.rs] all-features = true rustdoc-args = ["--cfg", "docsrs"] diff --git a/universal-hash/src/lib.rs b/universal-hash/src/lib.rs index d6d43aff3..06e75e658 100644 --- a/universal-hash/src/lib.rs +++ b/universal-hash/src/lib.rs @@ -8,9 +8,6 @@ #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms, missing_debug_implementations)] -#[cfg(feature = "std")] -extern crate std; - pub use crypto_common::{ self, array, typenum::{self, consts}, @@ -152,5 +149,4 @@ impl core::fmt::Display for Error { } } -#[cfg(feature = "std")] -impl std::error::Error for Error {} +impl core::error::Error for Error {} From 8bb338103292e9e709c9b45009c568ed9a6276f9 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Mon, 18 Nov 2024 16:51:28 +0300 Subject: [PATCH 1262/1461] password-hash: fix `needless_as_bytes` Clippy lint (#1715) --- password-hash/src/params.rs | 6 +++--- password-hash/src/salt.rs | 4 ++-- password-hash/src/value.rs | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/password-hash/src/params.rs b/password-hash/src/params.rs index d23d279fe..0d8074099 100644 --- a/password-hash/src/params.rs +++ b/password-hash/src/params.rs @@ -173,7 +173,7 @@ impl FromStr for ParamsString { type Err = Error; fn from_str(s: &str) -> Result { - if s.as_bytes().len() > MAX_LENGTH { + if s.len() > MAX_LENGTH { return Err(Error::ParamsMaxExceeded); } @@ -201,11 +201,11 @@ impl FromStr for ParamsString { } let mut bytes = [0u8; MAX_LENGTH]; - bytes[..s.as_bytes().len()].copy_from_slice(s.as_bytes()); + bytes[..s.len()].copy_from_slice(s.as_bytes()); Ok(Self(Buffer { bytes, - length: s.as_bytes().len() as u8, + length: s.len() as u8, })) } } diff --git a/password-hash/src/salt.rs b/password-hash/src/salt.rs index 8ab8baf99..eba6876f6 100644 --- a/password-hash/src/salt.rs +++ b/password-hash/src/salt.rs @@ -103,7 +103,7 @@ impl<'a> Salt<'a> { /// Create a [`Salt`] from the given B64-encoded input string, validating /// [`Salt::MIN_LENGTH`] and [`Salt::MAX_LENGTH`] restrictions. pub fn from_b64(input: &'a str) -> Result { - let length = input.as_bytes().len(); + let length = input.len(); if length < Self::MIN_LENGTH { return Err(Error::SaltInvalid(InvalidValue::TooShort)); @@ -215,7 +215,7 @@ impl SaltString { // Assert `s` parses successfully as a `Salt` Salt::from_b64(s)?; - let len = s.as_bytes().len(); + let len = s.len(); let mut bytes = [0u8; Salt::MAX_LENGTH]; bytes[..len].copy_from_slice(s.as_bytes()); diff --git a/password-hash/src/value.rs b/password-hash/src/value.rs index aacc85d53..f60a75590 100644 --- a/password-hash/src/value.rs +++ b/password-hash/src/value.rs @@ -50,7 +50,7 @@ impl<'a> Value<'a> { /// Parse a [`Value`] from the provided `str`, validating it according to /// the PHC string format's rules. pub fn new(input: &'a str) -> Result { - if input.as_bytes().len() > Self::MAX_LENGTH { + if input.len() > Self::MAX_LENGTH { return Err(Error::ParamValueInvalid(InvalidValue::TooLong)); } From 3597746976a972960152c1b562000b44d5a69da6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Jan 2025 15:57:05 -0700 Subject: [PATCH 1263/1461] build(deps): bump serdect from 0.3.0-rc.0 to 0.3 (#1725) --- Cargo.lock | 4 ++-- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 136d93a91..9bb81b27f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1120,9 +1120,9 @@ dependencies = [ [[package]] name = "serdect" -version = "0.3.0-rc.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a504c8ee181e3e594d84052f983d60afe023f4d94d050900be18062bbbf7b58" +checksum = "f42f67da2385b51a5f9652db9c93d78aeaf7610bf5ec366080b6de810604af53" dependencies = [ "base16ct", "serde", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 3372f996e..775da9017 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -34,7 +34,7 @@ hex-literal = { version = "0.4", optional = true } pem-rfc7468 = { version = "1.0.0-rc.2", optional = true, features = ["alloc"] } pkcs8 = { version = "0.11.0-rc.1", optional = true, default-features = false } sec1 = { version = "0.8.0-rc.3", optional = true, features = ["subtle", "zeroize"] } -serdect = { version = "=0.3.0-rc.0", optional = true, default-features = false, features = ["alloc"] } +serdect = { version = "0.3", optional = true, default-features = false, features = ["alloc"] } serde_json = { version = "1.0.121", optional = true, default-features = false, features = ["alloc"] } tap = { version = "1.0.1", optional = true, default-features = false } # hack for minimal-versions support for `bits` From 2b9e5f585a5fda5392ac81240ea5bfd9e2cc1790 Mon Sep 17 00:00:00 2001 From: nathan haim Date: Thu, 9 Jan 2025 17:24:19 +0100 Subject: [PATCH 1264/1461] fix IsHigh trait comment (#1726) The comment was saying that function informs if the scalar is **"greater or equal to"** whereas the implementation informs if the scalar is **"strictly greater than"** --- elliptic-curve/src/scalar.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elliptic-curve/src/scalar.rs b/elliptic-curve/src/scalar.rs index a53b93e12..9f3abdad7 100644 --- a/elliptic-curve/src/scalar.rs +++ b/elliptic-curve/src/scalar.rs @@ -49,6 +49,6 @@ pub trait FromUintUnchecked { /// - For scalars 0 through n / 2: `Choice::from(0)` /// - For scalars (n / 2) + 1 through n - 1: `Choice::from(1)` pub trait IsHigh { - /// Is this scalar greater than or equal to n / 2? + /// Is this scalar greater than n / 2? fn is_high(&self) -> Choice; } From 258340cb217cf30c474822ac2c7cb9d6dc83c38c Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 20 Jan 2025 18:17:51 -0700 Subject: [PATCH 1265/1461] elliptic-curve: bump `crypto-bigint` to v0.6.0-rc.8; MSRV 1.83 (#1730) --- .github/workflows/elliptic-curve.yml | 4 ++-- .github/workflows/workspace.yml | 2 +- Cargo.lock | 6 +++--- elliptic-curve/Cargo.toml | 4 ++-- elliptic-curve/README.md | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index 082155f07..d18193e87 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -24,7 +24,7 @@ jobs: strategy: matrix: rust: - - 1.81.0 # MSRV + - 1.83.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -75,7 +75,7 @@ jobs: strategy: matrix: rust: - - 1.81.0 # MSRV + - 1.83.0 # MSRV - stable - nightly steps: diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index 17e37767d..d41449d05 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -24,7 +24,7 @@ jobs: - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: - toolchain: 1.82.0 + toolchain: 1.84.0 components: clippy - run: cargo clippy --all --all-features --tests -- -D warnings diff --git a/Cargo.lock b/Cargo.lock index 9bb81b27f..9d8b6503c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -293,9 +293,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.6.0-rc.6" +version = "0.6.0-rc.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d748d1f5b807ee6d0df5a548d0130417295c3aaed1dcbbb3d6a2e7106e11fcca" +checksum = "e5b2d0aa9f9958eea3b6b6ecb18ee55408f0065a9ea96f777ecdb5fa55ebbcfc" dependencies = [ "hybrid-array", "num-traits", @@ -490,7 +490,7 @@ version = "0.14.0-rc.1" dependencies = [ "base16ct", "base64ct", - "crypto-bigint 0.6.0-rc.6", + "crypto-bigint 0.6.0-rc.8", "digest 0.11.0-pre.9", "ff 0.13.0", "group 0.13.0", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 775da9017..f3c42fb46 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -14,11 +14,11 @@ readme = "README.md" categories = ["cryptography", "no-std"] keywords = ["crypto", "ecc", "elliptic", "weierstrass"] edition = "2021" -rust-version = "1.81" +rust-version = "1.83" [dependencies] base16ct = "0.2" -crypto-bigint = { version = "0.6.0-rc.6", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } +crypto-bigint = { version = "0.6.0-rc.8", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } hybrid-array = { version = "0.2", default-features = false, features = ["zeroize"] } rand_core = { version = "0.6.4", default-features = false } subtle = { version = "2.6", default-features = false } diff --git a/elliptic-curve/README.md b/elliptic-curve/README.md index 0c8fad474..218d70eb9 100644 --- a/elliptic-curve/README.md +++ b/elliptic-curve/README.md @@ -15,7 +15,7 @@ and public/secret keys composed thereof. ## Minimum Supported Rust Version -Requires Rust **1.81** or higher. +Requires Rust **1.83** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -49,6 +49,6 @@ dual licensed as above, without any additional terms or conditions. [build-image]: https://github.com/RustCrypto/traits/actions/workflows/elliptic-curve.yml/badge.svg [build-link]: https://github.com/RustCrypto/traits/actions/workflows/elliptic-curve.yml [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.81+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.83+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260040-elliptic-curves From dda961540dedb487bd5c8f9ff63c704a98959e62 Mon Sep 17 00:00:00 2001 From: CODe <71spates.bravest@icloud.com> Date: Tue, 21 Jan 2025 19:25:02 +0100 Subject: [PATCH 1266/1461] minor typo CHANGELOG.md (#1727) I fixed a typo in the CHANGELOG.md file, correcting the misspelling of "Ouput" to "Output". --- universal-hash/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/universal-hash/CHANGELOG.md b/universal-hash/CHANGELOG.md index 3ff8bb0fa..1ee729f8a 100644 --- a/universal-hash/CHANGELOG.md +++ b/universal-hash/CHANGELOG.md @@ -51,7 +51,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Rust 2021 edition; MSRV 1.56 ([#1051]) ### Removed -- `Ouput` replaced by `Block` ([#1051]) +- `Output` replaced by `Block` ([#1051]) - `UniversalHash::reset` replaced with `Reset` trait from `crypto-common` ([#1051]) [#1051]: https://github.com/RustCrypto/traits/pull/1051 From aa00ba444f0ac9c0c7500948c8da7af625b4024f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 23 Jan 2025 16:14:38 -0700 Subject: [PATCH 1267/1461] build(deps): bump crypto-bigint from 0.6.0-rc.8 to 0.6 (#1731) --- Cargo.lock | 6 +++--- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9d8b6503c..eb4d560e7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -293,9 +293,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.6.0-rc.8" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5b2d0aa9f9958eea3b6b6ecb18ee55408f0065a9ea96f777ecdb5fa55ebbcfc" +checksum = "4919aa33c410cb537c1b2a8458a896f9e47ed4349a2002e5b240f358f7bf6ffc" dependencies = [ "hybrid-array", "num-traits", @@ -490,7 +490,7 @@ version = "0.14.0-rc.1" dependencies = [ "base16ct", "base64ct", - "crypto-bigint 0.6.0-rc.8", + "crypto-bigint 0.6.0", "digest 0.11.0-pre.9", "ff 0.13.0", "group 0.13.0", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index f3c42fb46..c04a8249a 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -18,7 +18,7 @@ rust-version = "1.83" [dependencies] base16ct = "0.2" -crypto-bigint = { version = "0.6.0-rc.8", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } +crypto-bigint = { version = "0.6", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } hybrid-array = { version = "0.2", default-features = false, features = ["zeroize"] } rand_core = { version = "0.6.4", default-features = false } subtle = { version = "2.6", default-features = false } From 33933561d1226918c02f0a58e9bf6a71f430fb4d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 28 Jan 2025 12:40:59 -0700 Subject: [PATCH 1268/1461] CI: add `typos` job (#1734) This should hopefully cut down on the number of typo-fixing PRs we receive by automatically checking for them in CI: https://github.com/crate-ci/typos --- .github/workflows/workspace.yml | 6 ++++++ .typos.toml | 10 ++++++++++ elliptic-curve/CHANGELOG.md | 2 +- 3 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 .typos.toml diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index d41449d05..dd85b43ae 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -47,3 +47,9 @@ jobs: toolchain: stable components: rustfmt - run: cargo fmt --all -- --check + + typos: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: crate-ci/typos@v1.29.4 diff --git a/.typos.toml b/.typos.toml new file mode 100644 index 000000000..6ae4f522c --- /dev/null +++ b/.typos.toml @@ -0,0 +1,10 @@ +[files] +extend-exclude = [ + ".git/", + "elliptic-curve/src/jwk.rs", + "signature/tests/derive.rs" +] + +[default.extend-words] +# Authenticated Key Exchange +"AKE" = "AKE" diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index 3f47710eb..37b563149 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -198,7 +198,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Move `hash2field` into `hash2curve` module ([#903]) - Bump `ff` and `group` dependencies to v0.12 ([#994]) - Use `serdect` crate ([#996]) -- Replace `AlgorithmParamters` with `AssociatedOid` ([#1001]) +- Replace `AlgorithmParameters` with `AssociatedOid` ([#1001]) - Bump `crypto-bigint` dependency to v0.4 ([#1005]) - Bump `der` dependency to v0.6 ([#1006]) - Bump `pkcs8` dependency to v0.9 ([#1006]) From 0596378b8b10d55d58155849bca2b34e225e3d71 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 28 Jan 2025 13:36:35 -0700 Subject: [PATCH 1269/1461] CI: add `typos` config for ignoring Base64 (#1735) Uses a regex to detect strings that appear to be sequences of Base64-encoded characters, and re-enables the lint for the JWK implementation in `elliptic-curve` --- .typos.toml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.typos.toml b/.typos.toml index 6ae4f522c..bf37da832 100644 --- a/.typos.toml +++ b/.typos.toml @@ -1,10 +1,16 @@ [files] extend-exclude = [ ".git/", - "elliptic-curve/src/jwk.rs", "signature/tests/derive.rs" ] +[default] +extend-ignore-re = [ + # Patterns which appear to be 36 or more characters of Base64/Base64url + '\b[0-9A-Za-z+/]{36,}\b', + '\b[0-9A-Za-z_-]{36,}\b', +] + [default.extend-words] # Authenticated Key Exchange "AKE" = "AKE" From fb85f4677002dce1352f6ac46e023443be8258d0 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 28 Jan 2025 16:11:18 -0700 Subject: [PATCH 1270/1461] aead: remove `AeadCore::CiphertextOverhead` (#1737) This size was intended for AEADs based on padded block cipher modes such as CBC in order to express the underlying cipher's block size and therefore the maximum amount of possible padding overhead beyond the original plaintext, which is a full block (in the case a sentinel block is added to a block-aligned plaintext input). However, every AEAD we implement uses counter mode, i.e. a stream cipher instead of a block cipher, which has no overhead, and as such `CiphertextOverhead` is set to `U0` in every AEAD implementation we currently maintain. Furthermore, to my knowledge there are no standard AEADs which use CBC or other padded block cipher modes of operation. The original goal was to support an expired draft specification of a CBC+HMAC AEAD. Since it doesn't appear to be of use, this PR removes it. --- aead/src/lib.rs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/aead/src/lib.rs b/aead/src/lib.rs index 2a3560c21..dc7f6bce1 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -85,10 +85,6 @@ pub trait AeadCore { /// The maximum length of the tag. type TagSize: ArraySize; - /// The upper bound amount of additional space required to support a - /// ciphertext vs. a plaintext. - type CiphertextOverhead: ArraySize + Unsigned; - /// Generate a random nonce for this AEAD algorithm. /// /// AEAD algorithms accept a parameter to encryption/decryption called @@ -575,11 +571,9 @@ mod tests { /// Ensure that `AeadInPlace` is object-safe #[allow(dead_code)] - type DynAeadInPlace = - dyn AeadInPlace; + type DynAeadInPlace = dyn AeadInPlace; /// Ensure that `AeadMutInPlace` is object-safe #[allow(dead_code)] - type DynAeadMutInPlace = - dyn AeadMutInPlace; + type DynAeadMutInPlace = dyn AeadMutInPlace; } From 1a770afb1818162f9958d0dff70f3504f4f6e73d Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Thu, 30 Jan 2025 23:15:12 +0300 Subject: [PATCH 1271/1461] cipher: add traits for tweakable block ciphers (#1721) The trait design generally follows the `BlockCipherEnc/Dec` traits. We currently do not have tweakable block cipher implementations which use the backend capability, but I think it's still worth to include it for API consistency and to future-proof the traits. Some of the helper methods (e.g. `encrypt_blocks`) are not translated since it's unclear how to organize passing of tweaks. Arguably, such methods should not be used with tweakable block ciphers either way. As a bridge between tweakable and non-tweakable traits the `ZeroTweak` wrapper is introduced. It allows users to use tweakable block cipher implementations with the parts of the ecosystem which expects non-tweakble block ciphers while still being explicit in the code (e.g. `ZeroTweak`). --- cipher/src/lib.rs | 2 + cipher/src/tweak.rs | 152 +++++++++++++++++++++++++++++++++++++++ cipher/src/tweak/ctx.rs | 41 +++++++++++ cipher/src/tweak/zero.rs | 118 ++++++++++++++++++++++++++++++ 4 files changed, 313 insertions(+) create mode 100644 cipher/src/tweak.rs create mode 100644 cipher/src/tweak/ctx.rs create mode 100644 cipher/src/tweak/zero.rs diff --git a/cipher/src/lib.rs b/cipher/src/lib.rs index 7e34bba0c..9fff63c52 100644 --- a/cipher/src/lib.rs +++ b/cipher/src/lib.rs @@ -36,9 +36,11 @@ pub mod block; #[cfg(feature = "dev")] mod dev; pub mod stream; +pub mod tweak; pub use block::*; pub use stream::*; +pub use tweak::*; pub use crypto_common::{ array::{self, Array}, diff --git a/cipher/src/tweak.rs b/cipher/src/tweak.rs new file mode 100644 index 000000000..ec3cb432e --- /dev/null +++ b/cipher/src/tweak.rs @@ -0,0 +1,152 @@ +//! Traits used to define functionality of [tweakable block ciphers][1]. +//! +//! [1]: https://people.eecs.berkeley.edu/~daw/papers/tweak-crypto02.pdf +use crypto_common::{ + array::{Array, ArraySize}, + Block, BlockSizeUser, +}; +use inout::InOut; + +mod ctx; +mod zero; + +pub use zero::ZeroTweak; + +/// Tweak used by a [`TweakSizeUser`] implementor. +pub type Tweak = Array::TweakSize>; + +/// Trait which contains tweak size used by the tweak cipher traits. +pub trait TweakSizeUser { + /// Size of the tweak in bytes. + type TweakSize: ArraySize; +} + +/// Encrypt-only functionality for tweakable block ciphers. +pub trait TweakBlockCipherEncrypt: BlockSizeUser + TweakSizeUser + Sized { + /// Encrypt data using backend provided to the rank-2 closure. + fn encrypt_with_backend( + &self, + f: impl TweakBlockCipherEncClosure, + ); + + /// Encrypt single `inout` block. + #[inline] + fn encrypt_block_inout(&self, tweak: &Tweak, block: InOut<'_, '_, Block>) { + self.encrypt_with_backend(ctx::BlockCtx { tweak, block }); + } + + /// Encrypt single block in-place. + #[inline] + fn encrypt_block(&self, tweak: &Tweak, block: &mut Block) { + self.encrypt_block_inout(tweak, block.into()); + } + + /// Encrypt `in_block` and write result to `out_block`. + #[inline] + fn encrypt_block_b2b( + &self, + tweak: &Tweak, + in_block: &Block, + out_block: &mut Block, + ) { + self.encrypt_block_inout(tweak, (in_block, out_block).into()); + } +} + +/// Decrypt-only functionality for tweakable block ciphers. +pub trait TweakBlockCipherDecrypt: BlockSizeUser + TweakSizeUser + Sized { + /// Decrypt data using backend provided to the rank-2 closure. + fn decrypt_with_backend( + &self, + f: impl TweakBlockCipherDecClosure, + ); + + /// Decrypt single `inout` block. + #[inline] + fn decrypt_block_inout(&self, tweak: &Tweak, block: InOut<'_, '_, Block>) { + self.decrypt_with_backend(ctx::BlockCtx { tweak, block }); + } + + /// Decrypt single block in-place. + #[inline] + fn decrypt_block(&self, tweak: &Tweak, block: &mut Block) { + self.decrypt_block_inout(tweak, block.into()); + } + + /// Decrypt `in_block` and write result to `out_block`. + #[inline] + fn decrypt_block_b2b( + &self, + tweak: &Tweak, + in_block: &Block, + out_block: &mut Block, + ) { + self.decrypt_block_inout(tweak, (in_block, out_block).into()); + } +} + +/// Trait for [`TweakBlockCipherEncBackend`] users. +/// +/// This trait is used to define rank-2 closures. +pub trait TweakBlockCipherEncClosure: BlockSizeUser + TweakSizeUser { + /// Execute closure with the provided block cipher backend. + fn call(self, backend: &B) + where + B: TweakBlockCipherEncBackend; +} + +/// Trait for [`TweakBlockCipherDecBackend`] users. +/// +/// This trait is used to define rank-2 closures. +pub trait TweakBlockCipherDecClosure: BlockSizeUser + TweakSizeUser { + /// Execute closure with the provided block cipher backend. + fn call(self, backend: &B) + where + B: TweakBlockCipherDecBackend; +} + +/// Trait implemented by block cipher mode encryption backends. +pub trait TweakBlockCipherEncBackend: BlockSizeUser + TweakSizeUser { + /// Encrypt single inout block. + fn encrypt_block_inout(&self, tweak: &Tweak, block: InOut<'_, '_, Block>); + + /// Encrypt single block in-place. + #[inline] + fn encrypt_block(&self, tweak: &Tweak, block: &mut Block) { + self.encrypt_block_inout(tweak, block.into()); + } + + /// Encrypt `in_block` and write result to `out_block`. + #[inline] + fn encrypt_block_b2b( + &self, + tweak: &Tweak, + in_block: &Block, + out_block: &mut Block, + ) { + self.encrypt_block_inout(tweak, (in_block, out_block).into()); + } +} + +/// Trait implemented by block cipher mode decryption backends. +pub trait TweakBlockCipherDecBackend: BlockSizeUser + TweakSizeUser { + /// Decrypt single inout block. + fn decrypt_block_inout(&self, tweak: &Tweak, block: InOut<'_, '_, Block>); + + /// Decrypt single block in-place. + #[inline] + fn decrypt_block(&self, tweak: &Tweak, block: &mut Block) { + self.decrypt_block_inout(tweak, block.into()); + } + + /// Decrypt `in_block` and write result to `out_block`. + #[inline] + fn decrypt_block_b2b( + &self, + tweak: &Tweak, + in_block: &Block, + out_block: &mut Block, + ) { + self.decrypt_block_inout(tweak, (in_block, out_block).into()); + } +} diff --git a/cipher/src/tweak/ctx.rs b/cipher/src/tweak/ctx.rs new file mode 100644 index 000000000..65ca6a557 --- /dev/null +++ b/cipher/src/tweak/ctx.rs @@ -0,0 +1,41 @@ +use crypto_common::{array::ArraySize, Block, BlockSizeUser, BlockSizes}; +use inout::InOut; + +use super::{ + Tweak, TweakBlockCipherDecBackend, TweakBlockCipherDecClosure, TweakBlockCipherEncBackend, + TweakBlockCipherEncClosure, TweakSizeUser, +}; + +/// Closure used in methods which operate over separate blocks. +pub(super) struct BlockCtx<'a, TS: ArraySize, BS: BlockSizes> { + pub tweak: &'a Tweak, + pub block: InOut<'a, 'a, Block>, +} + +impl BlockSizeUser for BlockCtx<'_, TS, BS> { + type BlockSize = BS; +} + +impl TweakSizeUser for BlockCtx<'_, TS, BS> { + type TweakSize = TS; +} + +impl TweakBlockCipherEncClosure for BlockCtx<'_, TS, BS> { + #[inline] + fn call(self, backend: &B) + where + B: TweakBlockCipherEncBackend, + { + backend.encrypt_block_inout(self.tweak, self.block); + } +} + +impl TweakBlockCipherDecClosure for BlockCtx<'_, TS, BS> { + #[inline] + fn call(self, backend: &B) + where + B: TweakBlockCipherDecBackend, + { + backend.decrypt_block_inout(self.tweak, self.block); + } +} diff --git a/cipher/src/tweak/zero.rs b/cipher/src/tweak/zero.rs new file mode 100644 index 000000000..9bebf1a90 --- /dev/null +++ b/cipher/src/tweak/zero.rs @@ -0,0 +1,118 @@ +use core::marker::PhantomData; + +use crypto_common::{array::ArraySize, Block, BlockSizes, ParBlocksSizeUser}; + +use super::{ + TweakBlockCipherDecBackend, TweakBlockCipherDecClosure, TweakBlockCipherDecrypt, + TweakBlockCipherEncBackend, TweakBlockCipherEncrypt, TweakSizeUser, +}; +use crate::{ + consts::U1, tweak::TweakBlockCipherEncClosure, BlockCipherDecBackend, BlockCipherDecClosure, + BlockCipherDecrypt, BlockCipherEncBackend, BlockCipherEncClosure, BlockCipherEncrypt, + BlockSizeUser, +}; + +/// Wrapper around tweakable block cipher which implements +/// the [common block cipher traits][crate::block] using zero tweak. +#[derive(Debug, Clone)] +pub struct ZeroTweak(pub C); + +impl BlockSizeUser for ZeroTweak { + type BlockSize = C::BlockSize; +} + +impl BlockCipherEncrypt for ZeroTweak { + #[inline] + fn encrypt_with_backend(&self, f: impl BlockCipherEncClosure) { + self.0.encrypt_with_backend(ClosureWrapper { + f, + _pd: PhantomData, + }); + } +} + +impl BlockCipherDecrypt for ZeroTweak { + #[inline] + fn decrypt_with_backend(&self, f: impl BlockCipherDecClosure) { + self.0.decrypt_with_backend(ClosureWrapper { + f, + _pd: PhantomData, + }); + } +} + +/// Wrapper around non-tweakble block cipher closures which implements the tweakable +/// block cipher closure traits using zero tweak. +struct ClosureWrapper { + f: F, + _pd: PhantomData<(TS, BS)>, +} + +impl BlockSizeUser for ClosureWrapper { + type BlockSize = BS; +} + +impl TweakSizeUser for ClosureWrapper { + type TweakSize = TS; +} + +impl TweakBlockCipherEncClosure for ClosureWrapper +where + F: BlockCipherEncClosure, +{ + #[inline] + fn call>(self, backend: &B) { + self.f.call(&BackendWrapper { + backend, + _pd: PhantomData, + }) + } +} + +impl TweakBlockCipherDecClosure for ClosureWrapper +where + F: BlockCipherDecClosure, +{ + #[inline] + fn call>(self, backend: &B) { + self.f.call(&BackendWrapper { + backend, + _pd: PhantomData, + }) + } +} + +/// Wrapper around tweakable block cipher backend which implements non-tweakable +/// block cipher backend traits using zero tweak. +struct BackendWrapper<'a, BS: BlockSizes, B> { + backend: &'a B, + _pd: PhantomData, +} + +impl BlockSizeUser for BackendWrapper<'_, BS, B> { + type BlockSize = BS; +} + +impl ParBlocksSizeUser for BackendWrapper<'_, BS, B> { + type ParBlocksSize = U1; +} + +impl BlockCipherEncBackend for BackendWrapper<'_, BS, B> +where + B: TweakBlockCipherEncBackend, +{ + #[inline] + fn encrypt_block(&self, block: inout::InOut<'_, '_, Block>) { + self.backend.encrypt_block_inout(&Default::default(), block); + } +} + +impl BlockCipherDecBackend for BackendWrapper<'_, BS, B> +where + B: TweakBlockCipherDecBackend, +{ + #[inline] + fn decrypt_block(&self, block: inout::InOut<'_, '_, Block>) { + self.backend.decrypt_block_inout(&Default::default(), block); + } +} From 88b327429ebf771e3ded6785442caeb127cb6e58 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 30 Jan 2025 13:24:59 -0700 Subject: [PATCH 1272/1461] aead: remove stateful AEAD traits (`AeadMut*`) (#1740) We currently have no implementations which require these traits, or plans to implement any. If we do wind up needing these, they can be easily added back. --- aead/src/lib.rs | 187 +++--------------------------------------------- 1 file changed, 10 insertions(+), 177 deletions(-) diff --git a/aead/src/lib.rs b/aead/src/lib.rs index dc7f6bce1..7f35e4571 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -149,9 +149,6 @@ pub trait AeadCore { } /// Authenticated Encryption with Associated Data (AEAD) algorithm. -/// -/// This trait is intended for use with stateless AEAD algorithms. The -/// [`AeadMut`] trait provides a stateful interface. #[cfg(feature = "alloc")] pub trait Aead: AeadCore { /// Encrypt the given plaintext payload, and return the resulting @@ -207,53 +204,6 @@ pub trait Aead: AeadCore { ) -> Result>; } -/// Stateful Authenticated Encryption with Associated Data algorithm. -#[cfg(feature = "alloc")] -pub trait AeadMut: AeadCore { - /// Encrypt the given plaintext slice, and return the resulting ciphertext - /// as a vector of bytes. - /// - /// See notes on [`Aead::encrypt()`] about allowable message payloads and - /// Associated Additional Data (AAD). - fn encrypt<'msg, 'aad>( - &mut self, - nonce: &Nonce, - plaintext: impl Into>, - ) -> Result>; - - /// Decrypt the given ciphertext slice, and return the resulting plaintext - /// as a vector of bytes. - /// - /// See notes on [`Aead::encrypt()`] and [`Aead::decrypt()`] about allowable - /// message payloads and Associated Additional Data (AAD). - fn decrypt<'msg, 'aad>( - &mut self, - nonce: &Nonce, - ciphertext: impl Into>, - ) -> Result>; -} - -/// Implement the `decrypt_in_place` method on [`AeadInPlace`] and -/// [`AeadMutInPlace]`, using a macro to gloss over the `&self` vs `&mut self`. -/// -/// Assumes a postfix authentication tag. AEAD ciphers which do not use a -/// postfix authentication tag will need to define their own implementation. -macro_rules! impl_decrypt_in_place { - ($aead:expr, $nonce:expr, $aad:expr, $buffer:expr) => {{ - let tag_pos = $buffer - .len() - .checked_sub(Self::TagSize::to_usize()) - .ok_or(Error)?; - - let (msg, tag) = $buffer.as_mut().split_at_mut(tag_pos); - let tag = Tag::::try_from(&*tag).expect("tag length mismatch"); - - $aead.decrypt_in_place_detached($nonce, $aad, msg, &tag)?; - $buffer.truncate(tag_pos); - Ok(()) - }}; -} - /// In-place stateless AEAD trait. /// /// This trait is both object safe and has no dependencies on `alloc` or `std`. @@ -297,72 +247,24 @@ pub trait AeadInPlace: AeadCore { associated_data: &[u8], buffer: &mut dyn Buffer, ) -> Result<()> { - impl_decrypt_in_place!(self, nonce, associated_data, buffer) - } + let tag_pos = buffer + .len() + .checked_sub(Self::TagSize::to_usize()) + .ok_or(Error)?; - /// Decrypt the message in-place, returning an error in the event the provided - /// authentication tag does not match the given ciphertext (i.e. ciphertext - /// is modified/unauthentic) - fn decrypt_in_place_detached( - &self, - nonce: &Nonce, - associated_data: &[u8], - buffer: &mut [u8], - tag: &Tag, - ) -> Result<()>; -} + let (msg, tag) = buffer.as_mut().split_at_mut(tag_pos); + let tag = Tag::::try_from(&*tag).expect("tag length mismatch"); -/// In-place stateful AEAD trait. -/// -/// This trait is both object safe and has no dependencies on `alloc` or `std`. -pub trait AeadMutInPlace: AeadCore { - /// Encrypt the given buffer containing a plaintext message in-place. - /// - /// The buffer must have sufficient capacity to store the ciphertext - /// message, which will always be larger than the original plaintext. - /// The exact size needed is cipher-dependent, but generally includes - /// the size of an authentication tag. - /// - /// Returns an error if the buffer has insufficient capacity to store the - /// resulting ciphertext message. - fn encrypt_in_place( - &mut self, - nonce: &Nonce, - associated_data: &[u8], - buffer: &mut impl Buffer, - ) -> Result<()> { - let tag = self.encrypt_in_place_detached(nonce, associated_data, buffer.as_mut())?; - buffer.extend_from_slice(tag.as_slice())?; + self.decrypt_in_place_detached(nonce, associated_data, msg, &tag)?; + buffer.truncate(tag_pos); Ok(()) } - /// Encrypt the data in-place, returning the authentication tag - fn encrypt_in_place_detached( - &mut self, - nonce: &Nonce, - associated_data: &[u8], - buffer: &mut [u8], - ) -> Result>; - - /// Decrypt the message in-place, returning an error in the event the - /// provided authentication tag does not match the given ciphertext. - /// - /// The buffer will be truncated to the length of the original plaintext - /// message upon success. - fn decrypt_in_place( - &mut self, - nonce: &Nonce, - associated_data: &[u8], - buffer: &mut impl Buffer, - ) -> Result<()> { - impl_decrypt_in_place!(self, nonce, associated_data, buffer) - } - - /// Decrypt the data in-place, returning an error in the event the provided + /// Decrypt the message in-place, returning an error in the event the provided /// authentication tag does not match the given ciphertext (i.e. ciphertext /// is modified/unauthentic) fn decrypt_in_place_detached( - &mut self, + &self, nonce: &Nonce, associated_data: &[u8], buffer: &mut [u8], @@ -396,71 +298,6 @@ impl Aead for Alg { } } -#[cfg(feature = "alloc")] -impl AeadMut for Alg { - fn encrypt<'msg, 'aad>( - &mut self, - nonce: &Nonce, - plaintext: impl Into>, - ) -> Result> { - let payload = plaintext.into(); - let mut buffer = Vec::with_capacity(payload.msg.len() + Self::TagSize::to_usize()); - buffer.extend_from_slice(payload.msg); - self.encrypt_in_place(nonce, payload.aad, &mut buffer)?; - Ok(buffer) - } - - fn decrypt<'msg, 'aad>( - &mut self, - nonce: &Nonce, - ciphertext: impl Into>, - ) -> Result> { - let payload = ciphertext.into(); - let mut buffer = Vec::from(payload.msg); - self.decrypt_in_place(nonce, payload.aad, &mut buffer)?; - Ok(buffer) - } -} - -impl AeadMutInPlace for Alg { - fn encrypt_in_place( - &mut self, - nonce: &Nonce, - associated_data: &[u8], - buffer: &mut impl Buffer, - ) -> Result<()> { - ::encrypt_in_place(self, nonce, associated_data, buffer) - } - - fn encrypt_in_place_detached( - &mut self, - nonce: &Nonce, - associated_data: &[u8], - buffer: &mut [u8], - ) -> Result> { - ::encrypt_in_place_detached(self, nonce, associated_data, buffer) - } - - fn decrypt_in_place( - &mut self, - nonce: &Nonce, - associated_data: &[u8], - buffer: &mut impl Buffer, - ) -> Result<()> { - ::decrypt_in_place(self, nonce, associated_data, buffer) - } - - fn decrypt_in_place_detached( - &mut self, - nonce: &Nonce, - associated_data: &[u8], - buffer: &mut [u8], - tag: &Tag, - ) -> Result<()> { - ::decrypt_in_place_detached(self, nonce, associated_data, buffer, tag) - } -} - /// AEAD payloads (message + AAD). /// /// Combination of a message (plaintext or ciphertext) and @@ -572,8 +409,4 @@ mod tests { /// Ensure that `AeadInPlace` is object-safe #[allow(dead_code)] type DynAeadInPlace = dyn AeadInPlace; - - /// Ensure that `AeadMutInPlace` is object-safe - #[allow(dead_code)] - type DynAeadMutInPlace = dyn AeadMutInPlace; } From b5fbe3437a83ea1c475b8c524d97660b21da1556 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Fri, 31 Jan 2025 19:35:55 +0300 Subject: [PATCH 1273/1461] Update getrandom to v0.3 (#1741) --- Cargo.lock | 184 ++++++++++++++++++++++++++++++--------- aead/src/lib.rs | 2 +- crypto-common/Cargo.toml | 2 +- crypto-common/src/lib.rs | 8 +- 4 files changed, 148 insertions(+), 48 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index eb4d560e7..d9498e3ca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -88,6 +88,12 @@ dependencies = [ "serde", ] +[[package]] +name = "bitflags" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" + [[package]] name = "bitvec" version = "1.0.1" @@ -160,15 +166,15 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" +checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" [[package]] name = "cc" -version = "1.2.0" +version = "1.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aeb932158bd710538c73702db6945cb68a8fb08c519e6e12706b94263b36db8" +checksum = "13208fcbb66eaeffe09b99fffbe1af420f00a7b35aa99ad683dfc1aa76145229" dependencies = [ "jobserver", "libc", @@ -222,7 +228,7 @@ version = "0.5.0-pre.7" dependencies = [ "blobby", "crypto-common 0.2.0-rc.1", - "inout 0.2.0-rc.2", + "inout 0.2.0-rc.3", "zeroize", ] @@ -246,9 +252,9 @@ checksum = "68ff6be19477a1bd5441f382916a89bc2a0b2c35db6d41e0f6e8538bf6d6463f" [[package]] name = "cpufeatures" -version = "0.2.15" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ca741a962e1b0bff6d724a1a0958b686406e853bb14061f218562e1896f95e6" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" dependencies = [ "libc", ] @@ -319,7 +325,7 @@ dependencies = [ name = "crypto-common" version = "0.2.0-rc.1" dependencies = [ - "getrandom", + "getrandom 0.3.1", "hybrid-array", "rand_core", ] @@ -562,7 +568,19 @@ checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.13.3+wasi-0.2.2", + "windows-targets", ] [[package]] @@ -577,9 +595,9 @@ dependencies = [ [[package]] name = "glob" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" [[package]] name = "group" @@ -707,9 +725,9 @@ dependencies = [ [[package]] name = "hybrid-array" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45a9a965bb102c1c891fb017c09a05c965186b1265a207640f323ddd009f9deb" +checksum = "f2d35805454dc9f8662a98d6d61886ffe26bd465f5960e0e55345c70d5c0d2a9" dependencies = [ "typenum", "zeroize", @@ -727,9 +745,9 @@ dependencies = [ [[package]] name = "inout" -version = "0.2.0-rc.2" +version = "0.2.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14db49369b2c3f15deb5806de446e05c7f07a2d778b54b278c994fcd1d686f31" +checksum = "de49db00f5add6dad75a57946b75de0f26287a6fc95f4f277d48419200422beb" dependencies = [ "block-padding 0.4.0-rc.2", "hybrid-array", @@ -737,9 +755,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "jobserver" @@ -775,9 +793,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.162" +version = "0.2.169" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" [[package]] name = "memchr" @@ -935,13 +953,13 @@ dependencies = [ [[package]] name = "pqcrypto-internals" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10cdd9eee50fe65bbd4f40211f1a492f1ee52e97a51100950b6f1fa319ab7cd" +checksum = "62cd8ebf02b43967cda06e6a3f54d0bd9659459c3003d16aeedd07b44c6db06c" dependencies = [ "cc", "dunce", - "getrandom", + "getrandom 0.2.15", "libc", ] @@ -975,18 +993,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.89" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" +checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" dependencies = [ "proc-macro2", ] @@ -1024,7 +1042,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom", + "getrandom 0.2.15", ] [[package]] @@ -1038,9 +1056,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.18" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd" [[package]] name = "sec1" @@ -1073,15 +1091,15 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.23" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" +checksum = "f79dfe2d285b0488816f30e700a7438c5a73d816b5b7d3ac72fbc48b0d185e03" [[package]] name = "serde" -version = "1.0.215" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" +checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" dependencies = [ "serde_derive", ] @@ -1097,9 +1115,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.215" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" +checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" dependencies = [ "proc-macro2", "quote", @@ -1108,9 +1126,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.132" +version = "1.0.138" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" +checksum = "d434192e7da787e94a6ea7e9670b26a036d0ca41e0b7efb2676dd32bae872949" dependencies = [ "itoa", "memchr", @@ -1261,9 +1279,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.87" +version = "2.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" +checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80" dependencies = [ "proc-macro2", "quote", @@ -1284,9 +1302,9 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "unicode-ident" -version = "1.0.13" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" +checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034" [[package]] name = "universal-hash" @@ -1318,6 +1336,88 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasi" +version = "0.13.3+wasi-0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2" +dependencies = [ + "wit-bindgen-rt", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "wit-bindgen-rt" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" +dependencies = [ + "bitflags", +] + [[package]] name = "wyz" version = "0.5.1" @@ -1346,7 +1446,7 @@ dependencies = [ "base64ct", "bincode", "const-oid 0.6.2", - "getrandom", + "getrandom 0.2.15", "hkdf 0.11.0", "p256 0.9.0", "rand_core", diff --git a/aead/src/lib.rs b/aead/src/lib.rs index 7f35e4571..5fbea4cc9 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -126,7 +126,7 @@ pub trait AeadCore { Nonce: Default, { let mut nonce = Nonce::::default(); - getrandom::getrandom(&mut nonce)?; + getrandom::fill(&mut nonce)?; Ok(nonce) } diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index 29ebe30a6..93b08c1c1 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -17,7 +17,7 @@ hybrid-array = "0.2" # optional dependencies rand_core = { version = "0.6.4", optional = true } -getrandom = { version = "0.2", optional = true } +getrandom = { version = "0.3", optional = true } [features] getrandom = ["dep:getrandom", "rand_core?/getrandom"] diff --git a/crypto-common/src/lib.rs b/crypto-common/src/lib.rs index 7721b86f6..3b503d4c6 100644 --- a/crypto-common/src/lib.rs +++ b/crypto-common/src/lib.rs @@ -176,7 +176,7 @@ pub trait KeyInit: KeySizeUser + Sized { #[inline] fn generate_key() -> Result, getrandom::Error> { let mut key = Key::::default(); - getrandom::getrandom(&mut key)?; + getrandom::fill(&mut key)?; Ok(key) } @@ -208,7 +208,7 @@ pub trait KeyIvInit: KeySizeUser + IvSizeUser + Sized { #[inline] fn generate_key() -> Result, getrandom::Error> { let mut key = Key::::default(); - getrandom::getrandom(&mut key)?; + getrandom::fill(&mut key)?; Ok(key) } @@ -226,7 +226,7 @@ pub trait KeyIvInit: KeySizeUser + IvSizeUser + Sized { #[inline] fn generate_iv() -> Result, getrandom::Error> { let mut iv = Iv::::default(); - getrandom::getrandom(&mut iv)?; + getrandom::fill(&mut iv)?; Ok(iv) } @@ -288,7 +288,7 @@ pub trait InnerIvInit: InnerUser + IvSizeUser + Sized { #[inline] fn generate_iv() -> Result, getrandom::Error> { let mut iv = Iv::::default(); - getrandom::getrandom(&mut iv)?; + getrandom::fill(&mut iv)?; Ok(iv) } From 99f7bc9c264ebae9ee31a5327c3e3202e77c09f7 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Sat, 1 Feb 2025 03:26:44 +0300 Subject: [PATCH 1274/1461] crypto-common: add methods for weak key testing (#1742) --- crypto-common/src/lib.rs | 54 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/crypto-common/src/lib.rs b/crypto-common/src/lib.rs index 3b503d4c6..79f7857cf 100644 --- a/crypto-common/src/lib.rs +++ b/crypto-common/src/lib.rs @@ -163,6 +163,19 @@ pub trait KeyInit: KeySizeUser + Sized { /// Create new value from fixed size key. fn new(key: &Key) -> Self; + /// Check if the key might be considered weak. + #[inline] + fn weak_key_test(_key: &Key) -> Result<(), WeakKeyError> { + Ok(()) + } + + /// Create new value from fixed size key after checking it for weakness. + #[inline] + fn new_checked(key: &Key) -> Result { + Self::weak_key_test(key)?; + Ok(Self::new(key)) + } + /// Create new value from variable size key. #[inline] fn new_from_slice(key: &[u8]) -> Result { @@ -195,6 +208,19 @@ pub trait KeyIvInit: KeySizeUser + IvSizeUser + Sized { /// Create new value from fixed length key and nonce. fn new(key: &Key, iv: &Iv) -> Self; + /// Check if the key might be considered weak. + #[inline] + fn weak_key_test(_key: &Key) -> Result<(), WeakKeyError> { + Ok(()) + } + + /// Create new value from fixed length key and nonce after checking the key for weakness. + #[inline] + fn new_checked(key: &Key, iv: &Iv) -> Result { + Self::weak_key_test(key)?; + Ok(Self::new(key, iv)) + } + /// Create new value from variable length key and nonce. #[inline] fn new_from_slices(key: &[u8], iv: &[u8]) -> Result { @@ -330,6 +356,11 @@ where fn new_from_slices(key: &[u8], iv: &[u8]) -> Result { T::Inner::new_from_slice(key).and_then(|i| T::inner_iv_slice_init(i, iv)) } + + #[inline] + fn weak_key_test(key: &Key) -> Result<(), WeakKeyError> { + T::Inner::weak_key_test(key) + } } impl KeyInit for T @@ -348,6 +379,11 @@ where .map_err(|_| InvalidLength) .map(Self::inner_init) } + + #[inline] + fn weak_key_test(key: &Key) -> Result<(), WeakKeyError> { + T::Inner::weak_key_test(key) + } } // Unfortunately this blanket impl is impossible without mutually @@ -370,6 +406,11 @@ where .map_err(|_| InvalidLength) .map(Self::inner_init) } + + #[inline] + fn weak_key_test(key: &Key) -> Result<(), WeakKeyError> { + T::Inner::weak_key_test(key) + } } */ @@ -387,3 +428,16 @@ impl fmt::Display for InvalidLength { } impl core::error::Error for InvalidLength {} + +/// The error type returned when a key is found to be weak. +#[derive(Copy, Clone, Eq, PartialEq, Debug)] +pub struct WeakKeyError; + +impl fmt::Display for WeakKeyError { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + f.write_str("WeakKey") + } +} + +impl core::error::Error for WeakKeyError {} From efe27ed0cca4ac6bc1ce993c8e49b156cd74f9d8 Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Tue, 11 Feb 2025 14:18:47 -0800 Subject: [PATCH 1275/1461] cipher: propagate the zeroize to hybrid-array (#1747) Example use: https://github.com/RustCrypto/block-ciphers/pull/467 --- cipher/Cargo.toml | 1 + crypto-common/Cargo.toml | 1 + 2 files changed, 2 insertions(+) diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index 95c239f7a..9f3d430af 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -26,6 +26,7 @@ block-padding = ["inout/block-padding"] # Enable random key and IV generation methods rand_core = ["crypto-common/rand_core"] dev = ["blobby"] +zeroize = ["dep:zeroize", "crypto-common/zeroize"] [package.metadata.docs.rs] all-features = true diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index 93b08c1c1..791a976c8 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -21,6 +21,7 @@ getrandom = { version = "0.3", optional = true } [features] getrandom = ["dep:getrandom", "rand_core?/getrandom"] +zeroize = ["hybrid-array/zeroize"] [package.metadata.docs.rs] all-features = true From 30b826f628665adad481ce5bc355700ff565d06a Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Wed, 12 Feb 2025 17:24:22 +0300 Subject: [PATCH 1276/1461] Partial migration to `rand_core` v0.9 (#1746) `kem` and `elliptic-curve` can not be migrated because of upstream dependencies which still use `rand_core` v0.6 and expose it in their public API. `getrandom` crate features are renamed to `os_rng` following the similar change in `rand_core`. --- Cargo.lock | 97 +++++++++++++++++--------- aead/Cargo.toml | 4 +- aead/src/lib.rs | 40 ++++++----- async-signature/src/lib.rs | 12 ++-- async-signature/tests/mock_impl.rs | 4 +- cipher/Cargo.toml | 1 + crypto-common/Cargo.toml | 6 +- crypto-common/src/lib.rs | 107 ++++++++++++++++++++--------- digest/Cargo.toml | 3 +- password-hash/Cargo.toml | 6 +- password-hash/src/output.rs | 3 +- password-hash/src/salt.rs | 15 +++- signature/Cargo.toml | 3 +- signature/src/error.rs | 13 ---- signature/src/hazmat.rs | 8 +-- signature/src/signer.rs | 16 ++--- universal-hash/Cargo.toml | 2 +- 17 files changed, 206 insertions(+), 134 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d9498e3ca..bd4561be6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -166,15 +166,15 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" +checksum = "f61dac84819c6588b558454b194026eb1f09c293b9036ae9b159e74e73ab6cf9" [[package]] name = "cc" -version = "1.2.10" +version = "1.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13208fcbb66eaeffe09b99fffbe1af420f00a7b35aa99ad683dfc1aa76145229" +checksum = "c7777341816418c02e033934a09f20dc0ccaf65a5201ef8a450ae0105a573fda" dependencies = [ "jobserver", "libc", @@ -280,7 +280,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8658c15c5d921ddf980f7fe25b1e82f4b7a4083b2c4985fea4922edb8e43e07d" dependencies = [ "generic-array", - "rand_core", + "rand_core 0.6.4", "subtle", "zeroize", ] @@ -292,7 +292,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ "generic-array", - "rand_core", + "rand_core 0.6.4", "subtle", "zeroize", ] @@ -305,7 +305,7 @@ checksum = "4919aa33c410cb537c1b2a8458a896f9e47ed4349a2002e5b240f358f7bf6ffc" dependencies = [ "hybrid-array", "num-traits", - "rand_core", + "rand_core 0.6.4", "subtle", "zeroize", ] @@ -317,7 +317,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", - "rand_core", + "rand_core 0.6.4", "typenum", ] @@ -325,9 +325,8 @@ dependencies = [ name = "crypto-common" version = "0.2.0-rc.1" dependencies = [ - "getrandom 0.3.1", "hybrid-array", - "rand_core", + "rand_core 0.9.0", ] [[package]] @@ -465,7 +464,7 @@ dependencies = [ "generic-array", "group 0.10.0", "pkcs8 0.7.6", - "rand_core", + "rand_core 0.6.4", "subtle", "zeroize", ] @@ -484,7 +483,7 @@ dependencies = [ "group 0.13.0", "hkdf 0.12.4", "pkcs8 0.10.2", - "rand_core", + "rand_core 0.6.4", "sec1 0.7.3", "subtle", "zeroize", @@ -505,7 +504,7 @@ dependencies = [ "hybrid-array", "pem-rfc7468 1.0.0-rc.2", "pkcs8 0.11.0-rc.1", - "rand_core", + "rand_core 0.6.4", "sec1 0.8.0-rc.3", "serde_json", "serdect", @@ -522,7 +521,7 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0f40b2dcd8bc322217a5f6559ae5f9e9d1de202a2ecee2e9eafcbece7562a4f" dependencies = [ - "rand_core", + "rand_core 0.6.4", "subtle", ] @@ -533,7 +532,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ "bitvec", - "rand_core", + "rand_core 0.6.4", "subtle", ] @@ -606,7 +605,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c363a5301b8f153d80747126a04b3c82073b9fe3130571a9d170cacdeaf7912" dependencies = [ "ff 0.10.1", - "rand_core", + "rand_core 0.6.4", "subtle", ] @@ -617,7 +616,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff 0.13.0", - "rand_core", + "rand_core 0.6.4", "subtle", ] @@ -716,7 +715,7 @@ dependencies = [ "hkdf 0.12.4", "hmac 0.12.1", "p256 0.13.2", - "rand_core", + "rand_core 0.6.4", "sha2 0.10.8", "subtle", "x25519-dalek", @@ -786,7 +785,7 @@ dependencies = [ "pqcrypto", "pqcrypto-traits", "rand", - "rand_core", + "rand_core 0.6.4", "x3dh-ke", "zeroize", ] @@ -846,7 +845,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" dependencies = [ "base64ct", - "rand_core", + "rand_core 0.6.4", "subtle", ] @@ -855,7 +854,7 @@ name = "password-hash" version = "0.6.0-rc.0" dependencies = [ "base64ct", - "rand_core", + "rand_core 0.9.0", "subtle", ] @@ -938,7 +937,7 @@ version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" dependencies = [ - "zerocopy", + "zerocopy 0.7.35", ] [[package]] @@ -953,9 +952,9 @@ dependencies = [ [[package]] name = "pqcrypto-internals" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62cd8ebf02b43967cda06e6a3f54d0bd9659459c3003d16aeedd07b44c6db06c" +checksum = "9cc3518d9ec325ec95d89749d4f5c111776b97c5bbd26e3ffe523aa300f1e27e" dependencies = [ "cc", "dunce", @@ -1023,7 +1022,7 @@ checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha", - "rand_core", + "rand_core 0.6.4", ] [[package]] @@ -1033,7 +1032,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", ] [[package]] @@ -1045,6 +1044,16 @@ dependencies = [ "getrandom 0.2.15", ] +[[package]] +name = "rand_core" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b08f3c9802962f7e1b25113931d94f43ed9725bebc59db9d0c3e9a23b67e15ff" +dependencies = [ + "getrandom 0.3.1", + "zerocopy 0.8.17", +] + [[package]] name = "rustc_version" version = "0.4.1" @@ -1204,7 +1213,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2807892cfa58e081aa1f1111391c7a0649d4fa127a4ffbe34bcbfb35a1171a4" dependencies = [ "digest 0.9.0", - "rand_core", + "rand_core 0.6.4", ] [[package]] @@ -1213,7 +1222,7 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ - "rand_core", + "rand_core 0.6.4", ] [[package]] @@ -1222,7 +1231,7 @@ version = "2.3.0-pre.4" dependencies = [ "digest 0.11.0-pre.9", "hex-literal", - "rand_core", + "rand_core 0.9.0", "sha2 0.11.0-pre.4", "signature_derive", ] @@ -1279,9 +1288,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.96" +version = "2.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80" +checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" dependencies = [ "proc-macro2", "quote", @@ -1434,7 +1443,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277" dependencies = [ "curve25519-dalek", - "rand_core", + "rand_core 0.6.4", ] [[package]] @@ -1449,7 +1458,7 @@ dependencies = [ "getrandom 0.2.15", "hkdf 0.11.0", "p256 0.9.0", - "rand_core", + "rand_core 0.6.4", "serde", "serde_bytes", "sha2 0.9.9", @@ -1462,7 +1471,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ "byteorder", - "zerocopy-derive", + "zerocopy-derive 0.7.35", +] + +[[package]] +name = "zerocopy" +version = "0.8.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa91407dacce3a68c56de03abe2760159582b846c6a4acd2f456618087f12713" +dependencies = [ + "zerocopy-derive 0.8.17", ] [[package]] @@ -1476,6 +1494,17 @@ dependencies = [ "syn", ] +[[package]] +name = "zerocopy-derive" +version = "0.8.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06718a168365cad3d5ff0bb133aad346959a2074bd4a85c121255a11304a8626" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "zeroize" version = "1.8.1" diff --git a/aead/Cargo.toml b/aead/Cargo.toml index 9cfaa2ff9..5c6da836f 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -16,7 +16,7 @@ categories = ["cryptography", "no-std"] rust-version = "1.81" [dependencies] -crypto-common = "0.2.0-rc.0" +crypto-common = "0.2.0-rc.1" # optional dependencies arrayvec = { version = "0.7", optional = true, default-features = false } @@ -28,7 +28,7 @@ heapless = { version = "0.8", optional = true, default-features = false } default = ["rand_core"] alloc = [] dev = ["blobby"] -getrandom = ["crypto-common/getrandom"] +os_rng = ["crypto-common/os_rng", "rand_core"] rand_core = ["crypto-common/rand_core"] [package.metadata.docs.rs] diff --git a/aead/src/lib.rs b/aead/src/lib.rs index 5fbea4cc9..cdd28e132 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -30,8 +30,6 @@ pub use crypto_common::{ pub use arrayvec; #[cfg(feature = "bytes")] pub use bytes; -#[cfg(feature = "getrandom")] -pub use crypto_common::rand_core::OsRng; #[cfg(feature = "heapless")] pub use heapless; @@ -45,10 +43,10 @@ use crypto_common::array::{typenum::Unsigned, Array, ArraySize}; use alloc::vec::Vec; #[cfg(feature = "bytes")] use bytes::BytesMut; -#[cfg(feature = "getrandom")] -use crypto_common::getrandom; +#[cfg(feature = "os_rng")] +use crypto_common::rand_core::{OsError, OsRng, TryRngCore}; #[cfg(feature = "rand_core")] -use rand_core::CryptoRngCore; +use rand_core::{CryptoRng, TryCryptoRng}; /// Error type. /// @@ -120,28 +118,32 @@ pub trait AeadCore { /// See the [`stream`] module for a ready-made implementation of the latter. /// /// [NIST SP 800-38D]: https://csrc.nist.gov/publications/detail/sp/800-38d/final - #[cfg(feature = "getrandom")] - fn generate_nonce() -> core::result::Result, getrandom::Error> - where - Nonce: Default, - { + #[cfg(feature = "os_rng")] + fn generate_nonce() -> core::result::Result, OsError> { let mut nonce = Nonce::::default(); - getrandom::fill(&mut nonce)?; + OsRng.try_fill_bytes(&mut nonce)?; Ok(nonce) } - /// Generate a random nonce for this AEAD algorithm using the specified - /// [`CryptoRngCore`]. + /// Generate a random nonce for this AEAD algorithm using the specified [`CryptoRng`]. /// /// See [`AeadCore::generate_nonce`] documentation for requirements for /// random nonces. #[cfg(feature = "rand_core")] - fn generate_nonce_with_rng( - rng: &mut impl CryptoRngCore, - ) -> core::result::Result, rand_core::Error> - where - Nonce: Default, - { + fn generate_nonce_with_rng(rng: &mut R) -> Nonce { + let mut nonce = Nonce::::default(); + rng.fill_bytes(&mut nonce); + nonce + } + + /// Generate a random nonce for this AEAD algorithm using the specified [`TryCryptoRng`]. + /// + /// See [`AeadCore::generate_nonce`] documentation for requirements for + /// random nonces. + #[cfg(feature = "rand_core")] + fn try_generate_nonce_with_rng( + rng: &mut R, + ) -> core::result::Result, R::Error> { let mut nonce = Nonce::::default(); rng.try_fill_bytes(&mut nonce)?; Ok(nonce) diff --git a/async-signature/src/lib.rs b/async-signature/src/lib.rs index 20ebd06d6..68c8aa8ba 100644 --- a/async-signature/src/lib.rs +++ b/async-signature/src/lib.rs @@ -19,7 +19,7 @@ pub use signature::{self, Error}; pub use signature::digest::{self, Digest}; #[cfg(feature = "rand_core")] -use signature::rand_core::CryptoRngCore; +use signature::rand_core::{CryptoRng, TryCryptoRng}; /// Asynchronously sign the provided message bytestring using `Self` /// (e.g. client for a Cloud KMS or HSM), returning a digital signature. @@ -63,7 +63,7 @@ where #[allow(async_fn_in_trait)] pub trait AsyncRandomizedSigner { /// Sign the given message and return a digital signature - async fn sign_with_rng_async(&self, rng: &mut impl CryptoRngCore, msg: &[u8]) -> S { + async fn sign_with_rng_async(&self, rng: &mut R, msg: &[u8]) -> S { self.try_sign_with_rng_async(rng, msg) .await .expect("signature operation failed") @@ -74,9 +74,9 @@ pub trait AsyncRandomizedSigner { /// /// The main intended use case for signing errors is when communicating /// with external signers, e.g. cloud KMS, HSMs, or other hardware tokens. - async fn try_sign_with_rng_async( + async fn try_sign_with_rng_async( &self, - rng: &mut impl CryptoRngCore, + rng: &mut R, msg: &[u8], ) -> Result; } @@ -86,9 +86,9 @@ impl AsyncRandomizedSigner for T where T: signature::RandomizedSigner, { - async fn try_sign_with_rng_async( + async fn try_sign_with_rng_async( &self, - rng: &mut impl CryptoRngCore, + rng: &mut R, msg: &[u8], ) -> Result { self.try_sign_with_rng(rng, msg) diff --git a/async-signature/tests/mock_impl.rs b/async-signature/tests/mock_impl.rs index 20286a22a..5391966b8 100644 --- a/async-signature/tests/mock_impl.rs +++ b/async-signature/tests/mock_impl.rs @@ -28,9 +28,9 @@ where #[cfg(feature = "rand_core")] impl async_signature::AsyncRandomizedSigner for MockSigner { - async fn try_sign_with_rng_async( + async fn try_sign_with_rng_async( &self, - _rng: &mut impl async_signature::signature::rand_core::CryptoRngCore, + _rng: &mut R, _msg: &[u8], ) -> Result { unimplemented!("just meant to check compilation") diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index 9f3d430af..ab140c9d1 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -25,6 +25,7 @@ alloc = [] block-padding = ["inout/block-padding"] # Enable random key and IV generation methods rand_core = ["crypto-common/rand_core"] +os_rng = ["crypto-common/os_rng", "rand_core"] dev = ["blobby"] zeroize = ["dep:zeroize", "crypto-common/zeroize"] diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index 791a976c8..48dcd6909 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -16,11 +16,11 @@ categories = ["cryptography", "no-std"] hybrid-array = "0.2" # optional dependencies -rand_core = { version = "0.6.4", optional = true } -getrandom = { version = "0.3", optional = true } +rand_core = { version = "0.9", optional = true } [features] -getrandom = ["dep:getrandom", "rand_core?/getrandom"] +os_rng = ["rand_core/os_rng", "rand_core"] +rand_core = ["dep:rand_core"] zeroize = ["hybrid-array/zeroize"] [package.metadata.docs.rs] diff --git a/crypto-common/src/lib.rs b/crypto-common/src/lib.rs index 79f7857cf..ddd2db7fe 100644 --- a/crypto-common/src/lib.rs +++ b/crypto-common/src/lib.rs @@ -12,8 +12,6 @@ /// Hazardous materials. pub mod hazmat; -#[cfg(feature = "getrandom")] -pub use getrandom; #[cfg(feature = "rand_core")] pub use rand_core; @@ -27,7 +25,9 @@ use hybrid_array::{ }; #[cfg(feature = "rand_core")] -use rand_core::CryptoRngCore; +use rand_core::{CryptoRng, TryCryptoRng}; +#[cfg(feature = "os_rng")] +use rand_core::{OsError, OsRng, TryRngCore}; /// Block on which [`BlockSizeUser`] implementors operate. pub type Block = Array::BlockSize>; @@ -185,18 +185,27 @@ pub trait KeyInit: KeySizeUser + Sized { } /// Generate random key using the operating system's secure RNG. - #[cfg(feature = "getrandom")] + #[cfg(feature = "os_rng")] #[inline] - fn generate_key() -> Result, getrandom::Error> { + fn generate_key() -> Result, OsError> { let mut key = Key::::default(); - getrandom::fill(&mut key)?; + OsRng.try_fill_bytes(&mut key)?; Ok(key) } - /// Generate random key using the provided [`CryptoRngCore`]. + /// Generate random key using the provided [`CryptoRng`]. #[cfg(feature = "rand_core")] #[inline] - fn generate_key_with_rng(rng: &mut impl CryptoRngCore) -> Result, rand_core::Error> { + fn generate_key_with_rng(rng: &mut R) -> Key { + let mut key = Key::::default(); + rng.fill_bytes(&mut key); + key + } + + /// Generate random key using the provided [`TryCryptoRng`]. + #[cfg(feature = "rand_core")] + #[inline] + fn try_generate_key_with_rng(rng: &mut R) -> Result, R::Error> { let mut key = Key::::default(); rng.try_fill_bytes(&mut key)?; Ok(key) @@ -230,58 +239,85 @@ pub trait KeyIvInit: KeySizeUser + IvSizeUser + Sized { } /// Generate random key using the operating system's secure RNG. - #[cfg(feature = "getrandom")] + #[cfg(feature = "os_rng")] #[inline] - fn generate_key() -> Result, getrandom::Error> { + fn generate_key() -> Result, OsError> { let mut key = Key::::default(); - getrandom::fill(&mut key)?; + OsRng.try_fill_bytes(&mut key)?; Ok(key) } - /// Generate random key using the provided [`CryptoRngCore`]. + /// Generate random key using the provided [`CryptoRng`]. + #[cfg(feature = "rand_core")] + #[inline] + fn generate_key_with_rng(rng: &mut R) -> Key { + let mut key = Key::::default(); + rng.fill_bytes(&mut key); + key + } + + /// Generate random key using the provided [`TryCryptoRng`]. #[cfg(feature = "rand_core")] #[inline] - fn generate_key_with_rng(rng: &mut impl CryptoRngCore) -> Result, rand_core::Error> { + fn try_generate_key_with_rng(rng: &mut R) -> Result, R::Error> { let mut key = Key::::default(); rng.try_fill_bytes(&mut key)?; Ok(key) } /// Generate random IV using the operating system's secure RNG. - #[cfg(feature = "getrandom")] + #[cfg(feature = "os_rng")] #[inline] - fn generate_iv() -> Result, getrandom::Error> { + fn generate_iv() -> Result, OsError> { let mut iv = Iv::::default(); - getrandom::fill(&mut iv)?; + OsRng.try_fill_bytes(&mut iv)?; Ok(iv) } - /// Generate random IV using the provided [`CryptoRngCore`]. + /// Generate random IV using the provided [`CryptoRng`]. + #[cfg(feature = "rand_core")] + #[inline] + fn generate_iv_with_rng(rng: &mut R) -> Iv { + let mut iv = Iv::::default(); + rng.fill_bytes(&mut iv); + iv + } + + /// Generate random IV using the provided [`TryCryptoRng`]. #[cfg(feature = "rand_core")] #[inline] - fn generate_iv_with_rng(rng: &mut impl CryptoRngCore) -> Result, rand_core::Error> { + fn try_generate_iv_with_rng(rng: &mut R) -> Result, R::Error> { let mut iv = Iv::::default(); rng.try_fill_bytes(&mut iv)?; Ok(iv) } /// Generate random key and IV using the operating system's secure RNG. - #[cfg(feature = "getrandom")] + #[cfg(feature = "os_rng")] #[inline] - fn generate_key_iv() -> Result<(Key, Iv), getrandom::Error> { + fn generate_key_iv() -> Result<(Key, Iv), OsError> { let key = Self::generate_key()?; let iv = Self::generate_iv()?; Ok((key, iv)) } - /// Generate random key and IV using the provided [`CryptoRngCore`]. + /// Generate random key and IV using the provided [`CryptoRng`]. + #[cfg(feature = "rand_core")] + #[inline] + fn generate_key_iv_with_rng(rng: &mut R) -> (Key, Iv) { + let key = Self::generate_key_with_rng(rng); + let iv = Self::generate_iv_with_rng(rng); + (key, iv) + } + + /// Generate random key and IV using the provided [`TryCryptoRng`]. #[cfg(feature = "rand_core")] #[inline] - fn generate_key_iv_with_rng( - rng: &mut impl CryptoRngCore, - ) -> Result<(Key, Iv), rand_core::Error> { - let key = Self::generate_key_with_rng(rng)?; - let iv = Self::generate_iv_with_rng(rng)?; + fn try_generate_key_iv_with_rng( + rng: &mut R, + ) -> Result<(Key, Iv), R::Error> { + let key = Self::try_generate_key_with_rng(rng)?; + let iv = Self::try_generate_iv_with_rng(rng)?; Ok((key, iv)) } } @@ -310,18 +346,27 @@ pub trait InnerIvInit: InnerUser + IvSizeUser + Sized { } /// Generate random IV using the operating system's secure RNG. - #[cfg(feature = "getrandom")] + #[cfg(feature = "os_rng")] #[inline] - fn generate_iv() -> Result, getrandom::Error> { + fn generate_iv() -> Result, OsError> { let mut iv = Iv::::default(); - getrandom::fill(&mut iv)?; + OsRng.try_fill_bytes(&mut iv)?; Ok(iv) } - /// Generate random IV using the provided [`CryptoRngCore`]. + /// Generate random IV using the provided [`CryptoRng`]. + #[cfg(feature = "rand_core")] + #[inline] + fn generate_iv_with_rng(rng: &mut R) -> Iv { + let mut iv = Iv::::default(); + rng.fill_bytes(&mut iv); + iv + } + + /// Generate random IV using the provided [`TryCryptoRng`]. #[cfg(feature = "rand_core")] #[inline] - fn generate_iv_with_rng(rng: &mut impl CryptoRngCore) -> Result, rand_core::Error> { + fn try_generate_iv_with_rng(rng: &mut R) -> Result, R::Error> { let mut iv = Iv::::default(); rng.try_fill_bytes(&mut iv)?; Ok(iv) diff --git a/digest/Cargo.toml b/digest/Cargo.toml index c6d2639f6..a30d3bf9d 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -13,7 +13,7 @@ keywords = ["digest", "crypto", "hash"] categories = ["cryptography", "no-std"] [dependencies] -crypto-common = "0.2.0-rc.0" +crypto-common = "0.2.0-rc.1" # optional dependencies block-buffer = { version = "0.11.0-rc.2", optional = true } @@ -27,6 +27,7 @@ default = ["core-api"] core-api = ["block-buffer"] # Enable Core API traits mac = ["subtle"] # Enable MAC traits rand_core = ["crypto-common/rand_core"] # Enable random key generation methods +os_rng = ["crypto-common/rand_core", "rand_core"] oid = ["const-oid"] zeroize = ["dep:zeroize", "block-buffer?/zeroize"] alloc = [] diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index ca1d81c48..83fe1136c 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -22,14 +22,14 @@ base64ct = "1.6" subtle = { version = "2", default-features = false } # optional dependencies -rand_core = { version = "0.6.4", optional = true, default-features = false } +rand_core = { version = "0.9", optional = true, default-features = false } [features] default = ["rand_core"] +rand_core = ["dep:rand_core"] +os_rng = ["rand_core", "rand_core/os_rng"] alloc = ["base64ct/alloc"] -getrandom = ["rand_core/getrandom"] - [package.metadata.docs.rs] all-features = true rustdoc-args = ["--cfg", "docsrs"] diff --git a/password-hash/src/output.rs b/password-hash/src/output.rs index 65ee3484c..cf3b1879a 100644 --- a/password-hash/src/output.rs +++ b/password-hash/src/output.rs @@ -88,7 +88,8 @@ use subtle::{Choice, ConstantTimeEq}; /// time, we would also suggest preventing such attacks by using randomly /// generated salts and keeping those salts secret. /// -/// The [`SaltString::generate`][`crate::SaltString::generate`] function can be +/// The [`SaltString::from_rng`][`crate::SaltString::from_rng`] and +/// [`SaltString::try_from_rng`][`crate::SaltString::try_from_rng`] functions can be /// used to generate random high-entropy salt values. /// /// [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#function-duties diff --git a/password-hash/src/salt.rs b/password-hash/src/salt.rs index eba6876f6..d96abe291 100644 --- a/password-hash/src/salt.rs +++ b/password-hash/src/salt.rs @@ -5,7 +5,7 @@ use core::{fmt, str}; use crate::errors::InvalidValue; #[cfg(feature = "rand_core")] -use rand_core::CryptoRngCore; +use rand_core::{CryptoRng, TryCryptoRng}; /// Error message used with `expect` for when internal invariants are violated /// (i.e. the contents of a [`Salt`] should always be valid) @@ -201,14 +201,23 @@ pub struct SaltString { #[allow(clippy::len_without_is_empty)] impl SaltString { - /// Generate a random B64-encoded [`SaltString`]. + /// Generate a random B64-encoded [`SaltString`] from [`CryptoRng`]. #[cfg(feature = "rand_core")] - pub fn generate(mut rng: impl CryptoRngCore) -> Self { + pub fn from_rng(rng: &mut R) -> Self { let mut bytes = [0u8; Salt::RECOMMENDED_LENGTH]; rng.fill_bytes(&mut bytes); Self::encode_b64(&bytes).expect(INVARIANT_VIOLATED_MSG) } + /// Generate a random B64-encoded [`SaltString`] from [`TryCryptoRng`]. + #[cfg(feature = "rand_core")] + pub fn try_from_rng(rng: &mut R) -> core::result::Result { + let mut bytes = [0u8; Salt::RECOMMENDED_LENGTH]; + rng.try_fill_bytes(&mut bytes)?; + let salt = Self::encode_b64(&bytes).expect(INVARIANT_VIOLATED_MSG); + Ok(salt) + } + /// Create a new [`SaltString`] from the given B64-encoded input string, /// validating [`Salt::MIN_LENGTH`] and [`Salt::MAX_LENGTH`] restrictions. pub fn from_b64(s: &str) -> Result { diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 921f0756a..69844aff1 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -16,7 +16,7 @@ rust-version = "1.81" [dependencies] derive = { package = "signature_derive", version = "2", optional = true, path = "../signature_derive" } digest = { version = "=0.11.0-pre.9", optional = true, default-features = false } -rand_core = { version = "0.6.4", optional = true, default-features = false } +rand_core = { version = "0.9", optional = true, default-features = false } [dev-dependencies] hex-literal = "0.4" @@ -26,6 +26,7 @@ sha2 = { version = "=0.11.0-pre.4", default-features = false } alloc = [] # TODO: remove this feature in the next breaking release std = ["alloc", "rand_core?/std"] +rand_core = ["dep:rand_core"] [package.metadata.docs.rs] all-features = true diff --git a/signature/src/error.rs b/signature/src/error.rs index dc30176ce..75b3a53d0 100644 --- a/signature/src/error.rs +++ b/signature/src/error.rs @@ -83,19 +83,6 @@ impl From> for Error { } } -#[cfg(feature = "rand_core")] -impl From for Error { - #[cfg(not(feature = "alloc"))] - fn from(_source: rand_core::Error) -> Error { - Error::new() - } - - #[cfg(feature = "alloc")] - fn from(source: rand_core::Error) -> Error { - Error::from_source(source) - } -} - impl core::error::Error for Error { fn source(&self) -> Option<&(dyn core::error::Error + 'static)> { #[cfg(not(feature = "alloc"))] diff --git a/signature/src/hazmat.rs b/signature/src/hazmat.rs index d2f3e9523..1f2c6aa84 100644 --- a/signature/src/hazmat.rs +++ b/signature/src/hazmat.rs @@ -9,7 +9,7 @@ use crate::Error; #[cfg(feature = "rand_core")] -use crate::rand_core::CryptoRngCore; +use crate::rand_core::CryptoRng; /// Sign the provided message prehash, returning a digital signature. pub trait PrehashSigner { @@ -43,11 +43,7 @@ pub trait RandomizedPrehashSigner { /// /// Allowed lengths are algorithm-dependent and up to a particular /// implementation to decide. - fn sign_prehash_with_rng( - &self, - rng: &mut impl CryptoRngCore, - prehash: &[u8], - ) -> Result; + fn sign_prehash_with_rng(&self, rng: &mut R, prehash: &[u8]) -> Result; } /// Verify the provided message prehash using `Self` (e.g. a public key) diff --git a/signature/src/signer.rs b/signature/src/signer.rs index 488f7da67..0c579ac12 100644 --- a/signature/src/signer.rs +++ b/signature/src/signer.rs @@ -6,7 +6,7 @@ use crate::error::Error; use crate::digest::Digest; #[cfg(feature = "rand_core")] -use crate::rand_core::CryptoRngCore; +use crate::rand_core::{CryptoRng, TryCryptoRng}; /// Sign the provided message bytestring using `Self` (e.g. a cryptographic key /// or connection to an HSM), returning a digital signature. @@ -86,7 +86,7 @@ pub trait DigestSigner { #[cfg(feature = "rand_core")] pub trait RandomizedSigner { /// Sign the given message and return a digital signature - fn sign_with_rng(&self, rng: &mut impl CryptoRngCore, msg: &[u8]) -> S { + fn sign_with_rng(&self, rng: &mut R, msg: &[u8]) -> S { self.try_sign_with_rng(rng, msg) .expect("signature operation failed") } @@ -96,7 +96,7 @@ pub trait RandomizedSigner { /// /// The main intended use case for signing errors is when communicating /// with external signers, e.g. cloud KMS, HSMs, or other hardware tokens. - fn try_sign_with_rng(&self, rng: &mut impl CryptoRngCore, msg: &[u8]) -> Result; + fn try_sign_with_rng(&self, rng: &mut R, msg: &[u8]) -> Result; } /// Combination of [`DigestSigner`] and [`RandomizedSigner`] with support for @@ -106,14 +106,14 @@ pub trait RandomizedDigestSigner { /// Sign the given prehashed message `Digest`, returning a signature. /// /// Panics in the event of a signing error. - fn sign_digest_with_rng(&self, rng: &mut impl CryptoRngCore, digest: D) -> S { + fn sign_digest_with_rng(&self, rng: &mut R, digest: D) -> S { self.try_sign_digest_with_rng(rng, digest) .expect("signature operation failed") } /// Attempt to sign the given prehashed message `Digest`, returning a /// digital signature on success, or an error if something went wrong. - fn try_sign_digest_with_rng(&self, rng: &mut impl CryptoRngCore, digest: D) + fn try_sign_digest_with_rng(&self, rng: &mut R, digest: D) -> Result; } @@ -123,7 +123,7 @@ pub trait RandomizedDigestSigner { #[cfg(feature = "rand_core")] pub trait RandomizedSignerMut { /// Sign the given message, update the state, and return a digital signature. - fn sign_with_rng(&mut self, rng: &mut impl CryptoRngCore, msg: &[u8]) -> S { + fn sign_with_rng(&mut self, rng: &mut R, msg: &[u8]) -> S { self.try_sign_with_rng(rng, msg) .expect("signature operation failed") } @@ -133,13 +133,13 @@ pub trait RandomizedSignerMut { /// /// Signing can fail, e.g., if the number of time periods allowed by the /// current key is exceeded. - fn try_sign_with_rng(&mut self, rng: &mut impl CryptoRngCore, msg: &[u8]) -> Result; + fn try_sign_with_rng(&mut self, rng: &mut R, msg: &[u8]) -> Result; } /// Blanket impl of [`RandomizedSignerMut`] for all [`RandomizedSigner`] types. #[cfg(feature = "rand_core")] impl> RandomizedSignerMut for T { - fn try_sign_with_rng(&mut self, rng: &mut impl CryptoRngCore, msg: &[u8]) -> Result { + fn try_sign_with_rng(&mut self, rng: &mut R, msg: &[u8]) -> Result { T::try_sign_with_rng(self, rng, msg) } } diff --git a/universal-hash/Cargo.toml b/universal-hash/Cargo.toml index 9068fa16e..28e3a180e 100644 --- a/universal-hash/Cargo.toml +++ b/universal-hash/Cargo.toml @@ -13,7 +13,7 @@ keywords = ["crypto", "mac"] categories = ["cryptography", "no-std"] [dependencies] -crypto-common = "0.2.0-rc.0" +crypto-common = "0.2.0-rc.1" subtle = { version = "2.4", default-features = false } [package.metadata.docs.rs] From 29920669ef4b1d8d33fed3c89fd6e6d8adb88ded Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Wed, 12 Feb 2025 14:50:24 -0800 Subject: [PATCH 1277/1461] signature: merge types from async-signature (#1720) Fixes #1677 This merge types defined in `async-signature` back into `signature` and effectively deprecates `async-signature` --- async-signature/README.md | 5 +++ async-signature/src/hazmat.rs | 20 +++++++++ async-signature/src/lib.rs | 83 +++++------------------------------ signature/src/hazmat.rs | 41 +++++++++++++++++ signature/src/signer.rs | 74 +++++++++++++++++++++++++++++++ 5 files changed, 151 insertions(+), 72 deletions(-) create mode 100644 async-signature/src/hazmat.rs diff --git a/async-signature/README.md b/async-signature/README.md index 838661376..a1898475b 100644 --- a/async-signature/README.md +++ b/async-signature/README.md @@ -7,6 +7,10 @@ [![Project Chat][chat-image]][chat-link] [![Build Status][build-image]][build-link] +## Deprecated + +This crate is now deprecated, all the types are available in [`signature`][signature-crate] + ## Minimum Supported Rust Version Rust **1.81** or higher. @@ -41,3 +45,4 @@ dual licensed as above, without any additional terms or conditions. [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260048-signatures [build-image]: https://github.com/RustCrypto/traits/workflows/async-signature/badge.svg?branch=master&event=push [build-link]: https://github.com/RustCrypto/traits/actions?query=workflow:async-signature +[signature-crate]: https://crates.io/crates/signature diff --git a/async-signature/src/hazmat.rs b/async-signature/src/hazmat.rs new file mode 100644 index 000000000..5fbdda362 --- /dev/null +++ b/async-signature/src/hazmat.rs @@ -0,0 +1,20 @@ +//! Hazardous Materials: low-level APIs which can be insecure if misused. +//! +//! The traits in this module are not generally recommended, and should only be +//! used in special cases where they are specifically needed. +//! +//! Using them incorrectly can introduce security vulnerabilities. Please +//! carefully read the documentation before attempting to use them. + +#[deprecated( + since = "0.6.0", + note = "use `signature::hazmat::AsyncPrehashSigner` instead" +)] +pub use signature::hazmat::AsyncPrehashSigner; + +#[cfg(feature = "rand_core")] +#[deprecated( + since = "0.6.0", + note = "use `signature::hazmat::AsyncRandomizedPrehashSigner` instead" +)] +pub use signature::hazmat::AsyncRandomizedPrehashSigner; diff --git a/async-signature/src/lib.rs b/async-signature/src/lib.rs index 68c8aa8ba..74fbee82b 100644 --- a/async-signature/src/lib.rs +++ b/async-signature/src/lib.rs @@ -13,84 +13,23 @@ missing_debug_implementations )] +pub mod hazmat; + pub use signature::{self, Error}; #[cfg(feature = "digest")] pub use signature::digest::{self, Digest}; -#[cfg(feature = "rand_core")] -use signature::rand_core::{CryptoRng, TryCryptoRng}; - -/// Asynchronously sign the provided message bytestring using `Self` -/// (e.g. client for a Cloud KMS or HSM), returning a digital signature. -/// -/// This trait is an async equivalent of the [`signature::Signer`] trait. -#[allow(async_fn_in_trait)] -pub trait AsyncSigner { - /// Attempt to sign the given message, returning a digital signature on - /// success, or an error if something went wrong. - /// - /// The main intended use case for signing errors is when communicating - /// with external signers, e.g. cloud KMS, HSMs, or other hardware tokens. - async fn sign_async(&self, msg: &[u8]) -> Result; -} - -impl AsyncSigner for T -where - T: signature::Signer, -{ - async fn sign_async(&self, msg: &[u8]) -> Result { - self.try_sign(msg) - } -} +#[deprecated(since = "0.6.0", note = "use `signature::AsyncSigner` instead")] +pub use signature::AsyncSigner; -/// Asynchronously sign the given prehashed message [`Digest`] using `Self`. -/// -/// This trait is an async equivalent of the [`signature::DigestSigner`] trait. #[cfg(feature = "digest")] -#[allow(async_fn_in_trait)] -pub trait AsyncDigestSigner -where - D: Digest, -{ - /// Attempt to sign the given prehashed message [`Digest`], returning a - /// digital signature on success, or an error if something went wrong. - async fn sign_digest_async(&self, digest: D) -> Result; -} +#[deprecated(since = "0.6.0", note = "use `signature::AsyncDigestSigner` instead")] +pub use signature::AsyncDigestSigner; -/// Sign the given message using the provided external randomness source. #[cfg(feature = "rand_core")] -#[allow(async_fn_in_trait)] -pub trait AsyncRandomizedSigner { - /// Sign the given message and return a digital signature - async fn sign_with_rng_async(&self, rng: &mut R, msg: &[u8]) -> S { - self.try_sign_with_rng_async(rng, msg) - .await - .expect("signature operation failed") - } - - /// Attempt to sign the given message, returning a digital signature on - /// success, or an error if something went wrong. - /// - /// The main intended use case for signing errors is when communicating - /// with external signers, e.g. cloud KMS, HSMs, or other hardware tokens. - async fn try_sign_with_rng_async( - &self, - rng: &mut R, - msg: &[u8], - ) -> Result; -} - -#[cfg(feature = "rand_core")] -impl AsyncRandomizedSigner for T -where - T: signature::RandomizedSigner, -{ - async fn try_sign_with_rng_async( - &self, - rng: &mut R, - msg: &[u8], - ) -> Result { - self.try_sign_with_rng(rng, msg) - } -} +#[deprecated( + since = "0.6.0", + note = "use `signature::AsyncRandomizedSigner` instead" +)] +pub use signature::AsyncRandomizedSigner; diff --git a/signature/src/hazmat.rs b/signature/src/hazmat.rs index 1f2c6aa84..cfd274f82 100644 --- a/signature/src/hazmat.rs +++ b/signature/src/hazmat.rs @@ -64,3 +64,44 @@ pub trait PrehashVerifier { /// solving a system of linear equations. fn verify_prehash(&self, prehash: &[u8], signature: &S) -> Result<(), Error>; } + +/// Asynchronously sign the provided message prehash, returning a digital signature. +#[allow(async_fn_in_trait)] +pub trait AsyncPrehashSigner { + /// Attempt to sign the given message digest, returning a digital signature + /// on success, or an error if something went wrong. + /// + /// The `prehash` parameter should be the output of a secure cryptographic + /// hash function. + /// + /// This API takes a `prehash` byte slice as there can potentially be many + /// compatible lengths for the message digest for a given concrete signature + /// algorithm. + /// + /// Allowed lengths are algorithm-dependent and up to a particular + /// implementation to decide. + async fn sign_prehash_async(&self, prehash: &[u8]) -> Result; +} + +/// Asynchronously sign the provided message prehash using the provided external randomness source, returning a digital signature. +#[cfg(feature = "rand_core")] +#[allow(async_fn_in_trait)] +pub trait AsyncRandomizedPrehashSigner { + /// Attempt to sign the given message digest, returning a digital signature + /// on success, or an error if something went wrong. + /// + /// The `prehash` parameter should be the output of a secure cryptographic + /// hash function. + /// + /// This API takes a `prehash` byte slice as there can potentially be many + /// compatible lengths for the message digest for a given concrete signature + /// algorithm. + /// + /// Allowed lengths are algorithm-dependent and up to a particular + /// implementation to decide. + async fn sign_prehash_with_rng_async( + &self, + rng: &mut impl CryptoRngCore, + prehash: &[u8], + ) -> Result; +} diff --git a/signature/src/signer.rs b/signature/src/signer.rs index 0c579ac12..dcb322490 100644 --- a/signature/src/signer.rs +++ b/signature/src/signer.rs @@ -143,3 +143,77 @@ impl> RandomizedSignerMut for T { T::try_sign_with_rng(self, rng, msg) } } + +/// Asynchronously sign the provided message bytestring using `Self` +/// (e.g. client for a Cloud KMS or HSM), returning a digital signature. +/// +/// This trait is an async equivalent of the [`Signer`] trait. +#[allow(async_fn_in_trait)] +pub trait AsyncSigner { + /// Attempt to sign the given message, returning a digital signature on + /// success, or an error if something went wrong. + /// + /// The main intended use case for signing errors is when communicating + /// with external signers, e.g. cloud KMS, HSMs, or other hardware tokens. + async fn sign_async(&self, msg: &[u8]) -> Result; +} + +impl AsyncSigner for T +where + T: Signer, +{ + async fn sign_async(&self, msg: &[u8]) -> Result { + self.try_sign(msg) + } +} + +/// Asynchronously sign the given prehashed message [`Digest`] using `Self`. +/// +/// This trait is an async equivalent of the [`DigestSigner`] trait. +#[cfg(feature = "digest")] +#[allow(async_fn_in_trait)] +pub trait AsyncDigestSigner +where + D: Digest, +{ + /// Attempt to sign the given prehashed message [`Digest`], returning a + /// digital signature on success, or an error if something went wrong. + async fn sign_digest_async(&self, digest: D) -> Result; +} + +/// Sign the given message using the provided external randomness source. +#[cfg(feature = "rand_core")] +#[allow(async_fn_in_trait)] +pub trait AsyncRandomizedSigner { + /// Sign the given message and return a digital signature + async fn sign_with_rng_async(&self, rng: &mut impl CryptoRngCore, msg: &[u8]) -> S { + self.try_sign_with_rng_async(rng, msg) + .await + .expect("signature operation failed") + } + + /// Attempt to sign the given message, returning a digital signature on + /// success, or an error if something went wrong. + /// + /// The main intended use case for signing errors is when communicating + /// with external signers, e.g. cloud KMS, HSMs, or other hardware tokens. + async fn try_sign_with_rng_async( + &self, + rng: &mut impl CryptoRngCore, + msg: &[u8], + ) -> Result; +} + +#[cfg(feature = "rand_core")] +impl AsyncRandomizedSigner for T +where + T: RandomizedSigner, +{ + async fn try_sign_with_rng_async( + &self, + rng: &mut impl CryptoRngCore, + msg: &[u8], + ) -> Result { + self.try_sign_with_rng(rng, msg) + } +} From 2e4bd57648ec464ba8c1af63fe30dcb1072a4640 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 12 Feb 2025 15:53:56 -0700 Subject: [PATCH 1278/1461] signature: async `rand_core` v0.9 updates (#1749) Followup to #1720 --- signature/src/hazmat.rs | 4 ++-- signature/src/signer.rs | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/signature/src/hazmat.rs b/signature/src/hazmat.rs index cfd274f82..4c549af9c 100644 --- a/signature/src/hazmat.rs +++ b/signature/src/hazmat.rs @@ -99,9 +99,9 @@ pub trait AsyncRandomizedPrehashSigner { /// /// Allowed lengths are algorithm-dependent and up to a particular /// implementation to decide. - async fn sign_prehash_with_rng_async( + async fn sign_prehash_with_rng_async( &self, - rng: &mut impl CryptoRngCore, + rng: &mut R, prehash: &[u8], ) -> Result; } diff --git a/signature/src/signer.rs b/signature/src/signer.rs index dcb322490..a6c2813f8 100644 --- a/signature/src/signer.rs +++ b/signature/src/signer.rs @@ -186,7 +186,7 @@ where #[allow(async_fn_in_trait)] pub trait AsyncRandomizedSigner { /// Sign the given message and return a digital signature - async fn sign_with_rng_async(&self, rng: &mut impl CryptoRngCore, msg: &[u8]) -> S { + async fn sign_with_rng_async(&self, rng: &mut R, msg: &[u8]) -> S { self.try_sign_with_rng_async(rng, msg) .await .expect("signature operation failed") @@ -197,9 +197,9 @@ pub trait AsyncRandomizedSigner { /// /// The main intended use case for signing errors is when communicating /// with external signers, e.g. cloud KMS, HSMs, or other hardware tokens. - async fn try_sign_with_rng_async( + async fn try_sign_with_rng_async( &self, - rng: &mut impl CryptoRngCore, + rng: &mut R, msg: &[u8], ) -> Result; } @@ -209,9 +209,9 @@ impl AsyncRandomizedSigner for T where T: RandomizedSigner, { - async fn try_sign_with_rng_async( + async fn try_sign_with_rng_async( &self, - rng: &mut impl CryptoRngCore, + rng: &mut R, msg: &[u8], ) -> Result { self.try_sign_with_rng(rng, msg) From 0c41df9a50721fa426ff8c86514672e44ac404d5 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 12 Feb 2025 16:42:08 -0700 Subject: [PATCH 1279/1461] signature v2.3.0-pre.5 (#1750) --- Cargo.lock | 4 ++-- async-signature/Cargo.toml | 2 +- signature/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bd4561be6..3f130ad24 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -58,7 +58,7 @@ checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" name = "async-signature" version = "0.6.0-pre.4" dependencies = [ - "signature 2.3.0-pre.4", + "signature 2.3.0-pre.5", ] [[package]] @@ -1227,7 +1227,7 @@ dependencies = [ [[package]] name = "signature" -version = "2.3.0-pre.4" +version = "2.3.0-pre.5" dependencies = [ "digest 0.11.0-pre.9", "hex-literal", diff --git a/async-signature/Cargo.toml b/async-signature/Cargo.toml index 0fe015a43..651406b22 100644 --- a/async-signature/Cargo.toml +++ b/async-signature/Cargo.toml @@ -14,7 +14,7 @@ edition = "2021" rust-version = "1.81" [dependencies] -signature = "=2.3.0-pre.4" +signature = "=2.3.0-pre.5" [features] digest = ["signature/digest"] diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 69844aff1..127c2be06 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "2.3.0-pre.4" +version = "2.3.0-pre.5" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/signature" From 684e9bcb0c530324b78de17f4543b5562ffd2344 Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Fri, 14 Feb 2025 21:07:42 -0800 Subject: [PATCH 1280/1461] signature: Prehash should accept a `TryCryptoRng` (#1752) This is so that a `RandomizedDigestSigner` can call into `hazmat::RandomizedPrehashSigner` directly with the provided rng. Example use: https://github.com/RustCrypto/signatures/pull/901 --- signature/src/hazmat.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/signature/src/hazmat.rs b/signature/src/hazmat.rs index 4c549af9c..25cc900a5 100644 --- a/signature/src/hazmat.rs +++ b/signature/src/hazmat.rs @@ -9,7 +9,7 @@ use crate::Error; #[cfg(feature = "rand_core")] -use crate::rand_core::CryptoRng; +use crate::rand_core::TryCryptoRng; /// Sign the provided message prehash, returning a digital signature. pub trait PrehashSigner { @@ -43,7 +43,11 @@ pub trait RandomizedPrehashSigner { /// /// Allowed lengths are algorithm-dependent and up to a particular /// implementation to decide. - fn sign_prehash_with_rng(&self, rng: &mut R, prehash: &[u8]) -> Result; + fn sign_prehash_with_rng( + &self, + rng: &mut R, + prehash: &[u8], + ) -> Result; } /// Verify the provided message prehash using `Self` (e.g. a public key) @@ -99,7 +103,7 @@ pub trait AsyncRandomizedPrehashSigner { /// /// Allowed lengths are algorithm-dependent and up to a particular /// implementation to decide. - async fn sign_prehash_with_rng_async( + async fn sign_prehash_with_rng_async( &self, rng: &mut R, prehash: &[u8], From 41fa95fde4953ffb2bc4af1ab9c7dd9151d83cb7 Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Thu, 20 Feb 2025 09:23:06 +0000 Subject: [PATCH 1281/1461] signature v2.3.0-pre.6 (#1755) --- Cargo.lock | 4 ++-- async-signature/Cargo.toml | 2 +- signature/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3f130ad24..b1d647303 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -58,7 +58,7 @@ checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" name = "async-signature" version = "0.6.0-pre.4" dependencies = [ - "signature 2.3.0-pre.5", + "signature 2.3.0-pre.6", ] [[package]] @@ -1227,7 +1227,7 @@ dependencies = [ [[package]] name = "signature" -version = "2.3.0-pre.5" +version = "2.3.0-pre.6" dependencies = [ "digest 0.11.0-pre.9", "hex-literal", diff --git a/async-signature/Cargo.toml b/async-signature/Cargo.toml index 651406b22..01ba8a4ff 100644 --- a/async-signature/Cargo.toml +++ b/async-signature/Cargo.toml @@ -14,7 +14,7 @@ edition = "2021" rust-version = "1.81" [dependencies] -signature = "=2.3.0-pre.5" +signature = "=2.3.0-pre.6" [features] digest = ["signature/digest"] diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 127c2be06..85cafb78b 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "2.3.0-pre.5" +version = "2.3.0-pre.6" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/signature" From 1fdcdc7daae1dd00f7b881fb9fdca78003c4a121 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Fri, 21 Feb 2025 11:07:39 +0300 Subject: [PATCH 1282/1461] kem: remove tests, update to rand_core v0.9 (#1757) As discussed [here][0] the tests are not particularity useful and block migration to rand_core v0.9. [0]: https://github.com/RustCrypto/traits/issues/1642#issuecomment-2660481543 --- Cargo.lock | 679 +++------------------------------------------ kem/Cargo.toml | 12 +- kem/src/lib.rs | 4 +- kem/tests/hpke.rs | 53 ---- kem/tests/saber.rs | 53 ---- kem/tests/x3dh.rs | 113 -------- 6 files changed, 43 insertions(+), 871 deletions(-) delete mode 100644 kem/tests/hpke.rs delete mode 100644 kem/tests/saber.rs delete mode 100644 kem/tests/x3dh.rs diff --git a/Cargo.lock b/Cargo.lock index b1d647303..a73daeabf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -23,31 +23,6 @@ dependencies = [ "heapless", ] -[[package]] -name = "aes" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" -dependencies = [ - "cfg-if", - "cipher 0.4.4", - "cpufeatures", -] - -[[package]] -name = "aes-gcm" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" -dependencies = [ - "aead 0.5.2", - "aes", - "cipher 0.4.4", - "ctr", - "ghash", - "subtle", -] - [[package]] name = "arrayvec" version = "0.7.6" @@ -79,15 +54,6 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" -[[package]] -name = "bincode" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" -dependencies = [ - "serde", -] - [[package]] name = "bitflags" version = "2.8.0" @@ -112,15 +78,6 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "847495c209977a90e8aad588b959d0ca9f5dc228096d29a6bd3defd53f35eaec" -[[package]] -name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "generic-array", -] - [[package]] name = "block-buffer" version = "0.10.4" @@ -170,47 +127,12 @@ version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f61dac84819c6588b558454b194026eb1f09c293b9036ae9b159e74e73ab6cf9" -[[package]] -name = "cc" -version = "1.2.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7777341816418c02e033934a09f20dc0ccaf65a5201ef8a450ae0105a573fda" -dependencies = [ - "jobserver", - "libc", - "shlex", -] - [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "chacha20" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" -dependencies = [ - "cfg-if", - "cipher 0.4.4", - "cpufeatures", -] - -[[package]] -name = "chacha20poly1305" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" -dependencies = [ - "aead 0.5.2", - "chacha20", - "cipher 0.4.4", - "poly1305", - "zeroize", -] - [[package]] name = "cipher" version = "0.4.4" @@ -219,7 +141,6 @@ checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ "crypto-common 0.1.6", "inout 0.1.3", - "zeroize", ] [[package]] @@ -232,12 +153,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "const-oid" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d6f2aa4d0537bcc1c74df8755072bd31c1ef1a3a1b85a68e8404a8c353b7b8b" - [[package]] name = "const-oid" version = "0.9.6" @@ -273,18 +188,6 @@ dependencies = [ "universal-hash 0.5.1", ] -[[package]] -name = "crypto-bigint" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8658c15c5d921ddf980f7fe25b1e82f4b7a4083b2c4985fea4922edb8e43e07d" -dependencies = [ - "generic-array", - "rand_core 0.6.4", - "subtle", - "zeroize", -] - [[package]] name = "crypto-bigint" version = "0.5.5" @@ -299,9 +202,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4919aa33c410cb537c1b2a8458a896f9e47ed4349a2002e5b240f358f7bf6ffc" +checksum = "96272c2ff28b807e09250b180ad1fb7889a3258f7455759b5c3c58b719467130" dependencies = [ "hybrid-array", "num-traits", @@ -326,60 +229,7 @@ name = "crypto-common" version = "0.2.0-rc.1" dependencies = [ "hybrid-array", - "rand_core 0.9.0", -] - -[[package]] -name = "crypto-mac" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25fab6889090c8133f3deb8f73ba3c65a7f456f66436fc012a1b1e272b1e103e" -dependencies = [ - "generic-array", - "subtle", -] - -[[package]] -name = "ctr" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" -dependencies = [ - "cipher 0.4.4", -] - -[[package]] -name = "curve25519-dalek" -version = "4.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" -dependencies = [ - "cfg-if", - "cpufeatures", - "curve25519-dalek-derive", - "fiat-crypto", - "rustc_version", - "subtle", -] - -[[package]] -name = "curve25519-dalek-derive" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "der" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79b71cca7d95d7681a4b3b9cdf63c8dbc3730d0584c2c74e31416d64a90493f4" -dependencies = [ - "const-oid 0.6.2", + "rand_core 0.9.1", ] [[package]] @@ -399,19 +249,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "82db698b33305f0134faf590b9d1259dc171b5481ac41d5c8146c3b3ee7d4319" dependencies = [ "const-oid 0.10.0-rc.3", - "pem-rfc7468 1.0.0-rc.2", + "pem-rfc7468", "zeroize", ] -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array", -] - [[package]] name = "digest" version = "0.10.7" @@ -435,40 +276,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "dunce" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" - -[[package]] -name = "ecdsa" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43ee23aa5b4f68c7a092b5c3beb25f50c406adc75e2363634f242f28ab255372" -dependencies = [ - "der 0.4.5", - "elliptic-curve 0.10.4", - "hmac 0.11.0", - "signature 1.3.2", -] - -[[package]] -name = "elliptic-curve" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83e5c176479da93a0983f0a6fdc3c1b8e7d5be0d7fe3fe05a99f15b96582b9a8" -dependencies = [ - "crypto-bigint 0.2.5", - "ff 0.10.1", - "generic-array", - "group 0.10.0", - "pkcs8 0.7.6", - "rand_core 0.6.4", - "subtle", - "zeroize", -] - [[package]] name = "elliptic-curve" version = "0.13.8" @@ -477,11 +284,9 @@ checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ "base16ct", "crypto-bigint 0.5.5", - "digest 0.10.7", - "ff 0.13.0", + "ff", "generic-array", - "group 0.13.0", - "hkdf 0.12.4", + "group", "pkcs8 0.10.2", "rand_core 0.6.4", "sec1 0.7.3", @@ -495,36 +300,26 @@ version = "0.14.0-rc.1" dependencies = [ "base16ct", "base64ct", - "crypto-bigint 0.6.0", + "crypto-bigint 0.6.1", "digest 0.11.0-pre.9", - "ff 0.13.0", - "group 0.13.0", + "ff", + "group", "hex-literal", - "hkdf 0.13.0-pre.4", + "hkdf", "hybrid-array", - "pem-rfc7468 1.0.0-rc.2", - "pkcs8 0.11.0-rc.1", + "pem-rfc7468", + "pkcs8 0.11.0-rc.2", "rand_core 0.6.4", "sec1 0.8.0-rc.3", "serde_json", "serdect", - "sha2 0.11.0-pre.4", + "sha2", "sha3", "subtle", "tap", "zeroize", ] -[[package]] -name = "ff" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0f40b2dcd8bc322217a5f6559ae5f9e9d1de202a2ecee2e9eafcbece7562a4f" -dependencies = [ - "rand_core 0.6.4", - "subtle", -] - [[package]] name = "ff" version = "0.13.0" @@ -536,12 +331,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "fiat-crypto" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" - [[package]] name = "funty" version = "2.0.0" @@ -582,40 +371,13 @@ dependencies = [ "windows-targets", ] -[[package]] -name = "ghash" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" -dependencies = [ - "opaque-debug", - "polyval", -] - -[[package]] -name = "glob" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" - -[[package]] -name = "group" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c363a5301b8f153d80747126a04b3c82073b9fe3130571a9d170cacdeaf7912" -dependencies = [ - "ff 0.10.1", - "rand_core 0.6.4", - "subtle", -] - [[package]] name = "group" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ - "ff 0.13.0", + "ff", "rand_core 0.6.4", "subtle", ] @@ -645,51 +407,13 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" -[[package]] -name = "hkdf" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01706d578d5c281058480e673ae4086a9f4710d8df1ad80a5b03e39ece5f886b" -dependencies = [ - "digest 0.9.0", - "hmac 0.11.0", -] - -[[package]] -name = "hkdf" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" -dependencies = [ - "hmac 0.12.1", -] - [[package]] name = "hkdf" version = "0.13.0-pre.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00176ff81091018d42ff82e8324f8e5adb0b7e0468d1358f653972562dbff031" dependencies = [ - "hmac 0.13.0-pre.4", -] - -[[package]] -name = "hmac" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" -dependencies = [ - "crypto-mac", - "digest 0.9.0", -] - -[[package]] -name = "hmac" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" -dependencies = [ - "digest 0.10.7", + "hmac", ] [[package]] @@ -701,27 +425,6 @@ dependencies = [ "digest 0.11.0-pre.9", ] -[[package]] -name = "hpke" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4917627a14198c3603282c5158b815ad5534795451d3c074b53cf3cee0960b11" -dependencies = [ - "aead 0.5.2", - "aes-gcm", - "chacha20poly1305", - "digest 0.10.7", - "generic-array", - "hkdf 0.12.4", - "hmac 0.12.1", - "p256 0.13.2", - "rand_core 0.6.4", - "sha2 0.10.8", - "subtle", - "x25519-dalek", - "zeroize", -] - [[package]] name = "hybrid-array" version = "0.2.3" @@ -758,15 +461,6 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" -[[package]] -name = "jobserver" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" -dependencies = [ - "libc", -] - [[package]] name = "keccak" version = "0.2.0-pre.0" @@ -780,13 +474,7 @@ dependencies = [ name = "kem" version = "0.3.0-pre.0" dependencies = [ - "hpke", - "p256 0.9.0", - "pqcrypto", - "pqcrypto-traits", - "rand", - "rand_core 0.6.4", - "x3dh-ke", + "rand_core 0.9.1", "zeroize", ] @@ -811,33 +499,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "opaque-debug" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" - -[[package]] -name = "p256" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d053368e1bae4c8a672953397bd1bd7183dde1c72b0b7612a15719173148d186" -dependencies = [ - "ecdsa", - "elliptic-curve 0.10.4", - "sha2 0.9.9", -] - -[[package]] -name = "p256" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" -dependencies = [ - "elliptic-curve 0.13.8", - "primeorder", -] - [[package]] name = "password-hash" version = "0.5.0" @@ -854,19 +515,10 @@ name = "password-hash" version = "0.6.0-rc.0" dependencies = [ "base64ct", - "rand_core 0.9.0", + "rand_core 0.9.1", "subtle", ] -[[package]] -name = "pem-rfc7468" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f22eb0e3c593294a99e9ff4b24cf6b752d43f193aa4415fe5077c159996d497" -dependencies = [ - "base64ct", -] - [[package]] name = "pem-rfc7468" version = "1.0.0-rc.2" @@ -876,18 +528,6 @@ dependencies = [ "base64ct", ] -[[package]] -name = "pkcs8" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee3ef9b64d26bad0536099c816c6734379e45bbd5f14798def6809e5cc350447" -dependencies = [ - "der 0.4.5", - "pem-rfc7468 0.2.3", - "spki 0.4.1", - "zeroize", -] - [[package]] name = "pkcs8" version = "0.10.2" @@ -900,96 +540,14 @@ dependencies = [ [[package]] name = "pkcs8" -version = "0.11.0-rc.1" +version = "0.11.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eacd2c7141f32aef1cfd1ad0defb5287a3d94592d7ab57c1ae20e3f9f1f0db1f" +checksum = "f22636de7c995e997ed3d8d2949b7414d4faba3efa7312a6c0e75d875a14bdd4" dependencies = [ "der 0.8.0-rc.1", "spki 0.8.0-rc.1", ] -[[package]] -name = "poly1305" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" -dependencies = [ - "cpufeatures", - "opaque-debug", - "universal-hash 0.5.1", -] - -[[package]] -name = "polyval" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" -dependencies = [ - "cfg-if", - "cpufeatures", - "opaque-debug", - "universal-hash 0.5.1", -] - -[[package]] -name = "ppv-lite86" -version = "0.2.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" -dependencies = [ - "zerocopy 0.7.35", -] - -[[package]] -name = "pqcrypto" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10caefecccc56b78d30a6b46effa2360048104d668fb7cea944c0761f9c1f11" -dependencies = [ - "pqcrypto-saber", - "pqcrypto-traits", -] - -[[package]] -name = "pqcrypto-internals" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cc3518d9ec325ec95d89749d4f5c111776b97c5bbd26e3ffe523aa300f1e27e" -dependencies = [ - "cc", - "dunce", - "getrandom 0.2.15", - "libc", -] - -[[package]] -name = "pqcrypto-saber" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7453b631d7bd268fffadf70514cdf05c9e9fd9574e26eafb85b5b86402e34c5b" -dependencies = [ - "cc", - "glob", - "libc", - "pqcrypto-internals", - "pqcrypto-traits", -] - -[[package]] -name = "pqcrypto-traits" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94e851c7654eed9e68d7d27164c454961a616cf8c203d500607ef22c737b51bb" - -[[package]] -name = "primeorder" -version = "0.13.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" -dependencies = [ - "elliptic-curve 0.13.8", -] - [[package]] name = "proc-macro2" version = "1.0.93" @@ -1014,27 +572,6 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", -] - [[package]] name = "rand_core" version = "0.6.4" @@ -1046,21 +583,12 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b08f3c9802962f7e1b25113931d94f43ed9725bebc59db9d0c3e9a23b67e15ff" +checksum = "a88e0da7a2c97baa202165137c158d0a2e824ac465d13d81046727b34cb247d3" dependencies = [ "getrandom 0.3.1", - "zerocopy 0.8.17", -] - -[[package]] -name = "rustc_version" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" -dependencies = [ - "semver", + "zerocopy", ] [[package]] @@ -1092,41 +620,26 @@ dependencies = [ "base16ct", "der 0.8.0-rc.1", "hybrid-array", - "pkcs8 0.11.0-rc.1", + "pkcs8 0.11.0-rc.2", "serdect", "subtle", "zeroize", ] -[[package]] -name = "semver" -version = "1.0.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f79dfe2d285b0488816f30e700a7438c5a73d816b5b7d3ac72fbc48b0d185e03" - [[package]] name = "serde" -version = "1.0.217" +version = "1.0.218" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" +checksum = "e8dfc9d19bdbf6d17e22319da49161d5d0108e4188e8b680aef6299eed22df60" dependencies = [ "serde_derive", ] -[[package]] -name = "serde_bytes" -version = "0.11.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "387cc504cb06bb40a96c8e04e951fe01854cf6bc921053c954e4a606d9675c6a" -dependencies = [ - "serde", -] - [[package]] name = "serde_derive" -version = "1.0.217" +version = "1.0.218" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" +checksum = "f09503e191f4e797cb8aac08e9a4a4695c5edf6a2e70e376d961ddd5c969f82b" dependencies = [ "proc-macro2", "quote", @@ -1135,9 +648,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.138" +version = "1.0.139" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d434192e7da787e94a6ea7e9670b26a036d0ca41e0b7efb2676dd32bae872949" +checksum = "44f86c3acccc9c65b153fe1b85a3be07fe5515274ec9f0653b4a0875731c72a6" dependencies = [ "itoa", "memchr", @@ -1155,30 +668,6 @@ dependencies = [ "serde", ] -[[package]] -name = "sha2" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if", - "cpufeatures", - "digest 0.9.0", - "opaque-debug", -] - -[[package]] -name = "sha2" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest 0.10.7", -] - [[package]] name = "sha2" version = "0.11.0-pre.4" @@ -1200,22 +689,6 @@ dependencies = [ "keccak", ] -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "signature" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2807892cfa58e081aa1f1111391c7a0649d4fa127a4ffbe34bcbfb35a1171a4" -dependencies = [ - "digest 0.9.0", - "rand_core 0.6.4", -] - [[package]] name = "signature" version = "2.2.0" @@ -1231,8 +704,8 @@ version = "2.3.0-pre.6" dependencies = [ "digest 0.11.0-pre.9", "hex-literal", - "rand_core 0.9.0", - "sha2 0.11.0-pre.4", + "rand_core 0.9.1", + "sha2", "signature_derive", ] @@ -1245,15 +718,6 @@ dependencies = [ "syn", ] -[[package]] -name = "spki" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c01a0c15da1b0b0e1494112e7af814a678fec9bd157881b49beac661e9b6f32" -dependencies = [ - "der 0.4.5", -] - [[package]] name = "spki" version = "0.7.3" @@ -1305,15 +769,15 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "typenum" -version = "1.17.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" [[package]] name = "unicode-ident" -version = "1.0.16" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034" +checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe" [[package]] name = "universal-hash" @@ -1436,69 +900,20 @@ dependencies = [ "tap", ] -[[package]] -name = "x25519-dalek" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277" -dependencies = [ - "curve25519-dalek", - "rand_core 0.6.4", -] - -[[package]] -name = "x3dh-ke" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ee8f59e7095cfd040618f328897c4b07925933de33b517949a64bc97b9fcde3" -dependencies = [ - "base64ct", - "bincode", - "const-oid 0.6.2", - "getrandom 0.2.15", - "hkdf 0.11.0", - "p256 0.9.0", - "rand_core 0.6.4", - "serde", - "serde_bytes", - "sha2 0.9.9", -] - -[[package]] -name = "zerocopy" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" -dependencies = [ - "byteorder", - "zerocopy-derive 0.7.35", -] - [[package]] name = "zerocopy" -version = "0.8.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa91407dacce3a68c56de03abe2760159582b846c6a4acd2f456618087f12713" -dependencies = [ - "zerocopy-derive 0.8.17", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.35" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +checksum = "dde3bb8c68a8f3f1ed4ac9221aad6b10cece3e60a8e2ea54a6a2dec806d0084c" dependencies = [ - "proc-macro2", - "quote", - "syn", + "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.17" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06718a168365cad3d5ff0bb133aad346959a2074bd4a85c121255a11304a8626" +checksum = "eea57037071898bf96a6da35fd626f4f27e9cee3ead2a6c703cf09d472b2e700" dependencies = [ "proc-macro2", "quote", @@ -1510,17 +925,3 @@ name = "zeroize" version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] diff --git a/kem/Cargo.toml b/kem/Cargo.toml index e4e1c7fb9..b07b3c16d 100644 --- a/kem/Cargo.toml +++ b/kem/Cargo.toml @@ -14,19 +14,9 @@ categories = ["cryptography", "no-std"] rust-version = "1.66" [dependencies] -rand_core = "0.6" +rand_core = "0.9" zeroize = { version = "1.7", default-features = false } -[dev-dependencies] -hpke = "0.12" -p256 = { version = "0.9", features = ["ecdsa"] } -pqcrypto = { version = "0.15", default-features = false, features = [ - "pqcrypto-saber", -] } -pqcrypto-traits = "0.3" -rand = { version = "0.8" } -x3dh-ke = "0.1" - [package.metadata.docs.rs] all-features = true rustdoc-args = ["--cfg", "docsrs"] diff --git a/kem/src/lib.rs b/kem/src/lib.rs index dc009d077..06365882a 100644 --- a/kem/src/lib.rs +++ b/kem/src/lib.rs @@ -10,7 +10,7 @@ #![warn(missing_docs, unused_qualifications, missing_debug_implementations)] use core::fmt::Debug; -use rand_core::CryptoRngCore; +use rand_core::CryptoRng; /// A value that can be encapsulated to. Often, this will just be a public key. However, it can /// also be a bundle of public keys, or it can include a sender's private key for authenticated @@ -20,7 +20,7 @@ pub trait Encapsulate { type Error: Debug; /// Encapsulates a fresh shared secret - fn encapsulate(&self, rng: &mut impl CryptoRngCore) -> Result<(EK, SS), Self::Error>; + fn encapsulate(&self, rng: &mut impl CryptoRng) -> Result<(EK, SS), Self::Error>; } /// A value that can be used to decapsulate an encapsulated key. diff --git a/kem/tests/hpke.rs b/kem/tests/hpke.rs deleted file mode 100644 index 43ad61c9d..000000000 --- a/kem/tests/hpke.rs +++ /dev/null @@ -1,53 +0,0 @@ -use kem::{Decapsulate, Encapsulate}; - -use hpke::{ - kem::{Kem as KemTrait, X25519HkdfSha256}, - HpkeError, -}; -use rand_core::{CryptoRng, CryptoRngCore, RngCore}; - -type SharedSecret = hpke::kem::SharedSecret; -type EncappedKey = ::EncappedKey; - -// We have to define a newtype for the public and private keys because we're gonna impl -// the Encapsulate and Decapsulate traits for them -struct PublicKey(::PublicKey); -struct PrivateKey(::PrivateKey); - -impl Encapsulate for PublicKey { - type Error = HpkeError; - - fn encapsulate( - &self, - mut csprng: &mut impl CryptoRngCore, - ) -> Result<(EncappedKey, SharedSecret), HpkeError> { - ::encap(&self.0, None, &mut csprng).map(|(ek, ss)| (ss, ek)) - } -} - -impl Decapsulate for PrivateKey { - type Error = HpkeError; - - fn decapsulate(&self, encapped_key: &EncappedKey) -> Result { - ::decap(&self.0, None, encapped_key) - } -} - -// A simple wrapper around the keypair generation function -fn gen_keypair(csprng: &mut R) -> (PrivateKey, PublicKey) { - let (sk, pk) = X25519HkdfSha256::gen_keypair(csprng); - (PrivateKey(sk), PublicKey(pk)) -} - -#[test] -fn test_hpke() { - let mut rng = rand::thread_rng(); - - // Make a recipient's keypair - let (sk_recip, pk_recip) = gen_keypair(&mut rng); - - // Encapsulate to the recipient. Check that the derived shared secrets are equal - let (ek, ss1) = pk_recip.encapsulate(&mut rng).unwrap(); - let ss2 = sk_recip.decapsulate(&ek).unwrap(); - assert_eq!(ss1.0, ss2.0); -} diff --git a/kem/tests/saber.rs b/kem/tests/saber.rs deleted file mode 100644 index 13e85ef6b..000000000 --- a/kem/tests/saber.rs +++ /dev/null @@ -1,53 +0,0 @@ -use kem::{Decapsulate, Encapsulate}; - -use pqcrypto::kem::firesaber::{ - decapsulate, encapsulate, keypair, Ciphertext as SaberEncappedKey, PublicKey, SecretKey, - SharedSecret as SaberSharedSecret, -}; -use rand_core::CryptoRngCore; - -// We have to define a newtype for the public and private keys because we're gonna impl -// the Encapsulate and Decapsulate traits for them -struct SaberPublicKey(PublicKey); -struct SaberPrivateKey(SecretKey); - -impl Encapsulate for SaberPublicKey { - // TODO: Encapsulation is infallible. Make this the never type once it's available - type Error = (); - - fn encapsulate( - &self, - _: &mut impl CryptoRngCore, - ) -> Result<(SaberEncappedKey, SaberSharedSecret), ()> { - let (ss, ek) = encapsulate(&self.0); - Ok((ek, ss)) - } -} - -impl Decapsulate for SaberPrivateKey { - // TODO: Decapsulation is infallible. Make this the never type once it's available - type Error = (); - - fn decapsulate(&self, ek: &SaberEncappedKey) -> Result { - Ok(decapsulate(ek, &self.0)) - } -} - -fn gen_keypair() -> (SaberPublicKey, SaberPrivateKey) { - let (pk, sk) = keypair(); - (SaberPublicKey(pk), SaberPrivateKey(sk)) -} - -#[test] -fn test_saber() { - use pqcrypto_traits::kem::SharedSecret as _; - let mut rng = rand::thread_rng(); - - // Make a recipient keypair - let (pk_recip, sk_recip) = gen_keypair(); - - // Encapsulate and decapsulate. Assert that the shared secrets are equal - let (ek, ss1) = pk_recip.encapsulate(&mut rng).unwrap(); - let ss2 = sk_recip.decapsulate(&ek).unwrap(); - assert_eq!(ss1.as_bytes(), ss2.as_bytes()); -} diff --git a/kem/tests/x3dh.rs b/kem/tests/x3dh.rs deleted file mode 100644 index b39a5adf8..000000000 --- a/kem/tests/x3dh.rs +++ /dev/null @@ -1,113 +0,0 @@ -use kem::{Decapsulate, Encapsulate}; - -use p256::ecdsa::Signature; -use rand_core::CryptoRngCore; -use x3dh_ke::{x3dh_a, x3dh_b, EphemeralKey, IdentityKey, Key, OneTimePreKey, SignedPreKey}; - -/// The shared secret type defined by x3dh_ke -type SharedSecret = [u8; 32]; - -// Define the recipient privkey type. This is a bundle of 3 privkeys of different lifespans -struct X3DhPrivkeyBundle { - ik: IdentityKey, - spk: SignedPreKey, - sig: Signature, - opk: OneTimePreKey, -} - -impl X3DhPrivkeyBundle { - fn gen() -> X3DhPrivkeyBundle { - // The default() method does actual key generation here - let ik = IdentityKey::default(); - let spk = SignedPreKey::default(); - let sig = ik.sign(&spk.pk_to_bytes()); - let opk = OneTimePreKey::default(); - X3DhPrivkeyBundle { ik, spk, sig, opk } - } - fn as_pubkeys(&self) -> X3DhPubkeyBundle { - X3DhPubkeyBundle { - ik: self.ik.strip(), - spk: self.spk.strip(), - opk: self.opk.strip(), - sig: self.sig, - } - } -} - -// The pubkeys keys associated with a privkey bundle. In x3dh-ke, all the keys serve as both -// pubkeys and privkeys. This seems dangerous but hey this isn't prod. -type X3DhPubkeyBundle = X3DhPrivkeyBundle; - -/// To encap, we need the recipient's public keys and the sender's private key -struct EncapContext(X3DhPubkeyBundle, IdentityKey); - -/// To decap, we need the recipient's private keys and the sender's public key -struct DecapContext(X3DhPrivkeyBundle, IdentityKey); - -// Define an authenticated encapsulator. To authenticate, we need a full sender keypair. -impl Encapsulate for EncapContext { - type Error = &'static str; - - fn encapsulate( - &self, - _: &mut impl CryptoRngCore, - ) -> Result<(EphemeralKey, SharedSecret), Self::Error> { - // Make a new ephemeral key. This will be the encapped key - let ek = EphemeralKey::default(); - // Deconstruct the recipient's pubkey bundle - let X3DhPubkeyBundle { - ref ik, - ref spk, - ref sig, - ref opk, - } = self.0; - let my_ik = &self.1; - - // Do the X3DH operation to get the shared secret - let shared_secret = x3dh_a(sig, my_ik, spk, &ek, ik, opk)?; - - Ok((ek, shared_secret)) - } -} - -// Define an decapsulator. Since authenticated and unauthenticated encapped keys are represented by -// the same type (which, outside of testing, should not be the case), this can do both auth'd and -// unauth'd decapsulation. -impl Decapsulate for DecapContext { - // TODO: Decapsulation is infallible. Make the Error type `!` when it's stable. - type Error = (); - - fn decapsulate(&self, ek: &EphemeralKey) -> Result { - // Deconstruct our private keys bundle - let X3DhPrivkeyBundle { - ref ik, - ref spk, - ref opk, - .. - } = self.0; - let sender_pubkey = &self.1; - - // Now decapsulate - Ok(x3dh_b(sender_pubkey, spk, ek, ik, opk)) - } -} - -#[test] -fn test_x3dh() { - let mut rng = rand::thread_rng(); - - // We use _a and _b suffixes to denote whether a key belongs to Alice or Bob. Alice is the - // sender in this case. - let sk_ident_a = IdentityKey::default(); - let pk_ident_a = sk_ident_a.strip(); - let sk_bundle_b = X3DhPrivkeyBundle::gen(); - let pk_bundle_b = sk_bundle_b.as_pubkeys(); - - let encap_context = EncapContext(pk_bundle_b, sk_ident_a); - let decap_context = DecapContext(sk_bundle_b, pk_ident_a); - - // Now do an authenticated encap - let (encapped_key, ss1) = encap_context.encapsulate(&mut rng).unwrap(); - let ss2 = decap_context.decapsulate(&encapped_key).unwrap(); - assert_eq!(ss1, ss2); -} From e22a9f6a8be72ee376eff0a9d9b29b1cbfb10fa1 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Fri, 21 Feb 2025 11:21:03 +0300 Subject: [PATCH 1283/1461] elliptic-curve: fix Nightly compiler warnings (#1758) `#[must_use]` annotations have no effect on trait methods. --- elliptic-curve/src/dev.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 5a5c38ede..1fd44bb37 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -114,12 +114,10 @@ impl Field for Scalar { self.0.is_zero() } - #[must_use] fn square(&self) -> Self { unimplemented!(); } - #[must_use] fn double(&self) -> Self { self.add(self) } @@ -601,7 +599,6 @@ impl group::Group for ProjectivePoint { Choice::from(u8::from(self == &Self::Identity)) } - #[must_use] fn double(&self) -> Self { unimplemented!(); } From 6bbf1a4a67a52c5863e3101b232e7f3f33bb47a5 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Sat, 22 Feb 2025 20:44:08 +0300 Subject: [PATCH 1284/1461] Upgrade all crates to the 2024 edition, bump MSRV to 1.85 (#1759) --- .github/workflows/aead.yml | 4 +- .github/workflows/async-signature.yml | 4 +- .github/workflows/cipher.yml | 4 +- .github/workflows/crypto-common.yml | 4 +- .github/workflows/crypto.yml | 4 +- .github/workflows/digest.yml | 4 +- .github/workflows/elliptic-curve.yml | 4 +- .github/workflows/kem.yml | 4 +- .github/workflows/password-hash.yml | 4 +- .github/workflows/signature.yml | 6 +- .github/workflows/universal-hash.yml | 4 +- .github/workflows/workspace.yml | 2 +- Cargo.lock | 473 +++--------------- Cargo.toml | 13 +- README.md | 31 +- aead/CHANGELOG.md | 2 + aead/Cargo.toml | 8 +- aead/README.md | 11 +- aead/src/dev.rs | 4 +- aead/src/lib.rs | 4 +- async-signature/CHANGELOG.md | 6 + async-signature/Cargo.toml | 4 +- async-signature/README.md | 9 +- cipher/CHANGELOG.md | 6 + cipher/Cargo.toml | 10 +- cipher/README.md | 11 +- cipher/src/block.rs | 4 +- cipher/src/block/backends.rs | 2 +- cipher/src/block/ctx.rs | 2 +- cipher/src/dev/block.rs | 10 +- cipher/src/dev/stream.rs | 2 +- cipher/src/lib.rs | 4 +- cipher/src/stream/wrapper.rs | 6 +- cipher/src/tweak.rs | 2 +- cipher/src/tweak/ctx.rs | 2 +- cipher/src/tweak/zero.rs | 8 +- crypto-common/CHANGELOG.md | 6 +- crypto-common/Cargo.toml | 6 +- crypto-common/README.md | 11 +- crypto-common/src/hazmat.rs | 7 +- crypto-common/src/lib.rs | 4 +- crypto/CHANGELOG.md | 6 + crypto/Cargo.toml | 28 +- crypto/README.md | 9 +- digest/CHANGELOG.md | 5 +- digest/Cargo.toml | 10 +- digest/README.md | 16 +- digest/src/core_api/ct_variable.rs | 2 +- digest/src/core_api/rt_variable.rs | 4 +- digest/src/core_api/wrapper.rs | 2 +- digest/src/dev.rs | 8 +- digest/src/digest.rs | 2 +- digest/src/lib.rs | 2 +- digest/src/mac.rs | 24 +- elliptic-curve/CHANGELOG.md | 6 + elliptic-curve/Cargo.lock | 447 +++++++++++++++++ elliptic-curve/Cargo.toml | 8 +- elliptic-curve/README.md | 16 +- elliptic-curve/src/arithmetic.rs | 2 +- elliptic-curve/src/dev.rs | 14 +- elliptic-curve/src/ecdh.rs | 8 +- elliptic-curve/src/field.rs | 4 +- elliptic-curve/src/hash2curve/group_digest.rs | 2 +- elliptic-curve/src/hash2curve/hash2field.rs | 2 +- .../hash2curve/hash2field/expand_msg/xmd.rs | 6 +- .../hash2curve/hash2field/expand_msg/xof.rs | 2 +- elliptic-curve/src/hash2curve/isogeny.rs | 2 +- elliptic-curve/src/jwk.rs | 6 +- elliptic-curve/src/point/non_identity.rs | 4 +- elliptic-curve/src/public_key.rs | 8 +- elliptic-curve/src/scalar/blinded.rs | 2 +- elliptic-curve/src/scalar/nonzero.rs | 4 +- elliptic-curve/src/scalar/primitive.rs | 6 +- elliptic-curve/src/secret_key.rs | 6 +- elliptic-curve/src/secret_key/pkcs8.rs | 10 +- elliptic-curve/tests/pkcs8.rs | 4 +- kem/CHANGELOG.md | 6 + kem/Cargo.toml | 4 +- kem/README.md | 16 +- password-hash/CHANGELOG.md | 6 + password-hash/Cargo.toml | 4 +- password-hash/README.md | 16 +- password-hash/src/params.rs | 2 +- signature/CHANGELOG.md | 10 +- signature/Cargo.lock | 269 ++++++++++ signature/Cargo.toml | 6 +- signature/README.md | 16 +- signature/src/signer.rs | 2 +- signature/tests/derive.rs | 4 +- signature_derive/CHANGELOG.md | 6 + signature_derive/Cargo.toml | 6 +- signature_derive/README.md | 22 +- signature_derive/src/lib.rs | 4 +- universal-hash/CHANGELOG.md | 4 +- universal-hash/Cargo.toml | 6 +- universal-hash/README.md | 16 +- universal-hash/src/lib.rs | 5 +- 97 files changed, 1055 insertions(+), 778 deletions(-) create mode 100644 elliptic-curve/Cargo.lock create mode 100644 signature/Cargo.lock diff --git a/.github/workflows/aead.yml b/.github/workflows/aead.yml index dc3476c09..5e052be8f 100644 --- a/.github/workflows/aead.yml +++ b/.github/workflows/aead.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.81.0 # MSRV + - 1.85.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -52,7 +52,7 @@ jobs: strategy: matrix: rust: - - 1.81.0 # MSRV + - 1.85.0 # MSRV - stable steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/async-signature.yml b/.github/workflows/async-signature.yml index 1846df7c6..ba351c4ef 100644 --- a/.github/workflows/async-signature.yml +++ b/.github/workflows/async-signature.yml @@ -23,7 +23,7 @@ jobs: strategy: matrix: rust: - - 1.81.0 # MSRV + - 1.85.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -42,7 +42,7 @@ jobs: strategy: matrix: rust: - - 1.81.0 # Minimum Rust version the tests pass on + - 1.85.0 # Minimum Rust version the tests pass on - stable steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/cipher.yml b/.github/workflows/cipher.yml index 28e2eb6bf..f60132124 100644 --- a/.github/workflows/cipher.yml +++ b/.github/workflows/cipher.yml @@ -23,7 +23,7 @@ jobs: strategy: matrix: rust: - - 1.81.0 # MSRV + - 1.85.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -57,7 +57,7 @@ jobs: strategy: matrix: rust: - - 1.81.0 # MSRV + - 1.85.0 # MSRV - stable steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/crypto-common.yml b/.github/workflows/crypto-common.yml index 3c4e4edf7..689ae58a5 100644 --- a/.github/workflows/crypto-common.yml +++ b/.github/workflows/crypto-common.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.81.0 # MSRV + - 1.85.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -46,7 +46,7 @@ jobs: strategy: matrix: rust: - - 1.81.0 # MSRV + - 1.85.0 # MSRV - stable steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/crypto.yml b/.github/workflows/crypto.yml index d3ec5fa81..7e197e877 100644 --- a/.github/workflows/crypto.yml +++ b/.github/workflows/crypto.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.65.0 # MSRV + - 1.85.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -55,7 +55,7 @@ jobs: strategy: matrix: rust: - - 1.65.0 # MSRV + - 1.85.0 # MSRV - stable steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/digest.yml b/.github/workflows/digest.yml index 75a70b20a..e2f6e0eb0 100644 --- a/.github/workflows/digest.yml +++ b/.github/workflows/digest.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.81.0 # MSRV + - 1.85.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -47,7 +47,7 @@ jobs: strategy: matrix: rust: - - 1.81.0 # MSRV + - 1.85.0 # MSRV - stable steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index d18193e87..ac4bdccdc 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -24,7 +24,7 @@ jobs: strategy: matrix: rust: - - 1.83.0 # MSRV + - 1.85.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -75,7 +75,7 @@ jobs: strategy: matrix: rust: - - 1.83.0 # MSRV + - 1.85.0 # MSRV - stable - nightly steps: diff --git a/.github/workflows/kem.yml b/.github/workflows/kem.yml index 70d1608f1..168f270dc 100644 --- a/.github/workflows/kem.yml +++ b/.github/workflows/kem.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.66.0 # MSRV + - 1.85.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -41,7 +41,7 @@ jobs: strategy: matrix: rust: - - 1.66.0 # MSRV + - 1.85.0 # MSRV - stable steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/password-hash.yml b/.github/workflows/password-hash.yml index 0b4754a15..0fe8ef3b4 100644 --- a/.github/workflows/password-hash.yml +++ b/.github/workflows/password-hash.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.81.0 # MSRV + - 1.85.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -57,7 +57,7 @@ jobs: strategy: matrix: rust: - - 1.81.0 # MSRV + - 1.85.0 # MSRV - stable steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/signature.yml b/.github/workflows/signature.yml index a54fe0478..905b447cf 100644 --- a/.github/workflows/signature.yml +++ b/.github/workflows/signature.yml @@ -24,7 +24,7 @@ jobs: strategy: matrix: rust: - - 1.81.0 # MSRV + - 1.85.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -51,7 +51,7 @@ jobs: strategy: matrix: rust: - - 1.81.0 # Minimum Rust version the tests pass on + - 1.85.0 # Minimum Rust version the tests pass on - stable steps: - uses: actions/checkout@v4 @@ -68,7 +68,7 @@ jobs: strategy: matrix: rust: - - 1.81.0 # MSRV + - 1.85.0 # MSRV - stable steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/universal-hash.yml b/.github/workflows/universal-hash.yml index 25896c2e1..232dc4676 100644 --- a/.github/workflows/universal-hash.yml +++ b/.github/workflows/universal-hash.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.81.0 # MSRV + - 1.85.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -47,7 +47,7 @@ jobs: strategy: matrix: rust: - - 1.81.0 # MSRV + - 1.85.0 # MSRV - stable steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index dd85b43ae..5cf81aa18 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -24,7 +24,7 @@ jobs: - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: - toolchain: 1.84.0 + toolchain: 1.85.0 components: clippy - run: cargo clippy --all --all-features --tests -- -D warnings diff --git a/Cargo.lock b/Cargo.lock index a73daeabf..85567be00 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,16 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 - -[[package]] -name = "aead" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" -dependencies = [ - "crypto-common 0.1.6", - "generic-array", -] +version = 4 [[package]] name = "aead" @@ -33,7 +23,7 @@ checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" name = "async-signature" version = "0.6.0-pre.4" dependencies = [ - "signature 2.3.0-pre.6", + "signature 2.3.0-pre.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -60,59 +50,29 @@ version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" -[[package]] -name = "bitvec" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" -dependencies = [ - "funty", - "radium", - "tap", - "wyz", -] - [[package]] name = "blobby" -version = "0.3.1" +version = "0.4.0-pre.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "847495c209977a90e8aad588b959d0ca9f5dc228096d29a6bd3defd53f35eaec" +checksum = "4a859067dcb257cb2ae028cb821399b55140b76fb8b2a360e052fe109019db43" [[package]] name = "block-buffer" -version = "0.10.4" +version = "0.11.0-rc.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +checksum = "a229bfd78e4827c91b9b95784f69492c1b77c1ab75a45a8a037b139215086f94" dependencies = [ - "generic-array", -] - -[[package]] -name = "block-buffer" -version = "0.11.0-rc.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fd016a0ddc7cb13661bf5576073ce07330a693f8608a1320b4e20561cc12cdc" -dependencies = [ - "hybrid-array", + "hybrid-array 0.3.0", "zeroize", ] [[package]] name = "block-padding" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" -dependencies = [ - "generic-array", -] - -[[package]] -name = "block-padding" -version = "0.4.0-rc.2" +version = "0.4.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6868e23cd7a5b2e18fb2e9a583910b88b8d645dd21017aafc5d0439cf16ae6d6" +checksum = "ee88d14c41bbae2e333f574a27fc73d96fe1039e5a356c20d06a7f2a34cd8e5a" dependencies = [ - "hybrid-array", + "hybrid-array 0.3.0", ] [[package]] @@ -133,71 +93,34 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "cipher" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" -dependencies = [ - "crypto-common 0.1.6", - "inout 0.1.3", -] - [[package]] name = "cipher" version = "0.5.0-pre.7" dependencies = [ "blobby", "crypto-common 0.2.0-rc.1", - "inout 0.2.0-rc.3", + "inout", "zeroize", ] -[[package]] -name = "const-oid" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" - [[package]] name = "const-oid" version = "0.10.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68ff6be19477a1bd5441f382916a89bc2a0b2c35db6d41e0f6e8538bf6d6463f" -[[package]] -name = "cpufeatures" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" -dependencies = [ - "libc", -] - [[package]] name = "crypto" -version = "0.5.1" -dependencies = [ - "aead 0.5.2", - "cipher 0.4.4", - "crypto-common 0.1.6", - "digest 0.10.7", - "elliptic-curve 0.13.8", - "password-hash 0.5.0", - "signature 2.2.0", - "universal-hash 0.5.1", -] - -[[package]] -name = "crypto-bigint" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +version = "0.6.0-pre" dependencies = [ - "generic-array", - "rand_core 0.6.4", - "subtle", - "zeroize", + "aead", + "cipher", + "crypto-common 0.2.0-rc.1", + "digest 0.11.0-pre.9", + "elliptic-curve", + "password-hash", + "signature 2.3.0-pre.6", + "universal-hash", ] [[package]] @@ -206,7 +129,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96272c2ff28b807e09250b180ad1fb7889a3258f7455759b5c3c58b719467130" dependencies = [ - "hybrid-array", + "hybrid-array 0.2.3", "num-traits", "rand_core 0.6.4", "subtle", @@ -215,31 +138,19 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +version = "0.2.0-rc.1" dependencies = [ - "generic-array", - "rand_core 0.6.4", - "typenum", + "hybrid-array 0.3.0", + "rand_core 0.9.2", ] [[package]] name = "crypto-common" version = "0.2.0-rc.1" -dependencies = [ - "hybrid-array", - "rand_core 0.9.1", -] - -[[package]] -name = "der" -version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +checksum = "b0b8ce8218c97789f16356e7896b3714f26c2ee1079b79c0b7ae7064bb9089fa" dependencies = [ - "const-oid 0.9.6", - "zeroize", + "hybrid-array 0.2.3", ] [[package]] @@ -248,50 +159,29 @@ version = "0.8.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "82db698b33305f0134faf590b9d1259dc171b5481ac41d5c8146c3b3ee7d4319" dependencies = [ - "const-oid 0.10.0-rc.3", - "pem-rfc7468", + "const-oid", "zeroize", ] -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer 0.10.4", - "crypto-common 0.1.6", - "subtle", -] - [[package]] name = "digest" version = "0.11.0-pre.9" dependencies = [ "blobby", - "block-buffer 0.11.0-rc.3", - "const-oid 0.10.0-rc.3", + "block-buffer", + "const-oid", "crypto-common 0.2.0-rc.1", "subtle", "zeroize", ] [[package]] -name = "elliptic-curve" -version = "0.13.8" +name = "digest" +version = "0.11.0-pre.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +checksum = "cf2e3d6615d99707295a9673e889bf363a04b2a466bd320c65a72536f7577379" dependencies = [ - "base16ct", - "crypto-bigint 0.5.5", - "ff", - "generic-array", - "group", - "pkcs8 0.10.2", - "rand_core 0.6.4", - "sec1 0.7.3", - "subtle", - "zeroize", + "crypto-common 0.2.0-rc.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -299,24 +189,14 @@ name = "elliptic-curve" version = "0.14.0-rc.1" dependencies = [ "base16ct", - "base64ct", - "crypto-bigint 0.6.1", - "digest 0.11.0-pre.9", + "crypto-bigint", "ff", "group", - "hex-literal", - "hkdf", - "hybrid-array", - "pem-rfc7468", - "pkcs8 0.11.0-rc.2", + "hybrid-array 0.2.3", + "pkcs8", "rand_core 0.6.4", - "sec1 0.8.0-rc.3", - "serde_json", - "serdect", - "sha2", - "sha3", + "sec1", "subtle", - "tap", "zeroize", ] @@ -326,28 +206,10 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ - "bitvec", "rand_core 0.6.4", "subtle", ] -[[package]] -name = "funty" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", - "zeroize", -] - [[package]] name = "getrandom" version = "0.2.15" @@ -401,30 +263,6 @@ dependencies = [ "stable_deref_trait", ] -[[package]] -name = "hex-literal" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" - -[[package]] -name = "hkdf" -version = "0.13.0-pre.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00176ff81091018d42ff82e8324f8e5adb0b7e0468d1358f653972562dbff031" -dependencies = [ - "hmac", -] - -[[package]] -name = "hmac" -version = "0.13.0-pre.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4b1fb14e4df79f9406b434b60acef9f45c26c50062cccf1346c6103b8c47d58" -dependencies = [ - "digest 0.11.0-pre.9", -] - [[package]] name = "hybrid-array" version = "0.2.3" @@ -436,45 +274,30 @@ dependencies = [ ] [[package]] -name = "inout" -version = "0.1.3" +name = "hybrid-array" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +checksum = "4dab50e193aebe510fe0e40230145820e02f48dae0cf339ea4204e6e708ff7bd" dependencies = [ - "block-padding 0.3.3", - "generic-array", + "typenum", + "zeroize", ] [[package]] name = "inout" -version = "0.2.0-rc.3" +version = "0.2.0-rc.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de49db00f5add6dad75a57946b75de0f26287a6fc95f4f277d48419200422beb" +checksum = "ac5e145e8ade9f74c0a5efc60ccb4e714b0144f7e2220b7ca64254feee71c57f" dependencies = [ - "block-padding 0.4.0-rc.2", - "hybrid-array", -] - -[[package]] -name = "itoa" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" - -[[package]] -name = "keccak" -version = "0.2.0-pre.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7cdd4f0dc5807b9a2b25dd48a3f58e862606fe7bd47f41ecde36e97422d7e90" -dependencies = [ - "cpufeatures", + "block-padding", + "hybrid-array 0.3.0", ] [[package]] name = "kem" version = "0.3.0-pre.0" dependencies = [ - "rand_core 0.9.1", + "rand_core 0.9.2", "zeroize", ] @@ -484,12 +307,6 @@ version = "0.2.169" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" -[[package]] -name = "memchr" -version = "2.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" - [[package]] name = "num-traits" version = "0.2.19" @@ -499,53 +316,23 @@ dependencies = [ "autocfg", ] -[[package]] -name = "password-hash" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" -dependencies = [ - "base64ct", - "rand_core 0.6.4", - "subtle", -] - [[package]] name = "password-hash" version = "0.6.0-rc.0" dependencies = [ "base64ct", - "rand_core 0.9.1", + "rand_core 0.9.2", "subtle", ] -[[package]] -name = "pem-rfc7468" -version = "1.0.0-rc.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2dfbfa5c6f0906884269722c5478e72fd4d6c0e24fe600332c6d62359567ce1" -dependencies = [ - "base64ct", -] - -[[package]] -name = "pkcs8" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" -dependencies = [ - "der 0.7.9", - "spki 0.7.3", -] - [[package]] name = "pkcs8" version = "0.11.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f22636de7c995e997ed3d8d2949b7414d4faba3efa7312a6c0e75d875a14bdd4" dependencies = [ - "der 0.8.0-rc.1", - "spki 0.8.0-rc.1", + "der", + "spki", ] [[package]] @@ -566,12 +353,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "radium" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" - [[package]] name = "rand_core" version = "0.6.4" @@ -583,34 +364,14 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a88e0da7a2c97baa202165137c158d0a2e824ac465d13d81046727b34cb247d3" +checksum = "7a509b1a2ffbe92afab0e55c8fd99dea1c280e8171bd2d88682bb20bc41cbc2c" dependencies = [ "getrandom 0.3.1", "zerocopy", ] -[[package]] -name = "ryu" -version = "1.0.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd" - -[[package]] -name = "sec1" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" -dependencies = [ - "base16ct", - "der 0.7.9", - "generic-array", - "pkcs8 0.10.2", - "subtle", - "zeroize", -] - [[package]] name = "sec1" version = "0.8.0-rc.3" @@ -618,116 +379,39 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d1988446eff153796413a73669dfaa4caa3f5ce8b25fac89e3821a39c611772e" dependencies = [ "base16ct", - "der 0.8.0-rc.1", - "hybrid-array", - "pkcs8 0.11.0-rc.2", - "serdect", + "der", + "hybrid-array 0.2.3", + "pkcs8", "subtle", "zeroize", ] -[[package]] -name = "serde" -version = "1.0.218" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8dfc9d19bdbf6d17e22319da49161d5d0108e4188e8b680aef6299eed22df60" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.218" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f09503e191f4e797cb8aac08e9a4a4695c5edf6a2e70e376d961ddd5c969f82b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.139" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44f86c3acccc9c65b153fe1b85a3be07fe5515274ec9f0653b4a0875731c72a6" -dependencies = [ - "itoa", - "memchr", - "ryu", - "serde", -] - -[[package]] -name = "serdect" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f42f67da2385b51a5f9652db9c93d78aeaf7610bf5ec366080b6de810604af53" -dependencies = [ - "base16ct", - "serde", -] - -[[package]] -name = "sha2" -version = "0.11.0-pre.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "540c0893cce56cdbcfebcec191ec8e0f470dd1889b6e7a0b503e310a94a168f5" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest 0.11.0-pre.9", -] - -[[package]] -name = "sha3" -version = "0.11.0-pre.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e485881f388c2818d709796dc883c1ffcadde9d1f0e054f3a5c14974185261a6" -dependencies = [ - "digest 0.11.0-pre.9", - "keccak", -] - [[package]] name = "signature" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +version = "2.3.0-pre.6" dependencies = [ - "rand_core 0.6.4", + "rand_core 0.9.2", ] [[package]] name = "signature" version = "2.3.0-pre.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4633ec5613e4218fbab07568ca79ee388e3c041af75f0f83a15f040f096f94cf" dependencies = [ - "digest 0.11.0-pre.9", - "hex-literal", - "rand_core 0.9.1", - "sha2", - "signature_derive", + "digest 0.11.0-pre.9 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.9.2", ] [[package]] name = "signature_derive" -version = "2.1.0" +version = "2.2.0" dependencies = [ "proc-macro2", "quote", "syn", ] -[[package]] -name = "spki" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" -dependencies = [ - "base64ct", - "der 0.7.9", -] - [[package]] name = "spki" version = "0.8.0-rc.1" @@ -735,7 +419,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37ac66481418fd7afdc584adcf3be9aa572cf6c2858814494dc2a01755f050bc" dependencies = [ "base64ct", - "der 0.8.0-rc.1", + "der", ] [[package]] @@ -761,12 +445,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "tap" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" - [[package]] name = "typenum" version = "1.18.0" @@ -779,16 +457,6 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe" -[[package]] -name = "universal-hash" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" -dependencies = [ - "crypto-common 0.1.6", - "subtle", -] - [[package]] name = "universal-hash" version = "0.6.0-rc.0" @@ -797,12 +465,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -891,15 +553,6 @@ dependencies = [ "bitflags", ] -[[package]] -name = "wyz" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" -dependencies = [ - "tap", -] - [[package]] name = "zerocopy" version = "0.8.20" diff --git a/Cargo.toml b/Cargo.toml index 354080ca9..811b606ad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -resolver = "2" +resolver = "3" members = [ "aead", "async-signature", @@ -7,15 +7,12 @@ members = [ "crypto", "crypto-common", "digest", - "elliptic-curve", "kem", "password-hash", - "signature", "signature_derive", "universal-hash", ] - -[patch.crates-io] -crypto-common = { path = "./crypto-common" } -digest = { path = "./digest" } -signature = { path = "./signature" } +exclude = [ + "elliptic-curve", + "signature", +] diff --git a/README.md b/README.md index 39f486ac5..89ffebebf 100644 --- a/README.md +++ b/README.md @@ -8,26 +8,22 @@ Collection of traits which describe functionality of cryptographic primitives. | Name | Algorithm | Crates.io | Docs | MSRV | |---------------------|-----------|:---------:|:-----:|:----:| -| [`aead`] | [Authenticated encryption] | [![crates.io](https://img.shields.io/crates/v/aead.svg)](https://crates.io/crates/aead) | [![Documentation](https://docs.rs/aead/badge.svg)](https://docs.rs/aead) | ![MSRV 1.56][msrv-1.56] | -| [`async‑signature`] | [Digital signature] | [![crates.io](https://img.shields.io/crates/v/async-signature.svg)](https://crates.io/crates/async-signature) | [![Documentation](https://docs.rs/async-signature/badge.svg)](https://docs.rs/async-signature) | ![MSRV 1.56][msrv-1.56] | -| [`cipher`] | [Block] and [stream cipher] | [![crates.io](https://img.shields.io/crates/v/cipher.svg)](https://crates.io/crates/cipher) | [![Documentation](https://docs.rs/cipher/badge.svg)](https://docs.rs/cipher) | ![MSRV 1.56][msrv-1.56] | -| [`crypto‑common`] | Common cryptographic traits | [![crates.io](https://img.shields.io/crates/v/crypto-common.svg)](https://crates.io/crates/crypto-common) | [![Documentation](https://docs.rs/crypto-common/badge.svg)](https://docs.rs/crypto-common) | ![MSRV 1.56][msrv-1.56] | -| [`digest`] | [Cryptographic hash function] | [![crates.io](https://img.shields.io/crates/v/digest.svg)](https://crates.io/crates/digest) | [![Documentation](https://docs.rs/digest/badge.svg)](https://docs.rs/digest) | ![MSRV 1.57][msrv-1.57] | -| [`elliptic‑curve`] | [Elliptic curve cryptography] | [![crates.io](https://img.shields.io/crates/v/elliptic-curve.svg)](https://crates.io/crates/elliptic-curve) | [![Documentation](https://docs.rs/elliptic-curve/badge.svg)](https://docs.rs/elliptic-curve) | ![MSRV 1.65][msrv-1.65] | -| [`kem`] | [Key encapsulation mechanism] | [![crates.io](https://img.shields.io/crates/v/kem.svg)](https://crates.io/crates/kem) | [![Documentation](https://docs.rs/kem/badge.svg)](https://docs.rs/kem) | ![MSRV 1.60][msrv-1.60] | -| [`password-hash`] | [Password hashing] | [![crates.io](https://img.shields.io/crates/v/password-hash.svg)](https://crates.io/crates/password-hash) | [![Documentation](https://docs.rs/password-hash/badge.svg)](https://docs.rs/password-hash) | ![MSRV 1.60][msrv-1.60] | -| [`signature`] | [Digital signature] | [![crates.io](https://img.shields.io/crates/v/signature.svg)](https://crates.io/crates/signature) | [![Documentation](https://docs.rs/signature/badge.svg)](https://docs.rs/signature) | ![MSRV 1.56][msrv-1.56] | -| [`universal‑hash`] | [Universal hash function] | [![crates.io](https://img.shields.io/crates/v/universal-hash.svg)](https://crates.io/crates/universal-hash) | [![Documentation](https://docs.rs/universal-hash/badge.svg)](https://docs.rs/universal-hash) | ![MSRV 1.56][msrv-1.56] | +| [`aead`] | [Authenticated encryption] | [![crates.io](https://img.shields.io/crates/v/aead.svg)](https://crates.io/crates/aead) | [![Documentation](https://docs.rs/aead/badge.svg)](https://docs.rs/aead) | ![MSRV 1.85][msrv-1.85] | +| [`async‑signature`] | [Digital signature] | [![crates.io](https://img.shields.io/crates/v/async-signature.svg)](https://crates.io/crates/async-signature) | [![Documentation](https://docs.rs/async-signature/badge.svg)](https://docs.rs/async-signature) | ![MSRV 1.85][msrv-1.85] | +| [`cipher`] | [Block] and [stream cipher] | [![crates.io](https://img.shields.io/crates/v/cipher.svg)](https://crates.io/crates/cipher) | [![Documentation](https://docs.rs/cipher/badge.svg)](https://docs.rs/cipher) | ![MSRV 1.85][msrv-1.85] | +| [`crypto‑common`] | Common cryptographic traits | [![crates.io](https://img.shields.io/crates/v/crypto-common.svg)](https://crates.io/crates/crypto-common) | [![Documentation](https://docs.rs/crypto-common/badge.svg)](https://docs.rs/crypto-common) | ![MSRV 1.85][msrv-1.85] | +| [`digest`] | [Cryptographic hash function] | [![crates.io](https://img.shields.io/crates/v/digest.svg)](https://crates.io/crates/digest) | [![Documentation](https://docs.rs/digest/badge.svg)](https://docs.rs/digest) | ![MSRV 1.85][msrv-1.85] | +| [`elliptic‑curve`] | [Elliptic curve cryptography] | [![crates.io](https://img.shields.io/crates/v/elliptic-curve.svg)](https://crates.io/crates/elliptic-curve) | [![Documentation](https://docs.rs/elliptic-curve/badge.svg)](https://docs.rs/elliptic-curve) | ![MSRV 1.85][msrv-1.85] | +| [`kem`] | [Key encapsulation mechanism] | [![crates.io](https://img.shields.io/crates/v/kem.svg)](https://crates.io/crates/kem) | [![Documentation](https://docs.rs/kem/badge.svg)](https://docs.rs/kem) | ![MSRV 1.85][msrv-1.85] | +| [`password-hash`] | [Password hashing] | [![crates.io](https://img.shields.io/crates/v/password-hash.svg)](https://crates.io/crates/password-hash) | [![Documentation](https://docs.rs/password-hash/badge.svg)](https://docs.rs/password-hash) | ![MSRV 1.85][msrv-1.85] | +| [`signature`] | [Digital signature] | [![crates.io](https://img.shields.io/crates/v/signature.svg)](https://crates.io/crates/signature) | [![Documentation](https://docs.rs/signature/badge.svg)](https://docs.rs/signature) | ![MSRV 1.85][msrv-1.85] | +| [`universal‑hash`] | [Universal hash function] | [![crates.io](https://img.shields.io/crates/v/universal-hash.svg)](https://crates.io/crates/universal-hash) | [![Documentation](https://docs.rs/universal-hash/badge.svg)](https://docs.rs/universal-hash) | ![MSRV 1.85][msrv-1.85] | ### Additional Crates | Crate name | Description | Crates.io | Docs | MSRV | |------------|-------------------------|:---------:|:-----:|:----:| -| [`crypto`] | Facade for trait crates | [![crates.io](https://img.shields.io/crates/v/crypto.svg)](https://crates.io/crates/crypto) | [![Documentation](https://docs.rs/crypto/badge.svg)](https://docs.rs/crypto) | ![MSRV 1.57][msrv-1.57] | - -### Minimum Supported Rust Version (MSRV) Policy - -MSRV bumps are considered breaking changes and will be performed only with minor version bump. +| [`crypto`] | Facade for trait crates | [![crates.io](https://img.shields.io/crates/v/crypto.svg)](https://crates.io/crates/crypto) | [![Documentation](https://docs.rs/crypto/badge.svg)](https://docs.rs/crypto) | ![MSRV 1.85][msrv-1.85] | ## License @@ -49,10 +45,7 @@ Unless you explicitly state otherwise, any contribution intentionally submitted [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg [deps-image]: https://deps.rs/repo/github/RustCrypto/traits/status.svg [deps-link]: https://deps.rs/repo/github/RustCrypto/traits -[msrv-1.56]: https://img.shields.io/badge/rustc-1.56.0+-blue.svg -[msrv-1.57]: https://img.shields.io/badge/rustc-1.57.0+-blue.svg -[msrv-1.60]: https://img.shields.io/badge/rustc-1.60.0+-blue.svg -[msrv-1.65]: https://img.shields.io/badge/rustc-1.65.0+-blue.svg +[msrv-1.85]: https://img.shields.io/badge/rustc-1.85.0+-blue.svg [//]: # (crates) diff --git a/aead/CHANGELOG.md b/aead/CHANGELOG.md index 64c3f094b..b1395f3dd 100644 --- a/aead/CHANGELOG.md +++ b/aead/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - fixup `hybrid-array` migration ([#1531]) ### Changed +- Edition changed to 2024 and MSRV bumped to 1.85 ([#1759]) - Migrate to `doc_auto_cfg` ([#1370]) - Exclude pre-1.60 crates from workspace ([#1380]) - bump `crypto-common` to v0.2.0-pre; MSRV 1.65 ([#1384]) @@ -39,6 +40,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [#1469]: https://github.com/RustCrypto/traits/pull/1469 [#1496]: https://github.com/RustCrypto/traits/pull/1496 [#1531]: https://github.com/RustCrypto/traits/pull/1531 +[#1759]: https://github.com/RustCrypto/traits/pull/1759 ## 0.5.2 (2023-04-02) ### Added diff --git a/aead/Cargo.toml b/aead/Cargo.toml index 5c6da836f..6259fcfc6 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -6,21 +6,21 @@ Traits for Authenticated Encryption with Associated Data (AEAD) algorithms, such as AES-GCM as ChaCha20Poly1305, which provide a high-level API """ authors = ["RustCrypto Developers"] -edition = "2021" license = "MIT OR Apache-2.0" readme = "README.md" +edition = "2024" +rust-version = "1.85" documentation = "https://docs.rs/aead" repository = "https://github.com/RustCrypto/traits" keywords = ["crypto", "encryption"] categories = ["cryptography", "no-std"] -rust-version = "1.81" [dependencies] -crypto-common = "0.2.0-rc.1" +crypto-common = { version = "0.2.0-rc.1", path = "../crypto-common" } # optional dependencies arrayvec = { version = "0.7", optional = true, default-features = false } -blobby = { version = "0.3", optional = true } +blobby = { version = "0.4.0-pre.0", optional = true } bytes = { version = "1", optional = true, default-features = false } heapless = { version = "0.8", optional = true, default-features = false } diff --git a/aead/README.md b/aead/README.md index 0a0dd045a..a775d428c 100644 --- a/aead/README.md +++ b/aead/README.md @@ -15,15 +15,6 @@ modern cryptographic implementations. See [RustCrypto/AEADs] for cipher implementations which use this trait. -[Documentation][docs-link] - -## Minimum Supported Rust Version - -Rust **1.81** or higher. - -Minimum supported Rust version can be changed in the future, but it will be -done with a minor version bump. - ## SemVer Policy - All on-by-default features of this library are covered by SemVer @@ -51,7 +42,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/aead/badge.svg [docs-link]: https://docs.rs/aead/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.81+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.85+-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/traits/workflows/aead/badge.svg?branch=master&event=push diff --git a/aead/src/dev.rs b/aead/src/dev.rs index b7edf89cb..b128014bd 100644 --- a/aead/src/dev.rs +++ b/aead/src/dev.rs @@ -8,9 +8,9 @@ macro_rules! new_test { #[test] fn $name() { use aead::{ - array::{typenum::Unsigned, Array}, - dev::blobby::Blob6Iterator, Aead, KeyInit, Payload, + array::{Array, typenum::Unsigned}, + dev::blobby::Blob6Iterator, }; fn run_test( diff --git a/aead/src/lib.rs b/aead/src/lib.rs index cdd28e132..0294b6f48 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -22,8 +22,8 @@ pub mod dev; pub mod stream; pub use crypto_common::{ - array::{self, typenum::consts}, Key, KeyInit, KeySizeUser, + array::{self, typenum::consts}, }; #[cfg(feature = "arrayvec")] @@ -37,7 +37,7 @@ pub use heapless; pub use crypto_common::rand_core; use core::fmt; -use crypto_common::array::{typenum::Unsigned, Array, ArraySize}; +use crypto_common::array::{Array, ArraySize, typenum::Unsigned}; #[cfg(feature = "alloc")] use alloc::vec::Vec; diff --git a/async-signature/CHANGELOG.md b/async-signature/CHANGELOG.md index 70bd82f9e..bef58c09a 100644 --- a/async-signature/CHANGELOG.md +++ b/async-signature/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.6.0 (UNRELEASED) +### Changed +- Edition changed to 2024 and MSRV bumped to 1.85 ([#1759]) + +[#1759]: https://github.com/RustCrypto/traits/pull/1759 + ## 0.5.1 (2024-04-02) ### Added - `no_std` support ([#1544]) diff --git a/async-signature/Cargo.toml b/async-signature/Cargo.toml index 01ba8a4ff..18bc0d095 100644 --- a/async-signature/Cargo.toml +++ b/async-signature/Cargo.toml @@ -10,8 +10,8 @@ repository = "https://github.com/RustCrypto/traits" readme = "README.md" keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"] categories = ["cryptography", "no-std"] -edition = "2021" -rust-version = "1.81" +edition = "2024" +rust-version = "1.85" [dependencies] signature = "=2.3.0-pre.6" diff --git a/async-signature/README.md b/async-signature/README.md index a1898475b..5c3fbe08e 100644 --- a/async-signature/README.md +++ b/async-signature/README.md @@ -11,13 +11,6 @@ This crate is now deprecated, all the types are available in [`signature`][signature-crate] -## Minimum Supported Rust Version - -Rust **1.81** or higher. - -Minimum supported Rust version can be changed in the future, but it will be -done with a minor version bump. - ## License Licensed under either of @@ -40,7 +33,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/async-signature/badge.svg [docs-link]: https://docs.rs/async-signature/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.81+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260048-signatures [build-image]: https://github.com/RustCrypto/traits/workflows/async-signature/badge.svg?branch=master&event=push diff --git a/cipher/CHANGELOG.md b/cipher/CHANGELOG.md index 4a388fb37..c818a3ece 100644 --- a/cipher/CHANGELOG.md +++ b/cipher/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.5.0 (UNRELEASED) +### Changed +- Edition changed to 2024 and MSRV bumped to 1.85 ([#1759]) + +[#1759]: https://github.com/RustCrypto/traits/pull/1759 + ## 0.4.4 (2022-03-09) ### Changed - Move `ParBlocks`/`ParBlocksSizeUser` to the `crypto-common` crate ([#1052]) diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index ab140c9d1..95b9735d4 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -5,19 +5,19 @@ version = "0.5.0-pre.7" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" -edition = "2021" -rust-version = "1.81" +edition = "2024" +rust-version = "1.85" documentation = "https://docs.rs/cipher" repository = "https://github.com/RustCrypto/traits" keywords = ["crypto", "block-cipher", "stream-cipher", "trait"] categories = ["cryptography", "no-std"] [dependencies] -crypto-common = "0.2.0-rc.1" -inout = "0.2.0-rc.1" +crypto-common = { version = "0.2.0-rc.1", path = "../crypto-common" } +inout = "0.2.0-rc.4" # optional dependencies -blobby = { version = "0.3", optional = true } +blobby = { version = "0.4.0-pre.0", optional = true } zeroize = { version = "1.8", optional = true, default-features = false } [features] diff --git a/cipher/README.md b/cipher/README.md index 350be54bd..217e5b909 100644 --- a/cipher/README.md +++ b/cipher/README.md @@ -12,15 +12,6 @@ Traits which define the functionality of [block ciphers] and [stream ciphers]. See [RustCrypto/block-ciphers] and [RustCrypto/stream-ciphers] for algorithm implementations which use these traits. -[Documentation][docs-link] - -## Minimum Supported Rust Version - -Rust **1.81** or higher. - -Minimum supported Rust version can be changed in the future, but it will be -done with a minor version bump. - ## SemVer Policy - All on-by-default features of this library are covered by SemVer @@ -48,7 +39,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/cipher/badge.svg [docs-link]: https://docs.rs/cipher/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.81+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260050-traits [build-image]: https://github.com/RustCrypto/traits/workflows/cipher/badge.svg?branch=master&event=push diff --git a/cipher/src/block.rs b/cipher/src/block.rs index 3699ebfdb..253e6c704 100644 --- a/cipher/src/block.rs +++ b/cipher/src/block.rs @@ -13,12 +13,12 @@ #[cfg(all(feature = "block-padding", feature = "alloc"))] use alloc::{vec, vec::Vec}; use crypto_common::{Block, BlockSizeUser}; +use inout::{InOut, InOutBuf, NotEqualError}; #[cfg(feature = "block-padding")] use inout::{ - block_padding::{Padding, UnpadError}, InOutBufReserved, PadError, + block_padding::{Padding, UnpadError}, }; -use inout::{InOut, InOutBuf, NotEqualError}; mod backends; mod ctx; diff --git a/cipher/src/block/backends.rs b/cipher/src/block/backends.rs index e035b3993..1def03b9b 100644 --- a/cipher/src/block/backends.rs +++ b/cipher/src/block/backends.rs @@ -1,4 +1,4 @@ -use crypto_common::{typenum::Unsigned, Block, BlockSizeUser, ParBlocks, ParBlocksSizeUser}; +use crypto_common::{Block, BlockSizeUser, ParBlocks, ParBlocksSizeUser, typenum::Unsigned}; use inout::{InOut, InOutBuf}; /// Trait implemented by block cipher mode encryption backends. diff --git a/cipher/src/block/ctx.rs b/cipher/src/block/ctx.rs index 7a7634120..80b0537ed 100644 --- a/cipher/src/block/ctx.rs +++ b/cipher/src/block/ctx.rs @@ -1,4 +1,4 @@ -use crypto_common::{typenum::Unsigned, Block, BlockSizeUser, BlockSizes}; +use crypto_common::{Block, BlockSizeUser, BlockSizes, typenum::Unsigned}; use inout::{InOut, InOutBuf}; use super::{ diff --git a/cipher/src/dev/block.rs b/cipher/src/dev/block.rs index 42558c561..6a7f90426 100644 --- a/cipher/src/dev/block.rs +++ b/cipher/src/dev/block.rs @@ -7,11 +7,11 @@ macro_rules! block_cipher_test { #[test] fn $name() { use cipher::{ + BlockSizeUser, KeyInit, array::Array, blobby::Blob3Iterator, block::{BlockCipherDecrypt, BlockCipherEncrypt}, typenum::Unsigned, - BlockSizeUser, KeyInit, }; fn run_test(key: &[u8], pt: &[u8], ct: &[u8]) -> bool { @@ -104,8 +104,8 @@ macro_rules! block_mode_enc_test { #[test] fn $name() { use cipher::{ - array::Array, blobby::Blob4Iterator, inout::InOutBuf, typenum::Unsigned, - BlockCipherEncrypt, BlockModeEncrypt, BlockSizeUser, KeyIvInit, + BlockCipherEncrypt, BlockModeEncrypt, BlockSizeUser, KeyIvInit, array::Array, + blobby::Blob4Iterator, inout::InOutBuf, typenum::Unsigned, }; fn run_test(key: &[u8], iv: &[u8], pt: &[u8], ct: &[u8]) -> bool { @@ -162,8 +162,8 @@ macro_rules! block_mode_dec_test { #[test] fn $name() { use cipher::{ - array::Array, blobby::Blob4Iterator, inout::InOutBuf, typenum::Unsigned, - BlockCipherDecrypt, BlockModeDecrypt, BlockSizeUser, KeyIvInit, + BlockCipherDecrypt, BlockModeDecrypt, BlockSizeUser, KeyIvInit, array::Array, + blobby::Blob4Iterator, inout::InOutBuf, typenum::Unsigned, }; fn run_test(key: &[u8], iv: &[u8], pt: &[u8], ct: &[u8]) -> bool { diff --git a/cipher/src/dev/stream.rs b/cipher/src/dev/stream.rs index 5502b7fe8..ff530f4cd 100644 --- a/cipher/src/dev/stream.rs +++ b/cipher/src/dev/stream.rs @@ -7,7 +7,7 @@ macro_rules! stream_cipher_test { #[test] fn $name() { use cipher::array::Array; - use cipher::{blobby::Blob4Iterator, KeyIvInit, StreamCipher}; + use cipher::{KeyIvInit, StreamCipher, blobby::Blob4Iterator}; let data = include_bytes!(concat!("data/", $test_name, ".blb")); for (i, row) in Blob4Iterator::new(data).unwrap().enumerate() { diff --git a/cipher/src/lib.rs b/cipher/src/lib.rs index 9fff63c52..7771e5973 100644 --- a/cipher/src/lib.rs +++ b/cipher/src/lib.rs @@ -43,9 +43,9 @@ pub use stream::*; pub use tweak::*; pub use crypto_common::{ - array::{self, Array}, - typenum::{self, consts}, AlgorithmName, Block, BlockSizeUser, InnerIvInit, InvalidLength, Iv, IvSizeUser, IvState, Key, KeyInit, KeyIvInit, KeySizeUser, ParBlocks, ParBlocksSizeUser, + array::{self, Array}, + typenum::{self, consts}, }; pub use inout::{InOut, InOutBuf}; diff --git a/cipher/src/stream/wrapper.rs b/cipher/src/stream/wrapper.rs index 16863a42c..e438ef4a4 100644 --- a/cipher/src/stream/wrapper.rs +++ b/cipher/src/stream/wrapper.rs @@ -1,9 +1,9 @@ use super::{ - errors::StreamCipherError, Block, OverflowError, SeekNum, StreamCipher, StreamCipherCore, - StreamCipherSeek, StreamCipherSeekCore, + Block, OverflowError, SeekNum, StreamCipher, StreamCipherCore, StreamCipherSeek, + StreamCipherSeekCore, errors::StreamCipherError, }; use core::fmt; -use crypto_common::{typenum::Unsigned, Iv, IvSizeUser, Key, KeyInit, KeyIvInit, KeySizeUser}; +use crypto_common::{Iv, IvSizeUser, Key, KeyInit, KeyIvInit, KeySizeUser, typenum::Unsigned}; use inout::InOutBuf; #[cfg(feature = "zeroize")] use zeroize::{Zeroize, ZeroizeOnDrop}; diff --git a/cipher/src/tweak.rs b/cipher/src/tweak.rs index ec3cb432e..3aa315d47 100644 --- a/cipher/src/tweak.rs +++ b/cipher/src/tweak.rs @@ -2,8 +2,8 @@ //! //! [1]: https://people.eecs.berkeley.edu/~daw/papers/tweak-crypto02.pdf use crypto_common::{ - array::{Array, ArraySize}, Block, BlockSizeUser, + array::{Array, ArraySize}, }; use inout::InOut; diff --git a/cipher/src/tweak/ctx.rs b/cipher/src/tweak/ctx.rs index 65ca6a557..07e91dc75 100644 --- a/cipher/src/tweak/ctx.rs +++ b/cipher/src/tweak/ctx.rs @@ -1,4 +1,4 @@ -use crypto_common::{array::ArraySize, Block, BlockSizeUser, BlockSizes}; +use crypto_common::{Block, BlockSizeUser, BlockSizes, array::ArraySize}; use inout::InOut; use super::{ diff --git a/cipher/src/tweak/zero.rs b/cipher/src/tweak/zero.rs index 9bebf1a90..1dca78f22 100644 --- a/cipher/src/tweak/zero.rs +++ b/cipher/src/tweak/zero.rs @@ -1,15 +1,15 @@ use core::marker::PhantomData; -use crypto_common::{array::ArraySize, Block, BlockSizes, ParBlocksSizeUser}; +use crypto_common::{Block, BlockSizes, ParBlocksSizeUser, array::ArraySize}; use super::{ TweakBlockCipherDecBackend, TweakBlockCipherDecClosure, TweakBlockCipherDecrypt, TweakBlockCipherEncBackend, TweakBlockCipherEncrypt, TweakSizeUser, }; use crate::{ - consts::U1, tweak::TweakBlockCipherEncClosure, BlockCipherDecBackend, BlockCipherDecClosure, - BlockCipherDecrypt, BlockCipherEncBackend, BlockCipherEncClosure, BlockCipherEncrypt, - BlockSizeUser, + BlockCipherDecBackend, BlockCipherDecClosure, BlockCipherDecrypt, BlockCipherEncBackend, + BlockCipherEncClosure, BlockCipherEncrypt, BlockSizeUser, consts::U1, + tweak::TweakBlockCipherEncClosure, }; /// Wrapper around tweakable block cipher which implements diff --git a/crypto-common/CHANGELOG.md b/crypto-common/CHANGELOG.md index 448cb106c..71cea962e 100644 --- a/crypto-common/CHANGELOG.md +++ b/crypto-common/CHANGELOG.md @@ -5,13 +5,15 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## UNRELEASED +## 0.2.0 (UNRELEASED) ### Added - Sealed `BlockSizes` trait implemented for types from `U1` to `U255` ### Changed - `BlockUser::BlockSize` is now bounded by the `BlockSizes` trait -- Edition changed to 2021 and MSRV bumped to 1.56 +- Edition changed to 2024 and MSRV bumped to 1.85 ([#1759]) + +[#1759]: https://github.com/RustCrypto/traits/pull/1759 ## 0.1.6 (2022-07-16) ### Added diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index 48dcd6909..47dc148aa 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -5,15 +5,15 @@ version = "0.2.0-rc.1" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" -edition = "2021" -rust-version = "1.81" +edition = "2024" +rust-version = "1.85" documentation = "https://docs.rs/crypto-common" repository = "https://github.com/RustCrypto/traits" keywords = ["crypto", "traits"] categories = ["cryptography", "no-std"] [dependencies] -hybrid-array = "0.2" +hybrid-array = "0.3" # optional dependencies rand_core = { version = "0.9", optional = true } diff --git a/crypto-common/README.md b/crypto-common/README.md index 2197b4091..afe814106 100644 --- a/crypto-common/README.md +++ b/crypto-common/README.md @@ -10,15 +10,6 @@ Common traits used by cryptographic algorithms. Users should generally use higher-level trait crates instead of this one. -[Documentation][docs-link] - -## Minimum Supported Rust Version - -Rust **1.81** or higher. - -Minimum supported Rust version can be changed in the future, but it will be -done with a minor version bump. - ## SemVer Policy - All on-by-default features of this library are covered by SemVer @@ -46,7 +37,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/crypto-common/badge.svg [docs-link]: https://docs.rs/crypto-common/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.81+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260041-hashes [build-image]: https://github.com/RustCrypto/traits/workflows/crypto-common/badge.svg?branch=master&event=push diff --git a/crypto-common/src/hazmat.rs b/crypto-common/src/hazmat.rs index b8df738aa..864239534 100644 --- a/crypto-common/src/hazmat.rs +++ b/crypto-common/src/hazmat.rs @@ -1,7 +1,6 @@ use crate::array::{ - self, - typenum::{Diff, Prod, Sum, Unsigned, U1, U16, U2, U4, U8}, - Array, ArraySize, + self, Array, ArraySize, + typenum::{Diff, Prod, Sum, U1, U2, U4, U8, U16, Unsigned}, }; use core::{convert::TryInto, default::Default, fmt}; @@ -52,7 +51,7 @@ where fn serialize(&self) -> SerializedState; /// Create an object from serialized internal state. fn deserialize(serialized_state: &SerializedState) - -> Result; + -> Result; } macro_rules! impl_seializable_state_unsigned { diff --git a/crypto-common/src/lib.rs b/crypto-common/src/lib.rs index ddd2db7fe..240e1257d 100644 --- a/crypto-common/src/lib.rs +++ b/crypto-common/src/lib.rs @@ -20,8 +20,8 @@ pub use hybrid_array::typenum; use core::fmt; use hybrid_array::{ - typenum::{Diff, Sum, Unsigned}, Array, ArraySize, + typenum::{Diff, Sum, Unsigned}, }; #[cfg(feature = "rand_core")] @@ -79,7 +79,7 @@ pub trait BlockSizes: ArraySize + sealed::BlockSizes {} impl BlockSizes for T {} mod sealed { - use crate::typenum::{Gr, IsGreater, IsLess, Le, NonZero, Unsigned, U0, U256}; + use crate::typenum::{Gr, IsGreater, IsLess, Le, NonZero, U0, U256, Unsigned}; pub trait BlockSizes {} diff --git a/crypto/CHANGELOG.md b/crypto/CHANGELOG.md index 55339b261..f5b7fd9c8 100644 --- a/crypto/CHANGELOG.md +++ b/crypto/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.6.0 (UNRELEASED) +### Changed +- Edition changed to 2024 and MSRV bumped to 1.85 ([#1759]) + +[#1759]: https://github.com/RustCrypto/traits/pull/1759 + ## 0.5.1 (2023-05-27) Unchanged from v0.5.0, but published to trigger a new docs.rs build. diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 24eb941cc..855af57ed 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "crypto" -version = "0.5.1" +version = "0.6.0-pre" description = "Facade crate for all of the RustCrypto traits (e.g. `aead`, `cipher`, `digest`)" authors = ["The RustCrypto Project Developers"] license = "Apache-2.0 OR MIT" @@ -9,32 +9,28 @@ repository = "https://github.com/RustCrypto/traits" keywords = ["crypto", "encryption", "rustcrypto"] categories = ["cryptography", "no-std"] readme = "README.md" -edition = "2021" -rust-version = "1.65" +edition = "2024" +rust-version = "1.85" [dependencies] -crypto-common = { version = "0.1", default-features = false } +crypto-common = { version = "0.2.0-rc.1", path = "../crypto-common", default-features = false } # optional dependencies -aead = { version = "0.5", optional = true } -cipher = { version = "0.4", optional = true } -digest = { version = "0.10", optional = true, features = ["mac"] } -elliptic-curve = { version = "0.13", optional = true } -password-hash = { version = "0.5", optional = true } -signature = { version = "2", optional = true, default-features = false } -universal-hash = { version = "0.5", optional = true } +aead = { version = "0.6.0-rc.0", path = "../aead", optional = true } +cipher = { version = "0.5.0-pre.7", path = "../cipher", optional = true } +digest = { version = "0.11.0-pre.9", path = "../digest", optional = true, features = ["mac"] } +elliptic-curve = { version = "0.14.0-rc.1", path = "../elliptic-curve", optional = true } +password-hash = { version = "0.6.0-rc.0", path = "../password-hash", optional = true } +signature = { version = "2.3.0-pre.6", path = "../signature", optional = true, default-features = false } +universal-hash = { version = "0.6.0-rc.0", path = "../universal-hash", optional = true } [features] std = [ - "aead/std", - "cipher/std", "digest/std", "elliptic-curve/std", - "password-hash/std", "signature/std", - "universal-hash/std" ] -getrandom = ["crypto-common/getrandom"] +os_rng = ["crypto-common/os_rng"] rand_core = ["crypto-common/rand_core"] [package.metadata.docs.rs] diff --git a/crypto/README.md b/crypto/README.md index 7c5ac4c49..5041bc108 100644 --- a/crypto/README.md +++ b/crypto/README.md @@ -50,13 +50,6 @@ depend on) must enable the associated Cargo feature named below. [1]: https://github.com/RustCrypto/traits [2]: https://github.com/RustCrypto -## Minimum Supported Rust Version - -Rust **1.65** or higher. - -Minimum supported Rust version can be changed in the future, but it will be -done with a minor version bump. - ## SemVer Policy - All on-by-default features of this library are covered by SemVer @@ -84,7 +77,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/crypto/badge.svg [docs-link]: https://docs.rs/crypto/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.65+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260050-Traits [build-image]: https://github.com/RustCrypto/traits/workflows/crypto/badge.svg?branch=master&event=push diff --git a/digest/CHANGELOG.md b/digest/CHANGELOG.md index afff142f6..a6c58234d 100644 --- a/digest/CHANGELOG.md +++ b/digest/CHANGELOG.md @@ -5,19 +5,20 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## UNRELEASED +## 0.11.0 (UNRELEASED) ### Added - `CustomizedInit` trait ([#1334]). ### Changed - `crypto-common` dependency bumped to v0.2 ([#1173]) -- Edition changed to 2021 and MSRV bumped to 1.57 ([#1173]) +- Edition changed to 2024 and MSRV bumped to 1.85 ([#1759]) ### Removed - `Mac::new`, `Mac::new_from_slice`, and `Mac::generate_key` methods ([#1173]) [#1173]: https://github.com/RustCrypto/traits/pull/1173 [#1334]: https://github.com/RustCrypto/traits/pull/1334 +[#1759]: https://github.com/RustCrypto/traits/pull/1759 ## 0.10.7 (2023-05-19) ### Changed diff --git a/digest/Cargo.toml b/digest/Cargo.toml index a30d3bf9d..3612efd63 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -5,20 +5,20 @@ version = "0.11.0-pre.9" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" -edition = "2021" -rust-version = "1.81" +edition = "2024" +rust-version = "1.85" documentation = "https://docs.rs/digest" repository = "https://github.com/RustCrypto/traits" keywords = ["digest", "crypto", "hash"] categories = ["cryptography", "no-std"] [dependencies] -crypto-common = "0.2.0-rc.1" +crypto-common = { version = "0.2.0-rc.1", path = "../crypto-common" } # optional dependencies -block-buffer = { version = "0.11.0-rc.2", optional = true } +block-buffer = { version = "0.11.0-rc.4", optional = true } subtle = { version = "2.4", default-features = false, optional = true } -blobby = { version = "0.3", optional = true } +blobby = { version = "0.4.0-pre.0", optional = true } const-oid = { version = "0.10.0-rc.3", optional = true } zeroize = { version = "1.7", optional = true, default-features = false } diff --git a/digest/README.md b/digest/README.md index dc527f713..e88f5ca88 100644 --- a/digest/README.md +++ b/digest/README.md @@ -12,20 +12,6 @@ digest algorithms. See [RustCrypto/hashes][1] for implementations which use this trait. -[Documentation][docs-link] - -## Minimum Supported Rust Version - -Rust **1.81** or higher. - -Minimum supported Rust version can be changed in the future, but it will be -done with a minor version bump. - -## SemVer Policy - -- All on-by-default features of this library are covered by SemVer -- MSRV is considered exempt from SemVer as noted above - ## Usage Let us demonstrate how to use crates in this repository using Sha256 as an @@ -147,7 +133,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/digest/badge.svg [docs-link]: https://docs.rs/digest/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.81+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260041-hashes [build-image]: https://github.com/RustCrypto/traits/workflows/digest/badge.svg?branch=master&event=push diff --git a/digest/src/core_api/ct_variable.rs b/digest/src/core_api/ct_variable.rs index b676a352c..57a093d98 100644 --- a/digest/src/core_api/ct_variable.rs +++ b/digest/src/core_api/ct_variable.rs @@ -13,10 +13,10 @@ use core::{ ops::{Add, Sub}, }; use crypto_common::{ + Block, BlockSizeUser, OutputSizeUser, array::{Array, ArraySize}, hazmat::{DeserializeStateError, SerializableState, SerializedState, SubSerializedStateSize}, typenum::{IsLess, IsLessOrEqual, Le, LeEq, NonZero, Sum, U1, U256}, - Block, BlockSizeUser, OutputSizeUser, }; /// Dummy type used with [`CtVariableCoreWrapper`] in cases when diff --git a/digest/src/core_api/rt_variable.rs b/digest/src/core_api/rt_variable.rs index b1a42942f..17f13ae8e 100644 --- a/digest/src/core_api/rt_variable.rs +++ b/digest/src/core_api/rt_variable.rs @@ -10,10 +10,10 @@ use core::{ ops::{Add, Sub}, }; use crypto_common::{ + AddBlockSize, SubBlockSize, array::{Array, ArraySize}, hazmat::{DeserializeStateError, SerializableState, SerializedState, SubSerializedStateSize}, - typenum::{Diff, IsLess, Le, NonZero, Sum, Unsigned, U1, U256}, - AddBlockSize, SubBlockSize, + typenum::{Diff, IsLess, Le, NonZero, Sum, U1, U256, Unsigned}, }; #[cfg(feature = "zeroize")] use zeroize::ZeroizeOnDrop; diff --git a/digest/src/core_api/wrapper.rs b/digest/src/core_api/wrapper.rs index 5d8f45d4d..55062e7c8 100644 --- a/digest/src/core_api/wrapper.rs +++ b/digest/src/core_api/wrapper.rs @@ -13,10 +13,10 @@ use core::{ ops::{Add, Sub}, }; use crypto_common::{ + BlockSizeUser, InvalidLength, Key, KeyInit, KeySizeUser, Output, array::{Array, ArraySize}, hazmat::{DeserializeStateError, SerializableState, SerializedState, SubSerializedStateSize}, typenum::{Diff, IsLess, Le, NonZero, Sum, U1, U256}, - BlockSizeUser, InvalidLength, Key, KeyInit, KeySizeUser, Output, }; #[cfg(feature = "mac")] diff --git a/digest/src/dev.rs b/digest/src/dev.rs index 00b93859b..b3d0203dc 100644 --- a/digest/src/dev.rs +++ b/digest/src/dev.rs @@ -44,9 +44,9 @@ macro_rules! hash_serialization_test { #[test] fn $name() { use digest::{ - crypto_common::{hazmat::SerializableState, BlockSizeUser}, - typenum::Unsigned, Digest, + crypto_common::{BlockSizeUser, hazmat::SerializableState}, + typenum::Unsigned, }; let mut h = <$hasher>::new(); @@ -77,9 +77,9 @@ macro_rules! hash_rt_outsize_serialization_test { #[test] fn $name() { use digest::{ - crypto_common::{hazmat::SerializableState, BlockSizeUser}, - typenum::Unsigned, Digest, Update, VariableOutput, + crypto_common::{BlockSizeUser, hazmat::SerializableState}, + typenum::Unsigned, }; const HASH_OUTPUT_SIZE: usize = <$hasher>::MAX_OUTPUT_SIZE - 1; diff --git a/digest/src/digest.rs b/digest/src/digest.rs index c8d1ca87e..1de1ea86d 100644 --- a/digest/src/digest.rs +++ b/digest/src/digest.rs @@ -1,5 +1,5 @@ use super::{FixedOutput, FixedOutputReset, InvalidBufferSize, Reset, Update}; -use crypto_common::{typenum::Unsigned, Output, OutputSizeUser}; +use crypto_common::{Output, OutputSizeUser, typenum::Unsigned}; #[cfg(feature = "alloc")] use alloc::boxed::Box; diff --git a/digest/src/lib.rs b/digest/src/lib.rs index a3e6fca86..b74ca517e 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -65,9 +65,9 @@ pub use crypto_common; #[cfg(feature = "const-oid")] pub use crate::digest::DynDigestWithOid; pub use crate::digest::{Digest, DynDigest, HashMarker}; -pub use crypto_common::{array, typenum, typenum::consts, Output, OutputSizeUser, Reset}; #[cfg(feature = "mac")] pub use crypto_common::{InnerInit, InvalidLength, Key, KeyInit}; +pub use crypto_common::{Output, OutputSizeUser, Reset, array, typenum, typenum::consts}; #[cfg(feature = "mac")] pub use mac::{CtOutput, Mac, MacError, MacMarker}; diff --git a/digest/src/mac.rs b/digest/src/mac.rs index 395f86e09..b49fe692e 100644 --- a/digest/src/mac.rs +++ b/digest/src/mac.rs @@ -134,11 +134,7 @@ impl Mac for T { return Err(MacError); } let choice = self.finalize_fixed().ct_eq(tag); - if choice.into() { - Ok(()) - } else { - Err(MacError) - } + if choice.into() { Ok(()) } else { Err(MacError) } } #[inline] @@ -151,11 +147,7 @@ impl Mac for T { return Err(MacError); } let choice = self.finalize_fixed_reset().ct_eq(tag); - if choice.into() { - Ok(()) - } else { - Err(MacError) - } + if choice.into() { Ok(()) } else { Err(MacError) } } fn verify_truncated_left(self, tag: &[u8]) -> Result<(), MacError> { @@ -165,11 +157,7 @@ impl Mac for T { } let choice = self.finalize_fixed()[..n].ct_eq(tag); - if choice.into() { - Ok(()) - } else { - Err(MacError) - } + if choice.into() { Ok(()) } else { Err(MacError) } } fn verify_truncated_right(self, tag: &[u8]) -> Result<(), MacError> { @@ -180,11 +168,7 @@ impl Mac for T { let m = Self::OutputSize::USIZE - n; let choice = self.finalize_fixed()[m..].ct_eq(tag); - if choice.into() { - Ok(()) - } else { - Err(MacError) - } + if choice.into() { Ok(()) } else { Err(MacError) } } } diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index 37b563149..7d50c6e18 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.14.0 (UNRELEASED) +### Changed +- Edition changed to 2024 and MSRV bumped to 1.85 ([#1759]) + +[#1759]: https://github.com/RustCrypto/traits/pull/1759 + ## 0.13.8 (2023-11-18) ### Changed - `SecretKey::from_slice` now allows >=24-bytes ([#1412]) diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock new file mode 100644 index 000000000..1659ec061 --- /dev/null +++ b/elliptic-curve/Cargo.lock @@ -0,0 +1,447 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "block-buffer" +version = "0.11.0-rc.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fd016a0ddc7cb13661bf5576073ce07330a693f8608a1320b4e20561cc12cdc" +dependencies = [ + "hybrid-array", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "const-oid" +version = "0.10.0-rc.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68ff6be19477a1bd5441f382916a89bc2a0b2c35db6d41e0f6e8538bf6d6463f" + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-bigint" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96272c2ff28b807e09250b180ad1fb7889a3258f7455759b5c3c58b719467130" +dependencies = [ + "hybrid-array", + "num-traits", + "rand_core", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.2.0-rc.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0b8ce8218c97789f16356e7896b3714f26c2ee1079b79c0b7ae7064bb9089fa" +dependencies = [ + "getrandom", + "hybrid-array", + "rand_core", +] + +[[package]] +name = "der" +version = "0.8.0-rc.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82db698b33305f0134faf590b9d1259dc171b5481ac41d5c8146c3b3ee7d4319" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + +[[package]] +name = "digest" +version = "0.11.0-pre.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf2e3d6615d99707295a9673e889bf363a04b2a466bd320c65a72536f7577379" +dependencies = [ + "block-buffer", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "elliptic-curve" +version = "0.14.0-rc.1" +dependencies = [ + "base16ct", + "base64ct", + "crypto-bigint", + "digest", + "ff", + "group", + "hex-literal", + "hkdf", + "hybrid-array", + "pem-rfc7468", + "pkcs8", + "rand_core", + "sec1", + "serde_json", + "serdect", + "sha2", + "sha3", + "subtle", + "tap", + "zeroize", +] + +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "bitvec", + "rand_core", + "subtle", +] + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core", + "subtle", +] + +[[package]] +name = "hex-literal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcaaec4551594c969335c98c903c1397853d4198408ea609190f420500f6be71" + +[[package]] +name = "hkdf" +version = "0.13.0-pre.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00176ff81091018d42ff82e8324f8e5adb0b7e0468d1358f653972562dbff031" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.13.0-pre.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4b1fb14e4df79f9406b434b60acef9f45c26c50062cccf1346c6103b8c47d58" +dependencies = [ + "digest", +] + +[[package]] +name = "hybrid-array" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2d35805454dc9f8662a98d6d61886ffe26bd465f5960e0e55345c70d5c0d2a9" +dependencies = [ + "typenum", + "zeroize", +] + +[[package]] +name = "itoa" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" + +[[package]] +name = "keccak" +version = "0.2.0-pre.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7cdd4f0dc5807b9a2b25dd48a3f58e862606fe7bd47f41ecde36e97422d7e90" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "libc" +version = "0.2.169" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "pem-rfc7468" +version = "1.0.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2dfbfa5c6f0906884269722c5478e72fd4d6c0e24fe600332c6d62359567ce1" +dependencies = [ + "base64ct", +] + +[[package]] +name = "pkcs8" +version = "0.11.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f22636de7c995e997ed3d8d2949b7414d4faba3efa7312a6c0e75d875a14bdd4" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "proc-macro2" +version = "1.0.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "ryu" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd" + +[[package]] +name = "sec1" +version = "0.8.0-rc.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1988446eff153796413a73669dfaa4caa3f5ce8b25fac89e3821a39c611772e" +dependencies = [ + "base16ct", + "der", + "hybrid-array", + "pkcs8", + "serdect", + "subtle", + "zeroize", +] + +[[package]] +name = "serde" +version = "1.0.218" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8dfc9d19bdbf6d17e22319da49161d5d0108e4188e8b680aef6299eed22df60" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.218" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f09503e191f4e797cb8aac08e9a4a4695c5edf6a2e70e376d961ddd5c969f82b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.139" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44f86c3acccc9c65b153fe1b85a3be07fe5515274ec9f0653b4a0875731c72a6" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serdect" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f42f67da2385b51a5f9652db9c93d78aeaf7610bf5ec366080b6de810604af53" +dependencies = [ + "base16ct", + "serde", +] + +[[package]] +name = "sha2" +version = "0.11.0-pre.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "540c0893cce56cdbcfebcec191ec8e0f470dd1889b6e7a0b503e310a94a168f5" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha3" +version = "0.11.0-pre.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e485881f388c2818d709796dc883c1ffcadde9d1f0e054f3a5c14974185261a6" +dependencies = [ + "digest", + "keccak", +] + +[[package]] +name = "spki" +version = "0.8.0-rc.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37ac66481418fd7afdc584adcf3be9aa572cf6c2858814494dc2a01755f050bc" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "2.0.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "typenum" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" + +[[package]] +name = "unicode-ident" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index c04a8249a..7166527b3 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -13,8 +13,8 @@ repository = "https://github.com/RustCrypto/traits" readme = "README.md" categories = ["cryptography", "no-std"] keywords = ["crypto", "ecc", "elliptic", "weierstrass"] -edition = "2021" -rust-version = "1.83" +edition = "2024" +rust-version = "1.85" [dependencies] base16ct = "0.2" @@ -30,7 +30,7 @@ digest = { version = "=0.11.0-pre.9", optional = true } ff = { version = "0.13", optional = true, default-features = false } group = { version = "0.13", optional = true, default-features = false } hkdf = { version = "=0.13.0-pre.4", optional = true, default-features = false } -hex-literal = { version = "0.4", optional = true } +hex-literal = { version = "1", optional = true } pem-rfc7468 = { version = "1.0.0-rc.2", optional = true, features = ["alloc"] } pkcs8 = { version = "0.11.0-rc.1", optional = true, default-features = false } sec1 = { version = "0.8.0-rc.3", optional = true, features = ["subtle", "zeroize"] } @@ -39,7 +39,7 @@ serde_json = { version = "1.0.121", optional = true, default-features = false, f tap = { version = "1.0.1", optional = true, default-features = false } # hack for minimal-versions support for `bits` [dev-dependencies] -hex-literal = "0.4" +hex-literal = "1" sha2 = "=0.11.0-pre.4" sha3 = "=0.11.0-pre.4" diff --git a/elliptic-curve/README.md b/elliptic-curve/README.md index 218d70eb9..a89c195d4 100644 --- a/elliptic-curve/README.md +++ b/elliptic-curve/README.md @@ -11,20 +11,6 @@ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. -[Documentation][docs-link] - -## Minimum Supported Rust Version - -Requires Rust **1.83** or higher. - -Minimum supported Rust version can be changed in the future, but it will be -done with a minor version bump. - -## SemVer Policy - -- All on-by-default features of this library are covered by SemVer -- MSRV is considered exempt from SemVer as noted above - ## License All crates licensed under either of @@ -49,6 +35,6 @@ dual licensed as above, without any additional terms or conditions. [build-image]: https://github.com/RustCrypto/traits/actions/workflows/elliptic-curve.yml/badge.svg [build-link]: https://github.com/RustCrypto/traits/actions/workflows/elliptic-curve.yml [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.83+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260040-elliptic-curves diff --git a/elliptic-curve/src/arithmetic.rs b/elliptic-curve/src/arithmetic.rs index 150d8a9eb..20fc57be1 100644 --- a/elliptic-curve/src/arithmetic.rs +++ b/elliptic-curve/src/arithmetic.rs @@ -1,10 +1,10 @@ //! Elliptic curve arithmetic traits. use crate::{ + Curve, FieldBytes, PrimeCurve, ScalarPrimitive, ops::{Invert, LinearCombination, MulByGenerator, Reduce, ShrAssign}, point::AffineCoordinates, scalar::{FromUintUnchecked, IsHigh}, - Curve, FieldBytes, PrimeCurve, ScalarPrimitive, }; use core::fmt::Debug; use subtle::{ConditionallySelectable, ConstantTimeEq, CtOption}; diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 1fd44bb37..567c97f4f 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -4,6 +4,7 @@ //! the traits in this crate. use crate::{ + Curve, CurveArithmetic, FieldBytesEncoding, PrimeCurve, array::typenum::U32, bigint::{Limb, U256}, error::{Error, Result}, @@ -14,7 +15,6 @@ use crate::{ sec1::{CompressedPoint, FromEncodedPoint, ToEncodedPoint}, subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}, zeroize::DefaultIsZeroes, - Curve, CurveArithmetic, FieldBytesEncoding, PrimeCurve, }; use core::{ iter::{Product, Sum}, @@ -448,11 +448,7 @@ impl ConstantTimeEq for AffinePoint { impl ConditionallySelectable for AffinePoint { fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { // Not really constant time, but this is dev code - if choice.into() { - *b - } else { - *a - } + if choice.into() { *b } else { *a } } } @@ -535,11 +531,7 @@ impl ConstantTimeEq for ProjectivePoint { impl ConditionallySelectable for ProjectivePoint { fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { - if choice.into() { - *b - } else { - *a - } + if choice.into() { *b } else { *a } } } diff --git a/elliptic-curve/src/ecdh.rs b/elliptic-curve/src/ecdh.rs index 243c61789..88b885220 100644 --- a/elliptic-curve/src/ecdh.rs +++ b/elliptic-curve/src/ecdh.rs @@ -27,13 +27,13 @@ //! [SIGMA]: https://webee.technion.ac.il/~hugo/sigma-pdf.pdf use crate::{ - point::AffineCoordinates, AffinePoint, Curve, CurveArithmetic, FieldBytes, NonZeroScalar, - ProjectivePoint, PublicKey, + AffinePoint, Curve, CurveArithmetic, FieldBytes, NonZeroScalar, ProjectivePoint, PublicKey, + point::AffineCoordinates, }; use core::{borrow::Borrow, fmt}; -use digest::{crypto_common::BlockSizeUser, Digest}; +use digest::{Digest, crypto_common::BlockSizeUser}; use group::Curve as _; -use hkdf::{hmac::SimpleHmac, Hkdf}; +use hkdf::{Hkdf, hmac::SimpleHmac}; use rand_core::CryptoRngCore; use zeroize::{Zeroize, ZeroizeOnDrop}; diff --git a/elliptic-curve/src/field.rs b/elliptic-curve/src/field.rs index 2884e241a..cda71dcb8 100644 --- a/elliptic-curve/src/field.rs +++ b/elliptic-curve/src/field.rs @@ -1,10 +1,10 @@ //! Field elements. use crate::{ - bigint::{ArrayEncoding, ByteArray, Integer}, Curve, + bigint::{ArrayEncoding, ByteArray, Integer}, }; -use hybrid_array::{typenum::Unsigned, Array}; +use hybrid_array::{Array, typenum::Unsigned}; /// Size of serialized field elements of this elliptic curve. pub type FieldBytesSize = ::FieldBytesSize; diff --git a/elliptic-curve/src/hash2curve/group_digest.rs b/elliptic-curve/src/hash2curve/group_digest.rs index ea7f0471f..2a663a11b 100644 --- a/elliptic-curve/src/hash2curve/group_digest.rs +++ b/elliptic-curve/src/hash2curve/group_digest.rs @@ -1,6 +1,6 @@ //! Traits for handling hash to curve. -use super::{hash_to_field, ExpandMsg, FromOkm, MapToCurve}; +use super::{ExpandMsg, FromOkm, MapToCurve, hash_to_field}; use crate::{CurveArithmetic, ProjectivePoint, Result}; use group::cofactor::CofactorGroup; diff --git a/elliptic-curve/src/hash2curve/hash2field.rs b/elliptic-curve/src/hash2curve/hash2field.rs index c9a980c1a..946c8a39d 100644 --- a/elliptic-curve/src/hash2curve/hash2field.rs +++ b/elliptic-curve/src/hash2curve/hash2field.rs @@ -7,7 +7,7 @@ mod expand_msg; pub use expand_msg::{xmd::*, xof::*, *}; use crate::{Error, Result}; -use hybrid_array::{typenum::Unsigned, Array, ArraySize}; +use hybrid_array::{Array, ArraySize, typenum::Unsigned}; /// The trait for helping to convert to a field element. pub trait FromOkm { diff --git a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs index fdd298c63..c1cb250b7 100644 --- a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs +++ b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs @@ -5,12 +5,12 @@ use core::marker::PhantomData; use super::{Domain, ExpandMsg, Expander}; use crate::{Error, Result}; use digest::{ + FixedOutput, HashMarker, array::{ - typenum::{IsLess, IsLessOrEqual, Unsigned, U256}, Array, + typenum::{IsLess, IsLessOrEqual, U256, Unsigned}, }, core_api::BlockSizeUser, - FixedOutput, HashMarker, }; /// Placeholder type for implementing `expand_message_xmd` based on a hash function @@ -156,8 +156,8 @@ mod test { use core::mem::size_of; use hex_literal::hex; use hybrid_array::{ - typenum::{U128, U32}, ArraySize, + typenum::{U32, U128}, }; use sha2::Sha256; diff --git a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs index 96eebe1e5..6a5c14621 100644 --- a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs +++ b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs @@ -78,7 +78,7 @@ mod test { use super::*; use core::mem::size_of; use hex_literal::hex; - use hybrid_array::{typenum::U128, Array, ArraySize}; + use hybrid_array::{Array, ArraySize, typenum::U128}; use sha3::Shake128; fn assert_message(msg: &[u8], domain: &Domain<'_, U32>, len_in_bytes: u16, bytes: &[u8]) { diff --git a/elliptic-curve/src/hash2curve/isogeny.rs b/elliptic-curve/src/hash2curve/isogeny.rs index 0d7e0853c..4644d786a 100644 --- a/elliptic-curve/src/hash2curve/isogeny.rs +++ b/elliptic-curve/src/hash2curve/isogeny.rs @@ -4,7 +4,7 @@ use core::ops::{AddAssign, Mul}; use ff::Field; -use hybrid_array::{typenum::Unsigned, Array, ArraySize}; +use hybrid_array::{Array, ArraySize, typenum::Unsigned}; /// The coefficients for mapping from one isogenous curve to another #[derive(Debug)] diff --git a/elliptic-curve/src/jwk.rs b/elliptic-curve/src/jwk.rs index 581448d71..b85ac90e1 100644 --- a/elliptic-curve/src/jwk.rs +++ b/elliptic-curve/src/jwk.rs @@ -4,9 +4,9 @@ //! use crate::{ + Curve, Error, FieldBytes, FieldBytesSize, Result, sec1::{Coordinates, EncodedPoint, ModulusSize, ValidatePublicKey}, secret_key::SecretKey, - Curve, Error, FieldBytes, FieldBytesSize, Result, }; use alloc::{ borrow::ToOwned, @@ -19,14 +19,14 @@ use core::{ marker::PhantomData, str::{self, FromStr}, }; -use serdect::serde::{de, ser, Deserialize, Serialize}; +use serdect::serde::{Deserialize, Serialize, de, ser}; use zeroize::{Zeroize, ZeroizeOnDrop}; #[cfg(feature = "arithmetic")] use crate::{ + AffinePoint, CurveArithmetic, public_key::PublicKey, sec1::{FromEncodedPoint, ToEncodedPoint}, - AffinePoint, CurveArithmetic, }; /// Key Type (`kty`) for elliptic curve keys. diff --git a/elliptic-curve/src/point/non_identity.rs b/elliptic-curve/src/point/non_identity.rs index a0f1e85ff..1cb1a7fdb 100644 --- a/elliptic-curve/src/point/non_identity.rs +++ b/elliptic-curve/src/point/non_identity.rs @@ -2,12 +2,12 @@ use core::ops::{Deref, Mul}; -use group::{prime::PrimeCurveAffine, Curve, GroupEncoding}; +use group::{Curve, GroupEncoding, prime::PrimeCurveAffine}; use rand_core::{CryptoRng, RngCore}; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; #[cfg(feature = "serde")] -use serdect::serde::{de, ser, Deserialize, Serialize}; +use serdect::serde::{Deserialize, Serialize, de, ser}; use crate::{CurveArithmetic, NonZeroScalar, Scalar}; diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index aa728d2f0..cd0389c4d 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -1,7 +1,7 @@ //! Elliptic curve public keys. use crate::{ - point::NonIdentity, AffinePoint, CurveArithmetic, Error, NonZeroScalar, ProjectivePoint, Result, + AffinePoint, CurveArithmetic, Error, NonZeroScalar, ProjectivePoint, Result, point::NonIdentity, }; use core::fmt::Debug; use group::{Curve, Group}; @@ -18,9 +18,9 @@ use core::str::FromStr; #[cfg(feature = "sec1")] use { crate::{ + FieldBytesSize, point::PointCompression, sec1::{CompressedPoint, EncodedPoint, FromEncodedPoint, ModulusSize, ToEncodedPoint}, - FieldBytesSize, }, core::cmp::Ordering, subtle::{Choice, CtOption}, @@ -36,14 +36,14 @@ use alloc::boxed::Box; use alloc::string::{String, ToString}; #[cfg(feature = "serde")] -use serdect::serde::{de, ser, Deserialize, Serialize}; +use serdect::serde::{Deserialize, Serialize, de, ser}; #[cfg(any(feature = "pem", feature = "serde"))] use pkcs8::DecodePublicKey; #[cfg(all(feature = "sec1", feature = "pkcs8"))] use { - crate::{pkcs8::AssociatedOid, ALGORITHM_OID}, + crate::{ALGORITHM_OID, pkcs8::AssociatedOid}, pkcs8::der, }; diff --git a/elliptic-curve/src/scalar/blinded.rs b/elliptic-curve/src/scalar/blinded.rs index 914427f55..685ba9d54 100644 --- a/elliptic-curve/src/scalar/blinded.rs +++ b/elliptic-curve/src/scalar/blinded.rs @@ -1,7 +1,7 @@ //! Random blinding support for [`Scalar`] use super::Scalar; -use crate::{ops::Invert, CurveArithmetic}; +use crate::{CurveArithmetic, ops::Invert}; use core::fmt; use group::ff::Field; use rand_core::CryptoRngCore; diff --git a/elliptic-curve/src/scalar/nonzero.rs b/elliptic-curve/src/scalar/nonzero.rs index 9fd617e2a..74a7d41af 100644 --- a/elliptic-curve/src/scalar/nonzero.rs +++ b/elliptic-curve/src/scalar/nonzero.rs @@ -1,9 +1,9 @@ //! Non-zero scalar type. use crate::{ + CurveArithmetic, Error, FieldBytes, PrimeCurve, Scalar, ScalarPrimitive, SecretKey, ops::{Invert, Reduce, ReduceNonZero}, scalar::IsHigh, - CurveArithmetic, Error, FieldBytes, PrimeCurve, Scalar, ScalarPrimitive, SecretKey, }; use base16ct::HexDisplay; use core::{ @@ -18,7 +18,7 @@ use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; use zeroize::Zeroize; #[cfg(feature = "serde")] -use serdect::serde::{de, ser, Deserialize, Serialize}; +use serdect::serde::{Deserialize, Serialize, de, ser}; /// Non-zero scalar type. /// diff --git a/elliptic-curve/src/scalar/primitive.rs b/elliptic-curve/src/scalar/primitive.rs index a4d31cb3e..e61d574be 100644 --- a/elliptic-curve/src/scalar/primitive.rs +++ b/elliptic-curve/src/scalar/primitive.rs @@ -1,11 +1,11 @@ //! Generic scalar type with primitive functionality. use crate::{ + Curve, Error, FieldBytes, FieldBytesEncoding, Result, array::Array, - bigint::{prelude::*, Limb, NonZero}, + bigint::{Limb, NonZero, prelude::*}, scalar::FromUintUnchecked, scalar::IsHigh, - Curve, Error, FieldBytes, FieldBytesEncoding, Result, }; use base16ct::HexDisplay; use core::{ @@ -25,7 +25,7 @@ use zeroize::DefaultIsZeroes; use super::{CurveArithmetic, Scalar}; #[cfg(feature = "serde")] -use serdect::serde::{de, ser, Deserialize, Serialize}; +use serdect::serde::{Deserialize, Serialize, de, ser}; /// Generic scalar type with primitive functionality. /// diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 09b6ba5ad..7da6c2e0c 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -15,7 +15,7 @@ use subtle::{Choice, ConstantTimeEq}; use zeroize::{Zeroize, ZeroizeOnDrop, Zeroizing}; #[cfg(feature = "arithmetic")] -use crate::{rand_core::CryptoRngCore, CurveArithmetic, NonZeroScalar, PublicKey}; +use crate::{CurveArithmetic, NonZeroScalar, PublicKey, rand_core::CryptoRngCore}; #[cfg(feature = "jwk")] use crate::jwk::{JwkEcKey, JwkParameters}; @@ -26,8 +26,8 @@ use pem_rfc7468::{self as pem, PemLabel}; #[cfg(feature = "sec1")] use { crate::{ - sec1::{EncodedPoint, ModulusSize, ValidatePublicKey}, FieldBytesSize, + sec1::{EncodedPoint, ModulusSize, ValidatePublicKey}, }, sec1::der::{self, oid::AssociatedOid}, }; @@ -35,8 +35,8 @@ use { #[cfg(all(feature = "alloc", feature = "arithmetic", feature = "sec1"))] use { crate::{ - sec1::{FromEncodedPoint, ToEncodedPoint}, AffinePoint, + sec1::{FromEncodedPoint, ToEncodedPoint}, }, alloc::vec::Vec, sec1::der::Encode, diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs index 433926f55..2598f9ec4 100644 --- a/elliptic-curve/src/secret_key/pkcs8.rs +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -2,9 +2,9 @@ use super::SecretKey; use crate::{ - pkcs8::{der::Decode, AssociatedOid}, + ALGORITHM_OID, Curve, FieldBytesSize, + pkcs8::{AssociatedOid, der::Decode}, sec1::{ModulusSize, ValidatePublicKey}, - Curve, FieldBytesSize, ALGORITHM_OID, }; use pkcs8::spki::{AlgorithmIdentifier, AssociatedAlgorithmIdentifier, ObjectIdentifier}; use sec1::EcPrivateKey; @@ -13,12 +13,12 @@ use sec1::EcPrivateKey; #[cfg(all(feature = "alloc", feature = "arithmetic"))] use { crate::{ - sec1::{FromEncodedPoint, ToEncodedPoint}, AffinePoint, CurveArithmetic, + sec1::{FromEncodedPoint, ToEncodedPoint}, }, pkcs8::{ - der::{self, asn1::OctetStringRef, Encode}, EncodePrivateKey, + der::{self, Encode, asn1::OctetStringRef}, }, zeroize::Zeroizing, }; @@ -26,7 +26,7 @@ use { // Imports for actual PEM support #[cfg(feature = "pem")] use { - crate::{error::Error, Result}, + crate::{Result, error::Error}, core::str::FromStr, pkcs8::DecodePrivateKey, }; diff --git a/elliptic-curve/tests/pkcs8.rs b/elliptic-curve/tests/pkcs8.rs index 2a27fc0c7..4234c2f48 100644 --- a/elliptic-curve/tests/pkcs8.rs +++ b/elliptic-curve/tests/pkcs8.rs @@ -39,7 +39,9 @@ fn decode_pkcs8_private_key_from_der() { #[test] fn decode_pkcs8_public_key_from_der() { let public_key = PublicKey::from_public_key_der(&PKCS8_PUBLIC_KEY_DER[..]).unwrap(); - let expected_sec1_point = hex!("041CACFFB55F2F2CEFD89D89EB374B2681152452802DEEA09916068137D839CF7FC481A44492304D7EF66AC117BEFE83A8D08F155F2B52F9F618DD447029048E0F"); + let expected_sec1_point = hex!( + "041CACFFB55F2F2CEFD89D89EB374B2681152452802DEEA09916068137D839CF7FC481A44492304D7EF66AC117BEFE83A8D08F155F2B52F9F618DD447029048E0F" + ); assert_eq!( public_key.to_encoded_point(false).as_bytes(), &expected_sec1_point[..] diff --git a/kem/CHANGELOG.md b/kem/CHANGELOG.md index 103b251f0..591c3e830 100644 --- a/kem/CHANGELOG.md +++ b/kem/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.3.0 (UNRELEASED) +### Changed +- Edition changed to 2024 and MSRV bumped to 1.85 ([#1759]) + +[#1759]: https://github.com/RustCrypto/traits/pull/1759 + ## 0.2.0 (2022-05-26) ### Added - Generic `SharedSecret` type ([#982]) diff --git a/kem/Cargo.toml b/kem/Cargo.toml index b07b3c16d..eb396b17c 100644 --- a/kem/Cargo.toml +++ b/kem/Cargo.toml @@ -8,10 +8,10 @@ documentation = "https://docs.rs/kem" homepage = "https://github.com/RustCrypto/traits/tree/master/kem" repository = "https://github.com/RustCrypto/traits" readme = "README.md" -edition = "2021" keywords = ["crypto"] categories = ["cryptography", "no-std"] -rust-version = "1.66" +edition = "2024" +rust-version = "1.85" [dependencies] rand_core = "0.9" diff --git a/kem/README.md b/kem/README.md index 8ca46b4ed..4ee06756e 100644 --- a/kem/README.md +++ b/kem/README.md @@ -70,20 +70,6 @@ impl Encapsulate for EncapContext { } ``` -[Documentation][docs-link] - -## Minimum Supported Rust Version - -Rust **1.66** or higher. - -Minimum supported Rust version can be changed in the future, but it will be -done with a minor version bump. - -## SemVer Policy - -- All on-by-default features of this library are covered by SemVer -- MSRV is considered exempt from SemVer as noted above - ## License Licensed under either of @@ -106,7 +92,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/kem/badge.svg [docs-link]: https://docs.rs/kem/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.66+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260048-signatures [build-image]: https://github.com/RustCrypto/traits/workflows/kem/badge.svg?branch=master&event=push diff --git a/password-hash/CHANGELOG.md b/password-hash/CHANGELOG.md index e32dd4271..e28a88cca 100644 --- a/password-hash/CHANGELOG.md +++ b/password-hash/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.6.0 (UNRELEASED) +### Changed +- Edition changed to 2024 and MSRV bumped to 1.85 ([#1759]) + +[#1759]: https://github.com/RustCrypto/traits/pull/1759 + ## 0.5.0 (2023-03-04) ### Added - `Error::OutputSize` ([#1026]) diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index 83fe1136c..3abcbca1b 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -14,8 +14,8 @@ homepage = "https://github.com/RustCrypto/traits/tree/master/password-hash" repository = "https://github.com/RustCrypto/traits" categories = ["authentication", "cryptography", "no-std"] keywords = ["crypt", "mcf", "password", "pbkdf", "phc"] -edition = "2021" -rust-version = "1.81" +edition = "2024" +rust-version = "1.85" [dependencies] base64ct = "1.6" diff --git a/password-hash/README.md b/password-hash/README.md index 20dffcd56..f7bc6e858 100644 --- a/password-hash/README.md +++ b/password-hash/README.md @@ -9,8 +9,6 @@ Traits which describe the functionality of [password hashing algorithms]. -[Documentation][docs-link] - ## About Provides a `no_std`-friendly implementation of the @@ -27,18 +25,6 @@ this crate for interoperability: - [`pbkdf2`] - Password-Based Key Derivation Function v2 - [`scrypt`] - scrypt key derivation function -## Minimum Supported Rust Version - -Rust **1.81** or higher. - -Minimum supported Rust version may be changed in the future, but it will be -accompanied by a minor version bump. - -## SemVer Policy - -- All on-by-default features of this library are covered by SemVer -- MSRV is considered exempt from SemVer as noted above - ## License Licensed under either of: @@ -63,7 +49,7 @@ dual licensed as above, without any additional terms or conditions. [build-image]: https://github.com/RustCrypto/traits/workflows/password-hash/badge.svg?branch=master&event=push [build-link]: https://github.com/RustCrypto/traits/actions?query=workflow:password-hash [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.81+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260046-password-hashes diff --git a/password-hash/src/params.rs b/password-hash/src/params.rs index 0d8074099..975e794a8 100644 --- a/password-hash/src/params.rs +++ b/password-hash/src/params.rs @@ -2,8 +2,8 @@ use crate::errors::InvalidValue; use crate::{ - value::{Decimal, Value}, Encoding, Error, Ident, Result, + value::{Decimal, Value}, }; use core::{ fmt::{self, Debug, Write}, diff --git a/signature/CHANGELOG.md b/signature/CHANGELOG.md index 554e0f5fd..faaaff7a4 100644 --- a/signature/CHANGELOG.md +++ b/signature/CHANGELOG.md @@ -4,11 +4,15 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## Unreleased +## 2.3.0 (UNRELEASED) ### Added -- `RandomizedSignerMut` trait +- `RandomizedSignerMut` trait ([#1448]) -[#1448](https://github.com/RustCrypto/traits/pull/1448) +### Changed +- Edition changed to 2024 and MSRV bumped to 1.85 ([#1759]) + +[#1448]: https://github.com/RustCrypto/traits/pull/1448 +[#1759]: https://github.com/RustCrypto/traits/pull/1759 ## 2.2.0 (2023-11-12) ### Changed diff --git a/signature/Cargo.lock b/signature/Cargo.lock new file mode 100644 index 000000000..c2f685474 --- /dev/null +++ b/signature/Cargo.lock @@ -0,0 +1,269 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "bitflags" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" + +[[package]] +name = "block-buffer" +version = "0.11.0-rc.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fd016a0ddc7cb13661bf5576073ce07330a693f8608a1320b4e20561cc12cdc" +dependencies = [ + "hybrid-array", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-common" +version = "0.2.0-rc.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0b8ce8218c97789f16356e7896b3714f26c2ee1079b79c0b7ae7064bb9089fa" +dependencies = [ + "hybrid-array", +] + +[[package]] +name = "digest" +version = "0.11.0-pre.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf2e3d6615d99707295a9673e889bf363a04b2a466bd320c65a72536f7577379" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "getrandom" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8" +dependencies = [ + "cfg-if", + "libc", + "wasi", + "windows-targets", +] + +[[package]] +name = "hex-literal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcaaec4551594c969335c98c903c1397853d4198408ea609190f420500f6be71" + +[[package]] +name = "hybrid-array" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2d35805454dc9f8662a98d6d61886ffe26bd465f5960e0e55345c70d5c0d2a9" +dependencies = [ + "typenum", +] + +[[package]] +name = "libc" +version = "0.2.169" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" + +[[package]] +name = "proc-macro2" +version = "1.0.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand_core" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a509b1a2ffbe92afab0e55c8fd99dea1c280e8171bd2d88682bb20bc41cbc2c" +dependencies = [ + "getrandom", + "zerocopy", +] + +[[package]] +name = "sha2" +version = "0.11.0-pre.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "540c0893cce56cdbcfebcec191ec8e0f470dd1889b6e7a0b503e310a94a168f5" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "signature" +version = "2.3.0-pre.6" +dependencies = [ + "digest", + "hex-literal", + "rand_core", + "sha2", + "signature_derive", +] + +[[package]] +name = "signature_derive" +version = "2.2.0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "syn" +version = "2.0.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "typenum" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" + +[[package]] +name = "unicode-ident" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe" + +[[package]] +name = "wasi" +version = "0.13.3+wasi-0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2" +dependencies = [ + "wit-bindgen-rt", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "wit-bindgen-rt" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" +dependencies = [ + "bitflags", +] + +[[package]] +name = "zerocopy" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dde3bb8c68a8f3f1ed4ac9221aad6b10cece3e60a8e2ea54a6a2dec806d0084c" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eea57037071898bf96a6da35fd626f4f27e9cee3ead2a6c703cf09d472b2e700" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 85cafb78b..7a428af8b 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -10,8 +10,8 @@ repository = "https://github.com/RustCrypto/traits" readme = "README.md" keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"] categories = ["cryptography", "no-std"] -edition = "2021" -rust-version = "1.81" +edition = "2024" +rust-version = "1.85" [dependencies] derive = { package = "signature_derive", version = "2", optional = true, path = "../signature_derive" } @@ -19,7 +19,7 @@ digest = { version = "=0.11.0-pre.9", optional = true, default-features = false rand_core = { version = "0.9", optional = true, default-features = false } [dev-dependencies] -hex-literal = "0.4" +hex-literal = "1" sha2 = { version = "=0.11.0-pre.4", default-features = false } [features] diff --git a/signature/README.md b/signature/README.md index 1da58187e..4e3cef37c 100644 --- a/signature/README.md +++ b/signature/README.md @@ -13,20 +13,8 @@ generating and verifying [digital signatures]. Used by the [`dsa`], [`ecdsa`], [`ed25519`], and [`rsa`] crates maintained by the [RustCrypto] organization, as well as [`ed25519-dalek`]. -[Documentation][docs-link] +## SemVer Policy Exemptions -## Minimum Supported Rust Version - -Rust **1.81** or higher. - -Minimum supported Rust version can be changed in the future, but it will be -done with a minor version bump. - -## SemVer Policy - -- All on-by-default features of this library are covered by SemVer -- MSRV is considered exempt from SemVer as noted above -- The `derive` feature is stable and covered by SemVer - The off-by-default features `digest` and `rand_core` are unstable features which are also considered exempt from SemVer as they correspond to pre-1.0 crates which are still subject to changes. Breaking changes to these features @@ -56,7 +44,7 @@ dual licensed as above, without any additional terms or conditions. [build-image]: https://github.com/RustCrypto/traits/actions/workflows/signature.yml/badge.svg [build-link]: https://github.com/RustCrypto/traits/actions/workflows/signature.yml [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.81+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260048-signatures diff --git a/signature/src/signer.rs b/signature/src/signer.rs index a6c2813f8..22f2e6aa0 100644 --- a/signature/src/signer.rs +++ b/signature/src/signer.rs @@ -114,7 +114,7 @@ pub trait RandomizedDigestSigner { /// Attempt to sign the given prehashed message `Digest`, returning a /// digital signature on success, or an error if something went wrong. fn try_sign_digest_with_rng(&self, rng: &mut R, digest: D) - -> Result; + -> Result; } /// Sign the provided message bytestring using `&mut Self` (e.g. an evolving diff --git a/signature/tests/derive.rs b/signature/tests/derive.rs index a63ece5ee..989890271 100644 --- a/signature/tests/derive.rs +++ b/signature/tests/derive.rs @@ -2,12 +2,12 @@ #![cfg(all(feature = "derive", feature = "digest"))] -use digest::{array::Array, Digest, OutputSizeUser}; +use digest::{Digest, OutputSizeUser, array::Array}; use hex_literal::hex; use sha2::Sha256; use signature::{ - hazmat::{PrehashSigner, PrehashVerifier}, DigestSigner, DigestVerifier, Error, PrehashSignature, SignatureEncoding, Signer, Verifier, + hazmat::{PrehashSigner, PrehashVerifier}, }; /// Test vector to compute SHA-256 digest of diff --git a/signature_derive/CHANGELOG.md b/signature_derive/CHANGELOG.md index 0edb20cdb..e88b15da1 100644 --- a/signature_derive/CHANGELOG.md +++ b/signature_derive/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 2.2.0 (UNRELEASED) +### Changed +- Edition changed to 2024 and MSRV bumped to 1.85 ([#1759]) + +[#1759]: https://github.com/RustCrypto/traits/pull/1759 + ## 2.1.0 (2023-11-12) ### Changed - MSRV 1.60 ([#1387]) diff --git a/signature_derive/Cargo.toml b/signature_derive/Cargo.toml index 3d01b5d0b..e5d8134ea 100644 --- a/signature_derive/Cargo.toml +++ b/signature_derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "signature_derive" -version = "2.1.0" +version = "2.2.0" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" description = "Custom derive support for the 'signature' crate" @@ -8,8 +8,8 @@ documentation = "https://docs.rs/signature" homepage = "https://github.com/RustCrypto/traits/tree/master/signature_derive" repository = "https://github.com/RustCrypto/traits" readme = "README.md" -edition = "2021" -rust-version = "1.60" +edition = "2024" +rust-version = "1.85" keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"] categories = ["cryptography", "no-std"] diff --git a/signature_derive/README.md b/signature_derive/README.md index e63f6f85f..1be2391d0 100644 --- a/signature_derive/README.md +++ b/signature_derive/README.md @@ -1,12 +1,17 @@ # `signature` crate custom derive support +[![crate][crate-image]][crate-link] +[![Docs][docs-image]][docs-link] +[![Build Status][build-image]][build-link] +![Apache2/MIT licensed][license-image] +![Rust Version][rustc-image] +[![Project Chat][chat-image]][chat-link] + This crate provides proc macros used by the `signature` crate. Not intended to be used directly. See the `signature` crate's documentation for additional details: -[Documentation] - ## License All crates licensed under either of @@ -22,4 +27,15 @@ Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. -[Documentation]: https://docs.rs/signature/ +[//]: # (badges) + +[crate-image]: https://img.shields.io/crates/v/password-hash +[crate-link]: https://crates.io/crates/password-hash +[docs-image]: https://docs.rs/password-hash/badge.svg +[docs-link]: https://docs.rs/password-hash/ +[build-image]: https://github.com/RustCrypto/traits/workflows/password-hash/badge.svg?branch=master&event=push +[build-link]: https://github.com/RustCrypto/traits/actions?query=workflow:password-hash +[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg +[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg +[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260046-password-hashes diff --git a/signature_derive/src/lib.rs b/signature_derive/src/lib.rs index 14930789b..bf6a94c5d 100644 --- a/signature_derive/src/lib.rs +++ b/signature_derive/src/lib.rs @@ -14,8 +14,8 @@ use proc_macro::TokenStream; use proc_macro2::{Span, TokenStream as TokenStream2}; use quote::quote; use syn::{ - parse_macro_input, parse_quote, punctuated::Punctuated, DeriveInput, Ident, PredicateType, - Token, TraitBound, Type, TypeParam, TypeParamBound, WhereClause, WherePredicate, + DeriveInput, Ident, PredicateType, Token, TraitBound, Type, TypeParam, TypeParamBound, + WhereClause, WherePredicate, parse_macro_input, parse_quote, punctuated::Punctuated, }; /// Derive the [`Signer`] trait for a type which impls [`DigestSigner`]. diff --git a/universal-hash/CHANGELOG.md b/universal-hash/CHANGELOG.md index 1ee729f8a..20c7c4829 100644 --- a/universal-hash/CHANGELOG.md +++ b/universal-hash/CHANGELOG.md @@ -5,8 +5,9 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## Unreleased +## 0.6.0 (UNRELEASED) ### Changed +- Edition changed to 2024 and MSRV bumped to 1.85 ([#1759]) - Migrate to `doc_auto_cfg` ([#1370]) - Exclude pre-1.60 crates from workspace ([#1380]) - bump crypto-common to v0.2.0-pre; MSRV 1.65 ([#1385]) @@ -30,6 +31,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [#1469]: https://github.com/RustCrypto/traits/pull/1469 [#1493]: https://github.com/RustCrypto/traits/pull/1493 [#1496]: https://github.com/RustCrypto/traits/pull/1496 +[#1759]: https://github.com/RustCrypto/traits/pull/1759 ## 0.5.1 (2023-05-19) ### Changed diff --git a/universal-hash/Cargo.toml b/universal-hash/Cargo.toml index 28e3a180e..bf1993107 100644 --- a/universal-hash/Cargo.toml +++ b/universal-hash/Cargo.toml @@ -4,8 +4,8 @@ version = "0.6.0-rc.0" description = "Traits which describe the functionality of universal hash functions (UHFs)" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" -edition = "2021" -rust-version = "1.81" +edition = "2024" +rust-version = "1.85" readme = "README.md" documentation = "https://docs.rs/universal-hash" repository = "https://github.com/RustCrypto/traits" @@ -13,7 +13,7 @@ keywords = ["crypto", "mac"] categories = ["cryptography", "no-std"] [dependencies] -crypto-common = "0.2.0-rc.1" +crypto-common = { version = "0.2.0-rc.1", path = "../crypto-common" } subtle = { version = "2.4", default-features = false } [package.metadata.docs.rs] diff --git a/universal-hash/README.md b/universal-hash/README.md index beaa9e58a..7e34e89eb 100644 --- a/universal-hash/README.md +++ b/universal-hash/README.md @@ -11,20 +11,6 @@ Traits which describe functionality of [universal hash functions] (UHFs). See [RustCrypto/universal-hashes] for implementations which use this trait. -[Documentation][docs-link] - -## Minimum Supported Rust Version - -Rust **1.81** or higher. - -Minimum supported Rust version can be changed in the future, but it will be -done with a minor version bump. - -## SemVer Policy - -- All on-by-default features of this library are covered by SemVer -- MSRV is considered exempt from SemVer as noted above - ## License Licensed under either of: @@ -47,7 +33,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/universal-hash/badge.svg [docs-link]: https://docs.rs/universal-hash/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.81+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260051-universal-hashes [build-image]: https://github.com/RustCrypto/traits/workflows/universal-hash/badge.svg?branch=master&event=push diff --git a/universal-hash/src/lib.rs b/universal-hash/src/lib.rs index 06e75e658..4fca3369f 100644 --- a/universal-hash/src/lib.rs +++ b/universal-hash/src/lib.rs @@ -9,13 +9,12 @@ #![warn(missing_docs, rust_2018_idioms, missing_debug_implementations)] pub use crypto_common::{ - self, array, + self, Block, Key, KeyInit, ParBlocks, Reset, array, typenum::{self, consts}, - Block, Key, KeyInit, ParBlocks, Reset, }; use core::slice; -use crypto_common::{array::Array, BlockSizeUser, BlockSizes, ParBlocksSizeUser}; +use crypto_common::{BlockSizeUser, BlockSizes, ParBlocksSizeUser, array::Array}; use subtle::ConstantTimeEq; use typenum::Unsigned; From 9aad4bfc217598a95471c850374c675e8a26155f Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Sat, 22 Feb 2025 21:52:01 +0300 Subject: [PATCH 1285/1461] crypto-common: release v0.2.0-rc.2 (#1762) --- Cargo.lock | 24 ++++++++++++------------ crypto-common/Cargo.toml | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 85567be00..70493eb39 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9,7 +9,7 @@ dependencies = [ "arrayvec", "blobby", "bytes", - "crypto-common 0.2.0-rc.1", + "crypto-common 0.2.0-rc.2", "heapless", ] @@ -98,7 +98,7 @@ name = "cipher" version = "0.5.0-pre.7" dependencies = [ "blobby", - "crypto-common 0.2.0-rc.1", + "crypto-common 0.2.0-rc.2", "inout", "zeroize", ] @@ -115,7 +115,7 @@ version = "0.6.0-pre" dependencies = [ "aead", "cipher", - "crypto-common 0.2.0-rc.1", + "crypto-common 0.2.0-rc.2", "digest 0.11.0-pre.9", "elliptic-curve", "password-hash", @@ -139,18 +139,18 @@ dependencies = [ [[package]] name = "crypto-common" version = "0.2.0-rc.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0b8ce8218c97789f16356e7896b3714f26c2ee1079b79c0b7ae7064bb9089fa" dependencies = [ - "hybrid-array 0.3.0", - "rand_core 0.9.2", + "hybrid-array 0.2.3", ] [[package]] name = "crypto-common" -version = "0.2.0-rc.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0b8ce8218c97789f16356e7896b3714f26c2ee1079b79c0b7ae7064bb9089fa" +version = "0.2.0-rc.2" dependencies = [ - "hybrid-array 0.2.3", + "hybrid-array 0.3.0", + "rand_core 0.9.2", ] [[package]] @@ -170,7 +170,7 @@ dependencies = [ "blobby", "block-buffer", "const-oid", - "crypto-common 0.2.0-rc.1", + "crypto-common 0.2.0-rc.2", "subtle", "zeroize", ] @@ -181,7 +181,7 @@ version = "0.11.0-pre.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf2e3d6615d99707295a9673e889bf363a04b2a466bd320c65a72536f7577379" dependencies = [ - "crypto-common 0.2.0-rc.1 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-common 0.2.0-rc.1", ] [[package]] @@ -461,7 +461,7 @@ checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe" name = "universal-hash" version = "0.6.0-rc.0" dependencies = [ - "crypto-common 0.2.0-rc.1", + "crypto-common 0.2.0-rc.2", "subtle", ] diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index 47dc148aa..43d455b7c 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crypto-common" description = "Common cryptographic traits" -version = "0.2.0-rc.1" +version = "0.2.0-rc.2" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" From be696aa8f811a71633c3456c8030af5048d547ea Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Sat, 22 Feb 2025 21:58:37 +0300 Subject: [PATCH 1286/1461] digest: release v0.11.0-pre.10 (#1763) --- Cargo.lock | 32 ++++++++++++++++---------------- digest/Cargo.toml | 4 ++-- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 70493eb39..b6035d19c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -116,7 +116,7 @@ dependencies = [ "aead", "cipher", "crypto-common 0.2.0-rc.2", - "digest 0.11.0-pre.9", + "digest 0.11.0-pre.10", "elliptic-curve", "password-hash", "signature 2.3.0-pre.6", @@ -138,19 +138,19 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.2.0-rc.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0b8ce8218c97789f16356e7896b3714f26c2ee1079b79c0b7ae7064bb9089fa" +version = "0.2.0-rc.2" dependencies = [ - "hybrid-array 0.2.3", + "hybrid-array 0.3.0", + "rand_core 0.9.2", ] [[package]] name = "crypto-common" version = "0.2.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "170d71b5b14dec99db7739f6fc7d6ec2db80b78c3acb77db48392ccc3d8a9ea0" dependencies = [ "hybrid-array 0.3.0", - "rand_core 0.9.2", ] [[package]] @@ -166,6 +166,15 @@ dependencies = [ [[package]] name = "digest" version = "0.11.0-pre.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf2e3d6615d99707295a9673e889bf363a04b2a466bd320c65a72536f7577379" +dependencies = [ + "crypto-common 0.2.0-rc.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "digest" +version = "0.11.0-pre.10" dependencies = [ "blobby", "block-buffer", @@ -175,15 +184,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "digest" -version = "0.11.0-pre.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf2e3d6615d99707295a9673e889bf363a04b2a466bd320c65a72536f7577379" -dependencies = [ - "crypto-common 0.2.0-rc.1", -] - [[package]] name = "elliptic-curve" version = "0.14.0-rc.1" @@ -399,7 +399,7 @@ version = "2.3.0-pre.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4633ec5613e4218fbab07568ca79ee388e3c041af75f0f83a15f040f096f94cf" dependencies = [ - "digest 0.11.0-pre.9 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.11.0-pre.9", "rand_core 0.9.2", ] diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 3612efd63..938cc21b7 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "digest" description = "Traits for cryptographic hash functions and message authentication codes" -version = "0.11.0-pre.9" +version = "0.11.0-pre.10" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" @@ -13,7 +13,7 @@ keywords = ["digest", "crypto", "hash"] categories = ["cryptography", "no-std"] [dependencies] -crypto-common = { version = "0.2.0-rc.1", path = "../crypto-common" } +crypto-common = { version = "0.2.0-rc.2", path = "../crypto-common" } # optional dependencies block-buffer = { version = "0.11.0-rc.4", optional = true } From ad7adbbf269076de8b05f6385a4743b24f42464b Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Sat, 22 Feb 2025 22:04:20 +0300 Subject: [PATCH 1287/1461] cipher: release v0.5.0-pre.8 (#1764) --- Cargo.lock | 2 +- cipher/Cargo.toml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b6035d19c..bab9ae87c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -95,7 +95,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cipher" -version = "0.5.0-pre.7" +version = "0.5.0-pre.8" dependencies = [ "blobby", "crypto-common 0.2.0-rc.2", diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index 95b9735d4..79bb3c59b 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "cipher" description = "Traits for describing block ciphers and stream ciphers" -version = "0.5.0-pre.7" +version = "0.5.0-pre.8" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" @@ -13,7 +13,7 @@ keywords = ["crypto", "block-cipher", "stream-cipher", "trait"] categories = ["cryptography", "no-std"] [dependencies] -crypto-common = { version = "0.2.0-rc.1", path = "../crypto-common" } +crypto-common = { version = "0.2.0-rc.2", path = "../crypto-common" } inout = "0.2.0-rc.4" # optional dependencies From f17b96292641666b8c1de9c77d689092af264f78 Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Sat, 22 Feb 2025 21:47:12 +0000 Subject: [PATCH 1288/1461] signature: relax `Sized` requirements on rng (#1765) --- signature/src/signer.rs | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/signature/src/signer.rs b/signature/src/signer.rs index 22f2e6aa0..1ff236007 100644 --- a/signature/src/signer.rs +++ b/signature/src/signer.rs @@ -86,7 +86,7 @@ pub trait DigestSigner { #[cfg(feature = "rand_core")] pub trait RandomizedSigner { /// Sign the given message and return a digital signature - fn sign_with_rng(&self, rng: &mut R, msg: &[u8]) -> S { + fn sign_with_rng(&self, rng: &mut R, msg: &[u8]) -> S { self.try_sign_with_rng(rng, msg) .expect("signature operation failed") } @@ -96,7 +96,11 @@ pub trait RandomizedSigner { /// /// The main intended use case for signing errors is when communicating /// with external signers, e.g. cloud KMS, HSMs, or other hardware tokens. - fn try_sign_with_rng(&self, rng: &mut R, msg: &[u8]) -> Result; + fn try_sign_with_rng( + &self, + rng: &mut R, + msg: &[u8], + ) -> Result; } /// Combination of [`DigestSigner`] and [`RandomizedSigner`] with support for @@ -106,15 +110,18 @@ pub trait RandomizedDigestSigner { /// Sign the given prehashed message `Digest`, returning a signature. /// /// Panics in the event of a signing error. - fn sign_digest_with_rng(&self, rng: &mut R, digest: D) -> S { + fn sign_digest_with_rng(&self, rng: &mut R, digest: D) -> S { self.try_sign_digest_with_rng(rng, digest) .expect("signature operation failed") } /// Attempt to sign the given prehashed message `Digest`, returning a /// digital signature on success, or an error if something went wrong. - fn try_sign_digest_with_rng(&self, rng: &mut R, digest: D) - -> Result; + fn try_sign_digest_with_rng( + &self, + rng: &mut R, + digest: D, + ) -> Result; } /// Sign the provided message bytestring using `&mut Self` (e.g. an evolving @@ -123,7 +130,7 @@ pub trait RandomizedDigestSigner { #[cfg(feature = "rand_core")] pub trait RandomizedSignerMut { /// Sign the given message, update the state, and return a digital signature. - fn sign_with_rng(&mut self, rng: &mut R, msg: &[u8]) -> S { + fn sign_with_rng(&mut self, rng: &mut R, msg: &[u8]) -> S { self.try_sign_with_rng(rng, msg) .expect("signature operation failed") } @@ -133,13 +140,21 @@ pub trait RandomizedSignerMut { /// /// Signing can fail, e.g., if the number of time periods allowed by the /// current key is exceeded. - fn try_sign_with_rng(&mut self, rng: &mut R, msg: &[u8]) -> Result; + fn try_sign_with_rng( + &mut self, + rng: &mut R, + msg: &[u8], + ) -> Result; } /// Blanket impl of [`RandomizedSignerMut`] for all [`RandomizedSigner`] types. #[cfg(feature = "rand_core")] impl> RandomizedSignerMut for T { - fn try_sign_with_rng(&mut self, rng: &mut R, msg: &[u8]) -> Result { + fn try_sign_with_rng( + &mut self, + rng: &mut R, + msg: &[u8], + ) -> Result { T::try_sign_with_rng(self, rng, msg) } } From 96dfc4a608c5ddf2972ff926ae3d695cae0275c7 Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Sat, 22 Feb 2025 22:02:26 +0000 Subject: [PATCH 1289/1461] signature: Relax `Sized` requirements on async signer traits (#1766) Follow up on https://github.com/RustCrypto/traits/pull/1765 --- signature/src/hazmat.rs | 4 ++-- signature/src/signer.rs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/signature/src/hazmat.rs b/signature/src/hazmat.rs index 25cc900a5..075fc489e 100644 --- a/signature/src/hazmat.rs +++ b/signature/src/hazmat.rs @@ -43,7 +43,7 @@ pub trait RandomizedPrehashSigner { /// /// Allowed lengths are algorithm-dependent and up to a particular /// implementation to decide. - fn sign_prehash_with_rng( + fn sign_prehash_with_rng( &self, rng: &mut R, prehash: &[u8], @@ -103,7 +103,7 @@ pub trait AsyncRandomizedPrehashSigner { /// /// Allowed lengths are algorithm-dependent and up to a particular /// implementation to decide. - async fn sign_prehash_with_rng_async( + async fn sign_prehash_with_rng_async( &self, rng: &mut R, prehash: &[u8], diff --git a/signature/src/signer.rs b/signature/src/signer.rs index 1ff236007..2b3fe9f1e 100644 --- a/signature/src/signer.rs +++ b/signature/src/signer.rs @@ -201,7 +201,7 @@ where #[allow(async_fn_in_trait)] pub trait AsyncRandomizedSigner { /// Sign the given message and return a digital signature - async fn sign_with_rng_async(&self, rng: &mut R, msg: &[u8]) -> S { + async fn sign_with_rng_async(&self, rng: &mut R, msg: &[u8]) -> S { self.try_sign_with_rng_async(rng, msg) .await .expect("signature operation failed") @@ -212,7 +212,7 @@ pub trait AsyncRandomizedSigner { /// /// The main intended use case for signing errors is when communicating /// with external signers, e.g. cloud KMS, HSMs, or other hardware tokens. - async fn try_sign_with_rng_async( + async fn try_sign_with_rng_async( &self, rng: &mut R, msg: &[u8], @@ -224,7 +224,7 @@ impl AsyncRandomizedSigner for T where T: RandomizedSigner, { - async fn try_sign_with_rng_async( + async fn try_sign_with_rng_async( &self, rng: &mut R, msg: &[u8], From fbb43215e51ca212dafed6f7b0a713fe6e37171c Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Sun, 23 Feb 2025 09:48:49 +0000 Subject: [PATCH 1290/1461] elliptic-curve: bump rand_core to 0.9.0 (#1751) This pulls: - https://github.com/RustCrypto/crypto-bigint/pull/762 - https://github.com/RustCrypto/crypto-bigint/pull/765 - https://github.com/zkcrypto/ff/pull/122 - https://github.com/zkcrypto/group/pull/56 - https://github.com/RustCrypto/MACs/pull/178 - https://github.com/RustCrypto/formats/pull/1666 --- .github/workflows/signature.yml | 1 + Cargo.lock | 273 ++++++++++---- Cargo.toml | 24 +- async-signature/tests/mock_impl.rs | 4 +- elliptic-curve/Cargo.lock | 447 ----------------------- elliptic-curve/Cargo.toml | 10 +- elliptic-curve/src/ecdh.rs | 4 +- elliptic-curve/src/point/non_identity.rs | 4 +- elliptic-curve/src/scalar/blinded.rs | 6 +- elliptic-curve/src/scalar/nonzero.rs | 4 +- elliptic-curve/src/scalar/primitive.rs | 4 +- elliptic-curve/src/secret_key.rs | 4 +- signature/Cargo.lock | 269 -------------- signature/Cargo.toml | 2 +- 14 files changed, 250 insertions(+), 806 deletions(-) delete mode 100644 elliptic-curve/Cargo.lock delete mode 100644 signature/Cargo.lock diff --git a/.github/workflows/signature.yml b/.github/workflows/signature.yml index 905b447cf..00e6f0a20 100644 --- a/.github/workflows/signature.yml +++ b/.github/workflows/signature.yml @@ -42,6 +42,7 @@ jobs: - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features derive,rand_core minimal-versions: + if: false # disabled until we stop using pre-releases uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master with: working-directory: ${{ github.workflow }} diff --git a/Cargo.lock b/Cargo.lock index bab9ae87c..3c89109e6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -23,7 +23,7 @@ checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" name = "async-signature" version = "0.6.0-pre.4" dependencies = [ - "signature 2.3.0-pre.6 (registry+https://github.com/rust-lang/crates.io-index)", + "signature", ] [[package]] @@ -50,6 +50,18 @@ version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + [[package]] name = "blobby" version = "0.4.0-pre.0" @@ -62,7 +74,7 @@ version = "0.11.0-rc.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a229bfd78e4827c91b9b95784f69492c1b77c1ab75a45a8a037b139215086f94" dependencies = [ - "hybrid-array 0.3.0", + "hybrid-array", "zeroize", ] @@ -72,7 +84,7 @@ version = "0.4.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee88d14c41bbae2e333f574a27fc73d96fe1039e5a356c20d06a7f2a34cd8e5a" dependencies = [ - "hybrid-array 0.3.0", + "hybrid-array", ] [[package]] @@ -109,6 +121,15 @@ version = "0.10.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68ff6be19477a1bd5441f382916a89bc2a0b2c35db6d41e0f6e8538bf6d6463f" +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + [[package]] name = "crypto" version = "0.6.0-pre" @@ -119,19 +140,18 @@ dependencies = [ "digest 0.11.0-pre.10", "elliptic-curve", "password-hash", - "signature 2.3.0-pre.6", + "signature", "universal-hash", ] [[package]] name = "crypto-bigint" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96272c2ff28b807e09250b180ad1fb7889a3258f7455759b5c3c58b719467130" +version = "0.7.0-pre.0" +source = "git+https://github.com/RustCrypto/crypto-bigint.git#8fe22cba8196b08acd06546757f2f474aa20db1e" dependencies = [ - "hybrid-array 0.2.3", + "hybrid-array", "num-traits", - "rand_core 0.6.4", + "rand_core", "subtle", "zeroize", ] @@ -140,8 +160,8 @@ dependencies = [ name = "crypto-common" version = "0.2.0-rc.2" dependencies = [ - "hybrid-array 0.3.0", - "rand_core 0.9.2", + "hybrid-array", + "rand_core", ] [[package]] @@ -150,7 +170,7 @@ version = "0.2.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "170d71b5b14dec99db7739f6fc7d6ec2db80b78c3acb77db48392ccc3d8a9ea0" dependencies = [ - "hybrid-array 0.3.0", + "hybrid-array", ] [[package]] @@ -160,28 +180,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "82db698b33305f0134faf590b9d1259dc171b5481ac41d5c8146c3b3ee7d4319" dependencies = [ "const-oid", + "pem-rfc7468", "zeroize", ] [[package]] name = "digest" -version = "0.11.0-pre.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf2e3d6615d99707295a9673e889bf363a04b2a466bd320c65a72536f7577379" +version = "0.11.0-pre.10" dependencies = [ - "crypto-common 0.2.0-rc.2 (registry+https://github.com/rust-lang/crates.io-index)", + "blobby", + "block-buffer", + "const-oid", + "crypto-common 0.2.0-rc.2", + "subtle", + "zeroize", ] [[package]] name = "digest" version = "0.11.0-pre.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c478574b20020306f98d61c8ca3322d762e1ff08117422ac6106438605ea516" dependencies = [ - "blobby", "block-buffer", "const-oid", - "crypto-common 0.2.0-rc.2", + "crypto-common 0.2.0-rc.2 (registry+https://github.com/rust-lang/crates.io-index)", "subtle", - "zeroize", ] [[package]] @@ -189,37 +213,42 @@ name = "elliptic-curve" version = "0.14.0-rc.1" dependencies = [ "base16ct", + "base64ct", "crypto-bigint", + "digest 0.11.0-pre.10 (registry+https://github.com/rust-lang/crates.io-index)", "ff", "group", - "hybrid-array 0.2.3", + "hex-literal", + "hkdf", + "hybrid-array", + "pem-rfc7468", "pkcs8", - "rand_core 0.6.4", + "rand_core", "sec1", + "serde_json", + "serdect", + "sha2", + "sha3", "subtle", + "tap", "zeroize", ] [[package]] name = "ff" version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +source = "git+https://github.com/pinkforest/ff.git?branch=bump-rand-core#c734f7f21d6639bc6494dde538209d0770207c49" dependencies = [ - "rand_core 0.6.4", + "bitvec", + "rand_core", "subtle", ] [[package]] -name = "getrandom" -version = "0.2.15" +name = "funty" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.11.0+wasi-snapshot-preview1", -] +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "getrandom" @@ -229,18 +258,17 @@ checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8" dependencies = [ "cfg-if", "libc", - "wasi 0.13.3+wasi-0.2.2", + "wasi", "windows-targets", ] [[package]] name = "group" version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +source = "git+https://github.com/pinkforest/group.git?branch=bump-rand-0.9#06ac6fb11ced26fbf980ee65e74fced4da66ec3e" dependencies = [ "ff", - "rand_core 0.6.4", + "rand_core", "subtle", ] @@ -264,13 +292,26 @@ dependencies = [ ] [[package]] -name = "hybrid-array" -version = "0.2.3" +name = "hex-literal" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2d35805454dc9f8662a98d6d61886ffe26bd465f5960e0e55345c70d5c0d2a9" +checksum = "bcaaec4551594c969335c98c903c1397853d4198408ea609190f420500f6be71" + +[[package]] +name = "hkdf" +version = "0.13.0-pre.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00176ff81091018d42ff82e8324f8e5adb0b7e0468d1358f653972562dbff031" dependencies = [ - "typenum", - "zeroize", + "hmac", +] + +[[package]] +name = "hmac" +version = "0.13.0-pre.4" +source = "git+https://github.com/baloo/MACs.git?branch=baloo%2Fedition-2024#e97856eac291ab85e181af927192277532af34ca" +dependencies = [ + "digest 0.11.0-pre.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -290,14 +331,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac5e145e8ade9f74c0a5efc60ccb4e714b0144f7e2220b7ca64254feee71c57f" dependencies = [ "block-padding", - "hybrid-array 0.3.0", + "hybrid-array", +] + +[[package]] +name = "itoa" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" + +[[package]] +name = "keccak" +version = "0.2.0-pre.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7cdd4f0dc5807b9a2b25dd48a3f58e862606fe7bd47f41ecde36e97422d7e90" +dependencies = [ + "cpufeatures", ] [[package]] name = "kem" version = "0.3.0-pre.0" dependencies = [ - "rand_core 0.9.2", + "rand_core", "zeroize", ] @@ -307,6 +363,12 @@ version = "0.2.169" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + [[package]] name = "num-traits" version = "0.2.19" @@ -321,10 +383,19 @@ name = "password-hash" version = "0.6.0-rc.0" dependencies = [ "base64ct", - "rand_core 0.9.2", + "rand_core", "subtle", ] +[[package]] +name = "pem-rfc7468" +version = "1.0.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2dfbfa5c6f0906884269722c5478e72fd4d6c0e24fe600332c6d62359567ce1" +dependencies = [ + "base64ct", +] + [[package]] name = "pkcs8" version = "0.11.0-rc.2" @@ -354,13 +425,10 @@ dependencies = [ ] [[package]] -name = "rand_core" -version = "0.6.4" +name = "radium" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.15", -] +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" [[package]] name = "rand_core" @@ -368,39 +436,101 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a509b1a2ffbe92afab0e55c8fd99dea1c280e8171bd2d88682bb20bc41cbc2c" dependencies = [ - "getrandom 0.3.1", + "getrandom", "zerocopy", ] +[[package]] +name = "ryu" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd" + [[package]] name = "sec1" -version = "0.8.0-rc.3" +version = "0.8.0-rc.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1988446eff153796413a73669dfaa4caa3f5ce8b25fac89e3821a39c611772e" +checksum = "a017a4aa8f0bd51e9d0184d98042dfe9285218fec098493f47d9a8aa0f1a3f27" dependencies = [ "base16ct", "der", - "hybrid-array 0.2.3", + "hybrid-array", "pkcs8", + "serdect", "subtle", "zeroize", ] [[package]] -name = "signature" -version = "2.3.0-pre.6" +name = "serde" +version = "1.0.218" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8dfc9d19bdbf6d17e22319da49161d5d0108e4188e8b680aef6299eed22df60" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.218" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f09503e191f4e797cb8aac08e9a4a4695c5edf6a2e70e376d961ddd5c969f82b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.139" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44f86c3acccc9c65b153fe1b85a3be07fe5515274ec9f0653b4a0875731c72a6" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serdect" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f42f67da2385b51a5f9652db9c93d78aeaf7610bf5ec366080b6de810604af53" +dependencies = [ + "base16ct", + "serde", +] + +[[package]] +name = "sha2" +version = "0.11.0-pre.4" +source = "git+https://github.com/RustCrypto/hashes.git?branch=edition_upgrade#cfe82a0f1a9a6c89c5b6d8309f2603c644dc97ea" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.11.0-pre.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "sha3" +version = "0.11.0-pre.4" +source = "git+https://github.com/RustCrypto/hashes.git?branch=edition_upgrade#cfe82a0f1a9a6c89c5b6d8309f2603c644dc97ea" dependencies = [ - "rand_core 0.9.2", + "digest 0.11.0-pre.10 (registry+https://github.com/rust-lang/crates.io-index)", + "keccak", ] [[package]] name = "signature" version = "2.3.0-pre.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4633ec5613e4218fbab07568ca79ee388e3c041af75f0f83a15f040f096f94cf" dependencies = [ - "digest 0.11.0-pre.9", - "rand_core 0.9.2", + "digest 0.11.0-pre.10 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal", + "rand_core", + "sha2", + "signature_derive", ] [[package]] @@ -445,6 +575,12 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + [[package]] name = "typenum" version = "1.18.0" @@ -465,12 +601,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - [[package]] name = "wasi" version = "0.13.3+wasi-0.2.2" @@ -553,6 +683,15 @@ dependencies = [ "bitflags", ] +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + [[package]] name = "zerocopy" version = "0.8.20" diff --git a/Cargo.toml b/Cargo.toml index 811b606ad..bc4d58826 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,12 +7,30 @@ members = [ "crypto", "crypto-common", "digest", + "elliptic-curve", "kem", "password-hash", "signature_derive", "universal-hash", -] -exclude = [ - "elliptic-curve", "signature", ] + +[patch.crates-io] +signature = { path = "signature" } + +# https://github.com/RustCrypto/hashes/pull/652 +sha2 = { git = "https://github.com/RustCrypto/hashes.git", branch = "edition_upgrade" } +sha3 = { git = "https://github.com/RustCrypto/hashes.git", branch = "edition_upgrade" } + +# https://github.com/RustCrypto/MACs/pull/178 +hmac = { git = "https://github.com/baloo/MACs.git", branch = "baloo/edition-2024" } + +# https://github.com/RustCrypto/crypto-bigint/pull/762 +# https://github.com/RustCrypto/crypto-bigint/pull/765 +crypto-bigint = { git = "https://github.com/RustCrypto/crypto-bigint.git" } + +# https://github.com/zkcrypto/ff/pull/122 +ff = { git = "https://github.com/pinkforest/ff.git", branch = "bump-rand-core" } + +# https://github.com/zkcrypto/group/pull/56 +group = { git = "https://github.com/pinkforest/group.git", branch = "bump-rand-0.9" } diff --git a/async-signature/tests/mock_impl.rs b/async-signature/tests/mock_impl.rs index 5391966b8..d8e17ea45 100644 --- a/async-signature/tests/mock_impl.rs +++ b/async-signature/tests/mock_impl.rs @@ -28,7 +28,9 @@ where #[cfg(feature = "rand_core")] impl async_signature::AsyncRandomizedSigner for MockSigner { - async fn try_sign_with_rng_async( + async fn try_sign_with_rng_async< + R: async_signature::signature::rand_core::TryCryptoRng + ?Sized, + >( &self, _rng: &mut R, _msg: &[u8], diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock deleted file mode 100644 index 1659ec061..000000000 --- a/elliptic-curve/Cargo.lock +++ /dev/null @@ -1,447 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "autocfg" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" - -[[package]] -name = "base16ct" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" - -[[package]] -name = "base64ct" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" - -[[package]] -name = "bitvec" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" -dependencies = [ - "funty", - "radium", - "tap", - "wyz", -] - -[[package]] -name = "block-buffer" -version = "0.11.0-rc.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fd016a0ddc7cb13661bf5576073ce07330a693f8608a1320b4e20561cc12cdc" -dependencies = [ - "hybrid-array", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "const-oid" -version = "0.10.0-rc.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ff6be19477a1bd5441f382916a89bc2a0b2c35db6d41e0f6e8538bf6d6463f" - -[[package]] -name = "cpufeatures" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" -dependencies = [ - "libc", -] - -[[package]] -name = "crypto-bigint" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96272c2ff28b807e09250b180ad1fb7889a3258f7455759b5c3c58b719467130" -dependencies = [ - "hybrid-array", - "num-traits", - "rand_core", - "subtle", - "zeroize", -] - -[[package]] -name = "crypto-common" -version = "0.2.0-rc.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0b8ce8218c97789f16356e7896b3714f26c2ee1079b79c0b7ae7064bb9089fa" -dependencies = [ - "getrandom", - "hybrid-array", - "rand_core", -] - -[[package]] -name = "der" -version = "0.8.0-rc.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82db698b33305f0134faf590b9d1259dc171b5481ac41d5c8146c3b3ee7d4319" -dependencies = [ - "const-oid", - "pem-rfc7468", - "zeroize", -] - -[[package]] -name = "digest" -version = "0.11.0-pre.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf2e3d6615d99707295a9673e889bf363a04b2a466bd320c65a72536f7577379" -dependencies = [ - "block-buffer", - "const-oid", - "crypto-common", - "subtle", -] - -[[package]] -name = "elliptic-curve" -version = "0.14.0-rc.1" -dependencies = [ - "base16ct", - "base64ct", - "crypto-bigint", - "digest", - "ff", - "group", - "hex-literal", - "hkdf", - "hybrid-array", - "pem-rfc7468", - "pkcs8", - "rand_core", - "sec1", - "serde_json", - "serdect", - "sha2", - "sha3", - "subtle", - "tap", - "zeroize", -] - -[[package]] -name = "ff" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" -dependencies = [ - "bitvec", - "rand_core", - "subtle", -] - -[[package]] -name = "funty" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" - -[[package]] -name = "getrandom" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "group" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" -dependencies = [ - "ff", - "rand_core", - "subtle", -] - -[[package]] -name = "hex-literal" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcaaec4551594c969335c98c903c1397853d4198408ea609190f420500f6be71" - -[[package]] -name = "hkdf" -version = "0.13.0-pre.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00176ff81091018d42ff82e8324f8e5adb0b7e0468d1358f653972562dbff031" -dependencies = [ - "hmac", -] - -[[package]] -name = "hmac" -version = "0.13.0-pre.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4b1fb14e4df79f9406b434b60acef9f45c26c50062cccf1346c6103b8c47d58" -dependencies = [ - "digest", -] - -[[package]] -name = "hybrid-array" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2d35805454dc9f8662a98d6d61886ffe26bd465f5960e0e55345c70d5c0d2a9" -dependencies = [ - "typenum", - "zeroize", -] - -[[package]] -name = "itoa" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" - -[[package]] -name = "keccak" -version = "0.2.0-pre.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7cdd4f0dc5807b9a2b25dd48a3f58e862606fe7bd47f41ecde36e97422d7e90" -dependencies = [ - "cpufeatures", -] - -[[package]] -name = "libc" -version = "0.2.169" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" - -[[package]] -name = "memchr" -version = "2.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - -[[package]] -name = "pem-rfc7468" -version = "1.0.0-rc.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2dfbfa5c6f0906884269722c5478e72fd4d6c0e24fe600332c6d62359567ce1" -dependencies = [ - "base64ct", -] - -[[package]] -name = "pkcs8" -version = "0.11.0-rc.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f22636de7c995e997ed3d8d2949b7414d4faba3efa7312a6c0e75d875a14bdd4" -dependencies = [ - "der", - "spki", -] - -[[package]] -name = "proc-macro2" -version = "1.0.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "radium" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - -[[package]] -name = "ryu" -version = "1.0.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd" - -[[package]] -name = "sec1" -version = "0.8.0-rc.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1988446eff153796413a73669dfaa4caa3f5ce8b25fac89e3821a39c611772e" -dependencies = [ - "base16ct", - "der", - "hybrid-array", - "pkcs8", - "serdect", - "subtle", - "zeroize", -] - -[[package]] -name = "serde" -version = "1.0.218" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8dfc9d19bdbf6d17e22319da49161d5d0108e4188e8b680aef6299eed22df60" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.218" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f09503e191f4e797cb8aac08e9a4a4695c5edf6a2e70e376d961ddd5c969f82b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.139" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44f86c3acccc9c65b153fe1b85a3be07fe5515274ec9f0653b4a0875731c72a6" -dependencies = [ - "itoa", - "memchr", - "ryu", - "serde", -] - -[[package]] -name = "serdect" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f42f67da2385b51a5f9652db9c93d78aeaf7610bf5ec366080b6de810604af53" -dependencies = [ - "base16ct", - "serde", -] - -[[package]] -name = "sha2" -version = "0.11.0-pre.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "540c0893cce56cdbcfebcec191ec8e0f470dd1889b6e7a0b503e310a94a168f5" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "sha3" -version = "0.11.0-pre.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e485881f388c2818d709796dc883c1ffcadde9d1f0e054f3a5c14974185261a6" -dependencies = [ - "digest", - "keccak", -] - -[[package]] -name = "spki" -version = "0.8.0-rc.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37ac66481418fd7afdc584adcf3be9aa572cf6c2858814494dc2a01755f050bc" -dependencies = [ - "base64ct", - "der", -] - -[[package]] -name = "subtle" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" - -[[package]] -name = "syn" -version = "2.0.98" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "tap" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" - -[[package]] -name = "typenum" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" - -[[package]] -name = "unicode-ident" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe" - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wyz" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" -dependencies = [ - "tap", -] - -[[package]] -name = "zeroize" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 7166527b3..b5c0915e0 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -18,22 +18,22 @@ rust-version = "1.85" [dependencies] base16ct = "0.2" -crypto-bigint = { version = "0.6", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } -hybrid-array = { version = "0.2", default-features = false, features = ["zeroize"] } -rand_core = { version = "0.6.4", default-features = false } +crypto-bigint = { version = "0.7.0-pre", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } +hybrid-array = { version = "0.3", default-features = false, features = ["zeroize"] } +rand_core = { version = "0.9.0", default-features = false } subtle = { version = "2.6", default-features = false } zeroize = { version = "1.7", default-features = false } # optional dependencies base64ct = { version = "1", optional = true, default-features = false, features = ["alloc"] } -digest = { version = "=0.11.0-pre.9", optional = true } +digest = { version = "=0.11.0-pre.10", optional = true } ff = { version = "0.13", optional = true, default-features = false } group = { version = "0.13", optional = true, default-features = false } hkdf = { version = "=0.13.0-pre.4", optional = true, default-features = false } hex-literal = { version = "1", optional = true } pem-rfc7468 = { version = "1.0.0-rc.2", optional = true, features = ["alloc"] } pkcs8 = { version = "0.11.0-rc.1", optional = true, default-features = false } -sec1 = { version = "0.8.0-rc.3", optional = true, features = ["subtle", "zeroize"] } +sec1 = { version = "0.8.0-rc.4", optional = true, features = ["subtle", "zeroize"] } serdect = { version = "0.3", optional = true, default-features = false, features = ["alloc"] } serde_json = { version = "1.0.121", optional = true, default-features = false, features = ["alloc"] } tap = { version = "1.0.1", optional = true, default-features = false } # hack for minimal-versions support for `bits` diff --git a/elliptic-curve/src/ecdh.rs b/elliptic-curve/src/ecdh.rs index 88b885220..c4881fe6e 100644 --- a/elliptic-curve/src/ecdh.rs +++ b/elliptic-curve/src/ecdh.rs @@ -34,7 +34,7 @@ use core::{borrow::Borrow, fmt}; use digest::{Digest, crypto_common::BlockSizeUser}; use group::Curve as _; use hkdf::{Hkdf, hmac::SimpleHmac}; -use rand_core::CryptoRngCore; +use rand_core::CryptoRng; use zeroize::{Zeroize, ZeroizeOnDrop}; /// Low-level Elliptic Curve Diffie-Hellman (ECDH) function. @@ -108,7 +108,7 @@ where C: CurveArithmetic, { /// Generate a cryptographically random [`EphemeralSecret`]. - pub fn random(rng: &mut impl CryptoRngCore) -> Self { + pub fn random(rng: &mut R) -> Self { Self { scalar: NonZeroScalar::random(rng), } diff --git a/elliptic-curve/src/point/non_identity.rs b/elliptic-curve/src/point/non_identity.rs index 1cb1a7fdb..c118852c1 100644 --- a/elliptic-curve/src/point/non_identity.rs +++ b/elliptic-curve/src/point/non_identity.rs @@ -3,7 +3,7 @@ use core::ops::{Deref, Mul}; use group::{Curve, GroupEncoding, prime::PrimeCurveAffine}; -use rand_core::{CryptoRng, RngCore}; +use rand_core::CryptoRng; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; #[cfg(feature = "serde")] @@ -58,7 +58,7 @@ where P: ConditionallySelectable + ConstantTimeEq + Curve + Default, { /// Generate a random `NonIdentity`. - pub fn random(mut rng: impl CryptoRng + RngCore) -> Self { + pub fn random(mut rng: R) -> Self { loop { if let Some(point) = Self::new(P::random(&mut rng)).into() { break point; diff --git a/elliptic-curve/src/scalar/blinded.rs b/elliptic-curve/src/scalar/blinded.rs index 685ba9d54..6638e84cc 100644 --- a/elliptic-curve/src/scalar/blinded.rs +++ b/elliptic-curve/src/scalar/blinded.rs @@ -4,7 +4,7 @@ use super::Scalar; use crate::{CurveArithmetic, ops::Invert}; use core::fmt; use group::ff::Field; -use rand_core::CryptoRngCore; +use rand_core::CryptoRng; use subtle::CtOption; use zeroize::Zeroize; @@ -37,8 +37,8 @@ impl BlindedScalar where C: CurveArithmetic, { - /// Create a new [`BlindedScalar`] from a scalar and a [`CryptoRngCore`]. - pub fn new(scalar: Scalar, rng: &mut impl CryptoRngCore) -> Self { + /// Create a new [`BlindedScalar`] from a scalar and a [`CryptoRng`]. + pub fn new(scalar: Scalar, rng: &mut R) -> Self { Self { scalar, mask: Scalar::::random(rng), diff --git a/elliptic-curve/src/scalar/nonzero.rs b/elliptic-curve/src/scalar/nonzero.rs index 74a7d41af..0500abe4c 100644 --- a/elliptic-curve/src/scalar/nonzero.rs +++ b/elliptic-curve/src/scalar/nonzero.rs @@ -13,7 +13,7 @@ use core::{ }; use crypto_bigint::{ArrayEncoding, Integer}; use ff::{Field, PrimeField}; -use rand_core::CryptoRngCore; +use rand_core::CryptoRng; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; use zeroize::Zeroize; @@ -47,7 +47,7 @@ where C: CurveArithmetic, { /// Generate a random `NonZeroScalar`. - pub fn random(mut rng: &mut impl CryptoRngCore) -> Self { + pub fn random(mut rng: &mut R) -> Self { // Use rejection sampling to eliminate zero values. // While this method isn't constant-time, the attacker shouldn't learn // anything about unrelated outputs so long as `rng` is a secure `CryptoRng`. diff --git a/elliptic-curve/src/scalar/primitive.rs b/elliptic-curve/src/scalar/primitive.rs index e61d574be..b6720b0a5 100644 --- a/elliptic-curve/src/scalar/primitive.rs +++ b/elliptic-curve/src/scalar/primitive.rs @@ -14,7 +14,7 @@ use core::{ ops::{Add, AddAssign, Neg, ShrAssign, Sub, SubAssign}, str, }; -use rand_core::CryptoRngCore; +use rand_core::CryptoRng; use subtle::{ Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeGreater, ConstantTimeLess, CtOption, @@ -65,7 +65,7 @@ where pub const MODULUS: C::Uint = C::ORDER; /// Generate a random [`ScalarPrimitive`]. - pub fn random(rng: &mut impl CryptoRngCore) -> Self { + pub fn random(rng: &mut R) -> Self { Self { inner: C::Uint::random_mod(rng, &NonZero::new(Self::MODULUS).unwrap()), } diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 7da6c2e0c..02f9778e8 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -15,7 +15,7 @@ use subtle::{Choice, ConstantTimeEq}; use zeroize::{Zeroize, ZeroizeOnDrop, Zeroizing}; #[cfg(feature = "arithmetic")] -use crate::{CurveArithmetic, NonZeroScalar, PublicKey, rand_core::CryptoRngCore}; +use crate::{CurveArithmetic, NonZeroScalar, PublicKey, rand_core::CryptoRng}; #[cfg(feature = "jwk")] use crate::jwk::{JwkEcKey, JwkParameters}; @@ -91,7 +91,7 @@ where /// Generate a random [`SecretKey`]. #[cfg(feature = "arithmetic")] - pub fn random(rng: &mut impl CryptoRngCore) -> Self + pub fn random(rng: &mut R) -> Self where C: CurveArithmetic, { diff --git a/signature/Cargo.lock b/signature/Cargo.lock deleted file mode 100644 index c2f685474..000000000 --- a/signature/Cargo.lock +++ /dev/null @@ -1,269 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "bitflags" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" - -[[package]] -name = "block-buffer" -version = "0.11.0-rc.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fd016a0ddc7cb13661bf5576073ce07330a693f8608a1320b4e20561cc12cdc" -dependencies = [ - "hybrid-array", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "cpufeatures" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" -dependencies = [ - "libc", -] - -[[package]] -name = "crypto-common" -version = "0.2.0-rc.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0b8ce8218c97789f16356e7896b3714f26c2ee1079b79c0b7ae7064bb9089fa" -dependencies = [ - "hybrid-array", -] - -[[package]] -name = "digest" -version = "0.11.0-pre.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf2e3d6615d99707295a9673e889bf363a04b2a466bd320c65a72536f7577379" -dependencies = [ - "block-buffer", - "crypto-common", -] - -[[package]] -name = "getrandom" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8" -dependencies = [ - "cfg-if", - "libc", - "wasi", - "windows-targets", -] - -[[package]] -name = "hex-literal" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcaaec4551594c969335c98c903c1397853d4198408ea609190f420500f6be71" - -[[package]] -name = "hybrid-array" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2d35805454dc9f8662a98d6d61886ffe26bd465f5960e0e55345c70d5c0d2a9" -dependencies = [ - "typenum", -] - -[[package]] -name = "libc" -version = "0.2.169" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" - -[[package]] -name = "proc-macro2" -version = "1.0.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand_core" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a509b1a2ffbe92afab0e55c8fd99dea1c280e8171bd2d88682bb20bc41cbc2c" -dependencies = [ - "getrandom", - "zerocopy", -] - -[[package]] -name = "sha2" -version = "0.11.0-pre.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "540c0893cce56cdbcfebcec191ec8e0f470dd1889b6e7a0b503e310a94a168f5" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "signature" -version = "2.3.0-pre.6" -dependencies = [ - "digest", - "hex-literal", - "rand_core", - "sha2", - "signature_derive", -] - -[[package]] -name = "signature_derive" -version = "2.2.0" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "syn" -version = "2.0.98" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "typenum" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" - -[[package]] -name = "unicode-ident" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe" - -[[package]] -name = "wasi" -version = "0.13.3+wasi-0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2" -dependencies = [ - "wit-bindgen-rt", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "wit-bindgen-rt" -version = "0.33.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" -dependencies = [ - "bitflags", -] - -[[package]] -name = "zerocopy" -version = "0.8.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dde3bb8c68a8f3f1ed4ac9221aad6b10cece3e60a8e2ea54a6a2dec806d0084c" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eea57037071898bf96a6da35fd626f4f27e9cee3ead2a6c703cf09d472b2e700" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 7a428af8b..c8a0047dd 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -15,7 +15,7 @@ rust-version = "1.85" [dependencies] derive = { package = "signature_derive", version = "2", optional = true, path = "../signature_derive" } -digest = { version = "=0.11.0-pre.9", optional = true, default-features = false } +digest = { version = "=0.11.0-pre.10", optional = true, default-features = false } rand_core = { version = "0.9", optional = true, default-features = false } [dev-dependencies] From 28b6e0d3231fa0fb31dc7f6bfdb62d6558bcfdf6 Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Sun, 23 Feb 2025 21:58:08 +0000 Subject: [PATCH 1291/1461] elliptic-curve: relax `Sized` requirements on Rng (#1767) --- elliptic-curve/src/scalar/nonzero.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elliptic-curve/src/scalar/nonzero.rs b/elliptic-curve/src/scalar/nonzero.rs index 0500abe4c..88f82a8a2 100644 --- a/elliptic-curve/src/scalar/nonzero.rs +++ b/elliptic-curve/src/scalar/nonzero.rs @@ -47,7 +47,7 @@ where C: CurveArithmetic, { /// Generate a random `NonZeroScalar`. - pub fn random(mut rng: &mut R) -> Self { + pub fn random(mut rng: &mut R) -> Self { // Use rejection sampling to eliminate zero values. // While this method isn't constant-time, the attacker shouldn't learn // anything about unrelated outputs so long as `rng` is a secure `CryptoRng`. From f8aa068be3e64ba8970107042f21605b237754ac Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Mon, 24 Feb 2025 14:58:31 +0300 Subject: [PATCH 1292/1461] Update year in license files (#1768) --- aead/LICENSE-MIT | 2 +- async-signature/LICENSE-MIT | 2 +- cipher/LICENSE-MIT | 2 +- crypto-common/LICENSE-MIT | 2 +- crypto/LICENSE-MIT | 2 +- digest/LICENSE-MIT | 1 + elliptic-curve/LICENSE-MIT | 2 +- kem/LICENSE-MIT | 2 +- password-hash/LICENSE-MIT | 2 +- signature/LICENSE-MIT | 2 +- signature_derive/LICENSE-MIT | 2 +- universal-hash/LICENSE-MIT | 2 +- 12 files changed, 12 insertions(+), 11 deletions(-) diff --git a/aead/LICENSE-MIT b/aead/LICENSE-MIT index 88e64ca7b..3972ddfd2 100644 --- a/aead/LICENSE-MIT +++ b/aead/LICENSE-MIT @@ -1,4 +1,4 @@ -Copyright (c) 2019 The RustCrypto Project Developers +Copyright (c) 2019-2025 The RustCrypto Project Developers Copyright (c) 2019 MobileCoin, LLC Permission is hereby granted, free of charge, to any diff --git a/async-signature/LICENSE-MIT b/async-signature/LICENSE-MIT index d4ce06527..b723e3eee 100644 --- a/async-signature/LICENSE-MIT +++ b/async-signature/LICENSE-MIT @@ -1,4 +1,4 @@ -Copyright (c) 2020-2022 RustCrypto Developers +Copyright (c) 2020-2025 RustCrypto Developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated diff --git a/cipher/LICENSE-MIT b/cipher/LICENSE-MIT index f3a832c3b..82812ae61 100644 --- a/cipher/LICENSE-MIT +++ b/cipher/LICENSE-MIT @@ -1,4 +1,4 @@ -Copyright (c) 2016-2020 RustCrypto Developers +Copyright (c) 2016-2025 RustCrypto Developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated diff --git a/crypto-common/LICENSE-MIT b/crypto-common/LICENSE-MIT index efb0b5f8b..d1c716154 100644 --- a/crypto-common/LICENSE-MIT +++ b/crypto-common/LICENSE-MIT @@ -1,4 +1,4 @@ -Copyright (c) 2021 RustCrypto Developers +Copyright (c) 2021-2025 RustCrypto Developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated diff --git a/crypto/LICENSE-MIT b/crypto/LICENSE-MIT index 2726e14a4..0cd648f76 100644 --- a/crypto/LICENSE-MIT +++ b/crypto/LICENSE-MIT @@ -1,4 +1,4 @@ -Copyright (c) 2020 The RustCrypto Project Developers +Copyright (c) 2020-2025 The RustCrypto Project Developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated diff --git a/digest/LICENSE-MIT b/digest/LICENSE-MIT index 8dcb85b30..37f14fe5e 100644 --- a/digest/LICENSE-MIT +++ b/digest/LICENSE-MIT @@ -1,3 +1,4 @@ +Copyright (c) 2017-2025 RustCrypto Developers Copyright (c) 2017 Artyom Pavlov Permission is hereby granted, free of charge, to any diff --git a/elliptic-curve/LICENSE-MIT b/elliptic-curve/LICENSE-MIT index d4ce06527..b723e3eee 100644 --- a/elliptic-curve/LICENSE-MIT +++ b/elliptic-curve/LICENSE-MIT @@ -1,4 +1,4 @@ -Copyright (c) 2020-2022 RustCrypto Developers +Copyright (c) 2020-2025 RustCrypto Developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated diff --git a/kem/LICENSE-MIT b/kem/LICENSE-MIT index a2b36f25c..d1c716154 100644 --- a/kem/LICENSE-MIT +++ b/kem/LICENSE-MIT @@ -1,4 +1,4 @@ -Copyright (c) 2021-2022 RustCrypto Developers +Copyright (c) 2021-2025 RustCrypto Developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated diff --git a/password-hash/LICENSE-MIT b/password-hash/LICENSE-MIT index 50b1254c1..b723e3eee 100644 --- a/password-hash/LICENSE-MIT +++ b/password-hash/LICENSE-MIT @@ -1,4 +1,4 @@ -Copyright (c) 2020-2023 RustCrypto Developers +Copyright (c) 2020-2025 RustCrypto Developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated diff --git a/signature/LICENSE-MIT b/signature/LICENSE-MIT index d8d87fe29..d767644da 100644 --- a/signature/LICENSE-MIT +++ b/signature/LICENSE-MIT @@ -1,4 +1,4 @@ -Copyright (c) 2018-2023 RustCrypto Developers +Copyright (c) 2018-2025 RustCrypto Developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated diff --git a/signature_derive/LICENSE-MIT b/signature_derive/LICENSE-MIT index d874d2e01..bb7ff7c2c 100644 --- a/signature_derive/LICENSE-MIT +++ b/signature_derive/LICENSE-MIT @@ -1,4 +1,4 @@ -Copyright (c) 2019-2022 RustCrypto Developers +Copyright (c) 2019-2025 RustCrypto Developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated diff --git a/universal-hash/LICENSE-MIT b/universal-hash/LICENSE-MIT index 468bccc2d..bb7ff7c2c 100644 --- a/universal-hash/LICENSE-MIT +++ b/universal-hash/LICENSE-MIT @@ -1,4 +1,4 @@ -Copyright (c) 2019-2020 RustCrypto Developers +Copyright (c) 2019-2025 RustCrypto Developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated From f19d414233d03ebd611cea5a8bd821999e3436d3 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Mon, 24 Feb 2025 15:39:09 +0300 Subject: [PATCH 1293/1461] Fix patch of sha2 and sha3 (#1769) --- Cargo.lock | 12 ++++++------ Cargo.toml | 5 ++--- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3c89109e6..b20d0a465 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -147,7 +147,7 @@ dependencies = [ [[package]] name = "crypto-bigint" version = "0.7.0-pre.0" -source = "git+https://github.com/RustCrypto/crypto-bigint.git#8fe22cba8196b08acd06546757f2f474aa20db1e" +source = "git+https://github.com/RustCrypto/crypto-bigint.git#e1065ce5fa73ee15e73f36a2ed0c6d4ca7b8fe8f" dependencies = [ "hybrid-array", "num-traits", @@ -309,7 +309,7 @@ dependencies = [ [[package]] name = "hmac" version = "0.13.0-pre.4" -source = "git+https://github.com/baloo/MACs.git?branch=baloo%2Fedition-2024#e97856eac291ab85e181af927192277532af34ca" +source = "git+https://github.com/baloo/MACs.git?branch=baloo%2Fedition-2024#cea718c1fcec0504c7ba030a2ad465d7b1881047" dependencies = [ "digest 0.11.0-pre.10 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -359,9 +359,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.169" +version = "0.2.170" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" +checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828" [[package]] name = "memchr" @@ -506,7 +506,7 @@ dependencies = [ [[package]] name = "sha2" version = "0.11.0-pre.4" -source = "git+https://github.com/RustCrypto/hashes.git?branch=edition_upgrade#cfe82a0f1a9a6c89c5b6d8309f2603c644dc97ea" +source = "git+https://github.com/RustCrypto/hashes#479ad0b5b48bc6044aa10a9896ccd54f28f0cccc" dependencies = [ "cfg-if", "cpufeatures", @@ -516,7 +516,7 @@ dependencies = [ [[package]] name = "sha3" version = "0.11.0-pre.4" -source = "git+https://github.com/RustCrypto/hashes.git?branch=edition_upgrade#cfe82a0f1a9a6c89c5b6d8309f2603c644dc97ea" +source = "git+https://github.com/RustCrypto/hashes#479ad0b5b48bc6044aa10a9896ccd54f28f0cccc" dependencies = [ "digest 0.11.0-pre.10 (registry+https://github.com/rust-lang/crates.io-index)", "keccak", diff --git a/Cargo.toml b/Cargo.toml index bc4d58826..583ea8839 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,9 +18,8 @@ members = [ [patch.crates-io] signature = { path = "signature" } -# https://github.com/RustCrypto/hashes/pull/652 -sha2 = { git = "https://github.com/RustCrypto/hashes.git", branch = "edition_upgrade" } -sha3 = { git = "https://github.com/RustCrypto/hashes.git", branch = "edition_upgrade" } +sha2 = { git = "https://github.com/RustCrypto/hashes" } +sha3 = { git = "https://github.com/RustCrypto/hashes" } # https://github.com/RustCrypto/MACs/pull/178 hmac = { git = "https://github.com/baloo/MACs.git", branch = "baloo/edition-2024" } From 76e6c2f1f361aeaf9b4c4444dc512282ab312373 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Mon, 24 Feb 2025 17:07:40 +0300 Subject: [PATCH 1294/1461] Fix build badges (#1770) --- aead/README.md | 4 ++-- async-signature/README.md | 4 ++-- cipher/README.md | 4 ++-- crypto-common/README.md | 4 ++-- crypto/README.md | 4 ++-- digest/README.md | 4 ++-- elliptic-curve/README.md | 4 ++-- kem/README.md | 4 ++-- password-hash/README.md | 4 ++-- signature/README.md | 4 ++-- signature_derive/README.md | 14 +++++++------- universal-hash/README.md | 4 ++-- 12 files changed, 29 insertions(+), 29 deletions(-) diff --git a/aead/README.md b/aead/README.md index a775d428c..acc1ad778 100644 --- a/aead/README.md +++ b/aead/README.md @@ -45,8 +45,8 @@ dual licensed as above, without any additional terms or conditions. [rustc-image]: https://img.shields.io/badge/rustc-1.85+-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/traits/workflows/aead/badge.svg?branch=master&event=push -[build-link]: https://github.com/RustCrypto/traits/actions?query=workflow%3Aaead +[build-image]: https://github.com/RustCrypto/traits/actions/workflows/aead.yml/badge.svg?branch=master +[build-link]: https://github.com/RustCrypto/traits/actions/workflows/aead.yml?query=branch:master [//]: # (general links) diff --git a/async-signature/README.md b/async-signature/README.md index 5c3fbe08e..13fbf3c13 100644 --- a/async-signature/README.md +++ b/async-signature/README.md @@ -36,6 +36,6 @@ dual licensed as above, without any additional terms or conditions. [rustc-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260048-signatures -[build-image]: https://github.com/RustCrypto/traits/workflows/async-signature/badge.svg?branch=master&event=push -[build-link]: https://github.com/RustCrypto/traits/actions?query=workflow:async-signature +[build-image]: https://github.com/RustCrypto/traits/actions/workflows/async-signature.yml/badge.svg?branch=master +[build-link]: https://github.com/RustCrypto/traits/actions/workflows/async-signature.yml?query=branch:master [signature-crate]: https://crates.io/crates/signature diff --git a/cipher/README.md b/cipher/README.md index 217e5b909..310b0b3b6 100644 --- a/cipher/README.md +++ b/cipher/README.md @@ -42,8 +42,8 @@ dual licensed as above, without any additional terms or conditions. [rustc-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260050-traits -[build-image]: https://github.com/RustCrypto/traits/workflows/cipher/badge.svg?branch=master&event=push -[build-link]: https://github.com/RustCrypto/traits/actions?query=workflow:cipher +[build-image]: https://github.com/RustCrypto/traits/actions/workflows/cipher.yml/badge.svg?branch=master +[build-link]: https://github.com/RustCrypto/traits/actions/workflows/cipher.yml?query=branch:master [//]: # (general links) diff --git a/crypto-common/README.md b/crypto-common/README.md index afe814106..456d865ec 100644 --- a/crypto-common/README.md +++ b/crypto-common/README.md @@ -40,5 +40,5 @@ dual licensed as above, without any additional terms or conditions. [rustc-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260041-hashes -[build-image]: https://github.com/RustCrypto/traits/workflows/crypto-common/badge.svg?branch=master&event=push -[build-link]: https://github.com/RustCrypto/traits/actions?query=workflow%3Acrypto-common +[build-image]: https://github.com/RustCrypto/traits/actions/workflows/crypto-common.yml/badge.svg?branch=master +[build-link]: https://github.com/RustCrypto/traits/actions/workflows/crypto-common.yml?query=branch:master diff --git a/crypto/README.md b/crypto/README.md index 5041bc108..8f23eeca0 100644 --- a/crypto/README.md +++ b/crypto/README.md @@ -80,8 +80,8 @@ dual licensed as above, without any additional terms or conditions. [rustc-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260050-Traits -[build-image]: https://github.com/RustCrypto/traits/workflows/crypto/badge.svg?branch=master&event=push -[build-link]: https://github.com/RustCrypto/traits/actions?query=workflow:crypto +[build-image]: https://github.com/RustCrypto/traits/actions/workflows/crypto.yml/badge.svg?branch=master +[build-link]: https://github.com/RustCrypto/traits/actions/workflows/crypto.yml?query=branch:master [//]: # (footnotes) diff --git a/digest/README.md b/digest/README.md index e88f5ca88..5038829ad 100644 --- a/digest/README.md +++ b/digest/README.md @@ -136,8 +136,8 @@ dual licensed as above, without any additional terms or conditions. [rustc-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260041-hashes -[build-image]: https://github.com/RustCrypto/traits/workflows/digest/badge.svg?branch=master&event=push -[build-link]: https://github.com/RustCrypto/traits/actions?query=workflow%3Adigest +[build-image]: https://github.com/RustCrypto/traits/actions/workflows/digest.yml/badge.svg?branch=master +[build-link]: https://github.com/RustCrypto/traits/actions/workflows/digest.yml?query=branch:master [//]: # (general links) diff --git a/elliptic-curve/README.md b/elliptic-curve/README.md index a89c195d4..3148a8c1b 100644 --- a/elliptic-curve/README.md +++ b/elliptic-curve/README.md @@ -32,8 +32,8 @@ dual licensed as above, without any additional terms or conditions. [crate-link]: https://crates.io/crates/elliptic-curve [docs-image]: https://docs.rs/elliptic-curve/badge.svg [docs-link]: https://docs.rs/elliptic-curve/ -[build-image]: https://github.com/RustCrypto/traits/actions/workflows/elliptic-curve.yml/badge.svg -[build-link]: https://github.com/RustCrypto/traits/actions/workflows/elliptic-curve.yml +[build-image]: https://github.com/RustCrypto/traits/actions/workflows/elliptic-curve.yml/badge.svg?branch=master +[build-link]: https://github.com/RustCrypto/traits/actions/workflows/elliptic-curve.yml?query=branch:master [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg [rustc-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg diff --git a/kem/README.md b/kem/README.md index 4ee06756e..9189f39e9 100644 --- a/kem/README.md +++ b/kem/README.md @@ -95,8 +95,8 @@ dual licensed as above, without any additional terms or conditions. [rustc-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260048-signatures -[build-image]: https://github.com/RustCrypto/traits/workflows/kem/badge.svg?branch=master&event=push -[build-link]: https://github.com/RustCrypto/traits/actions?query=workflow%3Akem +[build-image]: https://github.com/RustCrypto/traits/actions/workflows/kem.yml/badge.svg?branch=master +[build-link]: https://github.com/RustCrypto/traits/actions/workflows/kem.yml?query=branch:master [//]: # (links) diff --git a/password-hash/README.md b/password-hash/README.md index f7bc6e858..eaf223b5f 100644 --- a/password-hash/README.md +++ b/password-hash/README.md @@ -46,8 +46,8 @@ dual licensed as above, without any additional terms or conditions. [crate-link]: https://crates.io/crates/password-hash [docs-image]: https://docs.rs/password-hash/badge.svg [docs-link]: https://docs.rs/password-hash/ -[build-image]: https://github.com/RustCrypto/traits/workflows/password-hash/badge.svg?branch=master&event=push -[build-link]: https://github.com/RustCrypto/traits/actions?query=workflow:password-hash +[build-image]: https://github.com/RustCrypto/traits/actions/workflows/password-hash.yml/badge.svg?branch=master +[build-link]: https://github.com/RustCrypto/traits/actions/workflows/password-hash.yml?query=branch:master [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg [rustc-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg diff --git a/signature/README.md b/signature/README.md index 4e3cef37c..d64841bde 100644 --- a/signature/README.md +++ b/signature/README.md @@ -41,8 +41,8 @@ dual licensed as above, without any additional terms or conditions. [crate-link]: https://crates.io/crates/signature [docs-image]: https://docs.rs/signature/badge.svg [docs-link]: https://docs.rs/signature/ -[build-image]: https://github.com/RustCrypto/traits/actions/workflows/signature.yml/badge.svg -[build-link]: https://github.com/RustCrypto/traits/actions/workflows/signature.yml +[build-image]: https://github.com/RustCrypto/traits/actions/workflows/signature.yml/badge.svg?branch=master +[build-link]: https://github.com/RustCrypto/traits/actions/workflows/signature.yml?query=branch:master [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg [rustc-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg diff --git a/signature_derive/README.md b/signature_derive/README.md index 1be2391d0..74cd7871b 100644 --- a/signature_derive/README.md +++ b/signature_derive/README.md @@ -29,13 +29,13 @@ dual licensed as above, without any additional terms or conditions. [//]: # (badges) -[crate-image]: https://img.shields.io/crates/v/password-hash -[crate-link]: https://crates.io/crates/password-hash -[docs-image]: https://docs.rs/password-hash/badge.svg -[docs-link]: https://docs.rs/password-hash/ -[build-image]: https://github.com/RustCrypto/traits/workflows/password-hash/badge.svg?branch=master&event=push -[build-link]: https://github.com/RustCrypto/traits/actions?query=workflow:password-hash +[crate-image]: https://img.shields.io/crates/v/signature_derive +[crate-link]: https://crates.io/crates/signature_derive +[docs-image]: https://docs.rs/signature_derive/badge.svg +[docs-link]: https://docs.rs/signature_derive/ +[build-image]: https://github.com/RustCrypto/traits/actions/workflows/signature_derive.yml/badge.svg?branch=master +[build-link]: https://github.com/RustCrypto/traits/actions/workflows/signature_derive.yml?query=branch:master [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg [rustc-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg -[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260046-password-hashes +[chat-link]: https://rustcrypto.zulipchat.com/#narrow/channel/260048-signatures diff --git a/universal-hash/README.md b/universal-hash/README.md index 7e34e89eb..7ca8a6927 100644 --- a/universal-hash/README.md +++ b/universal-hash/README.md @@ -36,8 +36,8 @@ dual licensed as above, without any additional terms or conditions. [rustc-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260051-universal-hashes -[build-image]: https://github.com/RustCrypto/traits/workflows/universal-hash/badge.svg?branch=master&event=push -[build-link]: https://github.com/RustCrypto/traits/actions?query=workflow%3Auniversal-hash +[build-image]: https://github.com/RustCrypto/traits/actions/workflows/universal-hash.yml/badge.svg?branch=master +[build-link]: https://github.com/RustCrypto/traits/actions/workflows/universal-hash.yml?query=branch:master [//]: # (general links) From 8c1a1d0e385b37ebba56bbc1e2158c1052cc45d0 Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Mon, 24 Feb 2025 16:46:18 +0000 Subject: [PATCH 1295/1461] Patch `hmac` from RustCrypto/MACs (#1771) --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b20d0a465..e25126e95 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -309,7 +309,7 @@ dependencies = [ [[package]] name = "hmac" version = "0.13.0-pre.4" -source = "git+https://github.com/baloo/MACs.git?branch=baloo%2Fedition-2024#cea718c1fcec0504c7ba030a2ad465d7b1881047" +source = "git+https://github.com/RustCrypto/MACs.git#c7cbed0bd3f7026cc01251cd4602d0db4d0495b9" dependencies = [ "digest 0.11.0-pre.10 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/Cargo.toml b/Cargo.toml index 583ea8839..8c3861fb7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ sha2 = { git = "https://github.com/RustCrypto/hashes" } sha3 = { git = "https://github.com/RustCrypto/hashes" } # https://github.com/RustCrypto/MACs/pull/178 -hmac = { git = "https://github.com/baloo/MACs.git", branch = "baloo/edition-2024" } +hmac = { git = "https://github.com/RustCrypto/MACs.git" } # https://github.com/RustCrypto/crypto-bigint/pull/762 # https://github.com/RustCrypto/crypto-bigint/pull/765 From 3fa125f4ec6f7610de112220d38ce40113c18f2c Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 24 Feb 2025 18:54:27 +0000 Subject: [PATCH 1296/1461] digest: bump `const-oid` dependency to v0.10 (#1772) Release notes: https://github.com/RustCrypto/formats/pull/1672 --- Cargo.lock | 4 ++-- digest/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e25126e95..631bb0603 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -117,9 +117,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.10.0-rc.3" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ff6be19477a1bd5441f382916a89bc2a0b2c35db6d41e0f6e8538bf6d6463f" +checksum = "1cb3c4a0d3776f7535c32793be81d6d5fec0d48ac70955d9834e643aa249a52f" [[package]] name = "cpufeatures" diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 938cc21b7..317d2a607 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -19,7 +19,7 @@ crypto-common = { version = "0.2.0-rc.2", path = "../crypto-common" } block-buffer = { version = "0.11.0-rc.4", optional = true } subtle = { version = "2.4", default-features = false, optional = true } blobby = { version = "0.4.0-pre.0", optional = true } -const-oid = { version = "0.10.0-rc.3", optional = true } +const-oid = { version = "0.10", optional = true } zeroize = { version = "1.7", optional = true, default-features = false } [features] From d39ad3012ea1c68f6e515b5aef1ee16adae77a48 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 28 Feb 2025 11:13:36 +0000 Subject: [PATCH 1297/1461] aead: factor apart `AeadInPlace`/`*Detached` (#1714) Factors apart the detached methods of `AeadInPlace` into a separate `AeadInPlaceDetached` trait, which itself can now more easily be further refactored (by adding e.g. `inout` support). Also adds a `PostfixTagged` trait which is used to gate the blanket impls. --- aead/src/lib.rs | 71 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 48 insertions(+), 23 deletions(-) diff --git a/aead/src/lib.rs b/aead/src/lib.rs index 0294b6f48..edc0760a6 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -206,7 +206,7 @@ pub trait Aead: AeadCore { ) -> Result>; } -/// In-place stateless AEAD trait. +/// In-place AEAD trait. /// /// This trait is both object safe and has no dependencies on `alloc` or `std`. pub trait AeadInPlace: AeadCore { @@ -224,13 +224,24 @@ pub trait AeadInPlace: AeadCore { nonce: &Nonce, associated_data: &[u8], buffer: &mut dyn Buffer, - ) -> Result<()> { - let tag = self.encrypt_in_place_detached(nonce, associated_data, buffer.as_mut())?; - buffer.extend_from_slice(tag.as_slice())?; - Ok(()) - } + ) -> Result<()>; + + /// Decrypt the message in-place, returning an error in the event the + /// provided authentication tag does not match the given ciphertext. + /// + /// The buffer will be truncated to the length of the original plaintext + /// message upon success. + fn decrypt_in_place( + &self, + nonce: &Nonce, + associated_data: &[u8], + buffer: &mut dyn Buffer, + ) -> Result<()>; +} - /// Encrypt the data in-place, returning the authentication tag +/// In-place AEAD trait which handles the authentication tag as a return value/separate parameter. +pub trait AeadInPlaceDetached: AeadCore { + /// Encrypt the data in-place, returning the authentication tag. fn encrypt_in_place_detached( &self, nonce: &Nonce, @@ -238,11 +249,36 @@ pub trait AeadInPlace: AeadCore { buffer: &mut [u8], ) -> Result>; - /// Decrypt the message in-place, returning an error in the event the - /// provided authentication tag does not match the given ciphertext. - /// - /// The buffer will be truncated to the length of the original plaintext - /// message upon success. + /// Decrypt the message in-place, returning an error in the event the provided + /// authentication tag does not match the given ciphertext (i.e. ciphertext + /// is modified/unauthentic) + fn decrypt_in_place_detached( + &self, + nonce: &Nonce, + associated_data: &[u8], + buffer: &mut [u8], + tag: &Tag, + ) -> Result<()>; +} + +/// Marker trait for AEAD algorithms which append the authentication tag to the end of the +/// ciphertext message. +/// +/// This is the common convention for AEAD algorithms. +pub trait PostfixTagged {} + +impl AeadInPlace for T { + fn encrypt_in_place( + &self, + nonce: &Nonce, + associated_data: &[u8], + buffer: &mut dyn Buffer, + ) -> Result<()> { + let tag = self.encrypt_in_place_detached(nonce, associated_data, buffer.as_mut())?; + buffer.extend_from_slice(tag.as_slice())?; + Ok(()) + } + fn decrypt_in_place( &self, nonce: &Nonce, @@ -261,17 +297,6 @@ pub trait AeadInPlace: AeadCore { buffer.truncate(tag_pos); Ok(()) } - - /// Decrypt the message in-place, returning an error in the event the provided - /// authentication tag does not match the given ciphertext (i.e. ciphertext - /// is modified/unauthentic) - fn decrypt_in_place_detached( - &self, - nonce: &Nonce, - associated_data: &[u8], - buffer: &mut [u8], - tag: &Tag, - ) -> Result<()>; } #[cfg(feature = "alloc")] From 67c5bf8540a632f0f7a013fe343ec512c310a8fc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Mar 2025 01:12:46 +0300 Subject: [PATCH 1298/1461] build(deps): bump crate-ci/typos from 1.29.4 to 1.30.0 (#1781) --- .github/workflows/workspace.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index 5cf81aa18..ad7e67c33 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -52,4 +52,4 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: crate-ci/typos@v1.29.4 + - uses: crate-ci/typos@v1.30.0 From 27835aa66710bded06caef143284892dda83dda5 Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Tue, 4 Mar 2025 23:08:15 +0000 Subject: [PATCH 1299/1461] elliptic-curve: adds Scalar::try_from_rng method (#1774) Depends: - https://github.com/zkcrypto/ff/pull/126 - https://github.com/zkcrypto/ff/pull/127 This is to provide an `ecdsa::SigningKey::try_from_rng` API (https://github.com/RustCrypto/signatures/pull/915) --- Cargo.lock | 1 - Cargo.toml | 4 +++- elliptic-curve/src/dev.rs | 15 +++++++++++++-- elliptic-curve/src/scalar/nonzero.rs | 20 ++++++++++++++++---- 4 files changed, 32 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 631bb0603..1a2f3ae29 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -237,7 +237,6 @@ dependencies = [ [[package]] name = "ff" version = "0.13.0" -source = "git+https://github.com/pinkforest/ff.git?branch=bump-rand-core#c734f7f21d6639bc6494dde538209d0770207c49" dependencies = [ "bitvec", "rand_core", diff --git a/Cargo.toml b/Cargo.toml index 8c3861fb7..04a65869c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,9 @@ hmac = { git = "https://github.com/RustCrypto/MACs.git" } crypto-bigint = { git = "https://github.com/RustCrypto/crypto-bigint.git" } # https://github.com/zkcrypto/ff/pull/122 -ff = { git = "https://github.com/pinkforest/ff.git", branch = "bump-rand-core" } +# https://github.com/zkcrypto/ff/pull/126 +# https://github.com/zkcrypto/ff/pull/127 +ff = { git = "https://github.com/baloo/ff.git", branch = "baloo/try_from_rng" } # https://github.com/zkcrypto/group/pull/56 group = { git = "https://github.com/pinkforest/group.git", branch = "bump-rand-0.9" } diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 567c97f4f..26b14d902 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -10,7 +10,7 @@ use crate::{ error::{Error, Result}, ops::{Invert, LinearCombination, MulByGenerator, Reduce, ShrAssign}, point::AffineCoordinates, - rand_core::RngCore, + rand_core::{RngCore, TryRngCore}, scalar::{FromUintUnchecked, IsHigh}, sec1::{CompressedPoint, FromEncodedPoint, ToEncodedPoint}, subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}, @@ -99,7 +99,7 @@ impl Field for Scalar { const ZERO: Self = Self(ScalarPrimitive::ZERO); const ONE: Self = Self(ScalarPrimitive::ONE); - fn random(mut rng: impl RngCore) -> Self { + fn random(rng: &mut R) -> Self { let mut bytes = FieldBytes::default(); loop { @@ -110,6 +110,17 @@ impl Field for Scalar { } } + fn try_from_rng(rng: &mut R) -> core::result::Result { + let mut bytes = FieldBytes::default(); + + loop { + rng.try_fill_bytes(&mut bytes)?; + if let Some(scalar) = Self::from_repr(bytes).into() { + return Ok(scalar); + } + } + } + fn is_zero(&self) -> Choice { self.0.is_zero() } diff --git a/elliptic-curve/src/scalar/nonzero.rs b/elliptic-curve/src/scalar/nonzero.rs index 88f82a8a2..06e39b4de 100644 --- a/elliptic-curve/src/scalar/nonzero.rs +++ b/elliptic-curve/src/scalar/nonzero.rs @@ -13,7 +13,7 @@ use core::{ }; use crypto_bigint::{ArrayEncoding, Integer}; use ff::{Field, PrimeField}; -use rand_core::CryptoRng; +use rand_core::{CryptoRng, TryCryptoRng}; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; use zeroize::Zeroize; @@ -47,19 +47,31 @@ where C: CurveArithmetic, { /// Generate a random `NonZeroScalar`. - pub fn random(mut rng: &mut R) -> Self { + pub fn random(rng: &mut R) -> Self { // Use rejection sampling to eliminate zero values. // While this method isn't constant-time, the attacker shouldn't learn // anything about unrelated outputs so long as `rng` is a secure `CryptoRng`. loop { // TODO: remove after `Field::random` switches to `&mut impl RngCore` - #[allow(clippy::needless_borrows_for_generic_args)] - if let Some(result) = Self::new(Field::random(&mut rng)).into() { + if let Some(result) = Self::new(Field::random(rng)).into() { break result; } } } + /// Generate a random `NonZeroScalar`. + pub fn try_from_rng(rng: &mut R) -> Result { + // Use rejection sampling to eliminate zero values. + // While this method isn't constant-time, the attacker shouldn't learn + // anything about unrelated outputs so long as `rng` is a secure `CryptoRng`. + loop { + // TODO: remove after `Field::random` switches to `&mut impl RngCore` + if let Some(result) = Self::new(Scalar::::try_from_rng(rng)?).into() { + break Ok(result); + } + } + } + /// Create a [`NonZeroScalar`] from a scalar. pub fn new(scalar: Scalar) -> CtOption { CtOption::new(Self { scalar }, !scalar.is_zero()) From 1548d2a7d7ce71a278a783d19d94b59b0103ab15 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Wed, 5 Mar 2025 20:07:56 +0300 Subject: [PATCH 1300/1461] password-hash: add `Error::OutOfMemory` variant (#1782) --- password-hash/src/errors.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/password-hash/src/errors.rs b/password-hash/src/errors.rs index 11efd67bb..ff5b09843 100644 --- a/password-hash/src/errors.rs +++ b/password-hash/src/errors.rs @@ -63,6 +63,9 @@ pub enum Error { /// Invalid algorithm version. Version, + + /// Out of memory (heap allocation failure). + OutOfMemory, } impl fmt::Display for Error { @@ -95,6 +98,7 @@ impl fmt::Display for Error { } Self::SaltInvalid(val_err) => write!(f, "salt invalid: {}", val_err), Self::Version => write!(f, "invalid algorithm version"), + Self::OutOfMemory => write!(f, "out of memory"), } } } From f9a24b039baca8a40328f107b178868b45f24b73 Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Sun, 9 Mar 2025 13:54:38 +0000 Subject: [PATCH 1301/1461] move ff back to release branch (#1788) see https://github.com/zkcrypto/ff/pull/130 --- .github/workflows/cipher.yml | 1 + .github/workflows/crypto.yml | 1 + .github/workflows/password-hash.yml | 1 + Cargo.lock | 75 ++++++++++++++++++++++++++--- Cargo.toml | 5 +- elliptic-curve/Cargo.toml | 4 +- signature/Cargo.toml | 2 +- 7 files changed, 75 insertions(+), 14 deletions(-) diff --git a/.github/workflows/cipher.yml b/.github/workflows/cipher.yml index f60132124..048b0c562 100644 --- a/.github/workflows/cipher.yml +++ b/.github/workflows/cipher.yml @@ -42,6 +42,7 @@ jobs: # TODO: use the reusable workflow after this crate will be part of the # root workspace minimal-versions: + if: false # disabled until we stop using pre-releases runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/crypto.yml b/.github/workflows/crypto.yml index 7e197e877..e2926600c 100644 --- a/.github/workflows/crypto.yml +++ b/.github/workflows/crypto.yml @@ -39,6 +39,7 @@ jobs: --features aead,cipher,digest,elliptic-curve,signature,universal-hash minimal-versions: + if: false # disabled until we stop using pre-releases runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/password-hash.yml b/.github/workflows/password-hash.yml index 0fe8ef3b4..670fd7e54 100644 --- a/.github/workflows/password-hash.yml +++ b/.github/workflows/password-hash.yml @@ -41,6 +41,7 @@ jobs: # TODO: use the reusable workflow after this crate will be part of the # toot workspace minimal-versions: + if: false # disabled until we stop using pre-releases runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 diff --git a/Cargo.lock b/Cargo.lock index 1a2f3ae29..c9aede1b9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,17 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "addchain" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b2e69442aa5628ea6951fa33e24efe8313f4321a91bd729fc2f75bdfc858570" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + [[package]] name = "aead" version = "0.6.0-rc.0" @@ -237,12 +248,29 @@ dependencies = [ [[package]] name = "ff" version = "0.13.0" +source = "git+https://github.com/zkcrypto/ff.git?branch=release-0.14.0#1bb634588722b1b7ce986d239c263e332bedda7f" dependencies = [ "bitvec", + "ff_derive", "rand_core", "subtle", ] +[[package]] +name = "ff_derive" +version = "0.13.0" +source = "git+https://github.com/zkcrypto/ff.git?branch=release-0.14.0#1bb634588722b1b7ce986d239c263e332bedda7f" +dependencies = [ + "addchain", + "cfg-if", + "num-bigint", + "num-integer", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "funty" version = "2.0.0" @@ -368,6 +396,26 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +[[package]] +name = "num-bigint" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f6f7833f2cbf2360a6cfd58cd41a53aa7a90bd4c202f5b1c7dd2ed73c57b2c3" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -477,7 +525,7 @@ checksum = "f09503e191f4e797cb8aac08e9a4a4695c5edf6a2e70e376d961ddd5c969f82b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.98", ] [[package]] @@ -504,8 +552,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.11.0-pre.4" -source = "git+https://github.com/RustCrypto/hashes#479ad0b5b48bc6044aa10a9896ccd54f28f0cccc" +version = "0.11.0-pre.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b4241d1a56954dce82cecda5c8e9c794eef6f53abe5e5216bac0a0ea71ffa7" dependencies = [ "cfg-if", "cpufeatures", @@ -514,8 +563,9 @@ dependencies = [ [[package]] name = "sha3" -version = "0.11.0-pre.4" -source = "git+https://github.com/RustCrypto/hashes#479ad0b5b48bc6044aa10a9896ccd54f28f0cccc" +version = "0.11.0-pre.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bc997d7a5fa67cc1e352b2001124d28edb948b4e7a16567f9b3c1e51952524" dependencies = [ "digest 0.11.0-pre.10 (registry+https://github.com/rust-lang/crates.io-index)", "keccak", @@ -538,7 +588,7 @@ version = "2.2.0" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.98", ] [[package]] @@ -563,6 +613,17 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "syn" version = "2.0.98" @@ -708,7 +769,7 @@ checksum = "eea57037071898bf96a6da35fd626f4f27e9cee3ead2a6c703cf09d472b2e700" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.98", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 04a65869c..21a734666 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,9 +18,6 @@ members = [ [patch.crates-io] signature = { path = "signature" } -sha2 = { git = "https://github.com/RustCrypto/hashes" } -sha3 = { git = "https://github.com/RustCrypto/hashes" } - # https://github.com/RustCrypto/MACs/pull/178 hmac = { git = "https://github.com/RustCrypto/MACs.git" } @@ -31,7 +28,7 @@ crypto-bigint = { git = "https://github.com/RustCrypto/crypto-bigint.git" } # https://github.com/zkcrypto/ff/pull/122 # https://github.com/zkcrypto/ff/pull/126 # https://github.com/zkcrypto/ff/pull/127 -ff = { git = "https://github.com/baloo/ff.git", branch = "baloo/try_from_rng" } +ff = { git = "https://github.com/zkcrypto/ff.git", branch = "release-0.14.0" } # https://github.com/zkcrypto/group/pull/56 group = { git = "https://github.com/pinkforest/group.git", branch = "bump-rand-0.9" } diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index b5c0915e0..ec79dad51 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -40,8 +40,8 @@ tap = { version = "1.0.1", optional = true, default-features = false } # hack fo [dev-dependencies] hex-literal = "1" -sha2 = "=0.11.0-pre.4" -sha3 = "=0.11.0-pre.4" +sha2 = "=0.11.0-pre.5" +sha3 = "=0.11.0-pre.5" [features] default = ["arithmetic"] diff --git a/signature/Cargo.toml b/signature/Cargo.toml index c8a0047dd..0f1e3dae7 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -20,7 +20,7 @@ rand_core = { version = "0.9", optional = true, default-features = false } [dev-dependencies] hex-literal = "1" -sha2 = { version = "=0.11.0-pre.4", default-features = false } +sha2 = { version = "=0.11.0-pre.5", default-features = false } [features] alloc = [] From ea9b99a8444d1fdd98d72ff671f55e2fb2a1116b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 9 Mar 2025 20:35:12 +0300 Subject: [PATCH 1302/1461] build(deps): bump hkdf from 0.13.0-pre.4 to 0.13.0-pre.5 (#1786) --- Cargo.lock | 14 ++++++++++---- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c9aede1b9..972a00a21 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -326,17 +326,18 @@ checksum = "bcaaec4551594c969335c98c903c1397853d4198408ea609190f420500f6be71" [[package]] name = "hkdf" -version = "0.13.0-pre.4" +version = "0.13.0-pre.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00176ff81091018d42ff82e8324f8e5adb0b7e0468d1358f653972562dbff031" +checksum = "0aaa7579d1176645cee5dc206aa74873b5b3be479af9606025f9b8905bcf597b" dependencies = [ "hmac", ] [[package]] name = "hmac" -version = "0.13.0-pre.4" -source = "git+https://github.com/RustCrypto/MACs.git#c7cbed0bd3f7026cc01251cd4602d0db4d0495b9" +version = "0.13.0-pre.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62c11fc82c6b89c906b4d26b7b5a305d0b3aebd4b458dd1bd0a7ed98c548a28e" dependencies = [ "digest 0.11.0-pre.10 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -777,3 +778,8 @@ name = "zeroize" version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" + +[[patch.unused]] +name = "hmac" +version = "0.13.0-pre.4" +source = "git+https://github.com/RustCrypto/MACs.git#c7cbed0bd3f7026cc01251cd4602d0db4d0495b9" diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index ec79dad51..ccadfdc3e 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -29,7 +29,7 @@ base64ct = { version = "1", optional = true, default-features = false, features digest = { version = "=0.11.0-pre.10", optional = true } ff = { version = "0.13", optional = true, default-features = false } group = { version = "0.13", optional = true, default-features = false } -hkdf = { version = "=0.13.0-pre.4", optional = true, default-features = false } +hkdf = { version = "=0.13.0-pre.5", optional = true, default-features = false } hex-literal = { version = "1", optional = true } pem-rfc7468 = { version = "1.0.0-rc.2", optional = true, features = ["alloc"] } pkcs8 = { version = "0.11.0-rc.1", optional = true, default-features = false } From bd209960fa1cf9d5627a6045028b857675e279bd Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Sun, 9 Mar 2025 23:06:40 +0000 Subject: [PATCH 1303/1461] elliptic-curve:: adds `try_from_rng` method to `SecretKey` and `EphemeralSecret` (#1789) Follow up to https://github.com/RustCrypto/traits/pull/1774 --- elliptic-curve/src/dev.rs | 11 ----------- elliptic-curve/src/ecdh.rs | 9 ++++++++- elliptic-curve/src/secret_key.rs | 18 +++++++++++++++++- 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 26b14d902..4f1c58811 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -99,17 +99,6 @@ impl Field for Scalar { const ZERO: Self = Self(ScalarPrimitive::ZERO); const ONE: Self = Self(ScalarPrimitive::ONE); - fn random(rng: &mut R) -> Self { - let mut bytes = FieldBytes::default(); - - loop { - rng.fill_bytes(&mut bytes); - if let Some(scalar) = Self::from_repr(bytes).into() { - return scalar; - } - } - } - fn try_from_rng(rng: &mut R) -> core::result::Result { let mut bytes = FieldBytes::default(); diff --git a/elliptic-curve/src/ecdh.rs b/elliptic-curve/src/ecdh.rs index c4881fe6e..baf4d9a98 100644 --- a/elliptic-curve/src/ecdh.rs +++ b/elliptic-curve/src/ecdh.rs @@ -34,7 +34,7 @@ use core::{borrow::Borrow, fmt}; use digest::{Digest, crypto_common::BlockSizeUser}; use group::Curve as _; use hkdf::{Hkdf, hmac::SimpleHmac}; -use rand_core::CryptoRng; +use rand_core::{CryptoRng, TryCryptoRng}; use zeroize::{Zeroize, ZeroizeOnDrop}; /// Low-level Elliptic Curve Diffie-Hellman (ECDH) function. @@ -114,6 +114,13 @@ where } } + /// Generate a cryptographically random [`EphemeralSecret`]. + pub fn try_from_rng(rng: &mut R) -> Result { + Ok(Self { + scalar: NonZeroScalar::try_from_rng(rng)?, + }) + } + /// Get the public key associated with this ephemeral secret. /// /// The `compress` flag enables point compression. diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 02f9778e8..1c15dc797 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -15,7 +15,10 @@ use subtle::{Choice, ConstantTimeEq}; use zeroize::{Zeroize, ZeroizeOnDrop, Zeroizing}; #[cfg(feature = "arithmetic")] -use crate::{CurveArithmetic, NonZeroScalar, PublicKey, rand_core::CryptoRng}; +use crate::{ + CurveArithmetic, NonZeroScalar, PublicKey, + rand_core::{CryptoRng, TryCryptoRng}, +}; #[cfg(feature = "jwk")] use crate::jwk::{JwkEcKey, JwkParameters}; @@ -100,6 +103,19 @@ where } } + /// Generate a random [`SecretKey`]. + #[cfg(feature = "arithmetic")] + pub fn try_from_rng( + rng: &mut R, + ) -> core::result::Result + where + C: CurveArithmetic, + { + Ok(Self { + inner: NonZeroScalar::::try_from_rng(rng)?.into(), + }) + } + /// Create a new secret key from a scalar value. pub fn new(scalar: ScalarPrimitive) -> Self { Self { inner: scalar } From 266b044bf30cd74feda3a715b7211c457d5eaba3 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Mon, 10 Mar 2025 17:12:41 +0300 Subject: [PATCH 1304/1461] Use the standard order of the `[package]` section fields (#1773) --- aead/Cargo.toml | 12 ++++++------ async-signature/Cargo.toml | 11 +++++------ cipher/Cargo.toml | 6 +++--- crypto-common/Cargo.toml | 6 +++--- crypto/Cargo.toml | 10 +++++----- digest/Cargo.toml | 6 +++--- elliptic-curve/Cargo.toml | 18 +++++++++--------- kem/Cargo.toml | 11 +++++------ password-hash/Cargo.toml | 19 +++++++++---------- signature/Cargo.toml | 11 +++++------ signature_derive/Cargo.toml | 23 +++++++++++------------ universal-hash/Cargo.toml | 6 +++--- 12 files changed, 67 insertions(+), 72 deletions(-) diff --git a/aead/Cargo.toml b/aead/Cargo.toml index 6259fcfc6..66a4ae464 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -1,19 +1,19 @@ [package] name = "aead" version = "0.6.0-rc.0" -description = """ -Traits for Authenticated Encryption with Associated Data (AEAD) algorithms, -such as AES-GCM as ChaCha20Poly1305, which provide a high-level API -""" authors = ["RustCrypto Developers"] -license = "MIT OR Apache-2.0" -readme = "README.md" edition = "2024" rust-version = "1.85" documentation = "https://docs.rs/aead" +readme = "README.md" repository = "https://github.com/RustCrypto/traits" +license = "MIT OR Apache-2.0" keywords = ["crypto", "encryption"] categories = ["cryptography", "no-std"] +description = """ +Traits for Authenticated Encryption with Associated Data (AEAD) algorithms, +such as AES-GCM as ChaCha20Poly1305, which provide a high-level API +""" [dependencies] crypto-common = { version = "0.2.0-rc.1", path = "../crypto-common" } diff --git a/async-signature/Cargo.toml b/async-signature/Cargo.toml index 18bc0d095..dd25ff887 100644 --- a/async-signature/Cargo.toml +++ b/async-signature/Cargo.toml @@ -1,17 +1,16 @@ [package] name = "async-signature" -description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" version = "0.6.0-pre.4" authors = ["RustCrypto Developers"] -license = "Apache-2.0 OR MIT" +edition = "2024" +rust-version = "1.85" documentation = "https://docs.rs/async-signature" -homepage = "https://github.com/RustCrypto/traits/tree/master/async-signature" -repository = "https://github.com/RustCrypto/traits" readme = "README.md" +repository = "https://github.com/RustCrypto/traits" +license = "Apache-2.0 OR MIT" keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"] categories = ["cryptography", "no-std"] -edition = "2024" -rust-version = "1.85" +description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" [dependencies] signature = "=2.3.0-pre.6" diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index 79bb3c59b..b59bd1513 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -1,16 +1,16 @@ [package] name = "cipher" -description = "Traits for describing block ciphers and stream ciphers" version = "0.5.0-pre.8" authors = ["RustCrypto Developers"] -license = "MIT OR Apache-2.0" -readme = "README.md" edition = "2024" rust-version = "1.85" documentation = "https://docs.rs/cipher" +readme = "README.md" repository = "https://github.com/RustCrypto/traits" +license = "MIT OR Apache-2.0" keywords = ["crypto", "block-cipher", "stream-cipher", "trait"] categories = ["cryptography", "no-std"] +description = "Traits for describing block ciphers and stream ciphers" [dependencies] crypto-common = { version = "0.2.0-rc.2", path = "../crypto-common" } diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index 43d455b7c..84df0c67e 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -1,16 +1,16 @@ [package] name = "crypto-common" -description = "Common cryptographic traits" version = "0.2.0-rc.2" authors = ["RustCrypto Developers"] -license = "MIT OR Apache-2.0" -readme = "README.md" edition = "2024" rust-version = "1.85" documentation = "https://docs.rs/crypto-common" +readme = "README.md" repository = "https://github.com/RustCrypto/traits" +license = "MIT OR Apache-2.0" keywords = ["crypto", "traits"] categories = ["cryptography", "no-std"] +description = "Common cryptographic traits" [dependencies] hybrid-array = "0.3" diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 855af57ed..6aa12dd93 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -1,16 +1,16 @@ [package] name = "crypto" version = "0.6.0-pre" -description = "Facade crate for all of the RustCrypto traits (e.g. `aead`, `cipher`, `digest`)" authors = ["The RustCrypto Project Developers"] -license = "Apache-2.0 OR MIT" +edition = "2024" +rust-version = "1.85" documentation = "https://docs.rs/crypto" +readme = "README.md" repository = "https://github.com/RustCrypto/traits" +license = "Apache-2.0 OR MIT" keywords = ["crypto", "encryption", "rustcrypto"] categories = ["cryptography", "no-std"] -readme = "README.md" -edition = "2024" -rust-version = "1.85" +description = "Facade crate for all of the RustCrypto traits (e.g. `aead`, `cipher`, `digest`)" [dependencies] crypto-common = { version = "0.2.0-rc.1", path = "../crypto-common", default-features = false } diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 317d2a607..9f277b796 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -1,16 +1,16 @@ [package] name = "digest" -description = "Traits for cryptographic hash functions and message authentication codes" version = "0.11.0-pre.10" authors = ["RustCrypto Developers"] -license = "MIT OR Apache-2.0" -readme = "README.md" edition = "2024" rust-version = "1.85" documentation = "https://docs.rs/digest" +readme = "README.md" repository = "https://github.com/RustCrypto/traits" +license = "MIT OR Apache-2.0" keywords = ["digest", "crypto", "hash"] categories = ["cryptography", "no-std"] +description = "Traits for cryptographic hash functions and message authentication codes" [dependencies] crypto-common = { version = "0.2.0-rc.2", path = "../crypto-common" } diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index ccadfdc3e..f607a2c38 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,20 +1,20 @@ [package] name = "elliptic-curve" version = "0.14.0-rc.1" +authors = ["RustCrypto Developers"] +edition = "2024" +rust-version = "1.85" +documentation = "https://docs.rs/elliptic-curve" +readme = "README.md" +repository = "https://github.com/RustCrypto/traits" +license = "Apache-2.0 OR MIT" +categories = ["cryptography", "no-std"] +keywords = ["crypto", "ecc", "elliptic", "weierstrass"] description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. """ -authors = ["RustCrypto Developers"] -license = "Apache-2.0 OR MIT" -homepage = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve" -repository = "https://github.com/RustCrypto/traits" -readme = "README.md" -categories = ["cryptography", "no-std"] -keywords = ["crypto", "ecc", "elliptic", "weierstrass"] -edition = "2024" -rust-version = "1.85" [dependencies] base16ct = "0.2" diff --git a/kem/Cargo.toml b/kem/Cargo.toml index eb396b17c..4ffbf627e 100644 --- a/kem/Cargo.toml +++ b/kem/Cargo.toml @@ -1,17 +1,16 @@ [package] -name = "kem" description = "Traits for key encapsulation mechanisms" version = "0.3.0-pre.0" authors = ["RustCrypto Developers"] -license = "Apache-2.0 OR MIT" +edition = "2024" +rust-version = "1.85" documentation = "https://docs.rs/kem" -homepage = "https://github.com/RustCrypto/traits/tree/master/kem" -repository = "https://github.com/RustCrypto/traits" readme = "README.md" +repository = "https://github.com/RustCrypto/traits" +license = "Apache-2.0 OR MIT" keywords = ["crypto"] categories = ["cryptography", "no-std"] -edition = "2024" -rust-version = "1.85" +name = "kem" [dependencies] rand_core = "0.9" diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index 3abcbca1b..7319b7dd7 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -1,21 +1,20 @@ [package] name = "password-hash" -description = """ -Traits which describe the functionality of password hashing algorithms, -as well as a `no_std`-friendly implementation of the PHC string format -(a well-defined subset of the Modular Crypt Format a.k.a. MCF) -""" version = "0.6.0-rc.0" authors = ["RustCrypto Developers"] -license = "MIT OR Apache-2.0" -readme = "README.md" +edition = "2024" +rust-version = "1.85" documentation = "https://docs.rs/password-hash" -homepage = "https://github.com/RustCrypto/traits/tree/master/password-hash" +readme = "README.md" repository = "https://github.com/RustCrypto/traits" +license = "MIT OR Apache-2.0" categories = ["authentication", "cryptography", "no-std"] keywords = ["crypt", "mcf", "password", "pbkdf", "phc"] -edition = "2024" -rust-version = "1.85" +description = """ +Traits which describe the functionality of password hashing algorithms, +as well as a `no_std`-friendly implementation of the PHC string format +(a well-defined subset of the Modular Crypt Format a.k.a. MCF) +""" [dependencies] base64ct = "1.6" diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 0f1e3dae7..38fe3fea3 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,17 +1,16 @@ [package] name = "signature" -description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" version = "2.3.0-pre.6" authors = ["RustCrypto Developers"] -license = "Apache-2.0 OR MIT" +edition = "2024" +rust-version = "1.85" documentation = "https://docs.rs/signature" -homepage = "https://github.com/RustCrypto/traits/tree/master/signature" -repository = "https://github.com/RustCrypto/traits" readme = "README.md" +repository = "https://github.com/RustCrypto/traits" +license = "Apache-2.0 OR MIT" keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"] categories = ["cryptography", "no-std"] -edition = "2024" -rust-version = "1.85" +description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" [dependencies] derive = { package = "signature_derive", version = "2", optional = true, path = "../signature_derive" } diff --git a/signature_derive/Cargo.toml b/signature_derive/Cargo.toml index e5d8134ea..205bfdff6 100644 --- a/signature_derive/Cargo.toml +++ b/signature_derive/Cargo.toml @@ -1,17 +1,16 @@ [package] -name = "signature_derive" -version = "2.2.0" -authors = ["RustCrypto Developers"] -license = "Apache-2.0 OR MIT" -description = "Custom derive support for the 'signature' crate" +name = "signature_derive" +version = "2.2.0" +authors = ["RustCrypto Developers"] +edition = "2024" +rust-version = "1.85" documentation = "https://docs.rs/signature" -homepage = "https://github.com/RustCrypto/traits/tree/master/signature_derive" -repository = "https://github.com/RustCrypto/traits" -readme = "README.md" -edition = "2024" -rust-version = "1.85" -keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"] -categories = ["cryptography", "no-std"] +readme = "README.md" +repository = "https://github.com/RustCrypto/traits" +license = "Apache-2.0 OR MIT" +keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"] +categories = ["cryptography", "no-std"] +description = "Custom derive support for the 'signature' crate" [lib] proc-macro = true diff --git a/universal-hash/Cargo.toml b/universal-hash/Cargo.toml index bf1993107..22733619d 100644 --- a/universal-hash/Cargo.toml +++ b/universal-hash/Cargo.toml @@ -1,16 +1,16 @@ [package] name = "universal-hash" version = "0.6.0-rc.0" -description = "Traits which describe the functionality of universal hash functions (UHFs)" authors = ["RustCrypto Developers"] -license = "MIT OR Apache-2.0" edition = "2024" rust-version = "1.85" -readme = "README.md" documentation = "https://docs.rs/universal-hash" +readme = "README.md" repository = "https://github.com/RustCrypto/traits" +license = "MIT OR Apache-2.0" keywords = ["crypto", "mac"] categories = ["cryptography", "no-std"] +description = "Traits which describe the functionality of universal hash functions (UHFs)" [dependencies] crypto-common = { version = "0.2.0-rc.1", path = "../crypto-common" } From 7b82f397511d68f823d06a0fe50867e9011dd0f0 Mon Sep 17 00:00:00 2001 From: Sylvain Pelissier Date: Wed, 12 Mar 2025 13:50:14 +0100 Subject: [PATCH 1305/1461] Add hash customization trait for variable output hash (#1787) New trait for customized hash function with variable output `CtVariableCoreWrapper` like Blake2 to implement the `CustomizedInit` trait. --- digest/src/core_api/ct_variable.rs | 17 ++++++++++++++++- digest/src/lib.rs | 6 ++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/digest/src/core_api/ct_variable.rs b/digest/src/core_api/ct_variable.rs index 57a093d98..983f610cd 100644 --- a/digest/src/core_api/ct_variable.rs +++ b/digest/src/core_api/ct_variable.rs @@ -2,9 +2,9 @@ use super::{ AlgorithmName, Buffer, BufferKindUser, FixedOutputCore, Reset, TruncSide, UpdateCore, VariableOutputCore, }; -use crate::HashMarker; #[cfg(feature = "mac")] use crate::MacMarker; +use crate::{CustomizedInit, HashMarker, VarOutputCustomized}; #[cfg(feature = "oid")] use const_oid::{AssociatedOid, ObjectIdentifier}; use core::{ @@ -131,6 +131,21 @@ where } } +impl CustomizedInit for CtVariableCoreWrapper +where + T: VariableOutputCore + VarOutputCustomized, + OutSize: ArraySize + IsLessOrEqual, + LeEq: NonZero, +{ + #[inline] + fn new_customized(customization: &[u8]) -> Self { + Self { + inner: T::new_customized(customization, OutSize::USIZE), + _out: PhantomData, + } + } +} + impl Reset for CtVariableCoreWrapper where T: VariableOutputCore, diff --git a/digest/src/lib.rs b/digest/src/lib.rs index b74ca517e..bd9f3c035 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -274,6 +274,12 @@ pub trait CustomizedInit: Sized { fn new_customized(customization: &[u8]) -> Self; } +/// Trait adding customization string to hash functions with variable output. +pub trait VarOutputCustomized: Sized { + /// Create new hasher instance with the given customization string and output size. + fn new_customized(customization: &[u8], output_size: usize) -> Self; +} + /// The error type used in variable hash traits. #[derive(Clone, Copy, Debug, Default)] pub struct InvalidOutputSize; From 204a4e030fa98863429ccd3797e12f9e7c45dc33 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 12 Mar 2025 11:44:58 -0600 Subject: [PATCH 1306/1461] aead: add `inout` support (#1793) Renames `AeadInPlaceDetached` to `AeadInOut`, and changes the type signature so the provided `buffer` is now an `InOutBuf` --- Cargo.lock | 1 + aead/Cargo.toml | 3 +- aead/src/lib.rs | 89 ++++++++++++++++++++++++++----------------------- 3 files changed, 51 insertions(+), 42 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 972a00a21..33d30686a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -22,6 +22,7 @@ dependencies = [ "bytes", "crypto-common 0.2.0-rc.2", "heapless", + "inout", ] [[package]] diff --git a/aead/Cargo.toml b/aead/Cargo.toml index 66a4ae464..10c425dba 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -23,9 +23,10 @@ arrayvec = { version = "0.7", optional = true, default-features = false } blobby = { version = "0.4.0-pre.0", optional = true } bytes = { version = "1", optional = true, default-features = false } heapless = { version = "0.8", optional = true, default-features = false } +inout = { version = "0.2.0-rc.4", optional = true, default-features = false } [features] -default = ["rand_core"] +default = ["inout", "rand_core"] alloc = [] dev = ["blobby"] os_rng = ["crypto-common/os_rng", "rand_core"] diff --git a/aead/src/lib.rs b/aead/src/lib.rs index edc0760a6..26faef2a3 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -30,21 +30,26 @@ pub use crypto_common::{ pub use arrayvec; #[cfg(feature = "bytes")] pub use bytes; -#[cfg(feature = "heapless")] -pub use heapless; - #[cfg(feature = "rand_core")] pub use crypto_common::rand_core; +#[cfg(feature = "heapless")] +pub use heapless; +#[cfg(feature = "inout")] +pub use inout; use core::fmt; -use crypto_common::array::{Array, ArraySize, typenum::Unsigned}; +use crypto_common::array::{Array, ArraySize}; #[cfg(feature = "alloc")] use alloc::vec::Vec; #[cfg(feature = "bytes")] use bytes::BytesMut; +#[cfg(any(feature = "alloc", feature = "inout"))] +use crypto_common::array::typenum::Unsigned; #[cfg(feature = "os_rng")] use crypto_common::rand_core::{OsError, OsRng, TryRngCore}; +#[cfg(feature = "inout")] +use inout::InOutBuf; #[cfg(feature = "rand_core")] use rand_core::{CryptoRng, TryCryptoRng}; @@ -240,23 +245,24 @@ pub trait AeadInPlace: AeadCore { } /// In-place AEAD trait which handles the authentication tag as a return value/separate parameter. -pub trait AeadInPlaceDetached: AeadCore { - /// Encrypt the data in-place, returning the authentication tag. - fn encrypt_in_place_detached( +#[cfg(feature = "inout")] +pub trait AeadInOut: AeadCore { + /// Encrypt the data in the provided [`InOutBuf`], returning the authentication tag. + fn encrypt_inout_detached( &self, nonce: &Nonce, associated_data: &[u8], - buffer: &mut [u8], + buffer: InOutBuf<'_, '_, u8>, ) -> Result>; - /// Decrypt the message in-place, returning an error in the event the provided - /// authentication tag does not match the given ciphertext (i.e. ciphertext + /// Decrypt the data in the provided [`InOutBuf`], returning an error in the event the + /// provided authentication tag is invalid for the given ciphertext (i.e. ciphertext /// is modified/unauthentic) - fn decrypt_in_place_detached( + fn decrypt_inout_detached( &self, nonce: &Nonce, associated_data: &[u8], - buffer: &mut [u8], + buffer: InOutBuf<'_, '_, u8>, tag: &Tag, ) -> Result<()>; } @@ -267,14 +273,41 @@ pub trait AeadInPlaceDetached: AeadCore { /// This is the common convention for AEAD algorithms. pub trait PostfixTagged {} -impl AeadInPlace for T { +#[cfg(feature = "alloc")] +impl Aead for Alg { + fn encrypt<'msg, 'aad>( + &self, + nonce: &Nonce, + plaintext: impl Into>, + ) -> Result> { + let payload = plaintext.into(); + let mut buffer = Vec::with_capacity(payload.msg.len() + Self::TagSize::to_usize()); + buffer.extend_from_slice(payload.msg); + self.encrypt_in_place(nonce, payload.aad, &mut buffer)?; + Ok(buffer) + } + + fn decrypt<'msg, 'aad>( + &self, + nonce: &Nonce, + ciphertext: impl Into>, + ) -> Result> { + let payload = ciphertext.into(); + let mut buffer = Vec::from(payload.msg); + self.decrypt_in_place(nonce, payload.aad, &mut buffer)?; + Ok(buffer) + } +} + +#[cfg(feature = "inout")] +impl AeadInPlace for T { fn encrypt_in_place( &self, nonce: &Nonce, associated_data: &[u8], buffer: &mut dyn Buffer, ) -> Result<()> { - let tag = self.encrypt_in_place_detached(nonce, associated_data, buffer.as_mut())?; + let tag = self.encrypt_inout_detached(nonce, associated_data, buffer.as_mut().into())?; buffer.extend_from_slice(tag.as_slice())?; Ok(()) } @@ -293,38 +326,12 @@ impl AeadInPlace for T { let (msg, tag) = buffer.as_mut().split_at_mut(tag_pos); let tag = Tag::::try_from(&*tag).expect("tag length mismatch"); - self.decrypt_in_place_detached(nonce, associated_data, msg, &tag)?; + self.decrypt_inout_detached(nonce, associated_data, msg.into(), &tag)?; buffer.truncate(tag_pos); Ok(()) } } -#[cfg(feature = "alloc")] -impl Aead for Alg { - fn encrypt<'msg, 'aad>( - &self, - nonce: &Nonce, - plaintext: impl Into>, - ) -> Result> { - let payload = plaintext.into(); - let mut buffer = Vec::with_capacity(payload.msg.len() + Self::TagSize::to_usize()); - buffer.extend_from_slice(payload.msg); - self.encrypt_in_place(nonce, payload.aad, &mut buffer)?; - Ok(buffer) - } - - fn decrypt<'msg, 'aad>( - &self, - nonce: &Nonce, - ciphertext: impl Into>, - ) -> Result> { - let payload = ciphertext.into(); - let mut buffer = Vec::from(payload.msg); - self.decrypt_in_place(nonce, payload.aad, &mut buffer)?; - Ok(buffer) - } -} - /// AEAD payloads (message + AAD). /// /// Combination of a message (plaintext or ciphertext) and From ef4ce8d35e890ff2c32002beac26e7eec0441b59 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Wed, 19 Mar 2025 20:02:21 +0300 Subject: [PATCH 1307/1461] ci: update all upstream dependencies with Dependabot (#1785) This change automates Cargo.lock updates. --- .github/dependabot.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 397bdaa4f..e621f157b 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,9 +1,16 @@ version: 2 updates: - package-ecosystem: cargo + versioning-strategy: lockfile-only directory: "/" + allow: + - dependency-type: "all" + groups: + all-deps: + patterns: + - "*" schedule: - interval: daily + interval: weekly open-pull-requests-limit: 10 - package-ecosystem: github-actions directory: "/" From 8efa5bd941b3d85cc60d9b9513c9d0617359ade8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Mar 2025 20:36:19 +0300 Subject: [PATCH 1308/1461] build(deps): bump the all-deps group with 12 updates (#1800) --- Cargo.lock | 120 ++++++++++++++--------------------------------------- 1 file changed, 31 insertions(+), 89 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 33d30686a..3fce00d74 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -58,9 +58,9 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "bitflags" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" +checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" [[package]] name = "bitvec" @@ -280,14 +280,14 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "getrandom" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8" +checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" dependencies = [ "cfg-if", "libc", + "r-efi", "wasi", - "windows-targets", ] [[package]] @@ -365,9 +365,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "keccak" @@ -388,9 +388,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.170" +version = "0.2.171" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828" +checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" [[package]] name = "memchr" @@ -473,6 +473,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" + [[package]] name = "radium" version = "0.7.0" @@ -491,9 +497,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.19" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "sec1" @@ -512,18 +518,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.218" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8dfc9d19bdbf6d17e22319da49161d5d0108e4188e8b680aef6299eed22df60" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.218" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f09503e191f4e797cb8aac08e9a4a4695c5edf6a2e70e376d961ddd5c969f82b" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", @@ -651,9 +657,9 @@ checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" [[package]] name = "unicode-ident" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] name = "universal-hash" @@ -665,82 +671,18 @@ dependencies = [ [[package]] name = "wasi" -version = "0.13.3+wasi-0.2.2" +version = "0.14.2+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" dependencies = [ "wit-bindgen-rt", ] -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - [[package]] name = "wit-bindgen-rt" -version = "0.33.0" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" dependencies = [ "bitflags", ] @@ -756,18 +698,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.20" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dde3bb8c68a8f3f1ed4ac9221aad6b10cece3e60a8e2ea54a6a2dec806d0084c" +checksum = "fd97444d05a4328b90e75e503a34bad781f14e28a823ad3557f0750df1ebcbc6" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.20" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eea57037071898bf96a6da35fd626f4f27e9cee3ead2a6c703cf09d472b2e700" +checksum = "6352c01d0edd5db859a63e2605f4ea3183ddbd15e2c4a9e7d32184df75e4f154" dependencies = [ "proc-macro2", "quote", From 80dffedc4d46cfb7c4542435b6c945842ef13c86 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Fri, 21 Mar 2025 15:56:25 +0300 Subject: [PATCH 1309/1461] aead: add `AeadCore::TAG_POSITION` and move `AeadInPlace` methods to `AeadInOut` (#1798) --- aead/Cargo.toml | 4 +- aead/src/lib.rs | 215 ++++++++++++++++++++++----------------------- aead/src/stream.rs | 10 +-- 3 files changed, 113 insertions(+), 116 deletions(-) diff --git a/aead/Cargo.toml b/aead/Cargo.toml index 10c425dba..2665704b4 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -17,16 +17,16 @@ such as AES-GCM as ChaCha20Poly1305, which provide a high-level API [dependencies] crypto-common = { version = "0.2.0-rc.1", path = "../crypto-common" } +inout = "0.2.0-rc.4" # optional dependencies arrayvec = { version = "0.7", optional = true, default-features = false } blobby = { version = "0.4.0-pre.0", optional = true } bytes = { version = "1", optional = true, default-features = false } heapless = { version = "0.8", optional = true, default-features = false } -inout = { version = "0.2.0-rc.4", optional = true, default-features = false } [features] -default = ["inout", "rand_core"] +default = ["rand_core"] alloc = [] dev = ["blobby"] os_rng = ["crypto-common/os_rng", "rand_core"] diff --git a/aead/src/lib.rs b/aead/src/lib.rs index 26faef2a3..b61fbf023 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -34,22 +34,18 @@ pub use bytes; pub use crypto_common::rand_core; #[cfg(feature = "heapless")] pub use heapless; -#[cfg(feature = "inout")] pub use inout; use core::fmt; -use crypto_common::array::{Array, ArraySize}; +use crypto_common::array::{Array, ArraySize, typenum::Unsigned}; +use inout::InOutBuf; #[cfg(feature = "alloc")] use alloc::vec::Vec; #[cfg(feature = "bytes")] use bytes::BytesMut; -#[cfg(any(feature = "alloc", feature = "inout"))] -use crypto_common::array::typenum::Unsigned; #[cfg(feature = "os_rng")] use crypto_common::rand_core::{OsError, OsRng, TryRngCore}; -#[cfg(feature = "inout")] -use inout::InOutBuf; #[cfg(feature = "rand_core")] use rand_core::{CryptoRng, TryCryptoRng}; @@ -77,10 +73,16 @@ pub type Nonce = Array::NonceSize>; /// Tag: authentication code which ensures ciphertexts are authentic pub type Tag = Array::TagSize>; -/// Authenticated Encryption with Associated Data (AEAD) algorithm core trait. -/// -/// Defines nonce, tag, and overhead sizes that are consumed by various other -/// `Aead*` traits. +/// Enum which specifies tag position used by an AEAD algorithm. +#[derive(Debug, Clone, Copy, Eq, PartialEq)] +pub enum TagPosition { + /// Postfix tag + Postfix, + /// Prefix tag + Prefix, +} + +/// Authenticated Encryption with Associated Data (AEAD) algorithm. pub trait AeadCore { /// The length of a nonce. type NonceSize: ArraySize; @@ -88,6 +90,9 @@ pub trait AeadCore { /// The maximum length of the tag. type TagSize: ArraySize; + /// The AEAD tag position. + const TAG_POSITION: TagPosition; + /// Generate a random nonce for this AEAD algorithm. /// /// AEAD algorithms accept a parameter to encryption/decryption called @@ -155,6 +160,94 @@ pub trait AeadCore { } } +/// In-place and inout AEAD trait which handles the authentication tag as a return value/separate parameter. +pub trait AeadInOut: AeadCore { + /// Encrypt the data in the provided [`InOutBuf`], returning the authentication tag. + fn encrypt_inout_detached( + &self, + nonce: &Nonce, + associated_data: &[u8], + buffer: InOutBuf<'_, '_, u8>, + ) -> Result>; + + /// Decrypt the data in the provided [`InOutBuf`], returning an error in the event the + /// provided authentication tag is invalid for the given ciphertext (i.e. ciphertext + /// is modified/unauthentic) + fn decrypt_inout_detached( + &self, + nonce: &Nonce, + associated_data: &[u8], + buffer: InOutBuf<'_, '_, u8>, + tag: &Tag, + ) -> Result<()>; + + /// Encrypt the given buffer containing a plaintext message in-place. + /// + /// The buffer must have sufficient capacity to store the ciphertext + /// message, which will always be larger than the original plaintext. + /// The exact size needed is cipher-dependent, but generally includes + /// the size of an authentication tag. + /// + /// Returns an error if the buffer has insufficient capacity to store the + /// resulting ciphertext message. + fn encrypt_in_place( + &self, + nonce: &Nonce, + associated_data: &[u8], + buffer: &mut dyn Buffer, + ) -> Result<()> { + match Self::TAG_POSITION { + TagPosition::Prefix => { + let msg_len = buffer.len(); + buffer.extend_from_slice(&Tag::::default())?; + let buffer = buffer.as_mut(); + let tag_size = Self::TagSize::USIZE; + buffer.copy_within(..msg_len, tag_size); + let (tag_dst, msg) = buffer.split_at_mut(tag_size); + let tag = self.encrypt_inout_detached(nonce, associated_data, msg.into())?; + tag_dst.copy_from_slice(&tag); + } + TagPosition::Postfix => { + let tag = + self.encrypt_inout_detached(nonce, associated_data, buffer.as_mut().into())?; + buffer.extend_from_slice(tag.as_slice())?; + } + } + Ok(()) + } + + /// Decrypt the message in-place, returning an error in the event the + /// provided authentication tag does not match the given ciphertext. + /// + /// The buffer will be truncated to the length of the original plaintext + /// message upon success. + fn decrypt_in_place( + &self, + nonce: &Nonce, + associated_data: &[u8], + buffer: &mut dyn Buffer, + ) -> Result<()> { + let tag_size = Self::TagSize::USIZE; + let tagless_len = buffer.len().checked_sub(tag_size).ok_or(Error)?; + + match Self::TAG_POSITION { + TagPosition::Prefix => { + let (tag, msg) = buffer.as_mut().split_at_mut(tag_size); + let tag = Tag::::try_from(&*tag).expect("tag length mismatch"); + self.decrypt_inout_detached(nonce, associated_data, msg.into(), &tag)?; + buffer.as_mut().copy_within(tag_size.., 0); + } + TagPosition::Postfix => { + let (msg, tag) = buffer.as_mut().split_at_mut(tagless_len); + let tag = Tag::::try_from(&*tag).expect("tag length mismatch"); + self.decrypt_inout_detached(nonce, associated_data, msg.into(), &tag)?; + } + } + buffer.truncate(tagless_len); + Ok(()) + } +} + /// Authenticated Encryption with Associated Data (AEAD) algorithm. #[cfg(feature = "alloc")] pub trait Aead: AeadCore { @@ -211,70 +304,8 @@ pub trait Aead: AeadCore { ) -> Result>; } -/// In-place AEAD trait. -/// -/// This trait is both object safe and has no dependencies on `alloc` or `std`. -pub trait AeadInPlace: AeadCore { - /// Encrypt the given buffer containing a plaintext message in-place. - /// - /// The buffer must have sufficient capacity to store the ciphertext - /// message, which will always be larger than the original plaintext. - /// The exact size needed is cipher-dependent, but generally includes - /// the size of an authentication tag. - /// - /// Returns an error if the buffer has insufficient capacity to store the - /// resulting ciphertext message. - fn encrypt_in_place( - &self, - nonce: &Nonce, - associated_data: &[u8], - buffer: &mut dyn Buffer, - ) -> Result<()>; - - /// Decrypt the message in-place, returning an error in the event the - /// provided authentication tag does not match the given ciphertext. - /// - /// The buffer will be truncated to the length of the original plaintext - /// message upon success. - fn decrypt_in_place( - &self, - nonce: &Nonce, - associated_data: &[u8], - buffer: &mut dyn Buffer, - ) -> Result<()>; -} - -/// In-place AEAD trait which handles the authentication tag as a return value/separate parameter. -#[cfg(feature = "inout")] -pub trait AeadInOut: AeadCore { - /// Encrypt the data in the provided [`InOutBuf`], returning the authentication tag. - fn encrypt_inout_detached( - &self, - nonce: &Nonce, - associated_data: &[u8], - buffer: InOutBuf<'_, '_, u8>, - ) -> Result>; - - /// Decrypt the data in the provided [`InOutBuf`], returning an error in the event the - /// provided authentication tag is invalid for the given ciphertext (i.e. ciphertext - /// is modified/unauthentic) - fn decrypt_inout_detached( - &self, - nonce: &Nonce, - associated_data: &[u8], - buffer: InOutBuf<'_, '_, u8>, - tag: &Tag, - ) -> Result<()>; -} - -/// Marker trait for AEAD algorithms which append the authentication tag to the end of the -/// ciphertext message. -/// -/// This is the common convention for AEAD algorithms. -pub trait PostfixTagged {} - #[cfg(feature = "alloc")] -impl Aead for Alg { +impl Aead for T { fn encrypt<'msg, 'aad>( &self, nonce: &Nonce, @@ -299,39 +330,6 @@ impl Aead for Alg { } } -#[cfg(feature = "inout")] -impl AeadInPlace for T { - fn encrypt_in_place( - &self, - nonce: &Nonce, - associated_data: &[u8], - buffer: &mut dyn Buffer, - ) -> Result<()> { - let tag = self.encrypt_inout_detached(nonce, associated_data, buffer.as_mut().into())?; - buffer.extend_from_slice(tag.as_slice())?; - Ok(()) - } - - fn decrypt_in_place( - &self, - nonce: &Nonce, - associated_data: &[u8], - buffer: &mut dyn Buffer, - ) -> Result<()> { - let tag_pos = buffer - .len() - .checked_sub(Self::TagSize::to_usize()) - .ok_or(Error)?; - - let (msg, tag) = buffer.as_mut().split_at_mut(tag_pos); - let tag = Tag::::try_from(&*tag).expect("tag length mismatch"); - - self.decrypt_inout_detached(nonce, associated_data, msg.into(), &tag)?; - buffer.truncate(tag_pos); - Ok(()) - } -} - /// AEAD payloads (message + AAD). /// /// Combination of a message (plaintext or ciphertext) and @@ -340,7 +338,6 @@ impl AeadInPlace for T { /// /// If you don't care about AAD, you can pass a `&[u8]` as the payload to /// `encrypt`/`decrypt` and it will automatically be coerced to this type. -#[cfg(feature = "alloc")] #[derive(Debug)] pub struct Payload<'msg, 'aad> { /// Message to be encrypted/decrypted @@ -353,7 +350,6 @@ pub struct Payload<'msg, 'aad> { pub aad: &'aad [u8], } -#[cfg(feature = "alloc")] impl<'msg> From<&'msg [u8]> for Payload<'msg, '_> { fn from(msg: &'msg [u8]) -> Self { Self { msg, aad: b"" } @@ -436,11 +432,12 @@ impl Buffer for heapless::Vec { } } +#[cfg(feature = "alloc")] #[cfg(test)] mod tests { use super::*; /// Ensure that `AeadInPlace` is object-safe #[allow(dead_code)] - type DynAeadInPlace = dyn AeadInPlace; + type DynAeadInPlace = dyn Aead; } diff --git a/aead/src/stream.rs b/aead/src/stream.rs index 5ee90c5f8..b965108bc 100644 --- a/aead/src/stream.rs +++ b/aead/src/stream.rs @@ -6,7 +6,7 @@ #![allow(clippy::upper_case_acronyms)] -use crate::{AeadCore, AeadInPlace, Buffer, Error, Key, KeyInit, Result}; +use crate::{AeadCore, AeadInOut, Buffer, Error, Key, KeyInit, Result}; use core::ops::{AddAssign, Sub}; use crypto_common::array::{Array, ArraySize}; @@ -24,7 +24,7 @@ pub type NonceSize = /// Create a new STREAM from the provided AEAD. pub trait NewStream: StreamPrimitive where - A: AeadInPlace, + A: AeadInOut, A::NonceSize: Sub, NonceSize: ArraySize, { @@ -49,7 +49,7 @@ where /// Deliberately immutable and stateless to permit parallel operation. pub trait StreamPrimitive where - A: AeadInPlace, + A: AeadInOut, A::NonceSize: Sub, NonceSize: ArraySize, { @@ -157,7 +157,7 @@ macro_rules! impl_stream_object { #[derive(Debug)] pub struct $name where - A: AeadInPlace, + A: AeadInOut, S: StreamPrimitive, A::NonceSize: Sub<>::NonceOverhead>, NonceSize: ArraySize, @@ -171,7 +171,7 @@ macro_rules! impl_stream_object { impl $name where - A: AeadInPlace, + A: AeadInOut, S: StreamPrimitive, A::NonceSize: Sub<>::NonceOverhead>, NonceSize: ArraySize, From d2b4b596fa9f16134e3140cc5ceb3f56ec0e6f3a Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Fri, 21 Mar 2025 16:30:23 +0300 Subject: [PATCH 1310/1461] aead: remove `stream` module (#1801) The module contents do not need to be defined in `aead` and can be moved to the `aead-stream` crate. --- aead/src/lib.rs | 5 +- aead/src/stream.rs | 311 --------------------------------------------- 2 files changed, 2 insertions(+), 314 deletions(-) delete mode 100644 aead/src/stream.rs diff --git a/aead/src/lib.rs b/aead/src/lib.rs index b61fbf023..e2307cb2a 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -19,8 +19,6 @@ extern crate alloc; #[cfg(feature = "dev")] pub mod dev; -pub mod stream; - pub use crypto_common::{ Key, KeyInit, KeySizeUser, array::{self, typenum::consts}, @@ -125,9 +123,10 @@ pub trait AeadCore { /// reach it should consider alternatives to purely random nonces, like /// a counter or a combination of a random nonce + counter. /// - /// See the [`stream`] module for a ready-made implementation of the latter. + /// See the [`aead-stream`] crate for a ready-made implementation of the latter. /// /// [NIST SP 800-38D]: https://csrc.nist.gov/publications/detail/sp/800-38d/final + /// [`aead-stream`]: https://docs.rs/aead-stream #[cfg(feature = "os_rng")] fn generate_nonce() -> core::result::Result, OsError> { let mut nonce = Nonce::::default(); diff --git a/aead/src/stream.rs b/aead/src/stream.rs deleted file mode 100644 index b965108bc..000000000 --- a/aead/src/stream.rs +++ /dev/null @@ -1,311 +0,0 @@ -//! Streaming AEAD support. -//! -//! See the [`aead-stream`] crate for a generic implementation of the STREAM construction. -//! -//! [`aead-stream`]: https://docs.rs/aead-stream - -#![allow(clippy::upper_case_acronyms)] - -use crate::{AeadCore, AeadInOut, Buffer, Error, Key, KeyInit, Result}; -use core::ops::{AddAssign, Sub}; -use crypto_common::array::{Array, ArraySize}; - -#[cfg(feature = "alloc")] -use {crate::Payload, alloc::vec::Vec, crypto_common::array::typenum::Unsigned}; - -/// Nonce as used by a given AEAD construction and STREAM primitive. -pub type Nonce = Array>; - -/// Size of a nonce as used by a STREAM construction, sans the overhead of -/// the STREAM protocol itself. -pub type NonceSize = - <::NonceSize as Sub<>::NonceOverhead>>::Output; - -/// Create a new STREAM from the provided AEAD. -pub trait NewStream: StreamPrimitive -where - A: AeadInOut, - A::NonceSize: Sub, - NonceSize: ArraySize, -{ - /// Create a new STREAM with the given key and nonce. - fn new(key: &Key, nonce: &Nonce) -> Self - where - A: KeyInit, - Self: Sized, - { - Self::from_aead(A::new(key), nonce) - } - - /// Create a new STREAM from the given AEAD cipher. - fn from_aead(aead: A, nonce: &Nonce) -> Self; -} - -/// Low-level STREAM implementation. -/// -/// This trait provides a particular "flavor" of STREAM, as there are -/// different ways the specifics of the construction can be implemented. -/// -/// Deliberately immutable and stateless to permit parallel operation. -pub trait StreamPrimitive -where - A: AeadInOut, - A::NonceSize: Sub, - NonceSize: ArraySize, -{ - /// Number of bytes this STREAM primitive requires from the nonce. - type NonceOverhead: ArraySize; - - /// Type used as the STREAM counter. - type Counter: AddAssign + Copy + Default + Eq; - - /// Value to use when incrementing the STREAM counter (i.e. one) - const COUNTER_INCR: Self::Counter; - - /// Maximum value of the STREAM counter. - const COUNTER_MAX: Self::Counter; - - /// Encrypt an AEAD message in-place at the given position in the STREAM. - fn encrypt_in_place( - &self, - position: Self::Counter, - last_block: bool, - associated_data: &[u8], - buffer: &mut dyn Buffer, - ) -> Result<()>; - - /// Decrypt an AEAD message in-place at the given position in the STREAM. - fn decrypt_in_place( - &self, - position: Self::Counter, - last_block: bool, - associated_data: &[u8], - buffer: &mut dyn Buffer, - ) -> Result<()>; - - /// Encrypt the given plaintext payload, and return the resulting - /// ciphertext as a vector of bytes. - #[cfg(feature = "alloc")] - fn encrypt<'msg, 'aad>( - &self, - position: Self::Counter, - last_block: bool, - plaintext: impl Into>, - ) -> Result> { - let payload = plaintext.into(); - let mut buffer = Vec::with_capacity(payload.msg.len() + A::TagSize::to_usize()); - buffer.extend_from_slice(payload.msg); - self.encrypt_in_place(position, last_block, payload.aad, &mut buffer)?; - Ok(buffer) - } - - /// Decrypt the given ciphertext slice, and return the resulting plaintext - /// as a vector of bytes. - #[cfg(feature = "alloc")] - fn decrypt<'msg, 'aad>( - &self, - position: Self::Counter, - last_block: bool, - ciphertext: impl Into>, - ) -> Result> { - let payload = ciphertext.into(); - let mut buffer = Vec::from(payload.msg); - self.decrypt_in_place(position, last_block, payload.aad, &mut buffer)?; - Ok(buffer) - } - - /// Obtain [`Encryptor`] for this [`StreamPrimitive`]. - fn encryptor(self) -> Encryptor - where - Self: Sized, - { - Encryptor::from_stream_primitive(self) - } - - /// Obtain [`Decryptor`] for this [`StreamPrimitive`]. - fn decryptor(self) -> Decryptor - where - Self: Sized, - { - Decryptor::from_stream_primitive(self) - } -} - -/// Implement a stateful STREAM object (i.e. encryptor or decryptor) -macro_rules! impl_stream_object { - ( - $name:ident, - $next_method:tt, - $next_in_place_method:tt, - $last_method:tt, - $last_in_place_method:tt, - $op:tt, - $in_place_op:tt, - $op_desc:expr, - $obj_desc:expr - ) => { - #[doc = "Stateful STREAM object which can"] - #[doc = $op_desc] - #[doc = "AEAD messages one-at-a-time."] - #[doc = ""] - #[doc = "This corresponds to the "] - #[doc = $obj_desc] - #[doc = "object as defined in the paper"] - #[doc = "[Online Authenticated-Encryption and its Nonce-Reuse Misuse-Resistance][1]."] - #[doc = ""] - #[doc = "[1]: https://eprint.iacr.org/2015/189.pdf"] - #[derive(Debug)] - pub struct $name - where - A: AeadInOut, - S: StreamPrimitive, - A::NonceSize: Sub<>::NonceOverhead>, - NonceSize: ArraySize, - { - /// Underlying STREAM primitive. - stream: S, - - /// Current position in the STREAM. - position: S::Counter, - } - - impl $name - where - A: AeadInOut, - S: StreamPrimitive, - A::NonceSize: Sub<>::NonceOverhead>, - NonceSize: ArraySize, - { - #[doc = "Create a"] - #[doc = $obj_desc] - #[doc = "object from the given AEAD key and nonce."] - pub fn new(key: &Key, nonce: &Nonce) -> Self - where - A: KeyInit, - S: NewStream, - { - Self::from_stream_primitive(S::new(key, nonce)) - } - - #[doc = "Create a"] - #[doc = $obj_desc] - #[doc = "object from the given AEAD primitive."] - pub fn from_aead(aead: A, nonce: &Nonce) -> Self - where - A: KeyInit, - S: NewStream, - { - Self::from_stream_primitive(S::from_aead(aead, nonce)) - } - - #[doc = "Create a"] - #[doc = $obj_desc] - #[doc = "object from the given STREAM primitive."] - pub fn from_stream_primitive(stream: S) -> Self { - Self { - stream, - position: Default::default(), - } - } - - #[doc = "Use the underlying AEAD to"] - #[doc = $op_desc] - #[doc = "the next AEAD message in this STREAM, returning the"] - #[doc = "result as a [`Vec`]."] - #[cfg(feature = "alloc")] - pub fn $next_method<'msg, 'aad>( - &mut self, - payload: impl Into>, - ) -> Result> { - if self.position == S::COUNTER_MAX { - // Counter overflow. Note that the maximum counter value is - // deliberately disallowed, as it would preclude being able - // to encrypt a last block (i.e. with `$last_in_place_method`) - return Err(Error); - } - - let result = self.stream.$op(self.position, false, payload)?; - - // Note: overflow checked above - self.position += S::COUNTER_INCR; - Ok(result) - } - - #[doc = "Use the underlying AEAD to"] - #[doc = $op_desc] - #[doc = "the next AEAD message in this STREAM in-place."] - pub fn $next_in_place_method( - &mut self, - associated_data: &[u8], - buffer: &mut dyn Buffer, - ) -> Result<()> { - if self.position == S::COUNTER_MAX { - // Counter overflow. Note that the maximum counter value is - // deliberately disallowed, as it would preclude being able - // to encrypt a last block (i.e. with `$last_in_place_method`) - return Err(Error); - } - - self.stream - .$in_place_op(self.position, false, associated_data, buffer)?; - - // Note: overflow checked above - self.position += S::COUNTER_INCR; - Ok(()) - } - - #[doc = "Use the underlying AEAD to"] - #[doc = $op_desc] - #[doc = "the last AEAD message in this STREAM,"] - #[doc = "consuming the "] - #[doc = $obj_desc] - #[doc = "object in order to prevent further use."] - #[cfg(feature = "alloc")] - pub fn $last_method<'msg, 'aad>( - self, - payload: impl Into>, - ) -> Result> { - self.stream.$op(self.position, true, payload) - } - - #[doc = "Use the underlying AEAD to"] - #[doc = $op_desc] - #[doc = "the last AEAD message in this STREAM in-place,"] - #[doc = "consuming the "] - #[doc = $obj_desc] - #[doc = "object in order to prevent further use."] - pub fn $last_in_place_method( - self, - associated_data: &[u8], - buffer: &mut dyn Buffer, - ) -> Result<()> { - self.stream - .$in_place_op(self.position, true, associated_data, buffer) - } - } - }; -} - -impl_stream_object!( - Encryptor, - encrypt_next, - encrypt_next_in_place, - encrypt_last, - encrypt_last_in_place, - encrypt, - encrypt_in_place, - "encrypt", - "ℰ STREAM encryptor" -); - -impl_stream_object!( - Decryptor, - decrypt_next, - decrypt_next_in_place, - decrypt_last, - decrypt_last_in_place, - decrypt, - decrypt_in_place, - "decrypt", - "𝒟 STREAM decryptor" -); From a8d6711ab611964101f6b6d3571825dff5f23e28 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Fri, 21 Mar 2025 19:07:50 +0300 Subject: [PATCH 1311/1461] aead: tweak `dev` module and add `DummyAead` tests (#1802) Tests the inout methods and moves test vector code outside of the macro. --- aead/Cargo.toml | 2 +- aead/src/dev.rs | 150 ++++++++++++++++++++----------- aead/tests/data/postfix.blb | Bin 0 -> 208 bytes aead/tests/data/prefix.blb | Bin 0 -> 208 bytes aead/tests/dummy.rs | 175 ++++++++++++++++++++++++++++++++++++ 5 files changed, 272 insertions(+), 55 deletions(-) create mode 100644 aead/tests/data/postfix.blb create mode 100644 aead/tests/data/prefix.blb create mode 100644 aead/tests/dummy.rs diff --git a/aead/Cargo.toml b/aead/Cargo.toml index 2665704b4..f004bc699 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -28,7 +28,7 @@ heapless = { version = "0.8", optional = true, default-features = false } [features] default = ["rand_core"] alloc = [] -dev = ["blobby"] +dev = ["blobby", "alloc"] os_rng = ["crypto-common/os_rng", "rand_core"] rand_core = ["crypto-common/rand_core"] diff --git a/aead/src/dev.rs b/aead/src/dev.rs index b128014bd..f216b72cc 100644 --- a/aead/src/dev.rs +++ b/aead/src/dev.rs @@ -1,74 +1,116 @@ //! Development-related functionality +use crate::{ + Aead, AeadInOut, Nonce, Payload, Tag, TagPosition, array::typenum::Unsigned, inout::InOutBuf, +}; pub use blobby; +/// Run AEAD test for the provided passing test vector +pub fn run_pass_test( + cipher: &C, + nonce: &Nonce, + aad: &[u8], + pt: &[u8], + ct: &[u8], +) -> Result<(), &'static str> { + let res = cipher + .encrypt(nonce, Payload { aad, msg: pt }) + .map_err(|_| "encryption failure")?; + if res != ct { + return Err("encrypted data is different from target ciphertext"); + } + + let res = cipher + .decrypt(nonce, Payload { aad, msg: ct }) + .map_err(|_| "decryption failure")?; + if res != pt { + return Err("decrypted data is different from target plaintext"); + } + + let (ct, tag) = match C::TAG_POSITION { + TagPosition::Prefix => { + let (tag, ct) = ct.split_at(C::TagSize::USIZE); + (ct, tag) + } + TagPosition::Postfix => ct.split_at(pt.len()), + }; + let tag: &Tag = tag.try_into().expect("tag has correct length"); + + // Fill output buffer with "garbage" to test that its data does not get read during encryption + let mut buf: alloc::vec::Vec = (0..pt.len()).map(|i| i as u8).collect(); + let inout_buf = InOutBuf::new(pt, &mut buf).expect("pt and buf have the same length"); + + let calc_tag = cipher + .encrypt_inout_detached(nonce, aad, inout_buf) + .map_err(|_| "encrypt_inout_detached: encryption failure")?; + if tag != &calc_tag { + return Err("encrypt_inout_detached: tag mismatch"); + } + if ct != buf { + return Err("encrypt_inout_detached: ciphertext mismatch"); + } + + // Fill output buffer with "garbage" + buf.iter_mut().enumerate().for_each(|(i, v)| *v = i as u8); + + let inout_buf = InOutBuf::new(ct, &mut buf).expect("ct and buf have the same length"); + cipher + .decrypt_inout_detached(nonce, aad, inout_buf, tag) + .map_err(|_| "decrypt_inout_detached: decryption failure")?; + if pt != buf { + return Err("decrypt_inout_detached: plaintext mismatch"); + } + + Ok(()) +} + +/// Run AEAD test for the provided failing test vector +pub fn run_fail_test( + cipher: &C, + nonce: &Nonce, + aad: &[u8], + ct: &[u8], +) -> Result<(), &'static str> { + let res = cipher.decrypt(nonce, Payload { aad, msg: ct }); + if res.is_ok() { + Err("decryption must return error") + } else { + Ok(()) + } +} + /// Define AEAD test #[macro_export] macro_rules! new_test { ($name:ident, $test_name:expr, $cipher:ty $(,)?) => { #[test] fn $name() { - use aead::{ - Aead, KeyInit, Payload, - array::{Array, typenum::Unsigned}, - dev::blobby::Blob6Iterator, - }; - - fn run_test( - key: &[u8], - nonce: &[u8], - aad: &[u8], - pt: &[u8], - ct: &[u8], - pass: bool, - ) -> Result<(), &'static str> { - let key = key.try_into().map_err(|_| "wrong key size")?; - let cipher = <$cipher>::new(key); - let nonce = nonce.try_into().map_err(|_| "wrong nonce size")?; - - if !pass { - let res = cipher.decrypt(nonce, Payload { aad: aad, msg: ct }); - if res.is_ok() { - return Err("decryption must return error"); - } - return Ok(()); - } - - let res = cipher - .encrypt(nonce, Payload { aad: aad, msg: pt }) - .map_err(|_| "encryption failure")?; - if res != ct { - return Err("encrypted data is different from target ciphertext"); - } - let res = cipher - .decrypt(nonce, Payload { aad: aad, msg: ct }) - .map_err(|_| "decryption failure")?; - if res != pt { - return Err("decrypted data is different from target plaintext"); - } - Ok(()) - } + use $crate::KeyInit; + use $crate::dev::blobby::Blob6Iterator; let data = include_bytes!(concat!("data/", $test_name, ".blb")); for (i, row) in Blob6Iterator::new(data).unwrap().enumerate() { let [key, nonce, aad, pt, ct, status] = row.unwrap(); - let pass = match status[0] { - 0 => false, - 1 => true, + let key = key.try_into().expect("wrong key size"); + let nonce = nonce.try_into().expect("wrong nonce size"); + let cipher = <$cipher as KeyInit>::new(key); + + let res = match status { + [0] => $crate::dev::run_fail_test(&cipher, nonce, aad, ct), + [1] => $crate::dev::run_pass_test(&cipher, nonce, aad, pt, ct), _ => panic!("invalid value for pass flag"), }; - if let Err(reason) = run_test(key, nonce, aad, pt, ct, pass) { + let mut pass = status[0] == 1; + if let Err(reason) = res { panic!( "\n\ - Failed test №{}\n\ - reason: \t{:?}\n\ - key:\t{:?}\n\ - nonce:\t{:?}\n\ - aad:\t{:?}\n\ - plaintext:\t{:?}\n\ - ciphertext:\t{:?}\n\ - pass:\t{}\n\ - ", - i, reason, key, nonce, aad, pt, ct, pass, + Failed test #{i}\n\ + reason:\t{reason:?}\n\ + key:\t{key:?}\n\ + nonce:\t{nonce:?}\n\ + aad:\t{aad:?}\n\ + plaintext:\t{pt:?}\n\ + ciphertext:\t{ct:?}\n\ + pass:\t{pass}\n" ); } } diff --git a/aead/tests/data/postfix.blb b/aead/tests/data/postfix.blb new file mode 100644 index 0000000000000000000000000000000000000000..97d850e1c6241381a17571282a85b3497574640d GIT binary patch literal 208 zcmZQ&WME_z(G2@~Cc&WKghJEx8$14235I=C?c&(_TcvX@v(6QcuwJ&?@q-ZcY!Kcv8&)U bDoai8a@qq@0XK02BOwzn09D{OaRVa&v)@iI literal 0 HcmV?d00001 diff --git a/aead/tests/data/prefix.blb b/aead/tests/data/prefix.blb new file mode 100644 index 0000000000000000000000000000000000000000..8a5929ee6272c0f0a3fb33d93a032d1e2af944d5 GIT binary patch literal 208 zcmZQ&WME|E*!o+gb1t*a6^^i8xe2T8S!63i_HIWf$B7+4F9ut8oI2kM$@R-O50C*@(2LJ#7 literal 0 HcmV?d00001 diff --git a/aead/tests/dummy.rs b/aead/tests/dummy.rs new file mode 100644 index 000000000..817ab945c --- /dev/null +++ b/aead/tests/dummy.rs @@ -0,0 +1,175 @@ +//! This module defines dummy (horribly insecure!) AEAD implementations +//! to test implementation of the AEAD traits and helper macros in the `dev` module. +use aead::{ + AeadCore, AeadInOut, Error, Key, KeyInit, KeySizeUser, Nonce, Result, Tag, TagPosition, + array::Array, consts::U8, +}; +use inout::InOutBuf; + +struct DummyAead { + key: [u8; 8], +} + +impl DummyAead { + fn process_aad(&self, nonce: &[u8; 8], aad: &[u8]) -> u64 { + let mut tag = u64::from_le_bytes(*nonce); + let key = u64::from_le_bytes(self.key); + + let mut aad_iter = aad.chunks_exact(8); + for chunk in &mut aad_iter { + tag ^= u64::from_le_bytes(chunk.try_into().unwrap()); + tag = tag.wrapping_add(key); + } + let aad_rem = aad_iter.remainder(); + if !aad_rem.is_empty() { + let mut chunk = [0u8; 8]; + chunk[..aad_rem.len()].copy_from_slice(aad_rem); + tag ^= u64::from_le_bytes(chunk); + tag = tag.wrapping_add(key); + } + + tag + } + + fn encrypt_inner( + &self, + nonce: &[u8; 8], + aad: &[u8], + buffer: InOutBuf<'_, '_, u8>, + ) -> Result<[u8; 8]> { + let mut tag = self.process_aad(nonce, aad); + + let (blocks, mut rem) = buffer.into_chunks::(); + for mut block in blocks { + block.xor_in2out(&self.key.into()); + tag ^= u64::from_be_bytes(block.get_out().0); + } + + if !rem.is_empty() { + rem.xor_in2out(&self.key[..rem.len()]); + + let out_rem = rem.get_out(); + let mut block = [0u8; 8]; + block[..out_rem.len()].copy_from_slice(out_rem); + tag ^= u64::from_le_bytes(block); + } + + Ok(tag.to_le_bytes()) + } + + fn decrypt_inner( + &self, + nonce: &[u8; 8], + aad: &[u8], + mut buffer: InOutBuf<'_, '_, u8>, + tag: &[u8; 8], + ) -> Result<()> { + let exp_tag = u64::from_le_bytes(*tag); + let mut tag = self.process_aad(nonce, aad); + + let (blocks, mut rem) = buffer.reborrow().into_chunks::(); + for mut block in blocks { + tag ^= u64::from_be_bytes(block.get_in().0); + block.xor_in2out(&self.key.into()); + } + + if !rem.is_empty() { + let in_rem = rem.get_in(); + let mut block = [0u8; 8]; + block[..in_rem.len()].copy_from_slice(in_rem); + tag ^= u64::from_le_bytes(block); + + rem.xor_in2out(&self.key[..rem.len()]); + } + + if tag == exp_tag { + Ok(()) + } else { + buffer.get_out().fill(0); + Err(Error) + } + } +} + +struct PrefixDummyAead(DummyAead); + +impl KeySizeUser for PrefixDummyAead { + type KeySize = U8; +} + +impl KeyInit for PrefixDummyAead { + fn new(key: &Key) -> Self { + Self(DummyAead { key: key.0 }) + } +} + +impl AeadCore for PrefixDummyAead { + type NonceSize = U8; + type TagSize = U8; + const TAG_POSITION: TagPosition = TagPosition::Prefix; +} + +impl AeadInOut for PrefixDummyAead { + fn encrypt_inout_detached( + &self, + nonce: &Nonce, + aad: &[u8], + buffer: InOutBuf<'_, '_, u8>, + ) -> Result> { + self.0.encrypt_inner(nonce.into(), aad, buffer).map(Array) + } + + fn decrypt_inout_detached( + &self, + nonce: &Nonce, + aad: &[u8], + buffer: InOutBuf<'_, '_, u8>, + tag: &Tag, + ) -> Result<()> { + self.0.decrypt_inner(nonce.into(), aad, buffer, tag.into()) + } +} + +struct PostfixDummyAead(DummyAead); + +impl KeySizeUser for PostfixDummyAead { + type KeySize = U8; +} + +impl KeyInit for PostfixDummyAead { + fn new(key: &Key) -> Self { + Self(DummyAead { key: key.0 }) + } +} + +impl AeadCore for PostfixDummyAead { + type NonceSize = U8; + type TagSize = U8; + const TAG_POSITION: TagPosition = TagPosition::Postfix; +} + +impl AeadInOut for PostfixDummyAead { + fn encrypt_inout_detached( + &self, + nonce: &Nonce, + aad: &[u8], + buffer: InOutBuf<'_, '_, u8>, + ) -> Result> { + self.0.encrypt_inner(nonce.into(), aad, buffer).map(Array) + } + + fn decrypt_inout_detached( + &self, + nonce: &Nonce, + aad: &[u8], + buffer: InOutBuf<'_, '_, u8>, + tag: &Tag, + ) -> Result<()> { + self.0.decrypt_inner(nonce.into(), aad, buffer, tag.into()) + } +} + +#[cfg(feature = "dev")] +aead::new_test!(dummy_prefix, "prefix", PrefixDummyAead); +#[cfg(feature = "dev")] +aead::new_test!(dummy_postfix, "postfix", PostfixDummyAead); From de72c67026c5a0aee2a9beb2c9f25f3a19ec2bc8 Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Sun, 23 Mar 2025 18:07:11 -0700 Subject: [PATCH 1312/1461] elliptic-curve: make `SecretKey::new` failible (#1804) This fixes an invariant violation where you could create a secret key from an all-zero scalar and convert it to a non-zero scala. Fixes: https://github.com/RustCrypto/traits/issues/1607 --- elliptic-curve/src/secret_key.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 1c15dc797..f1559c8c4 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -11,7 +11,7 @@ mod pkcs8; use crate::{Curve, Error, FieldBytes, Result, ScalarPrimitive}; use core::fmt::{self, Debug}; use hybrid_array::typenum::Unsigned; -use subtle::{Choice, ConstantTimeEq}; +use subtle::{Choice, ConstantTimeEq, CtOption}; use zeroize::{Zeroize, ZeroizeOnDrop, Zeroizing}; #[cfg(feature = "arithmetic")] @@ -117,8 +117,12 @@ where } /// Create a new secret key from a scalar value. - pub fn new(scalar: ScalarPrimitive) -> Self { - Self { inner: scalar } + /// + /// # Returns + /// + /// This will return a none if the scalar is all-zero. + pub fn new(scalar: ScalarPrimitive) -> CtOption { + CtOption::new(Self { inner: scalar }, !scalar.is_zero()) } /// Borrow the inner secret [`ScalarPrimitive`] value. From 6cc9d4cd4d3b7d336db2d295d5b30b4cb44d8270 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 Mar 2025 04:29:23 +0300 Subject: [PATCH 1313/1461] Update Cargo.lock (#1805) --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3fce00d74..9ee8e0055 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -698,18 +698,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.23" +version = "0.8.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd97444d05a4328b90e75e503a34bad781f14e28a823ad3557f0750df1ebcbc6" +checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.23" +version = "0.8.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6352c01d0edd5db859a63e2605f4ea3183ddbd15e2c4a9e7d32184df75e4f154" +checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be" dependencies = [ "proc-macro2", "quote", From 4206e67077ac64f1f107c314784c018bd5de4c82 Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Mon, 31 Mar 2025 09:06:24 -0700 Subject: [PATCH 1314/1461] Relax Sized requirement on RNG types (#1777) --- Cargo.lock | 2 +- Cargo.toml | 3 ++- aead/src/lib.rs | 4 ++-- crypto-common/src/lib.rs | 28 +++++++++++++++--------- elliptic-curve/src/dev.rs | 4 ++-- elliptic-curve/src/ecdh.rs | 2 +- elliptic-curve/src/point/non_identity.rs | 4 ++-- elliptic-curve/src/scalar/blinded.rs | 2 +- elliptic-curve/src/scalar/primitive.rs | 2 +- elliptic-curve/src/secret_key.rs | 2 +- kem/src/lib.rs | 2 +- password-hash/src/salt.rs | 6 +++-- 12 files changed, 36 insertions(+), 25 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9ee8e0055..192ae78f5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -293,7 +293,7 @@ dependencies = [ [[package]] name = "group" version = "0.13.0" -source = "git+https://github.com/pinkforest/group.git?branch=bump-rand-0.9#06ac6fb11ced26fbf980ee65e74fced4da66ec3e" +source = "git+https://github.com/baloo/group.git?branch=baloo%2Ftry_from_rng#b0d6ea48fe55327b11ea03f9a965d9e16bb83adc" dependencies = [ "ff", "rand_core", diff --git a/Cargo.toml b/Cargo.toml index 21a734666..2df244b64 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,4 +31,5 @@ crypto-bigint = { git = "https://github.com/RustCrypto/crypto-bigint.git" } ff = { git = "https://github.com/zkcrypto/ff.git", branch = "release-0.14.0" } # https://github.com/zkcrypto/group/pull/56 -group = { git = "https://github.com/pinkforest/group.git", branch = "bump-rand-0.9" } +# https://github.com/zkcrypto/group/pull/57 +group = { git = "https://github.com/baloo/group.git", branch = "baloo/try_from_rng" } diff --git a/aead/src/lib.rs b/aead/src/lib.rs index e2307cb2a..140c6e19a 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -139,7 +139,7 @@ pub trait AeadCore { /// See [`AeadCore::generate_nonce`] documentation for requirements for /// random nonces. #[cfg(feature = "rand_core")] - fn generate_nonce_with_rng(rng: &mut R) -> Nonce { + fn generate_nonce_with_rng(rng: &mut R) -> Nonce { let mut nonce = Nonce::::default(); rng.fill_bytes(&mut nonce); nonce @@ -150,7 +150,7 @@ pub trait AeadCore { /// See [`AeadCore::generate_nonce`] documentation for requirements for /// random nonces. #[cfg(feature = "rand_core")] - fn try_generate_nonce_with_rng( + fn try_generate_nonce_with_rng( rng: &mut R, ) -> core::result::Result, R::Error> { let mut nonce = Nonce::::default(); diff --git a/crypto-common/src/lib.rs b/crypto-common/src/lib.rs index 240e1257d..3e070ad4c 100644 --- a/crypto-common/src/lib.rs +++ b/crypto-common/src/lib.rs @@ -196,7 +196,7 @@ pub trait KeyInit: KeySizeUser + Sized { /// Generate random key using the provided [`CryptoRng`]. #[cfg(feature = "rand_core")] #[inline] - fn generate_key_with_rng(rng: &mut R) -> Key { + fn generate_key_with_rng(rng: &mut R) -> Key { let mut key = Key::::default(); rng.fill_bytes(&mut key); key @@ -205,7 +205,9 @@ pub trait KeyInit: KeySizeUser + Sized { /// Generate random key using the provided [`TryCryptoRng`]. #[cfg(feature = "rand_core")] #[inline] - fn try_generate_key_with_rng(rng: &mut R) -> Result, R::Error> { + fn try_generate_key_with_rng( + rng: &mut R, + ) -> Result, R::Error> { let mut key = Key::::default(); rng.try_fill_bytes(&mut key)?; Ok(key) @@ -250,7 +252,7 @@ pub trait KeyIvInit: KeySizeUser + IvSizeUser + Sized { /// Generate random key using the provided [`CryptoRng`]. #[cfg(feature = "rand_core")] #[inline] - fn generate_key_with_rng(rng: &mut R) -> Key { + fn generate_key_with_rng(rng: &mut R) -> Key { let mut key = Key::::default(); rng.fill_bytes(&mut key); key @@ -259,7 +261,9 @@ pub trait KeyIvInit: KeySizeUser + IvSizeUser + Sized { /// Generate random key using the provided [`TryCryptoRng`]. #[cfg(feature = "rand_core")] #[inline] - fn try_generate_key_with_rng(rng: &mut R) -> Result, R::Error> { + fn try_generate_key_with_rng( + rng: &mut R, + ) -> Result, R::Error> { let mut key = Key::::default(); rng.try_fill_bytes(&mut key)?; Ok(key) @@ -277,7 +281,7 @@ pub trait KeyIvInit: KeySizeUser + IvSizeUser + Sized { /// Generate random IV using the provided [`CryptoRng`]. #[cfg(feature = "rand_core")] #[inline] - fn generate_iv_with_rng(rng: &mut R) -> Iv { + fn generate_iv_with_rng(rng: &mut R) -> Iv { let mut iv = Iv::::default(); rng.fill_bytes(&mut iv); iv @@ -286,7 +290,9 @@ pub trait KeyIvInit: KeySizeUser + IvSizeUser + Sized { /// Generate random IV using the provided [`TryCryptoRng`]. #[cfg(feature = "rand_core")] #[inline] - fn try_generate_iv_with_rng(rng: &mut R) -> Result, R::Error> { + fn try_generate_iv_with_rng( + rng: &mut R, + ) -> Result, R::Error> { let mut iv = Iv::::default(); rng.try_fill_bytes(&mut iv)?; Ok(iv) @@ -304,7 +310,7 @@ pub trait KeyIvInit: KeySizeUser + IvSizeUser + Sized { /// Generate random key and IV using the provided [`CryptoRng`]. #[cfg(feature = "rand_core")] #[inline] - fn generate_key_iv_with_rng(rng: &mut R) -> (Key, Iv) { + fn generate_key_iv_with_rng(rng: &mut R) -> (Key, Iv) { let key = Self::generate_key_with_rng(rng); let iv = Self::generate_iv_with_rng(rng); (key, iv) @@ -313,7 +319,7 @@ pub trait KeyIvInit: KeySizeUser + IvSizeUser + Sized { /// Generate random key and IV using the provided [`TryCryptoRng`]. #[cfg(feature = "rand_core")] #[inline] - fn try_generate_key_iv_with_rng( + fn try_generate_key_iv_with_rng( rng: &mut R, ) -> Result<(Key, Iv), R::Error> { let key = Self::try_generate_key_with_rng(rng)?; @@ -357,7 +363,7 @@ pub trait InnerIvInit: InnerUser + IvSizeUser + Sized { /// Generate random IV using the provided [`CryptoRng`]. #[cfg(feature = "rand_core")] #[inline] - fn generate_iv_with_rng(rng: &mut R) -> Iv { + fn generate_iv_with_rng(rng: &mut R) -> Iv { let mut iv = Iv::::default(); rng.fill_bytes(&mut iv); iv @@ -366,7 +372,9 @@ pub trait InnerIvInit: InnerUser + IvSizeUser + Sized { /// Generate random IV using the provided [`TryCryptoRng`]. #[cfg(feature = "rand_core")] #[inline] - fn try_generate_iv_with_rng(rng: &mut R) -> Result, R::Error> { + fn try_generate_iv_with_rng( + rng: &mut R, + ) -> Result, R::Error> { let mut iv = Iv::::default(); rng.try_fill_bytes(&mut iv)?; Ok(iv) diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 4f1c58811..ea333960e 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -10,7 +10,7 @@ use crate::{ error::{Error, Result}, ops::{Invert, LinearCombination, MulByGenerator, Reduce, ShrAssign}, point::AffineCoordinates, - rand_core::{RngCore, TryRngCore}, + rand_core::TryRngCore, scalar::{FromUintUnchecked, IsHigh}, sec1::{CompressedPoint, FromEncodedPoint, ToEncodedPoint}, subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}, @@ -575,7 +575,7 @@ impl ToEncodedPoint for ProjectivePoint { impl group::Group for ProjectivePoint { type Scalar = Scalar; - fn random(_rng: impl RngCore) -> Self { + fn try_from_rng(_rng: &mut R) -> core::result::Result { unimplemented!(); } diff --git a/elliptic-curve/src/ecdh.rs b/elliptic-curve/src/ecdh.rs index baf4d9a98..74143999a 100644 --- a/elliptic-curve/src/ecdh.rs +++ b/elliptic-curve/src/ecdh.rs @@ -108,7 +108,7 @@ where C: CurveArithmetic, { /// Generate a cryptographically random [`EphemeralSecret`]. - pub fn random(rng: &mut R) -> Self { + pub fn random(rng: &mut R) -> Self { Self { scalar: NonZeroScalar::random(rng), } diff --git a/elliptic-curve/src/point/non_identity.rs b/elliptic-curve/src/point/non_identity.rs index c118852c1..d76463e84 100644 --- a/elliptic-curve/src/point/non_identity.rs +++ b/elliptic-curve/src/point/non_identity.rs @@ -58,9 +58,9 @@ where P: ConditionallySelectable + ConstantTimeEq + Curve + Default, { /// Generate a random `NonIdentity`. - pub fn random(mut rng: R) -> Self { + pub fn random(rng: &mut R) -> Self { loop { - if let Some(point) = Self::new(P::random(&mut rng)).into() { + if let Some(point) = Self::new(P::random(rng)).into() { break point; } } diff --git a/elliptic-curve/src/scalar/blinded.rs b/elliptic-curve/src/scalar/blinded.rs index 6638e84cc..9828edb33 100644 --- a/elliptic-curve/src/scalar/blinded.rs +++ b/elliptic-curve/src/scalar/blinded.rs @@ -38,7 +38,7 @@ where C: CurveArithmetic, { /// Create a new [`BlindedScalar`] from a scalar and a [`CryptoRng`]. - pub fn new(scalar: Scalar, rng: &mut R) -> Self { + pub fn new(scalar: Scalar, rng: &mut R) -> Self { Self { scalar, mask: Scalar::::random(rng), diff --git a/elliptic-curve/src/scalar/primitive.rs b/elliptic-curve/src/scalar/primitive.rs index b6720b0a5..3772cb81f 100644 --- a/elliptic-curve/src/scalar/primitive.rs +++ b/elliptic-curve/src/scalar/primitive.rs @@ -65,7 +65,7 @@ where pub const MODULUS: C::Uint = C::ORDER; /// Generate a random [`ScalarPrimitive`]. - pub fn random(rng: &mut R) -> Self { + pub fn random(rng: &mut R) -> Self { Self { inner: C::Uint::random_mod(rng, &NonZero::new(Self::MODULUS).unwrap()), } diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index f1559c8c4..9e9df1f38 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -94,7 +94,7 @@ where /// Generate a random [`SecretKey`]. #[cfg(feature = "arithmetic")] - pub fn random(rng: &mut R) -> Self + pub fn random(rng: &mut R) -> Self where C: CurveArithmetic, { diff --git a/kem/src/lib.rs b/kem/src/lib.rs index 06365882a..415764764 100644 --- a/kem/src/lib.rs +++ b/kem/src/lib.rs @@ -20,7 +20,7 @@ pub trait Encapsulate { type Error: Debug; /// Encapsulates a fresh shared secret - fn encapsulate(&self, rng: &mut impl CryptoRng) -> Result<(EK, SS), Self::Error>; + fn encapsulate(&self, rng: &mut R) -> Result<(EK, SS), Self::Error>; } /// A value that can be used to decapsulate an encapsulated key. diff --git a/password-hash/src/salt.rs b/password-hash/src/salt.rs index d96abe291..c42f8b6ef 100644 --- a/password-hash/src/salt.rs +++ b/password-hash/src/salt.rs @@ -203,7 +203,7 @@ pub struct SaltString { impl SaltString { /// Generate a random B64-encoded [`SaltString`] from [`CryptoRng`]. #[cfg(feature = "rand_core")] - pub fn from_rng(rng: &mut R) -> Self { + pub fn from_rng(rng: &mut R) -> Self { let mut bytes = [0u8; Salt::RECOMMENDED_LENGTH]; rng.fill_bytes(&mut bytes); Self::encode_b64(&bytes).expect(INVARIANT_VIOLATED_MSG) @@ -211,7 +211,9 @@ impl SaltString { /// Generate a random B64-encoded [`SaltString`] from [`TryCryptoRng`]. #[cfg(feature = "rand_core")] - pub fn try_from_rng(rng: &mut R) -> core::result::Result { + pub fn try_from_rng( + rng: &mut R, + ) -> core::result::Result { let mut bytes = [0u8; Salt::RECOMMENDED_LENGTH]; rng.try_fill_bytes(&mut bytes)?; let salt = Self::encode_b64(&bytes).expect(INVARIANT_VIOLATED_MSG); From 67131afeab8f235bb1698f94585bb84c8afd9716 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Apr 2025 05:57:09 +0300 Subject: [PATCH 1315/1461] build(deps): bump crate-ci/typos from 1.30.0 to 1.31.1 (#1807) --- .github/workflows/workspace.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index ad7e67c33..26781a0e1 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -52,4 +52,4 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: crate-ci/typos@v1.30.0 + - uses: crate-ci/typos@v1.31.1 From 0397384348dc62db97c9bf71af145f068727864a Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Mon, 7 Apr 2025 15:06:26 +0300 Subject: [PATCH 1316/1461] digest: move `std::io` stuff to `digest-io` (#1809) The `digest-io` crate is added in https://github.com/RustCrypto/utils/pull/1172 --- .github/workflows/digest.yml | 1 - crypto/Cargo.toml | 1 - digest/CHANGELOG.md | 3 + digest/Cargo.toml | 1 - digest/src/core_api/rt_variable.rs | 14 --- digest/src/core_api/wrapper.rs | 14 --- digest/src/core_api/xof_reader.rs | 12 --- digest/src/hashreader.rs | 136 ----------------------------- digest/src/hashwriter.rs | 121 ------------------------- digest/src/lib.rs | 21 ++--- 10 files changed, 9 insertions(+), 315 deletions(-) delete mode 100644 digest/src/hashreader.rs delete mode 100644 digest/src/hashwriter.rs diff --git a/.github/workflows/digest.yml b/.github/workflows/digest.yml index e2f6e0eb0..f89b13c5d 100644 --- a/.github/workflows/digest.yml +++ b/.github/workflows/digest.yml @@ -60,5 +60,4 @@ jobs: - run: cargo test - run: cargo test --features dev - run: cargo test --features alloc - - run: cargo test --features std - run: cargo test --all-features diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 6aa12dd93..28782c641 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -26,7 +26,6 @@ universal-hash = { version = "0.6.0-rc.0", path = "../universal-hash", optional [features] std = [ - "digest/std", "elliptic-curve/std", "signature/std", ] diff --git a/digest/CHANGELOG.md b/digest/CHANGELOG.md index a6c58234d..8af2a4d3d 100644 --- a/digest/CHANGELOG.md +++ b/digest/CHANGELOG.md @@ -15,10 +15,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Removed - `Mac::new`, `Mac::new_from_slice`, and `Mac::generate_key` methods ([#1173]) +- `HashReader` and `HashWriter` are moved to the `digest-io` crate ([#1809]) +- Removed `io::Write/Read` implementations in favor of the `digest_io::IoWrapper` type ([#1809]) [#1173]: https://github.com/RustCrypto/traits/pull/1173 [#1334]: https://github.com/RustCrypto/traits/pull/1334 [#1759]: https://github.com/RustCrypto/traits/pull/1759 +[#1809]: https://github.com/RustCrypto/traits/pull/1809 ## 0.10.7 (2023-05-19) ### Changed diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 9f277b796..7f41d294e 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -31,7 +31,6 @@ os_rng = ["crypto-common/rand_core", "rand_core"] oid = ["const-oid"] zeroize = ["dep:zeroize", "block-buffer?/zeroize"] alloc = [] -std = ["alloc"] dev = ["blobby"] [package.metadata.docs.rs] diff --git a/digest/src/core_api/rt_variable.rs b/digest/src/core_api/rt_variable.rs index 17f13ae8e..1cb212ea9 100644 --- a/digest/src/core_api/rt_variable.rs +++ b/digest/src/core_api/rt_variable.rs @@ -184,17 +184,3 @@ where }) } } - -#[cfg(feature = "std")] -impl std::io::Write for RtVariableCoreWrapper { - #[inline] - fn write(&mut self, buf: &[u8]) -> std::io::Result { - Update::update(self, buf); - Ok(buf.len()) - } - - #[inline] - fn flush(&mut self) -> std::io::Result<()> { - Ok(()) - } -} diff --git a/digest/src/core_api/wrapper.rs b/digest/src/core_api/wrapper.rs index 55062e7c8..8d4cf6413 100644 --- a/digest/src/core_api/wrapper.rs +++ b/digest/src/core_api/wrapper.rs @@ -220,20 +220,6 @@ where } } -#[cfg(feature = "std")] -impl std::io::Write for CoreWrapper { - #[inline] - fn write(&mut self, buf: &[u8]) -> std::io::Result { - Update::update(self, buf); - Ok(buf.len()) - } - - #[inline] - fn flush(&mut self) -> std::io::Result<()> { - Ok(()) - } -} - /// A proxy trait to a core type implemented by [`CoreWrapper`] // TODO: replace with an inherent associated type on stabilization: // https://github.com/rust-lang/rust/issues/8995 diff --git a/digest/src/core_api/xof_reader.rs b/digest/src/core_api/xof_reader.rs index 0c832df0c..0bb63933c 100644 --- a/digest/src/core_api/xof_reader.rs +++ b/digest/src/core_api/xof_reader.rs @@ -36,18 +36,6 @@ where } } -#[cfg(feature = "std")] -impl std::io::Read for XofReaderCoreWrapper -where - T: XofReaderCore, -{ - #[inline] - fn read(&mut self, buf: &mut [u8]) -> std::io::Result { - XofReader::read(self, buf); - Ok(buf.len()) - } -} - impl Drop for XofReaderCoreWrapper { #[inline] fn drop(&mut self) { diff --git a/digest/src/hashreader.rs b/digest/src/hashreader.rs deleted file mode 100644 index eaca370b4..000000000 --- a/digest/src/hashreader.rs +++ /dev/null @@ -1,136 +0,0 @@ -//! Adds hashing to any reader -use super::{Digest, FixedOutputReset, Output, Reset}; -use std::io; - -/// Abstraction over a reader which hashes the data being read -#[derive(Debug)] -pub struct HashReader { - reader: R, - hasher: D, -} - -impl HashReader { - /// Construct a new `HashReader` given an existing `reader` by value. - pub fn new(reader: R) -> Self { - Self::new_from_parts(D::new(), reader) - } - - /// Construct a new `HashReader` given an existing `hasher` and `reader` by value. - pub fn new_from_parts(hasher: D, reader: R) -> Self { - HashReader { reader, hasher } - } - - /// Replace the reader with another reader - pub fn replace_reader(&mut self, reader: R) { - self.reader = reader; - } - - /// Gets a reference to the underlying hasher - pub fn get_hasher(&self) -> &D { - &self.hasher - } - - /// Gets a reference to the underlying reader - pub fn get_reader(&self) -> &R { - &self.reader - } - - /// Gets a mutable reference to the underlying hasher - pub fn get_hasher_mut(&mut self) -> &mut D { - &mut self.hasher - } - - /// Gets a mutable reference to the underlying reader - /// Direct reads from the underlying reader are not hashed - pub fn get_reader_mut(&mut self) -> &mut R { - &mut self.reader - } - - /// Consume the HashReader and return its hasher - pub fn into_hasher(self) -> D { - self.hasher - } - - /// Consume the HashReader and return its internal reader - pub fn into_inner_reader(self) -> R { - self.reader - } - - /// Consume the HashReader and return its hasher and internal reader - pub fn into_parts(self) -> (D, R) { - (self.hasher, self.reader) - } - - /// Retrieve result and consume HashReader instance. - pub fn finalize(self) -> Output { - self.hasher.finalize() - } - - /// Write result into provided array and consume the HashReader instance. - pub fn finalize_into(self, out: &mut Output) { - self.hasher.finalize_into(out) - } - - /// Get output size of the hasher - pub fn output_size() -> usize { - ::output_size() - } -} - -impl Clone for HashReader { - fn clone(&self) -> HashReader { - HashReader { - reader: self.reader.clone(), - hasher: self.hasher.clone(), - } - } -} - -impl io::Read for HashReader { - fn read(&mut self, buf: &mut [u8]) -> io::Result { - let bytes = self.reader.read(buf)?; - - if bytes > 0 { - self.hasher.update(&buf[0..bytes]); - } - - Ok(bytes) - } -} - -impl HashReader { - /// Retrieve result and reset hasher instance. - pub fn finalize_reset(&mut self) -> Output { - Digest::finalize_reset(&mut self.hasher) - } - - /// Rrite result into provided array and reset the hasher instance. - pub fn finalize_into_reset(&mut self, out: &mut Output) { - Digest::finalize_into_reset(&mut self.hasher, out) - } -} -impl Reset for HashReader { - fn reset(&mut self) { - Digest::reset(&mut self.hasher) - } -} - -impl HashReader { - /// Read and hash all bytes remaining in the reader, discarding the data - /// Based on implementation in b2sum crate, MIT License Copyright (c) 2017 John Downey - pub fn hash_to_end(&mut self) { - loop { - let count = { - let data = self.reader.fill_buf().unwrap(); - if data.is_empty() { - break; - } - - self.hasher.update(data); - data.len() - }; - - self.reader.consume(count); - } - } -} diff --git a/digest/src/hashwriter.rs b/digest/src/hashwriter.rs deleted file mode 100644 index 354590385..000000000 --- a/digest/src/hashwriter.rs +++ /dev/null @@ -1,121 +0,0 @@ -//! Adds hashing to any writer. Inspired by implementation in phase2 crate. -use super::{Digest, FixedOutputReset, Output, Reset}; -use std::io; - -/// Abstraction over a writer which hashes the data being written. -#[derive(Debug)] -pub struct HashWriter { - writer: W, - hasher: D, -} - -impl HashWriter { - /// Construct a new `HashWriter` given an existing `writer` by value. - pub fn new(writer: W) -> Self { - Self::new_from_parts(D::new(), writer) - } - - /// Construct a new `HashWriter` given an existing `hasher` and `writer` by value. - pub fn new_from_parts(hasher: D, writer: W) -> Self { - HashWriter { writer, hasher } - } - - /// Replace the writer with another writer - pub fn replace_writer(&mut self, writer: W) { - self.writer = writer; - } - - /// Gets a reference to the underlying hasher - pub fn get_hasher(&self) -> &D { - &self.hasher - } - - /// Gets a reference to the underlying writer - pub fn get_writer(&self) -> &W { - &self.writer - } - - /// Gets a mutable reference to the underlying hasher - /// Updates to the digest are not written to the underlying writer - pub fn get_hasher_mut(&mut self) -> &mut D { - &mut self.hasher - } - - /// Gets a mutable reference to the underlying writer - /// Direct writes to the underlying writer are not hashed - pub fn get_writer_mut(&mut self) -> &mut W { - &mut self.writer - } - - /// Consume the HashWriter and return its hasher - pub fn into_hasher(self) -> D { - self.hasher - } - - /// Consume the HashWriter and return its internal writer - pub fn into_inner_writer(self) -> W { - self.writer - } - - /// Consume the HashWriter and return its hasher and internal writer - pub fn into_parts(self) -> (D, W) { - (self.hasher, self.writer) - } - - /// Retrieve result and consume HashWriter instance. - pub fn finalize(self) -> Output { - self.hasher.finalize() - } - - /// Write result into provided array and consume the HashWriter instance. - pub fn finalize_into(self, out: &mut Output) { - self.hasher.finalize_into(out) - } - - /// Get output size of the hasher - pub fn output_size() -> usize { - ::output_size() - } -} - -impl Clone for HashWriter { - fn clone(&self) -> HashWriter { - HashWriter { - writer: self.writer.clone(), - hasher: self.hasher.clone(), - } - } -} - -impl io::Write for HashWriter { - fn write(&mut self, buf: &[u8]) -> io::Result { - let bytes = self.writer.write(buf)?; - - if bytes > 0 { - self.hasher.update(&buf[0..bytes]); - } - - Ok(bytes) - } - - fn flush(&mut self) -> io::Result<()> { - self.writer.flush() - } -} - -impl HashWriter { - /// Retrieve result and reset hasher instance. - pub fn finalize_reset(&mut self) -> Output { - Digest::finalize_reset(&mut self.hasher) - } - - /// Write result into provided array and reset the hasher instance. - pub fn finalize_into_reset(&mut self, out: &mut Output) { - Digest::finalize_into_reset(&mut self.hasher, out) - } -} -impl Reset for HashWriter { - fn reset(&mut self) { - Digest::reset(&mut self.hasher) - } -} diff --git a/digest/src/lib.rs b/digest/src/lib.rs index bd9f3c035..e323f3640 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -18,9 +18,12 @@ //! Usually they should not be used in application-level code. //! //! Additionally hash functions implement traits from the standard library: -//! [`Default`], [`Clone`], [`Write`][std::io::Write]. The latter is -//! feature-gated behind `std` feature, which is usually enabled by default -//! by hash implementation crates. +//! [`Default`] and [`Clone`]. +//! +//! This crate does not provide any implementations of the `io::Read/Write` traits, +//! see the [`digest-io`] crate for `std::io`-compatibility wrappers. +//! +//! [`digest-io`]: https://docs.rs/digest-io #![no_std] #![cfg_attr(docsrs, feature(doc_auto_cfg))] @@ -35,9 +38,6 @@ #[macro_use] extern crate alloc; -#[cfg(feature = "std")] -extern crate std; - #[cfg(feature = "rand_core")] pub use crypto_common::rand_core; @@ -303,12 +303,3 @@ impl fmt::Display for InvalidBufferSize { } impl core::error::Error for InvalidBufferSize {} - -#[cfg(feature = "std")] -mod hashwriter; -#[cfg(feature = "std")] -pub use hashwriter::HashWriter; -#[cfg(feature = "std")] -mod hashreader; -#[cfg(feature = "std")] -pub use hashreader::HashReader; From c48ea2a4f76127bd3febce8240095b893e6edb1c Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Mon, 7 Apr 2025 16:12:26 +0300 Subject: [PATCH 1317/1461] digest: remove `AssociatedOid` blanket impls for wrappers (#1810) Together with https://github.com/RustCrypto/traits/pull/1799 users would need to implement `AssociatedOid` manually for created newtypes. Also replaces `feature = "const-oid"` with `feature = "oid"`. --- digest/CHANGELOG.md | 5 ++- digest/src/core_api/ct_variable.rs | 67 +++++++----------------------- digest/src/core_api/wrapper.rs | 10 ----- digest/src/digest.rs | 6 +-- digest/src/lib.rs | 2 +- 5 files changed, 24 insertions(+), 66 deletions(-) diff --git a/digest/CHANGELOG.md b/digest/CHANGELOG.md index 8af2a4d3d..237e7887b 100644 --- a/digest/CHANGELOG.md +++ b/digest/CHANGELOG.md @@ -16,12 +16,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Removed - `Mac::new`, `Mac::new_from_slice`, and `Mac::generate_key` methods ([#1173]) - `HashReader` and `HashWriter` are moved to the `digest-io` crate ([#1809]) -- Removed `io::Write/Read` implementations in favor of the `digest_io::IoWrapper` type ([#1809]) +- `io::Write/Read` implementations in favor of the `digest_io::IoWrapper` type ([#1809]) +- `AssociatedOid` blanket impls for `CoreWrapper` and `CtVariableCoreWrapper` ([#1810]) +- `impl_oid_carrier!` macro ([#1810]) [#1173]: https://github.com/RustCrypto/traits/pull/1173 [#1334]: https://github.com/RustCrypto/traits/pull/1334 [#1759]: https://github.com/RustCrypto/traits/pull/1759 [#1809]: https://github.com/RustCrypto/traits/pull/1809 +[#1810]: https://github.com/RustCrypto/traits/pull/1810 ## 0.10.7 (2023-05-19) ### Changed diff --git a/digest/src/core_api/ct_variable.rs b/digest/src/core_api/ct_variable.rs index 983f610cd..eeb9cd554 100644 --- a/digest/src/core_api/ct_variable.rs +++ b/digest/src/core_api/ct_variable.rs @@ -5,8 +5,6 @@ use super::{ #[cfg(feature = "mac")] use crate::MacMarker; use crate::{CustomizedInit, HashMarker, VarOutputCustomized}; -#[cfg(feature = "oid")] -use const_oid::{AssociatedOid, ObjectIdentifier}; use core::{ fmt, marker::PhantomData, @@ -18,26 +16,20 @@ use crypto_common::{ hazmat::{DeserializeStateError, SerializableState, SerializedState, SubSerializedStateSize}, typenum::{IsLess, IsLessOrEqual, Le, LeEq, NonZero, Sum, U1, U256}, }; - -/// Dummy type used with [`CtVariableCoreWrapper`] in cases when -/// resulting hash does not have a known OID. -#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] -pub struct NoOid; - /// Wrapper around [`VariableOutputCore`] which selects output size /// at compile time. #[derive(Clone)] -pub struct CtVariableCoreWrapper +pub struct CtVariableCoreWrapper where T: VariableOutputCore, OutSize: ArraySize + IsLessOrEqual, LeEq: NonZero, { inner: T, - _out: PhantomData<(OutSize, O)>, + _out: PhantomData, } -impl HashMarker for CtVariableCoreWrapper +impl HashMarker for CtVariableCoreWrapper where T: VariableOutputCore + HashMarker, OutSize: ArraySize + IsLessOrEqual, @@ -46,7 +38,7 @@ where } #[cfg(feature = "mac")] -impl MacMarker for CtVariableCoreWrapper +impl MacMarker for CtVariableCoreWrapper where T: VariableOutputCore + MacMarker, OutSize: ArraySize + IsLessOrEqual, @@ -54,7 +46,7 @@ where { } -impl BlockSizeUser for CtVariableCoreWrapper +impl BlockSizeUser for CtVariableCoreWrapper where T: VariableOutputCore, OutSize: ArraySize + IsLessOrEqual, @@ -63,7 +55,7 @@ where type BlockSize = T::BlockSize; } -impl UpdateCore for CtVariableCoreWrapper +impl UpdateCore for CtVariableCoreWrapper where T: VariableOutputCore, OutSize: ArraySize + IsLessOrEqual, @@ -75,7 +67,7 @@ where } } -impl OutputSizeUser for CtVariableCoreWrapper +impl OutputSizeUser for CtVariableCoreWrapper where T: VariableOutputCore, OutSize: ArraySize + IsLessOrEqual, @@ -84,7 +76,7 @@ where type OutputSize = OutSize; } -impl BufferKindUser for CtVariableCoreWrapper +impl BufferKindUser for CtVariableCoreWrapper where T: VariableOutputCore, OutSize: ArraySize + IsLessOrEqual, @@ -93,7 +85,7 @@ where type BufferKind = T::BufferKind; } -impl FixedOutputCore for CtVariableCoreWrapper +impl FixedOutputCore for CtVariableCoreWrapper where T: VariableOutputCore, OutSize: ArraySize + IsLessOrEqual, @@ -116,7 +108,7 @@ where } } -impl Default for CtVariableCoreWrapper +impl Default for CtVariableCoreWrapper where T: VariableOutputCore, OutSize: ArraySize + IsLessOrEqual, @@ -131,7 +123,7 @@ where } } -impl CustomizedInit for CtVariableCoreWrapper +impl CustomizedInit for CtVariableCoreWrapper where T: VariableOutputCore + VarOutputCustomized, OutSize: ArraySize + IsLessOrEqual, @@ -146,7 +138,7 @@ where } } -impl Reset for CtVariableCoreWrapper +impl Reset for CtVariableCoreWrapper where T: VariableOutputCore, OutSize: ArraySize + IsLessOrEqual, @@ -158,7 +150,7 @@ where } } -impl AlgorithmName for CtVariableCoreWrapper +impl AlgorithmName for CtVariableCoreWrapper where T: VariableOutputCore + AlgorithmName, OutSize: ArraySize + IsLessOrEqual, @@ -171,19 +163,8 @@ where } } -#[cfg(feature = "oid")] -impl AssociatedOid for CtVariableCoreWrapper -where - T: VariableOutputCore, - O: AssociatedOid, - OutSize: ArraySize + IsLessOrEqual, - LeEq: NonZero, -{ - const OID: ObjectIdentifier = O::OID; -} - #[cfg(feature = "zeroize")] -impl zeroize::ZeroizeOnDrop for CtVariableCoreWrapper +impl zeroize::ZeroizeOnDrop for CtVariableCoreWrapper where T: VariableOutputCore + zeroize::ZeroizeOnDrop, OutSize: ArraySize + IsLessOrEqual, @@ -191,7 +172,7 @@ where { } -impl fmt::Debug for CtVariableCoreWrapper +impl fmt::Debug for CtVariableCoreWrapper where T: VariableOutputCore + AlgorithmName, OutSize: ArraySize + IsLessOrEqual, @@ -202,26 +183,10 @@ where } } -/// Implement dummy type with hidden docs which is used to "carry" hasher -/// OID for [`CtVariableCoreWrapper`]. -#[macro_export] -macro_rules! impl_oid_carrier { - ($name:ident, $oid:literal) => { - #[doc(hidden)] - #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] - pub struct $name; - - #[cfg(feature = "oid")] - impl AssociatedOid for $name { - const OID: ObjectIdentifier = ObjectIdentifier::new_unwrap($oid); - } - }; -} - type CtVariableCoreWrapperSerializedStateSize = Sum<::SerializedStateSize, U1>; -impl SerializableState for CtVariableCoreWrapper +impl SerializableState for CtVariableCoreWrapper where T: VariableOutputCore + SerializableState, OutSize: ArraySize + IsLessOrEqual, diff --git a/digest/src/core_api/wrapper.rs b/digest/src/core_api/wrapper.rs index 8d4cf6413..6cd006fab 100644 --- a/digest/src/core_api/wrapper.rs +++ b/digest/src/core_api/wrapper.rs @@ -21,8 +21,6 @@ use crypto_common::{ #[cfg(feature = "mac")] use crate::MacMarker; -#[cfg(feature = "oid")] -use const_oid::{AssociatedOid, ObjectIdentifier}; /// Wrapper around [`BufferKindUser`]. /// @@ -171,14 +169,6 @@ where } } -#[cfg(feature = "oid")] -impl AssociatedOid for CoreWrapper -where - T: BufferKindUser + AssociatedOid, -{ - const OID: ObjectIdentifier = T::OID; -} - type CoreWrapperSerializedStateSize = Sum::SerializedStateSize, U1>, ::BlockSize>; diff --git a/digest/src/digest.rs b/digest/src/digest.rs index 1de1ea86d..ef084928a 100644 --- a/digest/src/digest.rs +++ b/digest/src/digest.rs @@ -3,7 +3,7 @@ use crypto_common::{Output, OutputSizeUser, typenum::Unsigned}; #[cfg(feature = "alloc")] use alloc::boxed::Box; -#[cfg(feature = "const-oid")] +#[cfg(feature = "oid")] use const_oid::DynAssociatedOid; /// Marker trait for cryptographic hash functions. @@ -228,8 +228,8 @@ impl Clone for Box { } /// Convenience wrapper trait around [DynDigest] and [DynAssociatedOid]. -#[cfg(feature = "const-oid")] +#[cfg(feature = "oid")] pub trait DynDigestWithOid: DynDigest + DynAssociatedOid {} -#[cfg(feature = "const-oid")] +#[cfg(feature = "oid")] impl DynDigestWithOid for T {} diff --git a/digest/src/lib.rs b/digest/src/lib.rs index e323f3640..b0febdf1a 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -62,7 +62,7 @@ pub use block_buffer; pub use const_oid; pub use crypto_common; -#[cfg(feature = "const-oid")] +#[cfg(feature = "oid")] pub use crate::digest::DynDigestWithOid; pub use crate::digest::{Digest, DynDigest, HashMarker}; #[cfg(feature = "mac")] From 6fbdc179756379c823a53c0d5a60e0a40baeb765 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Tue, 8 Apr 2025 04:40:10 +0300 Subject: [PATCH 1318/1461] Remove explicit passing of the `docsrs` configuration flag (#1811) The flag is passed automatically by docs.rs. --- aead/Cargo.toml | 1 - async-signature/Cargo.toml | 1 - cipher/Cargo.toml | 1 - crypto-common/Cargo.toml | 1 - crypto/Cargo.toml | 1 - digest/Cargo.toml | 1 - elliptic-curve/Cargo.toml | 1 - kem/Cargo.toml | 1 - password-hash/Cargo.toml | 1 - signature/Cargo.toml | 1 - universal-hash/Cargo.toml | 1 - 11 files changed, 11 deletions(-) diff --git a/aead/Cargo.toml b/aead/Cargo.toml index f004bc699..359edd7d7 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -34,4 +34,3 @@ rand_core = ["crypto-common/rand_core"] [package.metadata.docs.rs] all-features = true -rustdoc-args = ["--cfg", "docsrs"] diff --git a/async-signature/Cargo.toml b/async-signature/Cargo.toml index dd25ff887..6a2029127 100644 --- a/async-signature/Cargo.toml +++ b/async-signature/Cargo.toml @@ -22,4 +22,3 @@ rand_core = ["signature/rand_core"] [package.metadata.docs.rs] all-features = true -rustdoc-args = ["--cfg", "docsrs"] diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index b59bd1513..4ef179087 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -31,4 +31,3 @@ zeroize = ["dep:zeroize", "crypto-common/zeroize"] [package.metadata.docs.rs] all-features = true -rustdoc-args = ["--cfg", "docsrs"] diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index 84df0c67e..42d338368 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -25,4 +25,3 @@ zeroize = ["hybrid-array/zeroize"] [package.metadata.docs.rs] all-features = true -rustdoc-args = ["--cfg", "docsrs"] diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 28782c641..4e37d83a1 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -34,4 +34,3 @@ rand_core = ["crypto-common/rand_core"] [package.metadata.docs.rs] all-features = true -rustdoc-args = ["--cfg", "docsrs"] diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 7f41d294e..db79a487d 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -35,4 +35,3 @@ dev = ["blobby"] [package.metadata.docs.rs] all-features = true -rustdoc-args = ["--cfg", "docsrs"] diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index f607a2c38..36f2a3ca1 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -74,4 +74,3 @@ voprf = ["digest"] [package.metadata.docs.rs] features = ["bits", "ecdh", "hash2curve", "jwk", "pem", "std", "voprf"] -rustdoc-args = ["--cfg", "docsrs"] diff --git a/kem/Cargo.toml b/kem/Cargo.toml index 4ffbf627e..f6d0e7a61 100644 --- a/kem/Cargo.toml +++ b/kem/Cargo.toml @@ -18,7 +18,6 @@ zeroize = { version = "1.7", default-features = false } [package.metadata.docs.rs] all-features = true -rustdoc-args = ["--cfg", "docsrs"] [lib] doctest = false diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index 7319b7dd7..8e6ba2813 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -31,4 +31,3 @@ alloc = ["base64ct/alloc"] [package.metadata.docs.rs] all-features = true -rustdoc-args = ["--cfg", "docsrs"] diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 38fe3fea3..6918ba36f 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -29,4 +29,3 @@ rand_core = ["dep:rand_core"] [package.metadata.docs.rs] all-features = true -rustdoc-args = ["--cfg", "docsrs"] diff --git a/universal-hash/Cargo.toml b/universal-hash/Cargo.toml index 22733619d..588a82003 100644 --- a/universal-hash/Cargo.toml +++ b/universal-hash/Cargo.toml @@ -18,4 +18,3 @@ subtle = { version = "2.4", default-features = false } [package.metadata.docs.rs] all-features = true -rustdoc-args = ["--cfg", "docsrs"] From ad1c1acbc1027c0c58880651b597c59e03283df4 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 14 Apr 2025 19:54:01 +0900 Subject: [PATCH 1319/1461] aead: move `Aead` ahead of `AeadInOut` (#1817) This follows an alphabetic ordering and ordering-of-interest, which should improve documentation --- aead/src/lib.rs | 164 ++++++++++++++++++++++++------------------------ 1 file changed, 82 insertions(+), 82 deletions(-) diff --git a/aead/src/lib.rs b/aead/src/lib.rs index 140c6e19a..a78c470cd 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -159,6 +159,88 @@ pub trait AeadCore { } } +/// Authenticated Encryption with Associated Data (AEAD) algorithm. +#[cfg(feature = "alloc")] +pub trait Aead: AeadCore { + /// Encrypt the given plaintext payload, and return the resulting + /// ciphertext as a vector of bytes. + /// + /// The [`Payload`] type can be used to provide Additional Associated Data + /// (AAD) along with the message: this is an optional bytestring which is + /// not encrypted, but *is* authenticated along with the message. Failure + /// to pass the same AAD that was used during encryption will cause + /// decryption to fail, which is useful if you would like to "bind" the + /// ciphertext to some other identifier, like a digital signature key + /// or other identifier. + /// + /// If you don't care about AAD and just want to encrypt a plaintext + /// message, `&[u8]` will automatically be coerced into a `Payload`: + /// + /// ```nobuild + /// let plaintext = b"Top secret message, handle with care"; + /// let ciphertext = cipher.encrypt(nonce, plaintext); + /// ``` + /// + /// The default implementation assumes a postfix tag (ala AES-GCM, + /// AES-GCM-SIV, ChaCha20Poly1305). [`Aead`] implementations which do not + /// use a postfix tag will need to override this to correctly assemble the + /// ciphertext message. + fn encrypt<'msg, 'aad>( + &self, + nonce: &Nonce, + plaintext: impl Into>, + ) -> Result>; + + /// Decrypt the given ciphertext slice, and return the resulting plaintext + /// as a vector of bytes. + /// + /// See notes on [`Aead::encrypt()`] about allowable message payloads and + /// Associated Additional Data (AAD). + /// + /// If you have no AAD, you can call this as follows: + /// + /// ```nobuild + /// let ciphertext = b"..."; + /// let plaintext = cipher.decrypt(nonce, ciphertext)?; + /// ``` + /// + /// The default implementation assumes a postfix tag (ala AES-GCM, + /// AES-GCM-SIV, ChaCha20Poly1305). [`Aead`] implementations which do not + /// use a postfix tag will need to override this to correctly parse the + /// ciphertext message. + fn decrypt<'msg, 'aad>( + &self, + nonce: &Nonce, + ciphertext: impl Into>, + ) -> Result>; +} + +#[cfg(feature = "alloc")] +impl Aead for T { + fn encrypt<'msg, 'aad>( + &self, + nonce: &Nonce, + plaintext: impl Into>, + ) -> Result> { + let payload = plaintext.into(); + let mut buffer = Vec::with_capacity(payload.msg.len() + Self::TagSize::to_usize()); + buffer.extend_from_slice(payload.msg); + self.encrypt_in_place(nonce, payload.aad, &mut buffer)?; + Ok(buffer) + } + + fn decrypt<'msg, 'aad>( + &self, + nonce: &Nonce, + ciphertext: impl Into>, + ) -> Result> { + let payload = ciphertext.into(); + let mut buffer = Vec::from(payload.msg); + self.decrypt_in_place(nonce, payload.aad, &mut buffer)?; + Ok(buffer) + } +} + /// In-place and inout AEAD trait which handles the authentication tag as a return value/separate parameter. pub trait AeadInOut: AeadCore { /// Encrypt the data in the provided [`InOutBuf`], returning the authentication tag. @@ -247,88 +329,6 @@ pub trait AeadInOut: AeadCore { } } -/// Authenticated Encryption with Associated Data (AEAD) algorithm. -#[cfg(feature = "alloc")] -pub trait Aead: AeadCore { - /// Encrypt the given plaintext payload, and return the resulting - /// ciphertext as a vector of bytes. - /// - /// The [`Payload`] type can be used to provide Additional Associated Data - /// (AAD) along with the message: this is an optional bytestring which is - /// not encrypted, but *is* authenticated along with the message. Failure - /// to pass the same AAD that was used during encryption will cause - /// decryption to fail, which is useful if you would like to "bind" the - /// ciphertext to some other identifier, like a digital signature key - /// or other identifier. - /// - /// If you don't care about AAD and just want to encrypt a plaintext - /// message, `&[u8]` will automatically be coerced into a `Payload`: - /// - /// ```nobuild - /// let plaintext = b"Top secret message, handle with care"; - /// let ciphertext = cipher.encrypt(nonce, plaintext); - /// ``` - /// - /// The default implementation assumes a postfix tag (ala AES-GCM, - /// AES-GCM-SIV, ChaCha20Poly1305). [`Aead`] implementations which do not - /// use a postfix tag will need to override this to correctly assemble the - /// ciphertext message. - fn encrypt<'msg, 'aad>( - &self, - nonce: &Nonce, - plaintext: impl Into>, - ) -> Result>; - - /// Decrypt the given ciphertext slice, and return the resulting plaintext - /// as a vector of bytes. - /// - /// See notes on [`Aead::encrypt()`] about allowable message payloads and - /// Associated Additional Data (AAD). - /// - /// If you have no AAD, you can call this as follows: - /// - /// ```nobuild - /// let ciphertext = b"..."; - /// let plaintext = cipher.decrypt(nonce, ciphertext)?; - /// ``` - /// - /// The default implementation assumes a postfix tag (ala AES-GCM, - /// AES-GCM-SIV, ChaCha20Poly1305). [`Aead`] implementations which do not - /// use a postfix tag will need to override this to correctly parse the - /// ciphertext message. - fn decrypt<'msg, 'aad>( - &self, - nonce: &Nonce, - ciphertext: impl Into>, - ) -> Result>; -} - -#[cfg(feature = "alloc")] -impl Aead for T { - fn encrypt<'msg, 'aad>( - &self, - nonce: &Nonce, - plaintext: impl Into>, - ) -> Result> { - let payload = plaintext.into(); - let mut buffer = Vec::with_capacity(payload.msg.len() + Self::TagSize::to_usize()); - buffer.extend_from_slice(payload.msg); - self.encrypt_in_place(nonce, payload.aad, &mut buffer)?; - Ok(buffer) - } - - fn decrypt<'msg, 'aad>( - &self, - nonce: &Nonce, - ciphertext: impl Into>, - ) -> Result> { - let payload = ciphertext.into(); - let mut buffer = Vec::from(payload.msg); - self.decrypt_in_place(nonce, payload.aad, &mut buffer)?; - Ok(buffer) - } -} - /// AEAD payloads (message + AAD). /// /// Combination of a message (plaintext or ciphertext) and From 25962771e032b3684cc72412df2000b37056586e Mon Sep 17 00:00:00 2001 From: daxpedda Date: Mon, 14 Apr 2025 16:22:06 +0200 Subject: [PATCH 1320/1461] digest: add `XofFixedWrapper` (#1815) --- digest/src/lib.rs | 2 + digest/src/xof_fixed.rs | 146 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 148 insertions(+) create mode 100644 digest/src/xof_fixed.rs diff --git a/digest/src/lib.rs b/digest/src/lib.rs index b0febdf1a..6537d84a9 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -55,6 +55,7 @@ pub mod core_api; mod digest; #[cfg(feature = "mac")] mod mac; +mod xof_fixed; #[cfg(feature = "core-api")] pub use block_buffer; @@ -70,6 +71,7 @@ pub use crypto_common::{InnerInit, InvalidLength, Key, KeyInit}; pub use crypto_common::{Output, OutputSizeUser, Reset, array, typenum, typenum::consts}; #[cfg(feature = "mac")] pub use mac::{CtOutput, Mac, MacError, MacMarker}; +pub use xof_fixed::XofFixedWrapper; use core::fmt; diff --git a/digest/src/xof_fixed.rs b/digest/src/xof_fixed.rs new file mode 100644 index 000000000..d852904bf --- /dev/null +++ b/digest/src/xof_fixed.rs @@ -0,0 +1,146 @@ +use core::fmt; +use core::marker::PhantomData; + +use crypto_common::array::ArraySize; +use crypto_common::hazmat::SerializableState; +use crypto_common::{BlockSizeUser, KeyInit, KeySizeUser, OutputSizeUser, Reset}; + +use crate::{ + CustomizedInit, ExtendableOutput, ExtendableOutputReset, FixedOutput, FixedOutputReset, + HashMarker, Update, +}; + +/// Wrapper around [`ExtendableOutput`] types adding [`OutputSizeUser`] with the given size of `S`. +pub struct XofFixedWrapper { + hash: T, + size: PhantomData, +} + +impl Clone for XofFixedWrapper { + fn clone(&self) -> Self { + Self { + hash: self.hash.clone(), + size: PhantomData, + } + } +} + +impl fmt::Debug for XofFixedWrapper { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("XofFixedWrapper") + .field("hash", &self.hash) + .field("_size", &self.size) + .finish() + } +} + +impl Default for XofFixedWrapper { + fn default() -> Self { + Self { + hash: Default::default(), + size: PhantomData, + } + } +} + +impl HashMarker for XofFixedWrapper {} + +#[cfg(feature = "mac")] +impl crate::MacMarker + for XofFixedWrapper +{ +} + +// this blanket impl is needed for HMAC +impl BlockSizeUser for XofFixedWrapper { + type BlockSize = T::BlockSize; +} + +impl KeySizeUser for XofFixedWrapper { + type KeySize = T::KeySize; +} + +impl KeyInit for XofFixedWrapper { + fn new(key: &crypto_common::Key) -> Self { + Self { + hash: T::new(key), + size: PhantomData, + } + } +} + +impl Reset for XofFixedWrapper { + fn reset(&mut self) { + self.hash.reset(); + } +} + +impl Update for XofFixedWrapper { + fn update(&mut self, data: &[u8]) { + self.hash.update(data) + } +} + +impl OutputSizeUser for XofFixedWrapper { + type OutputSize = S; +} + +impl FixedOutput for XofFixedWrapper { + fn finalize_into(self, out: &mut crypto_common::Output) { + self.hash.finalize_xof_into(out); + } +} + +impl FixedOutputReset for XofFixedWrapper { + fn finalize_into_reset(&mut self, out: &mut crypto_common::Output) { + self.hash.finalize_xof_reset_into(out); + } +} + +impl ExtendableOutput for XofFixedWrapper { + type Reader = T::Reader; + + fn finalize_xof(self) -> Self::Reader { + self.hash.finalize_xof() + } +} + +impl ExtendableOutputReset for XofFixedWrapper { + fn finalize_xof_reset(&mut self) -> Self::Reader { + self.hash.finalize_xof_reset() + } +} + +#[cfg(feature = "zeroize")] +impl zeroize::ZeroizeOnDrop + for XofFixedWrapper +{ +} + +impl CustomizedInit for XofFixedWrapper { + fn new_customized(customization: &[u8]) -> Self { + Self { + hash: T::new_customized(customization), + size: PhantomData, + } + } +} + +impl SerializableState + for XofFixedWrapper +{ + type SerializedStateSize = T::SerializedStateSize; + + fn serialize(&self) -> crypto_common::hazmat::SerializedState { + self.hash.serialize() + } + + fn deserialize( + serialized_state: &crypto_common::hazmat::SerializedState, + ) -> Result { + T::deserialize(serialized_state).map(|hash| Self { + hash, + size: PhantomData, + }) + } +} From 3620aba4f1e81e506b46a5f88c47f7ee3a7b87e0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Apr 2025 08:25:35 +0400 Subject: [PATCH 1321/1461] Update Cargo.lock (#1819) --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 192ae78f5..584b5781c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -129,9 +129,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cb3c4a0d3776f7535c32793be81d6d5fec0d48ac70955d9834e643aa249a52f" +checksum = "0dabb6555f92fb9ee4140454eb5dcd14c7960e1225c6d1a6cc361f032947713e" [[package]] name = "cpufeatures" From b46b3d185459416fdd86a0ac2713f716f1bd183e Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Fri, 18 Apr 2025 07:00:36 +0200 Subject: [PATCH 1322/1461] elliptic-curve: bump ff and group to pre-releases (#1821) --- Cargo.lock | 21 +++++++++------------ Cargo.toml | 12 ------------ elliptic-curve/Cargo.toml | 4 ++-- 3 files changed, 11 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 584b5781c..acf37857c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -248,8 +248,9 @@ dependencies = [ [[package]] name = "ff" -version = "0.13.0" -source = "git+https://github.com/zkcrypto/ff.git?branch=release-0.14.0#1bb634588722b1b7ce986d239c263e332bedda7f" +version = "0.14.0-pre.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d42dd26f5790eda47c1a2158ea4120e32c35ddc9a7743c98a292accc01b54ef3" dependencies = [ "bitvec", "ff_derive", @@ -259,11 +260,11 @@ dependencies = [ [[package]] name = "ff_derive" -version = "0.13.0" -source = "git+https://github.com/zkcrypto/ff.git?branch=release-0.14.0#1bb634588722b1b7ce986d239c263e332bedda7f" +version = "0.14.0-pre.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9266df7c7c72e5a865a447aca13bf480d7310eaa4f84de117c33e361d4da8888" dependencies = [ "addchain", - "cfg-if", "num-bigint", "num-integer", "num-traits", @@ -292,8 +293,9 @@ dependencies = [ [[package]] name = "group" -version = "0.13.0" -source = "git+https://github.com/baloo/group.git?branch=baloo%2Ftry_from_rng#b0d6ea48fe55327b11ea03f9a965d9e16bb83adc" +version = "0.14.0-pre.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ff6a0b2dd4b981b1ae9e3e6830ab146771f3660d31d57bafd9018805a91b0f1" dependencies = [ "ff", "rand_core", @@ -721,8 +723,3 @@ name = "zeroize" version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" - -[[patch.unused]] -name = "hmac" -version = "0.13.0-pre.4" -source = "git+https://github.com/RustCrypto/MACs.git#c7cbed0bd3f7026cc01251cd4602d0db4d0495b9" diff --git a/Cargo.toml b/Cargo.toml index 2df244b64..df917b659 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,18 +18,6 @@ members = [ [patch.crates-io] signature = { path = "signature" } -# https://github.com/RustCrypto/MACs/pull/178 -hmac = { git = "https://github.com/RustCrypto/MACs.git" } - # https://github.com/RustCrypto/crypto-bigint/pull/762 # https://github.com/RustCrypto/crypto-bigint/pull/765 crypto-bigint = { git = "https://github.com/RustCrypto/crypto-bigint.git" } - -# https://github.com/zkcrypto/ff/pull/122 -# https://github.com/zkcrypto/ff/pull/126 -# https://github.com/zkcrypto/ff/pull/127 -ff = { git = "https://github.com/zkcrypto/ff.git", branch = "release-0.14.0" } - -# https://github.com/zkcrypto/group/pull/56 -# https://github.com/zkcrypto/group/pull/57 -group = { git = "https://github.com/baloo/group.git", branch = "baloo/try_from_rng" } diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 36f2a3ca1..3bc730213 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -27,8 +27,8 @@ zeroize = { version = "1.7", default-features = false } # optional dependencies base64ct = { version = "1", optional = true, default-features = false, features = ["alloc"] } digest = { version = "=0.11.0-pre.10", optional = true } -ff = { version = "0.13", optional = true, default-features = false } -group = { version = "0.13", optional = true, default-features = false } +ff = { version = "=0.14.0-pre.0", optional = true, default-features = false } +group = { version = "=0.14.0-pre.0", optional = true, default-features = false } hkdf = { version = "=0.13.0-pre.5", optional = true, default-features = false } hex-literal = { version = "1", optional = true } pem-rfc7468 = { version = "1.0.0-rc.2", optional = true, features = ["alloc"] } From 829328e9405143cc86b81c297b39f1a6161700c8 Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Fri, 18 Apr 2025 14:50:41 +0200 Subject: [PATCH 1323/1461] elliptic-curve: deprecate `MulByGenerator` (#1822) This now should use `group::Group` directly. Followup to #1821 --- elliptic-curve/src/arithmetic.rs | 3 +-- elliptic-curve/src/dev.rs | 4 +--- elliptic-curve/src/ops.rs | 13 ------------- 3 files changed, 2 insertions(+), 18 deletions(-) diff --git a/elliptic-curve/src/arithmetic.rs b/elliptic-curve/src/arithmetic.rs index 20fc57be1..86d0947bb 100644 --- a/elliptic-curve/src/arithmetic.rs +++ b/elliptic-curve/src/arithmetic.rs @@ -2,7 +2,7 @@ use crate::{ Curve, FieldBytes, PrimeCurve, ScalarPrimitive, - ops::{Invert, LinearCombination, MulByGenerator, Reduce, ShrAssign}, + ops::{Invert, LinearCombination, Reduce, ShrAssign}, point::AffineCoordinates, scalar::{FromUintUnchecked, IsHigh}, }; @@ -46,7 +46,6 @@ pub trait CurveArithmetic: Curve { + Into + LinearCombination<[(Self::ProjectivePoint, Self::Scalar)]> + LinearCombination<[(Self::ProjectivePoint, Self::Scalar); 2]> - + MulByGenerator + group::Curve + group::Group; diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index ea333960e..020795544 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -8,7 +8,7 @@ use crate::{ array::typenum::U32, bigint::{Limb, U256}, error::{Error, Result}, - ops::{Invert, LinearCombination, MulByGenerator, Reduce, ShrAssign}, + ops::{Invert, LinearCombination, Reduce, ShrAssign}, point::AffineCoordinates, rand_core::TryRngCore, scalar::{FromUintUnchecked, IsHigh}, @@ -807,8 +807,6 @@ impl MulAssign<&Scalar> for ProjectivePoint { } } -impl MulByGenerator for ProjectivePoint {} - impl Neg for ProjectivePoint { type Output = ProjectivePoint; diff --git a/elliptic-curve/src/ops.rs b/elliptic-curve/src/ops.rs index 46bde0b87..b030a05c8 100644 --- a/elliptic-curve/src/ops.rs +++ b/elliptic-curve/src/ops.rs @@ -3,7 +3,6 @@ pub use core::ops::{Add, AddAssign, Mul, Neg, Shr, ShrAssign, Sub, SubAssign}; use crypto_bigint::Integer; -use group::Group; use subtle::{Choice, ConditionallySelectable, CtOption}; #[cfg(feature = "alloc")] @@ -168,18 +167,6 @@ where } } -/// Multiplication by the generator. -/// -/// May use optimizations (e.g. precomputed tables) when available. -// TODO(tarcieri): replace this with `Group::mul_by_generator``? (see zkcrypto/group#44) -pub trait MulByGenerator: Group { - /// Multiply by the generator of the prime-order subgroup. - #[must_use] - fn mul_by_generator(scalar: &Self::Scalar) -> Self { - Self::generator() * scalar - } -} - /// Modular reduction. pub trait Reduce: Sized { /// Bytes used as input to [`Reduce::reduce_bytes`]. From 61f68398106c8b1998ed0d1eef62b04533f91404 Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Sat, 19 Apr 2025 17:34:20 +0200 Subject: [PATCH 1324/1461] elliptic-curve: cleanup TODOs (#1823) Those TODOs should have been removed in #1774 --- elliptic-curve/src/scalar/nonzero.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/elliptic-curve/src/scalar/nonzero.rs b/elliptic-curve/src/scalar/nonzero.rs index 06e39b4de..4d2e4c51e 100644 --- a/elliptic-curve/src/scalar/nonzero.rs +++ b/elliptic-curve/src/scalar/nonzero.rs @@ -52,7 +52,6 @@ where // While this method isn't constant-time, the attacker shouldn't learn // anything about unrelated outputs so long as `rng` is a secure `CryptoRng`. loop { - // TODO: remove after `Field::random` switches to `&mut impl RngCore` if let Some(result) = Self::new(Field::random(rng)).into() { break result; } @@ -65,7 +64,6 @@ where // While this method isn't constant-time, the attacker shouldn't learn // anything about unrelated outputs so long as `rng` is a secure `CryptoRng`. loop { - // TODO: remove after `Field::random` switches to `&mut impl RngCore` if let Some(result) = Self::new(Scalar::::try_from_rng(rng)?).into() { break Ok(result); } From 2dc47f8d1461a2a7a22b68e2afafeb4b59e13420 Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Sat, 19 Apr 2025 17:34:51 +0200 Subject: [PATCH 1325/1461] password-hash: cleanup errors (#1824) --- Cargo.lock | 4 ++-- password-hash/Cargo.toml | 2 +- password-hash/src/errors.rs | 3 +-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index acf37857c..8bcaa83a2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -52,9 +52,9 @@ checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" [[package]] name = "base64ct" -version = "1.6.0" +version = "1.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +checksum = "89e25b6adfb930f02d1981565a6e5d9c547ac15a96606256d3b59040e5cd4ca3" [[package]] name = "bitflags" diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index 8e6ba2813..99a51eca3 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -17,7 +17,7 @@ as well as a `no_std`-friendly implementation of the PHC string format """ [dependencies] -base64ct = "1.6" +base64ct = "1.7" subtle = { version = "2", default-features = false } # optional dependencies diff --git a/password-hash/src/errors.rs b/password-hash/src/errors.rs index ff5b09843..14b5d9ea1 100644 --- a/password-hash/src/errors.rs +++ b/password-hash/src/errors.rs @@ -106,8 +106,7 @@ impl fmt::Display for Error { impl core::error::Error for Error { fn source(&self) -> Option<&(dyn core::error::Error + 'static)> { match self { - // TODO: restore after base64ct will migrate to core::error::Error - // Self::B64Encoding(err) => Some(err), + Self::B64Encoding(err) => Some(err), Self::ParamValueInvalid(err) => Some(err), Self::SaltInvalid(err) => Some(err), _ => None, From 5417c7f9321e3df2e1f024854fc715dad10d9cee Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 20 Apr 2025 14:37:50 -0600 Subject: [PATCH 1326/1461] signature v2.3.0-pre.7 (#1825) --- Cargo.lock | 2 +- async-signature/Cargo.toml | 2 +- signature/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8bcaa83a2..5baa70f4e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -583,7 +583,7 @@ dependencies = [ [[package]] name = "signature" -version = "2.3.0-pre.6" +version = "2.3.0-pre.7" dependencies = [ "digest 0.11.0-pre.10 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal", diff --git a/async-signature/Cargo.toml b/async-signature/Cargo.toml index 6a2029127..38d030667 100644 --- a/async-signature/Cargo.toml +++ b/async-signature/Cargo.toml @@ -13,7 +13,7 @@ categories = ["cryptography", "no-std"] description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" [dependencies] -signature = "=2.3.0-pre.6" +signature = "=2.3.0-pre.7" [features] digest = ["signature/digest"] diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 6918ba36f..ecd3caa42 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "signature" -version = "2.3.0-pre.6" +version = "2.3.0-pre.7" authors = ["RustCrypto Developers"] edition = "2024" rust-version = "1.85" From ba9dbacd95e51200b697ca6f7dfdfc200129b3d6 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 20 Apr 2025 15:04:28 -0600 Subject: [PATCH 1327/1461] elliptic-curve: use `crypto-bigint` release (#1826) Switches to the v0.7.0-pre.1 release --- Cargo.lock | 5 +++-- Cargo.toml | 4 ---- elliptic-curve/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5baa70f4e..ebd49e9c5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -158,8 +158,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.7.0-pre.0" -source = "git+https://github.com/RustCrypto/crypto-bigint.git#e1065ce5fa73ee15e73f36a2ed0c6d4ca7b8fe8f" +version = "0.7.0-pre.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6957fb7344601c8271b03e9d4c7efb46f1dee86553eee20f99e54db0cf53f36e" dependencies = [ "hybrid-array", "num-traits", diff --git a/Cargo.toml b/Cargo.toml index df917b659..dda804d3c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,3 @@ members = [ [patch.crates-io] signature = { path = "signature" } - -# https://github.com/RustCrypto/crypto-bigint/pull/762 -# https://github.com/RustCrypto/crypto-bigint/pull/765 -crypto-bigint = { git = "https://github.com/RustCrypto/crypto-bigint.git" } diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 3bc730213..2e9efd2bd 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -18,7 +18,7 @@ and public/secret keys composed thereof. [dependencies] base16ct = "0.2" -crypto-bigint = { version = "0.7.0-pre", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } +crypto-bigint = { version = "=0.7.0-pre.1", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } hybrid-array = { version = "0.3", default-features = false, features = ["zeroize"] } rand_core = { version = "0.9.0", default-features = false } subtle = { version = "2.6", default-features = false } From bf4774878c7c2e36451119a0ad24f1db6dc93cd8 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 21 Apr 2025 15:49:21 -0600 Subject: [PATCH 1328/1461] signature: replace `signature_derive` with blanket impls (#1827) Adds blanket impls of: - `Signer` for types which impl `PrehashSignature + DigestSignature` - `Verifier` for types which impl `PrehashSignature + DigestVerifier` These blanket impls eliminate the need to have a `signature_derive` crate, which only existed to write the `Signer` and `Verifier` impls for this particular case. Since this is a breaking change, bumps the version to `3.0.0-pre` --- .github/workflows/signature.yml | 21 +- Cargo.lock | 20 +- Cargo.toml | 1 - crypto/Cargo.toml | 2 +- signature/Cargo.toml | 3 +- signature/src/lib.rs | 6 - signature/src/prehash_signature.rs | 5 +- signature/src/signer.rs | 28 ++- signature/src/verifier.rs | 13 +- signature/tests/derive.rs | 85 ------- signature_derive/CHANGELOG.md | 76 ------ signature_derive/Cargo.toml | 21 -- signature_derive/LICENSE-APACHE | 201 --------------- signature_derive/LICENSE-MIT | 25 -- signature_derive/README.md | 41 --- signature_derive/src/lib.rs | 392 ----------------------------- 16 files changed, 55 insertions(+), 885 deletions(-) delete mode 100644 signature/tests/derive.rs delete mode 100644 signature_derive/CHANGELOG.md delete mode 100644 signature_derive/Cargo.toml delete mode 100644 signature_derive/LICENSE-APACHE delete mode 100644 signature_derive/LICENSE-MIT delete mode 100644 signature_derive/README.md delete mode 100644 signature_derive/src/lib.rs diff --git a/.github/workflows/signature.yml b/.github/workflows/signature.yml index 00e6f0a20..0a5ccfd9c 100644 --- a/.github/workflows/signature.yml +++ b/.github/workflows/signature.yml @@ -37,9 +37,8 @@ jobs: toolchain: ${{ matrix.rust }} targets: ${{ matrix.target }} - run: cargo build --target ${{ matrix.target }} --release --no-default-features - - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features derive + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features digest - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features rand_core - - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features derive,rand_core minimal-versions: if: false # disabled until we stop using pre-releases @@ -52,7 +51,7 @@ jobs: strategy: matrix: rust: - - 1.85.0 # Minimum Rust version the tests pass on + - 1.85.0 # MSRV - stable steps: - uses: actions/checkout@v4 @@ -63,19 +62,3 @@ jobs: - run: cargo test --release --no-default-features - run: cargo test --release - run: cargo test --release --all-features - - derive: - runs-on: ubuntu-latest - strategy: - matrix: - rust: - - 1.85.0 # MSRV - - stable - steps: - - uses: actions/checkout@v4 - - uses: RustCrypto/actions/cargo-cache@master - - uses: dtolnay/rust-toolchain@master - with: - toolchain: ${{ matrix.rust }} - - run: cargo test --release - working-directory: signature_derive diff --git a/Cargo.lock b/Cargo.lock index ebd49e9c5..bb25fa945 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -35,7 +35,7 @@ checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" name = "async-signature" version = "0.6.0-pre.4" dependencies = [ - "signature", + "signature 2.3.0-pre.7", ] [[package]] @@ -152,7 +152,7 @@ dependencies = [ "digest 0.11.0-pre.10", "elliptic-curve", "password-hash", - "signature", + "signature 3.0.0-pre", "universal-hash", ] @@ -585,21 +585,21 @@ dependencies = [ [[package]] name = "signature" version = "2.3.0-pre.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6e22be6d22b655ff65ed5635383d63ac17a99c5c0a05a83a414d399056d4e1d" dependencies = [ "digest 0.11.0-pre.10 (registry+https://github.com/rust-lang/crates.io-index)", - "hex-literal", "rand_core", - "sha2", - "signature_derive", ] [[package]] -name = "signature_derive" -version = "2.2.0" +name = "signature" +version = "3.0.0-pre" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.98", + "digest 0.11.0-pre.10 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal", + "rand_core", + "sha2", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index dda804d3c..6d87a02f9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,6 @@ members = [ "elliptic-curve", "kem", "password-hash", - "signature_derive", "universal-hash", "signature", ] diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 4e37d83a1..ccf8b569d 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -21,7 +21,7 @@ cipher = { version = "0.5.0-pre.7", path = "../cipher", optional = true } digest = { version = "0.11.0-pre.9", path = "../digest", optional = true, features = ["mac"] } elliptic-curve = { version = "0.14.0-rc.1", path = "../elliptic-curve", optional = true } password-hash = { version = "0.6.0-rc.0", path = "../password-hash", optional = true } -signature = { version = "2.3.0-pre.6", path = "../signature", optional = true, default-features = false } +signature = { version = "3.0.0-pre", path = "../signature", optional = true, default-features = false } universal-hash = { version = "0.6.0-rc.0", path = "../universal-hash", optional = true } [features] diff --git a/signature/Cargo.toml b/signature/Cargo.toml index ecd3caa42..f4887d394 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "signature" -version = "2.3.0-pre.7" +version = "3.0.0-pre" authors = ["RustCrypto Developers"] edition = "2024" rust-version = "1.85" @@ -13,7 +13,6 @@ categories = ["cryptography", "no-std"] description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" [dependencies] -derive = { package = "signature_derive", version = "2", optional = true, path = "../signature_derive" } digest = { version = "=0.11.0-pre.10", optional = true, default-features = false } rand_core = { version = "0.9", optional = true, default-features = false } diff --git a/signature/src/lib.rs b/signature/src/lib.rs index a3281f769..5f6048bd0 100644 --- a/signature/src/lib.rs +++ b/signature/src/lib.rs @@ -144,12 +144,6 @@ mod prehash_signature; pub use crate::{encoding::*, error::*, keypair::*, signer::*, verifier::*}; -#[cfg(feature = "derive")] -pub use derive::{Signer, Verifier}; - -#[cfg(all(feature = "derive", feature = "digest"))] -pub use derive::{DigestSigner, DigestVerifier}; - #[cfg(feature = "digest")] pub use {crate::prehash_signature::*, digest}; diff --git a/signature/src/prehash_signature.rs b/signature/src/prehash_signature.rs index d9a86456d..54317f05c 100644 --- a/signature/src/prehash_signature.rs +++ b/signature/src/prehash_signature.rs @@ -19,9 +19,8 @@ use crate::{ /// This approach is relatively common in signature schemes based on the /// [Fiat-Shamir heuristic]. /// -/// For signature types that implement this trait, when the `derive` crate -/// feature is enabled a custom derive for [`Signer`] is available for any -/// types that impl [`DigestSigner`], and likewise for deriving [`Verifier`] for +/// For signature types that implement this trait, a blanket impl of the [`Signer`] trait is +/// available for any types that impl [`DigestSigner`], and likewise for the [`Verifier`] for /// types which impl [`DigestVerifier`]. /// /// [Fiat-Shamir heuristic]: https://en.wikipedia.org/wiki/Fiat%E2%80%93Shamir_heuristic diff --git a/signature/src/signer.rs b/signature/src/signer.rs index 2b3fe9f1e..56ddcaaa8 100644 --- a/signature/src/signer.rs +++ b/signature/src/signer.rs @@ -3,7 +3,7 @@ use crate::error::Error; #[cfg(feature = "digest")] -use crate::digest::Digest; +use crate::{PrehashSignature, digest::Digest}; #[cfg(feature = "rand_core")] use crate::rand_core::{CryptoRng, TryCryptoRng}; @@ -82,6 +82,17 @@ pub trait DigestSigner { fn try_sign_digest(&self, digest: D) -> Result; } +#[cfg(feature = "digest")] +impl Signer for T +where + S: PrehashSignature, + T: DigestSigner, +{ + fn try_sign(&self, msg: &[u8]) -> Result { + self.try_sign_digest(S::Digest::new_with_prefix(msg)) + } +} + /// Sign the given message using the provided external randomness source. #[cfg(feature = "rand_core")] pub trait RandomizedSigner { @@ -124,6 +135,21 @@ pub trait RandomizedDigestSigner { ) -> Result; } +#[cfg(all(feature = "digest", feature = "rand_core"))] +impl RandomizedSigner for T +where + S: PrehashSignature, + T: RandomizedDigestSigner, +{ + fn try_sign_with_rng( + &self, + rng: &mut R, + msg: &[u8], + ) -> Result { + self.try_sign_digest_with_rng(rng, S::Digest::new_with_prefix(msg)) + } +} + /// Sign the provided message bytestring using `&mut Self` (e.g. an evolving /// cryptographic key such as a stateful hash-based signature), and a per-signature /// randomizer, returning a digital signature. diff --git a/signature/src/verifier.rs b/signature/src/verifier.rs index 65409a929..6fcfe3e52 100644 --- a/signature/src/verifier.rs +++ b/signature/src/verifier.rs @@ -3,7 +3,7 @@ use crate::error::Error; #[cfg(feature = "digest")] -use crate::digest::Digest; +use crate::{PrehashSignature, digest::Digest}; /// Verify the provided message bytestring using `Self` (e.g. a public key) pub trait Verifier { @@ -39,3 +39,14 @@ pub trait DigestVerifier { /// Verify the signature against the given [`Digest`] output. fn verify_digest(&self, digest: D, signature: &S) -> Result<(), Error>; } + +#[cfg(feature = "digest")] +impl Verifier for T +where + S: PrehashSignature, + T: DigestVerifier, +{ + fn verify(&self, msg: &[u8], signature: &S) -> Result<(), Error> { + self.verify_digest(S::Digest::new_with_prefix(msg), signature) + } +} diff --git a/signature/tests/derive.rs b/signature/tests/derive.rs deleted file mode 100644 index 989890271..000000000 --- a/signature/tests/derive.rs +++ /dev/null @@ -1,85 +0,0 @@ -//! Tests for code generated by `signature_derive` - -#![cfg(all(feature = "derive", feature = "digest"))] - -use digest::{Digest, OutputSizeUser, array::Array}; -use hex_literal::hex; -use sha2::Sha256; -use signature::{ - DigestSigner, DigestVerifier, Error, PrehashSignature, SignatureEncoding, Signer, Verifier, - hazmat::{PrehashSigner, PrehashVerifier}, -}; - -/// Test vector to compute SHA-256 digest of -const INPUT_STRING: &[u8] = b"abc"; - -/// Expected SHA-256 digest for the input string -const INPUT_STRING_DIGEST: [u8; 32] = - hex!("ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad"); - -type Repr = Array::OutputSize>; - -/// Dummy signature which just contains a digest output -#[derive(Clone, Debug)] -struct DummySignature(Repr); - -impl PrehashSignature for DummySignature { - type Digest = Sha256; -} - -impl SignatureEncoding for DummySignature { - type Repr = Repr; -} - -impl TryFrom<&[u8]> for DummySignature { - type Error = Error; - - fn try_from(bytes: &[u8]) -> Result { - bytes - .try_into() - .map(DummySignature) - .map_err(|_| Error::new()) - } -} - -impl From for Repr { - fn from(sig: DummySignature) -> Repr { - sig.0 - } -} - -/// Dummy signer which just returns the message digest as a `DummySignature` -#[derive(Signer, DigestSigner, Default)] -struct DummySigner {} - -impl PrehashSigner for DummySigner { - fn sign_prehash(&self, prehash: &[u8]) -> signature::Result { - DummySignature::try_from(prehash) - } -} - -/// Dummy verifier which ensures the `DummySignature` digest matches the -/// expected value. -/// -/// Panics (via `assert_eq!`) if the value is not what is expected. -#[derive(Verifier, DigestVerifier, Default)] -struct DummyVerifier {} - -impl PrehashVerifier for DummyVerifier { - fn verify_prehash(&self, prehash: &[u8], signature: &DummySignature) -> signature::Result<()> { - assert_eq!(signature.to_bytes().as_slice(), prehash); - Ok(()) - } -} - -#[test] -fn derived_signer_impl() { - let sig: DummySignature = DummySigner::default().sign(INPUT_STRING); - assert_eq!(sig.to_bytes().as_slice(), INPUT_STRING_DIGEST) -} - -#[test] -fn derived_verifier_impl() { - let sig: DummySignature = DummySigner::default().sign(INPUT_STRING); - assert!(DummyVerifier::default().verify(INPUT_STRING, &sig).is_ok()); -} diff --git a/signature_derive/CHANGELOG.md b/signature_derive/CHANGELOG.md deleted file mode 100644 index e88b15da1..000000000 --- a/signature_derive/CHANGELOG.md +++ /dev/null @@ -1,76 +0,0 @@ -# Changelog -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## 2.2.0 (UNRELEASED) -### Changed -- Edition changed to 2024 and MSRV bumped to 1.85 ([#1759]) - -[#1759]: https://github.com/RustCrypto/traits/pull/1759 - -## 2.1.0 (2023-11-12) -### Changed -- MSRV 1.60 ([#1387]) - -[#1387]: https://github.com/RustCrypto/traits/pull/1387 - -## 2.0.1 (2023-04-17) -### Changed -- Bump `syn` to v2 ([#1299]) - -[#1299]: https://github.com/RustCrypto/traits/pull/1299 - -## 2.0.0 (2023-01-15) -### Changed -- `Signature` trait has been removed, so don't emit it in custom derive ([#1141]) - -[#1141]: https://github.com/RustCrypto/traits/pull/1141 - -## 1.0.0-pre.7 (2022-09-16) -### Fixed -- Support for `where` bounds ([#1118]) - -[#1118]: https://github.com/RustCrypto/traits/pull/1118 - -## 1.0.0-pre.6 (2022-09-12) -### Added -- `DigestSigner`/`DigestVerifier` support ([#1103]) - -### Removed -- `synstructure` dependency ([#1100]) - -[#1100]: https://github.com/RustCrypto/traits/pull/1100 -[#1103]: https://github.com/RustCrypto/traits/pull/1103 - -## 1.0.0-pre.5 (2022-08-14) -### Changed -- Rust 2021 edition upgrade; MSRV 1.56 ([#1081]) - -[#1081]: https://github.com/RustCrypto/traits/pull/1081 - -## 1.0.0-pre.4 (2022-01-04) -### Changed -- Support for new `digest` v0.10 API ([#850]) - -[#850]: https://github.com/RustCrypto/traits/pull/850 - -## 1.0.0-pre.3 (2021-01-06) -### Fixed -- rustdoc links ([#458]) - -[#458]: https://github.com/RustCrypto/traits/pull/458 - -## 1.0.0-pre.2 (2020-04-19) -### Changed -- Rename `DigestSignature` => `PrehashSignature` ([#96]) - -[#96]: https://github.com/RustCrypto/traits/pull/96 - -## 1.0.0-pre.1 (2020-03-08) -### Added -- Initial changelog for `signature_derive` -- rustdoc ([#79]) - -[#79]: https://github.com/RustCrypto/traits/pull/79 diff --git a/signature_derive/Cargo.toml b/signature_derive/Cargo.toml deleted file mode 100644 index 205bfdff6..000000000 --- a/signature_derive/Cargo.toml +++ /dev/null @@ -1,21 +0,0 @@ -[package] -name = "signature_derive" -version = "2.2.0" -authors = ["RustCrypto Developers"] -edition = "2024" -rust-version = "1.85" -documentation = "https://docs.rs/signature" -readme = "README.md" -repository = "https://github.com/RustCrypto/traits" -license = "Apache-2.0 OR MIT" -keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"] -categories = ["cryptography", "no-std"] -description = "Custom derive support for the 'signature' crate" - -[lib] -proc-macro = true - -[dependencies] -proc-macro2 = "1" -quote = "1" -syn = "2" diff --git a/signature_derive/LICENSE-APACHE b/signature_derive/LICENSE-APACHE deleted file mode 100644 index 78173fa2e..000000000 --- a/signature_derive/LICENSE-APACHE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - -Copyright [yyyy] [name of copyright owner] - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/signature_derive/LICENSE-MIT b/signature_derive/LICENSE-MIT deleted file mode 100644 index bb7ff7c2c..000000000 --- a/signature_derive/LICENSE-MIT +++ /dev/null @@ -1,25 +0,0 @@ -Copyright (c) 2019-2025 RustCrypto Developers - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without -limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/signature_derive/README.md b/signature_derive/README.md deleted file mode 100644 index 74cd7871b..000000000 --- a/signature_derive/README.md +++ /dev/null @@ -1,41 +0,0 @@ -# `signature` crate custom derive support - -[![crate][crate-image]][crate-link] -[![Docs][docs-image]][docs-link] -[![Build Status][build-image]][build-link] -![Apache2/MIT licensed][license-image] -![Rust Version][rustc-image] -[![Project Chat][chat-image]][chat-link] - -This crate provides proc macros used by the `signature` crate. - -Not intended to be used directly. See the `signature` crate's documentation -for additional details: - -## License - -All crates licensed under either of - - * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) - * [MIT license](http://opensource.org/licenses/MIT) - -at your option. - -### Contribution - -Unless you explicitly state otherwise, any contribution intentionally submitted -for inclusion in the work by you, as defined in the Apache-2.0 license, shall be -dual licensed as above, without any additional terms or conditions. - -[//]: # (badges) - -[crate-image]: https://img.shields.io/crates/v/signature_derive -[crate-link]: https://crates.io/crates/signature_derive -[docs-image]: https://docs.rs/signature_derive/badge.svg -[docs-link]: https://docs.rs/signature_derive/ -[build-image]: https://github.com/RustCrypto/traits/actions/workflows/signature_derive.yml/badge.svg?branch=master -[build-link]: https://github.com/RustCrypto/traits/actions/workflows/signature_derive.yml?query=branch:master -[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg -[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg -[chat-link]: https://rustcrypto.zulipchat.com/#narrow/channel/260048-signatures diff --git a/signature_derive/src/lib.rs b/signature_derive/src/lib.rs deleted file mode 100644 index bf6a94c5d..000000000 --- a/signature_derive/src/lib.rs +++ /dev/null @@ -1,392 +0,0 @@ -#![crate_type = "proc-macro"] -#![doc = include_str!("../README.md")] -#![forbid(unsafe_code)] -#![warn( - clippy::unwrap_used, - rust_2018_idioms, - trivial_casts, - unused_import_braces, - missing_debug_implementations, - unused_qualifications -)] - -use proc_macro::TokenStream; -use proc_macro2::{Span, TokenStream as TokenStream2}; -use quote::quote; -use syn::{ - DeriveInput, Ident, PredicateType, Token, TraitBound, Type, TypeParam, TypeParamBound, - WhereClause, WherePredicate, parse_macro_input, parse_quote, punctuated::Punctuated, -}; - -/// Derive the [`Signer`] trait for a type which impls [`DigestSigner`]. -/// -/// When implementing the [`DigestSigner`] trait for a signature type which -/// itself impl's the [`PrehashSignature`] trait (which marks signature -/// algorithms which are computed using a [`Digest`]), signature providers -/// can automatically derive the [`Signer`] trait when the digest algorithm -/// is [`PrehashSignature::Digest`] (i.e. the "standard" digest algorithm -/// for a given signature type) -/// -/// This automates all of the digest computation otherwise needed for a -/// complete signature algorithm implementation. -/// -/// [`Digest`]: https://docs.rs/digest/latest/digest/trait.Digest.html -/// [`DigestSigner`]: https://docs.rs/signature/latest/signature/trait.DigestSigner.html -/// [`PrehashSignature`]: https://docs.rs/signature/latest/signature/trait.PrehashSignature.html -/// [`PrehashSignature::Digest`]: https://docs.rs/signature/latest/signature/trait.PrehashSignature.html#associated-types -#[proc_macro_derive(Signer)] -pub fn derive_signer(input: TokenStream) -> TokenStream { - let input = parse_macro_input!(input as DeriveInput); - emit_signer_impl(input).into() -} - -fn emit_signer_impl(input: DeriveInput) -> TokenStream2 { - let s_ident = Ident::new("__S", Span::call_site()); - - let mut params = DeriveParams::new(input); - params.add_bound(&s_ident, parse_quote!(::signature::PrehashSignature)); - params.add_bound( - &Ident::new("Self", Span::call_site()), - parse_quote!(::signature::DigestSigner<#s_ident::Digest, #s_ident>), - ); - - let name = params.name; - let impl_generics = params.impl_generics; - let ty_generics = params.ty_generics; - let where_clause = params.where_clause; - - quote! { - impl<#(#impl_generics),*> ::signature::Signer<#s_ident> for #name<#(#ty_generics),*> - #where_clause - { - fn try_sign(&self, msg: &[u8]) -> ::signature::Result<#s_ident> { - self.try_sign_digest(#s_ident::Digest::new_with_prefix(msg)) - } - } - } -} - -/// Derive the [`Verifier`] trait for a type which impls [`DigestVerifier`]. -/// -/// When implementing the [`DigestVerifier`] trait for a signature type which -/// itself impl's the [`PrehashSignature`] trait (which marks signature -/// algorithms which are computed using a [`Digest`]), signature providers -/// can automatically derive the [`Verifier`] trait when the digest algorithm -/// is [`PrehashSignature::Digest`] (i.e. the "standard" digest algorithm -/// for a given signature type) -/// -/// This automates all of the digest computation otherwise needed for a -/// complete signature algorithm implementation. -/// -/// [`Digest`]: https://docs.rs/digest/latest/digest/trait.Digest.html -/// [`DigestVerifier`]: https://docs.rs/signature/latest/signature/trait.DigestVerifier.html -/// [`PrehashSignature`]: https://docs.rs/signature/latest/signature/trait.PrehashSignature.html -/// [`PrehashSignature::Digest`]: https://docs.rs/signature/latest/signature/trait.PrehashSignature.html#associated-types -#[proc_macro_derive(Verifier)] -pub fn derive_verifier(input: TokenStream) -> TokenStream { - let input = parse_macro_input!(input as DeriveInput); - emit_verifier_impl(input).into() -} - -fn emit_verifier_impl(input: DeriveInput) -> TokenStream2 { - let s_ident = Ident::new("__S", Span::call_site()); - - let mut params = DeriveParams::new(input); - params.add_bound(&s_ident, parse_quote!(::signature::PrehashSignature)); - params.add_bound( - &Ident::new("Self", Span::call_site()), - parse_quote!(::signature::DigestVerifier<#s_ident::Digest, #s_ident>), - ); - - let name = params.name; - let impl_generics = params.impl_generics; - let ty_generics = params.ty_generics; - let where_clause = params.where_clause; - - quote! { - impl<#(#impl_generics),*> ::signature::Verifier<#s_ident> for #name<#(#ty_generics),*> - #where_clause - { - fn verify(&self, msg: &[u8], signature: &#s_ident) -> ::signature::Result<()> { - self.verify_digest(#s_ident::Digest::new_with_prefix(msg), signature) - } - } - } -} - -/// Derive the [`DigestSigner`] trait for a type which impls [`PrehashSigner`]. -/// -/// [`DigestSigner`]: https://docs.rs/signature/latest/signature/trait.DigestSigner.html -/// [`PrehashSigner`]: https://docs.rs/signature/latest/signature/hazmat/trait.PrehashSigner.html -#[proc_macro_derive(DigestSigner)] -pub fn derive_digest_signer(input: TokenStream) -> TokenStream { - let input = parse_macro_input!(input as DeriveInput); - emit_digest_signer_impl(input).into() -} - -fn emit_digest_signer_impl(input: DeriveInput) -> TokenStream2 { - let d_ident = Ident::new("__D", Span::call_site()); - let s_ident = Ident::new("__S", Span::call_site()); - - let mut params = DeriveParams::new(input); - params.add_bound(&d_ident, parse_quote!(::signature::digest::Digest)); - params.add_param(&s_ident); - params.add_bound( - &Ident::new("Self", Span::call_site()), - parse_quote!(::signature::hazmat::PrehashSigner<#s_ident>), - ); - - let name = params.name; - let impl_generics = params.impl_generics; - let ty_generics = params.ty_generics; - let where_clause = params.where_clause; - - quote! { - impl<#(#impl_generics),*> ::signature::DigestSigner<#d_ident, #s_ident> for #name<#(#ty_generics),*> - #where_clause - { - fn try_sign_digest(&self, digest: #d_ident) -> ::signature::Result<#s_ident> { - self.sign_prehash(&digest.finalize()) - } - } - } -} - -/// Derive the [`DigestVerifier`] trait for a type which impls [`PrehashVerifier`]. -/// -/// [`DigestVerifier`]: https://docs.rs/signature/latest/signature/trait.DigestVerifier.html -/// [`PrehashVerifier`]: https://docs.rs/signature/latest/signature/hazmat/trait.PrehashVerifier.html -#[proc_macro_derive(DigestVerifier)] -pub fn derive_digest_verifier(input: TokenStream) -> TokenStream { - let input = parse_macro_input!(input as DeriveInput); - emit_digest_verifier_impl(input).into() -} - -fn emit_digest_verifier_impl(input: DeriveInput) -> TokenStream2 { - let d_ident = Ident::new("__D", Span::call_site()); - let s_ident = Ident::new("__S", Span::call_site()); - - let mut params = DeriveParams::new(input); - params.add_bound(&d_ident, parse_quote!(::signature::digest::Digest)); - params.add_param(&s_ident); - params.add_bound( - &Ident::new("Self", Span::call_site()), - parse_quote!(::signature::hazmat::PrehashVerifier<#s_ident>), - ); - - let name = params.name; - let impl_generics = params.impl_generics; - let ty_generics = params.ty_generics; - let where_clause = params.where_clause; - - quote! { - impl<#(#impl_generics),*> ::signature::DigestVerifier<#d_ident, #s_ident> for #name<#(#ty_generics),*> - #where_clause - { - fn verify_digest(&self, digest: #d_ident, signature: &#s_ident) -> ::signature::Result<()> { - self.verify_prehash(&digest.finalize(), signature) - } - } - } -} - -/// Derivation parameters parsed from `DeriveInput`. -struct DeriveParams { - /// Name of the struct the trait impls are being added to. - name: Ident, - - /// Generic parameters of `impl`. - impl_generics: Vec, - - /// Generic parameters of the type. - ty_generics: Vec, - - /// Where clause in-progress. - where_clause: WhereClause, -} - -impl DeriveParams { - /// Parse parameters from `DeriveInput`. - fn new(input: DeriveInput) -> Self { - let impl_generics = input.generics.type_params().cloned().collect(); - - let ty_generics = input - .generics - .type_params() - .map(|bound| bound.ident.clone()) - .collect(); - - let where_clause = input - .generics - .where_clause - .clone() - .unwrap_or_else(|| WhereClause { - where_token: ::default(), - predicates: Punctuated::new(), - }); - - Self { - name: input.ident, - impl_generics, - ty_generics, - where_clause, - } - } - - /// Add a generic parameter with the given bound. - fn add_bound(&mut self, name: &Ident, bound: TraitBound) { - if name != "Self" { - self.add_param(name); - } - - let type_path = parse_quote!(#name); - - let mut bounds = Punctuated::new(); - bounds.push(TypeParamBound::Trait(bound)); - - let predicate_type = PredicateType { - lifetimes: None, - bounded_ty: Type::Path(type_path), - colon_token: ::default(), - bounds, - }; - - self.where_clause - .predicates - .push(WherePredicate::Type(predicate_type)) - } - - /// Add a generic parameter without a bound. - fn add_param(&mut self, name: &Ident) { - self.impl_generics.push(TypeParam { - attrs: vec![], - ident: name.clone(), - colon_token: None, - bounds: Default::default(), - eq_token: None, - default: None, - }); - } -} - -#[cfg(test)] -mod tests { - use super::*; - use syn::parse_quote; - - #[test] - fn signer() { - let input = parse_quote! { - #[derive(Signer)] - struct MySigner - where - C: EllipticCurve - { - scalar: Scalar - } - }; - - let output = emit_signer_impl(input); - - assert_eq!( - output.to_string(), - quote! { - impl ::signature::Signer<__S> for MySigner - where - C: EllipticCurve, - __S: ::signature::PrehashSignature, - Self: ::signature::DigestSigner<__S::Digest, __S> - { - fn try_sign(&self, msg: &[u8]) -> ::signature::Result<__S> { - self.try_sign_digest(__S::Digest::new_with_prefix(msg)) - } - } - } - .to_string() - ); - } - - #[test] - fn verifier() { - let input = parse_quote! { - #[derive(Verifier)] - struct MyVerifier { - point: UncompressedPoint - } - }; - - let output = emit_verifier_impl(input); - - assert_eq!( - output.to_string(), - quote! { - impl ::signature::Verifier<__S> for MyVerifier - where - __S: ::signature::PrehashSignature, - Self: ::signature::DigestVerifier<__S::Digest, __S> - { - fn verify(&self, msg: &[u8], signature: &__S) -> ::signature::Result<()> { - self.verify_digest(__S::Digest::new_with_prefix(msg), signature) - } - } - } - .to_string() - ); - } - - #[test] - fn digest_signer() { - let input = parse_quote! { - #[derive(DigestSigner)] - struct MySigner { - scalar: Scalar - } - }; - - let output = emit_digest_signer_impl(input); - - assert_eq!( - output.to_string(), - quote! { - impl ::signature::DigestSigner<__D, __S> for MySigner - where - __D: ::signature::digest::Digest, - Self: ::signature::hazmat::PrehashSigner<__S> - { - fn try_sign_digest(&self, digest: __D) -> ::signature::Result<__S> { - self.sign_prehash(&digest.finalize()) - } - } - } - .to_string() - ); - } - - #[test] - fn digest_verifier() { - let input = parse_quote! { - #[derive(DigestVerifier)] - struct MyVerifier { - point: UncompressedPoint - } - }; - - let output = emit_digest_verifier_impl(input); - - assert_eq!( - output.to_string(), - quote! { - impl ::signature::DigestVerifier<__D, __S> for MyVerifier - where - __D: ::signature::digest::Digest, - Self: ::signature::hazmat::PrehashVerifier<__S> - { - fn verify_digest(&self, digest: __D, signature: &__S) -> ::signature::Result<()> { - self.verify_prehash(&digest.finalize(), signature) - } - } - } - .to_string() - ); - } -} From e43a96fd2759e824189c8142341ac59ab828e3bd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Apr 2025 07:39:17 +0400 Subject: [PATCH 1329/1461] Update Cargo.lock (#1828) --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bb25fa945..2d46974cb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -391,9 +391,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.171" +version = "0.2.172" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" +checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" [[package]] name = "memchr" From 18325fde3cd15722bcc0d618c4233cdb9a05a51b Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 23 Apr 2025 11:51:11 -0600 Subject: [PATCH 1330/1461] signature: remove `std` feature (#1829) We've since migrated to `core::error::Error` (#1711) --- crypto/Cargo.toml | 5 +---- signature/CHANGELOG.md | 7 ++++++- signature/Cargo.toml | 2 -- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index ccf8b569d..a2fb7a20f 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -25,10 +25,7 @@ signature = { version = "3.0.0-pre", path = "../signature", optional = true, def universal-hash = { version = "0.6.0-rc.0", path = "../universal-hash", optional = true } [features] -std = [ - "elliptic-curve/std", - "signature/std", -] +std = ["elliptic-curve/std"] os_rng = ["crypto-common/os_rng"] rand_core = ["crypto-common/rand_core"] diff --git a/signature/CHANGELOG.md b/signature/CHANGELOG.md index faaaff7a4..d18641cf9 100644 --- a/signature/CHANGELOG.md +++ b/signature/CHANGELOG.md @@ -4,15 +4,20 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 2.3.0 (UNRELEASED) +## 3.0.0 (UNRELEASED) ### Added - `RandomizedSignerMut` trait ([#1448]) ### Changed +- Replace `signature_derive` with blanket impls ([#1827]) - Edition changed to 2024 and MSRV bumped to 1.85 ([#1759]) +### Removed +- `std` feature - replaced with `core::error::Error` + [#1448]: https://github.com/RustCrypto/traits/pull/1448 [#1759]: https://github.com/RustCrypto/traits/pull/1759 +[#1827]: https://github.com/RustCrypto/traits/pull/1827 ## 2.2.0 (2023-11-12) ### Changed diff --git a/signature/Cargo.toml b/signature/Cargo.toml index f4887d394..6e50f3822 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -22,8 +22,6 @@ sha2 = { version = "=0.11.0-pre.5", default-features = false } [features] alloc = [] -# TODO: remove this feature in the next breaking release -std = ["alloc", "rand_core?/std"] rand_core = ["dep:rand_core"] [package.metadata.docs.rs] From ef4b78d5a066f0e1613cde1f0378bf29362c088b Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 23 Apr 2025 12:02:57 -0600 Subject: [PATCH 1331/1461] signature: allow AFIT globally (#1830) --- signature/src/lib.rs | 1 + signature/src/signer.rs | 3 --- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/signature/src/lib.rs b/signature/src/lib.rs index 5f6048bd0..b8678e329 100644 --- a/signature/src/lib.rs +++ b/signature/src/lib.rs @@ -6,6 +6,7 @@ )] #![cfg_attr(docsrs, feature(doc_auto_cfg))] #![forbid(unsafe_code)] +#![allow(async_fn_in_trait)] #![warn( clippy::mod_module_files, clippy::unwrap_used, diff --git a/signature/src/signer.rs b/signature/src/signer.rs index 56ddcaaa8..662a379ff 100644 --- a/signature/src/signer.rs +++ b/signature/src/signer.rs @@ -189,7 +189,6 @@ impl> RandomizedSignerMut for T { /// (e.g. client for a Cloud KMS or HSM), returning a digital signature. /// /// This trait is an async equivalent of the [`Signer`] trait. -#[allow(async_fn_in_trait)] pub trait AsyncSigner { /// Attempt to sign the given message, returning a digital signature on /// success, or an error if something went wrong. @@ -212,7 +211,6 @@ where /// /// This trait is an async equivalent of the [`DigestSigner`] trait. #[cfg(feature = "digest")] -#[allow(async_fn_in_trait)] pub trait AsyncDigestSigner where D: Digest, @@ -224,7 +222,6 @@ where /// Sign the given message using the provided external randomness source. #[cfg(feature = "rand_core")] -#[allow(async_fn_in_trait)] pub trait AsyncRandomizedSigner { /// Sign the given message and return a digital signature async fn sign_with_rng_async(&self, rng: &mut R, msg: &[u8]) -> S { From 5d3e03178b822f13e85ce46316e1f524ed7921c4 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Wed, 23 Apr 2025 20:04:00 +0200 Subject: [PATCH 1332/1461] Various fixes and improvements to hash2curve (#1813) This was mainly to fix a bug in handling large DSTs for `expand_message_xof`. - `ExpandMsg::expand_message()`s `len_in_bytes` parameter is now a `NonZero`, moving one run-time error to the type system. - In tandem `FromOkm::Length` now requires `typenum::NonZero`. - Added generic `K` parameter to `ExpandMsg` implementers. - `ExpandMsgXmd` only uses it to follow constraints set by the specification more closely. See https://www.rfc-editor.org/rfc/rfc9380.html#section-5.3.1-2.1. - More importantly, `ExpandMsgXof`, requires `K` to calculate the size for the computed DST if the given DST is larger than 255 bytes. This was previously not implemented correctly in that it always used a 32-byte long computed DST. - Added `type K` to the `GroupDigest` trait. This allows blanket implementations to use the right `K` for `ExpandMsgXmd` and `ExpandMsgXof`. - Added `HashMarker` to the constraints of `HashT` for `ExpandMsgXof`. - Moved documentation from `ExpandMsg` trait implementations to the actual type and added links to the specification. Cc @mikelodder7. --- elliptic-curve/src/hash2curve/group_digest.rs | 6 ++ elliptic-curve/src/hash2curve/hash2field.rs | 14 +++- .../src/hash2curve/hash2field/expand_msg.rs | 4 +- .../hash2curve/hash2field/expand_msg/xmd.rs | 52 ++++++++----- .../hash2curve/hash2field/expand_msg/xof.rs | 76 ++++++++++++------- 5 files changed, 102 insertions(+), 50 deletions(-) diff --git a/elliptic-curve/src/hash2curve/group_digest.rs b/elliptic-curve/src/hash2curve/group_digest.rs index 2a663a11b..8fa27c46c 100644 --- a/elliptic-curve/src/hash2curve/group_digest.rs +++ b/elliptic-curve/src/hash2curve/group_digest.rs @@ -3,6 +3,7 @@ use super::{ExpandMsg, FromOkm, MapToCurve, hash_to_field}; use crate::{CurveArithmetic, ProjectivePoint, Result}; use group::cofactor::CofactorGroup; +use hybrid_array::typenum::Unsigned; /// Adds hashing arbitrary byte sequences to a valid group element pub trait GroupDigest: CurveArithmetic @@ -12,6 +13,11 @@ where /// The field element representation for a group value with multiple elements type FieldElement: FromOkm + MapToCurve> + Default + Copy; + /// The target security level in bytes: + /// + /// + type K: Unsigned; + /// Computes the hash to curve routine. /// /// From : diff --git a/elliptic-curve/src/hash2curve/hash2field.rs b/elliptic-curve/src/hash2curve/hash2field.rs index 946c8a39d..4ffcf8062 100644 --- a/elliptic-curve/src/hash2curve/hash2field.rs +++ b/elliptic-curve/src/hash2curve/hash2field.rs @@ -4,15 +4,20 @@ mod expand_msg; +use core::num::NonZeroUsize; + pub use expand_msg::{xmd::*, xof::*, *}; use crate::{Error, Result}; -use hybrid_array::{Array, ArraySize, typenum::Unsigned}; +use hybrid_array::{ + Array, ArraySize, + typenum::{NonZero, Unsigned}, +}; /// The trait for helping to convert to a field element. pub trait FromOkm { /// The number of bytes needed to convert to a field element. - type Length: ArraySize; + type Length: ArraySize + NonZero; /// Convert a byte sequence into a field element. fn from_okm(data: &Array) -> Self; @@ -37,7 +42,10 @@ where E: ExpandMsg<'a>, T: FromOkm + Default, { - let len_in_bytes = T::Length::to_usize().checked_mul(out.len()).ok_or(Error)?; + let len_in_bytes = T::Length::to_usize() + .checked_mul(out.len()) + .and_then(NonZeroUsize::new) + .ok_or(Error)?; let mut tmp = Array::::Length>::default(); let mut expander = E::expand_message(data, domain, len_in_bytes)?; for o in out.iter_mut() { diff --git a/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs b/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs index 510ce5b2f..444dbf72f 100644 --- a/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs +++ b/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs @@ -3,6 +3,8 @@ pub(super) mod xmd; pub(super) mod xof; +use core::num::NonZero; + use crate::{Error, Result}; use digest::{Digest, ExtendableOutput, Update, XofReader}; use hybrid_array::typenum::{IsLess, U256}; @@ -28,7 +30,7 @@ pub trait ExpandMsg<'a> { fn expand_message( msgs: &[&[u8]], dsts: &'a [&'a [u8]], - len_in_bytes: usize, + len_in_bytes: NonZero, ) -> Result; } diff --git a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs index c1cb250b7..e98843e38 100644 --- a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs +++ b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs @@ -1,6 +1,6 @@ //! `expand_message_xmd` based on a hash function. -use core::marker::PhantomData; +use core::{marker::PhantomData, num::NonZero, ops::Mul}; use super::{Domain, ExpandMsg, Expander}; use crate::{Error, Result}; @@ -8,52 +8,62 @@ use digest::{ FixedOutput, HashMarker, array::{ Array, - typenum::{IsLess, IsLessOrEqual, U256, Unsigned}, + typenum::{IsGreaterOrEqual, IsLess, IsLessOrEqual, U2, U256, Unsigned}, }, core_api::BlockSizeUser, }; -/// Placeholder type for implementing `expand_message_xmd` based on a hash function +/// Implements `expand_message_xof` via the [`ExpandMsg`] trait: +/// +/// +/// `K` is the target security level in bytes: +/// +/// /// /// # Errors /// - `dst.is_empty()` -/// - `len_in_bytes == 0` /// - `len_in_bytes > u16::MAX` /// - `len_in_bytes > 255 * HashT::OutputSize` #[derive(Debug)] -pub struct ExpandMsgXmd(PhantomData) +pub struct ExpandMsgXmd(PhantomData<(HashT, K)>) where HashT: BlockSizeUser + Default + FixedOutput + HashMarker, HashT::OutputSize: IsLess, - HashT::OutputSize: IsLessOrEqual; + HashT::OutputSize: IsLessOrEqual, + K: Mul, + HashT::OutputSize: IsGreaterOrEqual<>::Output>; -/// ExpandMsgXmd implements expand_message_xmd for the ExpandMsg trait -impl<'a, HashT> ExpandMsg<'a> for ExpandMsgXmd +impl<'a, HashT, K> ExpandMsg<'a> for ExpandMsgXmd where HashT: BlockSizeUser + Default + FixedOutput + HashMarker, - // If `len_in_bytes` is bigger then 256, length of the `DST` will depend on - // the output size of the hash, which is still not allowed to be bigger then 256: + // If DST is larger than 255 bytes, the length of the computed DST will depend on the output + // size of the hash, which is still not allowed to be larger than 256: // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-13.html#section-5.4.1-6 HashT::OutputSize: IsLess, // Constraint set by `expand_message_xmd`: // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-13.html#section-5.4.1-4 HashT::OutputSize: IsLessOrEqual, + // The number of bits output by `HashT` MUST be larger or equal to `K * 2`: + // https://www.rfc-editor.org/rfc/rfc9380.html#section-5.3.1-2.1 + K: Mul, + HashT::OutputSize: IsGreaterOrEqual<>::Output>, { type Expander = ExpanderXmd<'a, HashT>; fn expand_message( msgs: &[&[u8]], dsts: &'a [&'a [u8]], - len_in_bytes: usize, + len_in_bytes: NonZero, ) -> Result { - if len_in_bytes == 0 { + let len_in_bytes_u16 = u16::try_from(len_in_bytes.get()).map_err(|_| Error)?; + + // `255 * ` can not exceed `u16::MAX` + if len_in_bytes_u16 > 255 * HashT::OutputSize::to_u16() { return Err(Error); } - let len_in_bytes_u16 = u16::try_from(len_in_bytes).map_err(|_| Error)?; - let b_in_bytes = HashT::OutputSize::to_usize(); - let ell = u8::try_from(len_in_bytes.div_ceil(b_in_bytes)).map_err(|_| Error)?; + let ell = u8::try_from(len_in_bytes.get().div_ceil(b_in_bytes)).map_err(|_| Error)?; let domain = Domain::xmd::(dsts)?; let mut b_0 = HashT::default(); @@ -157,7 +167,7 @@ mod test { use hex_literal::hex; use hybrid_array::{ ArraySize, - typenum::{U32, U128}, + typenum::{U4, U8, U32, U128}, }; use sha2::Sha256; @@ -209,13 +219,17 @@ mod test { ) -> Result<()> where HashT: BlockSizeUser + Default + FixedOutput + HashMarker, - HashT::OutputSize: IsLess + IsLessOrEqual, + HashT::OutputSize: IsLess + IsLessOrEqual + Mul, + HashT::OutputSize: IsGreaterOrEqual<>::Output>, { assert_message::(self.msg, domain, L::to_u16(), self.msg_prime); let dst = [dst]; - let mut expander = - ExpandMsgXmd::::expand_message(&[self.msg], &dst, L::to_usize())?; + let mut expander = ExpandMsgXmd::::expand_message( + &[self.msg], + &dst, + NonZero::new(L::to_usize()).ok_or(Error)?, + )?; let mut uniform_bytes = Array::::default(); expander.fill_bytes(&mut uniform_bytes); diff --git a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs index 6a5c14621..9d40ed2c1 100644 --- a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs +++ b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs @@ -2,26 +2,38 @@ use super::{Domain, ExpandMsg, Expander}; use crate::{Error, Result}; -use core::fmt; -use digest::{ExtendableOutput, Update, XofReader}; -use hybrid_array::typenum::U32; - -/// Placeholder type for implementing `expand_message_xof` based on an extendable output function +use core::{fmt, marker::PhantomData, num::NonZero, ops::Mul}; +use digest::{ExtendableOutput, HashMarker, Update, XofReader}; +use hybrid_array::{ + ArraySize, + typenum::{IsLess, U2, U256}, +}; + +/// Implements `expand_message_xof` via the [`ExpandMsg`] trait: +/// +/// +/// `K` is the target security level in bytes: +/// +/// /// /// # Errors /// - `dst.is_empty()` -/// - `len_in_bytes == 0` /// - `len_in_bytes > u16::MAX` -pub struct ExpandMsgXof +pub struct ExpandMsgXof where - HashT: Default + ExtendableOutput + Update, + HashT: Default + ExtendableOutput + Update + HashMarker, + K: Mul, + >::Output: ArraySize + IsLess, { reader: ::Reader, + _k: PhantomData, } -impl fmt::Debug for ExpandMsgXof +impl fmt::Debug for ExpandMsgXof where - HashT: Default + ExtendableOutput + Update, + HashT: Default + ExtendableOutput + Update + HashMarker, + K: Mul, + >::Output: ArraySize + IsLess, ::Reader: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -31,25 +43,24 @@ where } } -/// ExpandMsgXof implements `expand_message_xof` for the [`ExpandMsg`] trait -impl<'a, HashT> ExpandMsg<'a> for ExpandMsgXof +impl<'a, HashT, K> ExpandMsg<'a> for ExpandMsgXof where - HashT: Default + ExtendableOutput + Update, + HashT: Default + ExtendableOutput + Update + HashMarker, + // If DST is larger than 255 bytes, the length of the computed DST is calculated by `K * 2`. + // https://www.rfc-editor.org/rfc/rfc9380.html#section-5.3.1-2.1 + K: Mul, + >::Output: ArraySize + IsLess, { type Expander = Self; fn expand_message( msgs: &[&[u8]], dsts: &'a [&'a [u8]], - len_in_bytes: usize, + len_in_bytes: NonZero, ) -> Result { - if len_in_bytes == 0 { - return Err(Error); - } - - let len_in_bytes = u16::try_from(len_in_bytes).map_err(|_| Error)?; + let len_in_bytes = u16::try_from(len_in_bytes.get()).map_err(|_| Error)?; - let domain = Domain::::xof::(dsts)?; + let domain = Domain::<>::Output>::xof::(dsts)?; let mut reader = HashT::default(); for msg in msgs { @@ -60,13 +71,18 @@ where domain.update_hash(&mut reader); reader.update(&[domain.len()]); let reader = reader.finalize_xof(); - Ok(Self { reader }) + Ok(Self { + reader, + _k: PhantomData, + }) } } -impl Expander for ExpandMsgXof +impl Expander for ExpandMsgXof where - HashT: Default + ExtendableOutput + Update, + HashT: Default + ExtendableOutput + Update + HashMarker, + K: Mul, + >::Output: ArraySize + IsLess, { fn fill_bytes(&mut self, okm: &mut [u8]) { self.reader.read(okm); @@ -78,7 +94,10 @@ mod test { use super::*; use core::mem::size_of; use hex_literal::hex; - use hybrid_array::{Array, ArraySize, typenum::U128}; + use hybrid_array::{ + Array, ArraySize, + typenum::{U16, U32, U128}, + }; use sha3::Shake128; fn assert_message(msg: &[u8], domain: &Domain<'_, U32>, len_in_bytes: u16, bytes: &[u8]) { @@ -110,13 +129,16 @@ mod test { #[allow(clippy::panic_in_result_fn)] fn assert(&self, dst: &'static [u8], domain: &Domain<'_, U32>) -> Result<()> where - HashT: Default + ExtendableOutput + Update, + HashT: Default + ExtendableOutput + Update + HashMarker, L: ArraySize, { assert_message(self.msg, domain, L::to_u16(), self.msg_prime); - let mut expander = - ExpandMsgXof::::expand_message(&[self.msg], &[dst], L::to_usize())?; + let mut expander = ExpandMsgXof::::expand_message( + &[self.msg], + &[dst], + NonZero::new(L::to_usize()).ok_or(Error)?, + )?; let mut uniform_bytes = Array::::default(); expander.fill_bytes(&mut uniform_bytes); From 515c951e09a46a05ceb2a694336c7acd021d078f Mon Sep 17 00:00:00 2001 From: daxpedda Date: Sun, 27 Apr 2025 21:23:17 +0200 Subject: [PATCH 1333/1461] elliptic-curve: impl `Zeroize` for `NonIdentity` (#1832) This PR implements `Zeroize` for `NonIdentity` setting it to `G` to prevent breaking any invariants. --- elliptic-curve/src/point/non_identity.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/elliptic-curve/src/point/non_identity.rs b/elliptic-curve/src/point/non_identity.rs index d76463e84..dbee44ec4 100644 --- a/elliptic-curve/src/point/non_identity.rs +++ b/elliptic-curve/src/point/non_identity.rs @@ -8,6 +8,7 @@ use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; #[cfg(feature = "serde")] use serdect::serde::{Deserialize, Serialize, de, ser}; +use zeroize::Zeroize; use crate::{CurveArithmetic, NonZeroScalar, Scalar}; @@ -194,12 +195,19 @@ where } } +impl Zeroize for NonIdentity

{ + fn zeroize(&mut self) { + self.point = P::generator(); + } +} + #[cfg(all(test, feature = "dev"))] mod tests { use super::NonIdentity; use crate::dev::{AffinePoint, ProjectivePoint}; use group::GroupEncoding; use hex_literal::hex; + use zeroize::Zeroize; #[test] fn new_success() { @@ -235,4 +243,16 @@ mod tests { let point = NonIdentity::::from_repr(&bytes.into()).unwrap(); assert_eq!(&bytes, point.to_bytes().as_slice()); } + + #[test] + fn zeroize() { + let point = ProjectivePoint::from_bytes( + &hex!("02c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721").into(), + ) + .unwrap(); + let mut point = NonIdentity::new(point).unwrap(); + point.zeroize(); + + assert_eq!(point.to_point(), ProjectivePoint::Generator); + } } From aa0cc553fd805cdb8b9395081eb3f0bcfbe1f22e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 29 Apr 2025 02:48:43 +0300 Subject: [PATCH 1334/1461] Update Cargo.lock (#1836) --- Cargo.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2d46974cb..d62e0ebfa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -188,9 +188,9 @@ dependencies = [ [[package]] name = "der" -version = "0.8.0-rc.1" +version = "0.8.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82db698b33305f0134faf590b9d1259dc171b5481ac41d5c8146c3b3ee7d4319" +checksum = "a348a791b3df164315b6733835b128f52f99bd76bc3b19adbd574bde4a1be2e7" dependencies = [ "const-oid", "pem-rfc7468", @@ -450,9 +450,9 @@ dependencies = [ [[package]] name = "pkcs8" -version = "0.11.0-rc.2" +version = "0.11.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f22636de7c995e997ed3d8d2949b7414d4faba3efa7312a6c0e75d875a14bdd4" +checksum = "eb59d311663eb310da092cb3b4525dac863f3fff825898db1a5a2f46420c5e84" dependencies = [ "der", "spki", @@ -701,18 +701,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.24" +version = "0.8.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879" +checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.24" +version = "0.8.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be" +checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef" dependencies = [ "proc-macro2", "quote", From 1681db50ac063c8be3ec471f153706c27a8bc1f0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 29 Apr 2025 02:49:26 +0300 Subject: [PATCH 1335/1461] ci: bump crate-ci/typos from 1.31.1 to 1.31.2 (#1835) --- .github/workflows/workspace.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index 26781a0e1..3bf0f9b3d 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -52,4 +52,4 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: crate-ci/typos@v1.31.1 + - uses: crate-ci/typos@v1.31.2 From f44963a897af10d125efe3af89b20930ebe4a999 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Tue, 29 Apr 2025 14:44:04 +0200 Subject: [PATCH 1336/1461] Add `NonIdentity::mul_by_generator()` (#1833) This PR adds `NonIdentity::mul_by_generator()`, which is similar to the `MulByGenerator` trait, but returns a `NonIdentity` instead of a `ProjectivePoint`. This is quite useful for getting the public key from a `NonZeroScalar` without having to go through the whole conversion dance. --- elliptic-curve/src/point/non_identity.rs | 30 +++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/elliptic-curve/src/point/non_identity.rs b/elliptic-curve/src/point/non_identity.rs index dbee44ec4..3068afaa0 100644 --- a/elliptic-curve/src/point/non_identity.rs +++ b/elliptic-curve/src/point/non_identity.rs @@ -2,7 +2,7 @@ use core::ops::{Deref, Mul}; -use group::{Curve, GroupEncoding, prime::PrimeCurveAffine}; +use group::{Curve, Group, GroupEncoding, prime::PrimeCurveAffine}; use rand_core::CryptoRng; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; @@ -73,6 +73,16 @@ where point: self.point.to_affine(), } } + + /// Multiply by the generator of the prime-order subgroup. + pub fn mul_by_generator(scalar: &NonZeroScalar) -> Self + where + P: Group, + { + Self { + point: P::mul_by_generator(scalar), + } + } } impl

NonIdentity

@@ -195,7 +205,7 @@ where } } -impl Zeroize for NonIdentity

{ +impl Zeroize for NonIdentity

{ fn zeroize(&mut self) { self.point = P::generator(); } @@ -204,7 +214,7 @@ impl Zeroize for NonIdentity

{ #[cfg(all(test, feature = "dev"))] mod tests { use super::NonIdentity; - use crate::dev::{AffinePoint, ProjectivePoint}; + use crate::dev::{AffinePoint, NonZeroScalar, ProjectivePoint, SecretKey}; use group::GroupEncoding; use hex_literal::hex; use zeroize::Zeroize; @@ -255,4 +265,18 @@ mod tests { assert_eq!(point.to_point(), ProjectivePoint::Generator); } + + #[test] + fn mul_by_generator() { + let scalar = NonZeroScalar::from_repr( + hex!("c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721").into(), + ) + .unwrap(); + let point = NonIdentity::::mul_by_generator(&scalar); + + let sk = SecretKey::from(scalar); + let pk = sk.public_key(); + + assert_eq!(point.to_point(), pk.to_projective()); + } } From beac4d7999a658fc59b1255b7480c27f4e2520ec Mon Sep 17 00:00:00 2001 From: daxpedda Date: Wed, 30 Apr 2025 15:43:13 +0200 Subject: [PATCH 1337/1461] Add `CollisionResistance` trait (#1820) This PR adds a new trait called `CollisionResistance` which can be applied to hashes and MACs to signify their collision resistance. --- digest/src/core_api/ct_variable.rs | 11 ++++++++++- digest/src/core_api/rt_variable.rs | 6 +++++- digest/src/core_api/wrapper.rs | 8 ++++++-- digest/src/lib.rs | 9 +++++++++ digest/src/xof_fixed.rs | 10 ++++++++-- 5 files changed, 38 insertions(+), 6 deletions(-) diff --git a/digest/src/core_api/ct_variable.rs b/digest/src/core_api/ct_variable.rs index eeb9cd554..d8ad3e8ca 100644 --- a/digest/src/core_api/ct_variable.rs +++ b/digest/src/core_api/ct_variable.rs @@ -4,7 +4,7 @@ use super::{ }; #[cfg(feature = "mac")] use crate::MacMarker; -use crate::{CustomizedInit, HashMarker, VarOutputCustomized}; +use crate::{CollisionResistance, CustomizedInit, HashMarker, VarOutputCustomized}; use core::{ fmt, marker::PhantomData, @@ -46,6 +46,15 @@ where { } +impl CollisionResistance for CtVariableCoreWrapper +where + T: VariableOutputCore + CollisionResistance, + OutSize: ArraySize + IsLessOrEqual, + LeEq: NonZero, +{ + type CollisionResistance = T::CollisionResistance; +} + impl BlockSizeUser for CtVariableCoreWrapper where T: VariableOutputCore, diff --git a/digest/src/core_api/rt_variable.rs b/digest/src/core_api/rt_variable.rs index 1cb212ea9..6b69f09d9 100644 --- a/digest/src/core_api/rt_variable.rs +++ b/digest/src/core_api/rt_variable.rs @@ -1,7 +1,7 @@ use super::{AlgorithmName, BlockSizeUser, TruncSide, VariableOutputCore}; #[cfg(feature = "mac")] use crate::MacMarker; -use crate::{HashMarker, InvalidBufferSize}; +use crate::{CollisionResistance, HashMarker, InvalidBufferSize}; use crate::{InvalidOutputSize, Reset, Update, VariableOutput, VariableOutputReset}; use block_buffer::BlockBuffer; use core::{ @@ -56,6 +56,10 @@ impl HashMarker for RtVariableCoreWrapper #[cfg(feature = "mac")] impl MacMarker for RtVariableCoreWrapper {} +impl CollisionResistance for RtVariableCoreWrapper { + type CollisionResistance = T::CollisionResistance; +} + impl BlockSizeUser for RtVariableCoreWrapper { type BlockSize = T::BlockSize; } diff --git a/digest/src/core_api/wrapper.rs b/digest/src/core_api/wrapper.rs index 6cd006fab..242871772 100644 --- a/digest/src/core_api/wrapper.rs +++ b/digest/src/core_api/wrapper.rs @@ -3,8 +3,8 @@ use super::{ UpdateCore, XofReaderCoreWrapper, }; use crate::{ - CustomizedInit, ExtendableOutput, ExtendableOutputReset, FixedOutput, FixedOutputReset, - HashMarker, Update, + CollisionResistance, CustomizedInit, ExtendableOutput, ExtendableOutputReset, FixedOutput, + FixedOutputReset, HashMarker, Update, }; use block_buffer::BlockBuffer; use core::{ @@ -36,6 +36,10 @@ impl HashMarker for CoreWrapper {} #[cfg(feature = "mac")] impl MacMarker for CoreWrapper {} +impl CollisionResistance for CoreWrapper { + type CollisionResistance = T::CollisionResistance; +} + // this blanket impl is needed for HMAC impl BlockSizeUser for CoreWrapper { type BlockSize = T::BlockSize; diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 6537d84a9..de2a784b6 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -74,6 +74,7 @@ pub use mac::{CtOutput, Mac, MacError, MacMarker}; pub use xof_fixed::XofFixedWrapper; use core::fmt; +use crypto_common::typenum::Unsigned; /// Types which consume data with byte granularity. pub trait Update { @@ -282,6 +283,14 @@ pub trait VarOutputCustomized: Sized { fn new_customized(customization: &[u8], output_size: usize) -> Self; } +/// Types with a certain collision resistance. +pub trait CollisionResistance { + /// Collision resistance in bytes. This applies to an output size of `CollisionResistance * 2`. + /// The collision resistance with a smaller output size is not defined by this trait and is at + /// least the given collision resistance with a bigger output. + type CollisionResistance: Unsigned; +} + /// The error type used in variable hash traits. #[derive(Clone, Copy, Debug, Default)] pub struct InvalidOutputSize; diff --git a/digest/src/xof_fixed.rs b/digest/src/xof_fixed.rs index d852904bf..a5e5d77a4 100644 --- a/digest/src/xof_fixed.rs +++ b/digest/src/xof_fixed.rs @@ -6,8 +6,8 @@ use crypto_common::hazmat::SerializableState; use crypto_common::{BlockSizeUser, KeyInit, KeySizeUser, OutputSizeUser, Reset}; use crate::{ - CustomizedInit, ExtendableOutput, ExtendableOutputReset, FixedOutput, FixedOutputReset, - HashMarker, Update, + CollisionResistance, CustomizedInit, ExtendableOutput, ExtendableOutputReset, FixedOutput, + FixedOutputReset, HashMarker, Update, }; /// Wrapper around [`ExtendableOutput`] types adding [`OutputSizeUser`] with the given size of `S`. @@ -51,6 +51,12 @@ impl crate::MacMarker { } +impl CollisionResistance + for XofFixedWrapper +{ + type CollisionResistance = T::CollisionResistance; +} + // this blanket impl is needed for HMAC impl BlockSizeUser for XofFixedWrapper { type BlockSize = T::BlockSize; From ddee7f8d6bf1559f1b000e82f7aed5235df951f9 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 30 Apr 2025 12:48:42 -0600 Subject: [PATCH 1338/1461] elliptic-curve: remove `tap` hack (#1838) This is hopefully no longer relevant --- Cargo.lock | 1 - elliptic-curve/Cargo.toml | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d62e0ebfa..2e81d888c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -243,7 +243,6 @@ dependencies = [ "sha2", "sha3", "subtle", - "tap", "zeroize", ] diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 2e9efd2bd..c8eaf160a 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -36,7 +36,6 @@ pkcs8 = { version = "0.11.0-rc.1", optional = true, default-features = false } sec1 = { version = "0.8.0-rc.4", optional = true, features = ["subtle", "zeroize"] } serdect = { version = "0.3", optional = true, default-features = false, features = ["alloc"] } serde_json = { version = "1.0.121", optional = true, default-features = false, features = ["alloc"] } -tap = { version = "1.0.1", optional = true, default-features = false } # hack for minimal-versions support for `bits` [dev-dependencies] hex-literal = "1" @@ -61,7 +60,7 @@ std = [ ] arithmetic = ["group"] -bits = ["arithmetic", "ff/bits", "dep:tap"] +bits = ["arithmetic", "ff/bits"] dev = ["arithmetic", "dep:hex-literal", "pem", "pkcs8"] hash2curve = ["arithmetic", "digest"] ecdh = ["arithmetic", "digest", "dep:hkdf"] From d676b98c5537e166f69e2ca7845e012f390ad34b Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 30 Apr 2025 21:48:22 -0600 Subject: [PATCH 1339/1461] elliptic-curve: use `crypto_bigint::Invert` trait (#1839) Replaces `elliptic_curve::ops::Invert` which has an identical shape --- Cargo.lock | 4 ++-- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/ops.rs | 21 +-------------------- 3 files changed, 4 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2e81d888c..6f012057c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -158,9 +158,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.7.0-pre.1" +version = "0.7.0-pre.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6957fb7344601c8271b03e9d4c7efb46f1dee86553eee20f99e54db0cf53f36e" +checksum = "87a5061ea0870b06f7fdd5a0f7268e30c04de1932c148cca0ce5c79a88d18bed" dependencies = [ "hybrid-array", "num-traits", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index c8eaf160a..e936b45bf 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -18,7 +18,7 @@ and public/secret keys composed thereof. [dependencies] base16ct = "0.2" -crypto-bigint = { version = "=0.7.0-pre.1", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } +crypto-bigint = { version = "=0.7.0-pre.2", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } hybrid-array = { version = "0.3", default-features = false, features = ["zeroize"] } rand_core = { version = "0.9.0", default-features = false } subtle = { version = "2.6", default-features = false } diff --git a/elliptic-curve/src/ops.rs b/elliptic-curve/src/ops.rs index b030a05c8..e5cf2a38d 100644 --- a/elliptic-curve/src/ops.rs +++ b/elliptic-curve/src/ops.rs @@ -1,6 +1,7 @@ //! Traits for arithmetic operations on elliptic curve field elements. pub use core::ops::{Add, AddAssign, Mul, Neg, Shr, ShrAssign, Sub, SubAssign}; +pub use crypto_bigint::Invert; use crypto_bigint::Integer; use subtle::{Choice, ConditionallySelectable, CtOption}; @@ -8,26 +9,6 @@ use subtle::{Choice, ConditionallySelectable, CtOption}; #[cfg(feature = "alloc")] use alloc::vec::Vec; -/// Perform an inversion on a field element (i.e. base field element or scalar) -pub trait Invert { - /// Field element type - type Output; - - /// Invert a field element. - fn invert(&self) -> Self::Output; - - /// Invert a field element in variable time. - /// - /// ⚠️ WARNING! - /// - /// This method should not be used with secret values, as its variable-time - /// operation can potentially leak secrets through sidechannels. - fn invert_vartime(&self) -> Self::Output { - // Fall back on constant-time implementation by default. - self.invert() - } -} - /// Perform a batched inversion on a sequence of field elements (i.e. base field elements or scalars) /// at an amortized cost that should be practically as efficient as a single inversion. pub trait BatchInvert: Invert + Sized { From 2ab0f99f7058f38a9f4740c33e9bfb9384996a2a Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 30 Apr 2025 22:01:18 -0600 Subject: [PATCH 1340/1461] Revert "Various fixes and improvements to hash2curve (#1813)" This reverts commit 5d3e03178b822f13e85ce46316e1f524ed7921c4. Temporarily reverting to unblock updating https://github.com/RustCrypto/elliptic-curves --- elliptic-curve/src/hash2curve/group_digest.rs | 6 -- elliptic-curve/src/hash2curve/hash2field.rs | 14 +--- .../src/hash2curve/hash2field/expand_msg.rs | 4 +- .../hash2curve/hash2field/expand_msg/xmd.rs | 52 +++++-------- .../hash2curve/hash2field/expand_msg/xof.rs | 76 +++++++------------ 5 files changed, 50 insertions(+), 102 deletions(-) diff --git a/elliptic-curve/src/hash2curve/group_digest.rs b/elliptic-curve/src/hash2curve/group_digest.rs index 8fa27c46c..2a663a11b 100644 --- a/elliptic-curve/src/hash2curve/group_digest.rs +++ b/elliptic-curve/src/hash2curve/group_digest.rs @@ -3,7 +3,6 @@ use super::{ExpandMsg, FromOkm, MapToCurve, hash_to_field}; use crate::{CurveArithmetic, ProjectivePoint, Result}; use group::cofactor::CofactorGroup; -use hybrid_array::typenum::Unsigned; /// Adds hashing arbitrary byte sequences to a valid group element pub trait GroupDigest: CurveArithmetic @@ -13,11 +12,6 @@ where /// The field element representation for a group value with multiple elements type FieldElement: FromOkm + MapToCurve> + Default + Copy; - /// The target security level in bytes: - /// - /// - type K: Unsigned; - /// Computes the hash to curve routine. /// /// From : diff --git a/elliptic-curve/src/hash2curve/hash2field.rs b/elliptic-curve/src/hash2curve/hash2field.rs index 4ffcf8062..946c8a39d 100644 --- a/elliptic-curve/src/hash2curve/hash2field.rs +++ b/elliptic-curve/src/hash2curve/hash2field.rs @@ -4,20 +4,15 @@ mod expand_msg; -use core::num::NonZeroUsize; - pub use expand_msg::{xmd::*, xof::*, *}; use crate::{Error, Result}; -use hybrid_array::{ - Array, ArraySize, - typenum::{NonZero, Unsigned}, -}; +use hybrid_array::{Array, ArraySize, typenum::Unsigned}; /// The trait for helping to convert to a field element. pub trait FromOkm { /// The number of bytes needed to convert to a field element. - type Length: ArraySize + NonZero; + type Length: ArraySize; /// Convert a byte sequence into a field element. fn from_okm(data: &Array) -> Self; @@ -42,10 +37,7 @@ where E: ExpandMsg<'a>, T: FromOkm + Default, { - let len_in_bytes = T::Length::to_usize() - .checked_mul(out.len()) - .and_then(NonZeroUsize::new) - .ok_or(Error)?; + let len_in_bytes = T::Length::to_usize().checked_mul(out.len()).ok_or(Error)?; let mut tmp = Array::::Length>::default(); let mut expander = E::expand_message(data, domain, len_in_bytes)?; for o in out.iter_mut() { diff --git a/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs b/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs index 444dbf72f..510ce5b2f 100644 --- a/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs +++ b/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs @@ -3,8 +3,6 @@ pub(super) mod xmd; pub(super) mod xof; -use core::num::NonZero; - use crate::{Error, Result}; use digest::{Digest, ExtendableOutput, Update, XofReader}; use hybrid_array::typenum::{IsLess, U256}; @@ -30,7 +28,7 @@ pub trait ExpandMsg<'a> { fn expand_message( msgs: &[&[u8]], dsts: &'a [&'a [u8]], - len_in_bytes: NonZero, + len_in_bytes: usize, ) -> Result; } diff --git a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs index e98843e38..c1cb250b7 100644 --- a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs +++ b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs @@ -1,6 +1,6 @@ //! `expand_message_xmd` based on a hash function. -use core::{marker::PhantomData, num::NonZero, ops::Mul}; +use core::marker::PhantomData; use super::{Domain, ExpandMsg, Expander}; use crate::{Error, Result}; @@ -8,62 +8,52 @@ use digest::{ FixedOutput, HashMarker, array::{ Array, - typenum::{IsGreaterOrEqual, IsLess, IsLessOrEqual, U2, U256, Unsigned}, + typenum::{IsLess, IsLessOrEqual, U256, Unsigned}, }, core_api::BlockSizeUser, }; -/// Implements `expand_message_xof` via the [`ExpandMsg`] trait: -/// -/// -/// `K` is the target security level in bytes: -/// -/// +/// Placeholder type for implementing `expand_message_xmd` based on a hash function /// /// # Errors /// - `dst.is_empty()` +/// - `len_in_bytes == 0` /// - `len_in_bytes > u16::MAX` /// - `len_in_bytes > 255 * HashT::OutputSize` #[derive(Debug)] -pub struct ExpandMsgXmd(PhantomData<(HashT, K)>) +pub struct ExpandMsgXmd(PhantomData) where HashT: BlockSizeUser + Default + FixedOutput + HashMarker, HashT::OutputSize: IsLess, - HashT::OutputSize: IsLessOrEqual, - K: Mul, - HashT::OutputSize: IsGreaterOrEqual<>::Output>; + HashT::OutputSize: IsLessOrEqual; -impl<'a, HashT, K> ExpandMsg<'a> for ExpandMsgXmd +/// ExpandMsgXmd implements expand_message_xmd for the ExpandMsg trait +impl<'a, HashT> ExpandMsg<'a> for ExpandMsgXmd where HashT: BlockSizeUser + Default + FixedOutput + HashMarker, - // If DST is larger than 255 bytes, the length of the computed DST will depend on the output - // size of the hash, which is still not allowed to be larger than 256: + // If `len_in_bytes` is bigger then 256, length of the `DST` will depend on + // the output size of the hash, which is still not allowed to be bigger then 256: // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-13.html#section-5.4.1-6 HashT::OutputSize: IsLess, // Constraint set by `expand_message_xmd`: // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-13.html#section-5.4.1-4 HashT::OutputSize: IsLessOrEqual, - // The number of bits output by `HashT` MUST be larger or equal to `K * 2`: - // https://www.rfc-editor.org/rfc/rfc9380.html#section-5.3.1-2.1 - K: Mul, - HashT::OutputSize: IsGreaterOrEqual<>::Output>, { type Expander = ExpanderXmd<'a, HashT>; fn expand_message( msgs: &[&[u8]], dsts: &'a [&'a [u8]], - len_in_bytes: NonZero, + len_in_bytes: usize, ) -> Result { - let len_in_bytes_u16 = u16::try_from(len_in_bytes.get()).map_err(|_| Error)?; - - // `255 * ` can not exceed `u16::MAX` - if len_in_bytes_u16 > 255 * HashT::OutputSize::to_u16() { + if len_in_bytes == 0 { return Err(Error); } + let len_in_bytes_u16 = u16::try_from(len_in_bytes).map_err(|_| Error)?; + let b_in_bytes = HashT::OutputSize::to_usize(); - let ell = u8::try_from(len_in_bytes.get().div_ceil(b_in_bytes)).map_err(|_| Error)?; + let ell = u8::try_from(len_in_bytes.div_ceil(b_in_bytes)).map_err(|_| Error)?; let domain = Domain::xmd::(dsts)?; let mut b_0 = HashT::default(); @@ -167,7 +157,7 @@ mod test { use hex_literal::hex; use hybrid_array::{ ArraySize, - typenum::{U4, U8, U32, U128}, + typenum::{U32, U128}, }; use sha2::Sha256; @@ -219,17 +209,13 @@ mod test { ) -> Result<()> where HashT: BlockSizeUser + Default + FixedOutput + HashMarker, - HashT::OutputSize: IsLess + IsLessOrEqual + Mul, - HashT::OutputSize: IsGreaterOrEqual<>::Output>, + HashT::OutputSize: IsLess + IsLessOrEqual, { assert_message::(self.msg, domain, L::to_u16(), self.msg_prime); let dst = [dst]; - let mut expander = ExpandMsgXmd::::expand_message( - &[self.msg], - &dst, - NonZero::new(L::to_usize()).ok_or(Error)?, - )?; + let mut expander = + ExpandMsgXmd::::expand_message(&[self.msg], &dst, L::to_usize())?; let mut uniform_bytes = Array::::default(); expander.fill_bytes(&mut uniform_bytes); diff --git a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs index 9d40ed2c1..6a5c14621 100644 --- a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs +++ b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs @@ -2,38 +2,26 @@ use super::{Domain, ExpandMsg, Expander}; use crate::{Error, Result}; -use core::{fmt, marker::PhantomData, num::NonZero, ops::Mul}; -use digest::{ExtendableOutput, HashMarker, Update, XofReader}; -use hybrid_array::{ - ArraySize, - typenum::{IsLess, U2, U256}, -}; - -/// Implements `expand_message_xof` via the [`ExpandMsg`] trait: -/// -/// -/// `K` is the target security level in bytes: -/// -/// +use core::fmt; +use digest::{ExtendableOutput, Update, XofReader}; +use hybrid_array::typenum::U32; + +/// Placeholder type for implementing `expand_message_xof` based on an extendable output function /// /// # Errors /// - `dst.is_empty()` +/// - `len_in_bytes == 0` /// - `len_in_bytes > u16::MAX` -pub struct ExpandMsgXof +pub struct ExpandMsgXof where - HashT: Default + ExtendableOutput + Update + HashMarker, - K: Mul, - >::Output: ArraySize + IsLess, + HashT: Default + ExtendableOutput + Update, { reader: ::Reader, - _k: PhantomData, } -impl fmt::Debug for ExpandMsgXof +impl fmt::Debug for ExpandMsgXof where - HashT: Default + ExtendableOutput + Update + HashMarker, - K: Mul, - >::Output: ArraySize + IsLess, + HashT: Default + ExtendableOutput + Update, ::Reader: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -43,24 +31,25 @@ where } } -impl<'a, HashT, K> ExpandMsg<'a> for ExpandMsgXof +/// ExpandMsgXof implements `expand_message_xof` for the [`ExpandMsg`] trait +impl<'a, HashT> ExpandMsg<'a> for ExpandMsgXof where - HashT: Default + ExtendableOutput + Update + HashMarker, - // If DST is larger than 255 bytes, the length of the computed DST is calculated by `K * 2`. - // https://www.rfc-editor.org/rfc/rfc9380.html#section-5.3.1-2.1 - K: Mul, - >::Output: ArraySize + IsLess, + HashT: Default + ExtendableOutput + Update, { type Expander = Self; fn expand_message( msgs: &[&[u8]], dsts: &'a [&'a [u8]], - len_in_bytes: NonZero, + len_in_bytes: usize, ) -> Result { - let len_in_bytes = u16::try_from(len_in_bytes.get()).map_err(|_| Error)?; + if len_in_bytes == 0 { + return Err(Error); + } + + let len_in_bytes = u16::try_from(len_in_bytes).map_err(|_| Error)?; - let domain = Domain::<>::Output>::xof::(dsts)?; + let domain = Domain::::xof::(dsts)?; let mut reader = HashT::default(); for msg in msgs { @@ -71,18 +60,13 @@ where domain.update_hash(&mut reader); reader.update(&[domain.len()]); let reader = reader.finalize_xof(); - Ok(Self { - reader, - _k: PhantomData, - }) + Ok(Self { reader }) } } -impl Expander for ExpandMsgXof +impl Expander for ExpandMsgXof where - HashT: Default + ExtendableOutput + Update + HashMarker, - K: Mul, - >::Output: ArraySize + IsLess, + HashT: Default + ExtendableOutput + Update, { fn fill_bytes(&mut self, okm: &mut [u8]) { self.reader.read(okm); @@ -94,10 +78,7 @@ mod test { use super::*; use core::mem::size_of; use hex_literal::hex; - use hybrid_array::{ - Array, ArraySize, - typenum::{U16, U32, U128}, - }; + use hybrid_array::{Array, ArraySize, typenum::U128}; use sha3::Shake128; fn assert_message(msg: &[u8], domain: &Domain<'_, U32>, len_in_bytes: u16, bytes: &[u8]) { @@ -129,16 +110,13 @@ mod test { #[allow(clippy::panic_in_result_fn)] fn assert(&self, dst: &'static [u8], domain: &Domain<'_, U32>) -> Result<()> where - HashT: Default + ExtendableOutput + Update + HashMarker, + HashT: Default + ExtendableOutput + Update, L: ArraySize, { assert_message(self.msg, domain, L::to_u16(), self.msg_prime); - let mut expander = ExpandMsgXof::::expand_message( - &[self.msg], - &[dst], - NonZero::new(L::to_usize()).ok_or(Error)?, - )?; + let mut expander = + ExpandMsgXof::::expand_message(&[self.msg], &[dst], L::to_usize())?; let mut uniform_bytes = Array::::default(); expander.fill_bytes(&mut uniform_bytes); From 622b6c0341b2ba11040affdd4688ec98f9b3c552 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 30 Apr 2025 22:04:08 -0600 Subject: [PATCH 1341/1461] Revert "Revert "Various fixes and improvements to hash2curve (#1813)"" This reverts commit 2ab0f99f7058f38a9f4740c33e9bfb9384996a2a. Reverting the revert now that we can pin to the hash with the revert --- elliptic-curve/src/hash2curve/group_digest.rs | 6 ++ elliptic-curve/src/hash2curve/hash2field.rs | 14 +++- .../src/hash2curve/hash2field/expand_msg.rs | 4 +- .../hash2curve/hash2field/expand_msg/xmd.rs | 52 ++++++++----- .../hash2curve/hash2field/expand_msg/xof.rs | 76 ++++++++++++------- 5 files changed, 102 insertions(+), 50 deletions(-) diff --git a/elliptic-curve/src/hash2curve/group_digest.rs b/elliptic-curve/src/hash2curve/group_digest.rs index 2a663a11b..8fa27c46c 100644 --- a/elliptic-curve/src/hash2curve/group_digest.rs +++ b/elliptic-curve/src/hash2curve/group_digest.rs @@ -3,6 +3,7 @@ use super::{ExpandMsg, FromOkm, MapToCurve, hash_to_field}; use crate::{CurveArithmetic, ProjectivePoint, Result}; use group::cofactor::CofactorGroup; +use hybrid_array::typenum::Unsigned; /// Adds hashing arbitrary byte sequences to a valid group element pub trait GroupDigest: CurveArithmetic @@ -12,6 +13,11 @@ where /// The field element representation for a group value with multiple elements type FieldElement: FromOkm + MapToCurve> + Default + Copy; + /// The target security level in bytes: + /// + /// + type K: Unsigned; + /// Computes the hash to curve routine. /// /// From : diff --git a/elliptic-curve/src/hash2curve/hash2field.rs b/elliptic-curve/src/hash2curve/hash2field.rs index 946c8a39d..4ffcf8062 100644 --- a/elliptic-curve/src/hash2curve/hash2field.rs +++ b/elliptic-curve/src/hash2curve/hash2field.rs @@ -4,15 +4,20 @@ mod expand_msg; +use core::num::NonZeroUsize; + pub use expand_msg::{xmd::*, xof::*, *}; use crate::{Error, Result}; -use hybrid_array::{Array, ArraySize, typenum::Unsigned}; +use hybrid_array::{ + Array, ArraySize, + typenum::{NonZero, Unsigned}, +}; /// The trait for helping to convert to a field element. pub trait FromOkm { /// The number of bytes needed to convert to a field element. - type Length: ArraySize; + type Length: ArraySize + NonZero; /// Convert a byte sequence into a field element. fn from_okm(data: &Array) -> Self; @@ -37,7 +42,10 @@ where E: ExpandMsg<'a>, T: FromOkm + Default, { - let len_in_bytes = T::Length::to_usize().checked_mul(out.len()).ok_or(Error)?; + let len_in_bytes = T::Length::to_usize() + .checked_mul(out.len()) + .and_then(NonZeroUsize::new) + .ok_or(Error)?; let mut tmp = Array::::Length>::default(); let mut expander = E::expand_message(data, domain, len_in_bytes)?; for o in out.iter_mut() { diff --git a/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs b/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs index 510ce5b2f..444dbf72f 100644 --- a/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs +++ b/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs @@ -3,6 +3,8 @@ pub(super) mod xmd; pub(super) mod xof; +use core::num::NonZero; + use crate::{Error, Result}; use digest::{Digest, ExtendableOutput, Update, XofReader}; use hybrid_array::typenum::{IsLess, U256}; @@ -28,7 +30,7 @@ pub trait ExpandMsg<'a> { fn expand_message( msgs: &[&[u8]], dsts: &'a [&'a [u8]], - len_in_bytes: usize, + len_in_bytes: NonZero, ) -> Result; } diff --git a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs index c1cb250b7..e98843e38 100644 --- a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs +++ b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs @@ -1,6 +1,6 @@ //! `expand_message_xmd` based on a hash function. -use core::marker::PhantomData; +use core::{marker::PhantomData, num::NonZero, ops::Mul}; use super::{Domain, ExpandMsg, Expander}; use crate::{Error, Result}; @@ -8,52 +8,62 @@ use digest::{ FixedOutput, HashMarker, array::{ Array, - typenum::{IsLess, IsLessOrEqual, U256, Unsigned}, + typenum::{IsGreaterOrEqual, IsLess, IsLessOrEqual, U2, U256, Unsigned}, }, core_api::BlockSizeUser, }; -/// Placeholder type for implementing `expand_message_xmd` based on a hash function +/// Implements `expand_message_xof` via the [`ExpandMsg`] trait: +/// +/// +/// `K` is the target security level in bytes: +/// +/// /// /// # Errors /// - `dst.is_empty()` -/// - `len_in_bytes == 0` /// - `len_in_bytes > u16::MAX` /// - `len_in_bytes > 255 * HashT::OutputSize` #[derive(Debug)] -pub struct ExpandMsgXmd(PhantomData) +pub struct ExpandMsgXmd(PhantomData<(HashT, K)>) where HashT: BlockSizeUser + Default + FixedOutput + HashMarker, HashT::OutputSize: IsLess, - HashT::OutputSize: IsLessOrEqual; + HashT::OutputSize: IsLessOrEqual, + K: Mul, + HashT::OutputSize: IsGreaterOrEqual<>::Output>; -/// ExpandMsgXmd implements expand_message_xmd for the ExpandMsg trait -impl<'a, HashT> ExpandMsg<'a> for ExpandMsgXmd +impl<'a, HashT, K> ExpandMsg<'a> for ExpandMsgXmd where HashT: BlockSizeUser + Default + FixedOutput + HashMarker, - // If `len_in_bytes` is bigger then 256, length of the `DST` will depend on - // the output size of the hash, which is still not allowed to be bigger then 256: + // If DST is larger than 255 bytes, the length of the computed DST will depend on the output + // size of the hash, which is still not allowed to be larger than 256: // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-13.html#section-5.4.1-6 HashT::OutputSize: IsLess, // Constraint set by `expand_message_xmd`: // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-13.html#section-5.4.1-4 HashT::OutputSize: IsLessOrEqual, + // The number of bits output by `HashT` MUST be larger or equal to `K * 2`: + // https://www.rfc-editor.org/rfc/rfc9380.html#section-5.3.1-2.1 + K: Mul, + HashT::OutputSize: IsGreaterOrEqual<>::Output>, { type Expander = ExpanderXmd<'a, HashT>; fn expand_message( msgs: &[&[u8]], dsts: &'a [&'a [u8]], - len_in_bytes: usize, + len_in_bytes: NonZero, ) -> Result { - if len_in_bytes == 0 { + let len_in_bytes_u16 = u16::try_from(len_in_bytes.get()).map_err(|_| Error)?; + + // `255 * ` can not exceed `u16::MAX` + if len_in_bytes_u16 > 255 * HashT::OutputSize::to_u16() { return Err(Error); } - let len_in_bytes_u16 = u16::try_from(len_in_bytes).map_err(|_| Error)?; - let b_in_bytes = HashT::OutputSize::to_usize(); - let ell = u8::try_from(len_in_bytes.div_ceil(b_in_bytes)).map_err(|_| Error)?; + let ell = u8::try_from(len_in_bytes.get().div_ceil(b_in_bytes)).map_err(|_| Error)?; let domain = Domain::xmd::(dsts)?; let mut b_0 = HashT::default(); @@ -157,7 +167,7 @@ mod test { use hex_literal::hex; use hybrid_array::{ ArraySize, - typenum::{U32, U128}, + typenum::{U4, U8, U32, U128}, }; use sha2::Sha256; @@ -209,13 +219,17 @@ mod test { ) -> Result<()> where HashT: BlockSizeUser + Default + FixedOutput + HashMarker, - HashT::OutputSize: IsLess + IsLessOrEqual, + HashT::OutputSize: IsLess + IsLessOrEqual + Mul, + HashT::OutputSize: IsGreaterOrEqual<>::Output>, { assert_message::(self.msg, domain, L::to_u16(), self.msg_prime); let dst = [dst]; - let mut expander = - ExpandMsgXmd::::expand_message(&[self.msg], &dst, L::to_usize())?; + let mut expander = ExpandMsgXmd::::expand_message( + &[self.msg], + &dst, + NonZero::new(L::to_usize()).ok_or(Error)?, + )?; let mut uniform_bytes = Array::::default(); expander.fill_bytes(&mut uniform_bytes); diff --git a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs index 6a5c14621..9d40ed2c1 100644 --- a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs +++ b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs @@ -2,26 +2,38 @@ use super::{Domain, ExpandMsg, Expander}; use crate::{Error, Result}; -use core::fmt; -use digest::{ExtendableOutput, Update, XofReader}; -use hybrid_array::typenum::U32; - -/// Placeholder type for implementing `expand_message_xof` based on an extendable output function +use core::{fmt, marker::PhantomData, num::NonZero, ops::Mul}; +use digest::{ExtendableOutput, HashMarker, Update, XofReader}; +use hybrid_array::{ + ArraySize, + typenum::{IsLess, U2, U256}, +}; + +/// Implements `expand_message_xof` via the [`ExpandMsg`] trait: +/// +/// +/// `K` is the target security level in bytes: +/// +/// /// /// # Errors /// - `dst.is_empty()` -/// - `len_in_bytes == 0` /// - `len_in_bytes > u16::MAX` -pub struct ExpandMsgXof +pub struct ExpandMsgXof where - HashT: Default + ExtendableOutput + Update, + HashT: Default + ExtendableOutput + Update + HashMarker, + K: Mul, + >::Output: ArraySize + IsLess, { reader: ::Reader, + _k: PhantomData, } -impl fmt::Debug for ExpandMsgXof +impl fmt::Debug for ExpandMsgXof where - HashT: Default + ExtendableOutput + Update, + HashT: Default + ExtendableOutput + Update + HashMarker, + K: Mul, + >::Output: ArraySize + IsLess, ::Reader: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -31,25 +43,24 @@ where } } -/// ExpandMsgXof implements `expand_message_xof` for the [`ExpandMsg`] trait -impl<'a, HashT> ExpandMsg<'a> for ExpandMsgXof +impl<'a, HashT, K> ExpandMsg<'a> for ExpandMsgXof where - HashT: Default + ExtendableOutput + Update, + HashT: Default + ExtendableOutput + Update + HashMarker, + // If DST is larger than 255 bytes, the length of the computed DST is calculated by `K * 2`. + // https://www.rfc-editor.org/rfc/rfc9380.html#section-5.3.1-2.1 + K: Mul, + >::Output: ArraySize + IsLess, { type Expander = Self; fn expand_message( msgs: &[&[u8]], dsts: &'a [&'a [u8]], - len_in_bytes: usize, + len_in_bytes: NonZero, ) -> Result { - if len_in_bytes == 0 { - return Err(Error); - } - - let len_in_bytes = u16::try_from(len_in_bytes).map_err(|_| Error)?; + let len_in_bytes = u16::try_from(len_in_bytes.get()).map_err(|_| Error)?; - let domain = Domain::::xof::(dsts)?; + let domain = Domain::<>::Output>::xof::(dsts)?; let mut reader = HashT::default(); for msg in msgs { @@ -60,13 +71,18 @@ where domain.update_hash(&mut reader); reader.update(&[domain.len()]); let reader = reader.finalize_xof(); - Ok(Self { reader }) + Ok(Self { + reader, + _k: PhantomData, + }) } } -impl Expander for ExpandMsgXof +impl Expander for ExpandMsgXof where - HashT: Default + ExtendableOutput + Update, + HashT: Default + ExtendableOutput + Update + HashMarker, + K: Mul, + >::Output: ArraySize + IsLess, { fn fill_bytes(&mut self, okm: &mut [u8]) { self.reader.read(okm); @@ -78,7 +94,10 @@ mod test { use super::*; use core::mem::size_of; use hex_literal::hex; - use hybrid_array::{Array, ArraySize, typenum::U128}; + use hybrid_array::{ + Array, ArraySize, + typenum::{U16, U32, U128}, + }; use sha3::Shake128; fn assert_message(msg: &[u8], domain: &Domain<'_, U32>, len_in_bytes: u16, bytes: &[u8]) { @@ -110,13 +129,16 @@ mod test { #[allow(clippy::panic_in_result_fn)] fn assert(&self, dst: &'static [u8], domain: &Domain<'_, U32>) -> Result<()> where - HashT: Default + ExtendableOutput + Update, + HashT: Default + ExtendableOutput + Update + HashMarker, L: ArraySize, { assert_message(self.msg, domain, L::to_u16(), self.msg_prime); - let mut expander = - ExpandMsgXof::::expand_message(&[self.msg], &[dst], L::to_usize())?; + let mut expander = ExpandMsgXof::::expand_message( + &[self.msg], + &[dst], + NonZero::new(L::to_usize()).ok_or(Error)?, + )?; let mut uniform_bytes = Array::::default(); expander.fill_bytes(&mut uniform_bytes); From ac5443909846354e11570e2968937a62f2019bed Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 1 May 2025 11:24:37 -0600 Subject: [PATCH 1342/1461] Revert "signature: replace `signature_derive` with blanket impls (#1827)" (#1840) This reverts commit bf4774878c7c2e36451119a0ad24f1db6dc93cd8. Per #1831 this change breaks inference when there is a single explicit impl of the `Signer` trait. It also wasn't possible to add corresponding blanket impls to the `Async*` traits, e.g. `AsyncSigner` for `AsyncDigestSigner`, because of the existing blanket impl of `AsyncSigner` for `Signer` which we definitely want to preserve. As a general rule of thumb, blanket impls only make sense if they work 100% of the time, which doesn't seem to be happening here. Closes #1831 --- .github/workflows/signature.yml | 21 +- Cargo.lock | 22 +- Cargo.toml | 1 + async-signature/Cargo.toml | 4 +- crypto/Cargo.toml | 2 +- signature/Cargo.toml | 1 + signature/src/lib.rs | 6 + signature/src/prehash_signature.rs | 5 +- signature/src/signer.rs | 28 +-- signature/src/verifier.rs | 13 +- signature/tests/derive.rs | 85 +++++++ signature_derive/CHANGELOG.md | 76 ++++++ signature_derive/Cargo.toml | 21 ++ signature_derive/LICENSE-APACHE | 201 +++++++++++++++ signature_derive/LICENSE-MIT | 25 ++ signature_derive/README.md | 41 +++ signature_derive/src/lib.rs | 392 +++++++++++++++++++++++++++++ 17 files changed, 887 insertions(+), 57 deletions(-) create mode 100644 signature/tests/derive.rs create mode 100644 signature_derive/CHANGELOG.md create mode 100644 signature_derive/Cargo.toml create mode 100644 signature_derive/LICENSE-APACHE create mode 100644 signature_derive/LICENSE-MIT create mode 100644 signature_derive/README.md create mode 100644 signature_derive/src/lib.rs diff --git a/.github/workflows/signature.yml b/.github/workflows/signature.yml index 0a5ccfd9c..00e6f0a20 100644 --- a/.github/workflows/signature.yml +++ b/.github/workflows/signature.yml @@ -37,8 +37,9 @@ jobs: toolchain: ${{ matrix.rust }} targets: ${{ matrix.target }} - run: cargo build --target ${{ matrix.target }} --release --no-default-features - - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features digest + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features derive - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features rand_core + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features derive,rand_core minimal-versions: if: false # disabled until we stop using pre-releases @@ -51,7 +52,7 @@ jobs: strategy: matrix: rust: - - 1.85.0 # MSRV + - 1.85.0 # Minimum Rust version the tests pass on - stable steps: - uses: actions/checkout@v4 @@ -62,3 +63,19 @@ jobs: - run: cargo test --release --no-default-features - run: cargo test --release - run: cargo test --release --all-features + + derive: + runs-on: ubuntu-latest + strategy: + matrix: + rust: + - 1.85.0 # MSRV + - stable + steps: + - uses: actions/checkout@v4 + - uses: RustCrypto/actions/cargo-cache@master + - uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ matrix.rust }} + - run: cargo test --release + working-directory: signature_derive diff --git a/Cargo.lock b/Cargo.lock index 6f012057c..a7bd88185 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -35,7 +35,7 @@ checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" name = "async-signature" version = "0.6.0-pre.4" dependencies = [ - "signature 2.3.0-pre.7", + "signature", ] [[package]] @@ -152,7 +152,7 @@ dependencies = [ "digest 0.11.0-pre.10", "elliptic-curve", "password-hash", - "signature 3.0.0-pre", + "signature", "universal-hash", ] @@ -583,22 +583,22 @@ dependencies = [ [[package]] name = "signature" -version = "2.3.0-pre.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6e22be6d22b655ff65ed5635383d63ac17a99c5c0a05a83a414d399056d4e1d" +version = "3.0.0-pre" dependencies = [ "digest 0.11.0-pre.10 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal", "rand_core", + "sha2", + "signature_derive", ] [[package]] -name = "signature" -version = "3.0.0-pre" +name = "signature_derive" +version = "2.2.0" dependencies = [ - "digest 0.11.0-pre.10 (registry+https://github.com/rust-lang/crates.io-index)", - "hex-literal", - "rand_core", - "sha2", + "proc-macro2", + "quote", + "syn 2.0.98", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 6d87a02f9..dda804d3c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ members = [ "elliptic-curve", "kem", "password-hash", + "signature_derive", "universal-hash", "signature", ] diff --git a/async-signature/Cargo.toml b/async-signature/Cargo.toml index 38d030667..231c36549 100644 --- a/async-signature/Cargo.toml +++ b/async-signature/Cargo.toml @@ -13,11 +13,11 @@ categories = ["cryptography", "no-std"] description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" [dependencies] -signature = "=2.3.0-pre.7" +signature = "=3.0.0-pre" [features] digest = ["signature/digest"] -std = ["signature/std"] +std = [] rand_core = ["signature/rand_core"] [package.metadata.docs.rs] diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index a2fb7a20f..591a90ee2 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -21,7 +21,7 @@ cipher = { version = "0.5.0-pre.7", path = "../cipher", optional = true } digest = { version = "0.11.0-pre.9", path = "../digest", optional = true, features = ["mac"] } elliptic-curve = { version = "0.14.0-rc.1", path = "../elliptic-curve", optional = true } password-hash = { version = "0.6.0-rc.0", path = "../password-hash", optional = true } -signature = { version = "3.0.0-pre", path = "../signature", optional = true, default-features = false } +signature = { version = "=3.0.0-pre", path = "../signature", optional = true, default-features = false } universal-hash = { version = "0.6.0-rc.0", path = "../universal-hash", optional = true } [features] diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 6e50f3822..168377c1d 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -13,6 +13,7 @@ categories = ["cryptography", "no-std"] description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" [dependencies] +derive = { package = "signature_derive", version = "2", optional = true, path = "../signature_derive" } digest = { version = "=0.11.0-pre.10", optional = true, default-features = false } rand_core = { version = "0.9", optional = true, default-features = false } diff --git a/signature/src/lib.rs b/signature/src/lib.rs index b8678e329..963031ab9 100644 --- a/signature/src/lib.rs +++ b/signature/src/lib.rs @@ -145,6 +145,12 @@ mod prehash_signature; pub use crate::{encoding::*, error::*, keypair::*, signer::*, verifier::*}; +#[cfg(feature = "derive")] +pub use derive::{Signer, Verifier}; + +#[cfg(all(feature = "derive", feature = "digest"))] +pub use derive::{DigestSigner, DigestVerifier}; + #[cfg(feature = "digest")] pub use {crate::prehash_signature::*, digest}; diff --git a/signature/src/prehash_signature.rs b/signature/src/prehash_signature.rs index 54317f05c..d9a86456d 100644 --- a/signature/src/prehash_signature.rs +++ b/signature/src/prehash_signature.rs @@ -19,8 +19,9 @@ use crate::{ /// This approach is relatively common in signature schemes based on the /// [Fiat-Shamir heuristic]. /// -/// For signature types that implement this trait, a blanket impl of the [`Signer`] trait is -/// available for any types that impl [`DigestSigner`], and likewise for the [`Verifier`] for +/// For signature types that implement this trait, when the `derive` crate +/// feature is enabled a custom derive for [`Signer`] is available for any +/// types that impl [`DigestSigner`], and likewise for deriving [`Verifier`] for /// types which impl [`DigestVerifier`]. /// /// [Fiat-Shamir heuristic]: https://en.wikipedia.org/wiki/Fiat%E2%80%93Shamir_heuristic diff --git a/signature/src/signer.rs b/signature/src/signer.rs index 662a379ff..02ffe0f9c 100644 --- a/signature/src/signer.rs +++ b/signature/src/signer.rs @@ -3,7 +3,7 @@ use crate::error::Error; #[cfg(feature = "digest")] -use crate::{PrehashSignature, digest::Digest}; +use crate::digest::Digest; #[cfg(feature = "rand_core")] use crate::rand_core::{CryptoRng, TryCryptoRng}; @@ -82,17 +82,6 @@ pub trait DigestSigner { fn try_sign_digest(&self, digest: D) -> Result; } -#[cfg(feature = "digest")] -impl Signer for T -where - S: PrehashSignature, - T: DigestSigner, -{ - fn try_sign(&self, msg: &[u8]) -> Result { - self.try_sign_digest(S::Digest::new_with_prefix(msg)) - } -} - /// Sign the given message using the provided external randomness source. #[cfg(feature = "rand_core")] pub trait RandomizedSigner { @@ -135,21 +124,6 @@ pub trait RandomizedDigestSigner { ) -> Result; } -#[cfg(all(feature = "digest", feature = "rand_core"))] -impl RandomizedSigner for T -where - S: PrehashSignature, - T: RandomizedDigestSigner, -{ - fn try_sign_with_rng( - &self, - rng: &mut R, - msg: &[u8], - ) -> Result { - self.try_sign_digest_with_rng(rng, S::Digest::new_with_prefix(msg)) - } -} - /// Sign the provided message bytestring using `&mut Self` (e.g. an evolving /// cryptographic key such as a stateful hash-based signature), and a per-signature /// randomizer, returning a digital signature. diff --git a/signature/src/verifier.rs b/signature/src/verifier.rs index 6fcfe3e52..65409a929 100644 --- a/signature/src/verifier.rs +++ b/signature/src/verifier.rs @@ -3,7 +3,7 @@ use crate::error::Error; #[cfg(feature = "digest")] -use crate::{PrehashSignature, digest::Digest}; +use crate::digest::Digest; /// Verify the provided message bytestring using `Self` (e.g. a public key) pub trait Verifier { @@ -39,14 +39,3 @@ pub trait DigestVerifier { /// Verify the signature against the given [`Digest`] output. fn verify_digest(&self, digest: D, signature: &S) -> Result<(), Error>; } - -#[cfg(feature = "digest")] -impl Verifier for T -where - S: PrehashSignature, - T: DigestVerifier, -{ - fn verify(&self, msg: &[u8], signature: &S) -> Result<(), Error> { - self.verify_digest(S::Digest::new_with_prefix(msg), signature) - } -} diff --git a/signature/tests/derive.rs b/signature/tests/derive.rs new file mode 100644 index 000000000..989890271 --- /dev/null +++ b/signature/tests/derive.rs @@ -0,0 +1,85 @@ +//! Tests for code generated by `signature_derive` + +#![cfg(all(feature = "derive", feature = "digest"))] + +use digest::{Digest, OutputSizeUser, array::Array}; +use hex_literal::hex; +use sha2::Sha256; +use signature::{ + DigestSigner, DigestVerifier, Error, PrehashSignature, SignatureEncoding, Signer, Verifier, + hazmat::{PrehashSigner, PrehashVerifier}, +}; + +/// Test vector to compute SHA-256 digest of +const INPUT_STRING: &[u8] = b"abc"; + +/// Expected SHA-256 digest for the input string +const INPUT_STRING_DIGEST: [u8; 32] = + hex!("ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad"); + +type Repr = Array::OutputSize>; + +/// Dummy signature which just contains a digest output +#[derive(Clone, Debug)] +struct DummySignature(Repr); + +impl PrehashSignature for DummySignature { + type Digest = Sha256; +} + +impl SignatureEncoding for DummySignature { + type Repr = Repr; +} + +impl TryFrom<&[u8]> for DummySignature { + type Error = Error; + + fn try_from(bytes: &[u8]) -> Result { + bytes + .try_into() + .map(DummySignature) + .map_err(|_| Error::new()) + } +} + +impl From for Repr { + fn from(sig: DummySignature) -> Repr { + sig.0 + } +} + +/// Dummy signer which just returns the message digest as a `DummySignature` +#[derive(Signer, DigestSigner, Default)] +struct DummySigner {} + +impl PrehashSigner for DummySigner { + fn sign_prehash(&self, prehash: &[u8]) -> signature::Result { + DummySignature::try_from(prehash) + } +} + +/// Dummy verifier which ensures the `DummySignature` digest matches the +/// expected value. +/// +/// Panics (via `assert_eq!`) if the value is not what is expected. +#[derive(Verifier, DigestVerifier, Default)] +struct DummyVerifier {} + +impl PrehashVerifier for DummyVerifier { + fn verify_prehash(&self, prehash: &[u8], signature: &DummySignature) -> signature::Result<()> { + assert_eq!(signature.to_bytes().as_slice(), prehash); + Ok(()) + } +} + +#[test] +fn derived_signer_impl() { + let sig: DummySignature = DummySigner::default().sign(INPUT_STRING); + assert_eq!(sig.to_bytes().as_slice(), INPUT_STRING_DIGEST) +} + +#[test] +fn derived_verifier_impl() { + let sig: DummySignature = DummySigner::default().sign(INPUT_STRING); + assert!(DummyVerifier::default().verify(INPUT_STRING, &sig).is_ok()); +} diff --git a/signature_derive/CHANGELOG.md b/signature_derive/CHANGELOG.md new file mode 100644 index 000000000..e88b15da1 --- /dev/null +++ b/signature_derive/CHANGELOG.md @@ -0,0 +1,76 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## 2.2.0 (UNRELEASED) +### Changed +- Edition changed to 2024 and MSRV bumped to 1.85 ([#1759]) + +[#1759]: https://github.com/RustCrypto/traits/pull/1759 + +## 2.1.0 (2023-11-12) +### Changed +- MSRV 1.60 ([#1387]) + +[#1387]: https://github.com/RustCrypto/traits/pull/1387 + +## 2.0.1 (2023-04-17) +### Changed +- Bump `syn` to v2 ([#1299]) + +[#1299]: https://github.com/RustCrypto/traits/pull/1299 + +## 2.0.0 (2023-01-15) +### Changed +- `Signature` trait has been removed, so don't emit it in custom derive ([#1141]) + +[#1141]: https://github.com/RustCrypto/traits/pull/1141 + +## 1.0.0-pre.7 (2022-09-16) +### Fixed +- Support for `where` bounds ([#1118]) + +[#1118]: https://github.com/RustCrypto/traits/pull/1118 + +## 1.0.0-pre.6 (2022-09-12) +### Added +- `DigestSigner`/`DigestVerifier` support ([#1103]) + +### Removed +- `synstructure` dependency ([#1100]) + +[#1100]: https://github.com/RustCrypto/traits/pull/1100 +[#1103]: https://github.com/RustCrypto/traits/pull/1103 + +## 1.0.0-pre.5 (2022-08-14) +### Changed +- Rust 2021 edition upgrade; MSRV 1.56 ([#1081]) + +[#1081]: https://github.com/RustCrypto/traits/pull/1081 + +## 1.0.0-pre.4 (2022-01-04) +### Changed +- Support for new `digest` v0.10 API ([#850]) + +[#850]: https://github.com/RustCrypto/traits/pull/850 + +## 1.0.0-pre.3 (2021-01-06) +### Fixed +- rustdoc links ([#458]) + +[#458]: https://github.com/RustCrypto/traits/pull/458 + +## 1.0.0-pre.2 (2020-04-19) +### Changed +- Rename `DigestSignature` => `PrehashSignature` ([#96]) + +[#96]: https://github.com/RustCrypto/traits/pull/96 + +## 1.0.0-pre.1 (2020-03-08) +### Added +- Initial changelog for `signature_derive` +- rustdoc ([#79]) + +[#79]: https://github.com/RustCrypto/traits/pull/79 diff --git a/signature_derive/Cargo.toml b/signature_derive/Cargo.toml new file mode 100644 index 000000000..205bfdff6 --- /dev/null +++ b/signature_derive/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "signature_derive" +version = "2.2.0" +authors = ["RustCrypto Developers"] +edition = "2024" +rust-version = "1.85" +documentation = "https://docs.rs/signature" +readme = "README.md" +repository = "https://github.com/RustCrypto/traits" +license = "Apache-2.0 OR MIT" +keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"] +categories = ["cryptography", "no-std"] +description = "Custom derive support for the 'signature' crate" + +[lib] +proc-macro = true + +[dependencies] +proc-macro2 = "1" +quote = "1" +syn = "2" diff --git a/signature_derive/LICENSE-APACHE b/signature_derive/LICENSE-APACHE new file mode 100644 index 000000000..78173fa2e --- /dev/null +++ b/signature_derive/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/signature_derive/LICENSE-MIT b/signature_derive/LICENSE-MIT new file mode 100644 index 000000000..bb7ff7c2c --- /dev/null +++ b/signature_derive/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2019-2025 RustCrypto Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/signature_derive/README.md b/signature_derive/README.md new file mode 100644 index 000000000..74cd7871b --- /dev/null +++ b/signature_derive/README.md @@ -0,0 +1,41 @@ +# `signature` crate custom derive support + +[![crate][crate-image]][crate-link] +[![Docs][docs-image]][docs-link] +[![Build Status][build-image]][build-link] +![Apache2/MIT licensed][license-image] +![Rust Version][rustc-image] +[![Project Chat][chat-image]][chat-link] + +This crate provides proc macros used by the `signature` crate. + +Not intended to be used directly. See the `signature` crate's documentation +for additional details: + +## License + +All crates licensed under either of + + * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) + * [MIT license](http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall be +dual licensed as above, without any additional terms or conditions. + +[//]: # (badges) + +[crate-image]: https://img.shields.io/crates/v/signature_derive +[crate-link]: https://crates.io/crates/signature_derive +[docs-image]: https://docs.rs/signature_derive/badge.svg +[docs-link]: https://docs.rs/signature_derive/ +[build-image]: https://github.com/RustCrypto/traits/actions/workflows/signature_derive.yml/badge.svg?branch=master +[build-link]: https://github.com/RustCrypto/traits/actions/workflows/signature_derive.yml?query=branch:master +[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg +[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg +[chat-link]: https://rustcrypto.zulipchat.com/#narrow/channel/260048-signatures diff --git a/signature_derive/src/lib.rs b/signature_derive/src/lib.rs new file mode 100644 index 000000000..bf6a94c5d --- /dev/null +++ b/signature_derive/src/lib.rs @@ -0,0 +1,392 @@ +#![crate_type = "proc-macro"] +#![doc = include_str!("../README.md")] +#![forbid(unsafe_code)] +#![warn( + clippy::unwrap_used, + rust_2018_idioms, + trivial_casts, + unused_import_braces, + missing_debug_implementations, + unused_qualifications +)] + +use proc_macro::TokenStream; +use proc_macro2::{Span, TokenStream as TokenStream2}; +use quote::quote; +use syn::{ + DeriveInput, Ident, PredicateType, Token, TraitBound, Type, TypeParam, TypeParamBound, + WhereClause, WherePredicate, parse_macro_input, parse_quote, punctuated::Punctuated, +}; + +/// Derive the [`Signer`] trait for a type which impls [`DigestSigner`]. +/// +/// When implementing the [`DigestSigner`] trait for a signature type which +/// itself impl's the [`PrehashSignature`] trait (which marks signature +/// algorithms which are computed using a [`Digest`]), signature providers +/// can automatically derive the [`Signer`] trait when the digest algorithm +/// is [`PrehashSignature::Digest`] (i.e. the "standard" digest algorithm +/// for a given signature type) +/// +/// This automates all of the digest computation otherwise needed for a +/// complete signature algorithm implementation. +/// +/// [`Digest`]: https://docs.rs/digest/latest/digest/trait.Digest.html +/// [`DigestSigner`]: https://docs.rs/signature/latest/signature/trait.DigestSigner.html +/// [`PrehashSignature`]: https://docs.rs/signature/latest/signature/trait.PrehashSignature.html +/// [`PrehashSignature::Digest`]: https://docs.rs/signature/latest/signature/trait.PrehashSignature.html#associated-types +#[proc_macro_derive(Signer)] +pub fn derive_signer(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as DeriveInput); + emit_signer_impl(input).into() +} + +fn emit_signer_impl(input: DeriveInput) -> TokenStream2 { + let s_ident = Ident::new("__S", Span::call_site()); + + let mut params = DeriveParams::new(input); + params.add_bound(&s_ident, parse_quote!(::signature::PrehashSignature)); + params.add_bound( + &Ident::new("Self", Span::call_site()), + parse_quote!(::signature::DigestSigner<#s_ident::Digest, #s_ident>), + ); + + let name = params.name; + let impl_generics = params.impl_generics; + let ty_generics = params.ty_generics; + let where_clause = params.where_clause; + + quote! { + impl<#(#impl_generics),*> ::signature::Signer<#s_ident> for #name<#(#ty_generics),*> + #where_clause + { + fn try_sign(&self, msg: &[u8]) -> ::signature::Result<#s_ident> { + self.try_sign_digest(#s_ident::Digest::new_with_prefix(msg)) + } + } + } +} + +/// Derive the [`Verifier`] trait for a type which impls [`DigestVerifier`]. +/// +/// When implementing the [`DigestVerifier`] trait for a signature type which +/// itself impl's the [`PrehashSignature`] trait (which marks signature +/// algorithms which are computed using a [`Digest`]), signature providers +/// can automatically derive the [`Verifier`] trait when the digest algorithm +/// is [`PrehashSignature::Digest`] (i.e. the "standard" digest algorithm +/// for a given signature type) +/// +/// This automates all of the digest computation otherwise needed for a +/// complete signature algorithm implementation. +/// +/// [`Digest`]: https://docs.rs/digest/latest/digest/trait.Digest.html +/// [`DigestVerifier`]: https://docs.rs/signature/latest/signature/trait.DigestVerifier.html +/// [`PrehashSignature`]: https://docs.rs/signature/latest/signature/trait.PrehashSignature.html +/// [`PrehashSignature::Digest`]: https://docs.rs/signature/latest/signature/trait.PrehashSignature.html#associated-types +#[proc_macro_derive(Verifier)] +pub fn derive_verifier(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as DeriveInput); + emit_verifier_impl(input).into() +} + +fn emit_verifier_impl(input: DeriveInput) -> TokenStream2 { + let s_ident = Ident::new("__S", Span::call_site()); + + let mut params = DeriveParams::new(input); + params.add_bound(&s_ident, parse_quote!(::signature::PrehashSignature)); + params.add_bound( + &Ident::new("Self", Span::call_site()), + parse_quote!(::signature::DigestVerifier<#s_ident::Digest, #s_ident>), + ); + + let name = params.name; + let impl_generics = params.impl_generics; + let ty_generics = params.ty_generics; + let where_clause = params.where_clause; + + quote! { + impl<#(#impl_generics),*> ::signature::Verifier<#s_ident> for #name<#(#ty_generics),*> + #where_clause + { + fn verify(&self, msg: &[u8], signature: &#s_ident) -> ::signature::Result<()> { + self.verify_digest(#s_ident::Digest::new_with_prefix(msg), signature) + } + } + } +} + +/// Derive the [`DigestSigner`] trait for a type which impls [`PrehashSigner`]. +/// +/// [`DigestSigner`]: https://docs.rs/signature/latest/signature/trait.DigestSigner.html +/// [`PrehashSigner`]: https://docs.rs/signature/latest/signature/hazmat/trait.PrehashSigner.html +#[proc_macro_derive(DigestSigner)] +pub fn derive_digest_signer(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as DeriveInput); + emit_digest_signer_impl(input).into() +} + +fn emit_digest_signer_impl(input: DeriveInput) -> TokenStream2 { + let d_ident = Ident::new("__D", Span::call_site()); + let s_ident = Ident::new("__S", Span::call_site()); + + let mut params = DeriveParams::new(input); + params.add_bound(&d_ident, parse_quote!(::signature::digest::Digest)); + params.add_param(&s_ident); + params.add_bound( + &Ident::new("Self", Span::call_site()), + parse_quote!(::signature::hazmat::PrehashSigner<#s_ident>), + ); + + let name = params.name; + let impl_generics = params.impl_generics; + let ty_generics = params.ty_generics; + let where_clause = params.where_clause; + + quote! { + impl<#(#impl_generics),*> ::signature::DigestSigner<#d_ident, #s_ident> for #name<#(#ty_generics),*> + #where_clause + { + fn try_sign_digest(&self, digest: #d_ident) -> ::signature::Result<#s_ident> { + self.sign_prehash(&digest.finalize()) + } + } + } +} + +/// Derive the [`DigestVerifier`] trait for a type which impls [`PrehashVerifier`]. +/// +/// [`DigestVerifier`]: https://docs.rs/signature/latest/signature/trait.DigestVerifier.html +/// [`PrehashVerifier`]: https://docs.rs/signature/latest/signature/hazmat/trait.PrehashVerifier.html +#[proc_macro_derive(DigestVerifier)] +pub fn derive_digest_verifier(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as DeriveInput); + emit_digest_verifier_impl(input).into() +} + +fn emit_digest_verifier_impl(input: DeriveInput) -> TokenStream2 { + let d_ident = Ident::new("__D", Span::call_site()); + let s_ident = Ident::new("__S", Span::call_site()); + + let mut params = DeriveParams::new(input); + params.add_bound(&d_ident, parse_quote!(::signature::digest::Digest)); + params.add_param(&s_ident); + params.add_bound( + &Ident::new("Self", Span::call_site()), + parse_quote!(::signature::hazmat::PrehashVerifier<#s_ident>), + ); + + let name = params.name; + let impl_generics = params.impl_generics; + let ty_generics = params.ty_generics; + let where_clause = params.where_clause; + + quote! { + impl<#(#impl_generics),*> ::signature::DigestVerifier<#d_ident, #s_ident> for #name<#(#ty_generics),*> + #where_clause + { + fn verify_digest(&self, digest: #d_ident, signature: &#s_ident) -> ::signature::Result<()> { + self.verify_prehash(&digest.finalize(), signature) + } + } + } +} + +/// Derivation parameters parsed from `DeriveInput`. +struct DeriveParams { + /// Name of the struct the trait impls are being added to. + name: Ident, + + /// Generic parameters of `impl`. + impl_generics: Vec, + + /// Generic parameters of the type. + ty_generics: Vec, + + /// Where clause in-progress. + where_clause: WhereClause, +} + +impl DeriveParams { + /// Parse parameters from `DeriveInput`. + fn new(input: DeriveInput) -> Self { + let impl_generics = input.generics.type_params().cloned().collect(); + + let ty_generics = input + .generics + .type_params() + .map(|bound| bound.ident.clone()) + .collect(); + + let where_clause = input + .generics + .where_clause + .clone() + .unwrap_or_else(|| WhereClause { + where_token: ::default(), + predicates: Punctuated::new(), + }); + + Self { + name: input.ident, + impl_generics, + ty_generics, + where_clause, + } + } + + /// Add a generic parameter with the given bound. + fn add_bound(&mut self, name: &Ident, bound: TraitBound) { + if name != "Self" { + self.add_param(name); + } + + let type_path = parse_quote!(#name); + + let mut bounds = Punctuated::new(); + bounds.push(TypeParamBound::Trait(bound)); + + let predicate_type = PredicateType { + lifetimes: None, + bounded_ty: Type::Path(type_path), + colon_token: ::default(), + bounds, + }; + + self.where_clause + .predicates + .push(WherePredicate::Type(predicate_type)) + } + + /// Add a generic parameter without a bound. + fn add_param(&mut self, name: &Ident) { + self.impl_generics.push(TypeParam { + attrs: vec![], + ident: name.clone(), + colon_token: None, + bounds: Default::default(), + eq_token: None, + default: None, + }); + } +} + +#[cfg(test)] +mod tests { + use super::*; + use syn::parse_quote; + + #[test] + fn signer() { + let input = parse_quote! { + #[derive(Signer)] + struct MySigner + where + C: EllipticCurve + { + scalar: Scalar + } + }; + + let output = emit_signer_impl(input); + + assert_eq!( + output.to_string(), + quote! { + impl ::signature::Signer<__S> for MySigner + where + C: EllipticCurve, + __S: ::signature::PrehashSignature, + Self: ::signature::DigestSigner<__S::Digest, __S> + { + fn try_sign(&self, msg: &[u8]) -> ::signature::Result<__S> { + self.try_sign_digest(__S::Digest::new_with_prefix(msg)) + } + } + } + .to_string() + ); + } + + #[test] + fn verifier() { + let input = parse_quote! { + #[derive(Verifier)] + struct MyVerifier { + point: UncompressedPoint + } + }; + + let output = emit_verifier_impl(input); + + assert_eq!( + output.to_string(), + quote! { + impl ::signature::Verifier<__S> for MyVerifier + where + __S: ::signature::PrehashSignature, + Self: ::signature::DigestVerifier<__S::Digest, __S> + { + fn verify(&self, msg: &[u8], signature: &__S) -> ::signature::Result<()> { + self.verify_digest(__S::Digest::new_with_prefix(msg), signature) + } + } + } + .to_string() + ); + } + + #[test] + fn digest_signer() { + let input = parse_quote! { + #[derive(DigestSigner)] + struct MySigner { + scalar: Scalar + } + }; + + let output = emit_digest_signer_impl(input); + + assert_eq!( + output.to_string(), + quote! { + impl ::signature::DigestSigner<__D, __S> for MySigner + where + __D: ::signature::digest::Digest, + Self: ::signature::hazmat::PrehashSigner<__S> + { + fn try_sign_digest(&self, digest: __D) -> ::signature::Result<__S> { + self.sign_prehash(&digest.finalize()) + } + } + } + .to_string() + ); + } + + #[test] + fn digest_verifier() { + let input = parse_quote! { + #[derive(DigestVerifier)] + struct MyVerifier { + point: UncompressedPoint + } + }; + + let output = emit_digest_verifier_impl(input); + + assert_eq!( + output.to_string(), + quote! { + impl ::signature::DigestVerifier<__D, __S> for MyVerifier + where + __D: ::signature::digest::Digest, + Self: ::signature::hazmat::PrehashVerifier<__S> + { + fn verify_digest(&self, digest: __D, signature: &__S) -> ::signature::Result<()> { + self.verify_prehash(&digest.finalize(), signature) + } + } + } + .to_string() + ); + } +} From 4dc547a43ecf3d5243630651bbab9fc3807f6e85 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 May 2025 04:11:37 +0300 Subject: [PATCH 1343/1461] build(deps): bump crate-ci/typos from 1.31.2 to 1.32.0 (#1842) --- .github/workflows/workspace.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index 3bf0f9b3d..622804dee 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -52,4 +52,4 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: crate-ci/typos@v1.31.2 + - uses: crate-ci/typos@v1.32.0 From d993dea32c465c01be31da0b729a3f0aa38993ab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 May 2025 04:12:04 +0300 Subject: [PATCH 1344/1461] Update Cargo.lock (#1841) --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a7bd88185..a3452ce62 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -347,9 +347,9 @@ dependencies = [ [[package]] name = "hybrid-array" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dab50e193aebe510fe0e40230145820e02f48dae0cf339ea4204e6e708ff7bd" +checksum = "891d15931895091dea5c47afa5b3c9a01ba634b311919fd4d41388fa0e3d76af" dependencies = [ "typenum", "zeroize", From 439fc8c28c61b09eff35349b4c091a5586d70ea7 Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Tue, 6 May 2025 18:41:37 +0000 Subject: [PATCH 1345/1461] signature: remove `derive` feature (#1843) `signature_derive` was used to provide a `Signer` implementation from a `DigestSigner` and `PrehashSignature` but it does not appears to be used in any place I can see. If this becomes to actually be used, we'll then provide a macro-based implementation for it but I'll hold on to that until we find a consumer. --- .github/workflows/signature.yml | 19 -- Cargo.toml | 1 - signature/CHANGELOG.md | 3 +- signature/Cargo.toml | 1 - signature/src/lib.rs | 6 - signature/src/prehash_signature.rs | 5 - signature/tests/derive.rs | 85 ------- signature_derive/CHANGELOG.md | 76 ------ signature_derive/Cargo.toml | 21 -- signature_derive/LICENSE-APACHE | 201 --------------- signature_derive/LICENSE-MIT | 25 -- signature_derive/README.md | 41 --- signature_derive/src/lib.rs | 392 ----------------------------- 13 files changed, 1 insertion(+), 875 deletions(-) delete mode 100644 signature/tests/derive.rs delete mode 100644 signature_derive/CHANGELOG.md delete mode 100644 signature_derive/Cargo.toml delete mode 100644 signature_derive/LICENSE-APACHE delete mode 100644 signature_derive/LICENSE-MIT delete mode 100644 signature_derive/README.md delete mode 100644 signature_derive/src/lib.rs diff --git a/.github/workflows/signature.yml b/.github/workflows/signature.yml index 00e6f0a20..1105f50b1 100644 --- a/.github/workflows/signature.yml +++ b/.github/workflows/signature.yml @@ -4,7 +4,6 @@ on: pull_request: paths: - "signature/**" - - "signature-derive/**" - "Cargo.*" push: branches: master @@ -37,9 +36,7 @@ jobs: toolchain: ${{ matrix.rust }} targets: ${{ matrix.target }} - run: cargo build --target ${{ matrix.target }} --release --no-default-features - - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features derive - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features rand_core - - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features derive,rand_core minimal-versions: if: false # disabled until we stop using pre-releases @@ -63,19 +60,3 @@ jobs: - run: cargo test --release --no-default-features - run: cargo test --release - run: cargo test --release --all-features - - derive: - runs-on: ubuntu-latest - strategy: - matrix: - rust: - - 1.85.0 # MSRV - - stable - steps: - - uses: actions/checkout@v4 - - uses: RustCrypto/actions/cargo-cache@master - - uses: dtolnay/rust-toolchain@master - with: - toolchain: ${{ matrix.rust }} - - run: cargo test --release - working-directory: signature_derive diff --git a/Cargo.toml b/Cargo.toml index dda804d3c..6d87a02f9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,6 @@ members = [ "elliptic-curve", "kem", "password-hash", - "signature_derive", "universal-hash", "signature", ] diff --git a/signature/CHANGELOG.md b/signature/CHANGELOG.md index d18641cf9..1f0304fbf 100644 --- a/signature/CHANGELOG.md +++ b/signature/CHANGELOG.md @@ -9,15 +9,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `RandomizedSignerMut` trait ([#1448]) ### Changed -- Replace `signature_derive` with blanket impls ([#1827]) - Edition changed to 2024 and MSRV bumped to 1.85 ([#1759]) ### Removed - `std` feature - replaced with `core::error::Error` +- `derive` feature [#1448]: https://github.com/RustCrypto/traits/pull/1448 [#1759]: https://github.com/RustCrypto/traits/pull/1759 -[#1827]: https://github.com/RustCrypto/traits/pull/1827 ## 2.2.0 (2023-11-12) ### Changed diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 168377c1d..6e50f3822 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -13,7 +13,6 @@ categories = ["cryptography", "no-std"] description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" [dependencies] -derive = { package = "signature_derive", version = "2", optional = true, path = "../signature_derive" } digest = { version = "=0.11.0-pre.10", optional = true, default-features = false } rand_core = { version = "0.9", optional = true, default-features = false } diff --git a/signature/src/lib.rs b/signature/src/lib.rs index 963031ab9..b8678e329 100644 --- a/signature/src/lib.rs +++ b/signature/src/lib.rs @@ -145,12 +145,6 @@ mod prehash_signature; pub use crate::{encoding::*, error::*, keypair::*, signer::*, verifier::*}; -#[cfg(feature = "derive")] -pub use derive::{Signer, Verifier}; - -#[cfg(all(feature = "derive", feature = "digest"))] -pub use derive::{DigestSigner, DigestVerifier}; - #[cfg(feature = "digest")] pub use {crate::prehash_signature::*, digest}; diff --git a/signature/src/prehash_signature.rs b/signature/src/prehash_signature.rs index d9a86456d..773dc6ff9 100644 --- a/signature/src/prehash_signature.rs +++ b/signature/src/prehash_signature.rs @@ -19,11 +19,6 @@ use crate::{ /// This approach is relatively common in signature schemes based on the /// [Fiat-Shamir heuristic]. /// -/// For signature types that implement this trait, when the `derive` crate -/// feature is enabled a custom derive for [`Signer`] is available for any -/// types that impl [`DigestSigner`], and likewise for deriving [`Verifier`] for -/// types which impl [`DigestVerifier`]. -/// /// [Fiat-Shamir heuristic]: https://en.wikipedia.org/wiki/Fiat%E2%80%93Shamir_heuristic pub trait PrehashSignature { /// Preferred `Digest` algorithm to use when computing this signature type. diff --git a/signature/tests/derive.rs b/signature/tests/derive.rs deleted file mode 100644 index 989890271..000000000 --- a/signature/tests/derive.rs +++ /dev/null @@ -1,85 +0,0 @@ -//! Tests for code generated by `signature_derive` - -#![cfg(all(feature = "derive", feature = "digest"))] - -use digest::{Digest, OutputSizeUser, array::Array}; -use hex_literal::hex; -use sha2::Sha256; -use signature::{ - DigestSigner, DigestVerifier, Error, PrehashSignature, SignatureEncoding, Signer, Verifier, - hazmat::{PrehashSigner, PrehashVerifier}, -}; - -/// Test vector to compute SHA-256 digest of -const INPUT_STRING: &[u8] = b"abc"; - -/// Expected SHA-256 digest for the input string -const INPUT_STRING_DIGEST: [u8; 32] = - hex!("ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad"); - -type Repr = Array::OutputSize>; - -/// Dummy signature which just contains a digest output -#[derive(Clone, Debug)] -struct DummySignature(Repr); - -impl PrehashSignature for DummySignature { - type Digest = Sha256; -} - -impl SignatureEncoding for DummySignature { - type Repr = Repr; -} - -impl TryFrom<&[u8]> for DummySignature { - type Error = Error; - - fn try_from(bytes: &[u8]) -> Result { - bytes - .try_into() - .map(DummySignature) - .map_err(|_| Error::new()) - } -} - -impl From for Repr { - fn from(sig: DummySignature) -> Repr { - sig.0 - } -} - -/// Dummy signer which just returns the message digest as a `DummySignature` -#[derive(Signer, DigestSigner, Default)] -struct DummySigner {} - -impl PrehashSigner for DummySigner { - fn sign_prehash(&self, prehash: &[u8]) -> signature::Result { - DummySignature::try_from(prehash) - } -} - -/// Dummy verifier which ensures the `DummySignature` digest matches the -/// expected value. -/// -/// Panics (via `assert_eq!`) if the value is not what is expected. -#[derive(Verifier, DigestVerifier, Default)] -struct DummyVerifier {} - -impl PrehashVerifier for DummyVerifier { - fn verify_prehash(&self, prehash: &[u8], signature: &DummySignature) -> signature::Result<()> { - assert_eq!(signature.to_bytes().as_slice(), prehash); - Ok(()) - } -} - -#[test] -fn derived_signer_impl() { - let sig: DummySignature = DummySigner::default().sign(INPUT_STRING); - assert_eq!(sig.to_bytes().as_slice(), INPUT_STRING_DIGEST) -} - -#[test] -fn derived_verifier_impl() { - let sig: DummySignature = DummySigner::default().sign(INPUT_STRING); - assert!(DummyVerifier::default().verify(INPUT_STRING, &sig).is_ok()); -} diff --git a/signature_derive/CHANGELOG.md b/signature_derive/CHANGELOG.md deleted file mode 100644 index e88b15da1..000000000 --- a/signature_derive/CHANGELOG.md +++ /dev/null @@ -1,76 +0,0 @@ -# Changelog -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## 2.2.0 (UNRELEASED) -### Changed -- Edition changed to 2024 and MSRV bumped to 1.85 ([#1759]) - -[#1759]: https://github.com/RustCrypto/traits/pull/1759 - -## 2.1.0 (2023-11-12) -### Changed -- MSRV 1.60 ([#1387]) - -[#1387]: https://github.com/RustCrypto/traits/pull/1387 - -## 2.0.1 (2023-04-17) -### Changed -- Bump `syn` to v2 ([#1299]) - -[#1299]: https://github.com/RustCrypto/traits/pull/1299 - -## 2.0.0 (2023-01-15) -### Changed -- `Signature` trait has been removed, so don't emit it in custom derive ([#1141]) - -[#1141]: https://github.com/RustCrypto/traits/pull/1141 - -## 1.0.0-pre.7 (2022-09-16) -### Fixed -- Support for `where` bounds ([#1118]) - -[#1118]: https://github.com/RustCrypto/traits/pull/1118 - -## 1.0.0-pre.6 (2022-09-12) -### Added -- `DigestSigner`/`DigestVerifier` support ([#1103]) - -### Removed -- `synstructure` dependency ([#1100]) - -[#1100]: https://github.com/RustCrypto/traits/pull/1100 -[#1103]: https://github.com/RustCrypto/traits/pull/1103 - -## 1.0.0-pre.5 (2022-08-14) -### Changed -- Rust 2021 edition upgrade; MSRV 1.56 ([#1081]) - -[#1081]: https://github.com/RustCrypto/traits/pull/1081 - -## 1.0.0-pre.4 (2022-01-04) -### Changed -- Support for new `digest` v0.10 API ([#850]) - -[#850]: https://github.com/RustCrypto/traits/pull/850 - -## 1.0.0-pre.3 (2021-01-06) -### Fixed -- rustdoc links ([#458]) - -[#458]: https://github.com/RustCrypto/traits/pull/458 - -## 1.0.0-pre.2 (2020-04-19) -### Changed -- Rename `DigestSignature` => `PrehashSignature` ([#96]) - -[#96]: https://github.com/RustCrypto/traits/pull/96 - -## 1.0.0-pre.1 (2020-03-08) -### Added -- Initial changelog for `signature_derive` -- rustdoc ([#79]) - -[#79]: https://github.com/RustCrypto/traits/pull/79 diff --git a/signature_derive/Cargo.toml b/signature_derive/Cargo.toml deleted file mode 100644 index 205bfdff6..000000000 --- a/signature_derive/Cargo.toml +++ /dev/null @@ -1,21 +0,0 @@ -[package] -name = "signature_derive" -version = "2.2.0" -authors = ["RustCrypto Developers"] -edition = "2024" -rust-version = "1.85" -documentation = "https://docs.rs/signature" -readme = "README.md" -repository = "https://github.com/RustCrypto/traits" -license = "Apache-2.0 OR MIT" -keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"] -categories = ["cryptography", "no-std"] -description = "Custom derive support for the 'signature' crate" - -[lib] -proc-macro = true - -[dependencies] -proc-macro2 = "1" -quote = "1" -syn = "2" diff --git a/signature_derive/LICENSE-APACHE b/signature_derive/LICENSE-APACHE deleted file mode 100644 index 78173fa2e..000000000 --- a/signature_derive/LICENSE-APACHE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - -Copyright [yyyy] [name of copyright owner] - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/signature_derive/LICENSE-MIT b/signature_derive/LICENSE-MIT deleted file mode 100644 index bb7ff7c2c..000000000 --- a/signature_derive/LICENSE-MIT +++ /dev/null @@ -1,25 +0,0 @@ -Copyright (c) 2019-2025 RustCrypto Developers - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without -limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/signature_derive/README.md b/signature_derive/README.md deleted file mode 100644 index 74cd7871b..000000000 --- a/signature_derive/README.md +++ /dev/null @@ -1,41 +0,0 @@ -# `signature` crate custom derive support - -[![crate][crate-image]][crate-link] -[![Docs][docs-image]][docs-link] -[![Build Status][build-image]][build-link] -![Apache2/MIT licensed][license-image] -![Rust Version][rustc-image] -[![Project Chat][chat-image]][chat-link] - -This crate provides proc macros used by the `signature` crate. - -Not intended to be used directly. See the `signature` crate's documentation -for additional details: - -## License - -All crates licensed under either of - - * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) - * [MIT license](http://opensource.org/licenses/MIT) - -at your option. - -### Contribution - -Unless you explicitly state otherwise, any contribution intentionally submitted -for inclusion in the work by you, as defined in the Apache-2.0 license, shall be -dual licensed as above, without any additional terms or conditions. - -[//]: # (badges) - -[crate-image]: https://img.shields.io/crates/v/signature_derive -[crate-link]: https://crates.io/crates/signature_derive -[docs-image]: https://docs.rs/signature_derive/badge.svg -[docs-link]: https://docs.rs/signature_derive/ -[build-image]: https://github.com/RustCrypto/traits/actions/workflows/signature_derive.yml/badge.svg?branch=master -[build-link]: https://github.com/RustCrypto/traits/actions/workflows/signature_derive.yml?query=branch:master -[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg -[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg -[chat-link]: https://rustcrypto.zulipchat.com/#narrow/channel/260048-signatures diff --git a/signature_derive/src/lib.rs b/signature_derive/src/lib.rs deleted file mode 100644 index bf6a94c5d..000000000 --- a/signature_derive/src/lib.rs +++ /dev/null @@ -1,392 +0,0 @@ -#![crate_type = "proc-macro"] -#![doc = include_str!("../README.md")] -#![forbid(unsafe_code)] -#![warn( - clippy::unwrap_used, - rust_2018_idioms, - trivial_casts, - unused_import_braces, - missing_debug_implementations, - unused_qualifications -)] - -use proc_macro::TokenStream; -use proc_macro2::{Span, TokenStream as TokenStream2}; -use quote::quote; -use syn::{ - DeriveInput, Ident, PredicateType, Token, TraitBound, Type, TypeParam, TypeParamBound, - WhereClause, WherePredicate, parse_macro_input, parse_quote, punctuated::Punctuated, -}; - -/// Derive the [`Signer`] trait for a type which impls [`DigestSigner`]. -/// -/// When implementing the [`DigestSigner`] trait for a signature type which -/// itself impl's the [`PrehashSignature`] trait (which marks signature -/// algorithms which are computed using a [`Digest`]), signature providers -/// can automatically derive the [`Signer`] trait when the digest algorithm -/// is [`PrehashSignature::Digest`] (i.e. the "standard" digest algorithm -/// for a given signature type) -/// -/// This automates all of the digest computation otherwise needed for a -/// complete signature algorithm implementation. -/// -/// [`Digest`]: https://docs.rs/digest/latest/digest/trait.Digest.html -/// [`DigestSigner`]: https://docs.rs/signature/latest/signature/trait.DigestSigner.html -/// [`PrehashSignature`]: https://docs.rs/signature/latest/signature/trait.PrehashSignature.html -/// [`PrehashSignature::Digest`]: https://docs.rs/signature/latest/signature/trait.PrehashSignature.html#associated-types -#[proc_macro_derive(Signer)] -pub fn derive_signer(input: TokenStream) -> TokenStream { - let input = parse_macro_input!(input as DeriveInput); - emit_signer_impl(input).into() -} - -fn emit_signer_impl(input: DeriveInput) -> TokenStream2 { - let s_ident = Ident::new("__S", Span::call_site()); - - let mut params = DeriveParams::new(input); - params.add_bound(&s_ident, parse_quote!(::signature::PrehashSignature)); - params.add_bound( - &Ident::new("Self", Span::call_site()), - parse_quote!(::signature::DigestSigner<#s_ident::Digest, #s_ident>), - ); - - let name = params.name; - let impl_generics = params.impl_generics; - let ty_generics = params.ty_generics; - let where_clause = params.where_clause; - - quote! { - impl<#(#impl_generics),*> ::signature::Signer<#s_ident> for #name<#(#ty_generics),*> - #where_clause - { - fn try_sign(&self, msg: &[u8]) -> ::signature::Result<#s_ident> { - self.try_sign_digest(#s_ident::Digest::new_with_prefix(msg)) - } - } - } -} - -/// Derive the [`Verifier`] trait for a type which impls [`DigestVerifier`]. -/// -/// When implementing the [`DigestVerifier`] trait for a signature type which -/// itself impl's the [`PrehashSignature`] trait (which marks signature -/// algorithms which are computed using a [`Digest`]), signature providers -/// can automatically derive the [`Verifier`] trait when the digest algorithm -/// is [`PrehashSignature::Digest`] (i.e. the "standard" digest algorithm -/// for a given signature type) -/// -/// This automates all of the digest computation otherwise needed for a -/// complete signature algorithm implementation. -/// -/// [`Digest`]: https://docs.rs/digest/latest/digest/trait.Digest.html -/// [`DigestVerifier`]: https://docs.rs/signature/latest/signature/trait.DigestVerifier.html -/// [`PrehashSignature`]: https://docs.rs/signature/latest/signature/trait.PrehashSignature.html -/// [`PrehashSignature::Digest`]: https://docs.rs/signature/latest/signature/trait.PrehashSignature.html#associated-types -#[proc_macro_derive(Verifier)] -pub fn derive_verifier(input: TokenStream) -> TokenStream { - let input = parse_macro_input!(input as DeriveInput); - emit_verifier_impl(input).into() -} - -fn emit_verifier_impl(input: DeriveInput) -> TokenStream2 { - let s_ident = Ident::new("__S", Span::call_site()); - - let mut params = DeriveParams::new(input); - params.add_bound(&s_ident, parse_quote!(::signature::PrehashSignature)); - params.add_bound( - &Ident::new("Self", Span::call_site()), - parse_quote!(::signature::DigestVerifier<#s_ident::Digest, #s_ident>), - ); - - let name = params.name; - let impl_generics = params.impl_generics; - let ty_generics = params.ty_generics; - let where_clause = params.where_clause; - - quote! { - impl<#(#impl_generics),*> ::signature::Verifier<#s_ident> for #name<#(#ty_generics),*> - #where_clause - { - fn verify(&self, msg: &[u8], signature: &#s_ident) -> ::signature::Result<()> { - self.verify_digest(#s_ident::Digest::new_with_prefix(msg), signature) - } - } - } -} - -/// Derive the [`DigestSigner`] trait for a type which impls [`PrehashSigner`]. -/// -/// [`DigestSigner`]: https://docs.rs/signature/latest/signature/trait.DigestSigner.html -/// [`PrehashSigner`]: https://docs.rs/signature/latest/signature/hazmat/trait.PrehashSigner.html -#[proc_macro_derive(DigestSigner)] -pub fn derive_digest_signer(input: TokenStream) -> TokenStream { - let input = parse_macro_input!(input as DeriveInput); - emit_digest_signer_impl(input).into() -} - -fn emit_digest_signer_impl(input: DeriveInput) -> TokenStream2 { - let d_ident = Ident::new("__D", Span::call_site()); - let s_ident = Ident::new("__S", Span::call_site()); - - let mut params = DeriveParams::new(input); - params.add_bound(&d_ident, parse_quote!(::signature::digest::Digest)); - params.add_param(&s_ident); - params.add_bound( - &Ident::new("Self", Span::call_site()), - parse_quote!(::signature::hazmat::PrehashSigner<#s_ident>), - ); - - let name = params.name; - let impl_generics = params.impl_generics; - let ty_generics = params.ty_generics; - let where_clause = params.where_clause; - - quote! { - impl<#(#impl_generics),*> ::signature::DigestSigner<#d_ident, #s_ident> for #name<#(#ty_generics),*> - #where_clause - { - fn try_sign_digest(&self, digest: #d_ident) -> ::signature::Result<#s_ident> { - self.sign_prehash(&digest.finalize()) - } - } - } -} - -/// Derive the [`DigestVerifier`] trait for a type which impls [`PrehashVerifier`]. -/// -/// [`DigestVerifier`]: https://docs.rs/signature/latest/signature/trait.DigestVerifier.html -/// [`PrehashVerifier`]: https://docs.rs/signature/latest/signature/hazmat/trait.PrehashVerifier.html -#[proc_macro_derive(DigestVerifier)] -pub fn derive_digest_verifier(input: TokenStream) -> TokenStream { - let input = parse_macro_input!(input as DeriveInput); - emit_digest_verifier_impl(input).into() -} - -fn emit_digest_verifier_impl(input: DeriveInput) -> TokenStream2 { - let d_ident = Ident::new("__D", Span::call_site()); - let s_ident = Ident::new("__S", Span::call_site()); - - let mut params = DeriveParams::new(input); - params.add_bound(&d_ident, parse_quote!(::signature::digest::Digest)); - params.add_param(&s_ident); - params.add_bound( - &Ident::new("Self", Span::call_site()), - parse_quote!(::signature::hazmat::PrehashVerifier<#s_ident>), - ); - - let name = params.name; - let impl_generics = params.impl_generics; - let ty_generics = params.ty_generics; - let where_clause = params.where_clause; - - quote! { - impl<#(#impl_generics),*> ::signature::DigestVerifier<#d_ident, #s_ident> for #name<#(#ty_generics),*> - #where_clause - { - fn verify_digest(&self, digest: #d_ident, signature: &#s_ident) -> ::signature::Result<()> { - self.verify_prehash(&digest.finalize(), signature) - } - } - } -} - -/// Derivation parameters parsed from `DeriveInput`. -struct DeriveParams { - /// Name of the struct the trait impls are being added to. - name: Ident, - - /// Generic parameters of `impl`. - impl_generics: Vec, - - /// Generic parameters of the type. - ty_generics: Vec, - - /// Where clause in-progress. - where_clause: WhereClause, -} - -impl DeriveParams { - /// Parse parameters from `DeriveInput`. - fn new(input: DeriveInput) -> Self { - let impl_generics = input.generics.type_params().cloned().collect(); - - let ty_generics = input - .generics - .type_params() - .map(|bound| bound.ident.clone()) - .collect(); - - let where_clause = input - .generics - .where_clause - .clone() - .unwrap_or_else(|| WhereClause { - where_token: ::default(), - predicates: Punctuated::new(), - }); - - Self { - name: input.ident, - impl_generics, - ty_generics, - where_clause, - } - } - - /// Add a generic parameter with the given bound. - fn add_bound(&mut self, name: &Ident, bound: TraitBound) { - if name != "Self" { - self.add_param(name); - } - - let type_path = parse_quote!(#name); - - let mut bounds = Punctuated::new(); - bounds.push(TypeParamBound::Trait(bound)); - - let predicate_type = PredicateType { - lifetimes: None, - bounded_ty: Type::Path(type_path), - colon_token: ::default(), - bounds, - }; - - self.where_clause - .predicates - .push(WherePredicate::Type(predicate_type)) - } - - /// Add a generic parameter without a bound. - fn add_param(&mut self, name: &Ident) { - self.impl_generics.push(TypeParam { - attrs: vec![], - ident: name.clone(), - colon_token: None, - bounds: Default::default(), - eq_token: None, - default: None, - }); - } -} - -#[cfg(test)] -mod tests { - use super::*; - use syn::parse_quote; - - #[test] - fn signer() { - let input = parse_quote! { - #[derive(Signer)] - struct MySigner - where - C: EllipticCurve - { - scalar: Scalar - } - }; - - let output = emit_signer_impl(input); - - assert_eq!( - output.to_string(), - quote! { - impl ::signature::Signer<__S> for MySigner - where - C: EllipticCurve, - __S: ::signature::PrehashSignature, - Self: ::signature::DigestSigner<__S::Digest, __S> - { - fn try_sign(&self, msg: &[u8]) -> ::signature::Result<__S> { - self.try_sign_digest(__S::Digest::new_with_prefix(msg)) - } - } - } - .to_string() - ); - } - - #[test] - fn verifier() { - let input = parse_quote! { - #[derive(Verifier)] - struct MyVerifier { - point: UncompressedPoint - } - }; - - let output = emit_verifier_impl(input); - - assert_eq!( - output.to_string(), - quote! { - impl ::signature::Verifier<__S> for MyVerifier - where - __S: ::signature::PrehashSignature, - Self: ::signature::DigestVerifier<__S::Digest, __S> - { - fn verify(&self, msg: &[u8], signature: &__S) -> ::signature::Result<()> { - self.verify_digest(__S::Digest::new_with_prefix(msg), signature) - } - } - } - .to_string() - ); - } - - #[test] - fn digest_signer() { - let input = parse_quote! { - #[derive(DigestSigner)] - struct MySigner { - scalar: Scalar - } - }; - - let output = emit_digest_signer_impl(input); - - assert_eq!( - output.to_string(), - quote! { - impl ::signature::DigestSigner<__D, __S> for MySigner - where - __D: ::signature::digest::Digest, - Self: ::signature::hazmat::PrehashSigner<__S> - { - fn try_sign_digest(&self, digest: __D) -> ::signature::Result<__S> { - self.sign_prehash(&digest.finalize()) - } - } - } - .to_string() - ); - } - - #[test] - fn digest_verifier() { - let input = parse_quote! { - #[derive(DigestVerifier)] - struct MyVerifier { - point: UncompressedPoint - } - }; - - let output = emit_digest_verifier_impl(input); - - assert_eq!( - output.to_string(), - quote! { - impl ::signature::DigestVerifier<__D, __S> for MyVerifier - where - __D: ::signature::digest::Digest, - Self: ::signature::hazmat::PrehashVerifier<__S> - { - fn verify_digest(&self, digest: __D, signature: &__S) -> ::signature::Result<()> { - self.verify_prehash(&digest.finalize(), signature) - } - } - } - .to_string() - ); - } -} From 74ee4ef88a09168020e079149ed8fd2cc8b741da Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 May 2025 01:58:04 +0300 Subject: [PATCH 1346/1461] Update Cargo.lock (#1846) --- Cargo.lock | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a3452ce62..b2ad3256c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -281,9 +281,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "getrandom" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" dependencies = [ "cfg-if", "libc", @@ -589,16 +589,6 @@ dependencies = [ "hex-literal", "rand_core", "sha2", - "signature_derive", -] - -[[package]] -name = "signature_derive" -version = "2.2.0" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.98", ] [[package]] From 73ffc4055c0d0b4ccfb0fecee8c7a217d0d53cec Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Tue, 13 May 2025 22:05:58 +0000 Subject: [PATCH 1347/1461] chore(deps): bump `crypto-bigint` to `0.7.0-pre.3` (#1845) --- Cargo.lock | 4 ++-- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/dev.rs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b2ad3256c..a11618ccc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -158,9 +158,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.7.0-pre.2" +version = "0.7.0-pre.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87a5061ea0870b06f7fdd5a0f7268e30c04de1932c148cca0ce5c79a88d18bed" +checksum = "f727d84cf16cb51297e4388421e2e51b2f94ffe92ee1d8664d81676901196fa3" dependencies = [ "hybrid-array", "num-traits", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index e936b45bf..32c103e37 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -18,7 +18,7 @@ and public/secret keys composed thereof. [dependencies] base16ct = "0.2" -crypto-bigint = { version = "=0.7.0-pre.2", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } +crypto-bigint = { version = "=0.7.0-pre.3", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } hybrid-array = { version = "0.3", default-features = false, features = ["zeroize"] } rand_core = { version = "0.9.0", default-features = false } subtle = { version = "2.6", default-features = false } diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 020795544..6e92c27ef 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -333,7 +333,7 @@ impl Reduce for Scalar { type Bytes = FieldBytes; fn reduce(w: U256) -> Self { - let (r, underflow) = w.sbb(&MockCurve::ORDER, Limb::ZERO); + let (r, underflow) = w.borrowing_sub(&MockCurve::ORDER, Limb::ZERO); let underflow = Choice::from((underflow.0 >> (Limb::BITS - 1)) as u8); let reduced = U256::conditional_select(&w, &r, !underflow); Self(ScalarPrimitive::new(reduced).unwrap()) From ae58a7766614dab71973fb3286754f782ed90820 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Thu, 15 May 2025 00:53:02 +0200 Subject: [PATCH 1348/1461] Implement `PartialEq + Eq` for `NonIdentity` and `NonZeroScalar` (#1834) This is done by the fact that the underlying types implement these traits already. --- elliptic-curve/src/point/non_identity.rs | 2 +- elliptic-curve/src/scalar/nonzero.rs | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/elliptic-curve/src/point/non_identity.rs b/elliptic-curve/src/point/non_identity.rs index 3068afaa0..c985ba7fd 100644 --- a/elliptic-curve/src/point/non_identity.rs +++ b/elliptic-curve/src/point/non_identity.rs @@ -18,7 +18,7 @@ use crate::{CurveArithmetic, NonZeroScalar, Scalar}; /// /// In the context of ECC, it's useful for ensuring that certain arithmetic /// cannot result in the identity point. -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] pub struct NonIdentity

{ point: P, } diff --git a/elliptic-curve/src/scalar/nonzero.rs b/elliptic-curve/src/scalar/nonzero.rs index 4d2e4c51e..550ef1833 100644 --- a/elliptic-curve/src/scalar/nonzero.rs +++ b/elliptic-curve/src/scalar/nonzero.rs @@ -128,6 +128,8 @@ where } } +impl Eq for NonZeroScalar where C: CurveArithmetic {} + impl From> for FieldBytes where C: CurveArithmetic, @@ -256,6 +258,15 @@ where } } +impl PartialEq for NonZeroScalar +where + C: CurveArithmetic, +{ + fn eq(&self, other: &Self) -> bool { + self.scalar.eq(&other.scalar) + } +} + /// Note: this is a non-zero reduction, as it's impl'd for [`NonZeroScalar`]. impl Reduce for NonZeroScalar where From 26119c29126bc869bdee3208da87471031bab354 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Sat, 17 May 2025 19:04:42 +0200 Subject: [PATCH 1349/1461] elliptic-curve: require `From` for `Projective/AffinePoint` (#1849) Equivalent of #1847 for `Projective/AffinePoint`. Companion PR to https://github.com/RustCrypto/elliptic-curves/pull/1190. --- elliptic-curve/src/arithmetic.rs | 4 +++- elliptic-curve/src/dev.rs | 14 +++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/elliptic-curve/src/arithmetic.rs b/elliptic-curve/src/arithmetic.rs index 86d0947bb..ed9f22169 100644 --- a/elliptic-curve/src/arithmetic.rs +++ b/elliptic-curve/src/arithmetic.rs @@ -3,7 +3,7 @@ use crate::{ Curve, FieldBytes, PrimeCurve, ScalarPrimitive, ops::{Invert, LinearCombination, Reduce, ShrAssign}, - point::AffineCoordinates, + point::{AffineCoordinates, NonIdentity}, scalar::{FromUintUnchecked, IsHigh}, }; use core::fmt::Debug; @@ -22,6 +22,7 @@ pub trait CurveArithmetic: Curve { + Default + DefaultIsZeroes + Eq + + From> + PartialEq + Sized + Send @@ -43,6 +44,7 @@ pub trait CurveArithmetic: Curve { + Default + DefaultIsZeroes + From + + From> + Into + LinearCombination<[(Self::ProjectivePoint, Self::Scalar)]> + LinearCombination<[(Self::ProjectivePoint, Self::Scalar); 2]> diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 6e92c27ef..9c050dad4 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -9,7 +9,7 @@ use crate::{ bigint::{Limb, U256}, error::{Error, Result}, ops::{Invert, LinearCombination, Reduce, ShrAssign}, - point::AffineCoordinates, + point::{AffineCoordinates, NonIdentity}, rand_core::TryRngCore, scalar::{FromUintUnchecked, IsHigh}, sec1::{CompressedPoint, FromEncodedPoint, ToEncodedPoint}, @@ -460,6 +460,12 @@ impl Default for AffinePoint { impl DefaultIsZeroes for AffinePoint {} +impl From> for AffinePoint { + fn from(affine: NonIdentity) -> Self { + affine.to_point() + } +} + impl FromEncodedPoint for AffinePoint { fn from_encoded_point(encoded_point: &EncodedPoint) -> CtOption { let point = if encoded_point.is_identity() { @@ -554,6 +560,12 @@ impl From for ProjectivePoint { } } +impl From> for ProjectivePoint { + fn from(point: NonIdentity) -> Self { + point.to_point() + } +} + impl From for AffinePoint { fn from(point: ProjectivePoint) -> AffinePoint { group::Curve::to_affine(&point) From 4b37715368ce485f3e99de134f10c75e00b999e9 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Mon, 19 May 2025 13:16:00 +0200 Subject: [PATCH 1350/1461] Use `Output = True` instead of `NonZero` (#1850) Bounds like `IsLess` aren't actually enforced unless the `IsLess::Output` is checked. This was done by adding `Le<...>: NonZero`. This PR simplifies this check by adding `IsLess<..., Output = True>`. --- crypto-common/src/lib.rs | 10 ++---- .../src/hash2curve/hash2field/expand_msg.rs | 6 ++-- .../hash2curve/hash2field/expand_msg/xmd.rs | 34 ++++++++++--------- .../hash2curve/hash2field/expand_msg/xof.rs | 10 +++--- 4 files changed, 28 insertions(+), 32 deletions(-) diff --git a/crypto-common/src/lib.rs b/crypto-common/src/lib.rs index 3e070ad4c..94b111508 100644 --- a/crypto-common/src/lib.rs +++ b/crypto-common/src/lib.rs @@ -79,17 +79,11 @@ pub trait BlockSizes: ArraySize + sealed::BlockSizes {} impl BlockSizes for T {} mod sealed { - use crate::typenum::{Gr, IsGreater, IsLess, Le, NonZero, U0, U256, Unsigned}; + use crate::typenum::{IsLess, NonZero, True, U256, Unsigned}; pub trait BlockSizes {} - impl BlockSizes for T - where - Self: IsLess + IsGreater, - Le: NonZero, - Gr: NonZero, - { - } + impl BlockSizes for T where Self: IsLess + NonZero {} } /// Types which can process blocks in parallel. diff --git a/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs b/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs index 444dbf72f..e8fb802a6 100644 --- a/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs +++ b/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs @@ -7,7 +7,7 @@ use core::num::NonZero; use crate::{Error, Result}; use digest::{Digest, ExtendableOutput, Update, XofReader}; -use hybrid_array::typenum::{IsLess, U256}; +use hybrid_array::typenum::{IsLess, True, U256}; use hybrid_array::{Array, ArraySize}; /// Salt when the DST is too long @@ -48,7 +48,7 @@ pub trait Expander { #[derive(Debug)] pub(crate) enum Domain<'a, L> where - L: ArraySize + IsLess, + L: ArraySize + IsLess, { /// > 255 Hashed(Array), @@ -58,7 +58,7 @@ where impl<'a, L> Domain<'a, L> where - L: ArraySize + IsLess, + L: ArraySize + IsLess, { pub fn xof(dsts: &'a [&'a [u8]]) -> Result where diff --git a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs index e98843e38..8ad5223ab 100644 --- a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs +++ b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs @@ -8,7 +8,7 @@ use digest::{ FixedOutput, HashMarker, array::{ Array, - typenum::{IsGreaterOrEqual, IsLess, IsLessOrEqual, U2, U256, Unsigned}, + typenum::{IsGreaterOrEqual, IsLess, IsLessOrEqual, True, U2, U256, Unsigned}, }, core_api::BlockSizeUser, }; @@ -28,10 +28,10 @@ use digest::{ pub struct ExpandMsgXmd(PhantomData<(HashT, K)>) where HashT: BlockSizeUser + Default + FixedOutput + HashMarker, - HashT::OutputSize: IsLess, - HashT::OutputSize: IsLessOrEqual, + HashT::OutputSize: IsLess, + HashT::OutputSize: IsLessOrEqual, K: Mul, - HashT::OutputSize: IsGreaterOrEqual<>::Output>; + HashT::OutputSize: IsGreaterOrEqual<>::Output, Output = True>; impl<'a, HashT, K> ExpandMsg<'a> for ExpandMsgXmd where @@ -39,14 +39,14 @@ where // If DST is larger than 255 bytes, the length of the computed DST will depend on the output // size of the hash, which is still not allowed to be larger than 256: // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-13.html#section-5.4.1-6 - HashT::OutputSize: IsLess, + HashT::OutputSize: IsLess, // Constraint set by `expand_message_xmd`: // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-13.html#section-5.4.1-4 - HashT::OutputSize: IsLessOrEqual, + HashT::OutputSize: IsLessOrEqual, // The number of bits output by `HashT` MUST be larger or equal to `K * 2`: // https://www.rfc-editor.org/rfc/rfc9380.html#section-5.3.1-2.1 K: Mul, - HashT::OutputSize: IsGreaterOrEqual<>::Output>, + HashT::OutputSize: IsGreaterOrEqual<>::Output, Output = True>, { type Expander = ExpanderXmd<'a, HashT>; @@ -102,8 +102,8 @@ where pub struct ExpanderXmd<'a, HashT> where HashT: BlockSizeUser + Default + FixedOutput + HashMarker, - HashT::OutputSize: IsLess, - HashT::OutputSize: IsLessOrEqual, + HashT::OutputSize: IsLess, + HashT::OutputSize: IsLessOrEqual, { b_0: Array, b_vals: Array, @@ -116,8 +116,8 @@ where impl ExpanderXmd<'_, HashT> where HashT: BlockSizeUser + Default + FixedOutput + HashMarker, - HashT::OutputSize: IsLess, - HashT::OutputSize: IsLessOrEqual, + HashT::OutputSize: IsLess, + HashT::OutputSize: IsLessOrEqual, { fn next(&mut self) -> bool { if self.index < self.ell { @@ -146,8 +146,8 @@ where impl Expander for ExpanderXmd<'_, HashT> where HashT: BlockSizeUser + Default + FixedOutput + HashMarker, - HashT::OutputSize: IsLess, - HashT::OutputSize: IsLessOrEqual, + HashT::OutputSize: IsLess, + HashT::OutputSize: IsLessOrEqual, { fn fill_bytes(&mut self, okm: &mut [u8]) { for b in okm { @@ -178,7 +178,7 @@ mod test { bytes: &[u8], ) where HashT: BlockSizeUser + Default + FixedOutput + HashMarker, - HashT::OutputSize: IsLess, + HashT::OutputSize: IsLess, { let block = HashT::BlockSize::to_usize(); assert_eq!( @@ -219,8 +219,10 @@ mod test { ) -> Result<()> where HashT: BlockSizeUser + Default + FixedOutput + HashMarker, - HashT::OutputSize: IsLess + IsLessOrEqual + Mul, - HashT::OutputSize: IsGreaterOrEqual<>::Output>, + HashT::OutputSize: IsLess + + IsLessOrEqual + + Mul, + HashT::OutputSize: IsGreaterOrEqual<>::Output, Output = True>, { assert_message::(self.msg, domain, L::to_u16(), self.msg_prime); diff --git a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs index 9d40ed2c1..201aee156 100644 --- a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs +++ b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs @@ -6,7 +6,7 @@ use core::{fmt, marker::PhantomData, num::NonZero, ops::Mul}; use digest::{ExtendableOutput, HashMarker, Update, XofReader}; use hybrid_array::{ ArraySize, - typenum::{IsLess, U2, U256}, + typenum::{IsLess, True, U2, U256}, }; /// Implements `expand_message_xof` via the [`ExpandMsg`] trait: @@ -23,7 +23,7 @@ pub struct ExpandMsgXof where HashT: Default + ExtendableOutput + Update + HashMarker, K: Mul, - >::Output: ArraySize + IsLess, + >::Output: ArraySize + IsLess, { reader: ::Reader, _k: PhantomData, @@ -33,7 +33,7 @@ impl fmt::Debug for ExpandMsgXof where HashT: Default + ExtendableOutput + Update + HashMarker, K: Mul, - >::Output: ArraySize + IsLess, + >::Output: ArraySize + IsLess, ::Reader: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -49,7 +49,7 @@ where // If DST is larger than 255 bytes, the length of the computed DST is calculated by `K * 2`. // https://www.rfc-editor.org/rfc/rfc9380.html#section-5.3.1-2.1 K: Mul, - >::Output: ArraySize + IsLess, + >::Output: ArraySize + IsLess, { type Expander = Self; @@ -82,7 +82,7 @@ impl Expander for ExpandMsgXof where HashT: Default + ExtendableOutput + Update + HashMarker, K: Mul, - >::Output: ArraySize + IsLess, + >::Output: ArraySize + IsLess, { fn fill_bytes(&mut self, okm: &mut [u8]) { self.reader.read(okm); From 6c9bad3ed1086af153b86d389042f426d73c3ac0 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Mon, 19 May 2025 19:02:34 +0200 Subject: [PATCH 1351/1461] Require `From>` for `Scalar` (#1847) This adds a new requirement to `CurveArithmetic::Scalar`: `From>`. Its currently a bit cumbersome to go through `Deref` or `AsRef` every time and then `Copy`. `Into` seems much more straightforward to me. Companion PR: https://github.com/RustCrypto/elliptic-curves/pull/1188. --- elliptic-curve/src/arithmetic.rs | 3 ++- elliptic-curve/src/dev.rs | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/elliptic-curve/src/arithmetic.rs b/elliptic-curve/src/arithmetic.rs index ed9f22169..e1cc29987 100644 --- a/elliptic-curve/src/arithmetic.rs +++ b/elliptic-curve/src/arithmetic.rs @@ -1,7 +1,7 @@ //! Elliptic curve arithmetic traits. use crate::{ - Curve, FieldBytes, PrimeCurve, ScalarPrimitive, + Curve, FieldBytes, NonZeroScalar, PrimeCurve, ScalarPrimitive, ops::{Invert, LinearCombination, Reduce, ShrAssign}, point::{AffineCoordinates, NonIdentity}, scalar::{FromUintUnchecked, IsHigh}, @@ -65,6 +65,7 @@ pub trait CurveArithmetic: Curve { /// - [`Sync`] type Scalar: AsRef + DefaultIsZeroes + + From> + From> + FromUintUnchecked + Into> diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 9c050dad4..d9aaabbd3 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -352,6 +352,12 @@ impl From for Scalar { } } +impl From for Scalar { + fn from(scalar: NonZeroScalar) -> Self { + scalar.0.into() + } +} + impl From for Scalar { fn from(scalar: ScalarPrimitive) -> Scalar { Self(scalar) From 2dcad3553c830b9bc7f4748a361914bb44d9539d Mon Sep 17 00:00:00 2001 From: daxpedda Date: Mon, 19 May 2025 19:03:38 +0200 Subject: [PATCH 1352/1461] Add `type ExpandMsg` to `VoprfParameters` (#1814) Main motivation was that `decaf448` (https://github.com/RustCrypto/elliptic-curves/pull/1121) requires `ExpandMsgXof` instead of `ExpandMsgXmd`. I was briefly tempted to add a `type Hash` to the `ExpandMsg` trait to be able to write `type ExpandMsg = ExpandMsg`. Otherwise it is possible to add a different hash in the `ExpandMsg` type: ```rust impl VoprfParamters for Fun128 { type Hash = Sha512; type ExpandMsg = ExpandMsgXmd; ... } ``` But I thought its a bit much. Let me know if you want me to add that. --- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/voprf.rs | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 32c103e37..f60db0eca 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -69,7 +69,7 @@ jwk = ["dep:base64ct", "dep:serde_json", "alloc", "serde", "zeroize/alloc"] pkcs8 = ["dep:pkcs8", "sec1"] pem = ["dep:pem-rfc7468", "alloc", "arithmetic", "pkcs8", "sec1/pem"] serde = ["dep:serdect", "alloc", "pkcs8", "sec1/serde"] -voprf = ["digest"] +voprf = ["digest", "hash2curve"] [package.metadata.docs.rs] features = ["bits", "ecdh", "hash2curve", "jwk", "pem", "std", "voprf"] diff --git a/elliptic-curve/src/voprf.rs b/elliptic-curve/src/voprf.rs index 68f2abf18..e882fe1b3 100644 --- a/elliptic-curve/src/voprf.rs +++ b/elliptic-curve/src/voprf.rs @@ -3,6 +3,7 @@ //! use crate::PrimeCurve; +use crate::hash2curve::ExpandMsg; /// Elliptic curve parameters used by VOPRF. pub trait VoprfParameters: PrimeCurve { @@ -17,4 +18,10 @@ pub trait VoprfParameters: PrimeCurve { /// /// [voprf]: https://www.ietf.org/archive/id/draft-irtf-cfrg-voprf-19.html#name-ciphersuites-2 type Hash: digest::Digest; + + /// The `expand_message` parameter which assigns a particular algorithm for `HashToGroup` + /// and `HashToScalar` as defined in [section 4 of `draft-irtf-cfrg-voprf-19`][voprf]. + /// + /// [voprf]: https://www.rfc-editor.org/rfc/rfc9497#name-ciphersuites + type ExpandMsg: for<'a> ExpandMsg<'a>; } From 2744cdb79cee28069755a870ab700e3827be8c07 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 May 2025 01:21:08 +0300 Subject: [PATCH 1353/1461] Update Cargo.lock (#1851) --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a11618ccc..54d058ded 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -58,9 +58,9 @@ checksum = "89e25b6adfb930f02d1981565a6e5d9c547ac15a96606256d3b59040e5cd4ca3" [[package]] name = "bitflags" -version = "2.9.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" [[package]] name = "bitvec" From d131d740cf047e27f6cfb6e21701b0adab83fb9f Mon Sep 17 00:00:00 2001 From: daxpedda Date: Wed, 21 May 2025 15:38:18 +0200 Subject: [PATCH 1354/1461] Implement `Mul<&NonZeroScalar>` for `NonIdentity` (#1852) --- elliptic-curve/src/point/non_identity.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/elliptic-curve/src/point/non_identity.rs b/elliptic-curve/src/point/non_identity.rs index c985ba7fd..9dddba6ef 100644 --- a/elliptic-curve/src/point/non_identity.rs +++ b/elliptic-curve/src/point/non_identity.rs @@ -163,6 +163,18 @@ where } } +impl Mul<&NonZeroScalar> for NonIdentity

+where + C: CurveArithmetic, + P: Copy + Mul, Output = P>, +{ + type Output = NonIdentity

; + + fn mul(self, rhs: &NonZeroScalar) -> Self::Output { + self * *rhs + } +} + impl Mul<&NonZeroScalar> for &NonIdentity

where C: CurveArithmetic, From 91d6acda098602f9026442bac7481f6e60db11a1 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 21 May 2025 20:20:57 -0600 Subject: [PATCH 1355/1461] elliptic-curve: scalar `Mul` bounds (#1854) Adds bounds on `CurveArithmetic::Scalar` that it has a `Mul

` impl for both `AffinePoint` and `ProjectivePoint` --- elliptic-curve/src/arithmetic.rs | 6 +++++- elliptic-curve/src/dev.rs | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/elliptic-curve/src/arithmetic.rs b/elliptic-curve/src/arithmetic.rs index e1cc29987..d0d17bc4c 100644 --- a/elliptic-curve/src/arithmetic.rs +++ b/elliptic-curve/src/arithmetic.rs @@ -2,7 +2,7 @@ use crate::{ Curve, FieldBytes, NonZeroScalar, PrimeCurve, ScalarPrimitive, - ops::{Invert, LinearCombination, Reduce, ShrAssign}, + ops::{Invert, LinearCombination, Mul, Reduce, ShrAssign}, point::{AffineCoordinates, NonIdentity}, scalar::{FromUintUnchecked, IsHigh}, }; @@ -73,6 +73,10 @@ pub trait CurveArithmetic: Curve { + Into + Invert> + IsHigh + + Mul + + for<'a> Mul<&'a Self::AffinePoint, Output = Self::ProjectivePoint> + + Mul + + for<'a> Mul<&'a Self::ProjectivePoint, Output = Self::ProjectivePoint> + PartialOrd + Reduce> + ShrAssign diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index d9aaabbd3..862b678be 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -271,6 +271,38 @@ impl Mul<&Scalar> for Scalar { } } +impl Mul for Scalar { + type Output = ProjectivePoint; + + fn mul(self, _other: AffinePoint) -> ProjectivePoint { + unimplemented!(); + } +} + +impl Mul<&AffinePoint> for Scalar { + type Output = ProjectivePoint; + + fn mul(self, _other: &AffinePoint) -> ProjectivePoint { + unimplemented!(); + } +} + +impl Mul for Scalar { + type Output = ProjectivePoint; + + fn mul(self, _other: ProjectivePoint) -> ProjectivePoint { + unimplemented!(); + } +} + +impl Mul<&ProjectivePoint> for Scalar { + type Output = ProjectivePoint; + + fn mul(self, _other: &ProjectivePoint) -> ProjectivePoint { + unimplemented!(); + } +} + impl MulAssign for Scalar { fn mul_assign(&mut self, _rhs: Scalar) { unimplemented!(); From 22ae23d4748e7b0e96f658fcbf4b2531c3d59fd7 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Thu, 22 May 2025 16:59:39 +0200 Subject: [PATCH 1356/1461] Implement `Mul` for `NonZeroScalar` (#1855) This implements `Mul for NonZeroScalar`. Analogous to #1854. --- elliptic-curve/src/point/non_identity.rs | 16 +++++++- elliptic-curve/src/scalar/nonzero.rs | 49 ++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/elliptic-curve/src/point/non_identity.rs b/elliptic-curve/src/point/non_identity.rs index 9dddba6ef..91217827b 100644 --- a/elliptic-curve/src/point/non_identity.rs +++ b/elliptic-curve/src/point/non_identity.rs @@ -175,20 +175,32 @@ where } } -impl Mul<&NonZeroScalar> for &NonIdentity

+impl Mul> for &NonIdentity

where C: CurveArithmetic, P: Copy + Mul, Output = P>, { type Output = NonIdentity

; - fn mul(self, rhs: &NonZeroScalar) -> Self::Output { + fn mul(self, rhs: NonZeroScalar) -> Self::Output { NonIdentity { point: self.point * *rhs.as_ref(), } } } +impl Mul<&NonZeroScalar> for &NonIdentity

+where + C: CurveArithmetic, + P: Copy + Mul, Output = P>, +{ + type Output = NonIdentity

; + + fn mul(self, rhs: &NonZeroScalar) -> Self::Output { + self * *rhs + } +} + #[cfg(feature = "serde")] impl

Serialize for NonIdentity

where diff --git a/elliptic-curve/src/scalar/nonzero.rs b/elliptic-curve/src/scalar/nonzero.rs index 550ef1833..a0cd28abc 100644 --- a/elliptic-curve/src/scalar/nonzero.rs +++ b/elliptic-curve/src/scalar/nonzero.rs @@ -3,6 +3,7 @@ use crate::{ CurveArithmetic, Error, FieldBytes, PrimeCurve, Scalar, ScalarPrimitive, SecretKey, ops::{Invert, Reduce, ReduceNonZero}, + point::NonIdentity, scalar::IsHigh, }; use base16ct::HexDisplay; @@ -258,6 +259,54 @@ where } } +impl Mul> for NonZeroScalar +where + C: CurveArithmetic, + NonIdentity

: Mul, Output = NonIdentity

>, +{ + type Output = NonIdentity

; + + fn mul(self, rhs: NonIdentity

) -> Self::Output { + rhs * self + } +} + +impl Mul<&NonIdentity

> for NonZeroScalar +where + C: CurveArithmetic, + for<'a> &'a NonIdentity

: Mul, Output = NonIdentity

>, +{ + type Output = NonIdentity

; + + fn mul(self, rhs: &NonIdentity

) -> Self::Output { + rhs * self + } +} + +impl Mul> for &NonZeroScalar +where + C: CurveArithmetic, + for<'a> NonIdentity

: Mul<&'a NonZeroScalar, Output = NonIdentity

>, +{ + type Output = NonIdentity

; + + fn mul(self, rhs: NonIdentity

) -> Self::Output { + rhs * self + } +} + +impl Mul<&NonIdentity

> for &NonZeroScalar +where + C: CurveArithmetic, + for<'a> &'a NonIdentity

: Mul<&'a NonZeroScalar, Output = NonIdentity

>, +{ + type Output = NonIdentity

; + + fn mul(self, rhs: &NonIdentity

) -> Self::Output { + rhs * self + } +} + impl PartialEq for NonZeroScalar where C: CurveArithmetic, From 663b4450e69910c94ff09c627d3f0dee64169f9d Mon Sep 17 00:00:00 2001 From: daxpedda Date: Thu, 22 May 2025 21:23:58 +0200 Subject: [PATCH 1357/1461] Require `TryInto` (#1853) This PR adds the following requirements: - `CurveArithmetic::Scalar`: `TryInto` - `CurveArithmetic::ProjectivePoint`: `TryInto>` - `CurveArithmetic::AffinePoint`: `TryInto>` Companion PR to https://github.com/RustCrypto/elliptic-curves/pull/1193. --- elliptic-curve/src/arithmetic.rs | 7 +++++-- elliptic-curve/src/dev.rs | 24 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/elliptic-curve/src/arithmetic.rs b/elliptic-curve/src/arithmetic.rs index d0d17bc4c..6e18774d2 100644 --- a/elliptic-curve/src/arithmetic.rs +++ b/elliptic-curve/src/arithmetic.rs @@ -1,7 +1,7 @@ //! Elliptic curve arithmetic traits. use crate::{ - Curve, FieldBytes, NonZeroScalar, PrimeCurve, ScalarPrimitive, + Curve, Error, FieldBytes, NonZeroScalar, PrimeCurve, ScalarPrimitive, ops::{Invert, LinearCombination, Mul, Reduce, ShrAssign}, point::{AffineCoordinates, NonIdentity}, scalar::{FromUintUnchecked, IsHigh}, @@ -26,7 +26,8 @@ pub trait CurveArithmetic: Curve { + PartialEq + Sized + Send - + Sync; + + Sync + + TryInto, Error = Error>; /// Elliptic curve point in projective coordinates. /// @@ -48,6 +49,7 @@ pub trait CurveArithmetic: Curve { + Into + LinearCombination<[(Self::ProjectivePoint, Self::Scalar)]> + LinearCombination<[(Self::ProjectivePoint, Self::Scalar); 2]> + + TryInto, Error = Error> + group::Curve + group::Group; @@ -80,6 +82,7 @@ pub trait CurveArithmetic: Curve { + PartialOrd + Reduce> + ShrAssign + + TryInto, Error = Error> + ff::Field + ff::PrimeField>; } diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 862b678be..98d4c8e1d 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -408,6 +408,14 @@ impl From for U256 { } } +impl TryFrom for NonZeroScalar { + type Error = Error; + + fn try_from(scalar: Scalar) -> Result { + NonZeroScalar::new(scalar).into_option().ok_or(Error) + } +} + impl TryFrom for Scalar { type Error = Error; @@ -544,6 +552,14 @@ impl Mul for AffinePoint { } } +impl TryFrom for NonIdentity { + type Error = Error; + + fn try_from(affine: AffinePoint) -> Result { + NonIdentity::new(affine).into_option().ok_or(Error) + } +} + /// Example projective point type #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum ProjectivePoint { @@ -622,6 +638,14 @@ impl ToEncodedPoint for ProjectivePoint { } } +impl TryFrom for NonIdentity { + type Error = Error; + + fn try_from(point: ProjectivePoint) -> Result { + NonIdentity::new(point).into_option().ok_or(Error) + } +} + impl group::Group for ProjectivePoint { type Scalar = Scalar; From a9489959bccbfd4b39e7cc367095ace6f051c682 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Fri, 23 May 2025 14:23:19 +0200 Subject: [PATCH 1358/1461] Use pre-computation tables for `PublicKey::from_secret_scalar()` (#1856) Potentially use pre-computation tables for calculating the `PublicKey` from a `SecretKey`. Though AFAICS currently only `k256` uses pre-computation tables. --- elliptic-curve/src/public_key.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index cd0389c4d..40bc93ac1 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -109,7 +109,7 @@ where pub fn from_secret_scalar(scalar: &NonZeroScalar) -> Self { // `NonZeroScalar` ensures the resulting point is not the identity Self { - point: (C::ProjectivePoint::generator() * scalar.as_ref()).to_affine(), + point: ProjectivePoint::::mul_by_generator(scalar).to_affine(), } } From 3d8039a2a50387d284fb006f463a982d812c2e76 Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Sun, 25 May 2025 19:20:04 +0000 Subject: [PATCH 1359/1461] Revert "digest: remove `AssociatedOid` blanket impls for wrappers (#1857) This reverts commit c48ea2a4f76127bd3febce8240095b893e6edb1c (#1810) This bring back `master` in a state that can be consumed with a `[patch.crates-io]` (see https://github.com/RustCrypto/traits/pull/1799#issuecomment-2885545411) --- digest/CHANGELOG.md | 3 -- digest/src/core_api/ct_variable.rs | 67 +++++++++++++++++++++++------- digest/src/core_api/wrapper.rs | 10 +++++ digest/src/digest.rs | 6 +-- digest/src/lib.rs | 2 +- 5 files changed, 65 insertions(+), 23 deletions(-) diff --git a/digest/CHANGELOG.md b/digest/CHANGELOG.md index 237e7887b..431816c5e 100644 --- a/digest/CHANGELOG.md +++ b/digest/CHANGELOG.md @@ -17,14 +17,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `Mac::new`, `Mac::new_from_slice`, and `Mac::generate_key` methods ([#1173]) - `HashReader` and `HashWriter` are moved to the `digest-io` crate ([#1809]) - `io::Write/Read` implementations in favor of the `digest_io::IoWrapper` type ([#1809]) -- `AssociatedOid` blanket impls for `CoreWrapper` and `CtVariableCoreWrapper` ([#1810]) -- `impl_oid_carrier!` macro ([#1810]) [#1173]: https://github.com/RustCrypto/traits/pull/1173 [#1334]: https://github.com/RustCrypto/traits/pull/1334 [#1759]: https://github.com/RustCrypto/traits/pull/1759 [#1809]: https://github.com/RustCrypto/traits/pull/1809 -[#1810]: https://github.com/RustCrypto/traits/pull/1810 ## 0.10.7 (2023-05-19) ### Changed diff --git a/digest/src/core_api/ct_variable.rs b/digest/src/core_api/ct_variable.rs index d8ad3e8ca..93ff2f96a 100644 --- a/digest/src/core_api/ct_variable.rs +++ b/digest/src/core_api/ct_variable.rs @@ -5,6 +5,8 @@ use super::{ #[cfg(feature = "mac")] use crate::MacMarker; use crate::{CollisionResistance, CustomizedInit, HashMarker, VarOutputCustomized}; +#[cfg(feature = "oid")] +use const_oid::{AssociatedOid, ObjectIdentifier}; use core::{ fmt, marker::PhantomData, @@ -16,20 +18,26 @@ use crypto_common::{ hazmat::{DeserializeStateError, SerializableState, SerializedState, SubSerializedStateSize}, typenum::{IsLess, IsLessOrEqual, Le, LeEq, NonZero, Sum, U1, U256}, }; + +/// Dummy type used with [`CtVariableCoreWrapper`] in cases when +/// resulting hash does not have a known OID. +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +pub struct NoOid; + /// Wrapper around [`VariableOutputCore`] which selects output size /// at compile time. #[derive(Clone)] -pub struct CtVariableCoreWrapper +pub struct CtVariableCoreWrapper where T: VariableOutputCore, OutSize: ArraySize + IsLessOrEqual, LeEq: NonZero, { inner: T, - _out: PhantomData, + _out: PhantomData<(OutSize, O)>, } -impl HashMarker for CtVariableCoreWrapper +impl HashMarker for CtVariableCoreWrapper where T: VariableOutputCore + HashMarker, OutSize: ArraySize + IsLessOrEqual, @@ -38,7 +46,7 @@ where } #[cfg(feature = "mac")] -impl MacMarker for CtVariableCoreWrapper +impl MacMarker for CtVariableCoreWrapper where T: VariableOutputCore + MacMarker, OutSize: ArraySize + IsLessOrEqual, @@ -55,7 +63,7 @@ where type CollisionResistance = T::CollisionResistance; } -impl BlockSizeUser for CtVariableCoreWrapper +impl BlockSizeUser for CtVariableCoreWrapper where T: VariableOutputCore, OutSize: ArraySize + IsLessOrEqual, @@ -64,7 +72,7 @@ where type BlockSize = T::BlockSize; } -impl UpdateCore for CtVariableCoreWrapper +impl UpdateCore for CtVariableCoreWrapper where T: VariableOutputCore, OutSize: ArraySize + IsLessOrEqual, @@ -76,7 +84,7 @@ where } } -impl OutputSizeUser for CtVariableCoreWrapper +impl OutputSizeUser for CtVariableCoreWrapper where T: VariableOutputCore, OutSize: ArraySize + IsLessOrEqual, @@ -85,7 +93,7 @@ where type OutputSize = OutSize; } -impl BufferKindUser for CtVariableCoreWrapper +impl BufferKindUser for CtVariableCoreWrapper where T: VariableOutputCore, OutSize: ArraySize + IsLessOrEqual, @@ -94,7 +102,7 @@ where type BufferKind = T::BufferKind; } -impl FixedOutputCore for CtVariableCoreWrapper +impl FixedOutputCore for CtVariableCoreWrapper where T: VariableOutputCore, OutSize: ArraySize + IsLessOrEqual, @@ -117,7 +125,7 @@ where } } -impl Default for CtVariableCoreWrapper +impl Default for CtVariableCoreWrapper where T: VariableOutputCore, OutSize: ArraySize + IsLessOrEqual, @@ -132,7 +140,7 @@ where } } -impl CustomizedInit for CtVariableCoreWrapper +impl CustomizedInit for CtVariableCoreWrapper where T: VariableOutputCore + VarOutputCustomized, OutSize: ArraySize + IsLessOrEqual, @@ -147,7 +155,7 @@ where } } -impl Reset for CtVariableCoreWrapper +impl Reset for CtVariableCoreWrapper where T: VariableOutputCore, OutSize: ArraySize + IsLessOrEqual, @@ -159,7 +167,7 @@ where } } -impl AlgorithmName for CtVariableCoreWrapper +impl AlgorithmName for CtVariableCoreWrapper where T: VariableOutputCore + AlgorithmName, OutSize: ArraySize + IsLessOrEqual, @@ -172,8 +180,19 @@ where } } +#[cfg(feature = "oid")] +impl AssociatedOid for CtVariableCoreWrapper +where + T: VariableOutputCore, + O: AssociatedOid, + OutSize: ArraySize + IsLessOrEqual, + LeEq: NonZero, +{ + const OID: ObjectIdentifier = O::OID; +} + #[cfg(feature = "zeroize")] -impl zeroize::ZeroizeOnDrop for CtVariableCoreWrapper +impl zeroize::ZeroizeOnDrop for CtVariableCoreWrapper where T: VariableOutputCore + zeroize::ZeroizeOnDrop, OutSize: ArraySize + IsLessOrEqual, @@ -181,7 +200,7 @@ where { } -impl fmt::Debug for CtVariableCoreWrapper +impl fmt::Debug for CtVariableCoreWrapper where T: VariableOutputCore + AlgorithmName, OutSize: ArraySize + IsLessOrEqual, @@ -192,10 +211,26 @@ where } } +/// Implement dummy type with hidden docs which is used to "carry" hasher +/// OID for [`CtVariableCoreWrapper`]. +#[macro_export] +macro_rules! impl_oid_carrier { + ($name:ident, $oid:literal) => { + #[doc(hidden)] + #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] + pub struct $name; + + #[cfg(feature = "oid")] + impl AssociatedOid for $name { + const OID: ObjectIdentifier = ObjectIdentifier::new_unwrap($oid); + } + }; +} + type CtVariableCoreWrapperSerializedStateSize = Sum<::SerializedStateSize, U1>; -impl SerializableState for CtVariableCoreWrapper +impl SerializableState for CtVariableCoreWrapper where T: VariableOutputCore + SerializableState, OutSize: ArraySize + IsLessOrEqual, diff --git a/digest/src/core_api/wrapper.rs b/digest/src/core_api/wrapper.rs index 242871772..c7368d8a2 100644 --- a/digest/src/core_api/wrapper.rs +++ b/digest/src/core_api/wrapper.rs @@ -21,6 +21,8 @@ use crypto_common::{ #[cfg(feature = "mac")] use crate::MacMarker; +#[cfg(feature = "oid")] +use const_oid::{AssociatedOid, ObjectIdentifier}; /// Wrapper around [`BufferKindUser`]. /// @@ -173,6 +175,14 @@ where } } +#[cfg(feature = "oid")] +impl AssociatedOid for CoreWrapper +where + T: BufferKindUser + AssociatedOid, +{ + const OID: ObjectIdentifier = T::OID; +} + type CoreWrapperSerializedStateSize = Sum::SerializedStateSize, U1>, ::BlockSize>; diff --git a/digest/src/digest.rs b/digest/src/digest.rs index ef084928a..1de1ea86d 100644 --- a/digest/src/digest.rs +++ b/digest/src/digest.rs @@ -3,7 +3,7 @@ use crypto_common::{Output, OutputSizeUser, typenum::Unsigned}; #[cfg(feature = "alloc")] use alloc::boxed::Box; -#[cfg(feature = "oid")] +#[cfg(feature = "const-oid")] use const_oid::DynAssociatedOid; /// Marker trait for cryptographic hash functions. @@ -228,8 +228,8 @@ impl Clone for Box { } /// Convenience wrapper trait around [DynDigest] and [DynAssociatedOid]. -#[cfg(feature = "oid")] +#[cfg(feature = "const-oid")] pub trait DynDigestWithOid: DynDigest + DynAssociatedOid {} -#[cfg(feature = "oid")] +#[cfg(feature = "const-oid")] impl DynDigestWithOid for T {} diff --git a/digest/src/lib.rs b/digest/src/lib.rs index de2a784b6..e8cb7b141 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -63,7 +63,7 @@ pub use block_buffer; pub use const_oid; pub use crypto_common; -#[cfg(feature = "oid")] +#[cfg(feature = "const-oid")] pub use crate::digest::DynDigestWithOid; pub use crate::digest::{Digest, DynDigest, HashMarker}; #[cfg(feature = "mac")] From d7807bf592a3ad1ba9c7f55379759a468bbece0b Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Mon, 26 May 2025 05:10:33 +0300 Subject: [PATCH 1360/1461] digest: add buffering macros (#1799) The new macros create buffered wrapper types and replace the old wrapper types (except `CtVariableCoreWrapper`). --- digest/CHANGELOG.md | 9 +- digest/Cargo.toml | 4 +- digest/README.md | 19 - digest/src/{core_api.rs => block_api.rs} | 16 +- .../{core_api => block_api}/ct_variable.rs | 121 ++--- digest/src/buffer_macros.rs | 4 + digest/src/buffer_macros/fixed.rs | 473 ++++++++++++++++++ digest/src/buffer_macros/variable_ct.rs | 226 +++++++++ digest/src/buffer_macros/variable_rt.rs | 188 +++++++ digest/src/buffer_macros/xof.rs | 328 ++++++++++++ digest/src/core_api/rt_variable.rs | 190 ------- digest/src/core_api/wrapper.rs | 243 --------- digest/src/core_api/xof_reader.rs | 51 -- digest/src/lib.rs | 9 +- digest/tests/dummy_fixed.rs | 101 ++++ 15 files changed, 1378 insertions(+), 604 deletions(-) rename digest/src/{core_api.rs => block_api.rs} (94%) rename digest/src/{core_api => block_api}/ct_variable.rs (51%) create mode 100644 digest/src/buffer_macros.rs create mode 100644 digest/src/buffer_macros/fixed.rs create mode 100644 digest/src/buffer_macros/variable_ct.rs create mode 100644 digest/src/buffer_macros/variable_rt.rs create mode 100644 digest/src/buffer_macros/xof.rs delete mode 100644 digest/src/core_api/rt_variable.rs delete mode 100644 digest/src/core_api/wrapper.rs delete mode 100644 digest/src/core_api/xof_reader.rs create mode 100644 digest/tests/dummy_fixed.rs diff --git a/digest/CHANGELOG.md b/digest/CHANGELOG.md index 431816c5e..a4fe6b64a 100644 --- a/digest/CHANGELOG.md +++ b/digest/CHANGELOG.md @@ -7,21 +7,28 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## 0.11.0 (UNRELEASED) ### Added -- `CustomizedInit` trait ([#1334]). +- `CustomizedInit` trait ([#1334]) +- `buffer_fixed`, `buffer_ct_variable`, `buffer_rt_variable`, and `buffer_xof` macros ([#1799]) +- `CollisionResistance` trait ([#1820]) ### Changed - `crypto-common` dependency bumped to v0.2 ([#1173]) - Edition changed to 2024 and MSRV bumped to 1.85 ([#1759]) +- `CtVariableCoreWrapper` renamed to `CtOutWrapper` ([#1799]) +- Removed the OID type parameter from `CtOutWrapper` ([#1799]) ### Removed - `Mac::new`, `Mac::new_from_slice`, and `Mac::generate_key` methods ([#1173]) +- `CoreWrapper`, `RtVariableCoreWrapper`, and `XofReaderCoreWrapper` types ([#1799]) - `HashReader` and `HashWriter` are moved to the `digest-io` crate ([#1809]) - `io::Write/Read` implementations in favor of the `digest_io::IoWrapper` type ([#1809]) [#1173]: https://github.com/RustCrypto/traits/pull/1173 [#1334]: https://github.com/RustCrypto/traits/pull/1334 [#1759]: https://github.com/RustCrypto/traits/pull/1759 +[#1799]: https://github.com/RustCrypto/traits/pull/1799 [#1809]: https://github.com/RustCrypto/traits/pull/1809 +[#1820]: https://github.com/RustCrypto/traits/pull/1820 ## 0.10.7 (2023-05-19) ### Changed diff --git a/digest/Cargo.toml b/digest/Cargo.toml index db79a487d..895d1efe9 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -23,8 +23,8 @@ const-oid = { version = "0.10", optional = true } zeroize = { version = "1.7", optional = true, default-features = false } [features] -default = ["core-api"] -core-api = ["block-buffer"] # Enable Core API traits +default = ["block-api"] +block-api = ["block-buffer"] # Enable block API traits mac = ["subtle"] # Enable MAC traits rand_core = ["crypto-common/rand_core"] # Enable random key generation methods os_rng = ["crypto-common/rand_core", "rand_core"] diff --git a/digest/README.md b/digest/README.md index 5038829ad..e17da08b0 100644 --- a/digest/README.md +++ b/digest/README.md @@ -64,25 +64,6 @@ let hash = Sha256::digest(b"my message"); println!("Result: {:x}", hash); ``` -### Hashing `Read`-able objects - -If you want to hash data from [`Read`][3] trait (e.g. from file) you can rely on -implementation of [`Write`][4] trait (requires enabled-by-default `std` feature): - -```rust -use sha2::{Sha256, Digest}; -use std::{fs, io}; - -let mut file = fs::File::open(&path)?; -let mut hasher = Sha256::new(); -let n = io::copy(&mut file, &mut hasher)?; -let hash = hasher.finalize(); - -println!("Path: {}", path); -println!("Bytes processed: {}", n); -println!("Hash value: {:x}", hash); -``` - ### Generic code You can write generic code over `Digest` (or other traits from `digest` crate) diff --git a/digest/src/core_api.rs b/digest/src/block_api.rs similarity index 94% rename from digest/src/core_api.rs rename to digest/src/block_api.rs index 6e8b8def7..bdc70ab6c 100644 --- a/digest/src/core_api.rs +++ b/digest/src/block_api.rs @@ -5,20 +5,14 @@ //! higher-level traits. use crate::InvalidOutputSize; +pub use block_buffer::{Eager, Lazy}; pub use crypto_common::{AlgorithmName, Block, BlockSizeUser, OutputSizeUser, Reset}; use block_buffer::{BlockBuffer, BufferKind}; use crypto_common::Output; mod ct_variable; -mod rt_variable; -mod wrapper; -mod xof_reader; - -pub use ct_variable::CtVariableCoreWrapper; -pub use rt_variable::RtVariableCoreWrapper; -pub use wrapper::{CoreProxy, CoreWrapper}; -pub use xof_reader::XofReaderCoreWrapper; +pub use ct_variable::CtOutWrapper; /// Buffer type used by type which implements [`BufferKindUser`]. pub type Buffer = @@ -102,3 +96,9 @@ pub enum TruncSide { /// Truncate right side, i.e. `&out[m..]`. Right, } + +/// A proxy trait to a core type. +pub trait CoreProxy { + /// Wrapped block-level type. + type Core; +} diff --git a/digest/src/core_api/ct_variable.rs b/digest/src/block_api/ct_variable.rs similarity index 51% rename from digest/src/core_api/ct_variable.rs rename to digest/src/block_api/ct_variable.rs index 93ff2f96a..775dd3c34 100644 --- a/digest/src/core_api/ct_variable.rs +++ b/digest/src/block_api/ct_variable.rs @@ -5,8 +5,6 @@ use super::{ #[cfg(feature = "mac")] use crate::MacMarker; use crate::{CollisionResistance, CustomizedInit, HashMarker, VarOutputCustomized}; -#[cfg(feature = "oid")] -use const_oid::{AssociatedOid, ObjectIdentifier}; use core::{ fmt, marker::PhantomData, @@ -16,67 +14,55 @@ use crypto_common::{ Block, BlockSizeUser, OutputSizeUser, array::{Array, ArraySize}, hazmat::{DeserializeStateError, SerializableState, SerializedState, SubSerializedStateSize}, - typenum::{IsLess, IsLessOrEqual, Le, LeEq, NonZero, Sum, U1, U256}, + typenum::{IsLess, IsLessOrEqual, Le, NonZero, Sum, True, U1, U256}, }; -/// Dummy type used with [`CtVariableCoreWrapper`] in cases when -/// resulting hash does not have a known OID. -#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] -pub struct NoOid; - -/// Wrapper around [`VariableOutputCore`] which selects output size -/// at compile time. +/// Wrapper around [`VariableOutputCore`] which selects output size at compile time. #[derive(Clone)] -pub struct CtVariableCoreWrapper +pub struct CtOutWrapper where T: VariableOutputCore, - OutSize: ArraySize + IsLessOrEqual, - LeEq: NonZero, + OutSize: ArraySize + IsLessOrEqual, { inner: T, - _out: PhantomData<(OutSize, O)>, + _out: PhantomData, } -impl HashMarker for CtVariableCoreWrapper +impl HashMarker for CtOutWrapper where T: VariableOutputCore + HashMarker, - OutSize: ArraySize + IsLessOrEqual, - LeEq: NonZero, + OutSize: ArraySize + IsLessOrEqual, { } #[cfg(feature = "mac")] -impl MacMarker for CtVariableCoreWrapper +impl MacMarker for CtOutWrapper where T: VariableOutputCore + MacMarker, - OutSize: ArraySize + IsLessOrEqual, - LeEq: NonZero, + OutSize: ArraySize + IsLessOrEqual, { } -impl CollisionResistance for CtVariableCoreWrapper +impl CollisionResistance for CtOutWrapper where T: VariableOutputCore + CollisionResistance, - OutSize: ArraySize + IsLessOrEqual, - LeEq: NonZero, + OutSize: ArraySize + IsLessOrEqual, { type CollisionResistance = T::CollisionResistance; } -impl BlockSizeUser for CtVariableCoreWrapper +impl BlockSizeUser for CtOutWrapper where T: VariableOutputCore, - OutSize: ArraySize + IsLessOrEqual, - LeEq: NonZero, + OutSize: ArraySize + IsLessOrEqual, { type BlockSize = T::BlockSize; } -impl UpdateCore for CtVariableCoreWrapper +impl UpdateCore for CtOutWrapper where T: VariableOutputCore, - OutSize: ArraySize + IsLessOrEqual, - LeEq: NonZero, + OutSize: ArraySize + IsLessOrEqual, { #[inline] fn update_blocks(&mut self, blocks: &[Block]) { @@ -84,29 +70,26 @@ where } } -impl OutputSizeUser for CtVariableCoreWrapper +impl OutputSizeUser for CtOutWrapper where T: VariableOutputCore, - OutSize: ArraySize + IsLessOrEqual, - LeEq: NonZero, + OutSize: ArraySize + IsLessOrEqual, { type OutputSize = OutSize; } -impl BufferKindUser for CtVariableCoreWrapper +impl BufferKindUser for CtOutWrapper where T: VariableOutputCore, - OutSize: ArraySize + IsLessOrEqual, - LeEq: NonZero, + OutSize: ArraySize + IsLessOrEqual, { type BufferKind = T::BufferKind; } -impl FixedOutputCore for CtVariableCoreWrapper +impl FixedOutputCore for CtOutWrapper where T: VariableOutputCore, - OutSize: ArraySize + IsLessOrEqual, - LeEq: NonZero, + OutSize: ArraySize + IsLessOrEqual, { #[inline] fn finalize_fixed_core( @@ -125,11 +108,10 @@ where } } -impl Default for CtVariableCoreWrapper +impl Default for CtOutWrapper where T: VariableOutputCore, - OutSize: ArraySize + IsLessOrEqual, - LeEq: NonZero, + OutSize: ArraySize + IsLessOrEqual, { #[inline] fn default() -> Self { @@ -140,11 +122,10 @@ where } } -impl CustomizedInit for CtVariableCoreWrapper +impl CustomizedInit for CtOutWrapper where T: VariableOutputCore + VarOutputCustomized, - OutSize: ArraySize + IsLessOrEqual, - LeEq: NonZero, + OutSize: ArraySize + IsLessOrEqual, { #[inline] fn new_customized(customization: &[u8]) -> Self { @@ -155,11 +136,10 @@ where } } -impl Reset for CtVariableCoreWrapper +impl Reset for CtOutWrapper where T: VariableOutputCore, - OutSize: ArraySize + IsLessOrEqual, - LeEq: NonZero, + OutSize: ArraySize + IsLessOrEqual, { #[inline] fn reset(&mut self) { @@ -167,11 +147,10 @@ where } } -impl AlgorithmName for CtVariableCoreWrapper +impl AlgorithmName for CtOutWrapper where T: VariableOutputCore + AlgorithmName, - OutSize: ArraySize + IsLessOrEqual, - LeEq: NonZero, + OutSize: ArraySize + IsLessOrEqual, { fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { T::write_alg_name(f)?; @@ -180,61 +159,31 @@ where } } -#[cfg(feature = "oid")] -impl AssociatedOid for CtVariableCoreWrapper -where - T: VariableOutputCore, - O: AssociatedOid, - OutSize: ArraySize + IsLessOrEqual, - LeEq: NonZero, -{ - const OID: ObjectIdentifier = O::OID; -} - #[cfg(feature = "zeroize")] -impl zeroize::ZeroizeOnDrop for CtVariableCoreWrapper +impl zeroize::ZeroizeOnDrop for CtOutWrapper where T: VariableOutputCore + zeroize::ZeroizeOnDrop, - OutSize: ArraySize + IsLessOrEqual, - LeEq: NonZero, + OutSize: ArraySize + IsLessOrEqual, { } -impl fmt::Debug for CtVariableCoreWrapper +impl fmt::Debug for CtOutWrapper where T: VariableOutputCore + AlgorithmName, - OutSize: ArraySize + IsLessOrEqual, - LeEq: NonZero, + OutSize: ArraySize + IsLessOrEqual, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { Self::write_alg_name(f) } } -/// Implement dummy type with hidden docs which is used to "carry" hasher -/// OID for [`CtVariableCoreWrapper`]. -#[macro_export] -macro_rules! impl_oid_carrier { - ($name:ident, $oid:literal) => { - #[doc(hidden)] - #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] - pub struct $name; - - #[cfg(feature = "oid")] - impl AssociatedOid for $name { - const OID: ObjectIdentifier = ObjectIdentifier::new_unwrap($oid); - } - }; -} - type CtVariableCoreWrapperSerializedStateSize = Sum<::SerializedStateSize, U1>; -impl SerializableState for CtVariableCoreWrapper +impl SerializableState for CtOutWrapper where T: VariableOutputCore + SerializableState, - OutSize: ArraySize + IsLessOrEqual, - LeEq: NonZero, + OutSize: ArraySize + IsLessOrEqual, T::BlockSize: IsLess, Le: NonZero, T::SerializedStateSize: Add, diff --git a/digest/src/buffer_macros.rs b/digest/src/buffer_macros.rs new file mode 100644 index 000000000..f03fec8d8 --- /dev/null +++ b/digest/src/buffer_macros.rs @@ -0,0 +1,4 @@ +mod fixed; +mod variable_ct; +mod variable_rt; +mod xof; diff --git a/digest/src/buffer_macros/fixed.rs b/digest/src/buffer_macros/fixed.rs new file mode 100644 index 000000000..7d27d8906 --- /dev/null +++ b/digest/src/buffer_macros/fixed.rs @@ -0,0 +1,473 @@ +/// Creates a buffered wrapper around block-level "core" type which implements fixed output size traits. +#[macro_export] +macro_rules! buffer_fixed { + ( + $(#[$attr:meta])* + $v:vis struct $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); + impl: $($trait_name:ident)*; + ) => { + $(#[$attr])* + $v struct $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? { + core: $core_ty, + buffer: $crate::block_api::Buffer<$core_ty>, + } + + $crate::buffer_fixed!( + impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); + $($trait_name)*; + ); + }; + + ( + $(#[$attr:meta])* + $v:vis struct $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); + oid: $oid:literal; + impl: $($trait_name:ident)*; + ) => { + $crate::buffer_fixed!( + $(#[$attr])* + $v struct $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); + impl: $($trait_name)*; + ); + + #[cfg(feature = "oid")] + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::const_oid::AssociatedOid for $name$(< $( $lt ),+ >)? { + const OID: $crate::const_oid::ObjectIdentifier = + $crate::const_oid::ObjectIdentifier::new_unwrap($oid); + } + }; + + // Terminates `impl_inner` sequences. + ( + impl_inner: $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); + ; + ) => {}; + + // Implements the set of traits common for fixed output hashes: + // `Default`, `Clone`, `HashMarker`, `Reset`, `FixedOutputReset`, `SerializableState` + ( + impl_inner: $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); + FixedHashTraits $($trait_name:ident)*; + ) => { + $crate::buffer_fixed!( + impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); + BaseFixedTraits AlgorithmName Default Clone HashMarker + Reset FixedOutputReset SerializableState $($trait_name)*; + ); + }; + + // Implements the set of traits common for MAC functions: + // `Debug`, `BlockSizeUser`, `OutputSizeUser`, `CoreProxy`, `Update`, `FixedOutput`, + // `Clone`, `MacMarker`. + ( + impl_inner: $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); + MacTraits $($trait_name:ident)*; + ) => { + $crate::buffer_fixed!( + impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); + BaseFixedTraits Clone MacMarker $($trait_name)*; + ); + }; + + // Implements the set of traits common for resettable MAC functions: + // `Debug`, `BlockSizeUser`, `OutputSizeUser`, `CoreProxy`, `Update`, `FixedOutput`, + // `Clone`, `MacMarker`, `Reset`, `FixedOutputReset`. + ( + impl_inner: $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); + ResetMacTraits $($trait_name:ident)*; + ) => { + $crate::buffer_fixed!( + impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); + MacTraits Reset FixedOutputReset $($trait_name)*; + ); + }; + + // Implements basic fixed traits: + // `Debug`, `BlockSizeUser`, `OutputSizeUser`, `CoreProxy`, `Update`, and `FixedOutput`. + ( + impl_inner: $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); + BaseFixedTraits $($trait_name:ident)*; + ) => { + $crate::buffer_fixed!( + impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); + Debug BlockSizeUser OutputSizeUser CoreProxy Update FixedOutput $($trait_name)*; + ); + }; + + // Implements `Debug` + ( + impl_inner: $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); + Debug $($trait_name:ident)*; + ) => { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? core::fmt::Debug for $name$(< $( $lt ),+ >)? { + #[inline] + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str(concat!(stringify!($name), " { ... }")) + } + } + + $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;); + }; + + // Implements `AlgorithmName` + ( + impl_inner: $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); + AlgorithmName $($trait_name:ident)*; + ) => { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::crypto_common::AlgorithmName for $name$(< $( $lt ),+ >)? { + #[inline] + fn write_alg_name(f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { + <$core_ty as $crate::crypto_common::AlgorithmName>::write_alg_name(f) + } + } + + $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;); + }; + + // Implements `BlockSizeUser` + ( + impl_inner: $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); + BlockSizeUser $($trait_name:ident)*; + ) => { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::block_api::BlockSizeUser for $name$(< $( $lt ),+ >)? { + type BlockSize = <$core_ty as $crate::crypto_common::BlockSizeUser>::BlockSize; + } + + $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;); + }; + + // Implements `OutputSizeUser` + ( + impl_inner: $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); + OutputSizeUser $($trait_name:ident)*; + ) => { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::OutputSizeUser for $name$(< $( $lt ),+ >)? { + type OutputSize = <$core_ty as $crate::block_api::OutputSizeUser>::OutputSize; + } + + $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;); + }; + + // Implements `CoreProxy` + ( + impl_inner: $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); + CoreProxy $($trait_name:ident)*; + ) => { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::block_api::CoreProxy for $name$(< $( $lt ),+ >)? { + type Core = $core_ty; + } + + $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;); + }; + + // Implements `Update` + ( + impl_inner: $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); + Update $($trait_name:ident)*; + ) => { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::Update for $name$(< $( $lt ),+ >)? { + #[inline] + fn update(&mut self, data: &[u8]) { + let Self { core, buffer } = self; + buffer.digest_blocks(data, |blocks| { + $crate::block_api::UpdateCore::update_blocks(core, blocks) + }); + } + } + + $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;); + }; + + // Implements `FixedOutput` + ( + impl_inner: $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); + FixedOutput $($trait_name:ident)*; + ) => { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::FixedOutput for $name$(< $( $lt ),+ >)? { + #[inline] + fn finalize_into(mut self, out: &mut $crate::Output) { + let Self { core, buffer } = &mut self; + $crate::block_api::FixedOutputCore::finalize_fixed_core(core, buffer, out); + } + } + + $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;); + }; + + // Implements `Default` + ( + impl_inner: $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); + Default $($trait_name:ident)*; + ) => { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? Default for $name$(< $( $lt ),+ >)? { + #[inline] + fn default() -> Self { + Self { + core: Default::default(), + buffer: Default::default(), + } + } + } + + $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;); + }; + + // Implements `CustomizedInit` + ( + impl_inner: $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); + CustomizedInit $($trait_name:ident)*; + ) => { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::CustomizedInit for $name$(< $( $lt ),+ >)? { + #[inline] + fn new_customized(customization: &[u8]) -> Self { + Self { + core: $crate::CustomizedInit::new_customized(customization), + buffer: Default::default(), + } + } + } + + $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;); + }; + + // Implements `Clone` + ( + impl_inner: $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); + Clone $($trait_name:ident)*; + ) => { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? Clone for $name$(< $( $lt ),+ >)? { + #[inline] + fn clone(&self) -> Self { + Self { + core: Clone::clone(&self.core), + buffer: Clone::clone(&self.buffer), + } + } + } + + $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;); + }; + + // Implements `HashMarker` and asserts that `$core_ty` implements it + ( + impl_inner: $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); + HashMarker $($trait_name:ident)*; + ) => { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::HashMarker for $name$(< $( $lt ),+ >)? {} + + // Verify that `$core_ty` implements `HashMarker` + const _: () = { + fn check$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?(v: &$core_ty) { + v as &dyn $crate::HashMarker; + } + }; + + $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;); + }; + + // Implements `MacMarker` and asserts that `$core_ty` implements it + ( + impl_inner: $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); + MacMarker $($trait_name:ident)*; + ) => { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::MacMarker for $name$(< $( $lt ),+ >)? {} + + // Verify that `$core_ty` implements `MacMarker` + const _: () = { + fn check$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?(v: &$core_ty) { + v as &dyn $crate::MacMarker; + } + }; + + $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;); + }; + + // Implements `InnerUser` and `InnerInit` + ( + impl_inner: $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); + InnerInit $($trait_name:ident)*; + ) => { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::crypto_common::InnerUser for $name$(< $( $lt ),+ >)? { + type Inner = <$core_ty as $crate::crypto_common::InnerUser>::Inner; + } + + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::crypto_common::InnerInit for $name$(< $( $lt ),+ >)? { + #[inline] + fn inner_init(inner: Self::Inner) -> Self { + Self { + core: <$core_ty as $crate::crypto_common::InnerInit>::inner_init(inner), + buffer: Default::default(), + } + } + } + + $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;); + }; + + // Implements `KeySizeUser` and `KeyInit` + ( + impl_inner: $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); + KeyInit $($trait_name:ident)*; + ) => { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::crypto_common::KeySizeUser for $name$(< $( $lt ),+ >)? { + type KeySize = <$core_ty as $crate::crypto_common::KeySizeUser>::KeySize; + } + + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::KeyInit for $name$(< $( $lt ),+ >)? { + #[inline] + fn new(key: &$crate::Key) -> Self { + Self { + core: <$core_ty as $crate::KeyInit>::new(key), + buffer: Default::default(), + } + } + + #[inline] + fn new_from_slice(key: &[u8]) -> Result { + <$core_ty as $crate::KeyInit>::new_from_slice(key).map(|core| + Self { core, buffer: Default::default() } + ) + } + } + + $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;); + }; + + // Implements `Reset` + ( + impl_inner: $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); + Reset $($trait_name:ident)*; + ) => { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::Reset for $name$(< $( $lt ),+ >)? { + #[inline] + fn reset(&mut self) { + $crate::Reset::reset(&mut self.core); + self.buffer.reset(); + } + } + + $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;); + }; + + // Implements `FixedOutputReset` + ( + impl_inner: $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); + FixedOutputReset $($trait_name:ident)*; + ) => { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::FixedOutputReset for $name$(< $( $lt ),+ >)? { + #[inline] + fn finalize_into_reset(&mut self, out: &mut $crate::Output) { + let Self { core, buffer } = self; + $crate::block_api::FixedOutputCore::finalize_fixed_core(core, buffer, out); + $crate::Reset::reset(self); + } + } + + $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;); + }; + + // Implements `SerializableState` + ( + impl_inner: $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); + SerializableState $($trait_name:ident)*; + ) => { + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::crypto_common::hazmat::SerializableState for $name$(< $( $lt ),+ >)? { + type SerializedStateSize = $crate::typenum::Sum< + <$core_ty as $crate::crypto_common::hazmat::SerializableState>::SerializedStateSize, + $crate::typenum::Add1< + <$core_ty as $crate::block_api::BlockSizeUser>::BlockSize + > + >; + + #[inline] + fn serialize(&self) -> $crate::crypto_common::hazmat::SerializedState { + use $crate::{ + array::Array, + consts::U1, + block_buffer::BlockBuffer, + crypto_common::hazmat::SerializableState, + }; + + let serialized_core = self.core.serialize(); + let pos = u8::try_from(self.buffer.get_pos()).unwrap(); + let serialized_pos: Array = Array([pos]); + let serialized_data = self.buffer.clone().pad_with_zeros(); + + serialized_core + .concat(serialized_pos) + .concat(serialized_data) + } + + #[inline] + fn deserialize( + serialized_state: &$crate::crypto_common::hazmat::SerializedState, + ) -> Result { + use $crate::{ + block_buffer::BlockBuffer, + consts::U1, + crypto_common::hazmat::{SerializableState, DeserializeStateError}, + }; + + let (serialized_core, remaining_buffer) = serialized_state + .split_ref::<<$core_ty as SerializableState>::SerializedStateSize>(); + let (serialized_pos, serialized_data) = remaining_buffer.split_ref::(); + + Ok(Self { + core: <$core_ty as SerializableState>::deserialize(serialized_core)?, + buffer: BlockBuffer::try_new(&serialized_data[..serialized_pos[0].into()]) + .map_err(|_| DeserializeStateError)?, + }) + } + } + + $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;); + } +} diff --git a/digest/src/buffer_macros/variable_ct.rs b/digest/src/buffer_macros/variable_ct.rs new file mode 100644 index 000000000..1399ec084 --- /dev/null +++ b/digest/src/buffer_macros/variable_ct.rs @@ -0,0 +1,226 @@ +/// Creates a buffered wrapper around block-level "core" type which implements variable output size traits +/// with output size selected at compile time. +#[macro_export] +macro_rules! buffer_ct_variable { + ( + $(#[$attr:meta])* + $vis:vis struct $name:ident<$out_size:ident>($core_ty:ty); + exclude: SerializableState; + // Ideally, we would use `$core_ty::OutputSize`, but unfortunately the compiler + // does not accept such code. The likely reason is this issue: + // https://github.com/rust-lang/rust/issues/79629 + max_size: $max_size:ty; + ) => { + $(#[$attr])* + $vis struct $name<$out_size> + where + $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size, Output = $crate::typenum::True>, + { + core: $crate::block_api::CtOutWrapper<$core_ty, $out_size>, + buffer: $crate::block_api::Buffer<$core_ty>, + } + + impl<$out_size> core::fmt::Debug for $name<$out_size> + where + $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size, Output = $crate::typenum::True>, + { + #[inline] + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str(concat!(stringify!($name), " { ... }")) + } + } + + impl<$out_size> $crate::crypto_common::AlgorithmName for $name<$out_size> + where + $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size, Output = $crate::typenum::True>, + { + #[inline] + fn write_alg_name(f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { + <$core_ty as $crate::crypto_common::AlgorithmName>::write_alg_name(f) + } + } + + impl<$out_size> Clone for $name<$out_size> + where + $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size, Output = $crate::typenum::True>, + { + #[inline] + fn clone(&self) -> Self { + Self { + core: Clone::clone(&self.core), + buffer: Clone::clone(&self.buffer), + } + } + } + + impl<$out_size> Default for $name<$out_size> + where + $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size, Output = $crate::typenum::True>, + { + #[inline] + fn default() -> Self { + Self { + core: Default::default(), + buffer: Default::default(), + } + } + } + + impl<$out_size> $crate::Reset for $name<$out_size> + where + $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size, Output = $crate::typenum::True>, + { + #[inline] + fn reset(&mut self) { + $crate::Reset::reset(&mut self.core); + self.buffer.reset(); + } + } + + impl<$out_size> $crate::block_api::BlockSizeUser for $name<$out_size> + where + $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size, Output = $crate::typenum::True>, + { + type BlockSize = <$core_ty as $crate::crypto_common::BlockSizeUser>::BlockSize; + } + + impl<$out_size> $crate::OutputSizeUser for $name<$out_size> + where + $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size, Output = $crate::typenum::True>, + { + type OutputSize = $out_size; + } + + impl<$out_size> $crate::HashMarker for $name<$out_size> + where + $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size, Output = $crate::typenum::True>, + {} + + // Verify that `$wrapped_ty` implements `HashMarker` + const _: () = { + fn check<$out_size>(v: &$core_ty) + where + $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size>, + $crate::typenum::LeEq<$out_size, $max_size>: $crate::typenum::NonZero, + { + v as &dyn $crate::HashMarker; + } + }; + + impl<$out_size> $crate::block_api::CoreProxy for $name<$out_size> + where + $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size, Output = $crate::typenum::True>, + { + type Core = $crate::block_api::CtOutWrapper<$core_ty, $out_size>; + } + + impl<$out_size> $crate::Update for $name<$out_size> + where + $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size, Output = $crate::typenum::True>, + { + #[inline] + fn update(&mut self, data: &[u8]) { + let Self { core, buffer } = self; + buffer.digest_blocks(data, |blocks| { + $crate::block_api::UpdateCore::update_blocks(core, blocks) + }); + } + } + + impl<$out_size> $crate::FixedOutput for $name<$out_size> + where + $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size, Output = $crate::typenum::True>, + { + #[inline] + fn finalize_into(mut self, out: &mut $crate::Output) { + let Self { core, buffer } = &mut self; + $crate::block_api::FixedOutputCore::finalize_fixed_core(core, buffer, out); + } + } + + impl<$out_size> $crate::FixedOutputReset for $name<$out_size> + where + $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size, Output = $crate::typenum::True>, + { + #[inline] + fn finalize_into_reset(&mut self, out: &mut $crate::Output) { + let Self { core, buffer } = self; + $crate::block_api::FixedOutputCore::finalize_fixed_core(core, buffer, out); + $crate::Reset::reset(self); + } + } + }; + ( + $(#[$attr:meta])* + $vis:vis struct $name:ident<$out_size:ident>($core_ty:ty); + // Ideally, we would use `$core_ty::OutputSize`, but unfortunately the compiler + // does not accept such code. The likely reason is this issue: + // https://github.com/rust-lang/rust/issues/79629 + max_size: $max_size:ty; + ) => { + $crate::buffer_ct_variable!( + $(#[$attr])* + $vis struct $name<$out_size>($core_ty); + exclude: SerializableState; + max_size: $max_size; + ); + + impl<$out_size> $crate::crypto_common::hazmat::SerializableState for $name<$out_size> + where + $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size, Output = $crate::typenum::True>, + { + type SerializedStateSize = $crate::typenum::Add1<$crate::typenum::Sum< + < + $crate::block_api::CtOutWrapper<$core_ty, $out_size> + as $crate::crypto_common::hazmat::SerializableState + >::SerializedStateSize, + <$core_ty as $crate::block_api::BlockSizeUser>::BlockSize, + >>; + + #[inline] + fn serialize(&self) -> $crate::crypto_common::hazmat::SerializedState { + use $crate::{ + array::Array, + consts::U1, + block_buffer::BlockBuffer, + crypto_common::hazmat::SerializableState, + }; + + let serialized_core = self.core.serialize(); + let pos = u8::try_from(self.buffer.get_pos()).unwrap(); + let serialized_pos: Array = Array([pos]); + let serialized_data = self.buffer.clone().pad_with_zeros(); + + serialized_core + .concat(serialized_pos) + .concat(serialized_data) + } + + #[inline] + fn deserialize( + serialized_state: &$crate::crypto_common::hazmat::SerializedState, + ) -> Result { + use $crate::{ + block_buffer::BlockBuffer, + consts::U1, + block_api::CtOutWrapper, + crypto_common::hazmat::{SerializableState, DeserializeStateError}, + }; + + let (serialized_core, remaining_buffer) = serialized_state + .split_ref::<< + CtOutWrapper<$core_ty, $out_size> + as SerializableState + >::SerializedStateSize>(); + let (serialized_pos, serialized_data) = remaining_buffer.split_ref::(); + + let core = SerializableState::deserialize(serialized_core)?; + let pos = usize::from(serialized_pos[0]); + let buffer = BlockBuffer::try_new(&serialized_data[..pos]) + .map_err(|_| DeserializeStateError)?; + + Ok(Self { core, buffer }) + } + } + }; +} diff --git a/digest/src/buffer_macros/variable_rt.rs b/digest/src/buffer_macros/variable_rt.rs new file mode 100644 index 000000000..e39ff5adb --- /dev/null +++ b/digest/src/buffer_macros/variable_rt.rs @@ -0,0 +1,188 @@ +/// Creates a buffered wrapper around block-level "core" type which implements variable output size traits +/// with output size selected at run time. +#[macro_export] +macro_rules! buffer_rt_variable { + ( + $(#[$attr:meta])* + $vis:vis struct $name:ident($core_ty:ty); + exclude: SerializableState; + ) => { + $(#[$attr])* + $vis struct $name { + core: $core_ty, + buffer: $crate::block_api::Buffer<$core_ty>, + output_size: u8, + } + + impl core::fmt::Debug for $name { + #[inline] + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str(concat!(stringify!($name), " { ... }")) + } + } + + impl $crate::crypto_common::AlgorithmName for $name { + #[inline] + fn write_alg_name(f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { + <$core_ty as $crate::crypto_common::AlgorithmName>::write_alg_name(f) + } + } + + impl Clone for $name { + #[inline] + fn clone(&self) -> Self { + Self { + core: Clone::clone(&self.core), + buffer: Clone::clone(&self.buffer), + output_size: self.output_size, + } + } + } + + impl $crate::Reset for $name { + #[inline] + fn reset(&mut self) { + let size = self.output_size.into(); + self.core = <$core_ty as $crate::block_api::VariableOutputCore>::new(size).unwrap(); + self.buffer.reset(); + } + } + + impl $crate::block_api::BlockSizeUser for $name { + type BlockSize = <$core_ty as $crate::crypto_common::BlockSizeUser>::BlockSize; + } + + impl $crate::HashMarker for $name {} + + // Verify that `$wrapped_ty` implements `HashMarker` + const _: () = { + fn check(v: &$core_ty) { + v as &dyn $crate::HashMarker; + } + }; + + impl $crate::Update for $name { + #[inline] + fn update(&mut self, data: &[u8]) { + let Self { core, buffer, .. } = self; + buffer.digest_blocks(data, |blocks| { + $crate::block_api::UpdateCore::update_blocks(core, blocks); + }); + } + } + + impl $name { + #[inline] + fn finalize_dirty(&mut self, out: &mut [u8]) -> Result<(), $crate::InvalidBufferSize> { + let Self { + core, + buffer, + output_size, + } = self; + let size_u8 = u8::try_from(out.len()).map_err(|_| $crate::InvalidBufferSize)?; + + let max_size = ::MAX_OUTPUT_SIZE; + if out.len() > max_size || size_u8 != *output_size { + return Err($crate::InvalidBufferSize); + } + let mut full_res = Default::default(); + $crate::block_api::VariableOutputCore::finalize_variable_core(core, buffer, &mut full_res); + let n = out.len(); + let m = full_res.len() - n; + use $crate::block_api::TruncSide::{Left, Right}; + let side = <$core_ty as $crate::block_api::VariableOutputCore>::TRUNC_SIDE; + match side { + Left => out.copy_from_slice(&full_res[..n]), + Right => out.copy_from_slice(&full_res[m..]), + } + Ok(()) + } + } + + impl $crate::VariableOutput for $name { + const MAX_OUTPUT_SIZE: usize = < + <$core_ty as $crate::block_api::OutputSizeUser>::OutputSize + as $crate::typenum::Unsigned + >::USIZE; + + #[inline] + fn new(output_size: usize) -> Result { + let output_size = u8::try_from(output_size).map_err(|_| $crate::InvalidOutputSize)?; + let buffer = Default::default(); + let core = <$core_ty as $crate::block_api::VariableOutputCore>::new(output_size.into())?; + Ok(Self { + core, + buffer, + output_size, + }) + } + + #[inline] + fn output_size(&self) -> usize { + self.output_size.into() + } + + #[inline] + fn finalize_variable(mut self, out: &mut [u8]) -> Result<(), $crate::InvalidBufferSize> { + self.finalize_dirty(out) + } + } + + impl $crate::VariableOutputReset for $name { + #[inline] + fn finalize_variable_reset( + &mut self, + out: &mut [u8], + ) -> Result<(), $crate::InvalidBufferSize> { + self.finalize_dirty(out)?; + $crate::Reset::reset(self); + Ok(()) + } + } + + impl Drop for $name { + #[inline] + fn drop(&mut self) { + #[cfg(feature = "zeroize")] + { + use $crate::zeroize::Zeroize; + self.buffer.zeroize(); + self.output_size.zeroize(); + } + } + } + + #[cfg(feature = "zeroize")] + impl $crate::zeroize::ZeroizeOnDrop for $name {} + }; + + ( + $(#[$attr:meta])* + $vis:vis struct $name:ident($core_ty:ty); + ) => { + $crate::buffer_rt_variable!( + $(#[$attr])* + $vis struct $name($core_ty); + exclude: SerializableState; + ); + + impl $crate::crypto_common::hazmat::SerializableState for $name { + type SerializedStateSize = $crate::typenum::Add1<$crate::typenum::Sum< + <$core_ty as $crate::crypto_common::hazmat::SerializableState>::SerializedStateSize, + <$core_ty as $crate::block_api::BlockSizeUser>::BlockSize, + >>; + + #[inline] + fn serialize(&self) -> $crate::crypto_common::hazmat::SerializedState { + todo!() + } + + #[inline] + fn deserialize( + serialized_state: &$crate::crypto_common::hazmat::SerializedState, + ) -> Result { + todo!() + } + } + }; +} diff --git a/digest/src/buffer_macros/xof.rs b/digest/src/buffer_macros/xof.rs new file mode 100644 index 000000000..dd635332c --- /dev/null +++ b/digest/src/buffer_macros/xof.rs @@ -0,0 +1,328 @@ +/// Creates a buffered wrapper around block-level "core" type which implements extendable output size traits. +#[macro_export] +macro_rules! buffer_xof { + ( + $(#[$hasher_attr:meta])* + $hasher_vis:vis struct $hasher_name:ident($hasher_core:ty); + $(oid: $oid:literal;)? + impl: $($hasher_trait_name:ident)*; + + $(#[$reader_attr:meta])* + $reader_vis:vis struct $reader_name:ident($reader_core:ty); + impl: $($reader_trait_name:ident)*; + ) => { + $(#[$hasher_attr])* + $hasher_vis struct $hasher_name { + core: $hasher_core, + buffer: $crate::block_api::Buffer<$hasher_core>, + } + + impl $crate::ExtendableOutput for $hasher_name { + type Reader = $reader_name; + + #[inline] + fn finalize_xof(mut self) -> Self::Reader { + let Self { core, buffer } = &mut self; + let core = <$hasher_core as $crate::block_api::ExtendableOutputCore>::finalize_xof_core(core, buffer); + let buffer = Default::default(); + Self::Reader { core, buffer } + } + } + + $( + #[cfg(feature = "oid")] + impl $crate::const_oid::AssociatedOid for $hasher_name { + const OID: $crate::const_oid::ObjectIdentifier = + $crate::const_oid::ObjectIdentifier::new_unwrap($oid); + } + )? + + $crate::buffer_xof!( + impl_inner: $hasher_name($hasher_core); + $($hasher_trait_name)*; + ); + + $(#[$reader_attr])* + $reader_vis struct $reader_name { + core: $reader_core, + buffer: $crate::block_buffer::ReadBuffer<<$reader_core as $crate::block_api::BlockSizeUser>::BlockSize>, + } + + impl $crate::XofReader for $reader_name { + #[inline] + fn read(&mut self, buf: &mut [u8]) { + let Self { core, buffer } = self; + buffer.read(buf, |block| { + *block = $crate::block_api::XofReaderCore::read_block(core); + }); + } + } + + $crate::buffer_xof!( + impl_inner: $reader_name($reader_core); + $($reader_trait_name)*; + ); + }; + + // Terminates `impl_inner` sequences. + ( + impl_inner: $name:ident($core_ty:ty); ; + ) => {}; + + // Implements the set of traits common for XOF hashers + ( + impl_inner: $name:ident($core_ty:ty); + XofHasherTraits $($trait_name:ident)*; + ) => { + $crate::buffer_xof!( + impl_inner: $name($core_ty); + Debug AlgorithmName Clone Default BlockSizeUser CoreProxy HashMarker Update SerializableState Reset ExtendableOutputReset $($trait_name)* ; + ); + }; + + // Implements the set of traits common for XOF readers + ( + impl_inner: $name:ident($core_ty:ty); + XofReaderTraits $($trait_name:ident)*; + ) => { + $crate::buffer_xof!( + impl_inner: $name($core_ty); + Debug Clone BlockSizeUser CoreProxy + $($trait_name)*;); + }; + + // Implements `Debug` + ( + impl_inner: $name:ident($core_ty:ty); + Debug $($trait_name:ident)*; + ) => { + impl core::fmt::Debug for $name { + #[inline] + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str(concat!(stringify!($name), " { ... }")) + } + } + + $crate::buffer_xof!(impl_inner: $name($core_ty); $($trait_name)*;); + }; + + // Implements `AlgorithmName` + ( + impl_inner: $name:ident($core_ty:ty); + AlgorithmName $($trait_name:ident)*; + ) => { + impl $crate::crypto_common::AlgorithmName for $name { + #[inline] + fn write_alg_name(f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { + <$core_ty as $crate::crypto_common::AlgorithmName>::write_alg_name(f) + } + } + + $crate::buffer_xof!(impl_inner: $name($core_ty); $($trait_name)*;); + }; + + // Implements `Default` + ( + impl_inner: $name:ident($core_ty:ty); + Default $($trait_name:ident)*; + ) => { + impl Default for $name { + #[inline] + fn default() -> Self { + Self { + core: Default::default(), + buffer: Default::default(), + } + } + } + + $crate::buffer_xof!(impl_inner: $name($core_ty); $($trait_name)*;); + }; + + // Implements `CustomizedInit` + ( + impl_inner: $name:ident($core_ty:ty); + CustomizedInit $($trait_name:ident)*; + ) => { + impl $crate::CustomizedInit for $name { + #[inline] + fn new_customized(customization: &[u8]) -> Self { + Self { + core: $crate::CustomizedInit::new_customized(customization), + buffer: Default::default(), + } + } + } + + $crate::buffer_xof!(impl_inner: $name($core_ty); $($trait_name)*;); + }; + + // Implements `Clone` + ( + impl_inner: $name:ident($core_ty:ty); + Clone $($trait_name:ident)*; + ) => { + impl Clone for $name { + #[inline] + fn clone(&self) -> Self { + Self { + core: Clone::clone(&self.core), + buffer: Clone::clone(&self.buffer), + } + } + } + + $crate::buffer_xof!(impl_inner: $name($core_ty); $($trait_name)*;); + }; + + // Implements `BlockSizeUser` + ( + impl_inner: $name:ident($core_ty:ty); + BlockSizeUser $($trait_name:ident)*; + ) => { + impl $crate::block_api::BlockSizeUser for $name { + type BlockSize = <$core_ty as $crate::crypto_common::BlockSizeUser>::BlockSize; + } + + $crate::buffer_xof!(impl_inner: $name($core_ty); $($trait_name)*;); + }; + + // Implements `CoreProxy` + ( + impl_inner: $name:ident($core_ty:ty); + CoreProxy $($trait_name:ident)*; + ) => { + impl $crate::block_api::CoreProxy for $name { + type Core = $core_ty; + } + + $crate::buffer_xof!(impl_inner: $name($core_ty); $($trait_name)*;); + }; + + // Implements `HashMarker` + ( + impl_inner: $name:ident($core_ty:ty); + HashMarker $($trait_name:ident)*; + ) => { + impl $crate::HashMarker for $name {} + + // Verify that `$core_ty` implements `HashMarker` + const _: () = { + fn check(v: &$core_ty) { + v as &dyn $crate::HashMarker; + } + }; + + $crate::buffer_xof!(impl_inner: $name($core_ty); $($trait_name)*;); + }; + + // Implements `Update` + ( + impl_inner: $name:ident($core_ty:ty); + Update $($trait_name:ident)*; + ) => { + impl $crate::Update for $name { + #[inline] + fn update(&mut self, data: &[u8]) { + let Self { core, buffer } = self; + buffer.digest_blocks(data, |blocks| { + $crate::block_api::UpdateCore::update_blocks(core, blocks) + }); + } + } + + $crate::buffer_xof!(impl_inner: $name($core_ty); $($trait_name)*;); + }; + + // Implements `Reset` + ( + impl_inner: $name:ident($core_ty:ty); + Reset $($trait_name:ident)*; + ) => { + impl $crate::Reset for $name { + #[inline] + fn reset(&mut self) { + $crate::Reset::reset(&mut self.core); + self.buffer.reset(); + } + } + + $crate::buffer_xof!(impl_inner: $name($core_ty); $($trait_name)*;); + }; + + // Implements `ExtendableOutputReset` + ( + impl_inner: $name:ident($core_ty:ty); + ExtendableOutputReset $($trait_name:ident)*; + ) => { + impl $crate::ExtendableOutputReset for $name { + #[inline] + fn finalize_xof_reset(&mut self) -> Self::Reader { + let Self { core, buffer } = self; + let core = <$core_ty as $crate::block_api::ExtendableOutputCore>::finalize_xof_core(core, buffer); + $crate::Reset::reset(self); + let buffer = Default::default(); + Self::Reader { core, buffer } + } + } + + $crate::buffer_xof!(impl_inner: $name($core_ty); $($trait_name)*;); + }; + + // Implements `SerializableState` + ( + impl_inner: $name:ident($core_ty:ty); + SerializableState $($trait_name:ident)*; + ) => { + impl $crate::crypto_common::hazmat::SerializableState for $name { + type SerializedStateSize = $crate::typenum::Sum< + <$core_ty as $crate::crypto_common::hazmat::SerializableState>::SerializedStateSize, + $crate::typenum::Add1< + <$core_ty as $crate::block_api::BlockSizeUser>::BlockSize + > + >; + + #[inline] + fn serialize(&self) -> $crate::crypto_common::hazmat::SerializedState { + use $crate::{ + array::Array, + consts::U1, + block_buffer::BlockBuffer, + crypto_common::hazmat::SerializableState, + }; + + let serialized_core = self.core.serialize(); + let pos = u8::try_from(self.buffer.get_pos()).unwrap(); + let serialized_pos: Array = Array([pos]); + let serialized_data = self.buffer.clone().pad_with_zeros(); + + serialized_core + .concat(serialized_pos) + .concat(serialized_data) + } + + #[inline] + fn deserialize( + serialized_state: &$crate::crypto_common::hazmat::SerializedState, + ) -> Result { + use $crate::{ + block_buffer::BlockBuffer, + consts::U1, + crypto_common::hazmat::{SerializableState, DeserializeStateError}, + }; + + let (serialized_core, remaining_buffer) = serialized_state + .split_ref::<<$core_ty as SerializableState>::SerializedStateSize>(); + let (serialized_pos, serialized_data) = remaining_buffer.split_ref::(); + + Ok(Self { + core: <$core_ty as SerializableState>::deserialize(serialized_core)?, + buffer: BlockBuffer::try_new(&serialized_data[..serialized_pos[0].into()]) + .map_err(|_| DeserializeStateError)?, + }) + } + } + + $crate::buffer_xof!(impl_inner: $name($core_ty); $($trait_name)*;); + }; +} diff --git a/digest/src/core_api/rt_variable.rs b/digest/src/core_api/rt_variable.rs deleted file mode 100644 index 6b69f09d9..000000000 --- a/digest/src/core_api/rt_variable.rs +++ /dev/null @@ -1,190 +0,0 @@ -use super::{AlgorithmName, BlockSizeUser, TruncSide, VariableOutputCore}; -#[cfg(feature = "mac")] -use crate::MacMarker; -use crate::{CollisionResistance, HashMarker, InvalidBufferSize}; -use crate::{InvalidOutputSize, Reset, Update, VariableOutput, VariableOutputReset}; -use block_buffer::BlockBuffer; -use core::{ - convert::TryInto, - fmt, - ops::{Add, Sub}, -}; -use crypto_common::{ - AddBlockSize, SubBlockSize, - array::{Array, ArraySize}, - hazmat::{DeserializeStateError, SerializableState, SerializedState, SubSerializedStateSize}, - typenum::{Diff, IsLess, Le, NonZero, Sum, U1, U256, Unsigned}, -}; -#[cfg(feature = "zeroize")] -use zeroize::ZeroizeOnDrop; - -/// Wrapper around [`VariableOutputCore`] which selects output size -/// at run time. -#[derive(Clone)] -pub struct RtVariableCoreWrapper { - core: T, - buffer: BlockBuffer, - output_size: u8, -} - -impl RtVariableCoreWrapper { - #[inline] - fn finalize_dirty(&mut self, out: &mut [u8]) -> Result<(), InvalidBufferSize> { - let Self { - core, - buffer, - output_size, - } = self; - let size_u8 = u8::try_from(out.len()).map_err(|_| InvalidBufferSize)?; - if out.len() > Self::MAX_OUTPUT_SIZE || size_u8 != *output_size { - return Err(InvalidBufferSize); - } - let mut full_res = Default::default(); - core.finalize_variable_core(buffer, &mut full_res); - let n = out.len(); - let m = full_res.len() - n; - match T::TRUNC_SIDE { - TruncSide::Left => out.copy_from_slice(&full_res[..n]), - TruncSide::Right => out.copy_from_slice(&full_res[m..]), - } - Ok(()) - } -} - -impl HashMarker for RtVariableCoreWrapper {} - -#[cfg(feature = "mac")] -impl MacMarker for RtVariableCoreWrapper {} - -impl CollisionResistance for RtVariableCoreWrapper { - type CollisionResistance = T::CollisionResistance; -} - -impl BlockSizeUser for RtVariableCoreWrapper { - type BlockSize = T::BlockSize; -} - -impl Reset for RtVariableCoreWrapper { - #[inline] - fn reset(&mut self) { - self.buffer.reset(); - self.core.reset(); - } -} - -impl Update for RtVariableCoreWrapper { - #[inline] - fn update(&mut self, input: &[u8]) { - let Self { core, buffer, .. } = self; - buffer.digest_blocks(input, |blocks| core.update_blocks(blocks)); - } -} - -impl VariableOutput for RtVariableCoreWrapper { - const MAX_OUTPUT_SIZE: usize = T::OutputSize::USIZE; - - #[inline] - fn new(output_size: usize) -> Result { - let output_size = u8::try_from(output_size).map_err(|_| InvalidOutputSize)?; - let buffer = Default::default(); - T::new(output_size.into()).map(|core| Self { - core, - buffer, - output_size, - }) - } - - #[inline] - fn output_size(&self) -> usize { - self.output_size.into() - } - - #[inline] - fn finalize_variable(mut self, out: &mut [u8]) -> Result<(), InvalidBufferSize> { - self.finalize_dirty(out) - } -} - -impl VariableOutputReset for RtVariableCoreWrapper { - #[inline] - fn finalize_variable_reset(&mut self, out: &mut [u8]) -> Result<(), InvalidBufferSize> { - self.finalize_dirty(out)?; - self.core.reset(); - self.buffer.reset(); - Ok(()) - } -} - -impl Drop for RtVariableCoreWrapper { - #[inline] - fn drop(&mut self) { - #[cfg(feature = "zeroize")] - { - use zeroize::Zeroize; - self.buffer.zeroize(); - self.output_size.zeroize(); - } - } -} - -#[cfg(feature = "zeroize")] -impl ZeroizeOnDrop for RtVariableCoreWrapper {} - -impl fmt::Debug for RtVariableCoreWrapper { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - T::write_alg_name(f)?; - f.write_str(" { .. }") - } -} - -type RtVariableCoreWrapperSerializedStateSize = - Sum::SerializedStateSize, U1>, T>, U1>; - -impl SerializableState for RtVariableCoreWrapper -where - T: VariableOutputCore + SerializableState, - T::BlockSize: IsLess, - Le: NonZero, - T::SerializedStateSize: Add, - Sum: Add + ArraySize, - AddBlockSize, T>: Add + ArraySize, - RtVariableCoreWrapperSerializedStateSize: Sub + ArraySize, - SubSerializedStateSize, T>: Sub + ArraySize, - Diff, T>, U1>: - Sub + ArraySize, - SubBlockSize< - Diff, T>, U1>, - T, - >: ArraySize, -{ - type SerializedStateSize = RtVariableCoreWrapperSerializedStateSize; - - fn serialize(&self) -> SerializedState { - let serialized_core = self.core.serialize(); - let serialized_pos = Array([self.buffer.get_pos().try_into().unwrap()]); - let serialized_data = self.buffer.clone().pad_with_zeros(); - let serialized_output_size = Array([self.output_size]); - - serialized_core - .concat(serialized_pos) - .concat(serialized_data) - .concat(serialized_output_size) - } - - fn deserialize( - serialized_state: &SerializedState, - ) -> Result { - let (serialized_core, remaining_buffer) = - serialized_state.split_ref::(); - let (serialized_pos, remaining_buffer) = remaining_buffer.split_ref::(); - let (serialized_data, serialized_output_size) = - remaining_buffer.split_ref::(); - - Ok(Self { - core: T::deserialize(serialized_core)?, - buffer: BlockBuffer::try_new(&serialized_data[..serialized_pos[0].into()]) - .map_err(|_| DeserializeStateError)?, - output_size: serialized_output_size[0], - }) - } -} diff --git a/digest/src/core_api/wrapper.rs b/digest/src/core_api/wrapper.rs deleted file mode 100644 index c7368d8a2..000000000 --- a/digest/src/core_api/wrapper.rs +++ /dev/null @@ -1,243 +0,0 @@ -use super::{ - AlgorithmName, BufferKindUser, ExtendableOutputCore, FixedOutputCore, OutputSizeUser, Reset, - UpdateCore, XofReaderCoreWrapper, -}; -use crate::{ - CollisionResistance, CustomizedInit, ExtendableOutput, ExtendableOutputReset, FixedOutput, - FixedOutputReset, HashMarker, Update, -}; -use block_buffer::BlockBuffer; -use core::{ - convert::TryInto, - fmt, - ops::{Add, Sub}, -}; -use crypto_common::{ - BlockSizeUser, InvalidLength, Key, KeyInit, KeySizeUser, Output, - array::{Array, ArraySize}, - hazmat::{DeserializeStateError, SerializableState, SerializedState, SubSerializedStateSize}, - typenum::{Diff, IsLess, Le, NonZero, Sum, U1, U256}, -}; - -#[cfg(feature = "mac")] -use crate::MacMarker; -#[cfg(feature = "oid")] -use const_oid::{AssociatedOid, ObjectIdentifier}; - -/// Wrapper around [`BufferKindUser`]. -/// -/// It handles data buffering and implements the slice-based traits. -#[derive(Clone, Default)] -pub struct CoreWrapper { - core: T, - buffer: BlockBuffer, -} - -impl HashMarker for CoreWrapper {} - -#[cfg(feature = "mac")] -impl MacMarker for CoreWrapper {} - -impl CollisionResistance for CoreWrapper { - type CollisionResistance = T::CollisionResistance; -} - -// this blanket impl is needed for HMAC -impl BlockSizeUser for CoreWrapper { - type BlockSize = T::BlockSize; -} - -impl CoreWrapper { - /// Create new wrapper from `core`. - #[inline] - pub fn from_core(core: T) -> Self { - let buffer = Default::default(); - Self { core, buffer } - } -} - -impl KeySizeUser for CoreWrapper { - type KeySize = T::KeySize; -} - -impl KeyInit for CoreWrapper { - #[inline] - fn new(key: &Key) -> Self { - Self { - core: T::new(key), - buffer: Default::default(), - } - } - - #[inline] - fn new_from_slice(key: &[u8]) -> Result { - Ok(Self { - core: T::new_from_slice(key)?, - buffer: Default::default(), - }) - } -} - -impl fmt::Debug for CoreWrapper { - #[inline] - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - T::write_alg_name(f)?; - f.write_str(" { .. }") - } -} - -impl Reset for CoreWrapper { - #[inline] - fn reset(&mut self) { - self.core.reset(); - self.buffer.reset(); - } -} - -impl Update for CoreWrapper { - #[inline] - fn update(&mut self, input: &[u8]) { - let Self { core, buffer } = self; - buffer.digest_blocks(input, |blocks| core.update_blocks(blocks)); - } -} - -impl OutputSizeUser for CoreWrapper { - type OutputSize = T::OutputSize; -} - -impl FixedOutput for CoreWrapper { - #[inline] - fn finalize_into(mut self, out: &mut Output) { - let Self { core, buffer } = &mut self; - core.finalize_fixed_core(buffer, out); - } -} - -impl FixedOutputReset for CoreWrapper { - #[inline] - fn finalize_into_reset(&mut self, out: &mut Output) { - let Self { core, buffer } = self; - core.finalize_fixed_core(buffer, out); - core.reset(); - buffer.reset(); - } -} - -impl ExtendableOutput for CoreWrapper { - type Reader = XofReaderCoreWrapper; - - #[inline] - fn finalize_xof(mut self) -> Self::Reader { - Self::Reader { - core: self.core.finalize_xof_core(&mut self.buffer), - buffer: Default::default(), - } - } -} - -impl ExtendableOutputReset for CoreWrapper { - #[inline] - fn finalize_xof_reset(&mut self) -> Self::Reader { - let Self { core, buffer } = self; - let reader_core = core.finalize_xof_core(buffer); - core.reset(); - buffer.reset(); - let buffer = Default::default(); - Self::Reader { - core: reader_core, - buffer, - } - } -} - -impl Drop for CoreWrapper { - #[inline] - fn drop(&mut self) { - #[cfg(feature = "zeroize")] - { - use zeroize::Zeroize; - self.buffer.zeroize(); - } - } -} - -#[cfg(feature = "zeroize")] -impl zeroize::ZeroizeOnDrop for CoreWrapper {} - -impl CustomizedInit for CoreWrapper -where - T: BufferKindUser + CustomizedInit, -{ - #[inline] - fn new_customized(customization: &[u8]) -> Self { - Self::from_core(T::new_customized(customization)) - } -} - -#[cfg(feature = "oid")] -impl AssociatedOid for CoreWrapper -where - T: BufferKindUser + AssociatedOid, -{ - const OID: ObjectIdentifier = T::OID; -} - -type CoreWrapperSerializedStateSize = - Sum::SerializedStateSize, U1>, ::BlockSize>; - -impl SerializableState for CoreWrapper -where - T: BufferKindUser + SerializableState, - T::BlockSize: IsLess, - Le: NonZero, - T::SerializedStateSize: Add, - Sum: Add + ArraySize, - CoreWrapperSerializedStateSize: Sub + ArraySize, - SubSerializedStateSize, T>: Sub + ArraySize, - Diff, T>, U1>: ArraySize, -{ - type SerializedStateSize = CoreWrapperSerializedStateSize; - - fn serialize(&self) -> SerializedState { - let serialized_core = self.core.serialize(); - let serialized_pos = Array([self.buffer.get_pos().try_into().unwrap()]); - let serialized_data = self.buffer.clone().pad_with_zeros(); - - serialized_core - .concat(serialized_pos) - .concat(serialized_data) - } - - fn deserialize( - serialized_state: &SerializedState, - ) -> Result { - let (serialized_core, remaining_buffer) = - serialized_state.split_ref::(); - let (serialized_pos, serialized_data) = remaining_buffer.split_ref::(); - - Ok(Self { - core: T::deserialize(serialized_core)?, - buffer: BlockBuffer::try_new(&serialized_data[..serialized_pos[0].into()]) - .map_err(|_| DeserializeStateError)?, - }) - } -} - -/// A proxy trait to a core type implemented by [`CoreWrapper`] -// TODO: replace with an inherent associated type on stabilization: -// https://github.com/rust-lang/rust/issues/8995 -pub trait CoreProxy: sealed::Sealed { - /// Type wrapped by [`CoreWrapper`]. - type Core; -} - -mod sealed { - pub trait Sealed {} -} - -impl sealed::Sealed for CoreWrapper {} - -impl CoreProxy for CoreWrapper { - type Core = T; -} diff --git a/digest/src/core_api/xof_reader.rs b/digest/src/core_api/xof_reader.rs deleted file mode 100644 index 0bb63933c..000000000 --- a/digest/src/core_api/xof_reader.rs +++ /dev/null @@ -1,51 +0,0 @@ -use super::{AlgorithmName, XofReaderCore}; -use crate::XofReader; -use block_buffer::ReadBuffer; -use core::fmt; - -/// Wrapper around [`XofReaderCore`] implementations. -/// -/// It handles data buffering and implements the mid-level traits. -#[derive(Clone, Default)] -pub struct XofReaderCoreWrapper -where - T: XofReaderCore, -{ - pub(super) core: T, - pub(super) buffer: ReadBuffer, -} - -impl fmt::Debug for XofReaderCoreWrapper -where - T: XofReaderCore + AlgorithmName, -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - T::write_alg_name(f)?; - f.write_str(" { .. }") - } -} - -impl XofReader for XofReaderCoreWrapper -where - T: XofReaderCore, -{ - #[inline] - fn read(&mut self, buffer: &mut [u8]) { - let Self { core, buffer: buf } = self; - buf.read(buffer, |block| *block = core.read_block()); - } -} - -impl Drop for XofReaderCoreWrapper { - #[inline] - fn drop(&mut self) { - #[cfg(feature = "zeroize")] - { - use zeroize::Zeroize; - self.buffer.zeroize(); - } - } -} - -#[cfg(feature = "zeroize")] -impl zeroize::ZeroizeOnDrop for XofReaderCoreWrapper {} diff --git a/digest/src/lib.rs b/digest/src/lib.rs index e8cb7b141..91ab8fb83 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -12,7 +12,7 @@ //! traits atomically describe available functionality of an algorithm. //! - **Marker traits**: [`HashMarker`], [`MacMarker`]. Used to distinguish //! different algorithm classes. -//! - **Low-level traits** defined in the [`core_api`] module. These traits +//! - **Low-level traits** defined in the [`block_api`] module. These traits //! operate at a block-level and do not contain any built-in buffering. //! They are intended to be implemented by low-level algorithm providers only. //! Usually they should not be used in application-level code. @@ -50,14 +50,15 @@ use alloc::boxed::Box; #[cfg(feature = "dev")] pub mod dev; -#[cfg(feature = "core-api")] -pub mod core_api; +#[cfg(feature = "block-api")] +pub mod block_api; +mod buffer_macros; mod digest; #[cfg(feature = "mac")] mod mac; mod xof_fixed; -#[cfg(feature = "core-api")] +#[cfg(feature = "block-api")] pub use block_buffer; #[cfg(feature = "oid")] pub use const_oid; diff --git a/digest/tests/dummy_fixed.rs b/digest/tests/dummy_fixed.rs new file mode 100644 index 000000000..cbec6aced --- /dev/null +++ b/digest/tests/dummy_fixed.rs @@ -0,0 +1,101 @@ +#![cfg(feature = "block-api")] + +mod block_api { + use core::fmt; + use digest::{ + HashMarker, Output, OutputSizeUser, Reset, + block_api::{ + AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, FixedOutputCore, + UpdateCore, + }, + consts::U8, + crypto_common::hazmat::{DeserializeStateError, SerializableState, SerializedState}, + }; + + /// Core of primitive XOR hasher for testing purposes + #[derive(Clone, Default, Debug)] + pub struct FixedHashCore { + state: u64, + } + + impl AlgorithmName for FixedHashCore { + fn write_alg_name(f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + f.write_str("FixedHash") + } + } + + impl BlockSizeUser for FixedHashCore { + type BlockSize = U8; + } + + impl BufferKindUser for FixedHashCore { + type BufferKind = block_buffer::Eager; + } + + impl Reset for FixedHashCore { + fn reset(&mut self) { + self.state = 0; + } + } + + impl UpdateCore for FixedHashCore { + fn update_blocks(&mut self, blocks: &[Block]) { + for block in blocks { + self.state ^= u64::from_le_bytes(block.0) + } + } + } + + impl HashMarker for FixedHashCore {} + + impl OutputSizeUser for FixedHashCore { + type OutputSize = U8; + } + + impl FixedOutputCore for FixedHashCore { + fn finalize_fixed_core(&mut self, buffer: &mut Buffer, out: &mut Output) { + let block = buffer.pad_with_zeros(); + self.state ^= u64::from_le_bytes(block.0); + out.copy_from_slice(&self.state.to_le_bytes()); + } + } + + impl SerializableState for FixedHashCore { + type SerializedStateSize = U8; + + fn serialize(&self) -> SerializedState { + self.state.to_le_bytes().into() + } + + fn deserialize( + serialized_state: &SerializedState, + ) -> Result { + Ok(Self { + state: u64::from_le_bytes(serialized_state.0), + }) + } + } +} + +digest::buffer_fixed!( + /// Primitive XOR hasher for testing purposes + pub struct FixedHash(block_api::FixedHashCore); + impl: BaseFixedTraits Default Clone HashMarker Reset FixedOutputReset; +); +digest::buffer_fixed!( + /// Primitive XOR hasher for testing purposes + pub struct FixedHashWithSer(block_api::FixedHashCore); + impl: FixedHashTraits; +); +digest::buffer_fixed!( + /// Primitive XOR hasher for testing purposes + pub struct FixedHashWithOid(block_api::FixedHashCore); + oid: "0.1.2.3.4.5"; + impl: BaseFixedTraits Default Clone HashMarker Reset FixedOutputReset; +); +digest::buffer_fixed!( + /// Primitive XOR hasher for testing purposes + pub struct FixedHashWithOidSer(block_api::FixedHashCore); + oid: "0.1.2.3.4.5"; + impl: FixedHashTraits; +); From 915474f1ed5be0a19fd102d5f75ef8e04c765416 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Mon, 26 May 2025 05:22:25 +0300 Subject: [PATCH 1361/1461] Fix `clippy::uninlined_format_args` (#1858) --- .github/workflows/workspace.yml | 2 +- password-hash/src/errors.rs | 21 +++++++++------------ password-hash/src/lib.rs | 6 +++--- password-hash/src/output.rs | 2 +- password-hash/src/params.rs | 4 ++-- signature/src/error.rs | 2 +- 6 files changed, 17 insertions(+), 20 deletions(-) diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index 622804dee..6947384c5 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -24,7 +24,7 @@ jobs: - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: - toolchain: 1.85.0 + toolchain: 1.87.0 components: clippy - run: cargo clippy --all --all-features --tests -- -D warnings diff --git a/password-hash/src/errors.rs b/password-hash/src/errors.rs index 14b5d9ea1..2d9d96646 100644 --- a/password-hash/src/errors.rs +++ b/password-hash/src/errors.rs @@ -72,31 +72,28 @@ impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> core::result::Result<(), fmt::Error> { match self { Self::Algorithm => write!(f, "unsupported algorithm"), - Self::B64Encoding(err) => write!(f, "{}", err), + Self::B64Encoding(err) => write!(f, "{err}"), Self::Crypto => write!(f, "cryptographic error"), Self::OutputSize { provided, expected } => match provided { Ordering::Less => write!( f, - "output size too short, expected at least {} bytes", - expected - ), - Ordering::Equal => write!(f, "output size unexpected, expected {} bytes", expected), - Ordering::Greater => write!( - f, - "output size too long, expected at most {} bytes", - expected + "output size too short, expected at least {expected} bytes", ), + Ordering::Equal => write!(f, "output size unexpected, expected {expected} bytes"), + Ordering::Greater => { + write!(f, "output size too long, expected at most {expected} bytes") + } }, Self::ParamNameDuplicated => f.write_str("duplicate parameter"), Self::ParamNameInvalid => f.write_str("invalid parameter name"), - Self::ParamValueInvalid(val_err) => write!(f, "invalid parameter value: {}", val_err), + Self::ParamValueInvalid(val_err) => write!(f, "invalid parameter value: {val_err}"), Self::ParamsMaxExceeded => f.write_str("maximum number of parameters reached"), Self::Password => write!(f, "invalid password"), Self::PhcStringField => write!(f, "password hash string missing field"), Self::PhcStringTrailingData => { write!(f, "password hash string contains trailing characters") } - Self::SaltInvalid(val_err) => write!(f, "salt invalid: {}", val_err), + Self::SaltInvalid(val_err) => write!(f, "salt invalid: {val_err}"), Self::Version => write!(f, "invalid algorithm version"), Self::OutOfMemory => write!(f, "out of memory"), } @@ -161,7 +158,7 @@ impl InvalidValue { impl fmt::Display for InvalidValue { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> core::result::Result<(), fmt::Error> { match self { - Self::InvalidChar(c) => write!(f, "contains invalid character: '{}'", c), + Self::InvalidChar(c) => write!(f, "contains invalid character: '{c}'"), Self::InvalidFormat => f.write_str("value format is invalid"), Self::Malformed => f.write_str("value malformed"), Self::TooLong => f.write_str("value to long"), diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index 7e3f283f1..19c2210bb 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -253,7 +253,7 @@ impl fmt::Display for PasswordHash<'_> { write!(f, "{}{}", PASSWORD_HASH_SEPARATOR, self.algorithm)?; if let Some(version) = self.version { - write!(f, "{}v={}", PASSWORD_HASH_SEPARATOR, version)?; + write!(f, "{PASSWORD_HASH_SEPARATOR}v={version}")?; } if !self.params.is_empty() { @@ -261,10 +261,10 @@ impl fmt::Display for PasswordHash<'_> { } if let Some(salt) = &self.salt { - write!(f, "{}{}", PASSWORD_HASH_SEPARATOR, salt)?; + write!(f, "{PASSWORD_HASH_SEPARATOR}{salt}")?; if let Some(hash) = &self.hash { - write!(f, "{}{}", PASSWORD_HASH_SEPARATOR, hash)?; + write!(f, "{PASSWORD_HASH_SEPARATOR}{hash}")?; } } diff --git a/password-hash/src/output.rs b/password-hash/src/output.rs index cf3b1879a..48592315c 100644 --- a/password-hash/src/output.rs +++ b/password-hash/src/output.rs @@ -272,7 +272,7 @@ impl fmt::Display for Output { impl fmt::Debug for Output { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "Output(\"{}\")", self) + write!(f, "Output(\"{self}\")") } } diff --git a/password-hash/src/params.rs b/password-hash/src/params.rs index 975e794a8..7fdb3baed 100644 --- a/password-hash/src/params.rs +++ b/password-hash/src/params.rs @@ -60,7 +60,7 @@ impl ParamsString { // Add param name let offset = self.0.length; - if write!(self.0, "{}=", name).is_err() { + if write!(self.0, "{name}=").is_err() { self.0.length = offset; return Err(Error::ParamsMaxExceeded); } @@ -160,7 +160,7 @@ impl ParamsString { .map_err(|_| Error::ParamsMaxExceeded)? } - if write!(self.0, "{}={}", name, value).is_err() { + if write!(self.0, "{name}={value}").is_err() { self.0.length = orig_len; return Err(Error::ParamsMaxExceeded); } diff --git a/signature/src/error.rs b/signature/src/error.rs index 75b3a53d0..8a831dea6 100644 --- a/signature/src/error.rs +++ b/signature/src/error.rs @@ -61,7 +61,7 @@ impl Debug for Error { f.write_str("signature::Error { source: ")?; if let Some(source) = &self.source { - write!(f, "Some({})", source)?; + write!(f, "Some({source})")?; } else { f.write_str("None")?; } From abab6dc5f800c85689f8f9a64d376b7561ab1558 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 27 May 2025 13:50:13 -0600 Subject: [PATCH 1362/1461] elliptic-curve: apply digest API breaking changes (#1860) Alternative to #1859 --- Cargo.lock | 55 +++++-------------- Cargo.toml | 5 ++ .../hash2curve/hash2field/expand_msg/xmd.rs | 2 +- 3 files changed, 21 insertions(+), 41 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 54d058ded..f11b4d85b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,7 +20,7 @@ dependencies = [ "arrayvec", "blobby", "bytes", - "crypto-common 0.2.0-rc.2", + "crypto-common", "heapless", "inout", ] @@ -122,7 +122,7 @@ name = "cipher" version = "0.5.0-pre.8" dependencies = [ "blobby", - "crypto-common 0.2.0-rc.2", + "crypto-common", "inout", "zeroize", ] @@ -148,8 +148,8 @@ version = "0.6.0-pre" dependencies = [ "aead", "cipher", - "crypto-common 0.2.0-rc.2", - "digest 0.11.0-pre.10", + "crypto-common", + "digest", "elliptic-curve", "password-hash", "signature", @@ -177,15 +177,6 @@ dependencies = [ "rand_core", ] -[[package]] -name = "crypto-common" -version = "0.2.0-rc.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "170d71b5b14dec99db7739f6fc7d6ec2db80b78c3acb77db48392ccc3d8a9ea0" -dependencies = [ - "hybrid-array", -] - [[package]] name = "der" version = "0.8.0-rc.2" @@ -204,23 +195,11 @@ dependencies = [ "blobby", "block-buffer", "const-oid", - "crypto-common 0.2.0-rc.2", + "crypto-common", "subtle", "zeroize", ] -[[package]] -name = "digest" -version = "0.11.0-pre.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c478574b20020306f98d61c8ca3322d762e1ff08117422ac6106438605ea516" -dependencies = [ - "block-buffer", - "const-oid", - "crypto-common 0.2.0-rc.2 (registry+https://github.com/rust-lang/crates.io-index)", - "subtle", -] - [[package]] name = "elliptic-curve" version = "0.14.0-rc.1" @@ -228,7 +207,7 @@ dependencies = [ "base16ct", "base64ct", "crypto-bigint", - "digest 0.11.0-pre.10 (registry+https://github.com/rust-lang/crates.io-index)", + "digest", "ff", "group", "hex-literal", @@ -330,8 +309,7 @@ checksum = "bcaaec4551594c969335c98c903c1397853d4198408ea609190f420500f6be71" [[package]] name = "hkdf" version = "0.13.0-pre.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0aaa7579d1176645cee5dc206aa74873b5b3be479af9606025f9b8905bcf597b" +source = "git+https://github.com/RustCrypto/KDFs.git#2e2dbcd45b8678696e85dcbef922345f3ca04dbf" dependencies = [ "hmac", ] @@ -339,10 +317,9 @@ dependencies = [ [[package]] name = "hmac" version = "0.13.0-pre.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62c11fc82c6b89c906b4d26b7b5a305d0b3aebd4b458dd1bd0a7ed98c548a28e" +source = "git+https://github.com/RustCrypto/MACs.git#64d671d5c375838173d18e30bc14dffc80c13e51" dependencies = [ - "digest 0.11.0-pre.10 (registry+https://github.com/rust-lang/crates.io-index)", + "digest", ] [[package]] @@ -563,21 +540,19 @@ dependencies = [ [[package]] name = "sha2" version = "0.11.0-pre.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b4241d1a56954dce82cecda5c8e9c794eef6f53abe5e5216bac0a0ea71ffa7" +source = "git+https://github.com/RustCrypto/hashes.git#7d44caf065dbeb3f10a372a26a8b9f1c927f8433" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.11.0-pre.10 (registry+https://github.com/rust-lang/crates.io-index)", + "digest", ] [[package]] name = "sha3" version = "0.11.0-pre.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bc997d7a5fa67cc1e352b2001124d28edb948b4e7a16567f9b3c1e51952524" +source = "git+https://github.com/RustCrypto/hashes.git#7d44caf065dbeb3f10a372a26a8b9f1c927f8433" dependencies = [ - "digest 0.11.0-pre.10 (registry+https://github.com/rust-lang/crates.io-index)", + "digest", "keccak", ] @@ -585,7 +560,7 @@ dependencies = [ name = "signature" version = "3.0.0-pre" dependencies = [ - "digest 0.11.0-pre.10 (registry+https://github.com/rust-lang/crates.io-index)", + "digest", "hex-literal", "rand_core", "sha2", @@ -657,7 +632,7 @@ checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" name = "universal-hash" version = "0.6.0-rc.0" dependencies = [ - "crypto-common 0.2.0-rc.2", + "crypto-common", "subtle", ] diff --git a/Cargo.toml b/Cargo.toml index 6d87a02f9..9bf7c610e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,4 +15,9 @@ members = [ ] [patch.crates-io] +digest = { path = "digest" } +hkdf = { git = "https://github.com/RustCrypto/KDFs.git" } +hmac = { git = "https://github.com/RustCrypto/MACs.git" } +sha2 = { git = "https://github.com/RustCrypto/hashes.git" } +sha3 = { git = "https://github.com/RustCrypto/hashes.git" } signature = { path = "signature" } diff --git a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs index 8ad5223ab..fcd63dca7 100644 --- a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs +++ b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs @@ -10,7 +10,7 @@ use digest::{ Array, typenum::{IsGreaterOrEqual, IsLess, IsLessOrEqual, True, U2, U256, Unsigned}, }, - core_api::BlockSizeUser, + block_api::BlockSizeUser, }; /// Implements `expand_message_xof` via the [`ExpandMsg`] trait: From e93dda2c74131f078a9b6e95dd9263433c93ef45 Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Tue, 27 May 2025 19:56:33 +0000 Subject: [PATCH 1363/1461] digest: alias core_api with a depreciation notice (#1861) Alternative to #1859 --- digest/src/lib.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 91ab8fb83..31bb0f235 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -74,6 +74,13 @@ pub use crypto_common::{Output, OutputSizeUser, Reset, array, typenum, typenum:: pub use mac::{CtOutput, Mac, MacError, MacMarker}; pub use xof_fixed::XofFixedWrapper; +#[cfg(feature = "block-api")] +#[deprecated( + since = "0.11.0", + note = "`digest::core_api` has been replaced by `digest::block_api`" +)] +pub use block_api as core_api; + use core::fmt; use crypto_common::typenum::Unsigned; From 1cae37d25c5bc6c59570d5136ccb710e1914b07a Mon Sep 17 00:00:00 2001 From: daxpedda Date: Wed, 28 May 2025 01:12:55 +0200 Subject: [PATCH 1364/1461] Remove unnecessary re-allocation in `BatchInvert` (#1863) I didn't look deeper into it, but I assume this was just a historic leftover. --- elliptic-curve/src/ops.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/elliptic-curve/src/ops.rs b/elliptic-curve/src/ops.rs index e5cf2a38d..5f647e6dc 100644 --- a/elliptic-curve/src/ops.rs +++ b/elliptic-curve/src/ops.rs @@ -71,10 +71,7 @@ where field_elements_inverses.as_mut(), ); - CtOption::new( - field_elements_inverses.into_iter().collect(), - inversion_succeeded, - ) + CtOption::new(field_elements_inverses, inversion_succeeded) } } From b01c581f68ea10faaac6678b540e37969696e93c Mon Sep 17 00:00:00 2001 From: daxpedda Date: Wed, 28 May 2025 18:53:51 +0200 Subject: [PATCH 1365/1461] Improve `BatchInvert` (#1864) This PR does a couple of things: - Changes the implementation to require two write stores instead of 3 write stores and one read. - Add a `BatchInvert::batch_invert_mut()` methods that allows users to pass one of the two stores themselves. With this a single store can be allocated instead of 3. - Reduce the bounds from `Invert + Mul + Copy + Default + ConditionallySelectable` to `Field`. This was largely inspired by [`curve25519-dalek`s implementation](https://github.com/dalek-cryptography/curve25519-dalek/blob/dd5bd108d6985491acb3de25497fb082a29c9fb7/curve25519-dalek/src/scalar.rs#L788-L837). I adjusted it a bit to save two unnecessary multiplications by one. Companion PR: https://github.com/RustCrypto/elliptic-curves/pull/1205. --- elliptic-curve/src/ops.rs | 134 ++++++++++++++++++++------------------ 1 file changed, 70 insertions(+), 64 deletions(-) diff --git a/elliptic-curve/src/ops.rs b/elliptic-curve/src/ops.rs index 5f647e6dc..bcccf9d0f 100644 --- a/elliptic-curve/src/ops.rs +++ b/elliptic-curve/src/ops.rs @@ -1,17 +1,19 @@ //! Traits for arithmetic operations on elliptic curve field elements. +use core::iter; pub use core::ops::{Add, AddAssign, Mul, Neg, Shr, ShrAssign, Sub, SubAssign}; pub use crypto_bigint::Invert; use crypto_bigint::Integer; -use subtle::{Choice, ConditionallySelectable, CtOption}; +use ff::Field; +use subtle::{Choice, CtOption}; #[cfg(feature = "alloc")] -use alloc::vec::Vec; +use alloc::{borrow::ToOwned, vec::Vec}; /// Perform a batched inversion on a sequence of field elements (i.e. base field elements or scalars) /// at an amortized cost that should be practically as efficient as a single inversion. -pub trait BatchInvert: Invert + Sized { +pub trait BatchInvert: Field + Sized { /// The output of batch inversion. A container of field elements. type Output: AsRef<[Self]>; @@ -19,60 +21,57 @@ pub trait BatchInvert: Invert + Sized { fn batch_invert( field_elements: &FieldElements, ) -> CtOption<>::Output>; + + /// Invert a batch of field elements in-place. + /// + /// # ⚠️ Warning + /// + /// Even though `field_elements` is modified regardless of success, on failure it does not + /// contain correctly inverted scalars and should be discarded instead. + /// + /// Consider using [`Self::batch_invert()`] instead. + fn batch_invert_mut(field_elements: &mut FieldElements) -> Choice; } impl BatchInvert<[T; N]> for T where - T: Invert> - + Mul - + Copy - + Default - + ConditionallySelectable, + T: Field, { type Output = [Self; N]; fn batch_invert(field_elements: &[Self; N]) -> CtOption<[Self; N]> { - let mut field_elements_multiples = [Self::default(); N]; - let mut field_elements_multiples_inverses = [Self::default(); N]; - let mut field_elements_inverses = [Self::default(); N]; - - let inversion_succeeded = invert_batch_internal( - field_elements, - &mut field_elements_multiples, - &mut field_elements_multiples_inverses, - &mut field_elements_inverses, - ); + let mut field_elements_inverses = *field_elements; + let inversion_succeeded = Self::batch_invert_mut(&mut field_elements_inverses); CtOption::new(field_elements_inverses, inversion_succeeded) } + + fn batch_invert_mut(field_elements: &mut [T; N]) -> Choice { + let mut field_elements_pad = [Self::default(); N]; + + invert_batch_internal(field_elements, &mut field_elements_pad) + } } #[cfg(feature = "alloc")] impl BatchInvert<[T]> for T where - T: Invert> - + Mul - + Copy - + Default - + ConditionallySelectable, + T: Field, { type Output = Vec; fn batch_invert(field_elements: &[Self]) -> CtOption> { - let mut field_elements_multiples: Vec = vec![Self::default(); field_elements.len()]; - let mut field_elements_multiples_inverses: Vec = - vec![Self::default(); field_elements.len()]; - let mut field_elements_inverses: Vec = vec![Self::default(); field_elements.len()]; - - let inversion_succeeded = invert_batch_internal( - field_elements, - field_elements_multiples.as_mut(), - field_elements_multiples_inverses.as_mut(), - field_elements_inverses.as_mut(), - ); + let mut field_elements_inverses: Vec = field_elements.to_owned(); + let inversion_succeeded = Self::batch_invert_mut(field_elements_inverses.as_mut_slice()); CtOption::new(field_elements_inverses, inversion_succeeded) } + + fn batch_invert_mut(field_elements: &mut [T]) -> Choice { + let mut field_elements_pad: Vec = vec![Self::default(); field_elements.len()]; + + invert_batch_internal(field_elements, field_elements_pad.as_mut()) + } } /// Implements "Montgomery's trick", a trick for computing many modular inverses at once. @@ -81,44 +80,51 @@ where /// to computing a single inversion, plus some storage and `O(n)` extra multiplications. /// /// See: https://iacr.org/archive/pkc2004/29470042/29470042.pdf section 2.2. -fn invert_batch_internal< - T: Invert> + Mul + Default + ConditionallySelectable, ->( - field_elements: &[T], - field_elements_multiples: &mut [T], - field_elements_multiples_inverses: &mut [T], - field_elements_inverses: &mut [T], +fn invert_batch_internal( + field_elements: &mut [T], + field_elements_pad: &mut [T], ) -> Choice { let batch_size = field_elements.len(); - if batch_size == 0 - || batch_size != field_elements_multiples.len() - || batch_size != field_elements_multiples_inverses.len() - { + if batch_size == 0 || batch_size != field_elements_pad.len() { return Choice::from(0); } - field_elements_multiples[0] = field_elements[0]; - for i in 1..batch_size { + let mut acc = field_elements[0]; + field_elements_pad[0] = acc; + + for (field_element, field_element_pad) in field_elements + .iter_mut() + .zip(field_elements_pad.iter_mut()) + .skip(1) + { // $ a_n = a_{n-1}*x_n $ - field_elements_multiples[i] = field_elements_multiples[i - 1] * field_elements[i]; + acc *= *field_element; + *field_element_pad = acc; } - field_elements_multiples[batch_size - 1] - .invert() - .map(|multiple_of_inverses_of_all_field_elements| { - field_elements_multiples_inverses[batch_size - 1] = - multiple_of_inverses_of_all_field_elements; - for i in (1..batch_size).rev() { - // $ a_{n-1} = {a_n}^{-1}*x_n $ - field_elements_multiples_inverses[i - 1] = - field_elements_multiples_inverses[i] * field_elements[i]; - } - - field_elements_inverses[0] = field_elements_multiples_inverses[0]; - for i in 1..batch_size { - // $ {x_n}^{-1} = a_{n}^{-1}*a_{n-1} $ - field_elements_inverses[i] = - field_elements_multiples_inverses[i] * field_elements_multiples[i - 1]; + acc.invert() + .map(|mut acc| { + // Shift the iterator by one element back. The one we are skipping is served in `acc`. + let field_elements_pad = field_elements_pad + .iter() + .rev() + .skip(1) + .map(Some) + .chain(iter::once(None)); + + for (field_element, field_element_pad) in + field_elements.iter_mut().rev().zip(field_elements_pad) + { + if let Some(field_element_pad) = field_element_pad { + // Store in a temporary so we can overwrite `field_element`. + // $ a_{n-1} = {a_n}^{-1}*x_n $ + let tmp = acc * *field_element; + // $ {x_n}^{-1} = a_{n}^{-1}*a_{n-1} $ + *field_element = acc * *field_element_pad; + acc = tmp; + } else { + *field_element = acc; + } } }) .is_some() From 857f6de047cffa855e6634e4fe61d3b023aca1fd Mon Sep 17 00:00:00 2001 From: daxpedda Date: Wed, 28 May 2025 19:25:24 +0200 Subject: [PATCH 1366/1461] elliptic-curve: remove insecure `BatchInvert` API (#1865) Implementing the idea I had in https://github.com/RustCrypto/traits/pull/1864#discussion_r2112346173, which in hindsight I actually think is better. The new implementation actually *should* take ownership instead of just cloning *for* the user. See [C-CALLER-CONTROL API guidelines](https://rust-lang.github.io/api-guidelines/flexibility.html?highlight=clone#caller-decides-where-to-copy-and-place-data-c-caller-control). This has the advantage of getting rid of the insecure `batch_invert_mut` API where users have to make sure to actually check the returned `Choice` and discard the input slice. I could also quickly add the following for even more control if desirable: ```rust #[cfg(feature = "alloc")] impl<'this, T> BatchInvert<&'this mut [Self]> for T where T: Field, { type Output = &'this mut [Self]; fn batch_invert(field_elements: &'this mut [Self]) -> CtOption<&'this mut [Self]> { let mut field_elements_pad: Vec = vec![Self::default(); field_elements.len()]; let inversion_succeeded = invert_batch_internal(field_elements, &mut field_elements_pad); CtOption::new(field_elements, inversion_succeeded) } } ``` --- elliptic-curve/src/ops.rs | 60 +++++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 24 deletions(-) diff --git a/elliptic-curve/src/ops.rs b/elliptic-curve/src/ops.rs index bcccf9d0f..c7c02cf91 100644 --- a/elliptic-curve/src/ops.rs +++ b/elliptic-curve/src/ops.rs @@ -19,18 +19,8 @@ pub trait BatchInvert: Field + Sized { /// Invert a batch of field elements. fn batch_invert( - field_elements: &FieldElements, + field_elements: FieldElements, ) -> CtOption<>::Output>; - - /// Invert a batch of field elements in-place. - /// - /// # ⚠️ Warning - /// - /// Even though `field_elements` is modified regardless of success, on failure it does not - /// contain correctly inverted scalars and should be discarded instead. - /// - /// Consider using [`Self::batch_invert()`] instead. - fn batch_invert_mut(field_elements: &mut FieldElements) -> Choice; } impl BatchInvert<[T; N]> for T @@ -39,38 +29,60 @@ where { type Output = [Self; N]; - fn batch_invert(field_elements: &[Self; N]) -> CtOption<[Self; N]> { - let mut field_elements_inverses = *field_elements; - let inversion_succeeded = Self::batch_invert_mut(&mut field_elements_inverses); + fn batch_invert(mut field_elements: [Self; N]) -> CtOption<[Self; N]> { + let mut field_elements_pad = [Self::default(); N]; + let inversion_succeeded = + invert_batch_internal(&mut field_elements, &mut field_elements_pad); - CtOption::new(field_elements_inverses, inversion_succeeded) + CtOption::new(field_elements, inversion_succeeded) } +} - fn batch_invert_mut(field_elements: &mut [T; N]) -> Choice { - let mut field_elements_pad = [Self::default(); N]; +#[cfg(feature = "alloc")] +impl<'this, T> BatchInvert<&'this mut [Self]> for T +where + T: Field, +{ + type Output = &'this mut [Self]; + + fn batch_invert(field_elements: &'this mut [Self]) -> CtOption<&'this mut [Self]> { + let mut field_elements_pad: Vec = vec![Self::default(); field_elements.len()]; + let inversion_succeeded = invert_batch_internal(field_elements, &mut field_elements_pad); - invert_batch_internal(field_elements, &mut field_elements_pad) + CtOption::new(field_elements, inversion_succeeded) } } #[cfg(feature = "alloc")] -impl BatchInvert<[T]> for T +impl BatchInvert<&[Self]> for T where T: Field, { type Output = Vec; fn batch_invert(field_elements: &[Self]) -> CtOption> { - let mut field_elements_inverses: Vec = field_elements.to_owned(); - let inversion_succeeded = Self::batch_invert_mut(field_elements_inverses.as_mut_slice()); + let mut field_elements: Vec = field_elements.to_owned(); + let mut field_elements_pad: Vec = vec![Self::default(); field_elements.len()]; + let inversion_succeeded = + invert_batch_internal(&mut field_elements, &mut field_elements_pad); - CtOption::new(field_elements_inverses, inversion_succeeded) + CtOption::new(field_elements, inversion_succeeded) } +} + +#[cfg(feature = "alloc")] +impl BatchInvert> for T +where + T: Field, +{ + type Output = Vec; - fn batch_invert_mut(field_elements: &mut [T]) -> Choice { + fn batch_invert(mut field_elements: Vec) -> CtOption> { let mut field_elements_pad: Vec = vec![Self::default(); field_elements.len()]; + let inversion_succeeded = + invert_batch_internal(&mut field_elements, &mut field_elements_pad); - invert_batch_internal(field_elements, field_elements_pad.as_mut()) + CtOption::new(field_elements, inversion_succeeded) } } From 4de33de9409d6534501c3d390a3051618482a419 Mon Sep 17 00:00:00 2001 From: Andrew Whitehead Date: Wed, 28 May 2025 11:57:39 -0700 Subject: [PATCH 1367/1461] elliptic-curve: update `MapToCurve` to avoid `CofactorGroup` dependency (#1866) Fixes #1146 This update implements `MapToCurve` for the curve itself rather than for the field element, and removes the dependency on `CofactorGroup`. Signed-off-by: Andrew Whitehead --- elliptic-curve/src/hash2curve/group_digest.rs | 33 ++++------------ elliptic-curve/src/hash2curve/map2curve.rs | 39 ++++++++++++++----- 2 files changed, 38 insertions(+), 34 deletions(-) diff --git a/elliptic-curve/src/hash2curve/group_digest.rs b/elliptic-curve/src/hash2curve/group_digest.rs index 8fa27c46c..5320c5a69 100644 --- a/elliptic-curve/src/hash2curve/group_digest.rs +++ b/elliptic-curve/src/hash2curve/group_digest.rs @@ -1,18 +1,11 @@ //! Traits for handling hash to curve. use super::{ExpandMsg, FromOkm, MapToCurve, hash_to_field}; -use crate::{CurveArithmetic, ProjectivePoint, Result}; -use group::cofactor::CofactorGroup; +use crate::{ProjectivePoint, Result}; use hybrid_array::typenum::Unsigned; -/// Adds hashing arbitrary byte sequences to a valid group element -pub trait GroupDigest: CurveArithmetic -where - ProjectivePoint: CofactorGroup, -{ - /// The field element representation for a group value with multiple elements - type FieldElement: FromOkm + MapToCurve> + Default + Copy; - +/// Hash arbitrary byte sequences to a valid group element. +pub trait GroupDigest: MapToCurve { /// The target security level in bytes: /// /// @@ -58,19 +51,9 @@ where ) -> Result> { let mut u = [Self::FieldElement::default(), Self::FieldElement::default()]; hash_to_field::(msgs, dsts, &mut u)?; - let q0 = u[0].map_to_curve(); - let q1 = u[1].map_to_curve(); - // Ideally we could add and then clear cofactor once - // thus saving a call but the field elements may not - // add properly due to the underlying implementation - // which could result in an incorrect subgroup. - // This is caused curve coefficients being different than - // what is usually implemented. - // FieldElement expects the `a` and `b` to be the original values - // isogenies are different with curves like k256 and bls12-381. - // This problem doesn't manifest for curves with no isogeny like p256. - // For k256 and p256 clear_cofactor doesn't do anything anyway so it will be a no-op. - Ok(q0.clear_cofactor().into() + q1.clear_cofactor()) + let q0 = Self::map_to_curve(u[0]); + let q1 = Self::map_to_curve(u[1]); + Ok(Self::add_and_map_to_subgroup(q0, q1)) } /// Computes the encode to curve routine. @@ -98,8 +81,8 @@ where ) -> Result> { let mut u = [Self::FieldElement::default()]; hash_to_field::(msgs, dsts, &mut u)?; - let q0 = u[0].map_to_curve(); - Ok(q0.clear_cofactor().into()) + let q0 = Self::map_to_curve(u[0]); + Ok(Self::map_to_subgroup(q0)) } /// Computes the hash to field routine according to diff --git a/elliptic-curve/src/hash2curve/map2curve.rs b/elliptic-curve/src/hash2curve/map2curve.rs index 6092e57ba..aa72e11b5 100644 --- a/elliptic-curve/src/hash2curve/map2curve.rs +++ b/elliptic-curve/src/hash2curve/map2curve.rs @@ -1,12 +1,33 @@ //! Traits for mapping field elements to points on the curve. -/// Trait for converting field elements into a point -/// via a mapping method like Simplified Shallue-van de Woestijne-Ulas -/// or Elligator -pub trait MapToCurve { - /// The output point - type Output; - - /// Map a field element into a point - fn map_to_curve(&self) -> Self::Output; +use crate::{CurveArithmetic, ProjectivePoint}; + +use super::FromOkm; + +/// Trait for converting field elements into a point via a mapping method like +/// Simplified Shallue-van de Woestijne-Ulas or Elligator. +pub trait MapToCurve: CurveArithmetic { + /// The intermediate representation, an element of the curve which may or may not + /// be in the curve subgroup. + type CurvePoint; + /// The field element representation for a group value with multiple elements. + type FieldElement: FromOkm + Default + Copy; + + /// Map a field element into a curve point. + fn map_to_curve(element: Self::FieldElement) -> Self::CurvePoint; + + /// Map a curve point to a point in the curve subgroup. + /// This is usually done by clearing the cofactor, if necessary. + fn map_to_subgroup(point: Self::CurvePoint) -> ProjectivePoint; + + /// Combine two curve points into a point in the curve subgroup. + /// This is usually done by clearing the cofactor of the sum. In case + /// addition is not implemented for `Self::CurvePoint`, then both terms + /// must be mapped to the subgroup individually before being added. + fn add_and_map_to_subgroup( + lhs: Self::CurvePoint, + rhs: Self::CurvePoint, + ) -> ProjectivePoint { + Self::map_to_subgroup(lhs) + Self::map_to_subgroup(rhs) + } } From e728ece19cb5df8d8a7f575c4676a323d449a885 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Wed, 28 May 2025 22:51:43 +0200 Subject: [PATCH 1368/1461] `ExpandMsg` improvements (#1862) ## Changes to `ExpandMsg` - Move generic parameter `K` from `ExpandMsg` implementers to `trait ExpandMsg` itself. This was necessary to be able to enforce the correct `K` instead of letting users insert an arbitrary one. E.g. `GroupDigest::hash_from_bytes()` can now `where X: ExpandMsg` instead of users calling `hash_from_bytes::>()`. However, this made calling `ExpandMsg` implementers directly more difficult. E.g. instead of `ExpandMsgXmd::::expand_msg(...)` users now have to write ` as ExpandMsg>::expand_message()`. If we want to address this, I propose adding `RawExpandMsgXmd`. - Add `CollisionResistance` requirement to `ExpandMsgXof`. - Move the lifetime on `ExpandMsg` to the associated `type Expander<'dst>`. - Fix `dst` not actually being checked to be empty, but instead checked for number of slices. - Move `GroupDigest`s `ProjectivePoint: CofactorGroup` bound to super trait bounds. This makes it less "poisoning" so downstream users don't have to write `where ProjectivePoint: CofactorGroup` every time they use `GroupDigest`. - Move `GroupDigest::hash_to_scalar()`s `Scalar: FromOkm` bounds to `GroupDigest`. I believe this was a historical leftover when `FromOkm` wasn't implemented for `Scalar`s yet. - Improved some documentation around hash2curve and updated all mentions of the draft to RFC9380. - Rename parameter names `msgs` and `dsts` to singular `msg` and `dst`. This is to avoid confusion: even though the type is `&[&[u8]]`, it doesn't represent multiple messages or DSTs, but single concated ones. - Remove non-functioning examples. While I don't think the examples are necessary, I'm happy to re-add them if desired, but I would have to add `GroupDigest` to the `Dev` curve. ## Changes to VOPRF While I was at it, I also adjusted a couple of things around `VoprfParameters` (but I'm happy to split this into its own PR): - Renamed all mentions of VOPRF to OPRF. VOPRF was the old name of the draft when it was just a single "mode", the RFC is split into three modes: OPRF, VOPRF and POPRF. The RFC itself is called ["Oblivious Pseudorandom Functions (OPRFs)"](https://www.rfc-editor.org/rfc/rfc9497.html). - Changed associated `const ID` from `&str` to `&[u8]`. - Changed associated `type Hash` from requiring `Digest` to `Default + FixedOutput + Update`. - Updated all mentions of the VOPRF draft to RFC9497. --- Related: https://github.com/RustCrypto/hashes/pull/694. Companion PR: https://github.com/RustCrypto/elliptic-curves/pull/1203. --- .github/workflows/elliptic-curve.yml | 4 +- Cargo.lock | 4 +- elliptic-curve/Cargo.toml | 4 +- elliptic-curve/src/hash2curve.rs | 2 +- elliptic-curve/src/hash2curve/group_digest.rs | 51 +++++---------- elliptic-curve/src/hash2curve/hash2field.rs | 8 +-- .../src/hash2curve/hash2field/expand_msg.rs | 46 ++++++++------ .../hash2curve/hash2field/expand_msg/xmd.rs | 46 ++++++-------- .../hash2curve/hash2field/expand_msg/xof.rs | 62 +++++++++---------- elliptic-curve/src/hash2curve/isogeny.rs | 2 +- elliptic-curve/src/hash2curve/map2curve.rs | 2 +- elliptic-curve/src/hash2curve/osswu.rs | 2 +- elliptic-curve/src/lib.rs | 8 +-- elliptic-curve/src/oprf.rs | 30 +++++++++ elliptic-curve/src/voprf.rs | 27 -------- 15 files changed, 139 insertions(+), 159 deletions(-) create mode 100644 elliptic-curve/src/oprf.rs delete mode 100644 elliptic-curve/src/voprf.rs diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index ac4bdccdc..57d4d4c9a 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -45,16 +45,16 @@ jobs: - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features ecdh - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features hash2curve - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features jwk + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features oprf - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features pem - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features pkcs8 - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features sec1 - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features serde - - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features voprf - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,arithmetic - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,arithmetic,pkcs8 - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,serde - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features arithmetic,serde - - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,digest,ecdh,hash2curve,jwk,pem,pkcs8,sec1,serde,voprf + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,digest,ecdh,hash2curve,jwk,oprf,pem,pkcs8,sec1,serde minimal-versions: # Temporarily disabled until elliptic-curve 0.13.0-pre.0 is published diff --git a/Cargo.lock b/Cargo.lock index f11b4d85b..9aadabffd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -540,7 +540,7 @@ dependencies = [ [[package]] name = "sha2" version = "0.11.0-pre.5" -source = "git+https://github.com/RustCrypto/hashes.git#7d44caf065dbeb3f10a372a26a8b9f1c927f8433" +source = "git+https://github.com/RustCrypto/hashes.git#d9ad085ed12dba58d2a6d75d76a17a1b2706c4c7" dependencies = [ "cfg-if", "cpufeatures", @@ -550,7 +550,7 @@ dependencies = [ [[package]] name = "sha3" version = "0.11.0-pre.5" -source = "git+https://github.com/RustCrypto/hashes.git#7d44caf065dbeb3f10a372a26a8b9f1c927f8433" +source = "git+https://github.com/RustCrypto/hashes.git#d9ad085ed12dba58d2a6d75d76a17a1b2706c4c7" dependencies = [ "digest", "keccak", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index f60db0eca..f9b545a4d 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -66,10 +66,10 @@ hash2curve = ["arithmetic", "digest"] ecdh = ["arithmetic", "digest", "dep:hkdf"] group = ["dep:group", "ff"] jwk = ["dep:base64ct", "dep:serde_json", "alloc", "serde", "zeroize/alloc"] +oprf = ["digest", "hash2curve"] pkcs8 = ["dep:pkcs8", "sec1"] pem = ["dep:pem-rfc7468", "alloc", "arithmetic", "pkcs8", "sec1/pem"] serde = ["dep:serdect", "alloc", "pkcs8", "sec1/serde"] -voprf = ["digest", "hash2curve"] [package.metadata.docs.rs] -features = ["bits", "ecdh", "hash2curve", "jwk", "pem", "std", "voprf"] +features = ["bits", "ecdh", "hash2curve", "jwk", "oprf", "pem", "std"] diff --git a/elliptic-curve/src/hash2curve.rs b/elliptic-curve/src/hash2curve.rs index 3df394f79..da923e4d2 100644 --- a/elliptic-curve/src/hash2curve.rs +++ b/elliptic-curve/src/hash2curve.rs @@ -1,6 +1,6 @@ //! Traits for hashing byte sequences to curve points. //! -//! +//! mod group_digest; mod hash2field; diff --git a/elliptic-curve/src/hash2curve/group_digest.rs b/elliptic-curve/src/hash2curve/group_digest.rs index 5320c5a69..571f43e81 100644 --- a/elliptic-curve/src/hash2curve/group_digest.rs +++ b/elliptic-curve/src/hash2curve/group_digest.rs @@ -1,6 +1,6 @@ //! Traits for handling hash to curve. -use super::{ExpandMsg, FromOkm, MapToCurve, hash_to_field}; +use super::{ExpandMsg, MapToCurve, hash_to_field}; use crate::{ProjectivePoint, Result}; use hybrid_array::typenum::Unsigned; @@ -13,7 +13,7 @@ pub trait GroupDigest: MapToCurve { /// Computes the hash to curve routine. /// - /// From : + /// From : /// /// > Uniform encoding from byte strings to points in G. /// > That is, the distribution of its output is statistically close @@ -22,20 +22,6 @@ pub trait GroupDigest: MapToCurve { /// > oracle returning points in G assuming a cryptographically secure /// > hash function is used. /// - /// # Examples - /// - /// ## Using a fixed size hash function - /// - /// ```ignore - /// let pt = ProjectivePoint::hash_from_bytes::>(b"test data", b"CURVE_XMD:SHA-256_SSWU_RO_"); - /// ``` - /// - /// ## Using an extendable output function - /// - /// ```ignore - /// let pt = ProjectivePoint::hash_from_bytes::>(b"test data", b"CURVE_XOF:SHAKE-256_SSWU_RO_"); - /// ``` - /// /// # Errors /// See implementors of [`ExpandMsg`] for errors: /// - [`ExpandMsgXmd`] @@ -45,12 +31,12 @@ pub trait GroupDigest: MapToCurve { /// /// [`ExpandMsgXmd`]: crate::hash2curve::ExpandMsgXmd /// [`ExpandMsgXof`]: crate::hash2curve::ExpandMsgXof - fn hash_from_bytes<'a, X: ExpandMsg<'a>>( - msgs: &[&[u8]], - dsts: &'a [&'a [u8]], - ) -> Result> { + fn hash_from_bytes(msg: &[&[u8]], dst: &[&[u8]]) -> Result> + where + X: ExpandMsg, + { let mut u = [Self::FieldElement::default(), Self::FieldElement::default()]; - hash_to_field::(msgs, dsts, &mut u)?; + hash_to_field::(msg, dst, &mut u)?; let q0 = Self::map_to_curve(u[0]); let q1 = Self::map_to_curve(u[1]); Ok(Self::add_and_map_to_subgroup(q0, q1)) @@ -58,7 +44,7 @@ pub trait GroupDigest: MapToCurve { /// Computes the encode to curve routine. /// - /// From : + /// From : /// /// > Nonuniform encoding from byte strings to /// > points in G. That is, the distribution of its output is not @@ -75,18 +61,18 @@ pub trait GroupDigest: MapToCurve { /// /// [`ExpandMsgXmd`]: crate::hash2curve::ExpandMsgXmd /// [`ExpandMsgXof`]: crate::hash2curve::ExpandMsgXof - fn encode_from_bytes<'a, X: ExpandMsg<'a>>( - msgs: &[&[u8]], - dsts: &'a [&'a [u8]], - ) -> Result> { + fn encode_from_bytes(msg: &[&[u8]], dst: &[&[u8]]) -> Result> + where + X: ExpandMsg, + { let mut u = [Self::FieldElement::default()]; - hash_to_field::(msgs, dsts, &mut u)?; + hash_to_field::(msg, dst, &mut u)?; let q0 = Self::map_to_curve(u[0]); Ok(Self::map_to_subgroup(q0)) } /// Computes the hash to field routine according to - /// + /// /// and returns a scalar. /// /// # Errors @@ -98,15 +84,12 @@ pub trait GroupDigest: MapToCurve { /// /// [`ExpandMsgXmd`]: crate::hash2curve::ExpandMsgXmd /// [`ExpandMsgXof`]: crate::hash2curve::ExpandMsgXof - fn hash_to_scalar<'a, X: ExpandMsg<'a>>( - msgs: &[&[u8]], - dsts: &'a [&'a [u8]], - ) -> Result + fn hash_to_scalar(msg: &[&[u8]], dst: &[&[u8]]) -> Result where - Self::Scalar: FromOkm, + X: ExpandMsg, { let mut u = [Self::Scalar::default()]; - hash_to_field::(msgs, dsts, &mut u)?; + hash_to_field::(msg, dst, &mut u)?; Ok(u[0]) } } diff --git a/elliptic-curve/src/hash2curve/hash2field.rs b/elliptic-curve/src/hash2curve/hash2field.rs index 4ffcf8062..990230105 100644 --- a/elliptic-curve/src/hash2curve/hash2field.rs +++ b/elliptic-curve/src/hash2curve/hash2field.rs @@ -1,6 +1,6 @@ //! Traits for hashing to field elements. //! -//! +//! mod expand_msg; @@ -25,7 +25,7 @@ pub trait FromOkm { /// Convert an arbitrary byte sequence into a field element. /// -/// +/// /// /// # Errors /// See implementors of [`ExpandMsg`] for errors: @@ -37,9 +37,9 @@ pub trait FromOkm { /// [`ExpandMsgXmd`]: crate::hash2field::ExpandMsgXmd /// [`ExpandMsgXof`]: crate::hash2field::ExpandMsgXof #[doc(hidden)] -pub fn hash_to_field<'a, E, T>(data: &[&[u8]], domain: &'a [&'a [u8]], out: &mut [T]) -> Result<()> +pub fn hash_to_field(data: &[&[u8]], domain: &[&[u8]], out: &mut [T]) -> Result<()> where - E: ExpandMsg<'a>, + E: ExpandMsg, T: FromOkm + Default, { let len_in_bytes = T::Length::to_usize() diff --git a/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs b/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs index e8fb802a6..233b6b9f0 100644 --- a/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs +++ b/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs @@ -17,21 +17,25 @@ const MAX_DST_LEN: usize = 255; /// Trait for types implementing expand_message interface for `hash_to_field`. /// +/// `K` is the target security level in bytes: +/// +/// +/// /// # Errors /// See implementors of [`ExpandMsg`] for errors. -pub trait ExpandMsg<'a> { +pub trait ExpandMsg { /// Type holding data for the [`Expander`]. - type Expander: Expander + Sized; + type Expander<'dst>: Expander + Sized; /// Expands `msg` to the required number of bytes. /// /// Returns an expander that can be used to call `read` until enough /// bytes have been consumed - fn expand_message( - msgs: &[&[u8]], - dsts: &'a [&'a [u8]], + fn expand_message<'dst>( + msg: &[&[u8]], + dst: &'dst [&[u8]], len_in_bytes: NonZero, - ) -> Result; + ) -> Result>; } /// Expander that, call `read` until enough bytes have been consumed. @@ -42,9 +46,9 @@ pub trait Expander { /// The domain separation tag /// -/// Implements [section 5.4.3 of `draft-irtf-cfrg-hash-to-curve-13`][dst]. +/// Implements [section 5.3.3 of RFC9380][dst]. /// -/// [dst]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-13#section-5.4.3 +/// [dst]: https://www.rfc-editor.org/rfc/rfc9380.html#name-using-dsts-longer-than-255- #[derive(Debug)] pub(crate) enum Domain<'a, L> where @@ -60,48 +64,50 @@ impl<'a, L> Domain<'a, L> where L: ArraySize + IsLess, { - pub fn xof(dsts: &'a [&'a [u8]]) -> Result + pub fn xof(dst: &'a [&'a [u8]]) -> Result where X: Default + ExtendableOutput + Update, { - if dsts.is_empty() { + // https://www.rfc-editor.org/rfc/rfc9380.html#section-3.1-4.2 + if dst.iter().map(|slice| slice.len()).sum::() == 0 { Err(Error) - } else if dsts.iter().map(|dst| dst.len()).sum::() > MAX_DST_LEN { + } else if dst.iter().map(|slice| slice.len()).sum::() > MAX_DST_LEN { let mut data = Array::::default(); let mut hash = X::default(); hash.update(OVERSIZE_DST_SALT); - for dst in dsts { - hash.update(dst); + for slice in dst { + hash.update(slice); } hash.finalize_xof().read(&mut data); Ok(Self::Hashed(data)) } else { - Ok(Self::Array(dsts)) + Ok(Self::Array(dst)) } } - pub fn xmd(dsts: &'a [&'a [u8]]) -> Result + pub fn xmd(dst: &'a [&'a [u8]]) -> Result where X: Digest, { - if dsts.is_empty() { + // https://www.rfc-editor.org/rfc/rfc9380.html#section-3.1-4.2 + if dst.iter().map(|slice| slice.len()).sum::() == 0 { Err(Error) - } else if dsts.iter().map(|dst| dst.len()).sum::() > MAX_DST_LEN { + } else if dst.iter().map(|slice| slice.len()).sum::() > MAX_DST_LEN { Ok(Self::Hashed({ let mut hash = X::new(); hash.update(OVERSIZE_DST_SALT); - for dst in dsts { - hash.update(dst); + for slice in dst { + hash.update(slice); } hash.finalize() })) } else { - Ok(Self::Array(dsts)) + Ok(Self::Array(dst)) } } diff --git a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs index fcd63dca7..8ae1ec022 100644 --- a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs +++ b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs @@ -8,7 +8,7 @@ use digest::{ FixedOutput, HashMarker, array::{ Array, - typenum::{IsGreaterOrEqual, IsLess, IsLessOrEqual, True, U2, U256, Unsigned}, + typenum::{IsGreaterOrEqual, IsLess, IsLessOrEqual, Prod, True, U2, U256, Unsigned}, }, block_api::BlockSizeUser, }; @@ -16,45 +16,39 @@ use digest::{ /// Implements `expand_message_xof` via the [`ExpandMsg`] trait: /// /// -/// `K` is the target security level in bytes: -/// -/// -/// /// # Errors -/// - `dst.is_empty()` +/// - `dst` contains no bytes /// - `len_in_bytes > u16::MAX` /// - `len_in_bytes > 255 * HashT::OutputSize` #[derive(Debug)] -pub struct ExpandMsgXmd(PhantomData<(HashT, K)>) +pub struct ExpandMsgXmd(PhantomData) where HashT: BlockSizeUser + Default + FixedOutput + HashMarker, HashT::OutputSize: IsLess, - HashT::OutputSize: IsLessOrEqual, - K: Mul, - HashT::OutputSize: IsGreaterOrEqual<>::Output, Output = True>; + HashT::OutputSize: IsLessOrEqual; -impl<'a, HashT, K> ExpandMsg<'a> for ExpandMsgXmd +impl ExpandMsg for ExpandMsgXmd where HashT: BlockSizeUser + Default + FixedOutput + HashMarker, // If DST is larger than 255 bytes, the length of the computed DST will depend on the output - // size of the hash, which is still not allowed to be larger than 256: - // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-13.html#section-5.4.1-6 + // size of the hash, which is still not allowed to be larger than 255. + // https://www.rfc-editor.org/rfc/rfc9380.html#section-5.3.1-6 HashT::OutputSize: IsLess, - // Constraint set by `expand_message_xmd`: - // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-13.html#section-5.4.1-4 + // The number of bits output by `HashT` MUST be at most `HashT::BlockSize`. + // https://www.rfc-editor.org/rfc/rfc9380.html#section-5.3.1-4 HashT::OutputSize: IsLessOrEqual, - // The number of bits output by `HashT` MUST be larger or equal to `K * 2`: + // The number of bits output by `HashT` MUST be at least `K * 2`. // https://www.rfc-editor.org/rfc/rfc9380.html#section-5.3.1-2.1 K: Mul, - HashT::OutputSize: IsGreaterOrEqual<>::Output, Output = True>, + HashT::OutputSize: IsGreaterOrEqual, Output = True>, { - type Expander = ExpanderXmd<'a, HashT>; + type Expander<'dst> = ExpanderXmd<'dst, HashT>; - fn expand_message( - msgs: &[&[u8]], - dsts: &'a [&'a [u8]], + fn expand_message<'dst>( + msg: &[&[u8]], + dst: &'dst [&[u8]], len_in_bytes: NonZero, - ) -> Result { + ) -> Result> { let len_in_bytes_u16 = u16::try_from(len_in_bytes.get()).map_err(|_| Error)?; // `255 * ` can not exceed `u16::MAX` @@ -65,11 +59,11 @@ where let b_in_bytes = HashT::OutputSize::to_usize(); let ell = u8::try_from(len_in_bytes.get().div_ceil(b_in_bytes)).map_err(|_| Error)?; - let domain = Domain::xmd::(dsts)?; + let domain = Domain::xmd::(dst)?; let mut b_0 = HashT::default(); b_0.update(&Array::::default()); - for msg in msgs { + for msg in msg { b_0.update(msg); } @@ -222,12 +216,12 @@ mod test { HashT::OutputSize: IsLess + IsLessOrEqual + Mul, - HashT::OutputSize: IsGreaterOrEqual<>::Output, Output = True>, + HashT::OutputSize: IsGreaterOrEqual, { assert_message::(self.msg, domain, L::to_u16(), self.msg_prime); let dst = [dst]; - let mut expander = ExpandMsgXmd::::expand_message( + let mut expander = as ExpandMsg>::expand_message( &[self.msg], &dst, NonZero::new(L::to_usize()).ok_or(Error)?, diff --git a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs index 201aee156..25f6858be 100644 --- a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs +++ b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs @@ -2,38 +2,31 @@ use super::{Domain, ExpandMsg, Expander}; use crate::{Error, Result}; -use core::{fmt, marker::PhantomData, num::NonZero, ops::Mul}; -use digest::{ExtendableOutput, HashMarker, Update, XofReader}; +use core::{fmt, num::NonZero, ops::Mul}; +use digest::{ + CollisionResistance, ExtendableOutput, HashMarker, Update, XofReader, typenum::IsGreaterOrEqual, +}; use hybrid_array::{ ArraySize, - typenum::{IsLess, True, U2, U256}, + typenum::{IsLess, Prod, True, U2, U256}, }; /// Implements `expand_message_xof` via the [`ExpandMsg`] trait: /// /// -/// `K` is the target security level in bytes: -/// -/// -/// /// # Errors -/// - `dst.is_empty()` +/// - `dst` contains no bytes /// - `len_in_bytes > u16::MAX` -pub struct ExpandMsgXof +pub struct ExpandMsgXof where HashT: Default + ExtendableOutput + Update + HashMarker, - K: Mul, - >::Output: ArraySize + IsLess, { reader: ::Reader, - _k: PhantomData, } -impl fmt::Debug for ExpandMsgXof +impl fmt::Debug for ExpandMsgXof where HashT: Default + ExtendableOutput + Update + HashMarker, - K: Mul, - >::Output: ArraySize + IsLess, ::Reader: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -43,27 +36,29 @@ where } } -impl<'a, HashT, K> ExpandMsg<'a> for ExpandMsgXof +impl ExpandMsg for ExpandMsgXof where HashT: Default + ExtendableOutput + Update + HashMarker, // If DST is larger than 255 bytes, the length of the computed DST is calculated by `K * 2`. // https://www.rfc-editor.org/rfc/rfc9380.html#section-5.3.1-2.1 - K: Mul, - >::Output: ArraySize + IsLess, + K: Mul>, + // The collision resistance of `HashT` MUST be at least `K` bits. + // https://www.rfc-editor.org/rfc/rfc9380.html#section-5.3.2-2.1 + HashT: CollisionResistance>, { - type Expander = Self; + type Expander<'dst> = Self; - fn expand_message( - msgs: &[&[u8]], - dsts: &'a [&'a [u8]], + fn expand_message<'dst>( + msg: &[&[u8]], + dst: &'dst [&[u8]], len_in_bytes: NonZero, - ) -> Result { + ) -> Result> { let len_in_bytes = u16::try_from(len_in_bytes.get()).map_err(|_| Error)?; - let domain = Domain::<>::Output>::xof::(dsts)?; + let domain = Domain::>::xof::(dst)?; let mut reader = HashT::default(); - for msg in msgs { + for msg in msg { reader = reader.chain(msg); } @@ -71,18 +66,13 @@ where domain.update_hash(&mut reader); reader.update(&[domain.len()]); let reader = reader.finalize_xof(); - Ok(Self { - reader, - _k: PhantomData, - }) + Ok(Self { reader }) } } -impl Expander for ExpandMsgXof +impl Expander for ExpandMsgXof where HashT: Default + ExtendableOutput + Update + HashMarker, - K: Mul, - >::Output: ArraySize + IsLess, { fn fill_bytes(&mut self, okm: &mut [u8]) { self.reader.read(okm); @@ -129,12 +119,16 @@ mod test { #[allow(clippy::panic_in_result_fn)] fn assert(&self, dst: &'static [u8], domain: &Domain<'_, U32>) -> Result<()> where - HashT: Default + ExtendableOutput + Update + HashMarker, + HashT: Default + + ExtendableOutput + + Update + + HashMarker + + CollisionResistance>, L: ArraySize, { assert_message(self.msg, domain, L::to_u16(), self.msg_prime); - let mut expander = ExpandMsgXof::::expand_message( + let mut expander = as ExpandMsg>::expand_message( &[self.msg], &[dst], NonZero::new(L::to_usize()).ok_or(Error)?, diff --git a/elliptic-curve/src/hash2curve/isogeny.rs b/elliptic-curve/src/hash2curve/isogeny.rs index 4644d786a..5b11900d9 100644 --- a/elliptic-curve/src/hash2curve/isogeny.rs +++ b/elliptic-curve/src/hash2curve/isogeny.rs @@ -1,6 +1,6 @@ //! Traits for mapping an isogeny to another curve //! -//! +//! use core::ops::{AddAssign, Mul}; use ff::Field; diff --git a/elliptic-curve/src/hash2curve/map2curve.rs b/elliptic-curve/src/hash2curve/map2curve.rs index aa72e11b5..7ab69a2af 100644 --- a/elliptic-curve/src/hash2curve/map2curve.rs +++ b/elliptic-curve/src/hash2curve/map2curve.rs @@ -6,7 +6,7 @@ use super::FromOkm; /// Trait for converting field elements into a point via a mapping method like /// Simplified Shallue-van de Woestijne-Ulas or Elligator. -pub trait MapToCurve: CurveArithmetic { +pub trait MapToCurve: CurveArithmetic { /// The intermediate representation, an element of the curve which may or may not /// be in the curve subgroup. type CurvePoint; diff --git a/elliptic-curve/src/hash2curve/osswu.rs b/elliptic-curve/src/hash2curve/osswu.rs index dc5d16d57..ea8acdc5b 100644 --- a/elliptic-curve/src/hash2curve/osswu.rs +++ b/elliptic-curve/src/hash2curve/osswu.rs @@ -1,6 +1,6 @@ //! Optimized simplified Shallue-van de Woestijne-Ulas methods. //! -//! +//! use ff::Field; use subtle::Choice; diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index ff5acd88f..8e5ccacaf 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -112,8 +112,8 @@ mod public_key; #[cfg(feature = "jwk")] mod jwk; -#[cfg(feature = "voprf")] -mod voprf; +#[cfg(feature = "oprf")] +mod oprf; pub use crate::{ error::{Error, Result}, @@ -146,8 +146,8 @@ pub use crate::jwk::{JwkEcKey, JwkParameters}; #[cfg(feature = "pkcs8")] pub use pkcs8; -#[cfg(feature = "voprf")] -pub use crate::voprf::VoprfParameters; +#[cfg(feature = "oprf")] +pub use crate::oprf::OprfParameters; use core::{ fmt::Debug, diff --git a/elliptic-curve/src/oprf.rs b/elliptic-curve/src/oprf.rs new file mode 100644 index 000000000..b6806f74f --- /dev/null +++ b/elliptic-curve/src/oprf.rs @@ -0,0 +1,30 @@ +//! Oblivious Pseudorandom Functions (OPRF) using prime order groups +//! +//! + +use digest::{FixedOutput, Update}; +use hybrid_array::typenum::{IsLess, True, U65536}; + +use crate::PrimeCurve; +use crate::hash2curve::{ExpandMsg, GroupDigest}; + +/// Elliptic curve parameters used by OPRF. +pub trait OprfParameters: GroupDigest + PrimeCurve { + /// The `ID` parameter which identifies a particular elliptic curve + /// as defined in [section 4 of RFC9497][oprf]. + /// + /// [oprf]: https://www.rfc-editor.org/rfc/rfc9497.html#name-ciphersuites + const ID: &'static [u8]; + + /// The `Hash` parameter which assigns a particular hash function to this + /// ciphersuite as defined in [section 4 of RFC9497][oprf]. + /// + /// [oprf]: https://www.rfc-editor.org/rfc/rfc9497.html#name-ciphersuites + type Hash: Default + FixedOutput> + Update; + + /// The `expand_message` parameter which assigns a particular algorithm for `HashToGroup` + /// and `HashToScalar` as defined in [section 4 of RFC9497][oprf]. + /// + /// [oprf]: https://www.rfc-editor.org/rfc/rfc9497.html#name-ciphersuites + type ExpandMsg: ExpandMsg<::K>; +} diff --git a/elliptic-curve/src/voprf.rs b/elliptic-curve/src/voprf.rs deleted file mode 100644 index e882fe1b3..000000000 --- a/elliptic-curve/src/voprf.rs +++ /dev/null @@ -1,27 +0,0 @@ -//! Verifiable Oblivious Pseudorandom Function (VOPRF) using prime order groups -//! -//! - -use crate::PrimeCurve; -use crate::hash2curve::ExpandMsg; - -/// Elliptic curve parameters used by VOPRF. -pub trait VoprfParameters: PrimeCurve { - /// The `ID` parameter which identifies a particular elliptic curve - /// as defined in [section 4 of `draft-irtf-cfrg-voprf-19`][voprf]. - /// - /// [voprf]: https://www.ietf.org/archive/id/draft-irtf-cfrg-voprf-19.html#name-ciphersuites-2 - const ID: &'static str; - - /// The `Hash` parameter which assigns a particular hash function to this - /// ciphersuite as defined in [section 4 of `draft-irtf-cfrg-voprf-19`][voprf]. - /// - /// [voprf]: https://www.ietf.org/archive/id/draft-irtf-cfrg-voprf-19.html#name-ciphersuites-2 - type Hash: digest::Digest; - - /// The `expand_message` parameter which assigns a particular algorithm for `HashToGroup` - /// and `HashToScalar` as defined in [section 4 of `draft-irtf-cfrg-voprf-19`][voprf]. - /// - /// [voprf]: https://www.rfc-editor.org/rfc/rfc9497#name-ciphersuites - type ExpandMsg: for<'a> ExpandMsg<'a>; -} From 9e54c34277231d94486b944a598c90f93220ce72 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 28 May 2025 15:57:31 -0600 Subject: [PATCH 1369/1461] crypto-common v0.2.0-rc.3 (#1867) --- Cargo.lock | 2 +- aead/Cargo.toml | 2 +- cipher/Cargo.toml | 2 +- crypto-common/Cargo.toml | 2 +- crypto/Cargo.toml | 2 +- digest/Cargo.toml | 2 +- universal-hash/Cargo.toml | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9aadabffd..2a65d13c5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -171,7 +171,7 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.2.0-rc.2" +version = "0.2.0-rc.3" dependencies = [ "hybrid-array", "rand_core", diff --git a/aead/Cargo.toml b/aead/Cargo.toml index 359edd7d7..50768f9d6 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -16,7 +16,7 @@ such as AES-GCM as ChaCha20Poly1305, which provide a high-level API """ [dependencies] -crypto-common = { version = "0.2.0-rc.1", path = "../crypto-common" } +crypto-common = { version = "0.2.0-rc.3", path = "../crypto-common" } inout = "0.2.0-rc.4" # optional dependencies diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index 4ef179087..c8b2b0325 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -13,7 +13,7 @@ categories = ["cryptography", "no-std"] description = "Traits for describing block ciphers and stream ciphers" [dependencies] -crypto-common = { version = "0.2.0-rc.2", path = "../crypto-common" } +crypto-common = { version = "0.2.0-rc.3", path = "../crypto-common" } inout = "0.2.0-rc.4" # optional dependencies diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index 42d338368..5cdf89f25 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "crypto-common" -version = "0.2.0-rc.2" +version = "0.2.0-rc.3" authors = ["RustCrypto Developers"] edition = "2024" rust-version = "1.85" diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 591a90ee2..013af7094 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -13,7 +13,7 @@ categories = ["cryptography", "no-std"] description = "Facade crate for all of the RustCrypto traits (e.g. `aead`, `cipher`, `digest`)" [dependencies] -crypto-common = { version = "0.2.0-rc.1", path = "../crypto-common", default-features = false } +crypto-common = { version = "0.2.0-rc.3", path = "../crypto-common", default-features = false } # optional dependencies aead = { version = "0.6.0-rc.0", path = "../aead", optional = true } diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 895d1efe9..6f9e14f07 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -13,7 +13,7 @@ categories = ["cryptography", "no-std"] description = "Traits for cryptographic hash functions and message authentication codes" [dependencies] -crypto-common = { version = "0.2.0-rc.2", path = "../crypto-common" } +crypto-common = { version = "0.2.0-rc.3", path = "../crypto-common" } # optional dependencies block-buffer = { version = "0.11.0-rc.4", optional = true } diff --git a/universal-hash/Cargo.toml b/universal-hash/Cargo.toml index 588a82003..db7923dbb 100644 --- a/universal-hash/Cargo.toml +++ b/universal-hash/Cargo.toml @@ -13,7 +13,7 @@ categories = ["cryptography", "no-std"] description = "Traits which describe the functionality of universal hash functions (UHFs)" [dependencies] -crypto-common = { version = "0.2.0-rc.1", path = "../crypto-common" } +crypto-common = { version = "0.2.0-rc.3", path = "../crypto-common" } subtle = { version = "2.4", default-features = false } [package.metadata.docs.rs] From 2b44f2c6aa76d5b40252fc820fc590a2d3dae50a Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 29 May 2025 07:44:54 -0600 Subject: [PATCH 1370/1461] digest v0.11.0-rc.0 (#1868) NOTE: this temporarily disables the `ecdh`, `hash2curve`, and `oprf` features of `elliptic-curve` to make the release possible. They can be re-enabled when the `hmac`, `hkdf`, `sha2`, and `sha3` crates have been updated. Going forward we can remove the `=` from the `digest` version requirement now that we're done making major breaking changes, which should allow for more flexible upgrades. --- .github/workflows/elliptic-curve.yml | 8 +-- Cargo.lock | 80 ++++++++-------------------- crypto/Cargo.toml | 2 +- digest/Cargo.toml | 2 +- elliptic-curve/Cargo.toml | 14 ++--- elliptic-curve/src/lib.rs | 16 +++--- signature/Cargo.toml | 6 +-- 7 files changed, 43 insertions(+), 85 deletions(-) diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index 57d4d4c9a..0544ded38 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -42,10 +42,10 @@ jobs: - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features bits - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features dev - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features digest - - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features ecdh - - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features hash2curve + #- run: cargo build --target ${{ matrix.target }} --release --no-default-features --features ecdh + #- run: cargo build --target ${{ matrix.target }} --release --no-default-features --features hash2curve - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features jwk - - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features oprf + #- run: cargo build --target ${{ matrix.target }} --release --no-default-features --features oprf - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features pem - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features pkcs8 - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features sec1 @@ -54,7 +54,7 @@ jobs: - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,arithmetic,pkcs8 - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,serde - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features arithmetic,serde - - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,digest,ecdh,hash2curve,jwk,oprf,pem,pkcs8,sec1,serde + #- run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,digest,ecdh,hash2curve,jwk,oprf,pem,pkcs8,sec1,serde minimal-versions: # Temporarily disabled until elliptic-curve 0.13.0-pre.0 is published diff --git a/Cargo.lock b/Cargo.lock index 2a65d13c5..0804ced48 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -133,15 +133,6 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0dabb6555f92fb9ee4140454eb5dcd14c7960e1225c6d1a6cc361f032947713e" -[[package]] -name = "cpufeatures" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" -dependencies = [ - "libc", -] - [[package]] name = "crypto" version = "0.6.0-pre" @@ -190,7 +181,7 @@ dependencies = [ [[package]] name = "digest" -version = "0.11.0-pre.10" +version = "0.11.0-rc.0" dependencies = [ "blobby", "block-buffer", @@ -211,7 +202,6 @@ dependencies = [ "ff", "group", "hex-literal", - "hkdf", "hybrid-array", "pem-rfc7468", "pkcs8", @@ -219,8 +209,6 @@ dependencies = [ "sec1", "serde_json", "serdect", - "sha2", - "sha3", "subtle", "zeroize", ] @@ -306,22 +294,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bcaaec4551594c969335c98c903c1397853d4198408ea609190f420500f6be71" -[[package]] -name = "hkdf" -version = "0.13.0-pre.5" -source = "git+https://github.com/RustCrypto/KDFs.git#2e2dbcd45b8678696e85dcbef922345f3ca04dbf" -dependencies = [ - "hmac", -] - -[[package]] -name = "hmac" -version = "0.13.0-pre.5" -source = "git+https://github.com/RustCrypto/MACs.git#64d671d5c375838173d18e30bc14dffc80c13e51" -dependencies = [ - "digest", -] - [[package]] name = "hybrid-array" version = "0.3.1" @@ -348,15 +320,6 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" -[[package]] -name = "keccak" -version = "0.2.0-pre.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7cdd4f0dc5807b9a2b25dd48a3f58e862606fe7bd47f41ecde36e97422d7e90" -dependencies = [ - "cpufeatures", -] - [[package]] name = "kem" version = "0.3.0-pre.0" @@ -537,33 +500,12 @@ dependencies = [ "serde", ] -[[package]] -name = "sha2" -version = "0.11.0-pre.5" -source = "git+https://github.com/RustCrypto/hashes.git#d9ad085ed12dba58d2a6d75d76a17a1b2706c4c7" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "sha3" -version = "0.11.0-pre.5" -source = "git+https://github.com/RustCrypto/hashes.git#d9ad085ed12dba58d2a6d75d76a17a1b2706c4c7" -dependencies = [ - "digest", - "keccak", -] - [[package]] name = "signature" version = "3.0.0-pre" dependencies = [ "digest", - "hex-literal", "rand_core", - "sha2", ] [[package]] @@ -688,3 +630,23 @@ name = "zeroize" version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" + +[[patch.unused]] +name = "hkdf" +version = "0.13.0-pre.5" +source = "git+https://github.com/RustCrypto/KDFs.git#2e2dbcd45b8678696e85dcbef922345f3ca04dbf" + +[[patch.unused]] +name = "hmac" +version = "0.13.0-pre.5" +source = "git+https://github.com/RustCrypto/MACs.git#64d671d5c375838173d18e30bc14dffc80c13e51" + +[[patch.unused]] +name = "sha2" +version = "0.11.0-pre.5" +source = "git+https://github.com/RustCrypto/hashes.git#d9ad085ed12dba58d2a6d75d76a17a1b2706c4c7" + +[[patch.unused]] +name = "sha3" +version = "0.11.0-pre.5" +source = "git+https://github.com/RustCrypto/hashes.git#d9ad085ed12dba58d2a6d75d76a17a1b2706c4c7" diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 013af7094..b165ca592 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -18,7 +18,7 @@ crypto-common = { version = "0.2.0-rc.3", path = "../crypto-common", default-fea # optional dependencies aead = { version = "0.6.0-rc.0", path = "../aead", optional = true } cipher = { version = "0.5.0-pre.7", path = "../cipher", optional = true } -digest = { version = "0.11.0-pre.9", path = "../digest", optional = true, features = ["mac"] } +digest = { version = "0.11.0-rc.0", path = "../digest", optional = true, features = ["mac"] } elliptic-curve = { version = "0.14.0-rc.1", path = "../elliptic-curve", optional = true } password-hash = { version = "0.6.0-rc.0", path = "../password-hash", optional = true } signature = { version = "=3.0.0-pre", path = "../signature", optional = true, default-features = false } diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 6f9e14f07..3f527d7d9 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "digest" -version = "0.11.0-pre.10" +version = "0.11.0-rc.0" authors = ["RustCrypto Developers"] edition = "2024" rust-version = "1.85" diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index f9b545a4d..2aedfb50a 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -26,10 +26,10 @@ zeroize = { version = "1.7", default-features = false } # optional dependencies base64ct = { version = "1", optional = true, default-features = false, features = ["alloc"] } -digest = { version = "=0.11.0-pre.10", optional = true } +digest = { version = "0.11.0-rc.0", optional = true } ff = { version = "=0.14.0-pre.0", optional = true, default-features = false } group = { version = "=0.14.0-pre.0", optional = true, default-features = false } -hkdf = { version = "=0.13.0-pre.5", optional = true, default-features = false } +#hkdf = { version = "=0.13.0-pre.5", optional = true, default-features = false } hex-literal = { version = "1", optional = true } pem-rfc7468 = { version = "1.0.0-rc.2", optional = true, features = ["alloc"] } pkcs8 = { version = "0.11.0-rc.1", optional = true, default-features = false } @@ -39,8 +39,8 @@ serde_json = { version = "1.0.121", optional = true, default-features = false, f [dev-dependencies] hex-literal = "1" -sha2 = "=0.11.0-pre.5" -sha3 = "=0.11.0-pre.5" +#sha2 = "=0.11.0-pre.5" +#sha3 = "=0.11.0-pre.5" [features] default = ["arithmetic"] @@ -62,11 +62,11 @@ std = [ arithmetic = ["group"] bits = ["arithmetic", "ff/bits"] dev = ["arithmetic", "dep:hex-literal", "pem", "pkcs8"] -hash2curve = ["arithmetic", "digest"] -ecdh = ["arithmetic", "digest", "dep:hkdf"] +#ecdh = ["arithmetic", "digest", "dep:hkdf"] group = ["dep:group", "ff"] +#hash2curve = ["arithmetic", "digest"] jwk = ["dep:base64ct", "dep:serde_json", "alloc", "serde", "zeroize/alloc"] -oprf = ["digest", "hash2curve"] +#oprf = ["digest", "hash2curve"] pkcs8 = ["dep:pkcs8", "sec1"] pem = ["dep:pem-rfc7468", "alloc", "arithmetic", "pkcs8", "sec1/pem"] serde = ["dep:serdect", "alloc", "pkcs8", "sec1/serde"] diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 8e5ccacaf..6f433bd3b 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -89,10 +89,10 @@ pub mod scalar; #[cfg(feature = "dev")] pub mod dev; -#[cfg(feature = "ecdh")] -pub mod ecdh; -#[cfg(feature = "hash2curve")] -pub mod hash2curve; +//#[cfg(feature = "ecdh")] +//pub mod ecdh; +//#[cfg(feature = "hash2curve")] +//pub mod hash2curve; #[cfg(feature = "arithmetic")] pub mod ops; #[cfg(feature = "sec1")] @@ -112,8 +112,8 @@ mod public_key; #[cfg(feature = "jwk")] mod jwk; -#[cfg(feature = "oprf")] -mod oprf; +//#[cfg(feature = "oprf")] +//mod oprf; pub use crate::{ error::{Error, Result}, @@ -146,8 +146,8 @@ pub use crate::jwk::{JwkEcKey, JwkParameters}; #[cfg(feature = "pkcs8")] pub use pkcs8; -#[cfg(feature = "oprf")] -pub use crate::oprf::OprfParameters; +//#[cfg(feature = "oprf")] +//pub use crate::oprf::OprfParameters; use core::{ fmt::Debug, diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 6e50f3822..56f79173a 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -13,13 +13,9 @@ categories = ["cryptography", "no-std"] description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" [dependencies] -digest = { version = "=0.11.0-pre.10", optional = true, default-features = false } +digest = { version = "0.11.0-rc.0", optional = true, default-features = false } rand_core = { version = "0.9", optional = true, default-features = false } -[dev-dependencies] -hex-literal = "1" -sha2 = { version = "=0.11.0-pre.5", default-features = false } - [features] alloc = [] rand_core = ["dep:rand_core"] From 75d7a1b04bd6b584904eed96c44da65c8cf9a1ec Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 29 May 2025 09:02:14 -0600 Subject: [PATCH 1371/1461] elliptic-curve: complete `digest` v0.11.0-rc.0 upgrade (#1870) Due to inter-repo dependency relationships and all of the crates previously using `=` to pin `digest`, some of the features of `elliptic-curve` had to be disabled to complete the `digest` v0.11.0-rc.0 release in #1868. Now that it's been released and there are new compatible versions of the `hkdf`, `sha2`, and `sha3` crates, it's possible to re-enable this functionality. --- .github/workflows/elliptic-curve.yml | 8 +-- Cargo.lock | 80 +++++++++++++++++++++------- Cargo.toml | 4 -- elliptic-curve/Cargo.toml | 12 ++--- elliptic-curve/src/lib.rs | 16 +++--- 5 files changed, 78 insertions(+), 42 deletions(-) diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index 0544ded38..57d4d4c9a 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -42,10 +42,10 @@ jobs: - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features bits - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features dev - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features digest - #- run: cargo build --target ${{ matrix.target }} --release --no-default-features --features ecdh - #- run: cargo build --target ${{ matrix.target }} --release --no-default-features --features hash2curve + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features ecdh + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features hash2curve - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features jwk - #- run: cargo build --target ${{ matrix.target }} --release --no-default-features --features oprf + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features oprf - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features pem - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features pkcs8 - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features sec1 @@ -54,7 +54,7 @@ jobs: - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,arithmetic,pkcs8 - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,serde - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features arithmetic,serde - #- run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,digest,ecdh,hash2curve,jwk,oprf,pem,pkcs8,sec1,serde + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,digest,ecdh,hash2curve,jwk,oprf,pem,pkcs8,sec1,serde minimal-versions: # Temporarily disabled until elliptic-curve 0.13.0-pre.0 is published diff --git a/Cargo.lock b/Cargo.lock index 0804ced48..de3fc5043 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -133,6 +133,15 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0dabb6555f92fb9ee4140454eb5dcd14c7960e1225c6d1a6cc361f032947713e" +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + [[package]] name = "crypto" version = "0.6.0-pre" @@ -202,6 +211,7 @@ dependencies = [ "ff", "group", "hex-literal", + "hkdf", "hybrid-array", "pem-rfc7468", "pkcs8", @@ -209,6 +219,8 @@ dependencies = [ "sec1", "serde_json", "serdect", + "sha2", + "sha3", "subtle", "zeroize", ] @@ -294,6 +306,24 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bcaaec4551594c969335c98c903c1397853d4198408ea609190f420500f6be71" +[[package]] +name = "hkdf" +version = "0.13.0-rc.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6738bc5110ee31b066339f0c9454db29a93db3b0484bbf2afa8a7e9cebc62141" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.13.0-rc.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8dc6a2fcc35ab09136c6df2cdf9ca49790701420a3a6b5db0987dddbabc79b21" +dependencies = [ + "digest", +] + [[package]] name = "hybrid-array" version = "0.3.1" @@ -320,6 +350,15 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +[[package]] +name = "keccak" +version = "0.2.0-pre.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7cdd4f0dc5807b9a2b25dd48a3f58e862606fe7bd47f41ecde36e97422d7e90" +dependencies = [ + "cpufeatures", +] + [[package]] name = "kem" version = "0.3.0-pre.0" @@ -500,6 +539,27 @@ dependencies = [ "serde", ] +[[package]] +name = "sha2" +version = "0.11.0-rc.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa1d2e6b3cc4e43a8258a9a3b17aa5dfd2cc5186c7024bba8a64aa65b2c71a59" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha3" +version = "0.11.0-rc.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e6a92fd180fd205defdc0b78288ce847c7309d329fd6647a814567e67db50e" +dependencies = [ + "digest", + "keccak", +] + [[package]] name = "signature" version = "3.0.0-pre" @@ -630,23 +690,3 @@ name = "zeroize" version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" - -[[patch.unused]] -name = "hkdf" -version = "0.13.0-pre.5" -source = "git+https://github.com/RustCrypto/KDFs.git#2e2dbcd45b8678696e85dcbef922345f3ca04dbf" - -[[patch.unused]] -name = "hmac" -version = "0.13.0-pre.5" -source = "git+https://github.com/RustCrypto/MACs.git#64d671d5c375838173d18e30bc14dffc80c13e51" - -[[patch.unused]] -name = "sha2" -version = "0.11.0-pre.5" -source = "git+https://github.com/RustCrypto/hashes.git#d9ad085ed12dba58d2a6d75d76a17a1b2706c4c7" - -[[patch.unused]] -name = "sha3" -version = "0.11.0-pre.5" -source = "git+https://github.com/RustCrypto/hashes.git#d9ad085ed12dba58d2a6d75d76a17a1b2706c4c7" diff --git a/Cargo.toml b/Cargo.toml index 9bf7c610e..51544176c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,8 +16,4 @@ members = [ [patch.crates-io] digest = { path = "digest" } -hkdf = { git = "https://github.com/RustCrypto/KDFs.git" } -hmac = { git = "https://github.com/RustCrypto/MACs.git" } -sha2 = { git = "https://github.com/RustCrypto/hashes.git" } -sha3 = { git = "https://github.com/RustCrypto/hashes.git" } signature = { path = "signature" } diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 2aedfb50a..dcade0e1e 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -29,7 +29,7 @@ base64ct = { version = "1", optional = true, default-features = false, features digest = { version = "0.11.0-rc.0", optional = true } ff = { version = "=0.14.0-pre.0", optional = true, default-features = false } group = { version = "=0.14.0-pre.0", optional = true, default-features = false } -#hkdf = { version = "=0.13.0-pre.5", optional = true, default-features = false } +hkdf = { version = "0.13.0-rc.0", optional = true, default-features = false } hex-literal = { version = "1", optional = true } pem-rfc7468 = { version = "1.0.0-rc.2", optional = true, features = ["alloc"] } pkcs8 = { version = "0.11.0-rc.1", optional = true, default-features = false } @@ -39,8 +39,8 @@ serde_json = { version = "1.0.121", optional = true, default-features = false, f [dev-dependencies] hex-literal = "1" -#sha2 = "=0.11.0-pre.5" -#sha3 = "=0.11.0-pre.5" +sha2 = "0.11.0-rc.0" +sha3 = "0.11.0-rc.0" [features] default = ["arithmetic"] @@ -62,11 +62,11 @@ std = [ arithmetic = ["group"] bits = ["arithmetic", "ff/bits"] dev = ["arithmetic", "dep:hex-literal", "pem", "pkcs8"] -#ecdh = ["arithmetic", "digest", "dep:hkdf"] +ecdh = ["arithmetic", "digest", "dep:hkdf"] group = ["dep:group", "ff"] -#hash2curve = ["arithmetic", "digest"] +hash2curve = ["arithmetic", "digest"] jwk = ["dep:base64ct", "dep:serde_json", "alloc", "serde", "zeroize/alloc"] -#oprf = ["digest", "hash2curve"] +oprf = ["digest", "hash2curve"] pkcs8 = ["dep:pkcs8", "sec1"] pem = ["dep:pem-rfc7468", "alloc", "arithmetic", "pkcs8", "sec1/pem"] serde = ["dep:serdect", "alloc", "pkcs8", "sec1/serde"] diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 6f433bd3b..8e5ccacaf 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -89,10 +89,10 @@ pub mod scalar; #[cfg(feature = "dev")] pub mod dev; -//#[cfg(feature = "ecdh")] -//pub mod ecdh; -//#[cfg(feature = "hash2curve")] -//pub mod hash2curve; +#[cfg(feature = "ecdh")] +pub mod ecdh; +#[cfg(feature = "hash2curve")] +pub mod hash2curve; #[cfg(feature = "arithmetic")] pub mod ops; #[cfg(feature = "sec1")] @@ -112,8 +112,8 @@ mod public_key; #[cfg(feature = "jwk")] mod jwk; -//#[cfg(feature = "oprf")] -//mod oprf; +#[cfg(feature = "oprf")] +mod oprf; pub use crate::{ error::{Error, Result}, @@ -146,8 +146,8 @@ pub use crate::jwk::{JwkEcKey, JwkParameters}; #[cfg(feature = "pkcs8")] pub use pkcs8; -//#[cfg(feature = "oprf")] -//pub use crate::oprf::OprfParameters; +#[cfg(feature = "oprf")] +pub use crate::oprf::OprfParameters; use core::{ fmt::Debug, From d0b53580629efda67e17ddd6e1b85ae80dcfbf12 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 29 May 2025 09:24:33 -0600 Subject: [PATCH 1372/1461] elliptic-curve v0.14.0-rc.2 (#1871) --- Cargo.lock | 2 +- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index de3fc5043..7e8d06a24 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -202,7 +202,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.14.0-rc.1" +version = "0.14.0-rc.2" dependencies = [ "base16ct", "base64ct", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index dcade0e1e..21753d6bf 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.14.0-rc.1" +version = "0.14.0-rc.2" authors = ["RustCrypto Developers"] edition = "2024" rust-version = "1.85" From 74e5e12e53e08af06f4e4247c9f74645b3c2b801 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 29 May 2025 09:32:51 -0600 Subject: [PATCH 1373/1461] signature v3.0.0-rc.0 (#1872) --- Cargo.lock | 2 +- async-signature/Cargo.toml | 2 +- crypto/Cargo.toml | 4 ++-- signature/Cargo.toml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7e8d06a24..5fd7c8814 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -562,7 +562,7 @@ dependencies = [ [[package]] name = "signature" -version = "3.0.0-pre" +version = "3.0.0-rc.0" dependencies = [ "digest", "rand_core", diff --git a/async-signature/Cargo.toml b/async-signature/Cargo.toml index 231c36549..a8515e233 100644 --- a/async-signature/Cargo.toml +++ b/async-signature/Cargo.toml @@ -13,7 +13,7 @@ categories = ["cryptography", "no-std"] description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" [dependencies] -signature = "=3.0.0-pre" +signature = "3.0.0-rc.0" [features] digest = ["signature/digest"] diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index b165ca592..b183cb171 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -19,9 +19,9 @@ crypto-common = { version = "0.2.0-rc.3", path = "../crypto-common", default-fea aead = { version = "0.6.0-rc.0", path = "../aead", optional = true } cipher = { version = "0.5.0-pre.7", path = "../cipher", optional = true } digest = { version = "0.11.0-rc.0", path = "../digest", optional = true, features = ["mac"] } -elliptic-curve = { version = "0.14.0-rc.1", path = "../elliptic-curve", optional = true } +elliptic-curve = { version = "0.14.0-rc.2", path = "../elliptic-curve", optional = true } password-hash = { version = "0.6.0-rc.0", path = "../password-hash", optional = true } -signature = { version = "=3.0.0-pre", path = "../signature", optional = true, default-features = false } +signature = { version = "3.0.0-rc.0", path = "../signature", optional = true, default-features = false } universal-hash = { version = "0.6.0-rc.0", path = "../universal-hash", optional = true } [features] diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 56f79173a..7435126ae 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "signature" -version = "3.0.0-pre" +version = "3.0.0-rc.0" authors = ["RustCrypto Developers"] edition = "2024" rust-version = "1.85" From b8f03c57df51d55b7970e6e3007f47c6a7f88699 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 29 May 2025 13:13:54 -0600 Subject: [PATCH 1374/1461] aead v0.6.0-rc.1 (#1873) --- Cargo.lock | 2 +- aead/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5fd7c8814..c686543c2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15,7 +15,7 @@ dependencies = [ [[package]] name = "aead" -version = "0.6.0-rc.0" +version = "0.6.0-rc.1" dependencies = [ "arrayvec", "blobby", diff --git a/aead/Cargo.toml b/aead/Cargo.toml index 50768f9d6..fbfdc8023 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aead" -version = "0.6.0-rc.0" +version = "0.6.0-rc.1" authors = ["RustCrypto Developers"] edition = "2024" rust-version = "1.85" From 6babfcbca018856282c4ee7f5dd211e70d916018 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 29 May 2025 14:56:05 -0600 Subject: [PATCH 1375/1461] universal-hash v0.6.0-rc.1 (#1875) --- Cargo.lock | 2 +- crypto/Cargo.toml | 2 +- universal-hash/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c686543c2..17f247391 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -632,7 +632,7 @@ checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] name = "universal-hash" -version = "0.6.0-rc.0" +version = "0.6.0-rc.1" dependencies = [ "crypto-common", "subtle", diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index b183cb171..9542cf47a 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -22,7 +22,7 @@ digest = { version = "0.11.0-rc.0", path = "../digest", optional = true, feature elliptic-curve = { version = "0.14.0-rc.2", path = "../elliptic-curve", optional = true } password-hash = { version = "0.6.0-rc.0", path = "../password-hash", optional = true } signature = { version = "3.0.0-rc.0", path = "../signature", optional = true, default-features = false } -universal-hash = { version = "0.6.0-rc.0", path = "../universal-hash", optional = true } +universal-hash = { version = "0.6.0-rc.1", path = "../universal-hash", optional = true } [features] std = ["elliptic-curve/std"] diff --git a/universal-hash/Cargo.toml b/universal-hash/Cargo.toml index db7923dbb..164fa7df7 100644 --- a/universal-hash/Cargo.toml +++ b/universal-hash/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "universal-hash" -version = "0.6.0-rc.0" +version = "0.6.0-rc.1" authors = ["RustCrypto Developers"] edition = "2024" rust-version = "1.85" From 4e0c383875b7905e64cfe22563d24ed3f8e40525 Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Thu, 29 May 2025 22:51:49 +0000 Subject: [PATCH 1376/1461] password-hash v0.6.0-rc.1 (#1876) --- Cargo.lock | 2 +- password-hash/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 17f247391..fd49656e5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -410,7 +410,7 @@ dependencies = [ [[package]] name = "password-hash" -version = "0.6.0-rc.0" +version = "0.6.0-rc.1" dependencies = [ "base64ct", "rand_core", diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index 99a51eca3..a5c523ba5 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "password-hash" -version = "0.6.0-rc.0" +version = "0.6.0-rc.1" authors = ["RustCrypto Developers"] edition = "2024" rust-version = "1.85" From f9ab27ccb60ea9a9663cae3df53e446f3beaf787 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 30 May 2025 07:39:03 -0600 Subject: [PATCH 1377/1461] cipher v0.5.0-rc.0 (#1874) --- Cargo.lock | 2 +- cipher/Cargo.toml | 2 +- crypto/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fd49656e5..3634cb21b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -119,7 +119,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cipher" -version = "0.5.0-pre.8" +version = "0.5.0-rc.0" dependencies = [ "blobby", "crypto-common", diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index c8b2b0325..393703371 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cipher" -version = "0.5.0-pre.8" +version = "0.5.0-rc.0" authors = ["RustCrypto Developers"] edition = "2024" rust-version = "1.85" diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 9542cf47a..fbcf281f1 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -17,7 +17,7 @@ crypto-common = { version = "0.2.0-rc.3", path = "../crypto-common", default-fea # optional dependencies aead = { version = "0.6.0-rc.0", path = "../aead", optional = true } -cipher = { version = "0.5.0-pre.7", path = "../cipher", optional = true } +cipher = { version = "0.5.0-rc.0", path = "../cipher", optional = true } digest = { version = "0.11.0-rc.0", path = "../digest", optional = true, features = ["mac"] } elliptic-curve = { version = "0.14.0-rc.2", path = "../elliptic-curve", optional = true } password-hash = { version = "0.6.0-rc.0", path = "../password-hash", optional = true } From baf8d73304ce4ef3ea84ad0989cbd1e2dcd4f31d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 30 May 2025 18:30:58 -0600 Subject: [PATCH 1378/1461] elliptic-curve v0.14.0-rc.3 (#1878) Bumps `crypto-bigint` to v0.7.0-pre.4 --- Cargo.lock | 6 +++--- elliptic-curve/Cargo.toml | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3634cb21b..6fd5180be 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -158,9 +158,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.7.0-pre.3" +version = "0.7.0-pre.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f727d84cf16cb51297e4388421e2e51b2f94ffe92ee1d8664d81676901196fa3" +checksum = "edaae5fb9dac79a07260e0b2006799ff4f1d342ab243fd7d0892215113b27904" dependencies = [ "hybrid-array", "num-traits", @@ -202,7 +202,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.14.0-rc.2" +version = "0.14.0-rc.3" dependencies = [ "base16ct", "base64ct", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 21753d6bf..1f9499755 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.14.0-rc.2" +version = "0.14.0-rc.3" authors = ["RustCrypto Developers"] edition = "2024" rust-version = "1.85" @@ -18,7 +18,7 @@ and public/secret keys composed thereof. [dependencies] base16ct = "0.2" -crypto-bigint = { version = "=0.7.0-pre.3", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } +crypto-bigint = { version = "=0.7.0-pre.4", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } hybrid-array = { version = "0.3", default-features = false, features = ["zeroize"] } rand_core = { version = "0.9.0", default-features = false } subtle = { version = "2.6", default-features = false } From 52a989fd956ab530502f4d8612ce7a56c6b2bddc Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 2 Jun 2025 06:37:02 -0600 Subject: [PATCH 1379/1461] aead: test fixups (#1881) - ~~There's no reason for these tests to be gated on `alloc`~~ (aah, we need it, but can go finer-grained) - Fixes comment on object safety / dyn compatibility test for `Aead` - Adds dyn compatibility test for `AeadInOut` --- aead/src/lib.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/aead/src/lib.rs b/aead/src/lib.rs index a78c470cd..c6c12637a 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -431,12 +431,16 @@ impl Buffer for heapless::Vec { } } -#[cfg(feature = "alloc")] #[cfg(test)] mod tests { use super::*; - /// Ensure that `AeadInPlace` is object-safe + /// Ensure that `Aead` is `dyn`-compatible + #[cfg(feature = "alloc")] + #[allow(dead_code)] + type DynAead = dyn Aead; + + /// Ensure that `AeadInOut` is `dyn`-compatible #[allow(dead_code)] - type DynAeadInPlace = dyn Aead; + type DynAeadInOut = dyn AeadInOut; } From cac73b049b4ce1e671edbc27666e0299779cd9d1 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 2 Jun 2025 06:49:59 -0600 Subject: [PATCH 1380/1461] aead: deprecated `AeadInPlace` trait (#1882) `AeadInPlace` was removed in #1798, however in migrating some older code I thought it would be really helpful to have backwards compatibility and deprecations in place to help people migrate to the new names, especially as the "in place" -> "inout" migrations aren't entirely intuitive. --- aead/src/lib.rs | 92 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/aead/src/lib.rs b/aead/src/lib.rs index c6c12637a..a1fbc5f84 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -329,6 +329,98 @@ pub trait AeadInOut: AeadCore { } } +/// Legacy in-place stateless AEAD trait. +/// +/// NOTE: deprecated! Please migrate to [`AeadInOut`]. +#[deprecated(since = "0.6.0", note = "use `AeadInOut` instead")] +pub trait AeadInPlace: AeadCore { + /// Encrypt the given buffer containing a plaintext message in-place. + #[deprecated(since = "0.6.0", note = "use `AeadInOut::encrypt_in_place` instead")] + fn encrypt_in_place( + &self, + nonce: &Nonce, + associated_data: &[u8], + buffer: &mut dyn Buffer, + ) -> Result<()>; + + /// Encrypt the data in-place, returning the authentication tag + #[deprecated( + since = "0.6.0", + note = "use `AeadInOut::encrypt_inout_detached` instead" + )] + fn encrypt_in_place_detached( + &self, + nonce: &Nonce, + associated_data: &[u8], + buffer: &mut [u8], + ) -> Result>; + + /// Decrypt the message in-place, returning an error in the event the + /// provided authentication tag does not match the given ciphertext. + #[deprecated(since = "0.6.0", note = "use `AeadInOut::decrypt_in_place` instead")] + fn decrypt_in_place( + &self, + nonce: &Nonce, + associated_data: &[u8], + buffer: &mut dyn Buffer, + ) -> Result<()>; + + /// Decrypt the message in-place, returning an error in the event the provided + /// authentication tag does not match the given ciphertext (i.e. ciphertext + /// is modified/unauthentic) + #[deprecated( + since = "0.6.0", + note = "use `AeadInOut::decrypt_inout_detached` instead" + )] + fn decrypt_in_place_detached( + &self, + nonce: &Nonce, + associated_data: &[u8], + buffer: &mut [u8], + tag: &Tag, + ) -> Result<()>; +} + +#[allow(deprecated)] +impl AeadInPlace for T { + fn encrypt_in_place( + &self, + nonce: &Nonce, + associated_data: &[u8], + buffer: &mut dyn Buffer, + ) -> Result<()> { + ::encrypt_in_place(self, nonce, associated_data, buffer) + } + + fn encrypt_in_place_detached( + &self, + nonce: &Nonce, + associated_data: &[u8], + buffer: &mut [u8], + ) -> Result> { + self.encrypt_inout_detached(nonce, associated_data, buffer.into()) + } + + fn decrypt_in_place( + &self, + nonce: &Nonce, + associated_data: &[u8], + buffer: &mut dyn Buffer, + ) -> Result<()> { + ::decrypt_in_place(self, nonce, associated_data, buffer) + } + + fn decrypt_in_place_detached( + &self, + nonce: &Nonce, + associated_data: &[u8], + buffer: &mut [u8], + tag: &Tag, + ) -> Result<()> { + self.decrypt_inout_detached(nonce, associated_data, buffer.into(), tag) + } +} + /// AEAD payloads (message + AAD). /// /// Combination of a message (plaintext or ciphertext) and From 01886bcd83a67390f0c4401b796c1f220f1d267d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 2 Jun 2025 14:09:42 -0600 Subject: [PATCH 1381/1461] kem: use Cargo Book ordering for Cargo.toml (#1883) See also: RustCrypto/meta#22 --- kem/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kem/Cargo.toml b/kem/Cargo.toml index f6d0e7a61..5c0ce0364 100644 --- a/kem/Cargo.toml +++ b/kem/Cargo.toml @@ -1,16 +1,16 @@ [package] -description = "Traits for key encapsulation mechanisms" +name = "kem" version = "0.3.0-pre.0" authors = ["RustCrypto Developers"] edition = "2024" rust-version = "1.85" +description = "Traits for key encapsulation mechanisms" documentation = "https://docs.rs/kem" readme = "README.md" repository = "https://github.com/RustCrypto/traits" license = "Apache-2.0 OR MIT" keywords = ["crypto"] categories = ["cryptography", "no-std"] -name = "kem" [dependencies] rand_core = "0.9" From de9be7073aef660c61e6105059f3e89e07fe3cc5 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 2 Jun 2025 14:13:26 -0600 Subject: [PATCH 1382/1461] kem: move description to end of Cargo.toml --- kem/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kem/Cargo.toml b/kem/Cargo.toml index 5c0ce0364..8c4167617 100644 --- a/kem/Cargo.toml +++ b/kem/Cargo.toml @@ -4,13 +4,13 @@ version = "0.3.0-pre.0" authors = ["RustCrypto Developers"] edition = "2024" rust-version = "1.85" -description = "Traits for key encapsulation mechanisms" documentation = "https://docs.rs/kem" readme = "README.md" repository = "https://github.com/RustCrypto/traits" license = "Apache-2.0 OR MIT" keywords = ["crypto"] categories = ["cryptography", "no-std"] +description = "Traits for key encapsulation mechanisms" [dependencies] rand_core = "0.9" From 57c9e791f8df3199b4c11ab9a3dd258255a79a42 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Mon, 2 Jun 2025 23:51:35 +0200 Subject: [PATCH 1383/1461] Allow `BatchInvert` with zero elements (#1884) --- elliptic-curve/src/ops.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/elliptic-curve/src/ops.rs b/elliptic-curve/src/ops.rs index c7c02cf91..7457d86c9 100644 --- a/elliptic-curve/src/ops.rs +++ b/elliptic-curve/src/ops.rs @@ -97,9 +97,12 @@ fn invert_batch_internal( field_elements_pad: &mut [T], ) -> Choice { let batch_size = field_elements.len(); - if batch_size == 0 || batch_size != field_elements_pad.len() { + if batch_size != field_elements_pad.len() { return Choice::from(0); } + if batch_size == 0 { + return Choice::from(1); + } let mut acc = field_elements[0]; field_elements_pad[0] = acc; From f73c1a23dde6847d0706bf06418f012580637dd6 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Tue, 3 Jun 2025 00:06:30 +0200 Subject: [PATCH 1384/1461] `signature`: add `MultipartSigner` and `MultipartVerifier` (#1880) This PR adds new traits for multipart messages: `MultipartSigner`, `RandomizedMultipartSigner`, `RandomizedMultipartSignerMut` and `MultipartVerifier`. The idea here is to allow non-contiguous bytes to be passed, which is necessary when the message has to be constructed from multiple sources without wanting to allocate memory for a contiguous message. E.g. for `no_std` environments or when the message is rather big but pre-hashing is not applicable, e.g. PureEdDSA, ML-DSA or SLH-DSA. I know this is a rather big breaking change, so let me know what you think! These new traits can be implemented by a bunch of crates: - [x] `ecdsa`: https://github.com/RustCrypto/signatures/pull/982 - [x] `ml-dsa`: https://github.com/RustCrypto/signatures/pull/982 - [x] `slh-dsa`: https://github.com/RustCrypto/signatures/pull/982 - [x] `bign256`: https://github.com/RustCrypto/elliptic-curves/pull/1221 - [x] `sm2`: https://github.com/RustCrypto/elliptic-curves/pull/1221 - [x] `k256`: https://github.com/RustCrypto/elliptic-curves/pull/1221 - [x] `dsa`: https://github.com/RustCrypto/signatures/pull/982 - [x] `lms`: https://github.com/RustCrypto/signatures/pull/982 - [x] `rsa`: https://github.com/RustCrypto/RSA/pull/525 - [ ] `ed25519-dalek` Resolves https://github.com/RustCrypto/signatures/issues/959. --- signature/src/signer.rs | 52 +++++++++++++++++++++++++++++++++++++++ signature/src/verifier.rs | 7 ++++++ 2 files changed, 59 insertions(+) diff --git a/signature/src/signer.rs b/signature/src/signer.rs index 02ffe0f9c..b9eec6eab 100644 --- a/signature/src/signer.rs +++ b/signature/src/signer.rs @@ -24,6 +24,20 @@ pub trait Signer { fn try_sign(&self, msg: &[u8]) -> Result; } +/// Equivalent of [`Signer`] but the message is provided in non-contiguous byte slices. +pub trait MultipartSigner { + /// Equivalent of [`Signer::sign()`] but the message + /// is provided in non-contiguous byte slices. + fn multipart_sign(&self, msg: &[&[u8]]) -> S { + self.try_multipart_sign(msg) + .expect("signature operation failed") + } + + /// Equivalent of [`Signer::try_sign()`] but the + /// message is provided in non-contiguous byte slices. + fn try_multipart_sign(&self, msg: &[&[u8]]) -> Result; +} + /// Sign the provided message bytestring using `&mut Self` (e.g. an evolving /// cryptographic key such as a stateful hash-based signature), returning a /// digital signature. @@ -103,6 +117,25 @@ pub trait RandomizedSigner { ) -> Result; } +/// Equivalent of [`RandomizedSigner`] but the message is provided in non-contiguous byte slices. +#[cfg(feature = "rand_core")] +pub trait RandomizedMultipartSigner { + /// Equivalent of [`RandomizedSigner::sign_with_rng()`] but + /// the message is provided in non-contiguous byte slices. + fn multipart_sign_with_rng(&self, rng: &mut R, msg: &[&[u8]]) -> S { + self.try_multipart_sign_with_rng(rng, msg) + .expect("signature operation failed") + } + + /// Equivalent of [`RandomizedSigner::try_sign_with_rng()`] but + /// the message is provided in non-contiguous byte slices. + fn try_multipart_sign_with_rng( + &self, + rng: &mut R, + msg: &[&[u8]], + ) -> Result; +} + /// Combination of [`DigestSigner`] and [`RandomizedSigner`] with support for /// computing a signature over a digest which requires entropy from an RNG. #[cfg(all(feature = "digest", feature = "rand_core"))] @@ -147,6 +180,25 @@ pub trait RandomizedSignerMut { ) -> Result; } +/// Equivalent of [`RandomizedSignerMut`] but the message is provided in non-contiguous byte slices. +#[cfg(feature = "rand_core")] +pub trait RandomizedMultipartSignerMut { + /// Equivalent of [`RandomizedSignerMut::sign_with_rng()`] but + /// the message is provided in non-contiguous byte slices. + fn multipart_sign_with_rng(&mut self, rng: &mut R, msg: &[&[u8]]) -> S { + self.try_multipart_sign_with_rng(rng, msg) + .expect("signature operation failed") + } + + /// Equivalent of [`RandomizedSignerMut::try_sign_with_rng()`] + /// but the message is provided in non-contiguous byte slices. + fn try_multipart_sign_with_rng( + &mut self, + rng: &mut R, + msg: &[&[u8]], + ) -> Result; +} + /// Blanket impl of [`RandomizedSignerMut`] for all [`RandomizedSigner`] types. #[cfg(feature = "rand_core")] impl> RandomizedSignerMut for T { diff --git a/signature/src/verifier.rs b/signature/src/verifier.rs index 65409a929..7c824f72d 100644 --- a/signature/src/verifier.rs +++ b/signature/src/verifier.rs @@ -14,6 +14,13 @@ pub trait Verifier { fn verify(&self, msg: &[u8], signature: &S) -> Result<(), Error>; } +/// Equivalent of [`Verifier`] but the message is provided in non-contiguous byte slices. +pub trait MultipartVerifier { + /// Equivalent of [`Verifier::verify()`] but the + /// message is provided in non-contiguous byte slices. + fn multipart_verify(&self, msg: &[&[u8]], signature: &S) -> Result<(), Error>; +} + /// Verify the provided signature for the given prehashed message [`Digest`] /// is authentic. /// From fe7d61fc8b187e23b1013c35636397f41e288c3d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Jun 2025 16:21:45 -0600 Subject: [PATCH 1385/1461] build(deps): bump crate-ci/typos from 1.32.0 to 1.33.1 (#1885) --- .github/workflows/workspace.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index 6947384c5..cf07eadfe 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -52,4 +52,4 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: crate-ci/typos@v1.32.0 + - uses: crate-ci/typos@v1.33.1 From a2ce6890145793fb43b952d8840f004ccdece9d0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Jun 2025 03:04:47 +0300 Subject: [PATCH 1386/1461] Update Cargo.lock (#1887) --- Cargo.lock | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6fd5180be..8668d7ba5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -179,9 +179,9 @@ dependencies = [ [[package]] name = "der" -version = "0.8.0-rc.2" +version = "0.8.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a348a791b3df164315b6733835b128f52f99bd76bc3b19adbd574bde4a1be2e7" +checksum = "b00a9651bf9c00a38b7c383073cb22fb42f20a5f978c9f97ad5c7128cbd3c1bd" dependencies = [ "const-oid", "pem-rfc7468", @@ -336,9 +336,9 @@ dependencies = [ [[package]] name = "inout" -version = "0.2.0-rc.4" +version = "0.2.0-rc.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac5e145e8ade9f74c0a5efc60ccb4e714b0144f7e2220b7ca64254feee71c57f" +checksum = "c774c86bce20ea04abe1c37cf0051c5690079a3a28ef5fdac2a5a0412b3d7d74" dependencies = [ "block-padding", "hybrid-array", @@ -419,18 +419,18 @@ dependencies = [ [[package]] name = "pem-rfc7468" -version = "1.0.0-rc.2" +version = "1.0.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2dfbfa5c6f0906884269722c5478e72fd4d6c0e24fe600332c6d62359567ce1" +checksum = "a8e58fab693c712c0d4e88f8eb3087b6521d060bcaf76aeb20cb192d809115ba" dependencies = [ "base64ct", ] [[package]] name = "pkcs8" -version = "0.11.0-rc.3" +version = "0.11.0-rc.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb59d311663eb310da092cb3b4525dac863f3fff825898db1a5a2f46420c5e84" +checksum = "3f1843d4345dfe1a55e487db747a04c01af50415b03e937410e0a41d8cc24ec7" dependencies = [ "der", "spki", @@ -484,9 +484,9 @@ checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "sec1" -version = "0.8.0-rc.4" +version = "0.8.0-rc.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a017a4aa8f0bd51e9d0184d98042dfe9285218fec098493f47d9a8aa0f1a3f27" +checksum = "e4855dd9b15e8e469fad23529698f7f7b7a6b250a81c88b1f9d7efe1abca7717" dependencies = [ "base16ct", "der", @@ -570,9 +570,9 @@ dependencies = [ [[package]] name = "spki" -version = "0.8.0-rc.1" +version = "0.8.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37ac66481418fd7afdc584adcf3be9aa572cf6c2858814494dc2a01755f050bc" +checksum = "c2f0e2bdca9b00f5be6dd3bb6647d50fd0f24a508a95f78e3bb2fe98d0403c85" dependencies = [ "base64ct", "der", From 62453c014ddcecbc1e2a617c1bfd61adca54776c Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 2 Jun 2025 18:12:30 -0600 Subject: [PATCH 1387/1461] async-signature: replace code with deprecation notice (#1886) We've merged the relevant functionality into the `signature` crate proper --- .github/workflows/async-signature.yml | 67 --------- Cargo.lock | 7 - Cargo.toml | 1 - async-signature/CHANGELOG.md | 79 ---------- async-signature/Cargo.toml | 24 --- async-signature/LICENSE-APACHE | 201 -------------------------- async-signature/LICENSE-MIT | 25 ---- async-signature/README.md | 41 +----- async-signature/src/hazmat.rs | 20 --- async-signature/src/lib.rs | 35 ----- async-signature/tests/mock_impl.rs | 40 ----- 11 files changed, 4 insertions(+), 536 deletions(-) delete mode 100644 .github/workflows/async-signature.yml delete mode 100644 async-signature/CHANGELOG.md delete mode 100644 async-signature/Cargo.toml delete mode 100644 async-signature/LICENSE-APACHE delete mode 100644 async-signature/LICENSE-MIT delete mode 100644 async-signature/src/hazmat.rs delete mode 100644 async-signature/src/lib.rs delete mode 100644 async-signature/tests/mock_impl.rs diff --git a/.github/workflows/async-signature.yml b/.github/workflows/async-signature.yml deleted file mode 100644 index ba351c4ef..000000000 --- a/.github/workflows/async-signature.yml +++ /dev/null @@ -1,67 +0,0 @@ -name: async-signature - -on: - pull_request: - paths: - - "async-signature/**" - - "signature/**" - - "Cargo.*" - push: - branches: master - -defaults: - run: - working-directory: async-signature - -env: - CARGO_INCREMENTAL: 0 - RUSTFLAGS: "-Dwarnings" - -jobs: - no_std: - runs-on: ubuntu-latest - strategy: - matrix: - rust: - - 1.85.0 # MSRV - - stable - target: - - thumbv7em-none-eabi - - wasm32-unknown-unknown - steps: - - uses: actions/checkout@v4 - - uses: RustCrypto/actions/cargo-cache@master - - uses: dtolnay/rust-toolchain@master - with: - toolchain: ${{ matrix.rust }} - targets: ${{ matrix.target }} - - run: cargo build --target ${{ matrix.target }} --release --no-default-features - - test: - runs-on: ubuntu-latest - strategy: - matrix: - rust: - - 1.85.0 # Minimum Rust version the tests pass on - - stable - steps: - - uses: actions/checkout@v4 - - uses: RustCrypto/actions/cargo-cache@master - - uses: dtolnay/rust-toolchain@master - with: - toolchain: ${{ matrix.rust }} - - run: cargo test --release - - run: cargo test --all-features --release - - minimal-versions: - if: false # Temporarily disabled until signature v2.3.0 is published - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: RustCrypto/actions/cargo-cache@master - - uses: dtolnay/rust-toolchain@nightly - - run: cargo update -Z minimal-versions - - uses: dtolnay/rust-toolchain@stable - - uses: RustCrypto/actions/cargo-hack-install@master - - run: rm ../Cargo.toml - - run: cargo hack test --release --feature-powerset diff --git a/Cargo.lock b/Cargo.lock index 8668d7ba5..e112d721f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -31,13 +31,6 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" -[[package]] -name = "async-signature" -version = "0.6.0-pre.4" -dependencies = [ - "signature", -] - [[package]] name = "autocfg" version = "1.4.0" diff --git a/Cargo.toml b/Cargo.toml index 51544176c..f89b4edce 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,6 @@ resolver = "3" members = [ "aead", - "async-signature", "cipher", "crypto", "crypto-common", diff --git a/async-signature/CHANGELOG.md b/async-signature/CHANGELOG.md deleted file mode 100644 index bef58c09a..000000000 --- a/async-signature/CHANGELOG.md +++ /dev/null @@ -1,79 +0,0 @@ -# Changelog -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## 0.6.0 (UNRELEASED) -### Changed -- Edition changed to 2024 and MSRV bumped to 1.85 ([#1759]) - -[#1759]: https://github.com/RustCrypto/traits/pull/1759 - -## 0.5.1 (2024-04-02) -### Added -- `no_std` support ([#1544]) - -[#1544]: https://github.com/RustCrypto/traits/pull/1544 - -## 0.5.0 (2024-01-02) -### Added -- Debug impls ([#1407]) - -### Changed -- Move to AFIT; MSRV 1.75 ([#1428]) - -### Removed -- `'static` bounds ([#1430]) - -[#1407]: https://github.com/RustCrypto/traits/pull/1407 -[#1428]: https://github.com/RustCrypto/traits/pull/1428 -[#1430]: https://github.com/RustCrypto/traits/pull/1430 - -## 0.4.0 (2023-11-12) -### Changed -- MSRV 1.60 ([#1387]) - -### Removed -- Mandatory `Send` + `Sync` bounds ([#1375]) - -[#1375]: https://github.com/RustCrypto/traits/pull/1375 -[#1387]: https://github.com/RustCrypto/traits/pull/1387 - -## 0.3.0 (2023-01-15) -### Changed -- Bump `signature` to v2 ([#1141], [#1211]) - -### Removed -- `AsyncKeypair` is no longer needed due to `signature` v2 bounds changes ([#1141]) - -[#1141]: https://github.com/RustCrypto/traits/pull/1141 -[#1211]: https://github.com/RustCrypto/traits/pull/1211 - -## 0.2.1 (2022-09-15) -### Changed -- Relax `AsyncKeypair` bounds ([#1107]) -- Deprecate `AsyncKeypair` ([#1112]) - -[#1107]: https://github.com/RustCrypto/traits/pull/1107 -[#1112]: https://github.com/RustCrypto/traits/pull/1112 - -## 0.2.0 (2022-08-14) [YANKED] -### Added -- `AsyncKeypair` trait ([#1085]) - -### Changed -- Bump minimum `signature` requirement to v1.6 ([#1084]) - -[#1084]: https://github.com/RustCrypto/traits/pull/1084 -[#1085]: https://github.com/RustCrypto/traits/pull/1085 - -## 0.1.0 (2022-01-04) -### Changed -- Bump `signature` crate dependency to v1.5 ([#850], [#867]) - -[#850]: https://github.com/RustCrypto/traits/pull/850 -[#867]: https://github.com/RustCrypto/traits/pull/867 - -## 0.0.1 (2020-10-06) -- Initial release diff --git a/async-signature/Cargo.toml b/async-signature/Cargo.toml deleted file mode 100644 index a8515e233..000000000 --- a/async-signature/Cargo.toml +++ /dev/null @@ -1,24 +0,0 @@ -[package] -name = "async-signature" -version = "0.6.0-pre.4" -authors = ["RustCrypto Developers"] -edition = "2024" -rust-version = "1.85" -documentation = "https://docs.rs/async-signature" -readme = "README.md" -repository = "https://github.com/RustCrypto/traits" -license = "Apache-2.0 OR MIT" -keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"] -categories = ["cryptography", "no-std"] -description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" - -[dependencies] -signature = "3.0.0-rc.0" - -[features] -digest = ["signature/digest"] -std = [] -rand_core = ["signature/rand_core"] - -[package.metadata.docs.rs] -all-features = true diff --git a/async-signature/LICENSE-APACHE b/async-signature/LICENSE-APACHE deleted file mode 100644 index 78173fa2e..000000000 --- a/async-signature/LICENSE-APACHE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - -Copyright [yyyy] [name of copyright owner] - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/async-signature/LICENSE-MIT b/async-signature/LICENSE-MIT deleted file mode 100644 index b723e3eee..000000000 --- a/async-signature/LICENSE-MIT +++ /dev/null @@ -1,25 +0,0 @@ -Copyright (c) 2020-2025 RustCrypto Developers - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without -limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/async-signature/README.md b/async-signature/README.md index 13fbf3c13..5011c81d7 100644 --- a/async-signature/README.md +++ b/async-signature/README.md @@ -1,41 +1,8 @@ -# RustCrypto: `async-signature` +## 🚨 DEPRECATED! 🚨 -[![crate][crate-image]][crate-link] -[![Docs][docs-image]][docs-link] -![Apache2/MIT licensed][license-image] -![Rust Version][rustc-image] -[![Project Chat][chat-image]][chat-link] -[![Build Status][build-image]][build-link] +The `async-signature` crate is deprecated and will not receive further releases. -## Deprecated +The relevant functionality has been merged into the `signature` crate: -This crate is now deprecated, all the types are available in [`signature`][signature-crate] + -## License - -Licensed under either of - - * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) - * [MIT license](http://opensource.org/licenses/MIT) - -at your option. - -### Contribution - -Unless you explicitly state otherwise, any contribution intentionally submitted -for inclusion in the work by you, as defined in the Apache-2.0 license, shall be -dual licensed as above, without any additional terms or conditions. - -[//]: # (badges) - -[crate-image]: https://img.shields.io/crates/v/async-signature.svg -[crate-link]: https://crates.io/crates/async-signature -[docs-image]: https://docs.rs/async-signature/badge.svg -[docs-link]: https://docs.rs/async-signature/ -[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg -[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg -[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260048-signatures -[build-image]: https://github.com/RustCrypto/traits/actions/workflows/async-signature.yml/badge.svg?branch=master -[build-link]: https://github.com/RustCrypto/traits/actions/workflows/async-signature.yml?query=branch:master -[signature-crate]: https://crates.io/crates/signature diff --git a/async-signature/src/hazmat.rs b/async-signature/src/hazmat.rs deleted file mode 100644 index 5fbdda362..000000000 --- a/async-signature/src/hazmat.rs +++ /dev/null @@ -1,20 +0,0 @@ -//! Hazardous Materials: low-level APIs which can be insecure if misused. -//! -//! The traits in this module are not generally recommended, and should only be -//! used in special cases where they are specifically needed. -//! -//! Using them incorrectly can introduce security vulnerabilities. Please -//! carefully read the documentation before attempting to use them. - -#[deprecated( - since = "0.6.0", - note = "use `signature::hazmat::AsyncPrehashSigner` instead" -)] -pub use signature::hazmat::AsyncPrehashSigner; - -#[cfg(feature = "rand_core")] -#[deprecated( - since = "0.6.0", - note = "use `signature::hazmat::AsyncRandomizedPrehashSigner` instead" -)] -pub use signature::hazmat::AsyncRandomizedPrehashSigner; diff --git a/async-signature/src/lib.rs b/async-signature/src/lib.rs deleted file mode 100644 index 74fbee82b..000000000 --- a/async-signature/src/lib.rs +++ /dev/null @@ -1,35 +0,0 @@ -#![no_std] -#![doc = include_str!("../README.md")] -#![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg" -)] -#![cfg_attr(docsrs, feature(doc_auto_cfg))] -#![forbid(unsafe_code)] -#![warn( - missing_docs, - rust_2018_idioms, - unused_qualifications, - missing_debug_implementations -)] - -pub mod hazmat; - -pub use signature::{self, Error}; - -#[cfg(feature = "digest")] -pub use signature::digest::{self, Digest}; - -#[deprecated(since = "0.6.0", note = "use `signature::AsyncSigner` instead")] -pub use signature::AsyncSigner; - -#[cfg(feature = "digest")] -#[deprecated(since = "0.6.0", note = "use `signature::AsyncDigestSigner` instead")] -pub use signature::AsyncDigestSigner; - -#[cfg(feature = "rand_core")] -#[deprecated( - since = "0.6.0", - note = "use `signature::AsyncRandomizedSigner` instead" -)] -pub use signature::AsyncRandomizedSigner; diff --git a/async-signature/tests/mock_impl.rs b/async-signature/tests/mock_impl.rs deleted file mode 100644 index d8e17ea45..000000000 --- a/async-signature/tests/mock_impl.rs +++ /dev/null @@ -1,40 +0,0 @@ -#![allow(dead_code)] -//! Check compilation of the various traits exposed by async_signature. -//! -//! This is intended to make sure we can implement those traits without conflict from a blanket -//! implementation. - -use async_signature::{AsyncSigner, Error}; - -struct Signature; - -struct MockSigner; - -impl AsyncSigner for MockSigner { - async fn sign_async(&self, _msg: &[u8]) -> Result { - unimplemented!("just meant to check compilation") - } -} - -#[cfg(feature = "digest")] -impl async_signature::AsyncDigestSigner for MockSigner -where - D: async_signature::Digest, -{ - async fn sign_digest_async(&self, _digest: D) -> Result { - unimplemented!("just meant to check compilation") - } -} - -#[cfg(feature = "rand_core")] -impl async_signature::AsyncRandomizedSigner for MockSigner { - async fn try_sign_with_rng_async< - R: async_signature::signature::rand_core::TryCryptoRng + ?Sized, - >( - &self, - _rng: &mut R, - _msg: &[u8], - ) -> Result { - unimplemented!("just meant to check compilation") - } -} From faf3f65bd129e6ec881f841cfb47c6a852232561 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 2 Jun 2025 20:16:48 -0600 Subject: [PATCH 1388/1461] signature 3.0.0-rc.1 (#1888) Includes `MultipartSigner`/`MultipartVerifier` --- Cargo.lock | 2 +- signature/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e112d721f..1394b6a3c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -555,7 +555,7 @@ dependencies = [ [[package]] name = "signature" -version = "3.0.0-rc.0" +version = "3.0.0-rc.1" dependencies = [ "digest", "rand_core", diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 7435126ae..1d29f9ead 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "signature" -version = "3.0.0-rc.0" +version = "3.0.0-rc.1" authors = ["RustCrypto Developers"] edition = "2024" rust-version = "1.85" From c190381106c260f5a577587385bd3234dc3f9874 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 5 Jun 2025 11:13:31 -0600 Subject: [PATCH 1389/1461] elliptic-curve: expose `AffineCoordinates::y` (#1891) In the past we've deliberately avoided exposing the y-coordinate to prevent the possibility of things like invalid curve attacks, although with time we have exposed more and more to support things like alternative point compression formats. See #1237 for some history. We're now trying to use these traits with Edwards curves like Curve25519 (in `curve25519-dalek`) and Ed448-Goldilocks, which use compressed Edwards y-coordinates as their compressed point format. That requires y-coordinate access. As such, this changes the previous `y_is_odd` method, which was used to implement SEC1-like compressed points, to a full `fn y` which returns a serialized field element for the y-coordinate. Closes #1019 --- elliptic-curve/src/dev.rs | 8 ++++++++ elliptic-curve/src/point.rs | 8 +++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 98d4c8e1d..5d1eb8887 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -473,6 +473,14 @@ impl AffineCoordinates for AffinePoint { unimplemented!(); } + fn y(&self) -> FieldBytes { + unimplemented!(); + } + + fn x_is_odd(&self) -> Choice { + unimplemented!(); + } + fn y_is_odd(&self) -> Choice { unimplemented!(); } diff --git a/elliptic-curve/src/point.rs b/elliptic-curve/src/point.rs index ee4eded44..2eec19245 100644 --- a/elliptic-curve/src/point.rs +++ b/elliptic-curve/src/point.rs @@ -22,12 +22,18 @@ pub type ProjectivePoint = ::ProjectivePoint; /// Access to the affine coordinates of an elliptic curve point. // TODO: use zkcrypto/group#30 coordinate API when available pub trait AffineCoordinates { - /// Field element representation. + /// Field element representation with curve-specific serialization/endianness. type FieldRepr: AsRef<[u8]>; /// Get the affine x-coordinate as a serialized field element. fn x(&self) -> Self::FieldRepr; + /// Get the affine y-coordinate as a serialized field element. + fn y(&self) -> Self::FieldRepr; + + /// Is the affine x-coordinate odd? + fn x_is_odd(&self) -> Choice; + /// Is the affine y-coordinate odd? fn y_is_odd(&self) -> Choice; } From 284a928d76d2eeaa5266734108f9d2497e09ba57 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 5 Jun 2025 15:02:08 -0600 Subject: [PATCH 1390/1461] elliptic-curve v0.14.0-rc.4 (#1892) --- Cargo.lock | 2 +- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1394b6a3c..c2d50830e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -195,7 +195,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.14.0-rc.3" +version = "0.14.0-rc.4" dependencies = [ "base16ct", "base64ct", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 1f9499755..4c1d36f3e 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.14.0-rc.3" +version = "0.14.0-rc.4" authors = ["RustCrypto Developers"] edition = "2024" rust-version = "1.85" From f8663d3c970695702c8a292541cc163a2b9f151f Mon Sep 17 00:00:00 2001 From: daxpedda Date: Fri, 6 Jun 2025 16:32:31 +0200 Subject: [PATCH 1391/1461] elliptic-curve: impl `BatchInvert` for `NonZeroScalar` (#1890) This implements `BatchInvert` for `NonZeroScalar`. To accomplish this, I did the following notable things: - Remove all trait bounds on `BatchInvert` itself. - Remove `CtOption` from `BatchInvert::batch_invert`s return type. - Expose `invert_batch_internal()` internally, which now takes an `invert` function instead of requiring `trait Invert`. - Implement `MulAssign` for `NonZeroScalar`. Things that could still be added: - Mirror all `BatchInvert` implementations on `Scalar`, I left the ones taking a reference to a slice out. - Implement `MulAssign` for `NonZeroScalar` on more combinations. It might be a tiny bit simpler if I implemented `Default` on `NonZeroScalar`, but that seemed like a footgun to me. --- elliptic-curve/src/ops.rs | 90 +++++++++++++++------------- elliptic-curve/src/scalar/nonzero.rs | 57 +++++++++++++++++- 2 files changed, 104 insertions(+), 43 deletions(-) diff --git a/elliptic-curve/src/ops.rs b/elliptic-curve/src/ops.rs index 7457d86c9..3fd9bb820 100644 --- a/elliptic-curve/src/ops.rs +++ b/elliptic-curve/src/ops.rs @@ -1,7 +1,7 @@ //! Traits for arithmetic operations on elliptic curve field elements. use core::iter; -pub use core::ops::{Add, AddAssign, Mul, Neg, Shr, ShrAssign, Sub, SubAssign}; +pub use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Shr, ShrAssign, Sub, SubAssign}; pub use crypto_bigint::Invert; use crypto_bigint::Integer; @@ -13,26 +13,24 @@ use alloc::{borrow::ToOwned, vec::Vec}; /// Perform a batched inversion on a sequence of field elements (i.e. base field elements or scalars) /// at an amortized cost that should be practically as efficient as a single inversion. -pub trait BatchInvert: Field + Sized { +pub trait BatchInvert { /// The output of batch inversion. A container of field elements. - type Output: AsRef<[Self]>; + type Output; /// Invert a batch of field elements. - fn batch_invert( - field_elements: FieldElements, - ) -> CtOption<>::Output>; + fn batch_invert(field_elements: FieldElements) -> >::Output; } impl BatchInvert<[T; N]> for T where T: Field, { - type Output = [Self; N]; + type Output = CtOption<[Self; N]>; fn batch_invert(mut field_elements: [Self; N]) -> CtOption<[Self; N]> { let mut field_elements_pad = [Self::default(); N]; let inversion_succeeded = - invert_batch_internal(&mut field_elements, &mut field_elements_pad); + invert_batch_internal(&mut field_elements, &mut field_elements_pad, invert); CtOption::new(field_elements, inversion_succeeded) } @@ -43,11 +41,12 @@ impl<'this, T> BatchInvert<&'this mut [Self]> for T where T: Field, { - type Output = &'this mut [Self]; + type Output = CtOption<&'this mut [Self]>; fn batch_invert(field_elements: &'this mut [Self]) -> CtOption<&'this mut [Self]> { let mut field_elements_pad: Vec = vec![Self::default(); field_elements.len()]; - let inversion_succeeded = invert_batch_internal(field_elements, &mut field_elements_pad); + let inversion_succeeded = + invert_batch_internal(field_elements, &mut field_elements_pad, invert); CtOption::new(field_elements, inversion_succeeded) } @@ -58,13 +57,13 @@ impl BatchInvert<&[Self]> for T where T: Field, { - type Output = Vec; + type Output = CtOption>; fn batch_invert(field_elements: &[Self]) -> CtOption> { let mut field_elements: Vec = field_elements.to_owned(); let mut field_elements_pad: Vec = vec![Self::default(); field_elements.len()]; let inversion_succeeded = - invert_batch_internal(&mut field_elements, &mut field_elements_pad); + invert_batch_internal(&mut field_elements, &mut field_elements_pad, invert); CtOption::new(field_elements, inversion_succeeded) } @@ -75,26 +74,35 @@ impl BatchInvert> for T where T: Field, { - type Output = Vec; + type Output = CtOption>; fn batch_invert(mut field_elements: Vec) -> CtOption> { let mut field_elements_pad: Vec = vec![Self::default(); field_elements.len()]; let inversion_succeeded = - invert_batch_internal(&mut field_elements, &mut field_elements_pad); + invert_batch_internal(&mut field_elements, &mut field_elements_pad, invert); CtOption::new(field_elements, inversion_succeeded) } } +fn invert(scalar: T) -> (T, Choice) { + let scalar = scalar.invert(); + let choice = scalar.is_some(); + let scalar = scalar.unwrap_or(T::default()); + + (scalar, choice) +} + /// Implements "Montgomery's trick", a trick for computing many modular inverses at once. /// /// "Montgomery's trick" works by reducing the problem of computing `n` inverses /// to computing a single inversion, plus some storage and `O(n)` extra multiplications. /// /// See: https://iacr.org/archive/pkc2004/29470042/29470042.pdf section 2.2. -fn invert_batch_internal( +pub(crate) fn invert_batch_internal + MulAssign>( field_elements: &mut [T], field_elements_pad: &mut [T], + invert: fn(T) -> (T, Choice), ) -> Choice { let batch_size = field_elements.len(); if batch_size != field_elements_pad.len() { @@ -117,32 +125,32 @@ fn invert_batch_internal( *field_element_pad = acc; } - acc.invert() - .map(|mut acc| { - // Shift the iterator by one element back. The one we are skipping is served in `acc`. - let field_elements_pad = field_elements_pad - .iter() - .rev() - .skip(1) - .map(Some) - .chain(iter::once(None)); - - for (field_element, field_element_pad) in - field_elements.iter_mut().rev().zip(field_elements_pad) - { - if let Some(field_element_pad) = field_element_pad { - // Store in a temporary so we can overwrite `field_element`. - // $ a_{n-1} = {a_n}^{-1}*x_n $ - let tmp = acc * *field_element; - // $ {x_n}^{-1} = a_{n}^{-1}*a_{n-1} $ - *field_element = acc * *field_element_pad; - acc = tmp; - } else { - *field_element = acc; - } - } - }) - .is_some() + let (mut acc, choice) = invert(acc); + + // Shift the iterator by one element back. The one we are skipping is served in `acc`. + let field_elements_pad = field_elements_pad + .iter() + .rev() + .skip(1) + .map(Some) + .chain(iter::once(None)); + + for (field_element, field_element_pad) in + field_elements.iter_mut().rev().zip(field_elements_pad) + { + if let Some(field_element_pad) = field_element_pad { + // Store in a temporary so we can overwrite `field_element`. + // $ a_{n-1} = {a_n}^{-1}*x_n $ + let tmp = acc * *field_element; + // $ {x_n}^{-1} = a_{n}^{-1}*a_{n-1} $ + *field_element = acc * *field_element_pad; + acc = tmp; + } else { + *field_element = acc; + } + } + + choice } /// Linear combination. diff --git a/elliptic-curve/src/scalar/nonzero.rs b/elliptic-curve/src/scalar/nonzero.rs index a0cd28abc..35688352a 100644 --- a/elliptic-curve/src/scalar/nonzero.rs +++ b/elliptic-curve/src/scalar/nonzero.rs @@ -2,14 +2,14 @@ use crate::{ CurveArithmetic, Error, FieldBytes, PrimeCurve, Scalar, ScalarPrimitive, SecretKey, - ops::{Invert, Reduce, ReduceNonZero}, + ops::{self, BatchInvert, Invert, Reduce, ReduceNonZero}, point::NonIdentity, scalar::IsHigh, }; use base16ct::HexDisplay; use core::{ fmt, - ops::{Deref, Mul, Neg}, + ops::{Deref, Mul, MulAssign, Neg}, str, }; use crypto_bigint::{ArrayEncoding, Integer}; @@ -18,6 +18,9 @@ use rand_core::{CryptoRng, TryCryptoRng}; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; use zeroize::Zeroize; +#[cfg(feature = "alloc")] +use alloc::vec::Vec; + #[cfg(feature = "serde")] use serdect::serde::{Deserialize, Serialize, de, ser}; @@ -96,6 +99,47 @@ where } } +impl BatchInvert<[Self; N]> for NonZeroScalar +where + C: CurveArithmetic + PrimeCurve, +{ + type Output = [Self; N]; + + fn batch_invert(mut field_elements: [Self; N]) -> [Self; N] { + let mut field_elements_pad = [Self { + scalar: Scalar::::ONE, + }; N]; + ops::invert_batch_internal(&mut field_elements, &mut field_elements_pad, |scalar| { + (scalar.invert(), Choice::from(1)) + }); + + field_elements + } +} + +#[cfg(feature = "alloc")] +impl BatchInvert> for NonZeroScalar +where + C: CurveArithmetic + PrimeCurve, +{ + type Output = Vec; + + fn batch_invert(mut field_elements: Vec) -> Vec { + let mut field_elements_pad: Vec = vec![ + Self { + scalar: Scalar::::ONE, + }; + field_elements.len() + ]; + + ops::invert_batch_internal(&mut field_elements, &mut field_elements_pad, |scalar| { + (scalar.invert(), Choice::from(1)) + }); + + field_elements + } +} + impl ConditionallySelectable for NonZeroScalar where C: CurveArithmetic, @@ -307,6 +351,15 @@ where } } +impl MulAssign for NonZeroScalar +where + C: PrimeCurve + CurveArithmetic, +{ + fn mul_assign(&mut self, rhs: Self) { + *self = *self * rhs; + } +} + impl PartialEq for NonZeroScalar where C: CurveArithmetic, From 24b68fabfaa526599dfc6f3e85b24f0ae19d4f02 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 6 Jun 2025 08:38:04 -0600 Subject: [PATCH 1392/1461] elliptic-curve: rename `SecretKey::new` => `::from_scalar` (#1893) Also changes its arg type to accept an `impl Into>` --- elliptic-curve/src/secret_key.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 9e9df1f38..a7119719d 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -121,8 +121,9 @@ where /// # Returns /// /// This will return a none if the scalar is all-zero. - pub fn new(scalar: ScalarPrimitive) -> CtOption { - CtOption::new(Self { inner: scalar }, !scalar.is_zero()) + pub fn from_scalar(scalar: impl Into>) -> CtOption { + let inner = scalar.into(); + CtOption::new(Self { inner }, !inner.is_zero()) } /// Borrow the inner secret [`ScalarPrimitive`] value. From 9c9ea0635a8c9f476fdae5b17c76d626f357a72b Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 6 Jun 2025 16:14:34 -0600 Subject: [PATCH 1393/1461] elliptic-curve: extract scalar macros from `primeorder` (#1894) Extracts macros for writing `From` and `Mul` impls for scalar types. It would be nice to use these with `ed448-goldilocks` which isn't a prime order curve, and really these macros work for any elliptic curve, not just prime order curves (`primeorder` was previously just a convenient place to put them). cc @baloo --- elliptic-curve/src/lib.rs | 1 + elliptic-curve/src/macros.rs | 147 +++++++++++++++++++++++++++++++++++ 2 files changed, 148 insertions(+) create mode 100644 elliptic-curve/src/macros.rs diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 8e5ccacaf..cca9515ed 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -102,6 +102,7 @@ pub mod weierstrass; mod error; mod field; +mod macros; mod secret_key; #[cfg(feature = "arithmetic")] diff --git a/elliptic-curve/src/macros.rs b/elliptic-curve/src/macros.rs new file mode 100644 index 000000000..0f868912e --- /dev/null +++ b/elliptic-curve/src/macros.rs @@ -0,0 +1,147 @@ +//! Macros for writing common patterns that interact with this crate. + +/// Writes all impls for scalar field types. +#[macro_export] +macro_rules! scalar_impls { + ($curve:path, $scalar:ty) => { + $crate::scalar_from_impls!($curve, $scalar); + $crate::scalar_mul_impls!($curve, $scalar); + }; +} + +/// Writes a series of `From` impls for scalar field types. +#[macro_export] +macro_rules! scalar_from_impls { + ($curve:path, $scalar:ty) => { + impl From<$crate::NonZeroScalar<$curve>> for $scalar { + fn from(scalar: $crate::NonZeroScalar<$curve>) -> Self { + *scalar.as_ref() + } + } + + impl From<&$crate::NonZeroScalar<$curve>> for $scalar { + fn from(scalar: &$crate::NonZeroScalar<$curve>) -> Self { + *scalar.as_ref() + } + } + + impl From<$crate::ScalarPrimitive<$curve>> for $scalar { + fn from(w: $crate::ScalarPrimitive<$curve>) -> Self { + <$scalar>::from(&w) + } + } + + impl From<&$crate::ScalarPrimitive<$curve>> for $scalar { + fn from(w: &$crate::ScalarPrimitive<$curve>) -> $scalar { + <$scalar>::from_uint_unchecked(*w.as_uint()) + } + } + + impl From<$scalar> for $crate::ScalarPrimitive<$curve> { + fn from(scalar: $scalar) -> $crate::ScalarPrimitive<$curve> { + $crate::ScalarPrimitive::from(&scalar) + } + } + + impl From<&$scalar> for $crate::ScalarPrimitive<$curve> { + fn from(scalar: &$scalar) -> $crate::ScalarPrimitive<$curve> { + $crate::ScalarPrimitive::new(scalar.into()).unwrap() + } + } + + impl From<&$crate::SecretKey<$curve>> for $scalar { + fn from(secret_key: &$crate::SecretKey<$curve>) -> $scalar { + *secret_key.to_nonzero_scalar() + } + } + + /// The constant-time alternative is available at [`$crate::NonZeroScalar<$curve>::new()`]. + impl TryFrom<$scalar> for $crate::NonZeroScalar<$curve> { + type Error = $crate::Error; + + fn try_from(scalar: $scalar) -> $crate::Result { + $crate::NonZeroScalar::new(scalar) + .into_option() + .ok_or($crate::Error) + } + } + }; +} + +/// Writes a series of `Mul` impls for an elliptic curve's scalar field +#[macro_export] +macro_rules! scalar_mul_impls { + ($curve:path, $scalar:ty) => { + impl ::core::ops::Mul<$crate::AffinePoint<$curve>> for $scalar { + type Output = $crate::ProjectivePoint<$curve>; + + #[inline] + fn mul(self, rhs: $crate::AffinePoint<$curve>) -> $crate::ProjectivePoint<$curve> { + rhs * self + } + } + + impl ::core::ops::Mul<&$crate::AffinePoint<$curve>> for $scalar { + type Output = $crate::ProjectivePoint<$curve>; + + #[inline] + fn mul(self, rhs: &$crate::AffinePoint<$curve>) -> $crate::ProjectivePoint<$curve> { + *rhs * self + } + } + + impl ::core::ops::Mul<$crate::AffinePoint<$curve>> for &$scalar { + type Output = $crate::ProjectivePoint<$curve>; + + #[inline] + fn mul(self, rhs: $crate::AffinePoint<$curve>) -> $crate::ProjectivePoint<$curve> { + rhs * self + } + } + + impl ::core::ops::Mul<&$crate::AffinePoint<$curve>> for &$scalar { + type Output = $crate::ProjectivePoint<$curve>; + + #[inline] + fn mul(self, rhs: &$crate::AffinePoint<$curve>) -> $crate::ProjectivePoint<$curve> { + *rhs * self + } + } + + impl ::core::ops::Mul<$crate::ProjectivePoint<$curve>> for $scalar { + type Output = $crate::ProjectivePoint<$curve>; + + #[inline] + fn mul(self, rhs: $crate::ProjectivePoint<$curve>) -> $crate::ProjectivePoint<$curve> { + rhs * self + } + } + + impl ::core::ops::Mul<&$crate::ProjectivePoint<$curve>> for $scalar { + type Output = $crate::ProjectivePoint<$curve>; + + #[inline] + fn mul(self, rhs: &$crate::ProjectivePoint<$curve>) -> $crate::ProjectivePoint<$curve> { + rhs * &self + } + } + + impl ::core::ops::Mul<$crate::ProjectivePoint<$curve>> for &$scalar { + type Output = $crate::ProjectivePoint<$curve>; + + #[inline] + fn mul(self, rhs: $crate::ProjectivePoint<$curve>) -> $crate::ProjectivePoint<$curve> { + rhs * self + } + } + + impl ::core::ops::Mul<&$crate::ProjectivePoint<$curve>> for &$scalar { + type Output = $crate::ProjectivePoint<$curve>; + + #[inline] + fn mul(self, rhs: &$crate::ProjectivePoint<$curve>) -> $crate::ProjectivePoint<$curve> { + rhs * self + } + } + }; +} From a4d8074d024236f9c2c18d562340772f3f3cff79 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 7 Jun 2025 07:25:45 -0600 Subject: [PATCH 1394/1461] elliptic-curve v0.14.0-rc.5 (#1895) --- Cargo.lock | 2 +- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c2d50830e..e83fd3321 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -195,7 +195,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.14.0-rc.4" +version = "0.14.0-rc.5" dependencies = [ "base16ct", "base64ct", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 4c1d36f3e..2773deb21 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.14.0-rc.4" +version = "0.14.0-rc.5" authors = ["RustCrypto Developers"] edition = "2024" rust-version = "1.85" From 81757de8a15d5ae628a15cbaad6e33b12cdb7893 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Jun 2025 02:00:31 +0300 Subject: [PATCH 1395/1461] Update Cargo.lock (#1899) --- Cargo.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e83fd3321..a4342b93a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -45,9 +45,9 @@ checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" [[package]] name = "base64ct" -version = "1.7.3" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89e25b6adfb930f02d1981565a6e5d9c547ac15a96606256d3b59040e5cd4ca3" +checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" [[package]] name = "bitflags" @@ -106,9 +106,9 @@ checksum = "f61dac84819c6588b558454b194026eb1f09c293b9036ae9b159e74e73ab6cf9" [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" [[package]] name = "cipher" @@ -172,9 +172,9 @@ dependencies = [ [[package]] name = "der" -version = "0.8.0-rc.3" +version = "0.8.0-rc.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b00a9651bf9c00a38b7c383073cb22fb42f20a5f978c9f97ad5c7128cbd3c1bd" +checksum = "0c2e6107818886eff6b71fba7a2da3dd11025ebb80f0c9b94ff961168ef629f2" dependencies = [ "const-oid", "pem-rfc7468", From 8534db4e8458c3192aaccbd41e76f32db1a94e07 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Tue, 10 Jun 2025 16:26:51 +0300 Subject: [PATCH 1396/1461] digest: add `CoreProxy::compose/decompose` methods (#1898) --- digest/src/block_api.rs | 11 ++++++++--- digest/src/buffer_macros/fixed.rs | 7 +++++++ digest/src/buffer_macros/variable_ct.rs | 7 +++++++ digest/src/buffer_macros/xof.rs | 9 ++++++++- 4 files changed, 30 insertions(+), 4 deletions(-) diff --git a/digest/src/block_api.rs b/digest/src/block_api.rs index bdc70ab6c..c0ec6cb28 100644 --- a/digest/src/block_api.rs +++ b/digest/src/block_api.rs @@ -97,8 +97,13 @@ pub enum TruncSide { Right, } -/// A proxy trait to a core type. +/// A proxy trait to the core block-level type. pub trait CoreProxy { - /// Wrapped block-level type. - type Core; + /// Core block-level type. + type Core: BufferKindUser; + + /// Create `Self` from core and buffer. + fn compose(core: Self::Core, buffer: Buffer) -> Self; + /// Decompose `self` into core and buffer. + fn decompose(self) -> (Self::Core, Buffer); } diff --git a/digest/src/buffer_macros/fixed.rs b/digest/src/buffer_macros/fixed.rs index 7d27d8906..716fda60c 100644 --- a/digest/src/buffer_macros/fixed.rs +++ b/digest/src/buffer_macros/fixed.rs @@ -179,6 +179,13 @@ macro_rules! buffer_fixed { ) => { impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::block_api::CoreProxy for $name$(< $( $lt ),+ >)? { type Core = $core_ty; + fn compose(core: Self::Core, buffer: $crate::block_api::Buffer) -> Self { + Self { core, buffer } + } + fn decompose(self) -> (Self::Core, $crate::block_api::Buffer) { + let Self { core, buffer } = self; + (core, buffer) + } } $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;); diff --git a/digest/src/buffer_macros/variable_ct.rs b/digest/src/buffer_macros/variable_ct.rs index 1399ec084..a767a1ca0 100644 --- a/digest/src/buffer_macros/variable_ct.rs +++ b/digest/src/buffer_macros/variable_ct.rs @@ -112,6 +112,13 @@ macro_rules! buffer_ct_variable { $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size, Output = $crate::typenum::True>, { type Core = $crate::block_api::CtOutWrapper<$core_ty, $out_size>; + fn compose(core: Self::Core, buffer: $crate::block_api::Buffer) -> Self { + Self { core, buffer } + } + fn decompose(self) -> (Self::Core, $crate::block_api::Buffer) { + let Self { core, buffer } = self; + (core, buffer) + } } impl<$out_size> $crate::Update for $name<$out_size> diff --git a/digest/src/buffer_macros/xof.rs b/digest/src/buffer_macros/xof.rs index dd635332c..8687c18b4 100644 --- a/digest/src/buffer_macros/xof.rs +++ b/digest/src/buffer_macros/xof.rs @@ -87,7 +87,7 @@ macro_rules! buffer_xof { ) => { $crate::buffer_xof!( impl_inner: $name($core_ty); - Debug Clone BlockSizeUser CoreProxy + Debug Clone BlockSizeUser $($trait_name)*;); }; @@ -194,6 +194,13 @@ macro_rules! buffer_xof { ) => { impl $crate::block_api::CoreProxy for $name { type Core = $core_ty; + fn compose(core: Self::Core, buffer: $crate::block_api::Buffer) -> Self { + Self { core, buffer } + } + fn decompose(self) -> (Self::Core, $crate::block_api::Buffer) { + let Self { core, buffer } = self; + (core, buffer) + } } $crate::buffer_xof!(impl_inner: $name($core_ty); $($trait_name)*;); From f24c2ae0b6ab6e897fab9645274d5c1d815e671e Mon Sep 17 00:00:00 2001 From: daxpedda Date: Fri, 13 Jun 2025 20:50:06 +0200 Subject: [PATCH 1397/1461] elliptic-curve: impl `BatchNormalize` for `NonIdentity` (#1896) As discussed in #1889. I will add some tests in `elliptic-curves` as well. Resolves #1889. Companion PR: https://github.com/RustCrypto/elliptic-curves/pull/1248. --- .github/workflows/elliptic-curve.yml | 18 ++++ elliptic-curve/src/dev.rs | 23 ++++- elliptic-curve/src/lib.rs | 3 +- elliptic-curve/src/point.rs | 4 +- elliptic-curve/src/point/non_identity.rs | 107 ++++++++++++++++++++++- 5 files changed, 150 insertions(+), 5 deletions(-) diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index 57d4d4c9a..8ab5154ce 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -88,3 +88,21 @@ jobs: - run: cargo test --no-default-features - run: cargo test - run: cargo test --all-features + + test-careful: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@nightly + - run: cargo install cargo-careful + - run: cargo careful test --all-features + + test-miri: + runs-on: ubuntu-latest + env: + MIRIFLAGS: "-Zmiri-symbolic-alignment-check -Zmiri-strict-provenance" + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@nightly + - run: rustup component add miri && cargo miri setup + - run: cargo miri test --all-features diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 5d1eb8887..4d1f6c080 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -4,7 +4,7 @@ //! the traits in this crate. use crate::{ - Curve, CurveArithmetic, FieldBytesEncoding, PrimeCurve, + BatchNormalize, Curve, CurveArithmetic, FieldBytesEncoding, PrimeCurve, array::typenum::U32, bigint::{Limb, U256}, error::{Error, Result}, @@ -17,6 +17,7 @@ use crate::{ zeroize::DefaultIsZeroes, }; use core::{ + array, iter::{Product, Sum}, ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign}, }; @@ -24,6 +25,9 @@ use ff::{Field, PrimeField}; use hex_literal::hex; use pkcs8::AssociatedOid; +#[cfg(feature = "alloc")] +use alloc::vec::Vec; + #[cfg(feature = "bits")] use ff::PrimeFieldBits; @@ -584,6 +588,23 @@ pub enum ProjectivePoint { Other(AffinePoint), } +impl BatchNormalize<[ProjectivePoint; N]> for ProjectivePoint { + type Output = [AffinePoint; N]; + + fn batch_normalize(points: &[ProjectivePoint; N]) -> [AffinePoint; N] { + array::from_fn(|index| points[index].into()) + } +} + +#[cfg(feature = "alloc")] +impl BatchNormalize<[ProjectivePoint]> for ProjectivePoint { + type Output = Vec; + + fn batch_normalize(points: &[ProjectivePoint]) -> Vec { + points.iter().copied().map(AffinePoint::from).collect() + } +} + impl ConstantTimeEq for ProjectivePoint { fn ct_eq(&self, other: &Self) -> Choice { match (self, other) { diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index cca9515ed..79f444d3b 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -5,7 +5,8 @@ html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg" )] -#![forbid(unsafe_code)] +// Only allowed for newtype casts. +#![deny(unsafe_code)] #![warn( clippy::cast_lossless, clippy::cast_possible_truncation, diff --git a/elliptic-curve/src/point.rs b/elliptic-curve/src/point.rs index 2eec19245..b82da0551 100644 --- a/elliptic-curve/src/point.rs +++ b/elliptic-curve/src/point.rs @@ -40,9 +40,9 @@ pub trait AffineCoordinates { /// Normalize point(s) in projective representation by converting them to their affine ones. #[cfg(feature = "arithmetic")] -pub trait BatchNormalize: group::Curve { +pub trait BatchNormalize { /// The output of the batch normalization; a container of affine points. - type Output: AsRef<[Self::AffineRepr]>; + type Output; /// Perform a batched conversion to affine representation on a sequence of projective points /// at an amortized cost that should be practically as efficient as a single conversion. diff --git a/elliptic-curve/src/point/non_identity.rs b/elliptic-curve/src/point/non_identity.rs index 91217827b..7bc99b3d7 100644 --- a/elliptic-curve/src/point/non_identity.rs +++ b/elliptic-curve/src/point/non_identity.rs @@ -6,11 +6,14 @@ use group::{Curve, Group, GroupEncoding, prime::PrimeCurveAffine}; use rand_core::CryptoRng; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; +#[cfg(feature = "alloc")] +use alloc::vec::Vec; + #[cfg(feature = "serde")] use serdect::serde::{Deserialize, Serialize, de, ser}; use zeroize::Zeroize; -use crate::{CurveArithmetic, NonZeroScalar, Scalar}; +use crate::{BatchNormalize, CurveArithmetic, NonZeroScalar, Scalar}; /// Non-identity point type. /// @@ -19,6 +22,7 @@ use crate::{CurveArithmetic, NonZeroScalar, Scalar}; /// In the context of ECC, it's useful for ensuring that certain arithmetic /// cannot result in the identity point. #[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[repr(transparent)] pub struct NonIdentity

{ point: P, } @@ -103,6 +107,72 @@ impl

AsRef

for NonIdentity

{ } } +impl BatchNormalize<[Self; N]> for NonIdentity

+where + P: Curve + BatchNormalize<[P; N], Output = [P::AffineRepr; N]>, +{ + type Output = [NonIdentity; N]; + + fn batch_normalize(points: &[Self; N]) -> [NonIdentity; N] { + // Ensure casting is safe. + // This always succeeds because `NonIdentity` is `repr(transparent)`. + debug_assert_eq!(size_of::

(), size_of::>()); + debug_assert_eq!(align_of::

(), align_of::>()); + + #[allow(unsafe_code)] + // SAFETY: `NonIdentity` is `repr(transparent)`. + let points: &[P; N] = unsafe { &*points.as_ptr().cast() }; + let affine_points =

>::batch_normalize(points); + + // Ensure `array::map()` can be optimized to a `memcpy`. + debug_assert_eq!( + size_of::(), + size_of::>() + ); + debug_assert_eq!( + align_of::(), + align_of::>() + ); + + affine_points.map(|point| NonIdentity { point }) + } +} + +#[cfg(feature = "alloc")] +impl

BatchNormalize<[Self]> for NonIdentity

+where + P: Curve + BatchNormalize<[P], Output = Vec>, +{ + type Output = Vec>; + + fn batch_normalize(points: &[Self]) -> Vec> { + // Ensure casting is safe. + // This always succeeds because `NonIdentity` is `repr(transparent)`. + debug_assert_eq!(size_of::

(), size_of::>()); + debug_assert_eq!(align_of::

(), align_of::>()); + + #[allow(unsafe_code)] + // SAFETY: `NonIdentity` is `repr(transparent)`. + let points: &[P] = unsafe { &*(points as *const [NonIdentity

] as *const [P]) }; + let affine_points =

>::batch_normalize(points); + + // Ensure `into_iter()` + `collect()` can be optimized away. + debug_assert_eq!( + size_of::(), + size_of::>() + ); + debug_assert_eq!( + align_of::(), + align_of::>() + ); + + affine_points + .into_iter() + .map(|point| NonIdentity { point }) + .collect() + } +} + impl

ConditionallySelectable for NonIdentity

where P: ConditionallySelectable, @@ -238,6 +308,7 @@ impl Zeroize for NonIdentity

{ #[cfg(all(test, feature = "dev"))] mod tests { use super::NonIdentity; + use crate::BatchNormalize; use crate::dev::{AffinePoint, NonZeroScalar, ProjectivePoint, SecretKey}; use group::GroupEncoding; use hex_literal::hex; @@ -303,4 +374,38 @@ mod tests { assert_eq!(point.to_point(), pk.to_projective()); } + + #[test] + fn batch_normalize() { + let point = ProjectivePoint::from_bytes( + &hex!("02c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721").into(), + ) + .unwrap(); + let point = NonIdentity::new(point).unwrap(); + let points = [point, point]; + + for (point, affine_point) in points + .into_iter() + .zip(NonIdentity::batch_normalize(&points)) + { + assert_eq!(point.to_affine(), affine_point); + } + } + + #[test] + #[cfg(feature = "alloc")] + fn batch_normalize_alloc() { + let point = ProjectivePoint::from_bytes( + &hex!("02c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721").into(), + ) + .unwrap(); + let point = NonIdentity::new(point).unwrap(); + let points = vec![point, point]; + + let affine_points = NonIdentity::batch_normalize(points.as_slice()); + + for (point, affine_point) in points.into_iter().zip(affine_points) { + assert_eq!(point.to_affine(), affine_point); + } + } } From 0eab8e247bcf0746a51215147c357e52b1f32f46 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Fri, 13 Jun 2025 22:35:22 +0200 Subject: [PATCH 1398/1461] hash2curve: move oversized DST requirements to runtime errors (#1901) This PR introduces two changes: - Remove requirements that were only relevant for oversized `DST`s. Now these requirements are checked on runtime. While this is unfortunate, the currently limitations simply was that usage with regular sized `DST`s incurred limitations that were not necessary. - Change `len_in_bytes` from `NonZero` to `NonZero`. This isn't a big improvement because the error is just moved from `expand_msg()` to the various `GroupDigest` methods. Companion PR: https://github.com/RustCrypto/elliptic-curves/pull/1256. --- I know I have been refactoring this API over and over again, but I actually think this is the last of it (apart from https://github.com/RustCrypto/traits/pull/872 with `generic_const_exprs`). But for completions sake I want to mention the following [from the spec](https://www.rfc-editor.org/rfc/rfc9380.html#section-5.3.1-8): > It is possible, however, to entirely avoid this overhead by taking advantage of the fact that Z_pad depends only on H, and not on the arguments to expand_message_xmd. To do so, first precompute and save the internal state of H after ingesting Z_pad. Then, when computing b_0, initialize H using the saved state. Further details are implementation dependent and are beyond the scope of this document. In summary, we could cache this part: ```rust let mut b_0 = HashT::default(); b_0.update(&Array::::default()); ``` Doing this requires passing `ExpandMsg` state, which would change the entire API having to add a parameter to every function. However, as the spec mentions, the cost of not caching it is most likely negligible. We will see in the future if this shows up in benchmarks and if it does we can re-evaluate. I don't believe this will be the case though. Alternatively, we could add a trait to `digest` which allows users to construct a hash prefixed with a `BlockSize` full of zeros that has been computed at compile-time. Which would also require no changes to the API except binding to this trait. --- elliptic-curve/src/hash2curve/group_digest.rs | 21 ++++++---- elliptic-curve/src/hash2curve/hash2field.rs | 14 ++++--- .../src/hash2curve/hash2field/expand_msg.rs | 25 +++++------ .../hash2curve/hash2field/expand_msg/xmd.rs | 41 +++++++------------ .../hash2curve/hash2field/expand_msg/xof.rs | 20 +++++---- 5 files changed, 59 insertions(+), 62 deletions(-) diff --git a/elliptic-curve/src/hash2curve/group_digest.rs b/elliptic-curve/src/hash2curve/group_digest.rs index 571f43e81..052098ce8 100644 --- a/elliptic-curve/src/hash2curve/group_digest.rs +++ b/elliptic-curve/src/hash2curve/group_digest.rs @@ -23,9 +23,10 @@ pub trait GroupDigest: MapToCurve { /// > hash function is used. /// /// # Errors - /// See implementors of [`ExpandMsg`] for errors: - /// - [`ExpandMsgXmd`] - /// - [`ExpandMsgXof`] + /// - `len_in_bytes > u16::MAX` + /// - See implementors of [`ExpandMsg`] for additional errors: + /// - [`ExpandMsgXmd`] + /// - [`ExpandMsgXof`] /// /// `len_in_bytes = ::Length * 2` /// @@ -53,9 +54,10 @@ pub trait GroupDigest: MapToCurve { /// > points in this set are more likely to be output than others. /// /// # Errors - /// See implementors of [`ExpandMsg`] for errors: - /// - [`ExpandMsgXmd`] - /// - [`ExpandMsgXof`] + /// - `len_in_bytes > u16::MAX` + /// - See implementors of [`ExpandMsg`] for additional errors: + /// - [`ExpandMsgXmd`] + /// - [`ExpandMsgXof`] /// /// `len_in_bytes = ::Length` /// @@ -76,9 +78,10 @@ pub trait GroupDigest: MapToCurve { /// and returns a scalar. /// /// # Errors - /// See implementors of [`ExpandMsg`] for errors: - /// - [`ExpandMsgXmd`] - /// - [`ExpandMsgXof`] + /// - `len_in_bytes > u16::MAX` + /// - See implementors of [`ExpandMsg`] for additional errors: + /// - [`ExpandMsgXmd`] + /// - [`ExpandMsgXof`] /// /// `len_in_bytes = ::Length` /// diff --git a/elliptic-curve/src/hash2curve/hash2field.rs b/elliptic-curve/src/hash2curve/hash2field.rs index 990230105..a0db0cbb3 100644 --- a/elliptic-curve/src/hash2curve/hash2field.rs +++ b/elliptic-curve/src/hash2curve/hash2field.rs @@ -4,7 +4,7 @@ mod expand_msg; -use core::num::NonZeroUsize; +use core::num::NonZeroU16; pub use expand_msg::{xmd::*, xof::*, *}; @@ -28,9 +28,10 @@ pub trait FromOkm { /// /// /// # Errors -/// See implementors of [`ExpandMsg`] for errors: -/// - [`ExpandMsgXmd`] -/// - [`ExpandMsgXof`] +/// - `len_in_bytes > u16::MAX` +/// - See implementors of [`ExpandMsg`] for additional errors: +/// - [`ExpandMsgXmd`] +/// - [`ExpandMsgXof`] /// /// `len_in_bytes = T::Length * out.len()` /// @@ -42,9 +43,10 @@ where E: ExpandMsg, T: FromOkm + Default, { - let len_in_bytes = T::Length::to_usize() + let len_in_bytes = T::Length::USIZE .checked_mul(out.len()) - .and_then(NonZeroUsize::new) + .and_then(|len| len.try_into().ok()) + .and_then(NonZeroU16::new) .ok_or(Error)?; let mut tmp = Array::::Length>::default(); let mut expander = E::expand_message(data, domain, len_in_bytes)?; diff --git a/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs b/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs index 233b6b9f0..c01b70e4a 100644 --- a/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs +++ b/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs @@ -7,7 +7,6 @@ use core::num::NonZero; use crate::{Error, Result}; use digest::{Digest, ExtendableOutput, Update, XofReader}; -use hybrid_array::typenum::{IsLess, True, U256}; use hybrid_array::{Array, ArraySize}; /// Salt when the DST is too long @@ -34,7 +33,7 @@ pub trait ExpandMsg { fn expand_message<'dst>( msg: &[&[u8]], dst: &'dst [&[u8]], - len_in_bytes: NonZero, + len_in_bytes: NonZero, ) -> Result>; } @@ -50,20 +49,14 @@ pub trait Expander { /// /// [dst]: https://www.rfc-editor.org/rfc/rfc9380.html#name-using-dsts-longer-than-255- #[derive(Debug)] -pub(crate) enum Domain<'a, L> -where - L: ArraySize + IsLess, -{ +pub(crate) enum Domain<'a, L: ArraySize> { /// > 255 Hashed(Array), /// <= 255 Array(&'a [&'a [u8]]), } -impl<'a, L> Domain<'a, L> -where - L: ArraySize + IsLess, -{ +impl<'a, L: ArraySize> Domain<'a, L> { pub fn xof(dst: &'a [&'a [u8]]) -> Result where X: Default + ExtendableOutput + Update, @@ -72,6 +65,10 @@ where if dst.iter().map(|slice| slice.len()).sum::() == 0 { Err(Error) } else if dst.iter().map(|slice| slice.len()).sum::() > MAX_DST_LEN { + if L::USIZE > u8::MAX.into() { + return Err(Error); + } + let mut data = Array::::default(); let mut hash = X::default(); hash.update(OVERSIZE_DST_SALT); @@ -96,6 +93,10 @@ where if dst.iter().map(|slice| slice.len()).sum::() == 0 { Err(Error) } else if dst.iter().map(|slice| slice.len()).sum::() > MAX_DST_LEN { + if L::USIZE > u8::MAX.into() { + return Err(Error); + } + Ok(Self::Hashed({ let mut hash = X::new(); hash.update(OVERSIZE_DST_SALT); @@ -124,8 +125,8 @@ where pub fn len(&self) -> u8 { match self { - // Can't overflow because it's enforced on a type level. - Self::Hashed(_) => L::to_u8(), + // Can't overflow because it's checked on creation. + Self::Hashed(_) => L::U8, // Can't overflow because it's checked on creation. Self::Array(d) => { u8::try_from(d.iter().map(|d| d.len()).sum::()).expect("length overflow") diff --git a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs index 8ae1ec022..a68f53ec7 100644 --- a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs +++ b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs @@ -8,7 +8,7 @@ use digest::{ FixedOutput, HashMarker, array::{ Array, - typenum::{IsGreaterOrEqual, IsLess, IsLessOrEqual, Prod, True, U2, U256, Unsigned}, + typenum::{IsGreaterOrEqual, IsLessOrEqual, Prod, True, U2, Unsigned}, }, block_api::BlockSizeUser, }; @@ -18,22 +18,17 @@ use digest::{ /// /// # Errors /// - `dst` contains no bytes -/// - `len_in_bytes > u16::MAX` +/// - `dst > 255 && HashT::OutputSize > 255` /// - `len_in_bytes > 255 * HashT::OutputSize` #[derive(Debug)] pub struct ExpandMsgXmd(PhantomData) where HashT: BlockSizeUser + Default + FixedOutput + HashMarker, - HashT::OutputSize: IsLess, HashT::OutputSize: IsLessOrEqual; impl ExpandMsg for ExpandMsgXmd where HashT: BlockSizeUser + Default + FixedOutput + HashMarker, - // If DST is larger than 255 bytes, the length of the computed DST will depend on the output - // size of the hash, which is still not allowed to be larger than 255. - // https://www.rfc-editor.org/rfc/rfc9380.html#section-5.3.1-6 - HashT::OutputSize: IsLess, // The number of bits output by `HashT` MUST be at most `HashT::BlockSize`. // https://www.rfc-editor.org/rfc/rfc9380.html#section-5.3.1-4 HashT::OutputSize: IsLessOrEqual, @@ -47,17 +42,17 @@ where fn expand_message<'dst>( msg: &[&[u8]], dst: &'dst [&[u8]], - len_in_bytes: NonZero, + len_in_bytes: NonZero, ) -> Result> { - let len_in_bytes_u16 = u16::try_from(len_in_bytes.get()).map_err(|_| Error)?; + let b_in_bytes = HashT::OutputSize::USIZE; // `255 * ` can not exceed `u16::MAX` - if len_in_bytes_u16 > 255 * HashT::OutputSize::to_u16() { + if usize::from(len_in_bytes.get()) > 255 * b_in_bytes { return Err(Error); } - let b_in_bytes = HashT::OutputSize::to_usize(); - let ell = u8::try_from(len_in_bytes.get().div_ceil(b_in_bytes)).map_err(|_| Error)?; + let ell = u8::try_from(usize::from(len_in_bytes.get()).div_ceil(b_in_bytes)) + .expect("should never pass the previous check"); let domain = Domain::xmd::(dst)?; let mut b_0 = HashT::default(); @@ -67,7 +62,7 @@ where b_0.update(msg); } - b_0.update(&len_in_bytes_u16.to_be_bytes()); + b_0.update(&len_in_bytes.get().to_be_bytes()); b_0.update(&[0]); domain.update_hash(&mut b_0); b_0.update(&[domain.len()]); @@ -96,7 +91,6 @@ where pub struct ExpanderXmd<'a, HashT> where HashT: BlockSizeUser + Default + FixedOutput + HashMarker, - HashT::OutputSize: IsLess, HashT::OutputSize: IsLessOrEqual, { b_0: Array, @@ -110,7 +104,6 @@ where impl ExpanderXmd<'_, HashT> where HashT: BlockSizeUser + Default + FixedOutput + HashMarker, - HashT::OutputSize: IsLess, HashT::OutputSize: IsLessOrEqual, { fn next(&mut self) -> bool { @@ -140,7 +133,6 @@ where impl Expander for ExpanderXmd<'_, HashT> where HashT: BlockSizeUser + Default + FixedOutput + HashMarker, - HashT::OutputSize: IsLess, HashT::OutputSize: IsLessOrEqual, { fn fill_bytes(&mut self, okm: &mut [u8]) { @@ -157,11 +149,10 @@ where #[cfg(test)] mod test { use super::*; - use core::mem::size_of; use hex_literal::hex; use hybrid_array::{ ArraySize, - typenum::{U4, U8, U32, U128}, + typenum::{IsLess, U4, U8, U32, U128, U65536}, }; use sha2::Sha256; @@ -172,9 +163,8 @@ mod test { bytes: &[u8], ) where HashT: BlockSizeUser + Default + FixedOutput + HashMarker, - HashT::OutputSize: IsLess, { - let block = HashT::BlockSize::to_usize(); + let block = HashT::BlockSize::USIZE; assert_eq!( Array::::default().as_slice(), &bytes[..block] @@ -206,25 +196,24 @@ mod test { impl TestVector { #[allow(clippy::panic_in_result_fn)] - fn assert( + fn assert( &self, dst: &'static [u8], domain: &Domain<'_, HashT::OutputSize>, ) -> Result<()> where HashT: BlockSizeUser + Default + FixedOutput + HashMarker, - HashT::OutputSize: IsLess - + IsLessOrEqual - + Mul, + HashT::OutputSize: IsLessOrEqual, HashT::OutputSize: IsGreaterOrEqual, + L: ArraySize + IsLess, { - assert_message::(self.msg, domain, L::to_u16(), self.msg_prime); + assert_message::(self.msg, domain, L::U16, self.msg_prime); let dst = [dst]; let mut expander = as ExpandMsg>::expand_message( &[self.msg], &dst, - NonZero::new(L::to_usize()).ok_or(Error)?, + NonZero::new(L::U16).ok_or(Error)?, )?; let mut uniform_bytes = Array::::default(); diff --git a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs index 25f6858be..43facde53 100644 --- a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs +++ b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs @@ -1,14 +1,14 @@ //! `expand_message_xof` for the `ExpandMsg` trait use super::{Domain, ExpandMsg, Expander}; -use crate::{Error, Result}; +use crate::Result; use core::{fmt, num::NonZero, ops::Mul}; use digest::{ CollisionResistance, ExtendableOutput, HashMarker, Update, XofReader, typenum::IsGreaterOrEqual, }; use hybrid_array::{ ArraySize, - typenum::{IsLess, Prod, True, U2, U256}, + typenum::{Prod, True, U2}, }; /// Implements `expand_message_xof` via the [`ExpandMsg`] trait: @@ -16,7 +16,7 @@ use hybrid_array::{ /// /// # Errors /// - `dst` contains no bytes -/// - `len_in_bytes > u16::MAX` +/// - `dst > 255 && K * 2 > 255` pub struct ExpandMsgXof where HashT: Default + ExtendableOutput + Update + HashMarker, @@ -41,7 +41,7 @@ where HashT: Default + ExtendableOutput + Update + HashMarker, // If DST is larger than 255 bytes, the length of the computed DST is calculated by `K * 2`. // https://www.rfc-editor.org/rfc/rfc9380.html#section-5.3.1-2.1 - K: Mul>, + K: Mul, // The collision resistance of `HashT` MUST be at least `K` bits. // https://www.rfc-editor.org/rfc/rfc9380.html#section-5.3.2-2.1 HashT: CollisionResistance>, @@ -51,9 +51,9 @@ where fn expand_message<'dst>( msg: &[&[u8]], dst: &'dst [&[u8]], - len_in_bytes: NonZero, + len_in_bytes: NonZero, ) -> Result> { - let len_in_bytes = u16::try_from(len_in_bytes.get()).map_err(|_| Error)?; + let len_in_bytes = len_in_bytes.get(); let domain = Domain::>::xof::(dst)?; let mut reader = HashT::default(); @@ -81,12 +81,14 @@ where #[cfg(test)] mod test { + use crate::Error; + use super::*; use core::mem::size_of; use hex_literal::hex; use hybrid_array::{ Array, ArraySize, - typenum::{U16, U32, U128}, + typenum::{IsLess, U16, U32, U128, U65536}, }; use sha3::Shake128; @@ -124,14 +126,14 @@ mod test { + Update + HashMarker + CollisionResistance>, - L: ArraySize, + L: ArraySize + IsLess, { assert_message(self.msg, domain, L::to_u16(), self.msg_prime); let mut expander = as ExpandMsg>::expand_message( &[self.msg], &[dst], - NonZero::new(L::to_usize()).ok_or(Error)?, + NonZero::new(L::U16).ok_or(Error)?, )?; let mut uniform_bytes = Array::::default(); From 5f5f6ab11a9cdc2ac81b536dca3e8ba5e2066f3f Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 13 Jun 2025 17:25:51 -0600 Subject: [PATCH 1399/1461] elliptic-curve: re-export `group::Curve` as `CurveGroup` (#1902) This crate also defines a `Curve` trait, and while that trait is used to describe an elliptic curve, `group::Curve` is a `Group`, i.e. the elliptic curve group for a particular curve. See also: zkcrypto/group#51 To prevent this name clash, this commit re-exports `group::Curve` as `CurveGroup`. cc @daxpedda --- elliptic-curve/src/arithmetic.rs | 6 +++--- elliptic-curve/src/dev.rs | 8 ++++---- elliptic-curve/src/ecdh.rs | 5 ++--- elliptic-curve/src/lib.rs | 2 +- elliptic-curve/src/ops.rs | 5 +++-- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/elliptic-curve/src/arithmetic.rs b/elliptic-curve/src/arithmetic.rs index 6e18774d2..88769e5dc 100644 --- a/elliptic-curve/src/arithmetic.rs +++ b/elliptic-curve/src/arithmetic.rs @@ -1,7 +1,7 @@ //! Elliptic curve arithmetic traits. use crate::{ - Curve, Error, FieldBytes, NonZeroScalar, PrimeCurve, ScalarPrimitive, + Curve, CurveGroup, Error, FieldBytes, Group, NonZeroScalar, PrimeCurve, ScalarPrimitive, ops::{Invert, LinearCombination, Mul, Reduce, ShrAssign}, point::{AffineCoordinates, NonIdentity}, scalar::{FromUintUnchecked, IsHigh}, @@ -50,8 +50,8 @@ pub trait CurveArithmetic: Curve { + LinearCombination<[(Self::ProjectivePoint, Self::Scalar)]> + LinearCombination<[(Self::ProjectivePoint, Self::Scalar); 2]> + TryInto, Error = Error> - + group::Curve - + group::Group; + + CurveGroup + + Group; /// Scalar field modulo this curve's order. /// diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 4d1f6c080..e6f6c1418 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -4,7 +4,7 @@ //! the traits in this crate. use crate::{ - BatchNormalize, Curve, CurveArithmetic, FieldBytesEncoding, PrimeCurve, + BatchNormalize, Curve, CurveArithmetic, CurveGroup, FieldBytesEncoding, PrimeCurve, array::typenum::U32, bigint::{Limb, U256}, error::{Error, Result}, @@ -651,7 +651,7 @@ impl From> for ProjectivePoint { impl From for AffinePoint { fn from(point: ProjectivePoint) -> AffinePoint { - group::Curve::to_affine(&point) + CurveGroup::to_affine(&point) } } @@ -736,11 +736,11 @@ impl group::GroupEncoding for ProjectivePoint { } fn to_bytes(&self) -> Self::Repr { - group::Curve::to_affine(self).to_bytes() + CurveGroup::to_affine(self).to_bytes() } } -impl group::Curve for ProjectivePoint { +impl CurveGroup for ProjectivePoint { type AffineRepr = AffinePoint; fn to_affine(&self) -> AffinePoint { diff --git a/elliptic-curve/src/ecdh.rs b/elliptic-curve/src/ecdh.rs index 74143999a..87784ec4a 100644 --- a/elliptic-curve/src/ecdh.rs +++ b/elliptic-curve/src/ecdh.rs @@ -27,12 +27,11 @@ //! [SIGMA]: https://webee.technion.ac.il/~hugo/sigma-pdf.pdf use crate::{ - AffinePoint, Curve, CurveArithmetic, FieldBytes, NonZeroScalar, ProjectivePoint, PublicKey, - point::AffineCoordinates, + AffinePoint, Curve, CurveArithmetic, CurveGroup, FieldBytes, NonZeroScalar, ProjectivePoint, + PublicKey, point::AffineCoordinates, }; use core::{borrow::Borrow, fmt}; use digest::{Digest, crypto_common::BlockSizeUser}; -use group::Curve as _; use hkdf::{Hkdf, hmac::SimpleHmac}; use rand_core::{CryptoRng, TryCryptoRng}; use zeroize::{Zeroize, ZeroizeOnDrop}; diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 79f444d3b..4876c9716 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -139,7 +139,7 @@ pub use { scalar::{NonZeroScalar, Scalar}, }, ff::{self, Field, PrimeField}, - group::{self, Group}, + group::{self, Curve as CurveGroup, Group}, }; #[cfg(feature = "jwk")] diff --git a/elliptic-curve/src/ops.rs b/elliptic-curve/src/ops.rs index 3fd9bb820..2e7252d65 100644 --- a/elliptic-curve/src/ops.rs +++ b/elliptic-curve/src/ops.rs @@ -1,9 +1,10 @@ //! Traits for arithmetic operations on elliptic curve field elements. -use core::iter; pub use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Shr, ShrAssign, Sub, SubAssign}; pub use crypto_bigint::Invert; +use crate::CurveGroup; +use core::iter; use crypto_bigint::Integer; use ff::Field; use subtle::{Choice, CtOption}; @@ -159,7 +160,7 @@ pub(crate) fn invert_batch_internal + MulAssign>( /// /// It's generic around `PointsAndScalars` to allow overlapping impls. For example, const generic /// impls can use the input size to determine the size needed to store temporary variables. -pub trait LinearCombination: group::Curve +pub trait LinearCombination: CurveGroup where PointsAndScalars: AsRef<[(Self, Self::Scalar)]> + ?Sized, { From 93974c9b453bd6f932de711b50bd928c34d8abaa Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 13 Jun 2025 19:35:45 -0600 Subject: [PATCH 1400/1461] elliptic-curve: extract `NonIdentity`/`NonZeroScalar` casting methods (#1903) These methods encapsulate safely casting references for arrays and slices of `NonIdentity

` to array/slice references to the inner `P` type, and the same for `NonZeroScalar` and its inner `Scalar` type. Note the choice of method names follows similar ones in `hybrid-array`: https://docs.rs/hybrid-array/latest/hybrid_array/struct.Array.html#method.cast_slice_to_core --- elliptic-curve/src/lib.rs | 3 +- elliptic-curve/src/point/non_identity.rs | 65 ++++++++++-------------- elliptic-curve/src/scalar/nonzero.rs | 22 ++++++++ 3 files changed, 49 insertions(+), 41 deletions(-) diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 4876c9716..ea08dd3b3 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -5,8 +5,7 @@ html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg" )] -// Only allowed for newtype casts. -#![deny(unsafe_code)] +#![deny(unsafe_code)] // Only allowed for newtype casts. #![warn( clippy::cast_lossless, clippy::cast_possible_truncation, diff --git a/elliptic-curve/src/point/non_identity.rs b/elliptic-curve/src/point/non_identity.rs index 7bc99b3d7..10f1a3de9 100644 --- a/elliptic-curve/src/point/non_identity.rs +++ b/elliptic-curve/src/point/non_identity.rs @@ -22,7 +22,7 @@ use crate::{BatchNormalize, CurveArithmetic, NonZeroScalar, Scalar}; /// In the context of ECC, it's useful for ensuring that certain arithmetic /// cannot result in the identity point. #[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[repr(transparent)] +#[repr(transparent)] // SAFETY: needed for `unsafe` safety invariants below pub struct NonIdentity

{ point: P, } @@ -51,6 +51,29 @@ where } } +impl

NonIdentity

{ + /// Transform array reference containing [`NonIdentity`] points to an array reference to the + /// inner point type. + pub fn cast_array_as_inner(points: &[Self; N]) -> &[P; N] { + // SAFETY: `NonIdentity` is a `repr(transparent)` newtype for `P` so it's safe to cast to + // the inner `P` type. + #[allow(unsafe_code)] + unsafe { + &*points.as_ptr().cast() + } + } + + /// Transform slice containing [`NonIdentity`] points to a slice of the inner point type. + pub fn cast_slice_as_inner(points: &[Self]) -> &[P] { + // SAFETY: `NonIdentity` is a `repr(transparent)` newtype for `P` so it's safe to cast to + // the inner `P` type. + #[allow(unsafe_code)] + unsafe { + &*(points as *const [NonIdentity

] as *const [P]) + } + } +} + impl NonIdentity

{ /// Return wrapped point. pub fn to_point(self) -> P { @@ -114,26 +137,8 @@ where type Output = [NonIdentity; N]; fn batch_normalize(points: &[Self; N]) -> [NonIdentity; N] { - // Ensure casting is safe. - // This always succeeds because `NonIdentity` is `repr(transparent)`. - debug_assert_eq!(size_of::

(), size_of::>()); - debug_assert_eq!(align_of::

(), align_of::>()); - - #[allow(unsafe_code)] - // SAFETY: `NonIdentity` is `repr(transparent)`. - let points: &[P; N] = unsafe { &*points.as_ptr().cast() }; + let points = Self::cast_array_as_inner::(points); let affine_points =

>::batch_normalize(points); - - // Ensure `array::map()` can be optimized to a `memcpy`. - debug_assert_eq!( - size_of::(), - size_of::>() - ); - debug_assert_eq!( - align_of::(), - align_of::>() - ); - affine_points.map(|point| NonIdentity { point }) } } @@ -146,26 +151,8 @@ where type Output = Vec>; fn batch_normalize(points: &[Self]) -> Vec> { - // Ensure casting is safe. - // This always succeeds because `NonIdentity` is `repr(transparent)`. - debug_assert_eq!(size_of::

(), size_of::>()); - debug_assert_eq!(align_of::

(), align_of::>()); - - #[allow(unsafe_code)] - // SAFETY: `NonIdentity` is `repr(transparent)`. - let points: &[P] = unsafe { &*(points as *const [NonIdentity

] as *const [P]) }; + let points = Self::cast_slice_as_inner(points); let affine_points =

>::batch_normalize(points); - - // Ensure `into_iter()` + `collect()` can be optimized away. - debug_assert_eq!( - size_of::(), - size_of::>() - ); - debug_assert_eq!( - align_of::(), - align_of::>() - ); - affine_points .into_iter() .map(|point| NonIdentity { point }) diff --git a/elliptic-curve/src/scalar/nonzero.rs b/elliptic-curve/src/scalar/nonzero.rs index 35688352a..d0dd1768b 100644 --- a/elliptic-curve/src/scalar/nonzero.rs +++ b/elliptic-curve/src/scalar/nonzero.rs @@ -33,6 +33,7 @@ use serdect::serde::{Deserialize, Serialize, de, ser}; /// In the context of ECC, it's useful for ensuring that scalar multiplication /// cannot result in the point at infinity. #[derive(Clone)] +#[repr(transparent)] // SAFETY: needed for `unsafe` safety invariants below pub struct NonZeroScalar where C: CurveArithmetic, @@ -88,6 +89,27 @@ where pub fn from_uint(uint: C::Uint) -> CtOption { ScalarPrimitive::new(uint).and_then(|scalar| Self::new(scalar.into())) } + + /// Transform array reference containing [`NonZeroScalar`]s to an array reference to the inner + /// scalar type. + pub fn cast_array_as_inner(scalars: &[Self; N]) -> &[Scalar; N] { + // SAFETY: `NonZeroScalar` is a `repr(transparent)` newtype for `Scalar` so it's safe to + // cast to the inner scalar type. + #[allow(unsafe_code)] + unsafe { + &*scalars.as_ptr().cast() + } + } + + /// Transform slice containing [`NonZeroScalar`]s to a slice of the inner scalar type. + pub fn cast_slice_as_inner(scalars: &[Self]) -> &[Scalar] { + // SAFETY: `NonZeroScalar` is a `repr(transparent)` newtype for `Scalar` so it's safe to + // cast to the inner scalar type. + #[allow(unsafe_code)] + unsafe { + &*(scalars as *const [NonZeroScalar] as *const [Scalar]) + } + } } impl AsRef> for NonZeroScalar From d4a01b11aef36d7a39c46e853a6fd68010171cf1 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 13 Jun 2025 19:40:44 -0600 Subject: [PATCH 1401/1461] elliptic-curve v0.14.0-rc.6 (#1904) --- Cargo.lock | 2 +- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a4342b93a..218014902 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -195,7 +195,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.14.0-rc.5" +version = "0.14.0-rc.6" dependencies = [ "base16ct", "base64ct", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 2773deb21..dd4ce4258 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.14.0-rc.5" +version = "0.14.0-rc.6" authors = ["RustCrypto Developers"] edition = "2024" rust-version = "1.85" From df51df4ba722181c9e221754afeefa2e972a678f Mon Sep 17 00:00:00 2001 From: daxpedda Date: Sat, 14 Jun 2025 15:31:47 +0200 Subject: [PATCH 1402/1461] Use `elliptic_curve::CurveGroup` (#1905) Where these missed in https://github.com/RustCrypto/traits/pull/1902? If not feel free to close. --- elliptic-curve/src/point/non_identity.rs | 10 +++++----- elliptic-curve/src/public_key.rs | 5 +++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/elliptic-curve/src/point/non_identity.rs b/elliptic-curve/src/point/non_identity.rs index 10f1a3de9..6617e2c9a 100644 --- a/elliptic-curve/src/point/non_identity.rs +++ b/elliptic-curve/src/point/non_identity.rs @@ -2,7 +2,7 @@ use core::ops::{Deref, Mul}; -use group::{Curve, Group, GroupEncoding, prime::PrimeCurveAffine}; +use group::{Group, GroupEncoding, prime::PrimeCurveAffine}; use rand_core::CryptoRng; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; @@ -13,7 +13,7 @@ use alloc::vec::Vec; use serdect::serde::{Deserialize, Serialize, de, ser}; use zeroize::Zeroize; -use crate::{BatchNormalize, CurveArithmetic, NonZeroScalar, Scalar}; +use crate::{BatchNormalize, CurveArithmetic, CurveGroup, NonZeroScalar, Scalar}; /// Non-identity point type. /// @@ -83,7 +83,7 @@ impl NonIdentity

{ impl

NonIdentity

where - P: ConditionallySelectable + ConstantTimeEq + Curve + Default, + P: ConditionallySelectable + ConstantTimeEq + CurveGroup + Default, { /// Generate a random `NonIdentity`. pub fn random(rng: &mut R) -> Self { @@ -132,7 +132,7 @@ impl

AsRef

for NonIdentity

{ impl BatchNormalize<[Self; N]> for NonIdentity

where - P: Curve + BatchNormalize<[P; N], Output = [P::AffineRepr; N]>, + P: CurveGroup + BatchNormalize<[P; N], Output = [P::AffineRepr; N]>, { type Output = [NonIdentity; N]; @@ -146,7 +146,7 @@ where #[cfg(feature = "alloc")] impl

BatchNormalize<[Self]> for NonIdentity

where - P: Curve + BatchNormalize<[P], Output = Vec>, + P: CurveGroup + BatchNormalize<[P], Output = Vec>, { type Output = Vec>; diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index 40bc93ac1..0dff18e99 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -1,10 +1,11 @@ //! Elliptic curve public keys. use crate::{ - AffinePoint, CurveArithmetic, Error, NonZeroScalar, ProjectivePoint, Result, point::NonIdentity, + AffinePoint, CurveArithmetic, CurveGroup, Error, NonZeroScalar, ProjectivePoint, Result, + point::NonIdentity, }; use core::fmt::Debug; -use group::{Curve, Group}; +use group::Group; #[cfg(feature = "jwk")] use crate::{JwkEcKey, JwkParameters}; From efb7780b086fad4b8d6eaf13f5471d102b162bf7 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 15 Jun 2025 18:43:44 -0600 Subject: [PATCH 1403/1461] elliptic-curve: bump `crypto-bigint` to v0.7.0-pre.5 (#1906) --- Cargo.lock | 4 ++-- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 218014902..585cfa6ec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -151,9 +151,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.7.0-pre.4" +version = "0.7.0-pre.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edaae5fb9dac79a07260e0b2006799ff4f1d342ab243fd7d0892215113b27904" +checksum = "a06a5e703b883b3744ddac8b7c5eade2d800d6559ef99760566f8103e3ad39bf" dependencies = [ "hybrid-array", "num-traits", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index dd4ce4258..da5a32e4b 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -18,7 +18,7 @@ and public/secret keys composed thereof. [dependencies] base16ct = "0.2" -crypto-bigint = { version = "=0.7.0-pre.4", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } +crypto-bigint = { version = "=0.7.0-pre.5", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } hybrid-array = { version = "0.3", default-features = false, features = ["zeroize"] } rand_core = { version = "0.9.0", default-features = false } subtle = { version = "2.6", default-features = false } From 2b8874dc645e2a7537c6d640dfe7418bd5839ab3 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 16 Jun 2025 12:09:40 -0600 Subject: [PATCH 1404/1461] elliptic-curve v0.14.0-rc.7 (#1908) --- Cargo.lock | 2 +- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 585cfa6ec..bc6eea668 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -195,7 +195,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.14.0-rc.6" +version = "0.14.0-rc.7" dependencies = [ "base16ct", "base64ct", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index da5a32e4b..400b57e7b 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.14.0-rc.6" +version = "0.14.0-rc.7" authors = ["RustCrypto Developers"] edition = "2024" rust-version = "1.85" From 946e0f471af4f4f5dd33c59b3eecdd50809f1511 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Jun 2025 12:25:44 +0300 Subject: [PATCH 1405/1461] Update Cargo.lock (#1909) --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bc6eea668..f8a506e66 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -362,15 +362,15 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.172" +version = "0.2.173" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" +checksum = "d8cfeafaffdbc32176b64fb251369d52ea9f0a8fbc6f8759edffef7b525d64bb" [[package]] name = "memchr" -version = "2.7.4" +version = "2.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" [[package]] name = "num-bigint" From 57aea511ffc6e8122ef4abced5135ea29473ef8d Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Tue, 17 Jun 2025 18:06:36 +0300 Subject: [PATCH 1406/1461] cipher: add methods for writing keystream (#1907) --- cipher/src/stream.rs | 20 +++++++++++++ cipher/src/stream/wrapper.rs | 56 +++++++++++++++++++++++++++++++++++- 2 files changed, 75 insertions(+), 1 deletion(-) diff --git a/cipher/src/stream.rs b/cipher/src/stream.rs index 520837db5..a1ba34347 100644 --- a/cipher/src/stream.rs +++ b/cipher/src/stream.rs @@ -104,6 +104,16 @@ pub trait StreamCipher { self.try_apply_keystream_inout(buf.into()) } + /// Write keystream to `buf`. + /// + /// If end of the keystream will be achieved with the given data length, + /// method will return [`StreamCipherError`] without modifying provided `data`. + #[inline] + fn try_write_keystream(&mut self, buf: &mut [u8]) -> Result<(), StreamCipherError> { + buf.fill(0); + self.try_apply_keystream(buf) + } + /// Apply keystream to `inout` data. /// /// It will XOR generated keystream with the data behind `in` pointer @@ -130,6 +140,16 @@ pub trait StreamCipher { self.try_apply_keystream(buf).unwrap(); } + /// Write keystream to `buf`. + /// + /// # Panics + /// If end of the keystream will be reached with the given data length, + /// method will panic without modifying the provided `data`. + #[inline] + fn write_keystream(&mut self, buf: &mut [u8]) { + self.try_write_keystream(buf).unwrap(); + } + /// Apply keystream to data buffer-to-buffer. /// /// It will XOR generated keystream with data from the `input` buffer diff --git a/cipher/src/stream/wrapper.rs b/cipher/src/stream/wrapper.rs index e438ef4a4..3dbc7e1b5 100644 --- a/cipher/src/stream/wrapper.rs +++ b/cipher/src/stream/wrapper.rs @@ -3,7 +3,9 @@ use super::{ StreamCipherSeekCore, errors::StreamCipherError, }; use core::fmt; -use crypto_common::{Iv, IvSizeUser, Key, KeyInit, KeyIvInit, KeySizeUser, typenum::Unsigned}; +use crypto_common::{ + Iv, IvSizeUser, Key, KeyInit, KeyIvInit, KeySizeUser, array::Array, typenum::Unsigned, +}; use inout::InOutBuf; #[cfg(feature = "zeroize")] use zeroize::{Zeroize, ZeroizeOnDrop}; @@ -170,6 +172,58 @@ impl StreamCipher for StreamCipherCoreWrapper { Ok(()) } + + #[inline] + fn try_write_keystream(&mut self, mut data: &mut [u8]) -> Result<(), StreamCipherError> { + self.check_remaining(data.len())?; + + let pos = usize::from(self.get_pos()); + let rem = usize::from(self.remaining()); + let data_len = data.len(); + + if rem != 0 { + if data_len <= rem { + data.copy_from_slice(&self.buffer[pos..][..data_len]); + // SAFETY: we have checked that `data_len` is less or equal to length + // of remaining keystream data, thus `pos + data_len` can not be bigger + // than block size. Since `pos` is never zero, `pos + data_len` can not + // be zero. Thus `pos + data_len` satisfies the safety invariant required + // by `set_pos_unchecked`. + unsafe { + self.set_pos_unchecked(pos + data_len); + } + return Ok(()); + } + let (left, right) = data.split_at_mut(rem); + data = right; + left.copy_from_slice(&self.buffer[pos..]); + } + + let (blocks, tail) = Array::slice_as_chunks_mut(data); + self.core.write_keystream_blocks(blocks); + + let new_pos = if tail.is_empty() { + T::BlockSize::USIZE + } else { + // Note that we temporarily write a pseudo-random byte into + // the first byte of `self.buffer`. It may break the safety invariant, + // but after writing keystream block with `tail`, we immediately + // overwrite the first byte with a correct value. + self.core.write_keystream_block(&mut self.buffer); + tail.copy_from_slice(&self.buffer[..tail.len()]); + tail.len() + }; + + // SAFETY: `into_chunks` always returns tail with size + // less than block size. If `tail.len()` is zero, we replace + // it with block size. Thus the invariant required by + // `set_pos_unchecked` is satisfied. + unsafe { + self.set_pos_unchecked(new_pos); + } + + Ok(()) + } } impl StreamCipherSeek for StreamCipherCoreWrapper { From fea157b0864f80a444aaff52c0a69b57b7f48492 Mon Sep 17 00:00:00 2001 From: VolodymyrBg Date: Thu, 19 Jun 2025 00:11:19 +0300 Subject: [PATCH 1407/1461] elliptic-curve: update SIGMA protocol reference link (#1910) Replaced the outdated SIGMA protocol reference link in the ECDH module documentation with the official IACR archive PDF. The new link points to the full text of "SIGMA: the 'SIGn-and-MAc' Approach to Authenticated Diffie-Hellman and its Use in the IKE Protocols" by Hugo Krawczyk (CRYPTO 2003), ensuring long-term accessibility and citation accuracy. --- elliptic-curve/src/ecdh.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elliptic-curve/src/ecdh.rs b/elliptic-curve/src/ecdh.rs index 87784ec4a..1fed3168d 100644 --- a/elliptic-curve/src/ecdh.rs +++ b/elliptic-curve/src/ecdh.rs @@ -24,7 +24,7 @@ //! [`diffie_hellman`] function. //! //! [AKE]: https://en.wikipedia.org/wiki/Authenticated_Key_Exchange -//! [SIGMA]: https://webee.technion.ac.il/~hugo/sigma-pdf.pdf +//! [SIGMA]: https://www.iacr.org/cryptodb/archive/2003/CRYPTO/1495/1495.pdf use crate::{ AffinePoint, Curve, CurveArithmetic, CurveGroup, FieldBytes, NonZeroScalar, ProjectivePoint, From f517eff1f9821f7d67c0bbf9f9fe873ba12f3ab5 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 21 Jun 2025 21:12:46 -0600 Subject: [PATCH 1408/1461] elliptic-curve: `der` error handling fixups (#1912) Companion PR to RustCrypto/formats#1889 --- Cargo.lock | 11 ++++------- Cargo.toml | 4 ++++ elliptic-curve/src/public_key.rs | 4 ++-- elliptic-curve/src/secret_key.rs | 4 ++-- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f8a506e66..7900f9f7c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -172,9 +172,8 @@ dependencies = [ [[package]] name = "der" -version = "0.8.0-rc.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c2e6107818886eff6b71fba7a2da3dd11025ebb80f0c9b94ff961168ef629f2" +version = "0.8.0-rc.5" +source = "git+https://github.com/RustCrypto/formats.git#4cb99df01f32ecc51f036de5d71a42d84cb6f499" dependencies = [ "const-oid", "pem-rfc7468", @@ -422,8 +421,7 @@ dependencies = [ [[package]] name = "pkcs8" version = "0.11.0-rc.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f1843d4345dfe1a55e487db747a04c01af50415b03e937410e0a41d8cc24ec7" +source = "git+https://github.com/RustCrypto/formats.git#4cb99df01f32ecc51f036de5d71a42d84cb6f499" dependencies = [ "der", "spki", @@ -478,8 +476,7 @@ checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "sec1" version = "0.8.0-rc.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4855dd9b15e8e469fad23529698f7f7b7a6b250a81c88b1f9d7efe1abca7717" +source = "git+https://github.com/RustCrypto/formats.git#4cb99df01f32ecc51f036de5d71a42d84cb6f499" dependencies = [ "base16ct", "der", diff --git a/Cargo.toml b/Cargo.toml index f89b4edce..7d2fdee4d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,3 +16,7 @@ members = [ [patch.crates-io] digest = { path = "digest" } signature = { path = "signature" } + +der = { git = "https://github.com/RustCrypto/formats.git" } +pkcs8 = { git = "https://github.com/RustCrypto/formats.git" } +sec1 = { git = "https://github.com/RustCrypto/formats.git" } diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index 0dff18e99..6995b2568 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -467,10 +467,10 @@ where let public_key_bytes = spki .subject_public_key .as_bytes() - .ok_or_else(|| der::Tag::BitString.value_error())?; + .ok_or_else(|| der::Tag::BitString.value_error().to_error())?; Self::from_sec1_bytes(public_key_bytes) - .map_err(|_| der::Tag::BitString.value_error().into()) + .map_err(|_| der::Tag::BitString.value_error().to_error().into()) } } diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index a7119719d..61b7655e5 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -374,7 +374,7 @@ where fn try_from(sec1_private_key: sec1::EcPrivateKey<'_>) -> der::Result { if let Some(sec1::EcParameters::NamedCurve(curve_oid)) = sec1_private_key.parameters { if C::OID != curve_oid { - return Err(der::Tag::ObjectIdentifier.value_error()); + return Err(der::Tag::ObjectIdentifier.value_error().into()); } } @@ -386,7 +386,7 @@ where .map_err(|_| der::Tag::BitString.value_error())?; if C::validate_public_key(&secret_key, &pk).is_err() { - return Err(der::Tag::BitString.value_error()); + return Err(der::Tag::BitString.value_error().into()); } } From 39a27c20db82f72d2368dc688851863cde73ff13 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Jun 2025 04:26:56 +0300 Subject: [PATCH 1409/1461] Update Cargo.lock (#1913) --- Cargo.lock | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7900f9f7c..3580b98c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -33,9 +33,9 @@ checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "autocfg" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "base16ct" @@ -361,9 +361,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.173" +version = "0.2.174" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8cfeafaffdbc32176b64fb251369d52ea9f0a8fbc6f8759edffef7b525d64bb" +checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" [[package]] name = "memchr" @@ -447,9 +447,9 @@ dependencies = [ [[package]] name = "r-efi" -version = "5.2.0" +version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" [[package]] name = "radium" @@ -657,18 +657,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.25" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb" +checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.25" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef" +checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" dependencies = [ "proc-macro2", "quote", From 3a293b63bf396cd058b2c7621a884134c8b456d5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Jul 2025 05:10:31 +0300 Subject: [PATCH 1410/1461] ci: bump crate-ci/typos from 1.33.1 to 1.34.0 (#1918) --- .github/workflows/workspace.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index cf07eadfe..564f5925a 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -52,4 +52,4 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: crate-ci/typos@v1.33.1 + - uses: crate-ci/typos@v1.34.0 From f786aba29c11038d5b5ec6493f2eb1c60c250fbd Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 3 Jul 2025 13:25:56 -0600 Subject: [PATCH 1411/1461] elliptic-curve: bump `pkcs8` and `sec1` (#1919) - pkcs8 v0.11.0-rc.5 - sec1 v0.8.0-rc.6 --- Cargo.lock | 19 +++++++++++-------- Cargo.toml | 4 ---- elliptic-curve/Cargo.toml | 4 ++-- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3580b98c7..89b84c13f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -172,8 +172,9 @@ dependencies = [ [[package]] name = "der" -version = "0.8.0-rc.5" -source = "git+https://github.com/RustCrypto/formats.git#4cb99df01f32ecc51f036de5d71a42d84cb6f499" +version = "0.8.0-rc.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7d571780ddd86c50ecbcf7099a945804a55e39c5d13f27d0225c1acecbae248" dependencies = [ "const-oid", "pem-rfc7468", @@ -420,8 +421,9 @@ dependencies = [ [[package]] name = "pkcs8" -version = "0.11.0-rc.4" -source = "git+https://github.com/RustCrypto/formats.git#4cb99df01f32ecc51f036de5d71a42d84cb6f499" +version = "0.11.0-rc.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef85549ba672d102373a0566b322f6618e009442459effa41d5b32741981014d" dependencies = [ "der", "spki", @@ -475,8 +477,9 @@ checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "sec1" -version = "0.8.0-rc.5" -source = "git+https://github.com/RustCrypto/formats.git#4cb99df01f32ecc51f036de5d71a42d84cb6f499" +version = "0.8.0-rc.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1231d6ed04c5242799d39a97ca91aeda70ecc27a67870a5fe43149e5c12aed3d" dependencies = [ "base16ct", "der", @@ -560,9 +563,9 @@ dependencies = [ [[package]] name = "spki" -version = "0.8.0-rc.2" +version = "0.8.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2f0e2bdca9b00f5be6dd3bb6647d50fd0f24a508a95f78e3bb2fe98d0403c85" +checksum = "4b59f16f15f6f84d24525ca54974b59147ec161ef666b44d055a419bc6392582" dependencies = [ "base64ct", "der", diff --git a/Cargo.toml b/Cargo.toml index 7d2fdee4d..f89b4edce 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,3 @@ members = [ [patch.crates-io] digest = { path = "digest" } signature = { path = "signature" } - -der = { git = "https://github.com/RustCrypto/formats.git" } -pkcs8 = { git = "https://github.com/RustCrypto/formats.git" } -sec1 = { git = "https://github.com/RustCrypto/formats.git" } diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 400b57e7b..66df17759 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -32,8 +32,8 @@ group = { version = "=0.14.0-pre.0", optional = true, default-features = false } hkdf = { version = "0.13.0-rc.0", optional = true, default-features = false } hex-literal = { version = "1", optional = true } pem-rfc7468 = { version = "1.0.0-rc.2", optional = true, features = ["alloc"] } -pkcs8 = { version = "0.11.0-rc.1", optional = true, default-features = false } -sec1 = { version = "0.8.0-rc.4", optional = true, features = ["subtle", "zeroize"] } +pkcs8 = { version = "0.11.0-rc.5", optional = true, default-features = false } +sec1 = { version = "0.8.0-rc.6", optional = true, features = ["subtle", "zeroize"] } serdect = { version = "0.3", optional = true, default-features = false, features = ["alloc"] } serde_json = { version = "1.0.121", optional = true, default-features = false, features = ["alloc"] } From e5d4332409022148040af5e4ae029996f90ff739 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 3 Jul 2025 13:58:14 -0600 Subject: [PATCH 1412/1461] elliptic-curve: bump `crypto-bigint` to v0.7.0-pre.6 (#1920) --- Cargo.lock | 4 ++-- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 89b84c13f..dd575748a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -151,9 +151,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.7.0-pre.5" +version = "0.7.0-pre.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06a5e703b883b3744ddac8b7c5eade2d800d6559ef99760566f8103e3ad39bf" +checksum = "98dc20cae677f0af161d98f18463804b680f9af060f6dbe6d4249bd7e838bca1" dependencies = [ "hybrid-array", "num-traits", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 66df17759..272125d1b 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -18,7 +18,7 @@ and public/secret keys composed thereof. [dependencies] base16ct = "0.2" -crypto-bigint = { version = "=0.7.0-pre.5", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } +crypto-bigint = { version = "=0.7.0-pre.6", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } hybrid-array = { version = "0.3", default-features = false, features = ["zeroize"] } rand_core = { version = "0.9.0", default-features = false } subtle = { version = "2.6", default-features = false } From ba41e2c30f4aab1a97fad65fe9bbc3bea893cd9c Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 3 Jul 2025 14:03:38 -0600 Subject: [PATCH 1413/1461] elliptic-curve v0.14.0-rc.8 (#1921) --- Cargo.lock | 2 +- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dd575748a..e6ea24012 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -195,7 +195,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.14.0-rc.7" +version = "0.14.0-rc.8" dependencies = [ "base16ct", "base64ct", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 272125d1b..66d77a514 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.14.0-rc.7" +version = "0.14.0-rc.8" authors = ["RustCrypto Developers"] edition = "2024" rust-version = "1.85" From 5cacd6508eab7c05724279d029b89849df5eba15 Mon Sep 17 00:00:00 2001 From: Charles Edward Gagnon <76854355+carloskiki@users.noreply.github.com> Date: Fri, 4 Jul 2025 12:48:07 -0400 Subject: [PATCH 1414/1461] signature: Remove blanket `SignerMut` impl (breaking change) (#1915) As discussed in #1914. --- signature/CHANGELOG.md | 1 + signature/src/signer.rs | 7 ------- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/signature/CHANGELOG.md b/signature/CHANGELOG.md index 1f0304fbf..619aa4e92 100644 --- a/signature/CHANGELOG.md +++ b/signature/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Removed - `std` feature - replaced with `core::error::Error` - `derive` feature +- `SignerMut` blanket implementation for `Signer` [#1448]: https://github.com/RustCrypto/traits/pull/1448 [#1759]: https://github.com/RustCrypto/traits/pull/1759 diff --git a/signature/src/signer.rs b/signature/src/signer.rs index b9eec6eab..7fc10764f 100644 --- a/signature/src/signer.rs +++ b/signature/src/signer.rs @@ -55,13 +55,6 @@ pub trait SignerMut { fn try_sign(&mut self, msg: &[u8]) -> Result; } -/// Blanket impl of [`SignerMut`] for all [`Signer`] types. -impl> SignerMut for T { - fn try_sign(&mut self, msg: &[u8]) -> Result { - T::try_sign(self, msg) - } -} - /// Sign the given prehashed message [`Digest`] using `Self`. /// /// ## Notes From e88b28f223990c2fc41a14fbec5b210add36ac47 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Sun, 6 Jul 2025 20:00:16 +0200 Subject: [PATCH 1415/1461] elliptic-curve: fix doc comment in `TryFrom` for `NonZeroScalar` (#1922) --- elliptic-curve/src/macros.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/elliptic-curve/src/macros.rs b/elliptic-curve/src/macros.rs index 0f868912e..9e69df31b 100644 --- a/elliptic-curve/src/macros.rs +++ b/elliptic-curve/src/macros.rs @@ -55,7 +55,8 @@ macro_rules! scalar_from_impls { } } - /// The constant-time alternative is available at [`$crate::NonZeroScalar<$curve>::new()`]. + /// The constant-time alternative is available at + #[doc = concat!("[`", stringify!(elliptic_curve), "::NonZeroScalar<", stringify!($curve), ">::new()`].")] impl TryFrom<$scalar> for $crate::NonZeroScalar<$curve> { type Error = $crate::Error; From 3b1f80e651bb6f7c1b5dd43a7b8ef531a7a00355 Mon Sep 17 00:00:00 2001 From: Charles Edward Gagnon <76854355+carloskiki@users.noreply.github.com> Date: Sun, 6 Jul 2025 17:34:32 -0400 Subject: [PATCH 1416/1461] signature: revome `PrehashSignature` (#1924) Closes #1917. --- signature/CHANGELOG.md | 1 + signature/src/lib.rs | 5 +---- signature/src/prehash_signature.rs | 26 -------------------------- 3 files changed, 2 insertions(+), 30 deletions(-) delete mode 100644 signature/src/prehash_signature.rs diff --git a/signature/CHANGELOG.md b/signature/CHANGELOG.md index 619aa4e92..4eeb0c2cf 100644 --- a/signature/CHANGELOG.md +++ b/signature/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `std` feature - replaced with `core::error::Error` - `derive` feature - `SignerMut` blanket implementation for `Signer` +- `PrehashSignature` trait [#1448]: https://github.com/RustCrypto/traits/pull/1448 [#1759]: https://github.com/RustCrypto/traits/pull/1759 diff --git a/signature/src/lib.rs b/signature/src/lib.rs index b8678e329..2baa59f1b 100644 --- a/signature/src/lib.rs +++ b/signature/src/lib.rs @@ -141,12 +141,9 @@ mod signer; mod verifier; #[cfg(feature = "digest")] -mod prehash_signature; +pub use digest; pub use crate::{encoding::*, error::*, keypair::*, signer::*, verifier::*}; -#[cfg(feature = "digest")] -pub use {crate::prehash_signature::*, digest}; - #[cfg(feature = "rand_core")] pub use rand_core; diff --git a/signature/src/prehash_signature.rs b/signature/src/prehash_signature.rs deleted file mode 100644 index 773dc6ff9..000000000 --- a/signature/src/prehash_signature.rs +++ /dev/null @@ -1,26 +0,0 @@ -//! `PrehashSignature` trait. - -/// For intra-doc link resolution. -#[allow(unused_imports)] -use crate::{ - signer::{DigestSigner, Signer}, - verifier::{DigestVerifier, Verifier}, -}; - -/// Marker trait for `Signature` types computable as `𝐒(𝐇(𝒎))` -/// i.e. ones which prehash a message to be signed as `𝐇(𝒎)` -/// -/// Where: -/// -/// - `𝐒`: signature algorithm -/// - `𝐇`: hash (a.k.a. digest) function -/// - `𝒎`: message -/// -/// This approach is relatively common in signature schemes based on the -/// [Fiat-Shamir heuristic]. -/// -/// [Fiat-Shamir heuristic]: https://en.wikipedia.org/wiki/Fiat%E2%80%93Shamir_heuristic -pub trait PrehashSignature { - /// Preferred `Digest` algorithm to use when computing this signature type. - type Digest: digest::Digest; -} From c88bf24f26717016484adfbd742c5cd1866f0af5 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Wed, 9 Jul 2025 16:37:56 +0200 Subject: [PATCH 1417/1461] Remove `hash2curve` and `oprf` (#1929) This is the companion PR to https://github.com/RustCrypto/elliptic-curves/pull/1286. Resolves #1928. --- .github/workflows/elliptic-curve.yml | 4 +- elliptic-curve/Cargo.toml | 4 +- elliptic-curve/src/hash2curve.rs | 15 - elliptic-curve/src/hash2curve/group_digest.rs | 98 ---- elliptic-curve/src/hash2curve/hash2field.rs | 58 --- .../src/hash2curve/hash2field/expand_msg.rs | 155 ------ .../hash2curve/hash2field/expand_msg/xmd.rs | 452 ------------------ .../hash2curve/hash2field/expand_msg/xof.rs | 376 --------------- elliptic-curve/src/hash2curve/isogeny.rs | 58 --- elliptic-curve/src/hash2curve/map2curve.rs | 33 -- elliptic-curve/src/hash2curve/osswu.rs | 131 ----- elliptic-curve/src/lib.rs | 8 - elliptic-curve/src/oprf.rs | 30 -- 13 files changed, 2 insertions(+), 1420 deletions(-) delete mode 100644 elliptic-curve/src/hash2curve.rs delete mode 100644 elliptic-curve/src/hash2curve/group_digest.rs delete mode 100644 elliptic-curve/src/hash2curve/hash2field.rs delete mode 100644 elliptic-curve/src/hash2curve/hash2field/expand_msg.rs delete mode 100644 elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs delete mode 100644 elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs delete mode 100644 elliptic-curve/src/hash2curve/isogeny.rs delete mode 100644 elliptic-curve/src/hash2curve/map2curve.rs delete mode 100644 elliptic-curve/src/hash2curve/osswu.rs delete mode 100644 elliptic-curve/src/oprf.rs diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index 8ab5154ce..43343005d 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -43,9 +43,7 @@ jobs: - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features dev - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features digest - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features ecdh - - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features hash2curve - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features jwk - - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features oprf - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features pem - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features pkcs8 - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features sec1 @@ -54,7 +52,7 @@ jobs: - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,arithmetic,pkcs8 - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,serde - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features arithmetic,serde - - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,digest,ecdh,hash2curve,jwk,oprf,pem,pkcs8,sec1,serde + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,digest,ecdh,jwk,pem,pkcs8,sec1,serde minimal-versions: # Temporarily disabled until elliptic-curve 0.13.0-pre.0 is published diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 66d77a514..d24885b87 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -64,12 +64,10 @@ bits = ["arithmetic", "ff/bits"] dev = ["arithmetic", "dep:hex-literal", "pem", "pkcs8"] ecdh = ["arithmetic", "digest", "dep:hkdf"] group = ["dep:group", "ff"] -hash2curve = ["arithmetic", "digest"] jwk = ["dep:base64ct", "dep:serde_json", "alloc", "serde", "zeroize/alloc"] -oprf = ["digest", "hash2curve"] pkcs8 = ["dep:pkcs8", "sec1"] pem = ["dep:pem-rfc7468", "alloc", "arithmetic", "pkcs8", "sec1/pem"] serde = ["dep:serdect", "alloc", "pkcs8", "sec1/serde"] [package.metadata.docs.rs] -features = ["bits", "ecdh", "hash2curve", "jwk", "oprf", "pem", "std"] +features = ["bits", "ecdh", "jwk", "pem", "std"] diff --git a/elliptic-curve/src/hash2curve.rs b/elliptic-curve/src/hash2curve.rs deleted file mode 100644 index da923e4d2..000000000 --- a/elliptic-curve/src/hash2curve.rs +++ /dev/null @@ -1,15 +0,0 @@ -//! Traits for hashing byte sequences to curve points. -//! -//! - -mod group_digest; -mod hash2field; -mod isogeny; -mod map2curve; -mod osswu; - -pub use group_digest::*; -pub use hash2field::*; -pub use isogeny::*; -pub use map2curve::*; -pub use osswu::*; diff --git a/elliptic-curve/src/hash2curve/group_digest.rs b/elliptic-curve/src/hash2curve/group_digest.rs deleted file mode 100644 index 052098ce8..000000000 --- a/elliptic-curve/src/hash2curve/group_digest.rs +++ /dev/null @@ -1,98 +0,0 @@ -//! Traits for handling hash to curve. - -use super::{ExpandMsg, MapToCurve, hash_to_field}; -use crate::{ProjectivePoint, Result}; -use hybrid_array::typenum::Unsigned; - -/// Hash arbitrary byte sequences to a valid group element. -pub trait GroupDigest: MapToCurve { - /// The target security level in bytes: - /// - /// - type K: Unsigned; - - /// Computes the hash to curve routine. - /// - /// From : - /// - /// > Uniform encoding from byte strings to points in G. - /// > That is, the distribution of its output is statistically close - /// > to uniform in G. - /// > This function is suitable for most applications requiring a random - /// > oracle returning points in G assuming a cryptographically secure - /// > hash function is used. - /// - /// # Errors - /// - `len_in_bytes > u16::MAX` - /// - See implementors of [`ExpandMsg`] for additional errors: - /// - [`ExpandMsgXmd`] - /// - [`ExpandMsgXof`] - /// - /// `len_in_bytes = ::Length * 2` - /// - /// [`ExpandMsgXmd`]: crate::hash2curve::ExpandMsgXmd - /// [`ExpandMsgXof`]: crate::hash2curve::ExpandMsgXof - fn hash_from_bytes(msg: &[&[u8]], dst: &[&[u8]]) -> Result> - where - X: ExpandMsg, - { - let mut u = [Self::FieldElement::default(), Self::FieldElement::default()]; - hash_to_field::(msg, dst, &mut u)?; - let q0 = Self::map_to_curve(u[0]); - let q1 = Self::map_to_curve(u[1]); - Ok(Self::add_and_map_to_subgroup(q0, q1)) - } - - /// Computes the encode to curve routine. - /// - /// From : - /// - /// > Nonuniform encoding from byte strings to - /// > points in G. That is, the distribution of its output is not - /// > uniformly random in G: the set of possible outputs of - /// > encode_to_curve is only a fraction of the points in G, and some - /// > points in this set are more likely to be output than others. - /// - /// # Errors - /// - `len_in_bytes > u16::MAX` - /// - See implementors of [`ExpandMsg`] for additional errors: - /// - [`ExpandMsgXmd`] - /// - [`ExpandMsgXof`] - /// - /// `len_in_bytes = ::Length` - /// - /// [`ExpandMsgXmd`]: crate::hash2curve::ExpandMsgXmd - /// [`ExpandMsgXof`]: crate::hash2curve::ExpandMsgXof - fn encode_from_bytes(msg: &[&[u8]], dst: &[&[u8]]) -> Result> - where - X: ExpandMsg, - { - let mut u = [Self::FieldElement::default()]; - hash_to_field::(msg, dst, &mut u)?; - let q0 = Self::map_to_curve(u[0]); - Ok(Self::map_to_subgroup(q0)) - } - - /// Computes the hash to field routine according to - /// - /// and returns a scalar. - /// - /// # Errors - /// - `len_in_bytes > u16::MAX` - /// - See implementors of [`ExpandMsg`] for additional errors: - /// - [`ExpandMsgXmd`] - /// - [`ExpandMsgXof`] - /// - /// `len_in_bytes = ::Length` - /// - /// [`ExpandMsgXmd`]: crate::hash2curve::ExpandMsgXmd - /// [`ExpandMsgXof`]: crate::hash2curve::ExpandMsgXof - fn hash_to_scalar(msg: &[&[u8]], dst: &[&[u8]]) -> Result - where - X: ExpandMsg, - { - let mut u = [Self::Scalar::default()]; - hash_to_field::(msg, dst, &mut u)?; - Ok(u[0]) - } -} diff --git a/elliptic-curve/src/hash2curve/hash2field.rs b/elliptic-curve/src/hash2curve/hash2field.rs deleted file mode 100644 index a0db0cbb3..000000000 --- a/elliptic-curve/src/hash2curve/hash2field.rs +++ /dev/null @@ -1,58 +0,0 @@ -//! Traits for hashing to field elements. -//! -//! - -mod expand_msg; - -use core::num::NonZeroU16; - -pub use expand_msg::{xmd::*, xof::*, *}; - -use crate::{Error, Result}; -use hybrid_array::{ - Array, ArraySize, - typenum::{NonZero, Unsigned}, -}; - -/// The trait for helping to convert to a field element. -pub trait FromOkm { - /// The number of bytes needed to convert to a field element. - type Length: ArraySize + NonZero; - - /// Convert a byte sequence into a field element. - fn from_okm(data: &Array) -> Self; -} - -/// Convert an arbitrary byte sequence into a field element. -/// -/// -/// -/// # Errors -/// - `len_in_bytes > u16::MAX` -/// - See implementors of [`ExpandMsg`] for additional errors: -/// - [`ExpandMsgXmd`] -/// - [`ExpandMsgXof`] -/// -/// `len_in_bytes = T::Length * out.len()` -/// -/// [`ExpandMsgXmd`]: crate::hash2field::ExpandMsgXmd -/// [`ExpandMsgXof`]: crate::hash2field::ExpandMsgXof -#[doc(hidden)] -pub fn hash_to_field(data: &[&[u8]], domain: &[&[u8]], out: &mut [T]) -> Result<()> -where - E: ExpandMsg, - T: FromOkm + Default, -{ - let len_in_bytes = T::Length::USIZE - .checked_mul(out.len()) - .and_then(|len| len.try_into().ok()) - .and_then(NonZeroU16::new) - .ok_or(Error)?; - let mut tmp = Array::::Length>::default(); - let mut expander = E::expand_message(data, domain, len_in_bytes)?; - for o in out.iter_mut() { - expander.fill_bytes(&mut tmp); - *o = T::from_okm(&tmp); - } - Ok(()) -} diff --git a/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs b/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs deleted file mode 100644 index c01b70e4a..000000000 --- a/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs +++ /dev/null @@ -1,155 +0,0 @@ -//! `expand_message` interface `for hash_to_field`. - -pub(super) mod xmd; -pub(super) mod xof; - -use core::num::NonZero; - -use crate::{Error, Result}; -use digest::{Digest, ExtendableOutput, Update, XofReader}; -use hybrid_array::{Array, ArraySize}; - -/// Salt when the DST is too long -const OVERSIZE_DST_SALT: &[u8] = b"H2C-OVERSIZE-DST-"; -/// Maximum domain separation tag length -const MAX_DST_LEN: usize = 255; - -/// Trait for types implementing expand_message interface for `hash_to_field`. -/// -/// `K` is the target security level in bytes: -/// -/// -/// -/// # Errors -/// See implementors of [`ExpandMsg`] for errors. -pub trait ExpandMsg { - /// Type holding data for the [`Expander`]. - type Expander<'dst>: Expander + Sized; - - /// Expands `msg` to the required number of bytes. - /// - /// Returns an expander that can be used to call `read` until enough - /// bytes have been consumed - fn expand_message<'dst>( - msg: &[&[u8]], - dst: &'dst [&[u8]], - len_in_bytes: NonZero, - ) -> Result>; -} - -/// Expander that, call `read` until enough bytes have been consumed. -pub trait Expander { - /// Fill the array with the expanded bytes - fn fill_bytes(&mut self, okm: &mut [u8]); -} - -/// The domain separation tag -/// -/// Implements [section 5.3.3 of RFC9380][dst]. -/// -/// [dst]: https://www.rfc-editor.org/rfc/rfc9380.html#name-using-dsts-longer-than-255- -#[derive(Debug)] -pub(crate) enum Domain<'a, L: ArraySize> { - /// > 255 - Hashed(Array), - /// <= 255 - Array(&'a [&'a [u8]]), -} - -impl<'a, L: ArraySize> Domain<'a, L> { - pub fn xof(dst: &'a [&'a [u8]]) -> Result - where - X: Default + ExtendableOutput + Update, - { - // https://www.rfc-editor.org/rfc/rfc9380.html#section-3.1-4.2 - if dst.iter().map(|slice| slice.len()).sum::() == 0 { - Err(Error) - } else if dst.iter().map(|slice| slice.len()).sum::() > MAX_DST_LEN { - if L::USIZE > u8::MAX.into() { - return Err(Error); - } - - let mut data = Array::::default(); - let mut hash = X::default(); - hash.update(OVERSIZE_DST_SALT); - - for slice in dst { - hash.update(slice); - } - - hash.finalize_xof().read(&mut data); - - Ok(Self::Hashed(data)) - } else { - Ok(Self::Array(dst)) - } - } - - pub fn xmd(dst: &'a [&'a [u8]]) -> Result - where - X: Digest, - { - // https://www.rfc-editor.org/rfc/rfc9380.html#section-3.1-4.2 - if dst.iter().map(|slice| slice.len()).sum::() == 0 { - Err(Error) - } else if dst.iter().map(|slice| slice.len()).sum::() > MAX_DST_LEN { - if L::USIZE > u8::MAX.into() { - return Err(Error); - } - - Ok(Self::Hashed({ - let mut hash = X::new(); - hash.update(OVERSIZE_DST_SALT); - - for slice in dst { - hash.update(slice); - } - - hash.finalize() - })) - } else { - Ok(Self::Array(dst)) - } - } - - pub fn update_hash(&self, hash: &mut HashT) { - match self { - Self::Hashed(d) => hash.update(d), - Self::Array(d) => { - for d in d.iter() { - hash.update(d) - } - } - } - } - - pub fn len(&self) -> u8 { - match self { - // Can't overflow because it's checked on creation. - Self::Hashed(_) => L::U8, - // Can't overflow because it's checked on creation. - Self::Array(d) => { - u8::try_from(d.iter().map(|d| d.len()).sum::()).expect("length overflow") - } - } - } - - #[cfg(test)] - pub fn assert(&self, bytes: &[u8]) { - let data = match self { - Domain::Hashed(d) => d.to_vec(), - Domain::Array(d) => d.iter().copied().flatten().copied().collect(), - }; - assert_eq!(data, bytes); - } - - #[cfg(test)] - pub fn assert_dst(&self, bytes: &[u8]) { - let data = match self { - Domain::Hashed(d) => d.to_vec(), - Domain::Array(d) => d.iter().copied().flatten().copied().collect(), - }; - assert_eq!(data, &bytes[..bytes.len() - 1]); - assert_eq!(self.len(), bytes[bytes.len() - 1]); - } -} diff --git a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs deleted file mode 100644 index a68f53ec7..000000000 --- a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs +++ /dev/null @@ -1,452 +0,0 @@ -//! `expand_message_xmd` based on a hash function. - -use core::{marker::PhantomData, num::NonZero, ops::Mul}; - -use super::{Domain, ExpandMsg, Expander}; -use crate::{Error, Result}; -use digest::{ - FixedOutput, HashMarker, - array::{ - Array, - typenum::{IsGreaterOrEqual, IsLessOrEqual, Prod, True, U2, Unsigned}, - }, - block_api::BlockSizeUser, -}; - -/// Implements `expand_message_xof` via the [`ExpandMsg`] trait: -/// -/// -/// # Errors -/// - `dst` contains no bytes -/// - `dst > 255 && HashT::OutputSize > 255` -/// - `len_in_bytes > 255 * HashT::OutputSize` -#[derive(Debug)] -pub struct ExpandMsgXmd(PhantomData) -where - HashT: BlockSizeUser + Default + FixedOutput + HashMarker, - HashT::OutputSize: IsLessOrEqual; - -impl ExpandMsg for ExpandMsgXmd -where - HashT: BlockSizeUser + Default + FixedOutput + HashMarker, - // The number of bits output by `HashT` MUST be at most `HashT::BlockSize`. - // https://www.rfc-editor.org/rfc/rfc9380.html#section-5.3.1-4 - HashT::OutputSize: IsLessOrEqual, - // The number of bits output by `HashT` MUST be at least `K * 2`. - // https://www.rfc-editor.org/rfc/rfc9380.html#section-5.3.1-2.1 - K: Mul, - HashT::OutputSize: IsGreaterOrEqual, Output = True>, -{ - type Expander<'dst> = ExpanderXmd<'dst, HashT>; - - fn expand_message<'dst>( - msg: &[&[u8]], - dst: &'dst [&[u8]], - len_in_bytes: NonZero, - ) -> Result> { - let b_in_bytes = HashT::OutputSize::USIZE; - - // `255 * ` can not exceed `u16::MAX` - if usize::from(len_in_bytes.get()) > 255 * b_in_bytes { - return Err(Error); - } - - let ell = u8::try_from(usize::from(len_in_bytes.get()).div_ceil(b_in_bytes)) - .expect("should never pass the previous check"); - - let domain = Domain::xmd::(dst)?; - let mut b_0 = HashT::default(); - b_0.update(&Array::::default()); - - for msg in msg { - b_0.update(msg); - } - - b_0.update(&len_in_bytes.get().to_be_bytes()); - b_0.update(&[0]); - domain.update_hash(&mut b_0); - b_0.update(&[domain.len()]); - let b_0 = b_0.finalize_fixed(); - - let mut b_vals = HashT::default(); - b_vals.update(&b_0[..]); - b_vals.update(&[1u8]); - domain.update_hash(&mut b_vals); - b_vals.update(&[domain.len()]); - let b_vals = b_vals.finalize_fixed(); - - Ok(ExpanderXmd { - b_0, - b_vals, - domain, - index: 1, - offset: 0, - ell, - }) - } -} - -/// [`Expander`] type for [`ExpandMsgXmd`]. -#[derive(Debug)] -pub struct ExpanderXmd<'a, HashT> -where - HashT: BlockSizeUser + Default + FixedOutput + HashMarker, - HashT::OutputSize: IsLessOrEqual, -{ - b_0: Array, - b_vals: Array, - domain: Domain<'a, HashT::OutputSize>, - index: u8, - offset: usize, - ell: u8, -} - -impl ExpanderXmd<'_, HashT> -where - HashT: BlockSizeUser + Default + FixedOutput + HashMarker, - HashT::OutputSize: IsLessOrEqual, -{ - fn next(&mut self) -> bool { - if self.index < self.ell { - self.index += 1; - self.offset = 0; - // b_0 XOR b_(idx - 1) - let mut tmp = Array::::default(); - self.b_0 - .iter() - .zip(&self.b_vals[..]) - .enumerate() - .for_each(|(j, (b0val, bi1val))| tmp[j] = b0val ^ bi1val); - let mut b_vals = HashT::default(); - b_vals.update(&tmp); - b_vals.update(&[self.index]); - self.domain.update_hash(&mut b_vals); - b_vals.update(&[self.domain.len()]); - self.b_vals = b_vals.finalize_fixed(); - true - } else { - false - } - } -} - -impl Expander for ExpanderXmd<'_, HashT> -where - HashT: BlockSizeUser + Default + FixedOutput + HashMarker, - HashT::OutputSize: IsLessOrEqual, -{ - fn fill_bytes(&mut self, okm: &mut [u8]) { - for b in okm { - if self.offset == self.b_vals.len() && !self.next() { - return; - } - *b = self.b_vals[self.offset]; - self.offset += 1; - } - } -} - -#[cfg(test)] -mod test { - use super::*; - use hex_literal::hex; - use hybrid_array::{ - ArraySize, - typenum::{IsLess, U4, U8, U32, U128, U65536}, - }; - use sha2::Sha256; - - fn assert_message( - msg: &[u8], - domain: &Domain<'_, HashT::OutputSize>, - len_in_bytes: u16, - bytes: &[u8], - ) where - HashT: BlockSizeUser + Default + FixedOutput + HashMarker, - { - let block = HashT::BlockSize::USIZE; - assert_eq!( - Array::::default().as_slice(), - &bytes[..block] - ); - - let msg_len = block + msg.len(); - assert_eq!(msg, &bytes[block..msg_len]); - - let l = msg_len + size_of::(); - assert_eq!(len_in_bytes.to_be_bytes(), &bytes[msg_len..l]); - - let pad = l + size_of::(); - assert_eq!([0], &bytes[l..pad]); - - let dst = pad + usize::from(domain.len()); - domain.assert(&bytes[pad..dst]); - - let dst_len = dst + size_of::(); - assert_eq!([domain.len()], &bytes[dst..dst_len]); - - assert_eq!(dst_len, bytes.len()); - } - - struct TestVector { - msg: &'static [u8], - msg_prime: &'static [u8], - uniform_bytes: &'static [u8], - } - - impl TestVector { - #[allow(clippy::panic_in_result_fn)] - fn assert( - &self, - dst: &'static [u8], - domain: &Domain<'_, HashT::OutputSize>, - ) -> Result<()> - where - HashT: BlockSizeUser + Default + FixedOutput + HashMarker, - HashT::OutputSize: IsLessOrEqual, - HashT::OutputSize: IsGreaterOrEqual, - L: ArraySize + IsLess, - { - assert_message::(self.msg, domain, L::U16, self.msg_prime); - - let dst = [dst]; - let mut expander = as ExpandMsg>::expand_message( - &[self.msg], - &dst, - NonZero::new(L::U16).ok_or(Error)?, - )?; - - let mut uniform_bytes = Array::::default(); - expander.fill_bytes(&mut uniform_bytes); - - assert_eq!(uniform_bytes.as_slice(), self.uniform_bytes); - Ok(()) - } - } - - #[test] - fn expand_message_xmd_sha_256() -> Result<()> { - const DST: &[u8] = b"QUUX-V01-CS02-with-expander-SHA256-128"; - const DST_PRIME: &[u8] = - &hex!("515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826"); - - let dst_prime = Domain::xmd::(&[DST])?; - dst_prime.assert_dst(DST_PRIME); - - const TEST_VECTORS_32: &[TestVector] = &[ - TestVector { - msg: b"", - msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826"), - uniform_bytes: &hex!("68a985b87eb6b46952128911f2a4412bbc302a9d759667f87f7a21d803f07235"), - }, - TestVector { - msg: b"abc", - msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000616263002000515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826"), - uniform_bytes: &hex!("d8ccab23b5985ccea865c6c97b6e5b8350e794e603b4b97902f53a8a0d605615"), - }, - TestVector { - msg: b"abcdef0123456789", - msg_prime: &hex!("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000061626364656630313233343536373839002000515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826"), - uniform_bytes: &hex!("eff31487c770a893cfb36f912fbfcbff40d5661771ca4b2cb4eafe524333f5c1"), - }, - TestVector { - msg: b"q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", - msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000713132385f7171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171002000515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826"), - uniform_bytes: &hex!("b23a1d2b4d97b2ef7785562a7e8bac7eed54ed6e97e29aa51bfe3f12ddad1ff9"), - }, - TestVector { - msg: b"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000613531325f6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161002000515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826"), - uniform_bytes: &hex!("4623227bcc01293b8c130bf771da8c298dede7383243dc0993d2d94823958c4c"), - }, - ]; - - for test_vector in TEST_VECTORS_32 { - test_vector.assert::(DST, &dst_prime)?; - } - - const TEST_VECTORS_128: &[TestVector] = &[ - TestVector { - msg: b"", - msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826"), - uniform_bytes: &hex!("af84c27ccfd45d41914fdff5df25293e221afc53d8ad2ac06d5e3e29485dadbee0d121587713a3e0dd4d5e69e93eb7cd4f5df4cd103e188cf60cb02edc3edf18eda8576c412b18ffb658e3dd6ec849469b979d444cf7b26911a08e63cf31f9dcc541708d3491184472c2c29bb749d4286b004ceb5ee6b9a7fa5b646c993f0ced"), - }, TestVector { - msg: b"abc", - msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000616263008000515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826"), - uniform_bytes: &hex!("abba86a6129e366fc877aab32fc4ffc70120d8996c88aee2fe4b32d6c7b6437a647e6c3163d40b76a73cf6a5674ef1d890f95b664ee0afa5359a5c4e07985635bbecbac65d747d3d2da7ec2b8221b17b0ca9dc8a1ac1c07ea6a1e60583e2cb00058e77b7b72a298425cd1b941ad4ec65e8afc50303a22c0f99b0509b4c895f40"), - }, TestVector { - msg: b"abcdef0123456789", - msg_prime: &hex!("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000061626364656630313233343536373839008000515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826"), - uniform_bytes: &hex!("ef904a29bffc4cf9ee82832451c946ac3c8f8058ae97d8d629831a74c6572bd9ebd0df635cd1f208e2038e760c4994984ce73f0d55ea9f22af83ba4734569d4bc95e18350f740c07eef653cbb9f87910d833751825f0ebefa1abe5420bb52be14cf489b37fe1a72f7de2d10be453b2c9d9eb20c7e3f6edc5a60629178d9478df"), - }, TestVector { - msg: b"q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", - msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000713132385f7171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171008000515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826"), - uniform_bytes: &hex!("80be107d0884f0d881bb460322f0443d38bd222db8bd0b0a5312a6fedb49c1bbd88fd75d8b9a09486c60123dfa1d73c1cc3169761b17476d3c6b7cbbd727acd0e2c942f4dd96ae3da5de368d26b32286e32de7e5a8cb2949f866a0b80c58116b29fa7fabb3ea7d520ee603e0c25bcaf0b9a5e92ec6a1fe4e0391d1cdbce8c68a"), - }, TestVector { - msg: b"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000613531325f6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161008000515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826"), - uniform_bytes: &hex!("546aff5444b5b79aa6148bd81728704c32decb73a3ba76e9e75885cad9def1d06d6792f8a7d12794e90efed817d96920d728896a4510864370c207f99bd4a608ea121700ef01ed879745ee3e4ceef777eda6d9e5e38b90c86ea6fb0b36504ba4a45d22e86f6db5dd43d98a294bebb9125d5b794e9d2a81181066eb954966a487"), - }, - ]; - - for test_vector in TEST_VECTORS_128 { - test_vector.assert::(DST, &dst_prime)?; - } - - Ok(()) - } - - #[test] - fn expand_message_xmd_sha_256_long() -> Result<()> { - const DST: &[u8] = b"QUUX-V01-CS02-with-expander-SHA256-128-long-DST-1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"; - const DST_PRIME: &[u8] = - &hex!("412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620"); - - let dst_prime = Domain::xmd::(&[DST])?; - dst_prime.assert_dst(DST_PRIME); - - const TEST_VECTORS_32: &[TestVector] = &[ - TestVector { - msg: b"", - msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620"), - uniform_bytes: &hex!("e8dc0c8b686b7ef2074086fbdd2f30e3f8bfbd3bdf177f73f04b97ce618a3ed3"), - }, - TestVector { - msg: b"abc", - msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000616263002000412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620"), - uniform_bytes: &hex!("52dbf4f36cf560fca57dedec2ad924ee9c266341d8f3d6afe5171733b16bbb12"), - }, - TestVector { - msg: b"abcdef0123456789", - msg_prime: &hex!("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000061626364656630313233343536373839002000412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620"), - uniform_bytes: &hex!("35387dcf22618f3728e6c686490f8b431f76550b0b2c61cbc1ce7001536f4521"), - }, - TestVector { - msg: b"q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", - msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000713132385f7171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171002000412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620"), - uniform_bytes: &hex!("01b637612bb18e840028be900a833a74414140dde0c4754c198532c3a0ba42bc"), - }, - TestVector { - msg: b"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000613531325f6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161002000412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620"), - uniform_bytes: &hex!("20cce7033cabc5460743180be6fa8aac5a103f56d481cf369a8accc0c374431b"), - }, - ]; - - for test_vector in TEST_VECTORS_32 { - test_vector.assert::(DST, &dst_prime)?; - } - - const TEST_VECTORS_128: &[TestVector] = &[ - TestVector { - msg: b"", - msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620"), - uniform_bytes: &hex!("14604d85432c68b757e485c8894db3117992fc57e0e136f71ad987f789a0abc287c47876978e2388a02af86b1e8d1342e5ce4f7aaa07a87321e691f6fba7e0072eecc1218aebb89fb14a0662322d5edbd873f0eb35260145cd4e64f748c5dfe60567e126604bcab1a3ee2dc0778102ae8a5cfd1429ebc0fa6bf1a53c36f55dfc"), - }, - TestVector { - msg: b"abc", - msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000616263008000412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620"), - uniform_bytes: &hex!("1a30a5e36fbdb87077552b9d18b9f0aee16e80181d5b951d0471d55b66684914aef87dbb3626eaabf5ded8cd0686567e503853e5c84c259ba0efc37f71c839da2129fe81afdaec7fbdc0ccd4c794727a17c0d20ff0ea55e1389d6982d1241cb8d165762dbc39fb0cee4474d2cbbd468a835ae5b2f20e4f959f56ab24cd6fe267"), - }, - TestVector { - msg: b"abcdef0123456789", - msg_prime: &hex!("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000061626364656630313233343536373839008000412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620"), - uniform_bytes: &hex!("d2ecef3635d2397f34a9f86438d772db19ffe9924e28a1caf6f1c8f15603d4028f40891044e5c7e39ebb9b31339979ff33a4249206f67d4a1e7c765410bcd249ad78d407e303675918f20f26ce6d7027ed3774512ef5b00d816e51bfcc96c3539601fa48ef1c07e494bdc37054ba96ecb9dbd666417e3de289d4f424f502a982"), - }, - TestVector { - msg: b"q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", - msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000713132385f7171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171008000412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620"), - uniform_bytes: &hex!("ed6e8c036df90111410431431a232d41a32c86e296c05d426e5f44e75b9a50d335b2412bc6c91e0a6dc131de09c43110d9180d0a70f0d6289cb4e43b05f7ee5e9b3f42a1fad0f31bac6a625b3b5c50e3a83316783b649e5ecc9d3b1d9471cb5024b7ccf40d41d1751a04ca0356548bc6e703fca02ab521b505e8e45600508d32"), - }, - TestVector { - msg: b"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000613531325f6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161008000412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620"), - uniform_bytes: &hex!("78b53f2413f3c688f07732c10e5ced29a17c6a16f717179ffbe38d92d6c9ec296502eb9889af83a1928cd162e845b0d3c5424e83280fed3d10cffb2f8431f14e7a23f4c68819d40617589e4c41169d0b56e0e3535be1fd71fbb08bb70c5b5ffed953d6c14bf7618b35fc1f4c4b30538236b4b08c9fbf90462447a8ada60be495"), - }, - ]; - - for test_vector in TEST_VECTORS_128 { - test_vector.assert::(DST, &dst_prime)?; - } - - Ok(()) - } - - #[test] - fn expand_message_xmd_sha_512() -> Result<()> { - use sha2::Sha512; - - const DST: &[u8] = b"QUUX-V01-CS02-with-expander-SHA512-256"; - const DST_PRIME: &[u8] = - &hex!("515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626"); - - let dst_prime = Domain::xmd::(&[DST])?; - dst_prime.assert_dst(DST_PRIME); - - const TEST_VECTORS_32: &[TestVector] = &[ - TestVector { - msg: b"", - msg_prime: &hex!("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626"), - uniform_bytes: &hex!("6b9a7312411d92f921c6f68ca0b6380730a1a4d982c507211a90964c394179ba"), - }, - TestVector { - msg: b"abc", - msg_prime: &hex!("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000616263002000515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626"), - uniform_bytes: &hex!("0da749f12fbe5483eb066a5f595055679b976e93abe9be6f0f6318bce7aca8dc"), - }, - TestVector { - msg: b"abcdef0123456789", - msg_prime: &hex!("000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000061626364656630313233343536373839002000515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626"), - uniform_bytes: &hex!("087e45a86e2939ee8b91100af1583c4938e0f5fc6c9db4b107b83346bc967f58"), - }, - TestVector { - msg: b"q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", - msg_prime: &hex!("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000713132385f7171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171002000515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626"), - uniform_bytes: &hex!("7336234ee9983902440f6bc35b348352013becd88938d2afec44311caf8356b3"), - }, - TestVector { - msg: b"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - msg_prime: &hex!("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000613531325f6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161002000515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626"), - uniform_bytes: &hex!("57b5f7e766d5be68a6bfe1768e3c2b7f1228b3e4b3134956dd73a59b954c66f4"), - }, - ]; - - for test_vector in TEST_VECTORS_32 { - test_vector.assert::(DST, &dst_prime)?; - } - - const TEST_VECTORS_128: &[TestVector] = &[ - TestVector { - msg: b"", - msg_prime: &hex!("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626"), - uniform_bytes: &hex!("41b037d1734a5f8df225dd8c7de38f851efdb45c372887be655212d07251b921b052b62eaed99b46f72f2ef4cc96bfaf254ebbbec091e1a3b9e4fb5e5b619d2e0c5414800a1d882b62bb5cd1778f098b8eb6cb399d5d9d18f5d5842cf5d13d7eb00a7cff859b605da678b318bd0e65ebff70bec88c753b159a805d2c89c55961"), - }, - TestVector { - msg: b"abc", - msg_prime: &hex!("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000616263008000515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626"), - uniform_bytes: &hex!("7f1dddd13c08b543f2e2037b14cefb255b44c83cc397c1786d975653e36a6b11bdd7732d8b38adb4a0edc26a0cef4bb45217135456e58fbca1703cd6032cb1347ee720b87972d63fbf232587043ed2901bce7f22610c0419751c065922b488431851041310ad659e4b23520e1772ab29dcdeb2002222a363f0c2b1c972b3efe1"), - }, - TestVector { - msg: b"abcdef0123456789", - msg_prime: &hex!("000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000061626364656630313233343536373839008000515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626"), - uniform_bytes: &hex!("3f721f208e6199fe903545abc26c837ce59ac6fa45733f1baaf0222f8b7acb0424814fcb5eecf6c1d38f06e9d0a6ccfbf85ae612ab8735dfdf9ce84c372a77c8f9e1c1e952c3a61b7567dd0693016af51d2745822663d0c2367e3f4f0bed827feecc2aaf98c949b5ed0d35c3f1023d64ad1407924288d366ea159f46287e61ac"), - }, - TestVector { - msg: b"q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", - msg_prime: &hex!("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000713132385f7171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171008000515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626"), - uniform_bytes: &hex!("b799b045a58c8d2b4334cf54b78260b45eec544f9f2fb5bd12fb603eaee70db7317bf807c406e26373922b7b8920fa29142703dd52bdf280084fb7ef69da78afdf80b3586395b433dc66cde048a258e476a561e9deba7060af40adf30c64249ca7ddea79806ee5beb9a1422949471d267b21bc88e688e4014087a0b592b695ed"), - }, - TestVector { - msg: b"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - msg_prime: &hex!("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000613531325f6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161008000515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626"), - uniform_bytes: &hex!("05b0bfef265dcee87654372777b7c44177e2ae4c13a27f103340d9cd11c86cb2426ffcad5bd964080c2aee97f03be1ca18e30a1f14e27bc11ebbd650f305269cc9fb1db08bf90bfc79b42a952b46daf810359e7bc36452684784a64952c343c52e5124cd1f71d474d5197fefc571a92929c9084ffe1112cf5eea5192ebff330b"), - }, - ]; - - for test_vector in TEST_VECTORS_128 { - test_vector.assert::(DST, &dst_prime)?; - } - - Ok(()) - } -} diff --git a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs deleted file mode 100644 index 43facde53..000000000 --- a/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs +++ /dev/null @@ -1,376 +0,0 @@ -//! `expand_message_xof` for the `ExpandMsg` trait - -use super::{Domain, ExpandMsg, Expander}; -use crate::Result; -use core::{fmt, num::NonZero, ops::Mul}; -use digest::{ - CollisionResistance, ExtendableOutput, HashMarker, Update, XofReader, typenum::IsGreaterOrEqual, -}; -use hybrid_array::{ - ArraySize, - typenum::{Prod, True, U2}, -}; - -/// Implements `expand_message_xof` via the [`ExpandMsg`] trait: -/// -/// -/// # Errors -/// - `dst` contains no bytes -/// - `dst > 255 && K * 2 > 255` -pub struct ExpandMsgXof -where - HashT: Default + ExtendableOutput + Update + HashMarker, -{ - reader: ::Reader, -} - -impl fmt::Debug for ExpandMsgXof -where - HashT: Default + ExtendableOutput + Update + HashMarker, - ::Reader: fmt::Debug, -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("ExpandMsgXof") - .field("reader", &self.reader) - .finish() - } -} - -impl ExpandMsg for ExpandMsgXof -where - HashT: Default + ExtendableOutput + Update + HashMarker, - // If DST is larger than 255 bytes, the length of the computed DST is calculated by `K * 2`. - // https://www.rfc-editor.org/rfc/rfc9380.html#section-5.3.1-2.1 - K: Mul, - // The collision resistance of `HashT` MUST be at least `K` bits. - // https://www.rfc-editor.org/rfc/rfc9380.html#section-5.3.2-2.1 - HashT: CollisionResistance>, -{ - type Expander<'dst> = Self; - - fn expand_message<'dst>( - msg: &[&[u8]], - dst: &'dst [&[u8]], - len_in_bytes: NonZero, - ) -> Result> { - let len_in_bytes = len_in_bytes.get(); - - let domain = Domain::>::xof::(dst)?; - let mut reader = HashT::default(); - - for msg in msg { - reader = reader.chain(msg); - } - - reader.update(&len_in_bytes.to_be_bytes()); - domain.update_hash(&mut reader); - reader.update(&[domain.len()]); - let reader = reader.finalize_xof(); - Ok(Self { reader }) - } -} - -impl Expander for ExpandMsgXof -where - HashT: Default + ExtendableOutput + Update + HashMarker, -{ - fn fill_bytes(&mut self, okm: &mut [u8]) { - self.reader.read(okm); - } -} - -#[cfg(test)] -mod test { - use crate::Error; - - use super::*; - use core::mem::size_of; - use hex_literal::hex; - use hybrid_array::{ - Array, ArraySize, - typenum::{IsLess, U16, U32, U128, U65536}, - }; - use sha3::Shake128; - - fn assert_message(msg: &[u8], domain: &Domain<'_, U32>, len_in_bytes: u16, bytes: &[u8]) { - let msg_len = msg.len(); - assert_eq!(msg, &bytes[..msg_len]); - - let len_in_bytes_len = msg_len + size_of::(); - assert_eq!( - len_in_bytes.to_be_bytes(), - &bytes[msg_len..len_in_bytes_len] - ); - - let dst = len_in_bytes_len + usize::from(domain.len()); - domain.assert(&bytes[len_in_bytes_len..dst]); - - let dst_len = dst + size_of::(); - assert_eq!([domain.len()], &bytes[dst..dst_len]); - - assert_eq!(dst_len, bytes.len()); - } - - struct TestVector { - msg: &'static [u8], - msg_prime: &'static [u8], - uniform_bytes: &'static [u8], - } - - impl TestVector { - #[allow(clippy::panic_in_result_fn)] - fn assert(&self, dst: &'static [u8], domain: &Domain<'_, U32>) -> Result<()> - where - HashT: Default - + ExtendableOutput - + Update - + HashMarker - + CollisionResistance>, - L: ArraySize + IsLess, - { - assert_message(self.msg, domain, L::to_u16(), self.msg_prime); - - let mut expander = as ExpandMsg>::expand_message( - &[self.msg], - &[dst], - NonZero::new(L::U16).ok_or(Error)?, - )?; - - let mut uniform_bytes = Array::::default(); - expander.fill_bytes(&mut uniform_bytes); - - assert_eq!(uniform_bytes.as_slice(), self.uniform_bytes); - Ok(()) - } - } - - #[test] - fn expand_message_xof_shake_128() -> Result<()> { - const DST: &[u8] = b"QUUX-V01-CS02-with-expander-SHAKE128"; - const DST_PRIME: &[u8] = - &hex!("515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824"); - - let dst_prime = Domain::::xof::(&[DST])?; - dst_prime.assert_dst(DST_PRIME); - - const TEST_VECTORS_32: &[TestVector] = &[ - TestVector { - msg: b"", - msg_prime: &hex!("0020515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824"), - uniform_bytes: &hex!("86518c9cd86581486e9485aa74ab35ba150d1c75c88e26b7043e44e2acd735a2"), - }, - TestVector { - msg: b"abc", - msg_prime: &hex!("6162630020515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824"), - uniform_bytes: &hex!("8696af52a4d862417c0763556073f47bc9b9ba43c99b505305cb1ec04a9ab468"), - }, - TestVector { - msg: b"abcdef0123456789", - msg_prime: &hex!("616263646566303132333435363738390020515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824"), - uniform_bytes: &hex!("912c58deac4821c3509dbefa094df54b34b8f5d01a191d1d3108a2c89077acca"), - }, - TestVector { - msg: b"q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", - msg_prime: &hex!("713132385f71717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171710020515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824"), - uniform_bytes: &hex!("1adbcc448aef2a0cebc71dac9f756b22e51839d348e031e63b33ebb50faeaf3f"), - }, - TestVector { - msg: b"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - msg_prime: &hex!("613531325f61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161610020515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824"), - uniform_bytes: &hex!("df3447cc5f3e9a77da10f819218ddf31342c310778e0e4ef72bbaecee786a4fe"), - }, - ]; - - for test_vector in TEST_VECTORS_32 { - test_vector.assert::(DST, &dst_prime)?; - } - - const TEST_VECTORS_128: &[TestVector] = &[ - TestVector { - msg: b"", - msg_prime: &hex!("0080515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824"), - uniform_bytes: &hex!("7314ff1a155a2fb99a0171dc71b89ab6e3b2b7d59e38e64419b8b6294d03ffee42491f11370261f436220ef787f8f76f5b26bdcd850071920ce023f3ac46847744f4612b8714db8f5db83205b2e625d95afd7d7b4d3094d3bdde815f52850bb41ead9822e08f22cf41d615a303b0d9dde73263c049a7b9898208003a739a2e57"), - }, - TestVector { - msg: b"abc", - msg_prime: &hex!("6162630080515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824"), - uniform_bytes: &hex!("c952f0c8e529ca8824acc6a4cab0e782fc3648c563ddb00da7399f2ae35654f4860ec671db2356ba7baa55a34a9d7f79197b60ddae6e64768a37d699a78323496db3878c8d64d909d0f8a7de4927dcab0d3dbbc26cb20a49eceb0530b431cdf47bc8c0fa3e0d88f53b318b6739fbed7d7634974f1b5c386d6230c76260d5337a"), - }, - TestVector { - msg: b"abcdef0123456789", - msg_prime: &hex!("616263646566303132333435363738390080515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824"), - uniform_bytes: &hex!("19b65ee7afec6ac06a144f2d6134f08eeec185f1a890fe34e68f0e377b7d0312883c048d9b8a1d6ecc3b541cb4987c26f45e0c82691ea299b5e6889bbfe589153016d8131717ba26f07c3c14ffbef1f3eff9752e5b6183f43871a78219a75e7000fbac6a7072e2b83c790a3a5aecd9d14be79f9fd4fb180960a3772e08680495"), - }, - TestVector { - msg: b"q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", - msg_prime: &hex!("713132385f71717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171710080515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824"), - uniform_bytes: &hex!("ca1b56861482b16eae0f4a26212112362fcc2d76dcc80c93c4182ed66c5113fe41733ed68be2942a3487394317f3379856f4822a611735e50528a60e7ade8ec8c71670fec6661e2c59a09ed36386513221688b35dc47e3c3111ee8c67ff49579089d661caa29db1ef10eb6eace575bf3dc9806e7c4016bd50f3c0e2a6481ee6d"), - }, - TestVector { - msg: b"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - msg_prime: &hex!("613531325f61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161610080515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824"), - uniform_bytes: &hex!("9d763a5ce58f65c91531b4100c7266d479a5d9777ba761693d052acd37d149e7ac91c796a10b919cd74a591a1e38719fb91b7203e2af31eac3bff7ead2c195af7d88b8bc0a8adf3d1e90ab9bed6ddc2b7f655dd86c730bdeaea884e73741097142c92f0e3fc1811b699ba593c7fbd81da288a29d423df831652e3a01a9374999"), - }, - ]; - - for test_vector in TEST_VECTORS_128 { - test_vector.assert::(DST, &dst_prime)?; - } - - Ok(()) - } - - #[test] - fn expand_message_xof_shake_128_long() -> Result<()> { - const DST: &[u8] = b"QUUX-V01-CS02-with-expander-SHAKE128-long-DST-111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"; - const DST_PRIME: &[u8] = - &hex!("acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20"); - - let dst_prime = Domain::::xof::(&[DST])?; - dst_prime.assert_dst(DST_PRIME); - - const TEST_VECTORS_32: &[TestVector] = &[ - TestVector { - msg: b"", - msg_prime: &hex!("0020acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20"), - uniform_bytes: &hex!("827c6216330a122352312bccc0c8d6e7a146c5257a776dbd9ad9d75cd880fc53"), - }, - TestVector { - msg: b"abc", - msg_prime: &hex!("6162630020acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20"), - uniform_bytes: &hex!("690c8d82c7213b4282c6cb41c00e31ea1d3e2005f93ad19bbf6da40f15790c5c"), - }, - TestVector { - msg: b"abcdef0123456789", - msg_prime: &hex!("616263646566303132333435363738390020acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20"), - uniform_bytes: &hex!("979e3a15064afbbcf99f62cc09fa9c85028afcf3f825eb0711894dcfc2f57057"), - }, - TestVector { - msg: b"q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", - msg_prime: &hex!("713132385f71717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171710020acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20"), - uniform_bytes: &hex!("c5a9220962d9edc212c063f4f65b609755a1ed96e62f9db5d1fd6adb5a8dc52b"), - }, - TestVector { - msg: b"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - msg_prime: &hex!("613531325f61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161610020acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20"), - uniform_bytes: &hex!("f7b96a5901af5d78ce1d071d9c383cac66a1dfadb508300ec6aeaea0d62d5d62"), - }, - ]; - - for test_vector in TEST_VECTORS_32 { - test_vector.assert::(DST, &dst_prime)?; - } - - const TEST_VECTORS_128: &[TestVector] = &[ - TestVector { - msg: b"", - msg_prime: &hex!("0080acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20"), - uniform_bytes: &hex!("3890dbab00a2830be398524b71c2713bbef5f4884ac2e6f070b092effdb19208c7df943dc5dcbaee3094a78c267ef276632ee2c8ea0c05363c94b6348500fae4208345dd3475fe0c834c2beac7fa7bc181692fb728c0a53d809fc8111495222ce0f38468b11becb15b32060218e285c57a60162c2c8bb5b6bded13973cd41819"), - }, - TestVector { - msg: b"abc", - msg_prime: &hex!("6162630080acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20"), - uniform_bytes: &hex!("41b7ffa7a301b5c1441495ebb9774e2a53dbbf4e54b9a1af6a20fd41eafd69ef7b9418599c5545b1ee422f363642b01d4a53449313f68da3e49dddb9cd25b97465170537d45dcbdf92391b5bdff344db4bd06311a05bca7dcd360b6caec849c299133e5c9194f4e15e3e23cfaab4003fab776f6ac0bfae9144c6e2e1c62e7d57"), - }, - TestVector { - msg: b"abcdef0123456789", - msg_prime: &hex!("616263646566303132333435363738390080acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20"), - uniform_bytes: &hex!("55317e4a21318472cd2290c3082957e1242241d9e0d04f47026f03401643131401071f01aa03038b2783e795bdfa8a3541c194ad5de7cb9c225133e24af6c86e748deb52e560569bd54ef4dac03465111a3a44b0ea490fb36777ff8ea9f1a8a3e8e0de3cf0880b4b2f8dd37d3a85a8b82375aee4fa0e909f9763319b55778e71"), - }, - TestVector { - msg: b"q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", - msg_prime: &hex!("713132385f71717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171710080acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20"), - uniform_bytes: &hex!("19fdd2639f082e31c77717ac9bb032a22ff0958382b2dbb39020cdc78f0da43305414806abf9a561cb2d0067eb2f7bc544482f75623438ed4b4e39dd9e6e2909dd858bd8f1d57cd0fce2d3150d90aa67b4498bdf2df98c0100dd1a173436ba5d0df6be1defb0b2ce55ccd2f4fc05eb7cb2c019c35d5398b85adc676da4238bc7"), - }, - TestVector { - msg: b"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - msg_prime: &hex!("613531325f61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161610080acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20"), - uniform_bytes: &hex!("945373f0b3431a103333ba6a0a34f1efab2702efde41754c4cb1d5216d5b0a92a67458d968562bde7fa6310a83f53dda1383680a276a283438d58ceebfa7ab7ba72499d4a3eddc860595f63c93b1c5e823ea41fc490d938398a26db28f61857698553e93f0574eb8c5017bfed6249491f9976aaa8d23d9485339cc85ca329308"), - }, - ]; - - for test_vector in TEST_VECTORS_128 { - test_vector.assert::(DST, &dst_prime)?; - } - - Ok(()) - } - - #[test] - fn expand_message_xof_shake_256() -> Result<()> { - use sha3::Shake256; - - const DST: &[u8] = b"QUUX-V01-CS02-with-expander-SHAKE256"; - const DST_PRIME: &[u8] = - &hex!("515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624"); - - let dst_prime = Domain::::xof::(&[DST])?; - dst_prime.assert_dst(DST_PRIME); - - const TEST_VECTORS_32: &[TestVector] = &[ - TestVector { - msg: b"", - msg_prime: &hex!("0020515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624"), - uniform_bytes: &hex!("2ffc05c48ed32b95d72e807f6eab9f7530dd1c2f013914c8fed38c5ccc15ad76"), - }, - TestVector { - msg: b"abc", - msg_prime: &hex!("6162630020515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624"), - uniform_bytes: &hex!("b39e493867e2767216792abce1f2676c197c0692aed061560ead251821808e07"), - }, - TestVector { - msg: b"abcdef0123456789", - msg_prime: &hex!("616263646566303132333435363738390020515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624"), - uniform_bytes: &hex!("245389cf44a13f0e70af8665fe5337ec2dcd138890bb7901c4ad9cfceb054b65"), - }, - TestVector { - msg: b"q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", - msg_prime: &hex!("713132385f71717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171710020515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624"), - uniform_bytes: &hex!("719b3911821e6428a5ed9b8e600f2866bcf23c8f0515e52d6c6c019a03f16f0e"), - }, - TestVector { - msg: b"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - msg_prime: &hex!("613531325f61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161610020515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624"), - uniform_bytes: &hex!("9181ead5220b1963f1b5951f35547a5ea86a820562287d6ca4723633d17ccbbc"), - }, - ]; - - for test_vector in TEST_VECTORS_32 { - test_vector.assert::(DST, &dst_prime)?; - } - - const TEST_VECTORS_128: &[TestVector] = &[ - TestVector { - msg: b"", - msg_prime: &hex!("0080515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624"), - uniform_bytes: &hex!("7a1361d2d7d82d79e035b8880c5a3c86c5afa719478c007d96e6c88737a3f631dd74a2c88df79a4cb5e5d9f7504957c70d669ec6bfedc31e01e2bacc4ff3fdf9b6a00b17cc18d9d72ace7d6b81c2e481b4f73f34f9a7505dccbe8f5485f3d20c5409b0310093d5d6492dea4e18aa6979c23c8ea5de01582e9689612afbb353df"), - }, - TestVector { - msg: b"abc", - msg_prime: &hex!("6162630080515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624"), - uniform_bytes: &hex!("a54303e6b172909783353ab05ef08dd435a558c3197db0c132134649708e0b9b4e34fb99b92a9e9e28fc1f1d8860d85897a8e021e6382f3eea10577f968ff6df6c45fe624ce65ca25932f679a42a404bc3681efe03fcd45ef73bb3a8f79ba784f80f55ea8a3c367408f30381299617f50c8cf8fbb21d0f1e1d70b0131a7b6fbe"), - }, - TestVector { - msg: b"abcdef0123456789", - msg_prime: &hex!("616263646566303132333435363738390080515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624"), - uniform_bytes: &hex!("e42e4d9538a189316e3154b821c1bafb390f78b2f010ea404e6ac063deb8c0852fcd412e098e231e43427bd2be1330bb47b4039ad57b30ae1fc94e34993b162ff4d695e42d59d9777ea18d3848d9d336c25d2acb93adcad009bcfb9cde12286df267ada283063de0bb1505565b2eb6c90e31c48798ecdc71a71756a9110ff373"), - }, - TestVector { - msg: b"q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", - msg_prime: &hex!("713132385f71717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171710080515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624"), - uniform_bytes: &hex!("4ac054dda0a38a65d0ecf7afd3c2812300027c8789655e47aecf1ecc1a2426b17444c7482c99e5907afd9c25b991990490bb9c686f43e79b4471a23a703d4b02f23c669737a886a7ec28bddb92c3a98de63ebf878aa363a501a60055c048bea11840c4717beae7eee28c3cfa42857b3d130188571943a7bd747de831bd6444e0"), - }, - TestVector { - msg: b"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - msg_prime: &hex!("613531325f61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161610080515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624"), - uniform_bytes: &hex!("09afc76d51c2cccbc129c2315df66c2be7295a231203b8ab2dd7f95c2772c68e500bc72e20c602abc9964663b7a03a389be128c56971ce81001a0b875e7fd17822db9d69792ddf6a23a151bf470079c518279aef3e75611f8f828994a9988f4a8a256ddb8bae161e658d5a2a09bcfe839c6396dc06ee5c8ff3c22d3b1f9deb7e"), - }, - ]; - - for test_vector in TEST_VECTORS_128 { - test_vector.assert::(DST, &dst_prime)?; - } - - Ok(()) - } -} diff --git a/elliptic-curve/src/hash2curve/isogeny.rs b/elliptic-curve/src/hash2curve/isogeny.rs deleted file mode 100644 index 5b11900d9..000000000 --- a/elliptic-curve/src/hash2curve/isogeny.rs +++ /dev/null @@ -1,58 +0,0 @@ -//! Traits for mapping an isogeny to another curve -//! -//! - -use core::ops::{AddAssign, Mul}; -use ff::Field; -use hybrid_array::{Array, ArraySize, typenum::Unsigned}; - -/// The coefficients for mapping from one isogenous curve to another -#[derive(Debug)] -pub struct IsogenyCoefficients> { - /// The coefficients for the x numerator - pub xnum: &'static [F], - /// The coefficients for the x denominator - pub xden: &'static [F], - /// The coefficients for the y numerator - pub ynum: &'static [F], - /// The coefficients for the x denominator - pub yden: &'static [F], -} - -/// The [`Isogeny`] methods to map to another curve. -pub trait Isogeny: Field + AddAssign + Mul { - /// The maximum number of coefficients - type Degree: ArraySize; - /// The isogeny coefficients - const COEFFICIENTS: IsogenyCoefficients; - - /// Map from the isogeny points to the main curve - fn isogeny(x: Self, y: Self) -> (Self, Self) { - let mut xs = Array::::default(); - xs[0] = Self::ONE; - xs[1] = x; - xs[2] = x.square(); - for i in 3..Self::Degree::to_usize() { - xs[i] = xs[i - 1] * x; - } - let x_num = Self::compute_iso(&xs, Self::COEFFICIENTS.xnum); - let x_den = Self::compute_iso(&xs, Self::COEFFICIENTS.xden) - .invert() - .unwrap(); - let y_num = Self::compute_iso(&xs, Self::COEFFICIENTS.ynum) * y; - let y_den = Self::compute_iso(&xs, Self::COEFFICIENTS.yden) - .invert() - .unwrap(); - - (x_num * x_den, y_num * y_den) - } - - /// Compute the ISO transform - fn compute_iso(xxs: &[Self], k: &[Self]) -> Self { - let mut xx = Self::ZERO; - for (xi, ki) in xxs.iter().zip(k.iter()) { - xx += *xi * ki; - } - xx - } -} diff --git a/elliptic-curve/src/hash2curve/map2curve.rs b/elliptic-curve/src/hash2curve/map2curve.rs deleted file mode 100644 index 7ab69a2af..000000000 --- a/elliptic-curve/src/hash2curve/map2curve.rs +++ /dev/null @@ -1,33 +0,0 @@ -//! Traits for mapping field elements to points on the curve. - -use crate::{CurveArithmetic, ProjectivePoint}; - -use super::FromOkm; - -/// Trait for converting field elements into a point via a mapping method like -/// Simplified Shallue-van de Woestijne-Ulas or Elligator. -pub trait MapToCurve: CurveArithmetic { - /// The intermediate representation, an element of the curve which may or may not - /// be in the curve subgroup. - type CurvePoint; - /// The field element representation for a group value with multiple elements. - type FieldElement: FromOkm + Default + Copy; - - /// Map a field element into a curve point. - fn map_to_curve(element: Self::FieldElement) -> Self::CurvePoint; - - /// Map a curve point to a point in the curve subgroup. - /// This is usually done by clearing the cofactor, if necessary. - fn map_to_subgroup(point: Self::CurvePoint) -> ProjectivePoint; - - /// Combine two curve points into a point in the curve subgroup. - /// This is usually done by clearing the cofactor of the sum. In case - /// addition is not implemented for `Self::CurvePoint`, then both terms - /// must be mapped to the subgroup individually before being added. - fn add_and_map_to_subgroup( - lhs: Self::CurvePoint, - rhs: Self::CurvePoint, - ) -> ProjectivePoint { - Self::map_to_subgroup(lhs) + Self::map_to_subgroup(rhs) - } -} diff --git a/elliptic-curve/src/hash2curve/osswu.rs b/elliptic-curve/src/hash2curve/osswu.rs deleted file mode 100644 index ea8acdc5b..000000000 --- a/elliptic-curve/src/hash2curve/osswu.rs +++ /dev/null @@ -1,131 +0,0 @@ -//! Optimized simplified Shallue-van de Woestijne-Ulas methods. -//! -//! - -use ff::Field; -use subtle::Choice; -use subtle::ConditionallySelectable; -use subtle::ConstantTimeEq; - -/// The Optimized Simplified Shallue-van de Woestijne-Ulas parameters -#[derive(Debug)] -pub struct OsswuMapParams -where - F: Field, -{ - /// The first constant term - pub c1: &'static [u64], - /// The second constant term - pub c2: F, - /// The ISO A variable or Curve A variable - pub map_a: F, - /// The ISO A variable or Curve A variable - pub map_b: F, - /// The Z parameter - pub z: F, -} - -/// Trait for determining the parity of the field -pub trait Sgn0 { - /// Return the parity of the field - /// 1 == negative - /// 0 == non-negative - fn sgn0(&self) -> Choice; -} - -/// The optimized simplified Shallue-van de Woestijne-Ulas method -/// for mapping elliptic curve scalars to affine points. -pub trait OsswuMap: Field + Sgn0 { - /// The OSSWU parameters for mapping the field to affine points. - /// For Weierstrass curves having A==0 or B==0, the parameters - /// should be for isogeny where A≠0 and B≠0. - const PARAMS: OsswuMapParams; - - /// Optimized sqrt_ratio for q = 3 mod 4. - fn sqrt_ratio_3mod4(u: Self, v: Self) -> (Choice, Self) { - // 1. tv1 = v^2 - let tv1 = v.square(); - // 2. tv2 = u * v - let tv2 = u * v; - // 3. tv1 = tv1 * tv2 - let tv1 = tv1 * tv2; - // 4. y1 = tv1^c1 - let y1 = tv1.pow_vartime(Self::PARAMS.c1); - // 5. y1 = y1 * tv2 - let y1 = y1 * tv2; - // 6. y2 = y1 * c2 - let y2 = y1 * Self::PARAMS.c2; - // 7. tv3 = y1^2 - let tv3 = y1.square(); - // 8. tv3 = tv3 * v - let tv3 = tv3 * v; - // 9. isQR = tv3 == u - let is_qr = tv3.ct_eq(&u); - // 10. y = CMOV(y2, y1, isQR) - let y = ConditionallySelectable::conditional_select(&y2, &y1, is_qr); - // 11. return (isQR, y) - (is_qr, y) - } - - /// Convert this field element into an affine point on the elliptic curve - /// returning (X, Y). For Weierstrass curves having A==0 or B==0 - /// the result is a point on an isogeny. - fn osswu(&self) -> (Self, Self) { - // 1. tv1 = u^2 - let tv1 = self.square(); - // 2. tv1 = Z * tv1 - let tv1 = Self::PARAMS.z * tv1; - // 3. tv2 = tv1^2 - let tv2 = tv1.square(); - // 4. tv2 = tv2 + tv1 - let tv2 = tv2 + tv1; - // 5. tv3 = tv2 + 1 - let tv3 = tv2 + Self::ONE; - // 6. tv3 = B * tv3 - let tv3 = Self::PARAMS.map_b * tv3; - // 7. tv4 = CMOV(Z, -tv2, tv2 != 0) - let tv4 = ConditionallySelectable::conditional_select( - &Self::PARAMS.z, - &-tv2, - !Field::is_zero(&tv2), - ); - // 8. tv4 = A * tv4 - let tv4 = Self::PARAMS.map_a * tv4; - // 9. tv2 = tv3^2 - let tv2 = tv3.square(); - // 10. tv6 = tv4^2 - let tv6 = tv4.square(); - // 11. tv5 = A * tv6 - let tv5 = Self::PARAMS.map_a * tv6; - // 12. tv2 = tv2 + tv5 - let tv2 = tv2 + tv5; - // 13. tv2 = tv2 * tv3 - let tv2 = tv2 * tv3; - // 14. tv6 = tv6 * tv4 - let tv6 = tv6 * tv4; - // 15. tv5 = B * tv6 - let tv5 = Self::PARAMS.map_b * tv6; - // 16. tv2 = tv2 + tv5 - let tv2 = tv2 + tv5; - // 17. x = tv1 * tv3 - let x = tv1 * tv3; - // 18. (is_gx1_square, y1) = sqrt_ratio(tv2, tv6) - let (is_gx1_square, y1) = Self::sqrt_ratio_3mod4(tv2, tv6); - // 19. y = tv1 * u - let y = tv1 * self; - // 20. y = y * y1 - let y = y * y1; - // 21. x = CMOV(x, tv3, is_gx1_square) - let x = ConditionallySelectable::conditional_select(&x, &tv3, is_gx1_square); - // 22. y = CMOV(y, y1, is_gx1_square) - let y = ConditionallySelectable::conditional_select(&y, &y1, is_gx1_square); - // 23. e1 = sgn0(u) == sgn0(y) - let e1 = self.sgn0().ct_eq(&y.sgn0()); - // 24. y = CMOV(-y, y, e1) - let y = ConditionallySelectable::conditional_select(&-y, &y, e1); - // 25. x = x / tv4 - let x = x * tv4.invert().unwrap(); - // 26. return (x, y) - (x, y) - } -} diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index ea08dd3b3..bd880be88 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -91,8 +91,6 @@ pub mod scalar; pub mod dev; #[cfg(feature = "ecdh")] pub mod ecdh; -#[cfg(feature = "hash2curve")] -pub mod hash2curve; #[cfg(feature = "arithmetic")] pub mod ops; #[cfg(feature = "sec1")] @@ -113,9 +111,6 @@ mod public_key; #[cfg(feature = "jwk")] mod jwk; -#[cfg(feature = "oprf")] -mod oprf; - pub use crate::{ error::{Error, Result}, field::{FieldBytes, FieldBytesEncoding, FieldBytesSize}, @@ -147,9 +142,6 @@ pub use crate::jwk::{JwkEcKey, JwkParameters}; #[cfg(feature = "pkcs8")] pub use pkcs8; -#[cfg(feature = "oprf")] -pub use crate::oprf::OprfParameters; - use core::{ fmt::Debug, ops::{Add, ShrAssign}, diff --git a/elliptic-curve/src/oprf.rs b/elliptic-curve/src/oprf.rs deleted file mode 100644 index b6806f74f..000000000 --- a/elliptic-curve/src/oprf.rs +++ /dev/null @@ -1,30 +0,0 @@ -//! Oblivious Pseudorandom Functions (OPRF) using prime order groups -//! -//! - -use digest::{FixedOutput, Update}; -use hybrid_array::typenum::{IsLess, True, U65536}; - -use crate::PrimeCurve; -use crate::hash2curve::{ExpandMsg, GroupDigest}; - -/// Elliptic curve parameters used by OPRF. -pub trait OprfParameters: GroupDigest + PrimeCurve { - /// The `ID` parameter which identifies a particular elliptic curve - /// as defined in [section 4 of RFC9497][oprf]. - /// - /// [oprf]: https://www.rfc-editor.org/rfc/rfc9497.html#name-ciphersuites - const ID: &'static [u8]; - - /// The `Hash` parameter which assigns a particular hash function to this - /// ciphersuite as defined in [section 4 of RFC9497][oprf]. - /// - /// [oprf]: https://www.rfc-editor.org/rfc/rfc9497.html#name-ciphersuites - type Hash: Default + FixedOutput> + Update; - - /// The `expand_message` parameter which assigns a particular algorithm for `HashToGroup` - /// and `HashToScalar` as defined in [section 4 of RFC9497][oprf]. - /// - /// [oprf]: https://www.rfc-editor.org/rfc/rfc9497.html#name-ciphersuites - type ExpandMsg: ExpandMsg<::K>; -} From 04402d6408500c6ed7afa941462396ec045cf5b0 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 9 Jul 2025 20:14:24 -0600 Subject: [PATCH 1418/1461] Remove PKCS#8 blanket impls for SEC1 private key traits (#1930) Companion PR to RustCrypto/formats#1927 which properly composes the PKCS#8 impl in terms of the SEC1 impl --- Cargo.lock | 4 +--- Cargo.toml | 2 ++ elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/secret_key.rs | 32 +++++++++++++++++++++++++- elliptic-curve/src/secret_key/pkcs8.rs | 16 ++----------- 5 files changed, 37 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e6ea24012..3f0b97dfe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -478,13 +478,11 @@ checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "sec1" version = "0.8.0-rc.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1231d6ed04c5242799d39a97ca91aeda70ecc27a67870a5fe43149e5c12aed3d" +source = "git+https://github.com/RustCrypto/formats/#17bb02635dba4ab75a51eeffdf5a5de80ffe8ce3" dependencies = [ "base16ct", "der", "hybrid-array", - "pkcs8", "serdect", "subtle", "zeroize", diff --git a/Cargo.toml b/Cargo.toml index f89b4edce..f5f4b80d4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,3 +16,5 @@ members = [ [patch.crates-io] digest = { path = "digest" } signature = { path = "signature" } + +sec1 = { git = "https://github.com/RustCrypto/formats/" } diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index d24885b87..8d4759bc9 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -66,7 +66,7 @@ ecdh = ["arithmetic", "digest", "dep:hkdf"] group = ["dep:group", "ff"] jwk = ["dep:base64ct", "dep:serde_json", "alloc", "serde", "zeroize/alloc"] pkcs8 = ["dep:pkcs8", "sec1"] -pem = ["dep:pem-rfc7468", "alloc", "arithmetic", "pkcs8", "sec1/pem"] +pem = ["dep:pem-rfc7468", "alloc", "arithmetic", "pkcs8/pem", "sec1/pem"] serde = ["dep:serdect", "alloc", "pkcs8", "sec1/serde"] [package.metadata.docs.rs] diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 61b7655e5..9d465612f 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -32,7 +32,7 @@ use { FieldBytesSize, sec1::{EncodedPoint, ModulusSize, ValidatePublicKey}, }, - sec1::der::{self, oid::AssociatedOid}, + sec1::der::{self, Decode, oid::AssociatedOid}, }; #[cfg(all(feature = "alloc", feature = "arithmetic", feature = "sec1"))] @@ -363,6 +363,36 @@ where } } +#[cfg(feature = "sec1")] +impl sec1::DecodeEcPrivateKey for SecretKey +where + C: AssociatedOid + Curve + ValidatePublicKey, + FieldBytesSize: ModulusSize, +{ + fn from_sec1_der(bytes: &[u8]) -> sec1::Result { + Ok(sec1::EcPrivateKey::from_der(bytes)?.try_into()?) + } +} + +#[cfg(all(feature = "alloc", feature = "arithmetic", feature = "sec1"))] +impl sec1::EncodeEcPrivateKey for SecretKey +where + C: AssociatedOid + CurveArithmetic, + AffinePoint: FromEncodedPoint + ToEncodedPoint, + FieldBytesSize: ModulusSize, +{ + fn to_sec1_der(&self) -> sec1::Result { + let private_key_bytes = Zeroizing::new(self.to_bytes()); + let public_key_bytes = self.public_key().to_encoded_point(false); + + Ok(der::SecretDocument::encode_msg(&sec1::EcPrivateKey { + private_key: &private_key_bytes, + parameters: None, + public_key: Some(public_key_bytes.as_bytes()), + })?) + } +} + #[cfg(feature = "sec1")] impl TryFrom> for SecretKey where diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs index 2598f9ec4..e28147e50 100644 --- a/elliptic-curve/src/secret_key/pkcs8.rs +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -18,9 +18,8 @@ use { }, pkcs8::{ EncodePrivateKey, - der::{self, Encode, asn1::OctetStringRef}, + der::{self, asn1::OctetStringRef}, }, - zeroize::Zeroizing, }; // Imports for actual PEM support @@ -72,18 +71,7 @@ where parameters: Some((&C::OID).into()), }; - let private_key_bytes = Zeroizing::new(self.to_bytes()); - let public_key_bytes = self.public_key().to_encoded_point(false); - - // TODO(tarcieri): unify with `to_sec1_der()` by building an owned `EcPrivateKey` - let ec_private_key = Zeroizing::new( - EcPrivateKey { - private_key: &private_key_bytes, - parameters: None, - public_key: Some(public_key_bytes.as_bytes()), - } - .to_der()?, - ); + let ec_private_key = self.to_sec1_der()?; let pkcs8_key = pkcs8::PrivateKeyInfoRef::new( algorithm_identifier, From 4e66a74dbabaa496bdbfe5c33abedb526457591d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 9 Jul 2025 21:46:47 -0600 Subject: [PATCH 1419/1461] elliptic-curve v0.14.0-rc.9 (#1931) --- Cargo.lock | 17 +++++++++-------- Cargo.toml | 2 -- elliptic-curve/Cargo.toml | 6 +++--- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3f0b97dfe..d0a27513c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -172,9 +172,9 @@ dependencies = [ [[package]] name = "der" -version = "0.8.0-rc.6" +version = "0.8.0-rc.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7d571780ddd86c50ecbcf7099a945804a55e39c5d13f27d0225c1acecbae248" +checksum = "e2fe0a4fafae25053c19a03fefe040607bda956b4941d692ed9fb9d3c18a3193" dependencies = [ "const-oid", "pem-rfc7468", @@ -421,9 +421,9 @@ dependencies = [ [[package]] name = "pkcs8" -version = "0.11.0-rc.5" +version = "0.11.0-rc.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef85549ba672d102373a0566b322f6618e009442459effa41d5b32741981014d" +checksum = "c53e5d0804fa4070b1b2a5b320102f2c1c094920a7533d5d87c2630609bcbd34" dependencies = [ "der", "spki", @@ -477,8 +477,9 @@ checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "sec1" -version = "0.8.0-rc.6" -source = "git+https://github.com/RustCrypto/formats/#17bb02635dba4ab75a51eeffdf5a5de80ffe8ce3" +version = "0.8.0-rc.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c54dee398d74b1d03d78ddc09c90e456bf906b5b7aa790ba4f48b025b2179e5d" dependencies = [ "base16ct", "der", @@ -561,9 +562,9 @@ dependencies = [ [[package]] name = "spki" -version = "0.8.0-rc.3" +version = "0.8.0-rc.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b59f16f15f6f84d24525ca54974b59147ec161ef666b44d055a419bc6392582" +checksum = "8baeff88f34ed0691978ec34440140e1572b68c7dd4a495fd14a3dc1944daa80" dependencies = [ "base64ct", "der", diff --git a/Cargo.toml b/Cargo.toml index f5f4b80d4..f89b4edce 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,5 +16,3 @@ members = [ [patch.crates-io] digest = { path = "digest" } signature = { path = "signature" } - -sec1 = { git = "https://github.com/RustCrypto/formats/" } diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 8d4759bc9..4785758cd 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.14.0-rc.8" +version = "0.14.0-rc.9" authors = ["RustCrypto Developers"] edition = "2024" rust-version = "1.85" @@ -32,8 +32,8 @@ group = { version = "=0.14.0-pre.0", optional = true, default-features = false } hkdf = { version = "0.13.0-rc.0", optional = true, default-features = false } hex-literal = { version = "1", optional = true } pem-rfc7468 = { version = "1.0.0-rc.2", optional = true, features = ["alloc"] } -pkcs8 = { version = "0.11.0-rc.5", optional = true, default-features = false } -sec1 = { version = "0.8.0-rc.6", optional = true, features = ["subtle", "zeroize"] } +pkcs8 = { version = "0.11.0-rc.6", optional = true, default-features = false } +sec1 = { version = "0.8.0-rc.8", optional = true, features = ["subtle", "zeroize"] } serdect = { version = "0.3", optional = true, default-features = false, features = ["alloc"] } serde_json = { version = "1.0.121", optional = true, default-features = false, features = ["alloc"] } From 84f7b56dbe2f79c5b9cc0d2ac2b2fe5eefde6080 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 10 Jul 2025 07:31:47 -0600 Subject: [PATCH 1420/1461] elliptic-curve: fix SEC1 serialization (#1933) It wasn't including the curve OID as `EcParameters`. Previously the logic for populating this field lived in the `sec1` crate. Since SEC1 needs a slightly different serialization than PKCS#8 (notably the latter hoists the curve OID onto `AlgorithmParameters` and omits it from the SEC1 `EcPrivateKey` this more or less reverts the PKCS#8 serialization logic to what it was before. --- elliptic-curve/src/secret_key.rs | 2 +- elliptic-curve/src/secret_key/pkcs8.rs | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 9d465612f..1559f62bc 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -387,7 +387,7 @@ where Ok(der::SecretDocument::encode_msg(&sec1::EcPrivateKey { private_key: &private_key_bytes, - parameters: None, + parameters: Some(C::OID.into()), public_key: Some(public_key_bytes.as_bytes()), })?) } diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs index e28147e50..2cdd8c7ae 100644 --- a/elliptic-curve/src/secret_key/pkcs8.rs +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -18,8 +18,9 @@ use { }, pkcs8::{ EncodePrivateKey, - der::{self, asn1::OctetStringRef}, + der::{self, Encode, asn1::OctetStringRef}, }, + zeroize::Zeroizing, }; // Imports for actual PEM support @@ -71,7 +72,17 @@ where parameters: Some((&C::OID).into()), }; - let ec_private_key = self.to_sec1_der()?; + let private_key_bytes = Zeroizing::new(self.to_bytes()); + let public_key_bytes = self.public_key().to_encoded_point(false); + + let ec_private_key = Zeroizing::new( + EcPrivateKey { + private_key: &private_key_bytes, + parameters: None, + public_key: Some(public_key_bytes.as_bytes()), + } + .to_der()?, + ); let pkcs8_key = pkcs8::PrivateKeyInfoRef::new( algorithm_identifier, From 7c6af870c0f688c6ad736ec4bcdc38a05baa2a51 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 10 Jul 2025 07:36:46 -0600 Subject: [PATCH 1421/1461] elliptic-curve v0.14.0-rc.10 (#1934) --- Cargo.lock | 2 +- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d0a27513c..2da921ab0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -195,7 +195,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.14.0-rc.8" +version = "0.14.0-rc.10" dependencies = [ "base16ct", "base64ct", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 4785758cd..76c32ef8d 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.14.0-rc.9" +version = "0.14.0-rc.10" authors = ["RustCrypto Developers"] edition = "2024" rust-version = "1.85" From 100740196b779cdc5c2dfb4dc1a3c939e4101cd0 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 16 Jul 2025 07:37:49 -0600 Subject: [PATCH 1422/1461] signature v3.0.0-rc.2 (#1935) --- Cargo.lock | 2 +- signature/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2da921ab0..508eac0c5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -554,7 +554,7 @@ dependencies = [ [[package]] name = "signature" -version = "3.0.0-rc.1" +version = "3.0.0-rc.2" dependencies = [ "digest", "rand_core", diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 1d29f9ead..4e70a09fd 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "signature" -version = "3.0.0-rc.1" +version = "3.0.0-rc.2" authors = ["RustCrypto Developers"] edition = "2024" rust-version = "1.85" From a10ef181945a480bba5d2fb36ad6f3f78a3474db Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 19 Jul 2025 08:44:26 -0600 Subject: [PATCH 1423/1461] elliptic-curve: bump `crypto-bigint` to v0.7.0-pre.7 (#1937) --- Cargo.lock | 4 ++-- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 508eac0c5..8294b8bbb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -151,9 +151,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.7.0-pre.6" +version = "0.7.0-pre.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98dc20cae677f0af161d98f18463804b680f9af060f6dbe6d4249bd7e838bca1" +checksum = "85ff38607b7ebe30e4715eeb0a0427ff42e3b6b47b2df55a775e767ef2658ccd" dependencies = [ "hybrid-array", "num-traits", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 76c32ef8d..dc2cfef16 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -18,7 +18,7 @@ and public/secret keys composed thereof. [dependencies] base16ct = "0.2" -crypto-bigint = { version = "=0.7.0-pre.6", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } +crypto-bigint = { version = "=0.7.0-pre.7", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } hybrid-array = { version = "0.3", default-features = false, features = ["zeroize"] } rand_core = { version = "0.9.0", default-features = false } subtle = { version = "2.6", default-features = false } From d5355ef8a85577d9842505cf3241f6e1d011d0da Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 21 Jul 2025 08:25:01 -0600 Subject: [PATCH 1424/1461] elliptic-curve: remove `ShrAssign` bound on `Scalar`s (#1938) Removes the bound from the `CurveArithmetic::Scalar` associated type. I was attempting to figure out why this issue didn't result in any bugs: https://github.com/RustCrypto/elliptic-curves/issues/1319 It appears to be completely unused. The easiest way to fix that bug is to delete all of the relevant code. --- elliptic-curve/src/arithmetic.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/elliptic-curve/src/arithmetic.rs b/elliptic-curve/src/arithmetic.rs index 88769e5dc..d955f02f3 100644 --- a/elliptic-curve/src/arithmetic.rs +++ b/elliptic-curve/src/arithmetic.rs @@ -2,7 +2,7 @@ use crate::{ Curve, CurveGroup, Error, FieldBytes, Group, NonZeroScalar, PrimeCurve, ScalarPrimitive, - ops::{Invert, LinearCombination, Mul, Reduce, ShrAssign}, + ops::{Invert, LinearCombination, Mul, Reduce}, point::{AffineCoordinates, NonIdentity}, scalar::{FromUintUnchecked, IsHigh}, }; @@ -81,7 +81,6 @@ pub trait CurveArithmetic: Curve { + for<'a> Mul<&'a Self::ProjectivePoint, Output = Self::ProjectivePoint> + PartialOrd + Reduce> - + ShrAssign + TryInto, Error = Error> + ff::Field + ff::PrimeField>; From f3b6f16c8bc8639edb464f2d4e0c36c929896424 Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Tue, 29 Jul 2025 07:54:32 -0700 Subject: [PATCH 1425/1461] digest: implement `Zeroize` for the buffering newtypes (#1940) This is a fixup to #1799 --- Cargo.lock | 3 +-- Cargo.toml | 3 +++ digest/src/buffer_macros/fixed.rs | 29 +++++++++++++++++++++++++++-- digest/tests/dummy_fixed.rs | 19 +++++++++++++++++++ 4 files changed, 50 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8294b8bbb..a0be023b6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -76,8 +76,7 @@ checksum = "4a859067dcb257cb2ae028cb821399b55140b76fb8b2a360e052fe109019db43" [[package]] name = "block-buffer" version = "0.11.0-rc.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a229bfd78e4827c91b9b95784f69492c1b77c1ab75a45a8a037b139215086f94" +source = "git+https://github.com/RustCrypto/utils.git#6fd0e8ddc827d7e7d9242e130f8944fc9ca328cf" dependencies = [ "hybrid-array", "zeroize", diff --git a/Cargo.toml b/Cargo.toml index f89b4edce..91b4f49f2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,3 +16,6 @@ members = [ [patch.crates-io] digest = { path = "digest" } signature = { path = "signature" } + +# https://github.com/RustCrypto/utils/pull/1192 +block-buffer = { git = "https://github.com/RustCrypto/utils.git" } diff --git a/digest/src/buffer_macros/fixed.rs b/digest/src/buffer_macros/fixed.rs index 716fda60c..f1e73b641 100644 --- a/digest/src/buffer_macros/fixed.rs +++ b/digest/src/buffer_macros/fixed.rs @@ -60,7 +60,7 @@ macro_rules! buffer_fixed { $crate::buffer_fixed!( impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); BaseFixedTraits AlgorithmName Default Clone HashMarker - Reset FixedOutputReset SerializableState $($trait_name)*; + Reset FixedOutputReset SerializableState ZeroizeOnDrop $($trait_name)*; ); }; @@ -476,5 +476,30 @@ macro_rules! buffer_fixed { } $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;); - } + }; + + // Implements `ZeroizeOnDrop` + ( + impl_inner: $name:ident + $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? + ($core_ty:ty); + ZeroizeOnDrop $($trait_name:ident)*; + ) => { + // Verify that `$core_ty` and `Buffer<$core_ty>` implement `ZeroizeOnDrop` + #[cfg(feature = "zeroize")] + const _: () = { + fn check_core$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?(v: &$core_ty) { + v as &dyn $crate::zeroize::ZeroizeOnDrop; + } + + fn check_buffer$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?(v: &$crate::block_api::Buffer<$core_ty>) { + v as &dyn $crate::zeroize::ZeroizeOnDrop; + } + }; + + #[cfg(feature = "zeroize")] + impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::zeroize::ZeroizeOnDrop for $name$(< $( $lt ),+ >)? {} + + $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;); + }; } diff --git a/digest/tests/dummy_fixed.rs b/digest/tests/dummy_fixed.rs index cbec6aced..cce734f59 100644 --- a/digest/tests/dummy_fixed.rs +++ b/digest/tests/dummy_fixed.rs @@ -75,6 +75,17 @@ mod block_api { }) } } + + #[cfg(feature = "zeroize")] + impl Drop for FixedHashCore { + fn drop(&mut self) { + use zeroize::Zeroize; + self.state.zeroize(); + } + } + + #[cfg(feature = "zeroize")] + impl zeroize::ZeroizeOnDrop for FixedHashCore {} } digest::buffer_fixed!( @@ -99,3 +110,11 @@ digest::buffer_fixed!( oid: "0.1.2.3.4.5"; impl: FixedHashTraits; ); + +#[cfg(feature = "zeroize")] +/// check for `ZeroizeOnDrop` implementations +const _: () = { + const fn check_zeroize() {} + check_zeroize::(); + check_zeroize::(); +}; From 13bb5400e49ddc5847e2d42e6771e784072af48c Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 1 Aug 2025 07:57:55 -0600 Subject: [PATCH 1426/1461] signature: update README.md (#1943) Breaks out a more extensive list of supported crates --- signature/README.md | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/signature/README.md b/signature/README.md index d64841bde..535dfe438 100644 --- a/signature/README.md +++ b/signature/README.md @@ -7,11 +7,30 @@ ![Rust Version][rustc-image] [![Project Chat][chat-image]][chat-link] -This crate contains traits which provide generic, object-safe APIs for +This crate contains traits which provide generic type-safe APIs for generating and verifying [digital signatures]. -Used by the [`dsa`], [`ecdsa`], [`ed25519`], and [`rsa`] crates maintained by -the [RustCrypto] organization, as well as [`ed25519-dalek`]. +## Supported crates + +The following crates are implemented using traits from the `signature` crate: + +### RustCrypto crates + +- [`dsa`] +- [`ecdsa`] +- [`ed25519`] +- [`ed448`] +- [`ed448-goldilocks`] +- [`lms`] +- [`ml-dsa`] +- [`slh-dsa`] +- [`sm2`] +- [`rsa`] + +### Third-party crates + +- [`ed25519-dalek`] +- [`yubihsm`] ## SemVer Policy Exemptions @@ -55,5 +74,12 @@ dual licensed as above, without any additional terms or conditions. [`dsa`]: https://github.com/RustCrypto/signatures/tree/master/dsa [`ecdsa`]: https://github.com/RustCrypto/signatures/tree/master/ecdsa [`ed25519`]: https://github.com/RustCrypto/signatures/tree/master/ed25519 -[`ed25519-dalek`]: https://github.com/dalek-cryptography/ed25519-dalek +[`ed25519-dalek`]: https://github.com/dalek-cryptography/curve25519-dalek/tree/main/ed25519-dalek +[`ed448`]: https://github.com/RustCrypto/elliptic-curves/tree/master/ed448 +[`ed448-goldilocks`]: https://github.com/RustCrypto/elliptic-curves/tree/master/ed448-goldilocks +[`lms`]: https://github.com/RustCrypto/signatures/tree/master/lms +[`ml-dsa`]: https://github.com/RustCrypto/signatures/tree/master/ml-dsa [`rsa`]: https://github.com/RustCrypto/RSA +[`slh-dsa`]: https://github.com/RustCrypto/signatures/tree/master/slh-dsa +[`sm2`]: https://github.com/RustCrypto/elliptic-curves/tree/master/sm2 +[`yubihsm`]: https://github.com/iqlusioninc/yubihsm.rs From c47bf37ad00c669e0a4bf6686aa9296b78ed5c15 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 4 Aug 2025 19:02:21 -0600 Subject: [PATCH 1427/1461] elliptic-curve: bump `crypto-bigint` to v0.7.0-rc.0 (#1947) --- Cargo.lock | 4 ++-- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a0be023b6..0fa32a600 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -150,9 +150,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.7.0-pre.7" +version = "0.7.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85ff38607b7ebe30e4715eeb0a0427ff42e3b6b47b2df55a775e767ef2658ccd" +checksum = "737a2363b81de8cc95d8780d84aecb4b3c6f41e4473759da6636072b5514c875" dependencies = [ "hybrid-array", "num-traits", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index dc2cfef16..8d4e5982f 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -18,7 +18,7 @@ and public/secret keys composed thereof. [dependencies] base16ct = "0.2" -crypto-bigint = { version = "=0.7.0-pre.7", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } +crypto-bigint = { version = "0.7.0-rc.0", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } hybrid-array = { version = "0.3", default-features = false, features = ["zeroize"] } rand_core = { version = "0.9.0", default-features = false } subtle = { version = "2.6", default-features = false } From 0be83862df3b42853d15748d0c6f168a04cf1b62 Mon Sep 17 00:00:00 2001 From: Arthur Gautier Date: Mon, 4 Aug 2025 19:51:34 -0700 Subject: [PATCH 1428/1461] elliptic-curve: v0.14.0-rc.11 (#1946) --- Cargo.lock | 2 +- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0fa32a600..cb0c39849 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -194,7 +194,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.14.0-rc.10" +version = "0.14.0-rc.11" dependencies = [ "base16ct", "base64ct", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 8d4e5982f..eb670cd50 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.14.0-rc.10" +version = "0.14.0-rc.11" authors = ["RustCrypto Developers"] edition = "2024" rust-version = "1.85" From 526970708925a6030483d55fb00e62a9781505b4 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 4 Aug 2025 21:22:42 -0600 Subject: [PATCH 1429/1461] elliptic-curve: use `crypto_bigint::Reduce` trait (#1949) Introduced in RustCrypto/crypto-bigint#887 --- elliptic-curve/src/arithmetic.rs | 3 ++- elliptic-curve/src/dev.rs | 10 ++++---- elliptic-curve/src/ops.rs | 23 +++-------------- elliptic-curve/src/scalar/nonzero.rs | 38 ++++++++-------------------- 4 files changed, 20 insertions(+), 54 deletions(-) diff --git a/elliptic-curve/src/arithmetic.rs b/elliptic-curve/src/arithmetic.rs index d955f02f3..e61ac45c8 100644 --- a/elliptic-curve/src/arithmetic.rs +++ b/elliptic-curve/src/arithmetic.rs @@ -80,7 +80,8 @@ pub trait CurveArithmetic: Curve { + Mul + for<'a> Mul<&'a Self::ProjectivePoint, Output = Self::ProjectivePoint> + PartialOrd - + Reduce> + + Reduce + + Reduce> + TryInto, Error = Error> + ff::Field + ff::PrimeField>; diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index e6f6c1418..a7af4ecd6 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -366,16 +366,16 @@ impl Invert for Scalar { } impl Reduce for Scalar { - type Bytes = FieldBytes; - - fn reduce(w: U256) -> Self { + fn reduce(w: &U256) -> Self { let (r, underflow) = w.borrowing_sub(&MockCurve::ORDER, Limb::ZERO); let underflow = Choice::from((underflow.0 >> (Limb::BITS - 1)) as u8); - let reduced = U256::conditional_select(&w, &r, !underflow); + let reduced = U256::conditional_select(w, &r, !underflow); Self(ScalarPrimitive::new(reduced).unwrap()) } +} - fn reduce_bytes(_: &FieldBytes) -> Self { +impl Reduce for Scalar { + fn reduce(_w: &FieldBytes) -> Self { todo!() } } diff --git a/elliptic-curve/src/ops.rs b/elliptic-curve/src/ops.rs index 2e7252d65..93abe7028 100644 --- a/elliptic-curve/src/ops.rs +++ b/elliptic-curve/src/ops.rs @@ -1,11 +1,10 @@ //! Traits for arithmetic operations on elliptic curve field elements. pub use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Shr, ShrAssign, Sub, SubAssign}; -pub use crypto_bigint::Invert; +pub use crypto_bigint::{Invert, Reduce}; use crate::CurveGroup; use core::iter; -use crypto_bigint::Integer; use ff::Field; use subtle::{Choice, CtOption}; @@ -175,18 +174,6 @@ where } } -/// Modular reduction. -pub trait Reduce: Sized { - /// Bytes used as input to [`Reduce::reduce_bytes`]. - type Bytes: AsRef<[u8]>; - - /// Perform a modular reduction, returning a field element. - fn reduce(n: Uint) -> Self; - - /// Interpret the given bytes as an integer and perform a modular reduction. - fn reduce_bytes(bytes: &Self::Bytes) -> Self; -} - /// Modular reduction to a non-zero output. /// /// This trait is primarily intended for use by curve implementations such @@ -194,11 +181,7 @@ pub trait Reduce: Sized { /// /// End users should use the [`Reduce`] impl on /// [`NonZeroScalar`][`crate::NonZeroScalar`] instead. -pub trait ReduceNonZero: Reduce + Sized { +pub trait ReduceNonZero: Reduce { /// Perform a modular reduction, returning a field element. - fn reduce_nonzero(n: Uint) -> Self; - - /// Interpret the given bytes as an integer and perform a modular reduction - /// to a non-zero output. - fn reduce_nonzero_bytes(bytes: &Self::Bytes) -> Self; + fn reduce_nonzero(n: &T) -> Self; } diff --git a/elliptic-curve/src/scalar/nonzero.rs b/elliptic-curve/src/scalar/nonzero.rs index d0dd1768b..fd9e5315c 100644 --- a/elliptic-curve/src/scalar/nonzero.rs +++ b/elliptic-curve/src/scalar/nonzero.rs @@ -12,7 +12,6 @@ use core::{ ops::{Deref, Mul, MulAssign, Neg}, str, }; -use crypto_bigint::{ArrayEncoding, Integer}; use ff::{Field, PrimeField}; use rand_core::{CryptoRng, TryCryptoRng}; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; @@ -391,42 +390,25 @@ where } } -/// Note: this is a non-zero reduction, as it's impl'd for [`NonZeroScalar`]. -impl Reduce for NonZeroScalar +impl Reduce for NonZeroScalar where C: CurveArithmetic, - I: Integer + ArrayEncoding, - Scalar: Reduce + ReduceNonZero, + Scalar: ReduceNonZero, { - type Bytes = as Reduce>::Bytes; - - fn reduce(n: I) -> Self { - let scalar = Scalar::::reduce_nonzero(n); - debug_assert!(!bool::from(scalar.is_zero())); - Self { scalar } - } - - fn reduce_bytes(bytes: &Self::Bytes) -> Self { - let scalar = Scalar::::reduce_nonzero_bytes(bytes); - debug_assert!(!bool::from(scalar.is_zero())); - Self { scalar } + fn reduce(n: &T) -> Self { + >::reduce_nonzero(n) } } -/// Note: forwards to the [`Reduce`] impl. -impl ReduceNonZero for NonZeroScalar +impl ReduceNonZero for NonZeroScalar where - Self: Reduce, C: CurveArithmetic, - I: Integer + ArrayEncoding, - Scalar: Reduce + ReduceNonZero, + Scalar: ReduceNonZero, { - fn reduce_nonzero(n: I) -> Self { - >::reduce(n) - } - - fn reduce_nonzero_bytes(bytes: &Self::Bytes) -> Self { - >::reduce_bytes(bytes) + fn reduce_nonzero(n: &T) -> Self { + let scalar = Scalar::::reduce_nonzero(n); + debug_assert!(!bool::from(scalar.is_zero())); + Self { scalar } } } From a7b906402e867fb5b9745eff92b0fe7f2b750c7f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Aug 2025 15:15:09 +0300 Subject: [PATCH 1430/1461] build(deps): bump crate-ci/typos from 1.34.0 to 1.35.1 (#1950) --- .github/workflows/workspace.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index 564f5925a..25634dd6a 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -52,4 +52,4 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: crate-ci/typos@v1.34.0 + - uses: crate-ci/typos@v1.35.1 From 0e59d80ef86c30488aebede48d1f34b898fe87e8 Mon Sep 17 00:00:00 2001 From: Charles Edward Gagnon <76854355+carloskiki@users.noreply.github.com> Date: Tue, 5 Aug 2025 16:54:36 -0400 Subject: [PATCH 1431/1461] Only run CI on latest commit of PR branches. (#1948) This is a little hack I make use of in my projects and found a bit annoying when opening PRs here. When successive commits are made to a PR, cancels CI workflows that are not ran on the latest commit - saving CI time and making things quicker. I can also make this PR to other RustCrpyto repos if this is something we want. --- .github/workflows/aead.yml | 5 +++++ .github/workflows/cipher.yml | 5 +++++ .github/workflows/crypto-common.yml | 5 +++++ .github/workflows/crypto.yml | 5 +++++ .github/workflows/digest.yml | 5 +++++ .github/workflows/elliptic-curve.yml | 5 +++++ .github/workflows/kem.yml | 5 +++++ .github/workflows/password-hash.yml | 5 +++++ .github/workflows/signature.yml | 5 +++++ .github/workflows/universal-hash.yml | 5 +++++ .github/workflows/workspace.yml | 5 +++++ 11 files changed, 55 insertions(+) diff --git a/.github/workflows/aead.yml b/.github/workflows/aead.yml index 5e052be8f..8f7d377ab 100644 --- a/.github/workflows/aead.yml +++ b/.github/workflows/aead.yml @@ -15,6 +15,11 @@ defaults: env: CARGO_INCREMENTAL: 0 RUSTFLAGS: "-Dwarnings" + +# Cancels CI jobs when new commits are pushed to a PR branch +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true jobs: build: diff --git a/.github/workflows/cipher.yml b/.github/workflows/cipher.yml index 048b0c562..2db6cbc1e 100644 --- a/.github/workflows/cipher.yml +++ b/.github/workflows/cipher.yml @@ -17,6 +17,11 @@ env: CARGO_INCREMENTAL: 0 RUSTFLAGS: "-Dwarnings" +# Cancels CI jobs when new commits are pushed to a PR branch +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + jobs: build: runs-on: ubuntu-latest diff --git a/.github/workflows/crypto-common.yml b/.github/workflows/crypto-common.yml index 689ae58a5..c52dc75d6 100644 --- a/.github/workflows/crypto-common.yml +++ b/.github/workflows/crypto-common.yml @@ -16,6 +16,11 @@ env: CARGO_INCREMENTAL: 0 RUSTFLAGS: "-Dwarnings" +# Cancels CI jobs when new commits are pushed to a PR branch +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + jobs: build: runs-on: ubuntu-latest diff --git a/.github/workflows/crypto.yml b/.github/workflows/crypto.yml index e2926600c..2a1a13f4d 100644 --- a/.github/workflows/crypto.yml +++ b/.github/workflows/crypto.yml @@ -16,6 +16,11 @@ env: CARGO_INCREMENTAL: 0 RUSTFLAGS: "-Dwarnings" +# Cancels CI jobs when new commits are pushed to a PR branch +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + jobs: build: runs-on: ubuntu-latest diff --git a/.github/workflows/digest.yml b/.github/workflows/digest.yml index f89b13c5d..ab16c4567 100644 --- a/.github/workflows/digest.yml +++ b/.github/workflows/digest.yml @@ -15,6 +15,11 @@ defaults: env: CARGO_INCREMENTAL: 0 RUSTFLAGS: "-Dwarnings" + +# Cancels CI jobs when new commits are pushed to a PR branch +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true jobs: build: diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index 43343005d..d24a39903 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -17,6 +17,11 @@ env: CARGO_INCREMENTAL: 0 RUSTFLAGS: "-Dwarnings" RUSTDOCFLAGS: "-Dwarnings" + +# Cancels CI jobs when new commits are pushed to a PR branch +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true jobs: build: diff --git a/.github/workflows/kem.yml b/.github/workflows/kem.yml index 168f270dc..66204e807 100644 --- a/.github/workflows/kem.yml +++ b/.github/workflows/kem.yml @@ -16,6 +16,11 @@ env: CARGO_INCREMENTAL: 0 RUSTFLAGS: "-Dwarnings" +# Cancels CI jobs when new commits are pushed to a PR branch +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + jobs: build: runs-on: ubuntu-latest diff --git a/.github/workflows/password-hash.yml b/.github/workflows/password-hash.yml index 670fd7e54..f30026fe8 100644 --- a/.github/workflows/password-hash.yml +++ b/.github/workflows/password-hash.yml @@ -16,6 +16,11 @@ env: CARGO_INCREMENTAL: 0 RUSTFLAGS: "-Dwarnings" +# Cancels CI jobs when new commits are pushed to a PR branch +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + jobs: build: runs-on: ubuntu-latest diff --git a/.github/workflows/signature.yml b/.github/workflows/signature.yml index 1105f50b1..7362c041c 100644 --- a/.github/workflows/signature.yml +++ b/.github/workflows/signature.yml @@ -17,6 +17,11 @@ env: RUSTFLAGS: "-Dwarnings" RUSTDOCFLAGS: "-Dwarnings" +# Cancels CI jobs when new commits are pushed to a PR branch +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + jobs: build: runs-on: ubuntu-latest diff --git a/.github/workflows/universal-hash.yml b/.github/workflows/universal-hash.yml index 232dc4676..6ee244acf 100644 --- a/.github/workflows/universal-hash.yml +++ b/.github/workflows/universal-hash.yml @@ -16,6 +16,11 @@ env: CARGO_INCREMENTAL: 0 RUSTFLAGS: "-Dwarnings" +# Cancels CI jobs when new commits are pushed to a PR branch +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + jobs: build: runs-on: ubuntu-latest diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index 25634dd6a..2ac87f0a9 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -16,6 +16,11 @@ env: RUSTFLAGS: "-Dwarnings" RUSTDOCFLAGS: "-Dwarnings" +# Cancels CI jobs when new commits are pushed to a PR branch +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + jobs: clippy: runs-on: ubuntu-latest From c18cd6d333d571c8d3639d986ca152626e956512 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 5 Aug 2025 18:56:24 -0600 Subject: [PATCH 1432/1461] elliptic-curve v0.14.0-rc.12 (#1951) --- Cargo.lock | 2 +- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cb0c39849..a43162635 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -194,7 +194,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.14.0-rc.11" +version = "0.14.0-rc.12" dependencies = [ "base16ct", "base64ct", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index eb670cd50..b5503969b 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.14.0-rc.11" +version = "0.14.0-rc.12" authors = ["RustCrypto Developers"] edition = "2024" rust-version = "1.85" From f531ed3162b3d368bcca90446b61c4664f48aa5a Mon Sep 17 00:00:00 2001 From: daxpedda Date: Wed, 6 Aug 2025 16:31:06 +0200 Subject: [PATCH 1433/1461] Add `NonIdentity::try_from_rng()` (#1944) I noticed that this was missing. --- elliptic-curve/src/point/non_identity.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/elliptic-curve/src/point/non_identity.rs b/elliptic-curve/src/point/non_identity.rs index 6617e2c9a..6380b3a68 100644 --- a/elliptic-curve/src/point/non_identity.rs +++ b/elliptic-curve/src/point/non_identity.rs @@ -3,7 +3,7 @@ use core::ops::{Deref, Mul}; use group::{Group, GroupEncoding, prime::PrimeCurveAffine}; -use rand_core::CryptoRng; +use rand_core::{CryptoRng, TryCryptoRng}; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; #[cfg(feature = "alloc")] @@ -94,6 +94,15 @@ where } } + /// Generate a random `NonIdentity`. + pub fn try_from_rng(rng: &mut R) -> Result { + loop { + if let Some(point) = Self::new(P::try_from_rng(rng)?).into() { + break Ok(point); + } + } + } + /// Converts this element into its affine representation. pub fn to_affine(self) -> NonIdentity { NonIdentity { From 5186264ed4178161971062db123934dfe40e2022 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Mon, 11 Aug 2025 15:46:05 +0300 Subject: [PATCH 1434/1461] aead: fix test by marking `Prefix/PostfixDummyAead` public (#1954) --- aead/tests/dummy.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aead/tests/dummy.rs b/aead/tests/dummy.rs index 817ab945c..f99278cec 100644 --- a/aead/tests/dummy.rs +++ b/aead/tests/dummy.rs @@ -91,7 +91,7 @@ impl DummyAead { } } -struct PrefixDummyAead(DummyAead); +pub struct PrefixDummyAead(DummyAead); impl KeySizeUser for PrefixDummyAead { type KeySize = U8; @@ -130,7 +130,7 @@ impl AeadInOut for PrefixDummyAead { } } -struct PostfixDummyAead(DummyAead); +pub struct PostfixDummyAead(DummyAead); impl KeySizeUser for PostfixDummyAead { type KeySize = U8; From 832c889be55234ec3f6271d0b2133017a0f5703b Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Mon, 11 Aug 2025 16:09:07 +0300 Subject: [PATCH 1435/1461] Migrate to const blobby parsing (#1916) --- Cargo.lock | 50 ++---- Cargo.toml | 4 +- aead/src/dev.rs | 137 ++++++++++----- aead/tests/dummy.rs | 3 +- cipher/src/dev.rs | 7 +- cipher/src/dev/block.rs | 335 +++++++++++++++---------------------- cipher/src/dev/stream.rs | 80 ++++++--- cipher/src/lib.rs | 4 +- digest/src/dev.rs | 34 ++-- digest/src/dev/fixed.rs | 33 ++-- digest/src/dev/mac.rs | 255 ++++++++++++++-------------- digest/src/dev/variable.rs | 33 ++-- digest/src/dev/xof.rs | 19 +-- 13 files changed, 502 insertions(+), 492 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a43162635..26902dbe3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -70,8 +70,7 @@ dependencies = [ [[package]] name = "blobby" version = "0.4.0-pre.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a859067dcb257cb2ae028cb821399b55140b76fb8b2a360e052fe109019db43" +source = "git+https://github.com/RustCrypto/utils#1227836d92c56dce5fddb3ed36003277f053267b" [[package]] name = "block-buffer" @@ -99,9 +98,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.10.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f61dac84819c6588b558454b194026eb1f09c293b9036ae9b159e74e73ab6cf9" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "cfg-if" @@ -430,18 +429,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.93" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.38" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] @@ -460,12 +459,11 @@ checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" [[package]] name = "rand_core" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a509b1a2ffbe92afab0e55c8fd99dea1c280e8171bd2d88682bb20bc41cbc2c" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ "getrandom", - "zerocopy", ] [[package]] @@ -505,14 +503,14 @@ checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.104", ] [[package]] name = "serde_json" -version = "1.0.139" +version = "1.0.141" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44f86c3acccc9c65b153fe1b85a3be07fe5515274ec9f0653b4a0875731c72a6" +checksum = "30b9eff21ebe718216c6ec64e1d9ac57087aad11efc64e32002bce4a0d4c03d3" dependencies = [ "itoa", "memchr", @@ -594,9 +592,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.98" +version = "2.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" dependencies = [ "proc-macro2", "quote", @@ -656,26 +654,6 @@ dependencies = [ "tap", ] -[[package]] -name = "zerocopy" -version = "0.8.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.98", -] - [[package]] name = "zeroize" version = "1.8.1" diff --git a/Cargo.toml b/Cargo.toml index 91b4f49f2..f3ed415c2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,5 +17,7 @@ members = [ digest = { path = "digest" } signature = { path = "signature" } +# https://github.com/RustCrypto/utils/pull/1187 +blobby = { git = "https://github.com/RustCrypto/utils" } # https://github.com/RustCrypto/utils/pull/1192 -block-buffer = { git = "https://github.com/RustCrypto/utils.git" } +block-buffer = { git = "https://github.com/RustCrypto/utils" } diff --git a/aead/src/dev.rs b/aead/src/dev.rs index f216b72cc..2f942d557 100644 --- a/aead/src/dev.rs +++ b/aead/src/dev.rs @@ -1,43 +1,80 @@ //! Development-related functionality use crate::{ - Aead, AeadInOut, Nonce, Payload, Tag, TagPosition, array::typenum::Unsigned, inout::InOutBuf, + Aead, AeadInOut, Payload, Tag, TagPosition, array::typenum::Unsigned, inout::InOutBuf, }; pub use blobby; +use crypto_common::KeyInit; + +/// AEAD test vector +#[derive(Debug, Clone, Copy)] +pub struct TestVector { + /// Initialization key + pub key: &'static [u8], + /// Nonce + pub nonce: &'static [u8], + /// Additional associated data + pub aad: &'static [u8], + /// Plaintext + pub plaintext: &'static [u8], + /// Ciphertext + pub ciphertext: &'static [u8], + /// Whether the test vector should pass (`[1]`) or fail (`[0]`) + pub pass: &'static [u8], +} /// Run AEAD test for the provided passing test vector -pub fn run_pass_test( - cipher: &C, - nonce: &Nonce, - aad: &[u8], - pt: &[u8], - ct: &[u8], +pub fn pass_test( + &TestVector { + key, + nonce, + aad, + plaintext, + ciphertext, + pass, + }: &TestVector, ) -> Result<(), &'static str> { + assert_eq!(pass, &[1]); + let nonce = nonce.try_into().expect("wrong nonce size"); + let cipher = ::new_from_slice(key).expect("failed to initialize the cipher"); + let res = cipher - .encrypt(nonce, Payload { aad, msg: pt }) + .encrypt( + nonce, + Payload { + aad, + msg: plaintext, + }, + ) .map_err(|_| "encryption failure")?; - if res != ct { + if res != ciphertext { return Err("encrypted data is different from target ciphertext"); } let res = cipher - .decrypt(nonce, Payload { aad, msg: ct }) + .decrypt( + nonce, + Payload { + aad, + msg: ciphertext, + }, + ) .map_err(|_| "decryption failure")?; - if res != pt { + if res != plaintext { return Err("decrypted data is different from target plaintext"); } let (ct, tag) = match C::TAG_POSITION { TagPosition::Prefix => { - let (tag, ct) = ct.split_at(C::TagSize::USIZE); + let (tag, ct) = ciphertext.split_at(C::TagSize::USIZE); (ct, tag) } - TagPosition::Postfix => ct.split_at(pt.len()), + TagPosition::Postfix => ciphertext.split_at(plaintext.len()), }; let tag: &Tag = tag.try_into().expect("tag has correct length"); // Fill output buffer with "garbage" to test that its data does not get read during encryption - let mut buf: alloc::vec::Vec = (0..pt.len()).map(|i| i as u8).collect(); - let inout_buf = InOutBuf::new(pt, &mut buf).expect("pt and buf have the same length"); + let mut buf: alloc::vec::Vec = (0..plaintext.len()).map(|i| i as u8).collect(); + let inout_buf = InOutBuf::new(plaintext, &mut buf).expect("pt and buf have the same length"); let calc_tag = cipher .encrypt_inout_detached(nonce, aad, inout_buf) @@ -50,13 +87,15 @@ pub fn run_pass_test( } // Fill output buffer with "garbage" - buf.iter_mut().enumerate().for_each(|(i, v)| *v = i as u8); + buf.iter_mut() + .enumerate() + .for_each(|(i, v): (usize, &mut u8)| *v = i as u8); let inout_buf = InOutBuf::new(ct, &mut buf).expect("ct and buf have the same length"); cipher .decrypt_inout_detached(nonce, aad, inout_buf, tag) .map_err(|_| "decrypt_inout_detached: decryption failure")?; - if pt != buf { + if plaintext != buf { return Err("decrypt_inout_detached: plaintext mismatch"); } @@ -64,13 +103,27 @@ pub fn run_pass_test( } /// Run AEAD test for the provided failing test vector -pub fn run_fail_test( - cipher: &C, - nonce: &Nonce, - aad: &[u8], - ct: &[u8], +pub fn fail_test( + &TestVector { + key, + nonce, + aad, + ciphertext, + pass, + .. + }: &TestVector, ) -> Result<(), &'static str> { - let res = cipher.decrypt(nonce, Payload { aad, msg: ct }); + assert_eq!(pass, &[0]); + let nonce = nonce.try_into().expect("wrong nonce size"); + let cipher = ::new_from_slice(key).expect("failed to initialize the cipher"); + + let res = cipher.decrypt( + nonce, + Payload { + aad, + msg: ciphertext, + }, + ); if res.is_ok() { Err("decryption must return error") } else { @@ -84,33 +137,29 @@ macro_rules! new_test { ($name:ident, $test_name:expr, $cipher:ty $(,)?) => { #[test] fn $name() { - use $crate::KeyInit; - use $crate::dev::blobby::Blob6Iterator; - - let data = include_bytes!(concat!("data/", $test_name, ".blb")); - for (i, row) in Blob6Iterator::new(data).unwrap().enumerate() { - let [key, nonce, aad, pt, ct, status] = row.unwrap(); - let key = key.try_into().expect("wrong key size"); - let nonce = nonce.try_into().expect("wrong nonce size"); - let cipher = <$cipher as KeyInit>::new(key); - - let res = match status { - [0] => $crate::dev::run_fail_test(&cipher, nonce, aad, ct), - [1] => $crate::dev::run_pass_test(&cipher, nonce, aad, pt, ct), - _ => panic!("invalid value for pass flag"), + use $crate::dev::TestVector; + + $crate::dev::blobby::parse_into_structs!( + include_bytes!(concat!("data/", $test_name, ".blb")); + static TEST_VECTORS: &[ + TestVector { key, nonce, aad, plaintext, ciphertext, pass } + ]; + ); + + for (i, tv) in TEST_VECTORS.iter().enumerate() { + let pass = tv.pass[0] == 1; + let res = if pass { + $crate::dev::pass_test::<$cipher>(tv) + } else { + $crate::dev::fail_test::<$cipher>(tv) }; - let mut pass = status[0] == 1; + if let Err(reason) = res { panic!( "\n\ Failed test #{i}\n\ reason:\t{reason:?}\n\ - key:\t{key:?}\n\ - nonce:\t{nonce:?}\n\ - aad:\t{aad:?}\n\ - plaintext:\t{pt:?}\n\ - ciphertext:\t{ct:?}\n\ - pass:\t{pass}\n" + test vector:\t{tv:?}\n" ); } } diff --git a/aead/tests/dummy.rs b/aead/tests/dummy.rs index f99278cec..ef7606f00 100644 --- a/aead/tests/dummy.rs +++ b/aead/tests/dummy.rs @@ -1,5 +1,6 @@ //! This module defines dummy (horribly insecure!) AEAD implementations //! to test implementation of the AEAD traits and helper macros in the `dev` module. +#![cfg(feature = "dev")] use aead::{ AeadCore, AeadInOut, Error, Key, KeyInit, KeySizeUser, Nonce, Result, Tag, TagPosition, array::Array, consts::U8, @@ -169,7 +170,5 @@ impl AeadInOut for PostfixDummyAead { } } -#[cfg(feature = "dev")] aead::new_test!(dummy_prefix, "prefix", PrefixDummyAead); -#[cfg(feature = "dev")] aead::new_test!(dummy_postfix, "postfix", PostfixDummyAead); diff --git a/cipher/src/dev.rs b/cipher/src/dev.rs index 6bedbe989..efd050267 100644 --- a/cipher/src/dev.rs +++ b/cipher/src/dev.rs @@ -1,2 +1,5 @@ -mod block; -mod stream; +//! Development-related functionality +pub mod block; +pub mod stream; + +pub use blobby; diff --git a/cipher/src/dev/block.rs b/cipher/src/dev/block.rs index 6a7f90426..7234535fb 100644 --- a/cipher/src/dev/block.rs +++ b/cipher/src/dev/block.rs @@ -1,213 +1,154 @@ -//! Development-related functionality - -/// Define block cipher test -#[macro_export] -macro_rules! block_cipher_test { - ($name:ident, $test_name:expr, $cipher:ty $(,)?) => { - #[test] - fn $name() { - use cipher::{ - BlockSizeUser, KeyInit, - array::Array, - blobby::Blob3Iterator, - block::{BlockCipherDecrypt, BlockCipherEncrypt}, - typenum::Unsigned, - }; - - fn run_test(key: &[u8], pt: &[u8], ct: &[u8]) -> bool { - let mut state = <$cipher as KeyInit>::new_from_slice(key).unwrap(); - - let mut block = Array::try_from(pt).unwrap(); - state.encrypt_block(&mut block); - if ct != block.as_slice() { - return false; - } - - state.decrypt_block(&mut block); - if pt != block.as_slice() { - return false; - } - - true - } - - fn run_par_test(key: &[u8], pt: &[u8]) -> bool { - type Block = cipher::Block<$cipher>; - - let mut state = <$cipher as KeyInit>::new_from_slice(key).unwrap(); - - let block = Block::try_from(pt).unwrap(); - let mut blocks1 = vec![block; 101]; - for (i, b) in blocks1.iter_mut().enumerate() { - *b = block; - b[0] = b[0].wrapping_add(i as u8); - } - let mut blocks2 = blocks1.clone(); +//! Development-related functionality for block ciphers + +use crate::{Block, BlockCipherDecrypt, BlockCipherEncrypt, KeyInit}; + +/// Block cipher test vector +#[derive(Debug, Clone, Copy)] +pub struct TestVector { + /// Initialization key + pub key: &'static [u8], + /// Plaintext block + pub plaintext: &'static [u8], + /// Ciphertext block + pub ciphertext: &'static [u8], +} - // check that `encrypt_blocks` and `encrypt_block` - // result in the same ciphertext - state.encrypt_blocks(&mut blocks1); - for b in blocks2.iter_mut() { - state.encrypt_block(b); - } - if blocks1 != blocks2 { - return false; - } +/// Block cipher encryption test +pub fn block_cipher_enc_test( + tv: &TestVector, +) -> Result<(), &'static str> { + let Ok(state) = C::new_from_slice(tv.key) else { + return Err("cipher initialization failure"); + }; - // check that `encrypt_blocks` and `encrypt_block` - // result in the same plaintext - state.decrypt_blocks(&mut blocks1); - for b in blocks2.iter_mut() { - state.decrypt_block(b); - } - if blocks1 != blocks2 { - return false; - } + let Ok(pt_block) = Block::::try_from(tv.plaintext) else { + return Err("unexpected size of plaintext block"); + }; + let Ok(ct_block) = Block::::try_from(tv.ciphertext) else { + return Err("unexpected size of ciphertext block"); + }; - true - } + let mut block = pt_block.clone(); + state.encrypt_block(&mut block); + if block != ct_block { + return Err("single block encryption failure"); + } + + let mut blocks1: [Block; 101] = core::array::from_fn(|i| { + let mut block = pt_block.clone(); + block[0] ^= i as u8; + block + }); + let mut blocks2 = blocks1.clone(); + + // Check that `encrypt_blocks` and `encrypt_block` result in the same ciphertext + state.encrypt_blocks(&mut blocks1); + for b in blocks2.iter_mut() { + state.encrypt_block(b); + } + if blocks1 != blocks2 { + return Err("multi-block encryption failure"); + } + + Ok(()) +} - let data = include_bytes!(concat!("data/", $test_name, ".blb")); - for (i, row) in Blob3Iterator::new(data).unwrap().enumerate() { - let [key, pt, ct] = row.unwrap(); - if !run_test(key, pt, ct) { - panic!( - "\n\ - Failed test №{}\n\ - key:\t{:?}\n\ - plaintext:\t{:?}\n\ - ciphertext:\t{:?}\n", - i, key, pt, ct, - ); - } +/// Block cipher encryption test +pub fn block_cipher_dec_test( + tv: &TestVector, +) -> Result<(), &'static str> { + let Ok(state) = C::new_from_slice(tv.key) else { + return Err("cipher initialization failure"); + }; - // test parallel blocks encryption/decryption - if !run_par_test(key, pt) { - panic!( - "\n\ - Failed parallel test №{}\n\ - key:\t{:?}\n\ - plaintext:\t{:?}\n\ - ciphertext:\t{:?}\n", - i, key, pt, ct, - ); - } - } - } + let Ok(pt_block) = Block::::try_from(tv.plaintext) else { + return Err("unexpected size of plaintext block"); + }; + let Ok(ct_block) = Block::::try_from(tv.ciphertext) else { + return Err("unexpected size of ciphertext block"); }; + + let mut block = ct_block.clone(); + state.decrypt_block(&mut block); + if block != pt_block { + return Err("single block decryption failure"); + } + + let mut blocks1: [Block; 101] = core::array::from_fn(|i| { + let mut block = ct_block.clone(); + block[0] ^= i as u8; + block + }); + let mut blocks2 = blocks1.clone(); + + // Check that `encrypt_blocks` and `encrypt_block` result in the same ciphertext + state.decrypt_blocks(&mut blocks1); + for b in blocks2.iter_mut() { + state.decrypt_block(b); + } + if blocks1 != blocks2 { + return Err("multi-block decryption failure"); + } + + Ok(()) } -/// Define block mode encryption test +/// Define block cipher test #[macro_export] -macro_rules! block_mode_enc_test { - ($name:ident, $test_name:expr, $cipher:ty $(,)?) => { - #[test] - fn $name() { - use cipher::{ - BlockCipherEncrypt, BlockModeEncrypt, BlockSizeUser, KeyIvInit, array::Array, - blobby::Blob4Iterator, inout::InOutBuf, typenum::Unsigned, - }; - - fn run_test(key: &[u8], iv: &[u8], pt: &[u8], ct: &[u8]) -> bool { - assert_eq!(pt.len(), ct.len()); - // test block-by-block processing - let mut state = <$cipher as KeyIvInit>::new_from_slices(key, iv).unwrap(); - - let mut out = vec![0u8; ct.len()]; - let mut buf = InOutBuf::new(pt, &mut out).unwrap(); - let (blocks, tail) = buf.reborrow().into_chunks(); - assert_eq!(tail.len(), 0); - for block in blocks { - state.encrypt_block_inout(block); - } - if buf.get_out() != ct { - return false; - } - - // test multi-block processing - let mut state = <$cipher as KeyIvInit>::new_from_slices(key, iv).unwrap(); - buf.get_out().iter_mut().for_each(|b| *b = 0); - let (blocks, _) = buf.reborrow().into_chunks(); - state.encrypt_blocks_inout(blocks); - if buf.get_out() != ct { - return false; - } - - true - } - - let data = include_bytes!(concat!("data/", $test_name, ".blb")); - for (i, row) in Blob4Iterator::new(data).unwrap().enumerate() { - let [key, iv, pt, ct] = row.unwrap(); - if !run_test(key, iv, pt, ct) { - panic!( - "\n\ - Failed test №{}\n\ - key:\t{:?}\n\ - iv:\t{:?}\n\ - plaintext:\t{:?}\n\ - ciphertext:\t{:?}\n", - i, key, iv, pt, ct, - ); - } - } - } +macro_rules! block_cipher_test { + ( + encdec: $name:ident, $test_name:expr, $cipher:ty $(,)? + ) => { + $crate::block_cipher_test!( + inner: $name, $test_name, $cipher, + "encryption" block_cipher_enc_test, + "decryption" block_cipher_dec_test, + ); + }; + ( + enc: $name:ident, $test_name:expr, $cipher:ty $(,)? + ) => { + $crate::block_cipher_test!( + inner: $name, $test_name, $cipher, + "encryption" block_cipher_enc_test, + ); + }; + ( + dec: $name:ident, $test_name:expr, $cipher:ty $(,)? + ) => { + $crate::block_cipher_test!( + inner: $name, $test_name, $cipher, + "decryption" block_cipher_dec_test, + ); }; -} -/// Define block mode decryption test -#[macro_export] -macro_rules! block_mode_dec_test { - ($name:ident, $test_name:expr, $cipher:ty $(,)?) => { + ( + inner: $name:ident, $test_name:expr, $cipher:ty, + $($test_desc:literal $test_fn:ident,)* + ) => { #[test] fn $name() { - use cipher::{ - BlockCipherDecrypt, BlockModeDecrypt, BlockSizeUser, KeyIvInit, array::Array, - blobby::Blob4Iterator, inout::InOutBuf, typenum::Unsigned, - }; - - fn run_test(key: &[u8], iv: &[u8], pt: &[u8], ct: &[u8]) -> bool { - assert_eq!(pt.len(), ct.len()); - // test block-by-block processing - let mut state = <$cipher as KeyIvInit>::new_from_slices(key, iv).unwrap(); - - let mut out = vec![0u8; pt.len()]; - let mut buf = InOutBuf::new(ct, &mut out).unwrap(); - let (blocks, tail) = buf.reborrow().into_chunks(); - assert_eq!(tail.len(), 0); - for block in blocks { - state.decrypt_block_inout(block); - } - if buf.get_out() != pt { - return false; - } - - // test multi-block processing - let mut state = <$cipher as KeyIvInit>::new_from_slices(key, iv).unwrap(); - buf.get_out().iter_mut().for_each(|b| *b = 0); - let (blocks, _) = buf.reborrow().into_chunks(); - state.decrypt_blocks_inout(blocks); - if buf.get_out() != pt { - return false; - } - - true - } - - let data = include_bytes!(concat!("data/", $test_name, ".blb")); - for (i, row) in Blob4Iterator::new(data).unwrap().enumerate() { - let [key, iv, pt, ct] = row.unwrap(); - if !run_test(key, iv, pt, ct) { - panic!( - "\n\ - Failed test №{}\n\ - key:\t{:?}\n\ - iv:\t{:?}\n\ - plaintext:\t{:?}\n\ - ciphertext:\t{:?}\n", - i, key, iv, pt, ct, - ); - } + use $crate::dev::block::TestVector; + + $crate::dev::blobby::parse_into_structs!( + include_bytes!(concat!("data/", $test_name, ".blb")); + static TEST_VECTORS: &[ + TestVector { key, plaintext, ciphertext } + ]; + ); + + for (i, tv) in TEST_VECTORS.iter().enumerate() { + $( + let res = $test_fn(tv); + if let Err(reason) = res { + panic!(concat!( + "\n\ + Failed ", $test_desc, " test #{i}\n\ + reason:\t{reason:?}\n\ + test vector:\t{tv:?}\n" + )); + } + )* } } }; diff --git a/cipher/src/dev/stream.rs b/cipher/src/dev/stream.rs index ff530f4cd..00dc14f54 100644 --- a/cipher/src/dev/stream.rs +++ b/cipher/src/dev/stream.rs @@ -1,4 +1,45 @@ -//! Development-related functionality +//! Development-related functionality for stream ciphers +use crate::{KeyIvInit, StreamCipher}; + +/// Stream cipher test vector +#[derive(Clone, Copy, Debug)] +pub struct TestVector { + /// Initialization key + pub key: &'static [u8], + /// Initialization vector + pub iv: &'static [u8], + /// Plaintext + pub plaintext: &'static [u8], + /// Ciphertext + pub ciphertext: &'static [u8], +} + +/// Run stream cipher test +pub fn stream_cipher_test( + tv: &TestVector, +) -> Result<(), &'static str> { + if tv.plaintext.len() != tv.ciphertext.len() { + return Err("mismatch of plaintext and ciphertext lengths"); + } + let mut buf = [0u8; 256]; + for chunk_len in 1..256 { + let Ok(mut mode) = C::new_from_slices(tv.key, tv.iv) else { + return Err("cipher initialization failure"); + }; + let pt_chunks = tv.plaintext.chunks(chunk_len); + let ct_chunks = tv.ciphertext.chunks(chunk_len); + for (pt_chunk, ct_chunk) in pt_chunks.zip(ct_chunks) { + let buf = &mut buf[..pt_chunk.len()]; + buf.copy_from_slice(pt_chunk); + mode.apply_keystream(buf); + + if buf != ct_chunk { + return Err("ciphertext mismatch"); + } + } + } + Ok(()) +} /// Test core functionality of synchronous stream cipher #[macro_export] @@ -6,29 +47,24 @@ macro_rules! stream_cipher_test { ($name:ident, $test_name:expr, $cipher:ty $(,)?) => { #[test] fn $name() { - use cipher::array::Array; - use cipher::{KeyIvInit, StreamCipher, blobby::Blob4Iterator}; + use $crate::dev::stream::TestVector; - let data = include_bytes!(concat!("data/", $test_name, ".blb")); - for (i, row) in Blob4Iterator::new(data).unwrap().enumerate() { - let [key, iv, pt, ct] = row.unwrap(); + $crate::dev::blobby::parse_into_structs!( + include_bytes!(concat!("data/", $test_name, ".blb")); + static TEST_VECTORS: &[ + TestVector { key, iv, plaintext, ciphertext } + ]; + ); - for chunk_n in 1..256 { - let mut mode = <$cipher>::new_from_slices(key, iv).unwrap(); - let mut pt = pt.to_vec(); - for chunk in pt.chunks_mut(chunk_n) { - mode.apply_keystream(chunk); - } - if pt != &ct[..] { - panic!( - "Failed main test №{}, chunk size: {}\n\ - key:\t{:?}\n\ - iv:\t{:?}\n\ - plaintext:\t{:?}\n\ - ciphertext:\t{:?}\n", - i, chunk_n, key, iv, pt, ct, - ); - } + for (i, tv) in TEST_VECTORS.iter().enumerate() { + let res = $crate::dev::stream::stream_cipher_test(tv); + if Err(reason) = res { + panic!( + "\n\ + Failed test #{i}\n\ + reason:\t{reason:?}\n\ + test vector:\t{tv:?}\n" + ); } } } diff --git a/cipher/src/lib.rs b/cipher/src/lib.rs index 7771e5973..009a8b8a9 100644 --- a/cipher/src/lib.rs +++ b/cipher/src/lib.rs @@ -18,7 +18,7 @@ missing_debug_implementations )] -#[cfg(all(feature = "block-padding", feature = "alloc"))] +#[cfg(feature = "alloc")] extern crate alloc; #[cfg(feature = "dev")] @@ -34,7 +34,7 @@ pub use zeroize; pub mod block; #[cfg(feature = "dev")] -mod dev; +pub mod dev; pub mod stream; pub mod tweak; diff --git a/digest/src/dev.rs b/digest/src/dev.rs index b3d0203dc..e7e4d0a23 100644 --- a/digest/src/dev.rs +++ b/digest/src/dev.rs @@ -3,33 +3,47 @@ pub use blobby; mod fixed; +#[cfg(feature = "mac")] mod mac; mod rng; mod variable; mod xof; pub use fixed::*; +#[cfg(feature = "mac")] +pub use mac::*; pub use variable::*; pub use xof::*; +/// Test vector for hash functions +#[derive(Debug, Clone, Copy)] +pub struct TestVector { + /// Input data + pub input: &'static [u8], + /// Output hash + pub output: &'static [u8], +} + /// Define hash function test #[macro_export] macro_rules! new_test { - ($name:ident, $test_name:expr, $hasher:ty, $test_func:ident $(,)?) => { + ($name:ident, $test_name:expr, $hasher:ty, $test_fn:ident $(,)?) => { #[test] fn $name() { - use digest::dev::blobby::Blob2Iterator; - let data = include_bytes!(concat!("data/", $test_name, ".blb")); + use $crate::dev::TestVector; + + $crate::dev::blobby::parse_into_structs!( + include_bytes!(concat!("data/", $test_name, ".blb")); + static TEST_VECTORS: &[TestVector { input, output }]; + ); - for (i, row) in Blob2Iterator::new(data).unwrap().enumerate() { - let [input, output] = row.unwrap(); - if let Some(desc) = $test_func::<$hasher>(input, output) { + for (i, tv) in TEST_VECTORS.iter().enumerate() { + if let Err(reason) = $test_fn::<$hasher>(tv) { panic!( "\n\ - Failed test №{}: {}\n\ - input:\t{:?}\n\ - output:\t{:?}\n", - i, desc, input, output, + Failed test #{i}:\n\ + reason:\t{reason}\n\ + test vector:\t{tv:?}\n" ); } } diff --git a/digest/src/dev/fixed.rs b/digest/src/dev/fixed.rs index 24f380112..ad57e7741 100644 --- a/digest/src/dev/fixed.rs +++ b/digest/src/dev/fixed.rs @@ -1,24 +1,22 @@ -use crate::{Digest, FixedOutput, FixedOutputReset, HashMarker, Update}; -use core::fmt::Debug; +use crate::{Digest, FixedOutput, FixedOutputReset, HashMarker, dev::TestVector}; /// Fixed-output resettable digest test via the `Digest` trait -pub fn fixed_reset_test(input: &[u8], output: &[u8]) -> Option<&'static str> -where - D: FixedOutputReset + Debug + Clone + Default + Update + HashMarker, -{ +pub fn fixed_reset_test( + &TestVector { input, output }: &TestVector, +) -> Result<(), &'static str> { let mut hasher = D::new(); // Test that it works when accepting the message all at once hasher.update(input); let mut hasher2 = hasher.clone(); if hasher.finalize()[..] != output[..] { - return Some("whole message"); + return Err("whole message"); } // Test if reset works correctly hasher2.reset(); hasher2.update(input); if hasher2.finalize_reset()[..] != output[..] { - return Some("whole message after reset"); + return Err("whole message after reset"); } // Test that it works when accepting the message in chunks @@ -29,26 +27,25 @@ where hasher2.update(chunk); } if hasher.finalize()[..] != output[..] { - return Some("message in chunks"); + return Err("message in chunks"); } if hasher2.finalize_reset()[..] != output[..] { - return Some("message in chunks"); + return Err("message in chunks"); } } - None + Ok(()) } /// Variable-output resettable digest test -pub fn fixed_test(input: &[u8], output: &[u8]) -> Option<&'static str> -where - D: FixedOutput + Default + Debug + Clone, -{ +pub fn fixed_test( + &TestVector { input, output }: &TestVector, +) -> Result<(), &'static str> { let mut hasher = D::default(); // Test that it works when accepting the message all at once hasher.update(input); if hasher.finalize_fixed()[..] != output[..] { - return Some("whole message"); + return Err("whole message"); } // Test that it works when accepting the message in chunks @@ -58,8 +55,8 @@ where hasher.update(chunk); } if hasher.finalize_fixed()[..] != output[..] { - return Some("message in chunks"); + return Err("message in chunks"); } } - None + Ok(()) } diff --git a/digest/src/dev/mac.rs b/digest/src/dev/mac.rs index 969a18b03..061a89e11 100644 --- a/digest/src/dev/mac.rs +++ b/digest/src/dev/mac.rs @@ -1,154 +1,149 @@ -/// Define MAC test -#[macro_export] -#[cfg(feature = "mac")] -macro_rules! new_mac_test { - ($name:ident, $test_name:expr, $mac:ty $(,)?) => { - digest::new_mac_test!($name, $test_name, $mac, ""); - }; - ($name:ident, $test_name:expr, $mac:ty, trunc_left $(,)?) => { - digest::new_mac_test!($name, $test_name, $mac, "left"); +use crate::{FixedOutputReset, Mac, crypto_common::KeyInit}; + +/// Tag truncation side used in MAC tests +#[derive(Clone, Copy, Debug)] +pub enum MacTruncSide { + /// Tag truncated from left (i.e. `tag[..n]`) + Left, + /// Tag truncated from right (i.e. `tag[n..]`) + Right, + /// Tag is not truncated + None, +} + +/// MAC test vector +#[derive(Debug, Clone, Copy)] +pub struct MacTestVector { + /// Initialization key + pub key: &'static [u8], + /// Input message + pub input: &'static [u8], + /// Output tag + pub tag: &'static [u8], +} + +/// Run MAC test +pub fn mac_test( + &MacTestVector { key, input, tag }: &MacTestVector, + trunc_side: MacTruncSide, +) -> Result<(), &'static str> { + let Ok(mac0) = ::new_from_slice(key) else { + return Err("Failed to initialize MAC instance"); }; - ($name:ident, $test_name:expr, $mac:ty, trunc_right $(,)?) => { - digest::new_mac_test!($name, $test_name, $mac, "right"); + + let mut mac = mac0.clone(); + mac.update(input); + let result = mac.finalize().into_bytes(); + let n = tag.len(); + let result_bytes = match trunc_side { + MacTruncSide::Left => &result[..n], + MacTruncSide::Right => &result[result.len() - n..], + MacTruncSide::None => &result[..], }; - ($name:ident, $test_name:expr, $mac:ty, $trunc:expr $(,)?) => { - #[test] - fn $name() { - use core::cmp::min; - use digest::dev::blobby::Blob3Iterator; - use digest::{KeyInit, Mac}; + if result_bytes != tag { + return Err("whole message"); + } - fn run_test(key: &[u8], input: &[u8], tag: &[u8]) -> Option<&'static str> { - let mac0 = <$mac as KeyInit>::new_from_slice(key).unwrap(); + // test reading different chunk sizes + for chunk_size in 1..core::cmp::min(64, input.len()) { + let mut mac = mac0.clone(); + for chunk in input.chunks(chunk_size) { + mac.update(chunk); + } + let res = match trunc_side { + MacTruncSide::Left => mac.verify_truncated_left(tag), + MacTruncSide::Right => mac.verify_truncated_right(tag), + MacTruncSide::None => mac.verify_slice(tag), + }; + if res.is_err() { + return Err("chunked message"); + } + } - let mut mac = mac0.clone(); - mac.update(input); - let result = mac.finalize().into_bytes(); - let n = tag.len(); - let result_bytes = match $trunc { - "left" => &result[..n], - "right" => &result[result.len() - n..], - _ => &result[..], - }; - if result_bytes != tag { - return Some("whole message"); - } + Ok(()) +} - // test reading different chunk sizes - for chunk_size in 1..min(64, input.len()) { - let mut mac = mac0.clone(); - for chunk in input.chunks(chunk_size) { - mac.update(chunk); - } - let res = match $trunc { - "left" => mac.verify_truncated_left(tag), - "right" => mac.verify_truncated_right(tag), - _ => mac.verify_slice(tag), - }; - if res.is_err() { - return Some("chunked message"); - } - } +/// Run resettable MAC test +pub fn reset_mac_test( + &MacTestVector { key, input, tag }: &MacTestVector, + trunc_side: MacTruncSide, +) -> Result<(), &'static str> { + let Ok(mac0) = ::new_from_slice(key) else { + return Err("Failed to initialize MAC instance"); + }; - None - } + let mut mac = mac0.clone(); + Mac::update(&mut mac, input); + let result = mac.finalize_reset().into_bytes(); + let n = tag.len(); + let result_bytes = match trunc_side { + MacTruncSide::Left => &result[..n], + MacTruncSide::Right => &result[result.len() - n..], + MacTruncSide::None => &result[..], + }; + if result_bytes != tag { + return Err("whole message"); + } - let data = include_bytes!(concat!("data/", $test_name, ".blb")); + // test if reset worked correctly + Mac::update(&mut mac, input); + let res = match trunc_side { + MacTruncSide::Left => mac.verify_truncated_left(tag), + MacTruncSide::Right => mac.verify_truncated_right(tag), + MacTruncSide::None => mac.verify_slice(tag), + }; + if res.is_err() { + return Err("after reset"); + } - for (i, row) in Blob3Iterator::new(data).unwrap().enumerate() { - let [key, input, tag] = row.unwrap(); - if let Some(desc) = run_test(key, input, tag) { - panic!( - "\n\ - Failed test №{}: {}\n\ - key:\t{:?}\n\ - input:\t{:?}\n\ - tag:\t{:?}\n", - i, desc, key, input, tag, - ); - } - } + // test reading different chunk sizes + for chunk_size in 1..core::cmp::min(64, input.len()) { + let mut mac = mac0.clone(); + for chunk in input.chunks(chunk_size) { + Mac::update(&mut mac, chunk); } - }; + let res = match trunc_side { + MacTruncSide::Left => mac.verify_truncated_left(tag), + MacTruncSide::Right => mac.verify_truncated_right(tag), + MacTruncSide::None => mac.verify_slice(tag), + }; + if res.is_err() { + return Err("chunked message"); + } + } + + Ok(()) } -/// Define resettable MAC test +/// Define MAC test #[macro_export] -#[cfg(feature = "mac")] -macro_rules! new_resettable_mac_test { - ($name:ident, $test_name:expr, $mac:ty $(,)?) => { - digest::new_resettable_mac_test!($name, $test_name, $mac, ""); +macro_rules! new_mac_test { + ($name:ident, $test_name:expr, $mac:ty, $test_fn:ident $(,)?) => { + digest::new_mac_test!($name, $test_name, $mac, $test_fn, $crate::dev::MacTruncSide::None); }; - ($name:ident, $test_name:expr, $mac:ty, trunc_left $(,)?) => { - digest::new_resettable_mac_test!($name, $test_name, $mac, "left"); + ($name:ident, $test_name:expr, $mac:ty, $test_fn:ident, trunc_left $(,)?) => { + digest::new_mac_test!($name, $test_name, $mac, $test_fn, $crate::dev::MacTruncSide::Left); }; - ($name:ident, $test_name:expr, $mac:ty, trunc_right $(,)?) => { - digest::new_resettable_mac_test!($name, $test_name, $mac, "right"); + ($name:ident, $test_name:expr, $mac:ty, $test_fn:ident, trunc_right $(,)?) => { + digest::new_mac_test!($name, $test_name, $mac, $test_fn, $crate::dev::MacTruncSide::Right); }; - ($name:ident, $test_name:expr, $mac:ty, $trunc:expr $(,)?) => { + ($name:ident, $test_name:expr, $mac:ty, $test_fn:ident, $trunc:expr $(,)?) => { #[test] fn $name() { - use core::cmp::min; - use digest::dev::blobby::Blob3Iterator; - use digest::{KeyInit, Mac}; - - fn run_test(key: &[u8], input: &[u8], tag: &[u8]) -> Option<&'static str> { - let mac0 = <$mac as KeyInit>::new_from_slice(key).unwrap(); - - let mut mac = mac0.clone(); - mac.update(input); - let result = mac.finalize_reset().into_bytes(); - let n = tag.len(); - let result_bytes = match $trunc { - "left" => &result[..n], - "right" => &result[result.len() - n..], - _ => &result[..], - }; - if result_bytes != tag { - return Some("whole message"); - } - - // test if reset worked correctly - mac.update(input); - let res = match $trunc { - "left" => mac.verify_truncated_left(tag), - "right" => mac.verify_truncated_right(tag), - _ => mac.verify_slice(tag), - }; - if res.is_err() { - return Some("after reset"); - } - - // test reading different chunk sizes - for chunk_size in 1..min(64, input.len()) { - let mut mac = mac0.clone(); - for chunk in input.chunks(chunk_size) { - mac.update(chunk); - } - let res = match $trunc { - "left" => mac.verify_truncated_left(tag), - "right" => mac.verify_truncated_right(tag), - _ => mac.verify_slice(tag), - }; - if res.is_err() { - return Some("chunked message"); - } - } - None - } + use digest::dev::MacTestVector; - let data = include_bytes!(concat!("data/", $test_name, ".blb")); + $crate::dev::blobby::parse_into_structs!( + include_bytes!(concat!("data/", $test_name, ".blb")); + static TEST_VECTORS: &[MacTestVector { key, input, tag }]; + ); - for (i, row) in Blob3Iterator::new(data).unwrap().enumerate() { - let [key, input, tag] = row.unwrap(); - if let Some(desc) = run_test(key, input, tag) { + for (i, tv) in TEST_VECTORS.iter().enumerate() { + if let Err(reason) = $test_fn::<$mac>(tv, $trunc) { panic!( "\n\ - Failed test №{}: {}\n\ - key:\t{:?}\n\ - input:\t{:?}\n\ - tag:\t{:?}\n", - i, desc, key, input, tag, + Failed test #{i}\n\ + reason:\t{reason:?}\n\ + test vector:\t{tv:?}\n" ); } } diff --git a/digest/src/dev/variable.rs b/digest/src/dev/variable.rs index ed8ff8828..aab77a38b 100644 --- a/digest/src/dev/variable.rs +++ b/digest/src/dev/variable.rs @@ -1,11 +1,9 @@ -use crate::{VariableOutput, VariableOutputReset}; -use core::fmt::Debug; +use crate::{VariableOutput, VariableOutputReset, dev::TestVector}; /// Variable-output resettable digest test -pub fn variable_reset_test(input: &[u8], output: &[u8]) -> Option<&'static str> -where - D: VariableOutputReset + Debug + Clone, -{ +pub fn variable_reset_test( + &TestVector { input, output }: &TestVector, +) -> Result<(), &'static str> { let mut hasher = D::new(output.len()).unwrap(); let mut buf = [0u8; 128]; let buf = &mut buf[..output.len()]; @@ -14,7 +12,7 @@ where let mut hasher2 = hasher.clone(); hasher.finalize_variable(buf).unwrap(); if buf != output { - return Some("whole message"); + return Err("whole message"); } buf.iter_mut().for_each(|b| *b = 0); @@ -23,7 +21,7 @@ where hasher2.update(input); hasher2.finalize_variable_reset(buf).unwrap(); if buf != output { - return Some("whole message after reset"); + return Err("whole message after reset"); } buf.iter_mut().for_each(|b| *b = 0); @@ -36,25 +34,24 @@ where } hasher.finalize_variable(buf).unwrap(); if buf != output { - return Some("message in chunks"); + return Err("message in chunks"); } buf.iter_mut().for_each(|b| *b = 0); hasher2.finalize_variable_reset(buf).unwrap(); if buf != output { - return Some("message in chunks"); + return Err("message in chunks"); } buf.iter_mut().for_each(|b| *b = 0); } - None + Ok(()) } /// Variable-output resettable digest test -pub fn variable_test(input: &[u8], output: &[u8]) -> Option<&'static str> -where - D: VariableOutput + Debug + Clone, -{ +pub fn variable_test( + &TestVector { input, output }: &TestVector, +) -> Result<(), &'static str> { let mut hasher = D::new(output.len()).unwrap(); let mut buf = [0u8; 128]; let buf = &mut buf[..output.len()]; @@ -62,7 +59,7 @@ where hasher.update(input); hasher.finalize_variable(buf).unwrap(); if buf != output { - return Some("whole message"); + return Err("whole message"); } buf.iter_mut().for_each(|b| *b = 0); @@ -74,9 +71,9 @@ where } hasher.finalize_variable(buf).unwrap(); if buf != output { - return Some("message in chunks"); + return Err("message in chunks"); } buf.iter_mut().for_each(|b| *b = 0); } - None + Ok(()) } diff --git a/digest/src/dev/xof.rs b/digest/src/dev/xof.rs index 9e5d07a09..acd4c8769 100644 --- a/digest/src/dev/xof.rs +++ b/digest/src/dev/xof.rs @@ -1,11 +1,10 @@ -use crate::ExtendableOutputReset; +use crate::{ExtendableOutputReset, dev::TestVector}; use core::fmt::Debug; /// Resettable XOF test -pub fn xof_reset_test(input: &[u8], output: &[u8]) -> Option<&'static str> -where - D: ExtendableOutputReset + Default + Debug + Clone, -{ +pub fn xof_reset_test( + &TestVector { input, output }: &TestVector, +) -> Result<(), &'static str> { let mut hasher = D::default(); let mut buf = [0u8; 1024]; let buf = &mut buf[..output.len()]; @@ -14,7 +13,7 @@ where let mut hasher2 = hasher.clone(); hasher.finalize_xof_into(buf); if buf != output { - return Some("whole message"); + return Err("whole message"); } buf.iter_mut().for_each(|b| *b = 0); @@ -23,7 +22,7 @@ where hasher2.update(input); hasher2.finalize_xof_reset_into(buf); if buf != output { - return Some("whole message after reset"); + return Err("whole message after reset"); } buf.iter_mut().for_each(|b| *b = 0); @@ -36,16 +35,16 @@ where } hasher.finalize_xof_into(buf); if buf != output { - return Some("message in chunks"); + return Err("message in chunks"); } buf.iter_mut().for_each(|b| *b = 0); hasher2.finalize_xof_reset_into(buf); if buf != output { - return Some("message in chunks"); + return Err("message in chunks"); } buf.iter_mut().for_each(|b| *b = 0); } - None + Ok(()) } From d0f8ceaf27d1356cab8c1833947885444c1a1793 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Aug 2025 13:53:16 +0300 Subject: [PATCH 1436/1461] Update Cargo.lock (#1955) --- Cargo.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 26902dbe3..21dd3f670 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -75,7 +75,7 @@ source = "git+https://github.com/RustCrypto/utils#1227836d92c56dce5fddb3ed360032 [[package]] name = "block-buffer" version = "0.11.0-rc.4" -source = "git+https://github.com/RustCrypto/utils.git#6fd0e8ddc827d7e7d9242e130f8944fc9ca328cf" +source = "git+https://github.com/RustCrypto/utils#6fd0e8ddc827d7e7d9242e130f8944fc9ca328cf" dependencies = [ "hybrid-array", "zeroize", @@ -170,9 +170,9 @@ dependencies = [ [[package]] name = "der" -version = "0.8.0-rc.7" +version = "0.8.0-rc.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2fe0a4fafae25053c19a03fefe040607bda956b4941d692ed9fb9d3c18a3193" +checksum = "7050e8041c28720851f7db83183195b6acf375bb7bb28e3b86f0fe6cbd69459d" dependencies = [ "const-oid", "pem-rfc7468", @@ -360,9 +360,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.174" +version = "0.2.175" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" +checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" [[package]] name = "memchr" From 037946fc548d797b7e5db9bc85563e6a15c9f08a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Aug 2025 13:53:55 +0300 Subject: [PATCH 1437/1461] build(deps): bump crate-ci/typos from 1.35.1 to 1.35.3 (#1956) --- .github/workflows/workspace.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index 2ac87f0a9..8192df46a 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -57,4 +57,4 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: crate-ci/typos@v1.35.1 + - uses: crate-ci/typos@v1.35.3 From 75413c9f776edaa3194e772d5f7286e549d6a96d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Aug 2025 14:00:03 +0300 Subject: [PATCH 1438/1461] build(deps): bump actions/checkout from 4 to 5 (#1957) --- .github/workflows/aead.yml | 4 ++-- .github/workflows/cipher.yml | 6 +++--- .github/workflows/crypto-common.yml | 4 ++-- .github/workflows/crypto.yml | 6 +++--- .github/workflows/digest.yml | 4 ++-- .github/workflows/elliptic-curve.yml | 10 +++++----- .github/workflows/kem.yml | 4 ++-- .github/workflows/password-hash.yml | 6 +++--- .github/workflows/security-audit.yml | 2 +- .github/workflows/signature.yml | 4 ++-- .github/workflows/universal-hash.yml | 4 ++-- .github/workflows/workspace.yml | 8 ++++---- 12 files changed, 31 insertions(+), 31 deletions(-) diff --git a/.github/workflows/aead.yml b/.github/workflows/aead.yml index 8f7d377ab..b5241969f 100644 --- a/.github/workflows/aead.yml +++ b/.github/workflows/aead.yml @@ -33,7 +33,7 @@ jobs: - thumbv7em-none-eabi - wasm32-unknown-unknown steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: @@ -60,7 +60,7 @@ jobs: - 1.85.0 # MSRV - stable steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: diff --git a/.github/workflows/cipher.yml b/.github/workflows/cipher.yml index 2db6cbc1e..23f51d0ae 100644 --- a/.github/workflows/cipher.yml +++ b/.github/workflows/cipher.yml @@ -34,7 +34,7 @@ jobs: - thumbv7em-none-eabi - wasm32-unknown-unknown steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: @@ -50,7 +50,7 @@ jobs: if: false # disabled until we stop using pre-releases runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@nightly - uses: RustCrypto/actions/cargo-hack-install@master @@ -66,7 +66,7 @@ jobs: - 1.85.0 # MSRV - stable steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: diff --git a/.github/workflows/crypto-common.yml b/.github/workflows/crypto-common.yml index c52dc75d6..3d93597ed 100644 --- a/.github/workflows/crypto-common.yml +++ b/.github/workflows/crypto-common.yml @@ -33,7 +33,7 @@ jobs: - thumbv7em-none-eabi - wasm32-unknown-unknown steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: @@ -54,7 +54,7 @@ jobs: - 1.85.0 # MSRV - stable steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: diff --git a/.github/workflows/crypto.yml b/.github/workflows/crypto.yml index 2a1a13f4d..88894e8f0 100644 --- a/.github/workflows/crypto.yml +++ b/.github/workflows/crypto.yml @@ -33,7 +33,7 @@ jobs: - thumbv7em-none-eabi - wasm32-unknown-unknown steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: @@ -47,7 +47,7 @@ jobs: if: false # disabled until we stop using pre-releases runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: @@ -64,7 +64,7 @@ jobs: - 1.85.0 # MSRV - stable steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: diff --git a/.github/workflows/digest.yml b/.github/workflows/digest.yml index ab16c4567..c6b67ea1a 100644 --- a/.github/workflows/digest.yml +++ b/.github/workflows/digest.yml @@ -33,7 +33,7 @@ jobs: - thumbv7em-none-eabi - wasm32-unknown-unknown steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: @@ -55,7 +55,7 @@ jobs: - 1.85.0 # MSRV - stable steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index d24a39903..6ebeb9a05 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -35,7 +35,7 @@ jobs: - thumbv7em-none-eabi - wasm32-unknown-unknown steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: @@ -64,7 +64,7 @@ jobs: if: false runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: @@ -82,7 +82,7 @@ jobs: - stable - nightly steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: @@ -95,7 +95,7 @@ jobs: test-careful: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: dtolnay/rust-toolchain@nightly - run: cargo install cargo-careful - run: cargo careful test --all-features @@ -105,7 +105,7 @@ jobs: env: MIRIFLAGS: "-Zmiri-symbolic-alignment-check -Zmiri-strict-provenance" steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: dtolnay/rust-toolchain@nightly - run: rustup component add miri && cargo miri setup - run: cargo miri test --all-features diff --git a/.github/workflows/kem.yml b/.github/workflows/kem.yml index 66204e807..6ca2b5b73 100644 --- a/.github/workflows/kem.yml +++ b/.github/workflows/kem.yml @@ -33,7 +33,7 @@ jobs: - thumbv7em-none-eabi - wasm32-unknown-unknown steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: @@ -49,7 +49,7 @@ jobs: - 1.85.0 # MSRV - stable steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: diff --git a/.github/workflows/password-hash.yml b/.github/workflows/password-hash.yml index f30026fe8..2b08a42e8 100644 --- a/.github/workflows/password-hash.yml +++ b/.github/workflows/password-hash.yml @@ -33,7 +33,7 @@ jobs: - thumbv7em-none-eabi - wasm32-unknown-unknown steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: @@ -49,7 +49,7 @@ jobs: if: false # disabled until we stop using pre-releases runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: @@ -66,7 +66,7 @@ jobs: - 1.85.0 # MSRV - stable steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: diff --git a/.github/workflows/security-audit.yml b/.github/workflows/security-audit.yml index 8c535dc00..d07cd6025 100644 --- a/.github/workflows/security-audit.yml +++ b/.github/workflows/security-audit.yml @@ -15,7 +15,7 @@ jobs: name: Security Audit Workspace runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Cache cargo bin uses: actions/cache@v4 with: diff --git a/.github/workflows/signature.yml b/.github/workflows/signature.yml index 7362c041c..8c067c1ec 100644 --- a/.github/workflows/signature.yml +++ b/.github/workflows/signature.yml @@ -34,7 +34,7 @@ jobs: - thumbv7em-none-eabi - wasm32-unknown-unknown steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: @@ -57,7 +57,7 @@ jobs: - 1.85.0 # Minimum Rust version the tests pass on - stable steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: diff --git a/.github/workflows/universal-hash.yml b/.github/workflows/universal-hash.yml index 6ee244acf..f5777667a 100644 --- a/.github/workflows/universal-hash.yml +++ b/.github/workflows/universal-hash.yml @@ -33,7 +33,7 @@ jobs: - thumbv7em-none-eabi - wasm32-unknown-unknown steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: @@ -55,7 +55,7 @@ jobs: - 1.85.0 # MSRV - stable steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index 8192df46a..f5eedd2b2 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -25,7 +25,7 @@ jobs: clippy: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: @@ -36,7 +36,7 @@ jobs: doc: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: dtolnay/rust-toolchain@master with: toolchain: stable @@ -46,7 +46,7 @@ jobs: rustfmt: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: dtolnay/rust-toolchain@master with: toolchain: stable @@ -56,5 +56,5 @@ jobs: typos: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: crate-ci/typos@v1.35.3 From 7bbc010a76ef459a04c696ac9f4e6694a776fe7e Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Wed, 13 Aug 2025 13:43:22 +0300 Subject: [PATCH 1439/1461] digest: improve implementations of the `SerializableState` trait (#1953) Previously we were using block size + 1 byte to serialize eager block buffers while block size is sufficient. It resulted in odd serialization state sizes. The `SerializableState` impl also a bit convoluted. The new implementation results in more efficient serialization and more straightforward code. The main drawback is that it inevitably involves a breaking change in the serialization format. --- Cargo.lock | 12 ++--- Cargo.toml | 1 + digest/CHANGELOG.md | 2 + digest/src/block_api/ct_variable.rs | 38 +++---------- digest/src/buffer_macros/fixed.rs | 40 +++++--------- digest/src/buffer_macros/variable_ct.rs | 50 +++++------------- digest/src/buffer_macros/xof.rs | 40 +++++--------- digest/src/dev.rs | 5 +- .../tests/data/fixed_hash_serialization.bin | Bin 0 -> 16 bytes digest/tests/dummy_fixed.rs | 3 ++ 10 files changed, 60 insertions(+), 131 deletions(-) create mode 100644 digest/tests/data/fixed_hash_serialization.bin diff --git a/Cargo.lock b/Cargo.lock index 21dd3f670..de2cf1a0b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -70,12 +70,12 @@ dependencies = [ [[package]] name = "blobby" version = "0.4.0-pre.0" -source = "git+https://github.com/RustCrypto/utils#1227836d92c56dce5fddb3ed36003277f053267b" +source = "git+https://github.com/RustCrypto/utils#f5ac85f6aa02aa39614f62a6a1add9468be67892" [[package]] name = "block-buffer" version = "0.11.0-rc.4" -source = "git+https://github.com/RustCrypto/utils#6fd0e8ddc827d7e7d9242e130f8944fc9ca328cf" +source = "git+https://github.com/RustCrypto/utils#f5ac85f6aa02aa39614f62a6a1add9468be67892" dependencies = [ "hybrid-array", "zeroize", @@ -429,9 +429,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.95" +version = "1.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +checksum = "beef09f85ae72cea1ef96ba6870c51e6382ebfa4f0e85b643459331f3daa5be0" dependencies = [ "unicode-ident", ] @@ -508,9 +508,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.141" +version = "1.0.142" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30b9eff21ebe718216c6ec64e1d9ac57087aad11efc64e32002bce4a0d4c03d3" +checksum = "030fedb782600dcbd6f02d479bf0d817ac3bb40d644745b769d6a96bc3afc5a7" dependencies = [ "itoa", "memchr", diff --git a/Cargo.toml b/Cargo.toml index f3ed415c2..7f57fc98b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,4 +20,5 @@ signature = { path = "signature" } # https://github.com/RustCrypto/utils/pull/1187 blobby = { git = "https://github.com/RustCrypto/utils" } # https://github.com/RustCrypto/utils/pull/1192 +# https://github.com/RustCrypto/utils/pull/1200 block-buffer = { git = "https://github.com/RustCrypto/utils" } diff --git a/digest/CHANGELOG.md b/digest/CHANGELOG.md index a4fe6b64a..c483c46b2 100644 --- a/digest/CHANGELOG.md +++ b/digest/CHANGELOG.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Edition changed to 2024 and MSRV bumped to 1.85 ([#1759]) - `CtVariableCoreWrapper` renamed to `CtOutWrapper` ([#1799]) - Removed the OID type parameter from `CtOutWrapper` ([#1799]) +- Implementations of the `SerializableState` trait ([#1953]) ### Removed - `Mac::new`, `Mac::new_from_slice`, and `Mac::generate_key` methods ([#1173]) @@ -29,6 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [#1799]: https://github.com/RustCrypto/traits/pull/1799 [#1809]: https://github.com/RustCrypto/traits/pull/1809 [#1820]: https://github.com/RustCrypto/traits/pull/1820 +[#1953]: https://github.com/RustCrypto/traits/pull/1953 ## 0.10.7 (2023-05-19) ### Changed diff --git a/digest/src/block_api/ct_variable.rs b/digest/src/block_api/ct_variable.rs index 775dd3c34..0e6459932 100644 --- a/digest/src/block_api/ct_variable.rs +++ b/digest/src/block_api/ct_variable.rs @@ -5,16 +5,12 @@ use super::{ #[cfg(feature = "mac")] use crate::MacMarker; use crate::{CollisionResistance, CustomizedInit, HashMarker, VarOutputCustomized}; -use core::{ - fmt, - marker::PhantomData, - ops::{Add, Sub}, -}; +use core::{fmt, marker::PhantomData}; use crypto_common::{ Block, BlockSizeUser, OutputSizeUser, array::{Array, ArraySize}, - hazmat::{DeserializeStateError, SerializableState, SerializedState, SubSerializedStateSize}, - typenum::{IsLess, IsLessOrEqual, Le, NonZero, Sum, True, U1, U256}, + hazmat::{DeserializeStateError, SerializableState, SerializedState}, + typenum::{IsLessOrEqual, True}, }; /// Wrapper around [`VariableOutputCore`] which selects output size at compile time. @@ -177,41 +173,21 @@ where } } -type CtVariableCoreWrapperSerializedStateSize = - Sum<::SerializedStateSize, U1>; - impl SerializableState for CtOutWrapper where T: VariableOutputCore + SerializableState, OutSize: ArraySize + IsLessOrEqual, - T::BlockSize: IsLess, - Le: NonZero, - T::SerializedStateSize: Add, - CtVariableCoreWrapperSerializedStateSize: Sub + ArraySize, - SubSerializedStateSize, T>: ArraySize, { - type SerializedStateSize = CtVariableCoreWrapperSerializedStateSize; + type SerializedStateSize = ::SerializedStateSize; fn serialize(&self) -> SerializedState { - let serialized_inner = self.inner.serialize(); - let serialized_outsize = Array([OutSize::U8]); - - serialized_inner.concat(serialized_outsize) + self.inner.serialize() } fn deserialize( serialized_state: &SerializedState, ) -> Result { - let (serialized_inner, serialized_outsize) = - serialized_state.split_ref::(); - - if serialized_outsize[0] != OutSize::U8 { - return Err(DeserializeStateError); - } - - Ok(Self { - inner: T::deserialize(serialized_inner)?, - _out: PhantomData, - }) + let _out = PhantomData; + T::deserialize(serialized_state).map(|inner| Self { inner, _out }) } } diff --git a/digest/src/buffer_macros/fixed.rs b/digest/src/buffer_macros/fixed.rs index f1e73b641..407581bb3 100644 --- a/digest/src/buffer_macros/fixed.rs +++ b/digest/src/buffer_macros/fixed.rs @@ -429,49 +429,33 @@ macro_rules! buffer_fixed { impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::crypto_common::hazmat::SerializableState for $name$(< $( $lt ),+ >)? { type SerializedStateSize = $crate::typenum::Sum< <$core_ty as $crate::crypto_common::hazmat::SerializableState>::SerializedStateSize, - $crate::typenum::Add1< - <$core_ty as $crate::block_api::BlockSizeUser>::BlockSize + $crate::block_buffer::SerializedBufferSize< + <$core_ty as $crate::block_api::BlockSizeUser>::BlockSize, + <$core_ty as $crate::block_api::BufferKindUser>::BufferKind, > >; #[inline] fn serialize(&self) -> $crate::crypto_common::hazmat::SerializedState { - use $crate::{ - array::Array, - consts::U1, - block_buffer::BlockBuffer, - crypto_common::hazmat::SerializableState, - }; - let serialized_core = self.core.serialize(); - let pos = u8::try_from(self.buffer.get_pos()).unwrap(); - let serialized_pos: Array = Array([pos]); - let serialized_data = self.buffer.clone().pad_with_zeros(); - - serialized_core - .concat(serialized_pos) - .concat(serialized_data) + let serialized_buf = self.buffer.serialize(); + serialized_core.concat(serialized_buf) } #[inline] fn deserialize( serialized_state: &$crate::crypto_common::hazmat::SerializedState, ) -> Result { - use $crate::{ - block_buffer::BlockBuffer, - consts::U1, - crypto_common::hazmat::{SerializableState, DeserializeStateError}, - }; + use $crate::crypto_common::hazmat::{SerializableState, DeserializeStateError}; - let (serialized_core, remaining_buffer) = serialized_state + let (serialized_core, serialized_buf) = serialized_state .split_ref::<<$core_ty as SerializableState>::SerializedStateSize>(); - let (serialized_pos, serialized_data) = remaining_buffer.split_ref::(); - Ok(Self { - core: <$core_ty as SerializableState>::deserialize(serialized_core)?, - buffer: BlockBuffer::try_new(&serialized_data[..serialized_pos[0].into()]) - .map_err(|_| DeserializeStateError)?, - }) + let core = SerializableState::deserialize(serialized_core)?; + let buffer = $crate::block_buffer::BlockBuffer::deserialize(serialized_buf) + .map_err(|_| DeserializeStateError)?; + + Ok(Self { core, buffer }) } } diff --git a/digest/src/buffer_macros/variable_ct.rs b/digest/src/buffer_macros/variable_ct.rs index a767a1ca0..b02b69a57 100644 --- a/digest/src/buffer_macros/variable_ct.rs +++ b/digest/src/buffer_macros/variable_ct.rs @@ -176,54 +176,32 @@ macro_rules! buffer_ct_variable { where $out_size: $crate::array::ArraySize + $crate::typenum::IsLessOrEqual<$max_size, Output = $crate::typenum::True>, { - type SerializedStateSize = $crate::typenum::Add1<$crate::typenum::Sum< - < - $crate::block_api::CtOutWrapper<$core_ty, $out_size> - as $crate::crypto_common::hazmat::SerializableState - >::SerializedStateSize, - <$core_ty as $crate::block_api::BlockSizeUser>::BlockSize, - >>; + type SerializedStateSize = $crate::typenum::Sum< + <$core_ty as $crate::crypto_common::hazmat::SerializableState>::SerializedStateSize, + $crate::block_buffer::SerializedBufferSize< + <$core_ty as $crate::block_api::BlockSizeUser>::BlockSize, + <$core_ty as $crate::block_api::BufferKindUser>::BufferKind, + > + >; #[inline] fn serialize(&self) -> $crate::crypto_common::hazmat::SerializedState { - use $crate::{ - array::Array, - consts::U1, - block_buffer::BlockBuffer, - crypto_common::hazmat::SerializableState, - }; - let serialized_core = self.core.serialize(); - let pos = u8::try_from(self.buffer.get_pos()).unwrap(); - let serialized_pos: Array = Array([pos]); - let serialized_data = self.buffer.clone().pad_with_zeros(); - - serialized_core - .concat(serialized_pos) - .concat(serialized_data) + let serialized_buf = self.buffer.serialize(); + serialized_core.concat(serialized_buf) } #[inline] fn deserialize( serialized_state: &$crate::crypto_common::hazmat::SerializedState, ) -> Result { - use $crate::{ - block_buffer::BlockBuffer, - consts::U1, - block_api::CtOutWrapper, - crypto_common::hazmat::{SerializableState, DeserializeStateError}, - }; - - let (serialized_core, remaining_buffer) = serialized_state - .split_ref::<< - CtOutWrapper<$core_ty, $out_size> - as SerializableState - >::SerializedStateSize>(); - let (serialized_pos, serialized_data) = remaining_buffer.split_ref::(); + use $crate::crypto_common::hazmat::{SerializableState, DeserializeStateError}; + + let (serialized_core, serialized_buf) = serialized_state + .split_ref::<<$core_ty as SerializableState>::SerializedStateSize>(); let core = SerializableState::deserialize(serialized_core)?; - let pos = usize::from(serialized_pos[0]); - let buffer = BlockBuffer::try_new(&serialized_data[..pos]) + let buffer = $crate::block_buffer::BlockBuffer::deserialize(serialized_buf) .map_err(|_| DeserializeStateError)?; Ok(Self { core, buffer }) diff --git a/digest/src/buffer_macros/xof.rs b/digest/src/buffer_macros/xof.rs index 8687c18b4..c8cbe72c7 100644 --- a/digest/src/buffer_macros/xof.rs +++ b/digest/src/buffer_macros/xof.rs @@ -284,49 +284,33 @@ macro_rules! buffer_xof { impl $crate::crypto_common::hazmat::SerializableState for $name { type SerializedStateSize = $crate::typenum::Sum< <$core_ty as $crate::crypto_common::hazmat::SerializableState>::SerializedStateSize, - $crate::typenum::Add1< - <$core_ty as $crate::block_api::BlockSizeUser>::BlockSize + $crate::block_buffer::SerializedBufferSize< + <$core_ty as $crate::block_api::BlockSizeUser>::BlockSize, + <$core_ty as $crate::block_api::BufferKindUser>::BufferKind, > >; #[inline] fn serialize(&self) -> $crate::crypto_common::hazmat::SerializedState { - use $crate::{ - array::Array, - consts::U1, - block_buffer::BlockBuffer, - crypto_common::hazmat::SerializableState, - }; - let serialized_core = self.core.serialize(); - let pos = u8::try_from(self.buffer.get_pos()).unwrap(); - let serialized_pos: Array = Array([pos]); - let serialized_data = self.buffer.clone().pad_with_zeros(); - - serialized_core - .concat(serialized_pos) - .concat(serialized_data) + let serialized_buf = self.buffer.serialize(); + serialized_core.concat(serialized_buf) } #[inline] fn deserialize( serialized_state: &$crate::crypto_common::hazmat::SerializedState, ) -> Result { - use $crate::{ - block_buffer::BlockBuffer, - consts::U1, - crypto_common::hazmat::{SerializableState, DeserializeStateError}, - }; + use $crate::crypto_common::hazmat::{SerializableState, DeserializeStateError}; - let (serialized_core, remaining_buffer) = serialized_state + let (serialized_core, serialized_buf) = serialized_state .split_ref::<<$core_ty as SerializableState>::SerializedStateSize>(); - let (serialized_pos, serialized_data) = remaining_buffer.split_ref::(); - Ok(Self { - core: <$core_ty as SerializableState>::deserialize(serialized_core)?, - buffer: BlockBuffer::try_new(&serialized_data[..serialized_pos[0].into()]) - .map_err(|_| DeserializeStateError)?, - }) + let core = SerializableState::deserialize(serialized_core)?; + let buffer = $crate::block_buffer::BlockBuffer::deserialize(serialized_buf) + .map_err(|_| DeserializeStateError)?; + + Ok(Self { core, buffer }) } } diff --git a/digest/src/dev.rs b/digest/src/dev.rs index e7e4d0a23..abc174f96 100644 --- a/digest/src/dev.rs +++ b/digest/src/dev.rs @@ -54,7 +54,7 @@ macro_rules! new_test { /// Define hash function serialization test #[macro_export] macro_rules! hash_serialization_test { - ($name:ident, $hasher:ty, $expected_serialized_state:expr) => { + ($name:ident, $hasher:ty $(,)?) => { #[test] fn $name() { use digest::{ @@ -68,7 +68,8 @@ macro_rules! hash_serialization_test { h.update(&[0x13; <$hasher as BlockSizeUser>::BlockSize::USIZE + 1]); let serialized_state = h.serialize(); - assert_eq!(serialized_state.as_slice(), $expected_serialized_state); + let expected = include_bytes!(concat!("data/", stringify!($name), ".bin")); + assert_eq!(serialized_state.as_slice(), expected); let mut h = <$hasher>::deserialize(&serialized_state).unwrap(); diff --git a/digest/tests/data/fixed_hash_serialization.bin b/digest/tests/data/fixed_hash_serialization.bin new file mode 100644 index 0000000000000000000000000000000000000000..2a034968a1c142c68888ae9fbf5600cd01a655a4 GIT binary patch literal 16 PcmWd@h5$xk1~32s2nhhK literal 0 HcmV?d00001 diff --git a/digest/tests/dummy_fixed.rs b/digest/tests/dummy_fixed.rs index cce734f59..e66b430a0 100644 --- a/digest/tests/dummy_fixed.rs +++ b/digest/tests/dummy_fixed.rs @@ -111,6 +111,9 @@ digest::buffer_fixed!( impl: FixedHashTraits; ); +#[cfg(feature = "dev")] +digest::hash_serialization_test!(fixed_hash_serialization, FixedHashWithSer,); + #[cfg(feature = "zeroize")] /// check for `ZeroizeOnDrop` implementations const _: () = { From 441824ae3d55d55f15c7bccd6a254b2aacba2c4a Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Wed, 13 Aug 2025 15:02:48 +0300 Subject: [PATCH 1440/1461] digest: simplify test macros using `stringify!` (#1958) Names of test functions and names of associated KAT file usually match, so it's worth to simplify the macro to reduce amount of duplication at call sites. --- digest/CHANGELOG.md | 2 ++ digest/src/dev.rs | 4 ++-- digest/src/dev/mac.rs | 16 ++++++++-------- digest/src/dev/rng.rs | 2 +- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/digest/CHANGELOG.md b/digest/CHANGELOG.md index c483c46b2..5e2f14e17 100644 --- a/digest/CHANGELOG.md +++ b/digest/CHANGELOG.md @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `CtVariableCoreWrapper` renamed to `CtOutWrapper` ([#1799]) - Removed the OID type parameter from `CtOutWrapper` ([#1799]) - Implementations of the `SerializableState` trait ([#1953]) +- `new_test!` and `new_mac_test!` macros ([#1958]) ### Removed - `Mac::new`, `Mac::new_from_slice`, and `Mac::generate_key` methods ([#1173]) @@ -31,6 +32,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [#1809]: https://github.com/RustCrypto/traits/pull/1809 [#1820]: https://github.com/RustCrypto/traits/pull/1820 [#1953]: https://github.com/RustCrypto/traits/pull/1953 +[#1958]: https://github.com/RustCrypto/traits/pull/1958 ## 0.10.7 (2023-05-19) ### Changed diff --git a/digest/src/dev.rs b/digest/src/dev.rs index abc174f96..da08409d5 100644 --- a/digest/src/dev.rs +++ b/digest/src/dev.rs @@ -27,13 +27,13 @@ pub struct TestVector { /// Define hash function test #[macro_export] macro_rules! new_test { - ($name:ident, $test_name:expr, $hasher:ty, $test_fn:ident $(,)?) => { + ($name:ident, $hasher:ty, $test_fn:ident $(,)?) => { #[test] fn $name() { use $crate::dev::TestVector; $crate::dev::blobby::parse_into_structs!( - include_bytes!(concat!("data/", $test_name, ".blb")); + include_bytes!(concat!("data/", stringify!($name), ".blb")); static TEST_VECTORS: &[TestVector { input, output }]; ); diff --git a/digest/src/dev/mac.rs b/digest/src/dev/mac.rs index 061a89e11..f33a0bb66 100644 --- a/digest/src/dev/mac.rs +++ b/digest/src/dev/mac.rs @@ -118,22 +118,22 @@ pub fn reset_mac_test( /// Define MAC test #[macro_export] macro_rules! new_mac_test { - ($name:ident, $test_name:expr, $mac:ty, $test_fn:ident $(,)?) => { - digest::new_mac_test!($name, $test_name, $mac, $test_fn, $crate::dev::MacTruncSide::None); + ($name:ident, $mac:ty, $test_fn:ident $(,)?) => { + digest::new_mac_test!($name, $mac, $test_fn, $crate::dev::MacTruncSide::None); }; - ($name:ident, $test_name:expr, $mac:ty, $test_fn:ident, trunc_left $(,)?) => { - digest::new_mac_test!($name, $test_name, $mac, $test_fn, $crate::dev::MacTruncSide::Left); + ($name:ident, $mac:ty, $test_fn:ident, trunc_left $(,)?) => { + digest::new_mac_test!($name, $mac, $test_fn, $crate::dev::MacTruncSide::Left); }; - ($name:ident, $test_name:expr, $mac:ty, $test_fn:ident, trunc_right $(,)?) => { - digest::new_mac_test!($name, $test_name, $mac, $test_fn, $crate::dev::MacTruncSide::Right); + ($name:ident, $mac:ty, $test_fn:ident, trunc_right $(,)?) => { + digest::new_mac_test!($name, $mac, $test_fn, $crate::dev::MacTruncSide::Right); }; - ($name:ident, $test_name:expr, $mac:ty, $test_fn:ident, $trunc:expr $(,)?) => { + ($name:ident, $mac:ty, $test_fn:ident, $trunc:expr $(,)?) => { #[test] fn $name() { use digest::dev::MacTestVector; $crate::dev::blobby::parse_into_structs!( - include_bytes!(concat!("data/", $test_name, ".blb")); + include_bytes!(concat!("data/", stringify!($name), ".blb")); static TEST_VECTORS: &[MacTestVector { key, input, tag }]; ); diff --git a/digest/src/dev/rng.rs b/digest/src/dev/rng.rs index d34a1cf31..038a6f6ee 100644 --- a/digest/src/dev/rng.rs +++ b/digest/src/dev/rng.rs @@ -10,7 +10,7 @@ pub(crate) const RNG: XorShiftRng = XorShiftRng { w: Wrapping(0xB0AD_B4F3), }; -/// Xorshift RNG instance/ +/// Xorshift RNG instance pub(crate) struct XorShiftRng { x: Wrapping, y: Wrapping, From 079b4ab4743d835aa5acebd038856a83cc13dcdc Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Fri, 15 Aug 2025 04:44:37 +0300 Subject: [PATCH 1441/1461] cipher: use `block_buffer::ReadBuffer` in `StreamCipherCoreWrapper` (#1959) This simplifies the wrapper code and allows to mark the `cipher` crate with `#![forbid(unsafe_code)]`. --- Cargo.lock | 7 +- Cargo.toml | 3 +- cipher/Cargo.toml | 4 +- cipher/src/dev/stream.rs | 4 +- cipher/src/lib.rs | 1 + cipher/src/stream.rs | 2 + cipher/src/stream/wrapper.rs | 223 ++++++++--------------------------- 7 files changed, 63 insertions(+), 181 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index de2cf1a0b..91d3a73b3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -75,7 +75,7 @@ source = "git+https://github.com/RustCrypto/utils#f5ac85f6aa02aa39614f62a6a1add9 [[package]] name = "block-buffer" version = "0.11.0-rc.4" -source = "git+https://github.com/RustCrypto/utils#f5ac85f6aa02aa39614f62a6a1add9468be67892" +source = "git+https://github.com/RustCrypto/utils?branch=block-buffer%2Fread-buf#79e12dfd745e732d24ba1566f705f35ba409edc6" dependencies = [ "hybrid-array", "zeroize", @@ -113,6 +113,7 @@ name = "cipher" version = "0.5.0-rc.0" dependencies = [ "blobby", + "block-buffer", "crypto-common", "inout", "zeroize", @@ -429,9 +430,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.96" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "beef09f85ae72cea1ef96ba6870c51e6382ebfa4f0e85b643459331f3daa5be0" +checksum = "d61789d7719defeb74ea5fe81f2fdfdbd28a803847077cecce2ff14e1472f6f1" dependencies = [ "unicode-ident", ] diff --git a/Cargo.toml b/Cargo.toml index 7f57fc98b..63c918333 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,4 +21,5 @@ signature = { path = "signature" } blobby = { git = "https://github.com/RustCrypto/utils" } # https://github.com/RustCrypto/utils/pull/1192 # https://github.com/RustCrypto/utils/pull/1200 -block-buffer = { git = "https://github.com/RustCrypto/utils" } +# https://github.com/RustCrypto/utils/pull/1201 +block-buffer = { git = "https://github.com/RustCrypto/utils", branch = "block-buffer/read-buf" } diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index 393703371..ac7cedecb 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -18,16 +18,18 @@ inout = "0.2.0-rc.4" # optional dependencies blobby = { version = "0.4.0-pre.0", optional = true } +block-buffer = { version = "0.11.0-rc.4", optional = true} zeroize = { version = "1.8", optional = true, default-features = false } [features] alloc = [] block-padding = ["inout/block-padding"] +stream-wrapper = ["block-buffer"] # Enable random key and IV generation methods rand_core = ["crypto-common/rand_core"] os_rng = ["crypto-common/os_rng", "rand_core"] dev = ["blobby"] -zeroize = ["dep:zeroize", "crypto-common/zeroize"] +zeroize = ["dep:zeroize", "crypto-common/zeroize", "block-buffer?/zeroize"] [package.metadata.docs.rs] all-features = true diff --git a/cipher/src/dev/stream.rs b/cipher/src/dev/stream.rs index 00dc14f54..50e13b28f 100644 --- a/cipher/src/dev/stream.rs +++ b/cipher/src/dev/stream.rs @@ -57,8 +57,8 @@ macro_rules! stream_cipher_test { ); for (i, tv) in TEST_VECTORS.iter().enumerate() { - let res = $crate::dev::stream::stream_cipher_test(tv); - if Err(reason) = res { + let res = $crate::dev::stream::stream_cipher_test::<$cipher>(tv); + if let Err(reason) = res { panic!( "\n\ Failed test #{i}\n\ diff --git a/cipher/src/lib.rs b/cipher/src/lib.rs index 009a8b8a9..af95d9fc7 100644 --- a/cipher/src/lib.rs +++ b/cipher/src/lib.rs @@ -17,6 +17,7 @@ unused_lifetimes, missing_debug_implementations )] +#![forbid(unsafe_code)] #[cfg(feature = "alloc")] extern crate alloc; diff --git a/cipher/src/stream.rs b/cipher/src/stream.rs index a1ba34347..f6169595d 100644 --- a/cipher/src/stream.rs +++ b/cipher/src/stream.rs @@ -9,6 +9,7 @@ use inout::{InOutBuf, NotEqualError}; mod core_api; mod errors; +#[cfg(feature = "stream-wrapper")] mod wrapper; pub use core_api::{ @@ -16,6 +17,7 @@ pub use core_api::{ StreamCipherSeekCore, }; pub use errors::{OverflowError, StreamCipherError}; +#[cfg(feature = "stream-wrapper")] pub use wrapper::StreamCipherCoreWrapper; /// Marker trait for block-level asynchronous stream ciphers diff --git a/cipher/src/stream/wrapper.rs b/cipher/src/stream/wrapper.rs index 3dbc7e1b5..5789cdddd 100644 --- a/cipher/src/stream/wrapper.rs +++ b/cipher/src/stream/wrapper.rs @@ -1,29 +1,22 @@ use super::{ - Block, OverflowError, SeekNum, StreamCipher, StreamCipherCore, StreamCipherSeek, - StreamCipherSeekCore, errors::StreamCipherError, + OverflowError, SeekNum, StreamCipher, StreamCipherCore, StreamCipherSeek, StreamCipherSeekCore, + errors::StreamCipherError, }; +use block_buffer::ReadBuffer; use core::fmt; use crypto_common::{ Iv, IvSizeUser, Key, KeyInit, KeyIvInit, KeySizeUser, array::Array, typenum::Unsigned, }; use inout::InOutBuf; #[cfg(feature = "zeroize")] -use zeroize::{Zeroize, ZeroizeOnDrop}; +use zeroize::ZeroizeOnDrop; /// Buffering wrapper around a [`StreamCipherCore`] implementation. /// /// It handles data buffering and implements the slice-based traits. pub struct StreamCipherCoreWrapper { core: T, - // First byte is used as position - buffer: Block, -} - -impl Default for StreamCipherCoreWrapper { - #[inline] - fn default() -> Self { - Self::from_core(T::default()) - } + buffer: ReadBuffer, } impl Clone for StreamCipherCoreWrapper { @@ -38,70 +31,19 @@ impl Clone for StreamCipherCoreWrapper { impl fmt::Debug for StreamCipherCoreWrapper { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let pos = self.get_pos().into(); - let buf_data = &self.buffer[pos..]; f.debug_struct("StreamCipherCoreWrapper") - .field("core", &self.core) - .field("buffer_data", &buf_data) - .finish() + .finish_non_exhaustive() } } impl StreamCipherCoreWrapper { - /// Return reference to the core type. - pub fn get_core(&self) -> &T { - &self.core - } - - /// Return reference to the core type. - pub fn from_core(core: T) -> Self { - let mut buffer: Block = Default::default(); - buffer[0] = T::BlockSize::U8; - Self { core, buffer } - } - - /// Return current cursor position. - #[inline] - fn get_pos(&self) -> u8 { - let pos = self.buffer[0]; - if pos == 0 || pos > T::BlockSize::U8 { - debug_assert!(false); - // SAFETY: `pos` never breaks the invariant - unsafe { - core::hint::unreachable_unchecked(); - } - } - pos - } - - /// Set buffer position without checking that it's smaller - /// than buffer size. - /// - /// # Safety - /// `pos` MUST be bigger than zero and smaller or equal to `T::BlockSize::USIZE`. - #[inline] - unsafe fn set_pos_unchecked(&mut self, pos: usize) { - debug_assert!(pos != 0 && pos <= T::BlockSize::USIZE); - // Block size is always smaller than 256 because of the `BlockSizes` bound, - // so if the safety condition is satisfied, the `as` cast does not truncate - // any non-zero bits. - self.buffer[0] = pos as u8; - } - - /// Return number of remaining bytes in the internal buffer. - #[inline] - fn remaining(&self) -> u8 { - // This never underflows because of the safety invariant - T::BlockSize::U8 - self.get_pos() - } - fn check_remaining(&self, data_len: usize) -> Result<(), StreamCipherError> { let rem_blocks = match self.core.remaining_blocks() { Some(v) => v, None => return Ok(()), }; - let buf_rem = usize::from(self.remaining()); + let buf_rem = self.buffer.remaining(); let data_len = match data_len.checked_sub(buf_rem) { Some(0) | None => return Ok(()), Some(res) => res, @@ -121,106 +63,46 @@ impl StreamCipher for StreamCipherCoreWrapper { #[inline] fn try_apply_keystream_inout( &mut self, - mut data: InOutBuf<'_, '_, u8>, + data: InOutBuf<'_, '_, u8>, ) -> Result<(), StreamCipherError> { self.check_remaining(data.len())?; - let pos = usize::from(self.get_pos()); - let rem = usize::from(self.remaining()); - let data_len = data.len(); - - if rem != 0 { - if data_len <= rem { - data.xor_in2out(&self.buffer[pos..][..data_len]); - // SAFETY: we have checked that `data_len` is less or equal to length - // of remaining keystream data, thus `pos + data_len` can not be bigger - // than block size. Since `pos` is never zero, `pos + data_len` can not - // be zero. Thus `pos + data_len` satisfies the safety invariant required - // by `set_pos_unchecked`. - unsafe { - self.set_pos_unchecked(pos + data_len); - } - return Ok(()); - } - let (mut left, right) = data.split_at(rem); - data = right; - left.xor_in2out(&self.buffer[pos..]); - } + let head_ks = self.buffer.read_cached(data.len()); + let (mut head, data) = data.split_at(head_ks.len()); let (blocks, mut tail) = data.into_chunks(); - self.core.apply_keystream_blocks_inout(blocks); - let new_pos = if tail.is_empty() { - T::BlockSize::USIZE - } else { - // Note that we temporarily write a pseudo-random byte into - // the first byte of `self.buffer`. It may break the safety invariant, - // but after XORing keystream block with `tail`, we immediately - // overwrite the first byte with a correct value. - self.core.write_keystream_block(&mut self.buffer); - tail.xor_in2out(&self.buffer[..tail.len()]); - tail.len() - }; + head.xor_in2out(head_ks); + self.core.apply_keystream_blocks_inout(blocks); - // SAFETY: `into_chunks` always returns tail with size - // less than block size. If `tail.len()` is zero, we replace - // it with block size. Thus the invariant required by - // `set_pos_unchecked` is satisfied. - unsafe { - self.set_pos_unchecked(new_pos); - } + self.buffer.write_block( + tail.len(), + |b| self.core.write_keystream_block(b), + |tail_ks| { + tail.xor_in2out(tail_ks); + }, + ); Ok(()) } #[inline] - fn try_write_keystream(&mut self, mut data: &mut [u8]) -> Result<(), StreamCipherError> { + fn try_write_keystream(&mut self, data: &mut [u8]) -> Result<(), StreamCipherError> { self.check_remaining(data.len())?; - let pos = usize::from(self.get_pos()); - let rem = usize::from(self.remaining()); - let data_len = data.len(); - - if rem != 0 { - if data_len <= rem { - data.copy_from_slice(&self.buffer[pos..][..data_len]); - // SAFETY: we have checked that `data_len` is less or equal to length - // of remaining keystream data, thus `pos + data_len` can not be bigger - // than block size. Since `pos` is never zero, `pos + data_len` can not - // be zero. Thus `pos + data_len` satisfies the safety invariant required - // by `set_pos_unchecked`. - unsafe { - self.set_pos_unchecked(pos + data_len); - } - return Ok(()); - } - let (left, right) = data.split_at_mut(rem); - data = right; - left.copy_from_slice(&self.buffer[pos..]); - } + let head_ks = self.buffer.read_cached(data.len()); + let (head, data) = data.split_at_mut(head_ks.len()); let (blocks, tail) = Array::slice_as_chunks_mut(data); - self.core.write_keystream_blocks(blocks); - let new_pos = if tail.is_empty() { - T::BlockSize::USIZE - } else { - // Note that we temporarily write a pseudo-random byte into - // the first byte of `self.buffer`. It may break the safety invariant, - // but after writing keystream block with `tail`, we immediately - // overwrite the first byte with a correct value. - self.core.write_keystream_block(&mut self.buffer); - tail.copy_from_slice(&self.buffer[..tail.len()]); - tail.len() - }; + head.copy_from_slice(head_ks); + self.core.write_keystream_blocks(blocks); - // SAFETY: `into_chunks` always returns tail with size - // less than block size. If `tail.len()` is zero, we replace - // it with block size. Thus the invariant required by - // `set_pos_unchecked` is satisfied. - unsafe { - self.set_pos_unchecked(new_pos); - } + self.buffer.write_block( + tail.len(), + |b| self.core.write_keystream_block(b), + |tail_ks| tail.copy_from_slice(tail_ks), + ); Ok(()) } @@ -228,7 +110,8 @@ impl StreamCipher for StreamCipherCoreWrapper { impl StreamCipherSeek for StreamCipherCoreWrapper { fn try_current_pos(&self) -> Result { - let pos = self.get_pos(); + let pos = u8::try_from(self.buffer.get_pos()) + .expect("buffer position is always smaller than 256"); SN::from_block_byte(self.core.get_block_pos(), pos, T::BlockSize::U8) } @@ -239,19 +122,14 @@ impl StreamCipherSeek for StreamCipherCoreWrapper { assert!(byte_pos < T::BlockSize::U8); self.core.set_block_pos(block_pos); - let new_pos = if byte_pos != 0 { - // See comment in `try_apply_keystream_inout` for use of `write_keystream_block` - self.core.write_keystream_block(&mut self.buffer); - byte_pos.into() - } else { - T::BlockSize::USIZE - }; - // SAFETY: we assert that `byte_pos` is always smaller than block size. - // If `byte_pos` is zero, we replace it with block size. Thus the invariant - // required by `set_pos_unchecked` is satisfied. - unsafe { - self.set_pos_unchecked(new_pos); - } + + self.buffer.reset(); + + self.buffer.write_block( + usize::from(byte_pos), + |b| self.core.write_keystream_block(b), + |_| {}, + ); Ok(()) } } @@ -272,11 +150,9 @@ impl IvSizeUser for StreamCipherCoreWrapper impl KeyIvInit for StreamCipherCoreWrapper { #[inline] fn new(key: &Key, iv: &Iv) -> Self { - let mut buffer = Block::::default(); - buffer[0] = T::BlockSize::U8; Self { core: T::new(key, iv), - buffer, + buffer: Default::default(), } } } @@ -284,22 +160,21 @@ impl KeyIvInit for StreamCipherCoreWrapper { impl KeyInit for StreamCipherCoreWrapper { #[inline] fn new(key: &Key) -> Self { - let mut buffer = Block::::default(); - buffer[0] = T::BlockSize::U8; Self { core: T::new(key), - buffer, + buffer: Default::default(), } } } #[cfg(feature = "zeroize")] -impl Drop for StreamCipherCoreWrapper { - fn drop(&mut self) { - // If present, `core` will be zeroized by its own `Drop`. - self.buffer.zeroize(); - } -} +impl ZeroizeOnDrop for StreamCipherCoreWrapper {} +// Assert that `ReadBuffer` implements `ZeroizeOnDrop` #[cfg(feature = "zeroize")] -impl ZeroizeOnDrop for StreamCipherCoreWrapper {} +const _: () = { + #[allow(dead_code)] + fn check_buffer(v: &ReadBuffer) { + let _ = v as &dyn crate::zeroize::ZeroizeOnDrop; + } +}; From 04771a8d32e617b1d7510b5c6c4f7faf53140326 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 18 Aug 2025 11:44:07 -0600 Subject: [PATCH 1442/1461] password-hash: remove deprecated methods on `Salt*` types (#1961) These methods were deprecated in the v0.5 release --- password-hash/src/salt.rs | 36 ------------------------------------ 1 file changed, 36 deletions(-) diff --git a/password-hash/src/salt.rs b/password-hash/src/salt.rs index c42f8b6ef..2d1975407 100644 --- a/password-hash/src/salt.rs +++ b/password-hash/src/salt.rs @@ -146,21 +146,6 @@ impl<'a> Salt<'a> { pub fn len(&self) -> usize { self.as_str().len() } - - /// Create a [`Salt`] from the given B64-encoded input string, validating - /// [`Salt::MIN_LENGTH`] and [`Salt::MAX_LENGTH`] restrictions. - #[deprecated(since = "0.5.0", note = "use `from_b64` instead")] - pub fn new(input: &'a str) -> Result { - Self::from_b64(input) - } - - /// Attempt to decode a B64-encoded [`Salt`] into bytes, writing the - /// decoded output into the provided buffer, and returning a slice of the - /// portion of the buffer containing the decoded result on success. - #[deprecated(since = "0.5.0", note = "use `decode_b64` instead")] - pub fn b64_decode<'b>(&self, buf: &'b mut [u8]) -> Result<&'b [u8]> { - self.decode_b64(buf) - } } impl AsRef for Salt<'_> { @@ -268,27 +253,6 @@ impl SaltString { pub fn len(&self) -> usize { self.as_str().len() } - - /// Create a new [`SaltString`] from the given B64-encoded input string, - /// validating [`Salt::MIN_LENGTH`] and [`Salt::MAX_LENGTH`] restrictions. - #[deprecated(since = "0.5.0", note = "use `from_b64` instead")] - pub fn new(s: &str) -> Result { - Self::from_b64(s) - } - - /// Decode this [`SaltString`] from B64 into the provided output buffer. - #[deprecated(since = "0.5.0", note = "use `decode_b64` instead")] - pub fn b64_decode<'a>(&self, buf: &'a mut [u8]) -> Result<&'a [u8]> { - self.decode_b64(buf) - } - - /// Encode the given byte slice as B64 into a new [`SaltString`]. - /// - /// Returns `Error` if the slice is too long. - #[deprecated(since = "0.5.0", note = "use `encode_b64` instead")] - pub fn b64_encode(input: &[u8]) -> Result { - Self::encode_b64(input) - } } impl AsRef for SaltString { From b69d839d96db9191cb136685cc9927c0cecb59c8 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 18 Aug 2025 13:37:31 -0600 Subject: [PATCH 1443/1461] elliptic-curve: remove JWK support (#1963) Migrated to the `jose-jwk` crate in RustCrypto/JOSE#85 --- .github/workflows/elliptic-curve.yml | 7 +- Cargo.lock | 32 -- elliptic-curve/Cargo.toml | 5 +- elliptic-curve/src/dev.rs | 8 - elliptic-curve/src/jwk.rs | 676 --------------------------- elliptic-curve/src/lib.rs | 7 - elliptic-curve/src/public_key.rs | 63 +-- elliptic-curve/src/secret_key.rs | 50 +- 8 files changed, 12 insertions(+), 836 deletions(-) delete mode 100644 elliptic-curve/src/jwk.rs diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index 6ebeb9a05..b35b68ff0 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -17,7 +17,7 @@ env: CARGO_INCREMENTAL: 0 RUSTFLAGS: "-Dwarnings" RUSTDOCFLAGS: "-Dwarnings" - + # Cancels CI jobs when new commits are pushed to a PR branch concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} @@ -48,7 +48,6 @@ jobs: - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features dev - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features digest - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features ecdh - - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features jwk - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features pem - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features pkcs8 - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features sec1 @@ -57,10 +56,10 @@ jobs: - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,arithmetic,pkcs8 - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,serde - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features arithmetic,serde - - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,digest,ecdh,jwk,pem,pkcs8,sec1,serde + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,digest,ecdh,pem,pkcs8,sec1,serde minimal-versions: - # Temporarily disabled until elliptic-curve 0.13.0-pre.0 is published + # Temporarily disabled until elliptic-curve 0.14.0 is published if: false runs-on: ubuntu-latest steps: diff --git a/Cargo.lock b/Cargo.lock index 91d3a73b3..e9e05b63e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -197,7 +197,6 @@ name = "elliptic-curve" version = "0.14.0-rc.12" dependencies = [ "base16ct", - "base64ct", "crypto-bigint", "digest", "ff", @@ -209,7 +208,6 @@ dependencies = [ "pkcs8", "rand_core", "sec1", - "serde_json", "serdect", "sha2", "sha3", @@ -336,12 +334,6 @@ dependencies = [ "hybrid-array", ] -[[package]] -name = "itoa" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" - [[package]] name = "keccak" version = "0.2.0-pre.0" @@ -365,12 +357,6 @@ version = "0.2.175" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" -[[package]] -name = "memchr" -version = "2.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" - [[package]] name = "num-bigint" version = "0.3.3" @@ -467,12 +453,6 @@ dependencies = [ "getrandom", ] -[[package]] -name = "ryu" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" - [[package]] name = "sec1" version = "0.8.0-rc.8" @@ -507,18 +487,6 @@ dependencies = [ "syn 2.0.104", ] -[[package]] -name = "serde_json" -version = "1.0.142" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "030fedb782600dcbd6f02d479bf0d817ac3bb40d644745b769d6a96bc3afc5a7" -dependencies = [ - "itoa", - "memchr", - "ryu", - "serde", -] - [[package]] name = "serdect" version = "0.3.0" diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index b5503969b..d8184004b 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -25,7 +25,6 @@ subtle = { version = "2.6", default-features = false } zeroize = { version = "1.7", default-features = false } # optional dependencies -base64ct = { version = "1", optional = true, default-features = false, features = ["alloc"] } digest = { version = "0.11.0-rc.0", optional = true } ff = { version = "=0.14.0-pre.0", optional = true, default-features = false } group = { version = "=0.14.0-pre.0", optional = true, default-features = false } @@ -35,7 +34,6 @@ pem-rfc7468 = { version = "1.0.0-rc.2", optional = true, features = ["alloc"] } pkcs8 = { version = "0.11.0-rc.6", optional = true, default-features = false } sec1 = { version = "0.8.0-rc.8", optional = true, features = ["subtle", "zeroize"] } serdect = { version = "0.3", optional = true, default-features = false, features = ["alloc"] } -serde_json = { version = "1.0.121", optional = true, default-features = false, features = ["alloc"] } [dev-dependencies] hex-literal = "1" @@ -64,10 +62,9 @@ bits = ["arithmetic", "ff/bits"] dev = ["arithmetic", "dep:hex-literal", "pem", "pkcs8"] ecdh = ["arithmetic", "digest", "dep:hkdf"] group = ["dep:group", "ff"] -jwk = ["dep:base64ct", "dep:serde_json", "alloc", "serde", "zeroize/alloc"] pkcs8 = ["dep:pkcs8", "sec1"] pem = ["dep:pem-rfc7468", "alloc", "arithmetic", "pkcs8/pem", "sec1/pem"] serde = ["dep:serdect", "alloc", "pkcs8", "sec1/serde"] [package.metadata.docs.rs] -features = ["bits", "ecdh", "jwk", "pem", "std"] +features = ["bits", "ecdh", "pem", "std"] diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index a7af4ecd6..4e7c334f0 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -31,9 +31,6 @@ use alloc::vec::Vec; #[cfg(feature = "bits")] use ff::PrimeFieldBits; -#[cfg(feature = "jwk")] -use crate::JwkParameters; - /// Pseudo-coordinate for fixed-based scalar mult output pub const PSEUDO_COORDINATE_FIXED_BASE_MUL: [u8; 32] = hex!("deadbeef00000000000000000000000000000000000000000000000000000001"); @@ -90,11 +87,6 @@ impl AssociatedOid for MockCurve { const OID: pkcs8::ObjectIdentifier = pkcs8::ObjectIdentifier::new_unwrap("1.2.840.10045.3.1.7"); } -#[cfg(feature = "jwk")] -impl JwkParameters for MockCurve { - const CRV: &'static str = "P-256"; -} - /// Example scalar type #[derive(Clone, Copy, Debug, Default, Eq, PartialEq, PartialOrd, Ord)] pub struct Scalar(ScalarPrimitive); diff --git a/elliptic-curve/src/jwk.rs b/elliptic-curve/src/jwk.rs deleted file mode 100644 index b85ac90e1..000000000 --- a/elliptic-curve/src/jwk.rs +++ /dev/null @@ -1,676 +0,0 @@ -//! JSON Web Key (JWK) Support. -//! -//! Specified in RFC 7518 Section 6: Cryptographic Algorithms for Keys: -//! - -use crate::{ - Curve, Error, FieldBytes, FieldBytesSize, Result, - sec1::{Coordinates, EncodedPoint, ModulusSize, ValidatePublicKey}, - secret_key::SecretKey, -}; -use alloc::{ - borrow::ToOwned, - format, - string::{String, ToString}, -}; -use base64ct::{Base64UrlUnpadded as Base64Url, Encoding}; -use core::{ - fmt::{self, Debug}, - marker::PhantomData, - str::{self, FromStr}, -}; -use serdect::serde::{Deserialize, Serialize, de, ser}; -use zeroize::{Zeroize, ZeroizeOnDrop}; - -#[cfg(feature = "arithmetic")] -use crate::{ - AffinePoint, CurveArithmetic, - public_key::PublicKey, - sec1::{FromEncodedPoint, ToEncodedPoint}, -}; - -/// Key Type (`kty`) for elliptic curve keys. -pub const EC_KTY: &str = "EC"; - -/// Deserialization error message. -const DE_ERROR_MSG: &str = "struct JwkEcKey with 5 elements"; - -/// Name of the JWK type -const JWK_TYPE_NAME: &str = "JwkEcKey"; - -/// Field names -const FIELDS: &[&str] = &["kty", "crv", "x", "y", "d"]; - -/// Elliptic curve parameters used by JSON Web Keys. -pub trait JwkParameters: Curve { - /// The `crv` parameter which identifies a particular elliptic curve - /// as defined in RFC 7518 Section 6.2.1.1: - /// - /// - /// Curve values are registered in the IANA "JSON Web Key Elliptic Curve" - /// registry defined in RFC 7518 Section 7.6: - /// - const CRV: &'static str; -} - -/// JSON Web Key (JWK) with a `kty` of `"EC"` (elliptic curve). -/// -/// Specified in [RFC 7518 Section 6: Cryptographic Algorithms for Keys][1]. -/// -/// This type can represent either a public/private keypair, or just a -/// public key, depending on whether or not the `d` parameter is present. -/// -/// [1]: https://tools.ietf.org/html/rfc7518#section-6 -// TODO(tarcieri): eagerly decode or validate `x`, `y`, and `d` as Base64 -#[derive(Clone)] -pub struct JwkEcKey { - /// The `crv` parameter which identifies a particular elliptic curve - /// as defined in RFC 7518 Section 6.2.1.1: - /// - crv: String, - - /// The x-coordinate of the elliptic curve point which is the public key - /// value associated with this JWK as defined in RFC 7518 6.2.1.2: - /// - x: String, - - /// The y-coordinate of the elliptic curve point which is the public key - /// value associated with this JWK as defined in RFC 7518 6.2.1.3: - /// - y: String, - - /// The `d` ECC private key parameter as described in RFC 7518 6.2.2.1: - /// - /// - /// Value is optional and if omitted, this JWK represents a private key. - /// - /// Inner value is encoded according to the `Integer-to-Octet-String` - /// conversion as defined in SEC1 section 2.3.7: - /// - d: Option, -} - -impl JwkEcKey { - /// Get the `crv` parameter for this JWK. - pub fn crv(&self) -> &str { - &self.crv - } - - /// Is this JWK a keypair that includes a private key? - pub fn is_keypair(&self) -> bool { - self.d.is_some() - } - - /// Does this JWK contain only a public key? - pub fn is_public_key(&self) -> bool { - self.d.is_none() - } - - /// Decode a JWK into a [`PublicKey`]. - #[cfg(feature = "arithmetic")] - pub fn to_public_key(&self) -> Result> - where - C: CurveArithmetic + JwkParameters, - AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldBytesSize: ModulusSize, - { - PublicKey::from_sec1_bytes(self.to_encoded_point::()?.as_bytes()) - } - - /// Create a JWK from a SEC1 [`EncodedPoint`]. - pub fn from_encoded_point(point: &EncodedPoint) -> Option - where - C: Curve + JwkParameters, - FieldBytesSize: ModulusSize, - { - match point.coordinates() { - Coordinates::Uncompressed { x, y } => Some(JwkEcKey { - crv: C::CRV.to_owned(), - x: Base64Url::encode_string(x), - y: Base64Url::encode_string(y), - d: None, - }), - _ => None, - } - } - - /// Get the public key component of this JWK as a SEC1 [`EncodedPoint`]. - pub fn to_encoded_point(&self) -> Result> - where - C: Curve + JwkParameters, - FieldBytesSize: ModulusSize, - { - if self.crv != C::CRV { - return Err(Error); - } - - let x = decode_base64url_fe::(&self.x)?; - let y = decode_base64url_fe::(&self.y)?; - Ok(EncodedPoint::::from_affine_coordinates(&x, &y, false)) - } - - /// Decode a JWK into a [`SecretKey`]. - #[cfg(feature = "arithmetic")] - pub fn to_secret_key(&self) -> Result> - where - C: Curve + JwkParameters + ValidatePublicKey, - FieldBytesSize: ModulusSize, - { - self.try_into() - } -} - -impl FromStr for JwkEcKey { - type Err = Error; - - fn from_str(s: &str) -> Result { - serde_json::from_str(s).map_err(|_| Error) - } -} - -#[allow(clippy::to_string_trait_impl)] -impl ToString for JwkEcKey { - fn to_string(&self) -> String { - serde_json::to_string(self).expect("JWK encoding error") - } -} - -impl TryFrom for SecretKey -where - C: Curve + JwkParameters + ValidatePublicKey, - FieldBytesSize: ModulusSize, -{ - type Error = Error; - - fn try_from(jwk: JwkEcKey) -> Result> { - (&jwk).try_into() - } -} - -impl TryFrom<&JwkEcKey> for SecretKey -where - C: Curve + JwkParameters + ValidatePublicKey, - FieldBytesSize: ModulusSize, -{ - type Error = Error; - - fn try_from(jwk: &JwkEcKey) -> Result> { - if let Some(d_base64) = &jwk.d { - let pk = jwk.to_encoded_point::()?; - let mut d_bytes = decode_base64url_fe::(d_base64)?; - let result = SecretKey::from_slice(&d_bytes); - d_bytes.zeroize(); - - result.and_then(|secret_key| { - C::validate_public_key(&secret_key, &pk)?; - Ok(secret_key) - }) - } else { - Err(Error) - } - } -} - -#[cfg(feature = "arithmetic")] -impl From> for JwkEcKey -where - C: CurveArithmetic + JwkParameters, - AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldBytesSize: ModulusSize, -{ - fn from(sk: SecretKey) -> JwkEcKey { - (&sk).into() - } -} - -#[cfg(feature = "arithmetic")] -impl From<&SecretKey> for JwkEcKey -where - C: CurveArithmetic + JwkParameters, - AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldBytesSize: ModulusSize, -{ - fn from(sk: &SecretKey) -> JwkEcKey { - let mut jwk = sk.public_key().to_jwk(); - let mut d = sk.to_bytes(); - jwk.d = Some(Base64Url::encode_string(&d)); - d.zeroize(); - jwk - } -} - -#[cfg(feature = "arithmetic")] -impl TryFrom for PublicKey -where - C: CurveArithmetic + JwkParameters, - AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldBytesSize: ModulusSize, -{ - type Error = Error; - - fn try_from(jwk: JwkEcKey) -> Result> { - (&jwk).try_into() - } -} - -#[cfg(feature = "arithmetic")] -impl TryFrom<&JwkEcKey> for PublicKey -where - C: CurveArithmetic + JwkParameters, - AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldBytesSize: ModulusSize, -{ - type Error = Error; - - fn try_from(jwk: &JwkEcKey) -> Result> { - PublicKey::from_sec1_bytes(jwk.to_encoded_point::()?.as_bytes()) - } -} - -#[cfg(feature = "arithmetic")] -impl From> for JwkEcKey -where - C: CurveArithmetic + JwkParameters, - AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldBytesSize: ModulusSize, -{ - fn from(pk: PublicKey) -> JwkEcKey { - (&pk).into() - } -} - -#[cfg(feature = "arithmetic")] -impl From<&PublicKey> for JwkEcKey -where - C: CurveArithmetic + JwkParameters, - AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldBytesSize: ModulusSize, -{ - fn from(pk: &PublicKey) -> JwkEcKey { - Self::from_encoded_point::(&pk.to_encoded_point(false)).expect("JWK encoding error") - } -} - -impl Debug for JwkEcKey { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let d = if self.d.is_some() { - "Some(...)" - } else { - "None" - }; - - // NOTE: this implementation omits the `d` private key parameter - f.debug_struct(JWK_TYPE_NAME) - .field("crv", &self.crv) - .field("x", &self.x) - .field("y", &self.y) - .field("d", &d) - .finish() - } -} - -impl PartialEq for JwkEcKey { - fn eq(&self, other: &Self) -> bool { - use subtle::ConstantTimeEq; - - // Compare private key in constant time - let d_eq = match &self.d { - Some(d1) => match &other.d { - Some(d2) => d1.as_bytes().ct_eq(d2.as_bytes()).into(), - None => other.d.is_none(), - }, - None => other.d.is_none(), - }; - - self.crv == other.crv && self.x == other.x && self.y == other.y && d_eq - } -} - -impl Eq for JwkEcKey {} - -impl ZeroizeOnDrop for JwkEcKey {} - -impl Drop for JwkEcKey { - fn drop(&mut self) { - self.zeroize(); - } -} - -impl Zeroize for JwkEcKey { - fn zeroize(&mut self) { - if let Some(d) = &mut self.d { - d.zeroize(); - } - } -} - -impl<'de> Deserialize<'de> for JwkEcKey { - fn deserialize(deserializer: D) -> core::result::Result - where - D: de::Deserializer<'de>, - { - /// Field positions - enum Field { - Kty, - Crv, - X, - Y, - D, - } - - /// Field visitor - struct FieldVisitor; - - impl de::Visitor<'_> for FieldVisitor { - type Value = Field; - - fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Formatter::write_str(formatter, "field identifier") - } - - fn visit_u64(self, value: u64) -> core::result::Result - where - E: de::Error, - { - match value { - 0 => Ok(Field::Kty), - 1 => Ok(Field::Crv), - 2 => Ok(Field::X), - 3 => Ok(Field::Y), - 4 => Ok(Field::D), - _ => Err(de::Error::invalid_value( - de::Unexpected::Unsigned(value), - &"field index 0 <= i < 5", - )), - } - } - - fn visit_str(self, value: &str) -> core::result::Result - where - E: de::Error, - { - self.visit_bytes(value.as_bytes()) - } - - fn visit_bytes(self, value: &[u8]) -> core::result::Result - where - E: de::Error, - { - match value { - b"kty" => Ok(Field::Kty), - b"crv" => Ok(Field::Crv), - b"x" => Ok(Field::X), - b"y" => Ok(Field::Y), - b"d" => Ok(Field::D), - _ => Err(de::Error::unknown_field( - &String::from_utf8_lossy(value), - FIELDS, - )), - } - } - } - - impl<'de> Deserialize<'de> for Field { - #[inline] - fn deserialize(__deserializer: D) -> core::result::Result - where - D: de::Deserializer<'de>, - { - de::Deserializer::deserialize_identifier(__deserializer, FieldVisitor) - } - } - - struct Visitor<'de> { - marker: PhantomData, - lifetime: PhantomData<&'de ()>, - } - - impl<'de> de::Visitor<'de> for Visitor<'de> { - type Value = JwkEcKey; - - fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Formatter::write_str(formatter, "struct JwkEcKey") - } - - #[inline] - fn visit_seq(self, mut seq: A) -> core::result::Result - where - A: de::SeqAccess<'de>, - { - let kty = de::SeqAccess::next_element::(&mut seq)? - .ok_or_else(|| de::Error::invalid_length(0, &DE_ERROR_MSG))?; - - if kty != EC_KTY { - return Err(de::Error::custom(format!("unsupported JWK kty: {kty:?}"))); - } - - let crv = de::SeqAccess::next_element::(&mut seq)? - .ok_or_else(|| de::Error::invalid_length(1, &DE_ERROR_MSG))?; - - let x = de::SeqAccess::next_element::(&mut seq)? - .ok_or_else(|| de::Error::invalid_length(2, &DE_ERROR_MSG))?; - - let y = de::SeqAccess::next_element::(&mut seq)? - .ok_or_else(|| de::Error::invalid_length(3, &DE_ERROR_MSG))?; - - let d = de::SeqAccess::next_element::>(&mut seq)? - .ok_or_else(|| de::Error::invalid_length(4, &DE_ERROR_MSG))?; - - Ok(JwkEcKey { crv, x, y, d }) - } - - #[inline] - fn visit_map(self, mut map: A) -> core::result::Result - where - A: de::MapAccess<'de>, - { - let mut kty: Option = None; - let mut crv: Option = None; - let mut x: Option = None; - let mut y: Option = None; - let mut d: Option = None; - - while let Some(key) = de::MapAccess::next_key::(&mut map)? { - match key { - Field::Kty => { - if kty.is_none() { - kty = Some(de::MapAccess::next_value::(&mut map)?); - } else { - return Err(de::Error::duplicate_field(FIELDS[0])); - } - } - Field::Crv => { - if crv.is_none() { - crv = Some(de::MapAccess::next_value::(&mut map)?); - } else { - return Err(de::Error::duplicate_field(FIELDS[1])); - } - } - Field::X => { - if x.is_none() { - x = Some(de::MapAccess::next_value::(&mut map)?); - } else { - return Err(de::Error::duplicate_field(FIELDS[2])); - } - } - Field::Y => { - if y.is_none() { - y = Some(de::MapAccess::next_value::(&mut map)?); - } else { - return Err(de::Error::duplicate_field(FIELDS[3])); - } - } - Field::D => { - if d.is_none() { - d = de::MapAccess::next_value::>(&mut map)?; - } else { - return Err(de::Error::duplicate_field(FIELDS[4])); - } - } - } - } - - let kty = kty.ok_or_else(|| de::Error::missing_field("kty"))?; - - if kty != EC_KTY { - return Err(de::Error::custom(format!("unsupported JWK kty: {kty}"))); - } - - let crv = crv.ok_or_else(|| de::Error::missing_field("crv"))?; - let x = x.ok_or_else(|| de::Error::missing_field("x"))?; - let y = y.ok_or_else(|| de::Error::missing_field("y"))?; - - Ok(JwkEcKey { crv, x, y, d }) - } - } - - de::Deserializer::deserialize_struct( - deserializer, - JWK_TYPE_NAME, - FIELDS, - Visitor { - marker: PhantomData::, - lifetime: PhantomData, - }, - ) - } -} - -impl Serialize for JwkEcKey { - fn serialize(&self, serializer: S) -> core::result::Result - where - S: ser::Serializer, - { - use ser::SerializeStruct; - - let mut state = serializer.serialize_struct(JWK_TYPE_NAME, 5)?; - - for (i, field) in [EC_KTY, &self.crv, &self.x, &self.y].iter().enumerate() { - state.serialize_field(FIELDS[i], field)?; - } - - if let Some(d) = &self.d { - state.serialize_field("d", d)?; - } - - SerializeStruct::end(state) - } -} - -/// Decode a Base64url-encoded field element -fn decode_base64url_fe(s: &str) -> Result> { - let mut result = FieldBytes::::default(); - Base64Url::decode(s, &mut result).map_err(|_| Error)?; - Ok(result) -} - -#[cfg(test)] -mod tests { - #![allow(clippy::unwrap_used, clippy::panic)] - use super::*; - - #[cfg(feature = "dev")] - use crate::dev::MockCurve; - - /// Example private key. From RFC 7518 Appendix C: - /// - const JWK_PRIVATE_KEY: &str = r#" - { - "kty":"EC", - "crv":"P-256", - "x":"gI0GAILBdu7T53akrFmMyGcsF3n5dO7MmwNBHKW5SV0", - "y":"SLW_xSffzlPWrHEVI30DHM_4egVwt3NQqeUD7nMFpps", - "d":"0_NxaRPUMQoAJt50Gz8YiTr8gRTwyEaCumd-MToTmIo" - } - "#; - - /// Example public key. - const JWK_PUBLIC_KEY: &str = r#" - { - "kty":"EC", - "crv":"P-256", - "x":"gI0GAILBdu7T53akrFmMyGcsF3n5dO7MmwNBHKW5SV0", - "y":"SLW_xSffzlPWrHEVI30DHM_4egVwt3NQqeUD7nMFpps" - } - "#; - - /// Example unsupported JWK (RSA key) - const UNSUPPORTED_JWK: &str = r#" - { - "kty":"RSA", - "kid":"cc34c0a0-bd5a-4a3c-a50d-a2a7db7643df", - "use":"sig", - "n":"pjdss8ZaDfEH6K6U7GeW2nxDqR4IP049fk1fK0lndimbMMVBdPv_hSpm8T8EtBDxrUdi1OHZfMhUixGaut-3nQ4GG9nM249oxhCtxqqNvEXrmQRGqczyLxuh-fKn9Fg--hS9UpazHpfVAFnB5aCfXoNhPuI8oByyFKMKaOVgHNqP5NBEqabiLftZD3W_lsFCPGuzr4Vp0YS7zS2hDYScC2oOMu4rGU1LcMZf39p3153Cq7bS2Xh6Y-vw5pwzFYZdjQxDn8x8BG3fJ6j8TGLXQsbKH1218_HcUJRvMwdpbUQG5nvA2GXVqLqdwp054Lzk9_B_f1lVrmOKuHjTNHq48w", - "e":"AQAB", - "d":"ksDmucdMJXkFGZxiomNHnroOZxe8AmDLDGO1vhs-POa5PZM7mtUPonxwjVmthmpbZzla-kg55OFfO7YcXhg-Hm2OWTKwm73_rLh3JavaHjvBqsVKuorX3V3RYkSro6HyYIzFJ1Ek7sLxbjDRcDOj4ievSX0oN9l-JZhaDYlPlci5uJsoqro_YrE0PRRWVhtGynd-_aWgQv1YzkfZuMD-hJtDi1Im2humOWxA4eZrFs9eG-whXcOvaSwO4sSGbS99ecQZHM2TcdXeAs1PvjVgQ_dKnZlGN3lTWoWfQP55Z7Tgt8Nf1q4ZAKd-NlMe-7iqCFfsnFwXjSiaOa2CRGZn-Q", - "p":"4A5nU4ahEww7B65yuzmGeCUUi8ikWzv1C81pSyUKvKzu8CX41hp9J6oRaLGesKImYiuVQK47FhZ--wwfpRwHvSxtNU9qXb8ewo-BvadyO1eVrIk4tNV543QlSe7pQAoJGkxCia5rfznAE3InKF4JvIlchyqs0RQ8wx7lULqwnn0", - "q":"ven83GM6SfrmO-TBHbjTk6JhP_3CMsIvmSdo4KrbQNvp4vHO3w1_0zJ3URkmkYGhz2tgPlfd7v1l2I6QkIh4Bumdj6FyFZEBpxjE4MpfdNVcNINvVj87cLyTRmIcaGxmfylY7QErP8GFA-k4UoH_eQmGKGK44TRzYj5hZYGWIC8", - "dp":"lmmU_AG5SGxBhJqb8wxfNXDPJjf__i92BgJT2Vp4pskBbr5PGoyV0HbfUQVMnw977RONEurkR6O6gxZUeCclGt4kQlGZ-m0_XSWx13v9t9DIbheAtgVJ2mQyVDvK4m7aRYlEceFh0PsX8vYDS5o1txgPwb3oXkPTtrmbAGMUBpE", - "dq":"mxRTU3QDyR2EnCv0Nl0TCF90oliJGAHR9HJmBe__EjuCBbwHfcT8OG3hWOv8vpzokQPRl5cQt3NckzX3fs6xlJN4Ai2Hh2zduKFVQ2p-AF2p6Yfahscjtq-GY9cB85NxLy2IXCC0PF--Sq9LOrTE9QV988SJy_yUrAjcZ5MmECk", - "qi":"ldHXIrEmMZVaNwGzDF9WG8sHj2mOZmQpw9yrjLK9hAsmsNr5LTyqWAqJIYZSwPTYWhY4nu2O0EY9G9uYiqewXfCKw_UngrJt8Xwfq1Zruz0YY869zPN4GiE9-9rzdZB33RBw8kIOquY3MK74FMwCihYx_LiU2YTHkaoJ3ncvtvg" - } - "#; - - #[test] - fn parse_private_key() { - let jwk = JwkEcKey::from_str(JWK_PRIVATE_KEY).unwrap(); - assert_eq!(jwk.crv, "P-256"); - assert_eq!(jwk.x, "gI0GAILBdu7T53akrFmMyGcsF3n5dO7MmwNBHKW5SV0"); - assert_eq!(jwk.y, "SLW_xSffzlPWrHEVI30DHM_4egVwt3NQqeUD7nMFpps"); - assert_eq!( - jwk.d.as_ref().unwrap(), - "0_NxaRPUMQoAJt50Gz8YiTr8gRTwyEaCumd-MToTmIo" - ); - } - - #[test] - fn parse_public_key() { - let jwk = JwkEcKey::from_str(JWK_PUBLIC_KEY).unwrap(); - assert_eq!(jwk.crv, "P-256"); - assert_eq!(jwk.x, "gI0GAILBdu7T53akrFmMyGcsF3n5dO7MmwNBHKW5SV0"); - assert_eq!(jwk.y, "SLW_xSffzlPWrHEVI30DHM_4egVwt3NQqeUD7nMFpps"); - assert_eq!(jwk.d, None); - } - - #[test] - fn parse_unsupported() { - assert_eq!(JwkEcKey::from_str(UNSUPPORTED_JWK), Err(Error)); - } - - #[test] - fn serialize_private_key() { - let actual = JwkEcKey::from_str(JWK_PRIVATE_KEY).unwrap().to_string(); - let expected: String = JWK_PRIVATE_KEY.split_whitespace().collect(); - assert_eq!(actual, expected); - } - - #[test] - fn serialize_public_key() { - let actual = JwkEcKey::from_str(JWK_PUBLIC_KEY).unwrap().to_string(); - let expected: String = JWK_PUBLIC_KEY.split_whitespace().collect(); - assert_eq!(actual, expected); - } - - #[cfg(feature = "dev")] - #[test] - fn jwk_into_encoded_point() { - let jwk = JwkEcKey::from_str(JWK_PUBLIC_KEY).unwrap(); - let point = jwk.to_encoded_point::().unwrap(); - let (x, y) = match point.coordinates() { - Coordinates::Uncompressed { x, y } => (x, y), - other => panic!("unexpected coordinates: {other:?}"), - }; - - assert_eq!(&decode_base64url_fe::(&jwk.x).unwrap(), x); - assert_eq!(&decode_base64url_fe::(&jwk.y).unwrap(), y); - } - - #[cfg(feature = "dev")] - #[test] - fn encoded_point_into_jwk() { - let jwk = JwkEcKey::from_str(JWK_PUBLIC_KEY).unwrap(); - let point = jwk.to_encoded_point::().unwrap(); - let jwk2 = JwkEcKey::from_encoded_point::(&point).unwrap(); - assert_eq!(jwk, jwk2); - } -} diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index bd880be88..4c64d8a4f 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -61,7 +61,6 @@ //! When the `serde` feature of this crate is enabled, `Serialize` and //! `Deserialize` impls are provided for the following types: //! -//! - [`JwkEcKey`] //! - [`PublicKey`] //! - [`ScalarPrimitive`] //! @@ -108,9 +107,6 @@ mod arithmetic; #[cfg(feature = "arithmetic")] mod public_key; -#[cfg(feature = "jwk")] -mod jwk; - pub use crate::{ error::{Error, Result}, field::{FieldBytes, FieldBytesEncoding, FieldBytesSize}, @@ -136,9 +132,6 @@ pub use { group::{self, Curve as CurveGroup, Group}, }; -#[cfg(feature = "jwk")] -pub use crate::jwk::{JwkEcKey, JwkParameters}; - #[cfg(feature = "pkcs8")] pub use pkcs8; diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index 6995b2568..f0e4a1637 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -7,14 +7,14 @@ use crate::{ use core::fmt::Debug; use group::Group; -#[cfg(feature = "jwk")] -use crate::{JwkEcKey, JwkParameters}; - #[cfg(feature = "pkcs8")] use pkcs8::spki::{AlgorithmIdentifier, AssociatedAlgorithmIdentifier, ObjectIdentifier}; #[cfg(feature = "pem")] -use core::str::FromStr; +use { + alloc::string::{String, ToString}, + core::str::FromStr, +}; #[cfg(feature = "sec1")] use { @@ -27,18 +27,15 @@ use { subtle::{Choice, CtOption}, }; +#[cfg(feature = "serde")] +use serdect::serde::{Deserialize, Serialize, de, ser}; + #[cfg(all(feature = "alloc", feature = "pkcs8"))] use pkcs8::EncodePublicKey; #[cfg(all(feature = "alloc", feature = "sec1"))] use alloc::boxed::Box; -#[cfg(any(feature = "jwk", feature = "pem"))] -use alloc::string::{String, ToString}; - -#[cfg(feature = "serde")] -use serdect::serde::{Deserialize, Serialize, de, ser}; - #[cfg(any(feature = "pem", feature = "serde"))] use pkcs8::DecodePublicKey; @@ -82,8 +79,6 @@ use { /// /// The serialization is binary-oriented and supports ASN.1 DER /// Subject Public Key Info (SPKI) as the encoding format. -/// -/// For a more text-friendly encoding of public keys, use [`JwkEcKey`] instead. #[derive(Clone, Debug, Eq, PartialEq)] pub struct PublicKey where @@ -162,50 +157,6 @@ where pub fn to_nonidentity(&self) -> NonIdentity> { NonIdentity::new_unchecked(self.point) } - - /// Parse a [`JwkEcKey`] JSON Web Key (JWK) into a [`PublicKey`]. - #[cfg(feature = "jwk")] - pub fn from_jwk(jwk: &JwkEcKey) -> Result - where - C: JwkParameters, - AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldBytesSize: ModulusSize, - { - jwk.to_public_key::() - } - - /// Parse a string containing a JSON Web Key (JWK) into a [`PublicKey`]. - #[cfg(feature = "jwk")] - pub fn from_jwk_str(jwk: &str) -> Result - where - C: JwkParameters, - AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldBytesSize: ModulusSize, - { - jwk.parse::().and_then(|jwk| Self::from_jwk(&jwk)) - } - - /// Serialize this public key as [`JwkEcKey`] JSON Web Key (JWK). - #[cfg(feature = "jwk")] - pub fn to_jwk(&self) -> JwkEcKey - where - C: JwkParameters, - AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldBytesSize: ModulusSize, - { - self.into() - } - - /// Serialize this public key as JSON Web Key (JWK) string. - #[cfg(feature = "jwk")] - pub fn to_jwk_string(&self) -> String - where - C: JwkParameters, - AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldBytesSize: ModulusSize, - { - self.to_jwk().to_string() - } } impl AsRef> for PublicKey diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 1559f62bc..dbc435605 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -20,9 +20,6 @@ use crate::{ rand_core::{CryptoRng, TryCryptoRng}, }; -#[cfg(feature = "jwk")] -use crate::jwk::{JwkEcKey, JwkParameters}; - #[cfg(feature = "pem")] use pem_rfc7468::{self as pem, PemLabel}; @@ -45,12 +42,9 @@ use { sec1::der::Encode, }; -#[cfg(all(feature = "arithmetic", any(feature = "jwk", feature = "pem")))] +#[cfg(all(feature = "arithmetic", feature = "pem"))] use alloc::string::String; -#[cfg(all(feature = "arithmetic", feature = "jwk"))] -use alloc::string::ToString; - #[cfg(all(doc, feature = "pkcs8"))] use {crate::pkcs8::DecodePrivateKey, core::str::FromStr}; @@ -278,48 +272,6 @@ where .map(Zeroizing::new) .ok_or(Error) } - - /// Parse a [`JwkEcKey`] JSON Web Key (JWK) into a [`SecretKey`]. - #[cfg(feature = "jwk")] - pub fn from_jwk(jwk: &JwkEcKey) -> Result - where - C: JwkParameters + ValidatePublicKey, - FieldBytesSize: ModulusSize, - { - Self::try_from(jwk) - } - - /// Parse a string containing a JSON Web Key (JWK) into a [`SecretKey`]. - #[cfg(feature = "jwk")] - pub fn from_jwk_str(jwk: &str) -> Result - where - C: JwkParameters + ValidatePublicKey, - FieldBytesSize: ModulusSize, - { - jwk.parse::().and_then(|jwk| Self::from_jwk(&jwk)) - } - - /// Serialize this secret key as [`JwkEcKey`] JSON Web Key (JWK). - #[cfg(all(feature = "arithmetic", feature = "jwk"))] - pub fn to_jwk(&self) -> JwkEcKey - where - C: CurveArithmetic + JwkParameters, - AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldBytesSize: ModulusSize, - { - self.into() - } - - /// Serialize this secret key as JSON Web Key (JWK) string. - #[cfg(all(feature = "arithmetic", feature = "jwk"))] - pub fn to_jwk_string(&self) -> Zeroizing - where - C: CurveArithmetic + JwkParameters, - AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldBytesSize: ModulusSize, - { - Zeroizing::new(self.to_jwk().to_string()) - } } impl ConstantTimeEq for SecretKey From 373e1539dba1a85fe620160c521815f1f4843186 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Aug 2025 13:15:54 +0300 Subject: [PATCH 1444/1461] build(deps): bump crate-ci/typos from 1.35.3 to 1.35.5 (#1965) --- .github/workflows/workspace.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index f5eedd2b2..1638edd4b 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -57,4 +57,4 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v5 - - uses: crate-ci/typos@v1.35.3 + - uses: crate-ci/typos@v1.35.5 From 9ca298409b8da26edc48216ec4e931ce22317494 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 19 Aug 2025 07:22:46 -0600 Subject: [PATCH 1445/1461] elliptic-curve: bump `crypto-bigint` to v0.7.0-rc.1 (#1967) This isn't ideal but gets the crate upgraded. I would like to experiment with changing `Curve::ORDER` to `NonZero` or `Odd` as a better solution --- Cargo.lock | 4 ++-- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 1 + elliptic-curve/src/scalar/primitive.rs | 11 ++++++++--- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e9e05b63e..6daabfc12 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -150,9 +150,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.7.0-rc.0" +version = "0.7.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "737a2363b81de8cc95d8780d84aecb4b3c6f41e4473759da6636072b5514c875" +checksum = "a19d32a062a0953e04cb5be69dd1ed8dc1ae0713c5bb4c247ce31b56a4ff6963" dependencies = [ "hybrid-array", "num-traits", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index d8184004b..7fb6bf2eb 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -18,7 +18,7 @@ and public/secret keys composed thereof. [dependencies] base16ct = "0.2" -crypto-bigint = { version = "0.7.0-rc.0", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } +crypto-bigint = { version = "0.7.0-rc.1", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } hybrid-array = { version = "0.3", default-features = false, features = ["zeroize"] } rand_core = { version = "0.9.0", default-features = false } subtle = { version = "2.6", default-features = false } diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 4c64d8a4f..078747b05 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -179,6 +179,7 @@ pub trait Curve: 'static + Copy + Clone + Debug + Default + Eq + Ord + Send + Sy /// Order of this elliptic curve, i.e. number of elements in the scalar /// field. + // TODO(tarcieri): make `NonZero` or `Odd`? const ORDER: Self::Uint; } diff --git a/elliptic-curve/src/scalar/primitive.rs b/elliptic-curve/src/scalar/primitive.rs index 3772cb81f..abc569efe 100644 --- a/elliptic-curve/src/scalar/primitive.rs +++ b/elliptic-curve/src/scalar/primitive.rs @@ -62,6 +62,7 @@ where }; /// Scalar modulus. + // TODO(tarcieri): make `NonZero` or `Odd`? pub const MODULUS: C::Uint = C::ORDER; /// Generate a random [`ScalarPrimitive`]. @@ -254,7 +255,9 @@ where fn add(self, other: &Self) -> Self { Self { - inner: self.inner.add_mod(&other.inner, &Self::MODULUS), + inner: self + .inner + .add_mod(&other.inner, &NonZero::new(Self::MODULUS).unwrap()), } } } @@ -296,7 +299,9 @@ where fn sub(self, other: &Self) -> Self { Self { - inner: self.inner.sub_mod(&other.inner, &Self::MODULUS), + inner: self + .inner + .sub_mod(&other.inner, &NonZero::new(Self::MODULUS).unwrap()), } } } @@ -327,7 +332,7 @@ where fn neg(self) -> Self { Self { - inner: self.inner.neg_mod(&Self::MODULUS), + inner: self.inner.neg_mod(&NonZero::new(Self::MODULUS).unwrap()), } } } From 40508e0480c748542358c620e055b12aa858b042 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 19 Aug 2025 17:40:52 -0600 Subject: [PATCH 1446/1461] elliptic-curve: make `Curve::Order` a `NonZero` (#1969) After RustCrypto/crypto-bigint#917 it's much more ergonomic to have the order be `NonZero`. We could also consider making it `Odd`, although `NonZero` is the immediate need so this is the most straightforward transition. --- Cargo.lock | 3 +-- Cargo.toml | 1 + elliptic-curve/src/dev.rs | 7 ++++--- elliptic-curve/src/lib.rs | 6 ++++-- elliptic-curve/src/scalar/primitive.rs | 17 ++++++----------- 5 files changed, 16 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6daabfc12..1ab500cd4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -151,8 +151,7 @@ dependencies = [ [[package]] name = "crypto-bigint" version = "0.7.0-rc.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a19d32a062a0953e04cb5be69dd1ed8dc1ae0713c5bb4c247ce31b56a4ff6963" +source = "git+https://github.com/RustCrypto/crypto-bigint#3c3a24a85c439c8946e133eb717bfbf8e86148bc" dependencies = [ "hybrid-array", "num-traits", diff --git a/Cargo.toml b/Cargo.toml index 63c918333..e97fb628d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,3 +23,4 @@ blobby = { git = "https://github.com/RustCrypto/utils" } # https://github.com/RustCrypto/utils/pull/1200 # https://github.com/RustCrypto/utils/pull/1201 block-buffer = { git = "https://github.com/RustCrypto/utils", branch = "block-buffer/read-buf" } +crypto-bigint = { git = "https://github.com/RustCrypto/crypto-bigint" } diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 4e7c334f0..05f391ec5 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -6,7 +6,7 @@ use crate::{ BatchNormalize, Curve, CurveArithmetic, CurveGroup, FieldBytesEncoding, PrimeCurve, array::typenum::U32, - bigint::{Limb, U256}, + bigint::{Limb, NonZero, U256}, error::{Error, Result}, ops::{Invert, LinearCombination, Reduce, ShrAssign}, point::{AffineCoordinates, NonIdentity}, @@ -70,8 +70,9 @@ impl Curve for MockCurve { type FieldBytesSize = U32; type Uint = U256; - const ORDER: U256 = - U256::from_be_hex("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551"); + const ORDER: NonZero = NonZero::::from_be_hex( + "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", + ); } impl PrimeCurve for MockCurve {} diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 078747b05..3bf084788 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -135,6 +135,7 @@ pub use { #[cfg(feature = "pkcs8")] pub use pkcs8; +use bigint::NonZero; use core::{ fmt::Debug, ops::{Add, ShrAssign}, @@ -179,8 +180,9 @@ pub trait Curve: 'static + Copy + Clone + Debug + Default + Eq + Ord + Send + Sy /// Order of this elliptic curve, i.e. number of elements in the scalar /// field. - // TODO(tarcieri): make `NonZero` or `Odd`? - const ORDER: Self::Uint; + // TODO(tarcieri): make `Odd`? the prime order subgroup should always have an odd number of + // elements, even if there is a cofactor + const ORDER: NonZero; } /// Marker trait for elliptic curves with prime order. diff --git a/elliptic-curve/src/scalar/primitive.rs b/elliptic-curve/src/scalar/primitive.rs index abc569efe..adfcf1cec 100644 --- a/elliptic-curve/src/scalar/primitive.rs +++ b/elliptic-curve/src/scalar/primitive.rs @@ -62,13 +62,12 @@ where }; /// Scalar modulus. - // TODO(tarcieri): make `NonZero` or `Odd`? - pub const MODULUS: C::Uint = C::ORDER; + pub const MODULUS: NonZero = C::ORDER; /// Generate a random [`ScalarPrimitive`]. pub fn random(rng: &mut R) -> Self { Self { - inner: C::Uint::random_mod(rng, &NonZero::new(Self::MODULUS).unwrap()), + inner: C::Uint::random_mod(rng, &Self::MODULUS), } } @@ -255,9 +254,7 @@ where fn add(self, other: &Self) -> Self { Self { - inner: self - .inner - .add_mod(&other.inner, &NonZero::new(Self::MODULUS).unwrap()), + inner: self.inner.add_mod(&other.inner, &Self::MODULUS), } } } @@ -299,9 +296,7 @@ where fn sub(self, other: &Self) -> Self { Self { - inner: self - .inner - .sub_mod(&other.inner, &NonZero::new(Self::MODULUS).unwrap()), + inner: self.inner.sub_mod(&other.inner, &Self::MODULUS), } } } @@ -332,7 +327,7 @@ where fn neg(self) -> Self { Self { - inner: self.inner.neg_mod(&NonZero::new(Self::MODULUS).unwrap()), + inner: self.inner.neg_mod(&Self::MODULUS), } } } @@ -362,7 +357,7 @@ where C: Curve, { fn is_high(&self) -> Choice { - let n_2 = C::ORDER >> 1u32; + let n_2 = Self::MODULUS.get() >> 1u32; self.inner.ct_gt(&n_2) } } From cc3b4991c7cc981cff2d789f6872edce9dff6e62 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Thu, 21 Aug 2025 12:06:35 +0300 Subject: [PATCH 1447/1461] Fix `block-buffer` patch (#1971) --- Cargo.lock | 22 +++++++++++----------- Cargo.toml | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1ab500cd4..e6d011ed2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -51,9 +51,9 @@ checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" [[package]] name = "bitflags" -version = "2.9.1" +version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" +checksum = "6a65b545ab31d687cff52899d4890855fec459eb6afe0da6417b8a18da87aa29" [[package]] name = "bitvec" @@ -70,12 +70,12 @@ dependencies = [ [[package]] name = "blobby" version = "0.4.0-pre.0" -source = "git+https://github.com/RustCrypto/utils#f5ac85f6aa02aa39614f62a6a1add9468be67892" +source = "git+https://github.com/RustCrypto/utils#dfcd9a0a75c45085f0e594597fb0d1dc8b781b86" [[package]] name = "block-buffer" version = "0.11.0-rc.4" -source = "git+https://github.com/RustCrypto/utils?branch=block-buffer%2Fread-buf#79e12dfd745e732d24ba1566f705f35ba409edc6" +source = "git+https://github.com/RustCrypto/utils#dfcd9a0a75c45085f0e594597fb0d1dc8b781b86" dependencies = [ "hybrid-array", "zeroize", @@ -104,9 +104,9 @@ checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "cfg-if" -version = "1.0.1" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" +checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" [[package]] name = "cipher" @@ -415,9 +415,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.97" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d61789d7719defeb74ea5fe81f2fdfdbd28a803847077cecce2ff14e1472f6f1" +checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" dependencies = [ "unicode-ident", ] @@ -483,7 +483,7 @@ checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -560,9 +560,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.104" +version = "2.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" +checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index e97fb628d..04bfffe25 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,5 +22,5 @@ blobby = { git = "https://github.com/RustCrypto/utils" } # https://github.com/RustCrypto/utils/pull/1192 # https://github.com/RustCrypto/utils/pull/1200 # https://github.com/RustCrypto/utils/pull/1201 -block-buffer = { git = "https://github.com/RustCrypto/utils", branch = "block-buffer/read-buf" } +block-buffer = { git = "https://github.com/RustCrypto/utils" } crypto-bigint = { git = "https://github.com/RustCrypto/crypto-bigint" } From 4082ff5aa1c20339e2d1f6de4e04351d5e32828c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Aug 2025 18:21:37 +0300 Subject: [PATCH 1448/1461] Update Cargo.lock (#1973) --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e6d011ed2..eca708846 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -51,9 +51,9 @@ checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" [[package]] name = "bitflags" -version = "2.9.2" +version = "2.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a65b545ab31d687cff52899d4890855fec459eb6afe0da6417b8a18da87aa29" +checksum = "34efbcccd345379ca2868b2b2c9d3782e9cc58ba87bc7d79d5b53d9c9ae6f25d" [[package]] name = "bitvec" From 894bc718e10997ee0df3c2ac7cc4dff468d546be Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 1 Sep 2025 16:59:38 -0600 Subject: [PATCH 1449/1461] Bump `hybrid-array` to v0.4 (#1976) --- Cargo.lock | 47 +++++++++++++++++++++++++-------------- Cargo.toml | 4 ++++ crypto-common/Cargo.toml | 2 +- elliptic-curve/Cargo.toml | 2 +- 4 files changed, 36 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index eca708846..467034841 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -43,6 +43,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" +[[package]] +name = "base16ct" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b59d472eab27ade8d770dcb11da7201c11234bef9f82ce7aa517be028d462b" + [[package]] name = "base64ct" version = "1.8.0" @@ -70,12 +76,12 @@ dependencies = [ [[package]] name = "blobby" version = "0.4.0-pre.0" -source = "git+https://github.com/RustCrypto/utils#dfcd9a0a75c45085f0e594597fb0d1dc8b781b86" +source = "git+https://github.com/RustCrypto/utils#adfccfea2686ef191b607f653cc3587753b6ec66" [[package]] name = "block-buffer" version = "0.11.0-rc.4" -source = "git+https://github.com/RustCrypto/utils#dfcd9a0a75c45085f0e594597fb0d1dc8b781b86" +source = "git+https://github.com/RustCrypto/utils#adfccfea2686ef191b607f653cc3587753b6ec66" dependencies = [ "hybrid-array", "zeroize", @@ -84,8 +90,7 @@ dependencies = [ [[package]] name = "block-padding" version = "0.4.0-rc.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee88d14c41bbae2e333f574a27fc73d96fe1039e5a356c20d06a7f2a34cd8e5a" +source = "git+https://github.com/RustCrypto/utils#adfccfea2686ef191b607f653cc3587753b6ec66" dependencies = [ "hybrid-array", ] @@ -150,8 +155,8 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.7.0-rc.1" -source = "git+https://github.com/RustCrypto/crypto-bigint#3c3a24a85c439c8946e133eb717bfbf8e86148bc" +version = "0.7.0-rc.2" +source = "git+https://github.com/RustCrypto/crypto-bigint#22ac4ade73a2e280972d67774ed5c5d8c95dbe33" dependencies = [ "hybrid-array", "num-traits", @@ -195,7 +200,7 @@ dependencies = [ name = "elliptic-curve" version = "0.14.0-rc.12" dependencies = [ - "base16ct", + "base16ct 0.2.0", "crypto-bigint", "digest", "ff", @@ -207,7 +212,7 @@ dependencies = [ "pkcs8", "rand_core", "sec1", - "serdect", + "serdect 0.3.0", "sha2", "sha3", "subtle", @@ -315,9 +320,9 @@ dependencies = [ [[package]] name = "hybrid-array" -version = "0.3.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891d15931895091dea5c47afa5b3c9a01ba634b311919fd4d41388fa0e3d76af" +checksum = "6fe39a812f039072707ce38020acbab2f769087952eddd9e2b890f37654b2349" dependencies = [ "typenum", "zeroize", @@ -326,8 +331,7 @@ dependencies = [ [[package]] name = "inout" version = "0.2.0-rc.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c774c86bce20ea04abe1c37cf0051c5690079a3a28ef5fdac2a5a0412b3d7d74" +source = "git+https://github.com/RustCrypto/utils#adfccfea2686ef191b607f653cc3587753b6ec66" dependencies = [ "block-padding", "hybrid-array", @@ -455,13 +459,12 @@ dependencies = [ [[package]] name = "sec1" version = "0.8.0-rc.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c54dee398d74b1d03d78ddc09c90e456bf906b5b7aa790ba4f48b025b2179e5d" +source = "git+https://github.com/RustCrypto/formats?branch=sec1%2Fhybrid-array-v0.4#fdc1f293f71bfbbee5e89997b1ec17b13e632c61" dependencies = [ - "base16ct", + "base16ct 0.3.0", "der", "hybrid-array", - "serdect", + "serdect 0.4.0", "subtle", "zeroize", ] @@ -492,7 +495,17 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f42f67da2385b51a5f9652db9c93d78aeaf7610bf5ec366080b6de810604af53" dependencies = [ - "base16ct", + "base16ct 0.2.0", + "serde", +] + +[[package]] +name = "serdect" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90faa9344350bebcc60a4beae3290b8548ecc55a542e25f5ca1cdc83b267fe7e" +dependencies = [ + "base16ct 0.2.0", "serde", ] diff --git a/Cargo.toml b/Cargo.toml index 04bfffe25..7ea6103d0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,5 +22,9 @@ blobby = { git = "https://github.com/RustCrypto/utils" } # https://github.com/RustCrypto/utils/pull/1192 # https://github.com/RustCrypto/utils/pull/1200 # https://github.com/RustCrypto/utils/pull/1201 +# https://github.com/RustCrypto/utils/pull/1208 block-buffer = { git = "https://github.com/RustCrypto/utils" } +block-padding = { git = "https://github.com/RustCrypto/utils" } crypto-bigint = { git = "https://github.com/RustCrypto/crypto-bigint" } +inout = { git = "https://github.com/RustCrypto/utils" } +sec1 = { git = "https://github.com/RustCrypto/formats", branch = "sec1/hybrid-array-v0.4" } diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index 5cdf89f25..7d34abe09 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -13,7 +13,7 @@ categories = ["cryptography", "no-std"] description = "Common cryptographic traits" [dependencies] -hybrid-array = "0.3" +hybrid-array = "0.4" # optional dependencies rand_core = { version = "0.9", optional = true } diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 7fb6bf2eb..28bdd7f34 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -19,7 +19,7 @@ and public/secret keys composed thereof. [dependencies] base16ct = "0.2" crypto-bigint = { version = "0.7.0-rc.1", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } -hybrid-array = { version = "0.3", default-features = false, features = ["zeroize"] } +hybrid-array = { version = "0.4", default-features = false, features = ["zeroize"] } rand_core = { version = "0.9.0", default-features = false } subtle = { version = "2.6", default-features = false } zeroize = { version = "1.7", default-features = false } From c11a7cc4d8e13a48ffb8e65557ec25f6b3ebbbb2 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 1 Sep 2025 17:19:07 -0600 Subject: [PATCH 1450/1461] elliptic-curve: bump `base16ct` to v0.3 (#1977) --- Cargo.lock | 2 +- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 467034841..5892e3b0b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -200,7 +200,7 @@ dependencies = [ name = "elliptic-curve" version = "0.14.0-rc.12" dependencies = [ - "base16ct 0.2.0", + "base16ct 0.3.0", "crypto-bigint", "digest", "ff", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 28bdd7f34..ffc3d6bd1 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -17,7 +17,7 @@ and public/secret keys composed thereof. """ [dependencies] -base16ct = "0.2" +base16ct = "0.3" crypto-bigint = { version = "0.7.0-rc.1", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } hybrid-array = { version = "0.4", default-features = false, features = ["zeroize"] } rand_core = { version = "0.9.0", default-features = false } From 26cbd81642aa8ed2304c0cf000de467429b79556 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 1 Sep 2025 17:22:48 -0600 Subject: [PATCH 1451/1461] elliptic-curve: bump `serdect` dependency to v0.4 (#1978) --- Cargo.lock | 14 ++------------ elliptic-curve/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5892e3b0b..192cba9e5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -212,7 +212,7 @@ dependencies = [ "pkcs8", "rand_core", "sec1", - "serdect 0.3.0", + "serdect", "sha2", "sha3", "subtle", @@ -464,7 +464,7 @@ dependencies = [ "base16ct 0.3.0", "der", "hybrid-array", - "serdect 0.4.0", + "serdect", "subtle", "zeroize", ] @@ -489,16 +489,6 @@ dependencies = [ "syn 2.0.106", ] -[[package]] -name = "serdect" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f42f67da2385b51a5f9652db9c93d78aeaf7610bf5ec366080b6de810604af53" -dependencies = [ - "base16ct 0.2.0", - "serde", -] - [[package]] name = "serdect" version = "0.4.0" diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index ffc3d6bd1..e993ca67f 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -33,7 +33,7 @@ hex-literal = { version = "1", optional = true } pem-rfc7468 = { version = "1.0.0-rc.2", optional = true, features = ["alloc"] } pkcs8 = { version = "0.11.0-rc.6", optional = true, default-features = false } sec1 = { version = "0.8.0-rc.8", optional = true, features = ["subtle", "zeroize"] } -serdect = { version = "0.3", optional = true, default-features = false, features = ["alloc"] } +serdect = { version = "0.4", optional = true, default-features = false, features = ["alloc"] } [dev-dependencies] hex-literal = "1" From 062af9bd26c388f371dfec79cdaf889b515fe381 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 1 Sep 2025 17:24:01 -0600 Subject: [PATCH 1452/1461] elliptic-curve: remove unused `sha2` and `sha3` dev-dependencies (#1979) --- Cargo.lock | 41 --------------------------------------- elliptic-curve/Cargo.toml | 2 -- 2 files changed, 43 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 192cba9e5..734303dfc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -130,15 +130,6 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0dabb6555f92fb9ee4140454eb5dcd14c7960e1225c6d1a6cc361f032947713e" -[[package]] -name = "cpufeatures" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" -dependencies = [ - "libc", -] - [[package]] name = "crypto" version = "0.6.0-pre" @@ -213,8 +204,6 @@ dependencies = [ "rand_core", "sec1", "serdect", - "sha2", - "sha3", "subtle", "zeroize", ] @@ -337,15 +326,6 @@ dependencies = [ "hybrid-array", ] -[[package]] -name = "keccak" -version = "0.2.0-pre.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7cdd4f0dc5807b9a2b25dd48a3f58e862606fe7bd47f41ecde36e97422d7e90" -dependencies = [ - "cpufeatures", -] - [[package]] name = "kem" version = "0.3.0-pre.0" @@ -499,27 +479,6 @@ dependencies = [ "serde", ] -[[package]] -name = "sha2" -version = "0.11.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa1d2e6b3cc4e43a8258a9a3b17aa5dfd2cc5186c7024bba8a64aa65b2c71a59" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "sha3" -version = "0.11.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e6a92fd180fd205defdc0b78288ce847c7309d329fd6647a814567e67db50e" -dependencies = [ - "digest", - "keccak", -] - [[package]] name = "signature" version = "3.0.0-rc.2" diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index e993ca67f..33cc8fd72 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -37,8 +37,6 @@ serdect = { version = "0.4", optional = true, default-features = false, features [dev-dependencies] hex-literal = "1" -sha2 = "0.11.0-rc.0" -sha3 = "0.11.0-rc.0" [features] default = ["arithmetic"] From b91704f633a83798c1ba89f908cff067ddc7d843 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 1 Sep 2025 18:37:34 -0600 Subject: [PATCH 1453/1461] Bump `serdect` to v0.4.1 (#1980) v0.4.0 was the last thing depending on `base16ct` v0.2 --- Cargo.lock | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 734303dfc..1f8762c80 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -37,12 +37,6 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" -[[package]] -name = "base16ct" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" - [[package]] name = "base16ct" version = "0.3.0" @@ -191,7 +185,7 @@ dependencies = [ name = "elliptic-curve" version = "0.14.0-rc.12" dependencies = [ - "base16ct 0.3.0", + "base16ct", "crypto-bigint", "digest", "ff", @@ -441,7 +435,7 @@ name = "sec1" version = "0.8.0-rc.8" source = "git+https://github.com/RustCrypto/formats?branch=sec1%2Fhybrid-array-v0.4#fdc1f293f71bfbbee5e89997b1ec17b13e632c61" dependencies = [ - "base16ct 0.3.0", + "base16ct", "der", "hybrid-array", "serdect", @@ -471,11 +465,11 @@ dependencies = [ [[package]] name = "serdect" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90faa9344350bebcc60a4beae3290b8548ecc55a542e25f5ca1cdc83b267fe7e" +checksum = "d3ef0e35b322ddfaecbc60f34ab448e157e48531288ee49fafbb053696b8ffe2" dependencies = [ - "base16ct 0.2.0", + "base16ct", "serde", ] From 9b4113d1dc9f609a7a2c39da5bb7337d33f4c15c Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 1 Sep 2025 22:10:33 -0600 Subject: [PATCH 1454/1461] sec1: source from git `master` (#1981) Bumped in RustCrypto/formats#2019 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1f8762c80..20995b210 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -433,7 +433,7 @@ dependencies = [ [[package]] name = "sec1" version = "0.8.0-rc.8" -source = "git+https://github.com/RustCrypto/formats?branch=sec1%2Fhybrid-array-v0.4#fdc1f293f71bfbbee5e89997b1ec17b13e632c61" +source = "git+https://github.com/RustCrypto/formats#4f55e5849921b1754f73903e612ca5ea3cb5cf69" dependencies = [ "base16ct", "der", diff --git a/Cargo.toml b/Cargo.toml index 7ea6103d0..36002f89b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,4 +27,4 @@ block-buffer = { git = "https://github.com/RustCrypto/utils" } block-padding = { git = "https://github.com/RustCrypto/utils" } crypto-bigint = { git = "https://github.com/RustCrypto/crypto-bigint" } inout = { git = "https://github.com/RustCrypto/utils" } -sec1 = { git = "https://github.com/RustCrypto/formats", branch = "sec1/hybrid-array-v0.4" } +sec1 = { git = "https://github.com/RustCrypto/formats" } From a55964aed6270602338f536611e05f5aec76f766 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 1 Sep 2025 22:12:31 -0600 Subject: [PATCH 1455/1461] elliptic-curve: have `alloc` activate `hybrid-array/alloc` (#1982) Enable `alloc` support for `hybrid-array` when the `alloc` crate feature of `elliptic-curve` is enabled --- elliptic-curve/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 33cc8fd72..c4f1537ea 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -44,6 +44,7 @@ alloc = [ "base16ct/alloc", "ff?/alloc", "group?/alloc", + "hybrid-array/alloc", "pkcs8?/alloc", "sec1?/alloc", "zeroize/alloc" From 5202618e4596f30146380c595e0b1c279253e419 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 2 Sep 2025 06:28:02 -0600 Subject: [PATCH 1456/1461] cipher: restore `StreamCipherCoreWrapper::from_core` (#1983) Removed in #1959 but there are definitely still quite a few usages and I don't see ways to completely replace all of them with `KeyIvInit` (though that seems ideal). See RustCrypto/AEADs#710 --- cipher/src/stream/wrapper.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cipher/src/stream/wrapper.rs b/cipher/src/stream/wrapper.rs index 5789cdddd..5b9513c37 100644 --- a/cipher/src/stream/wrapper.rs +++ b/cipher/src/stream/wrapper.rs @@ -37,6 +37,14 @@ impl fmt::Debug for StreamCipherCoreWrapper } impl StreamCipherCoreWrapper { + /// Initialize from a [`StreamCipherCore`] instance. + pub fn from_core(core: T) -> Self { + Self { + core, + buffer: Default::default(), + } + } + fn check_remaining(&self, data_len: usize) -> Result<(), StreamCipherError> { let rem_blocks = match self.core.remaining_blocks() { Some(v) => v, From 34407ee38b382f8e68bd56cdbf355208b8c2919e Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 2 Sep 2025 12:40:34 -0600 Subject: [PATCH 1457/1461] Update `block-buffer`, `block-padding`, and `inout` crates (#1986) Uses `hybrid-array` v0.4-compatible crate releases rather than sourcing these crates from git: - `block-buffer` v0.11.0-rc.5 - `block-padding` v0.4.0-rc.4 - `inout` v0.2.0-rc.6 --- Cargo.lock | 15 +++++++++------ Cargo.toml | 3 --- aead/Cargo.toml | 2 +- cipher/Cargo.toml | 4 ++-- digest/Cargo.toml | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 20995b210..3514b42bd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -74,8 +74,9 @@ source = "git+https://github.com/RustCrypto/utils#adfccfea2686ef191b607f653cc358 [[package]] name = "block-buffer" -version = "0.11.0-rc.4" -source = "git+https://github.com/RustCrypto/utils#adfccfea2686ef191b607f653cc3587753b6ec66" +version = "0.11.0-rc.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9ef36a6fcdb072aa548f3da057640ec10859eb4e91ddf526ee648d50c76a949" dependencies = [ "hybrid-array", "zeroize", @@ -83,8 +84,9 @@ dependencies = [ [[package]] name = "block-padding" -version = "0.4.0-rc.3" -source = "git+https://github.com/RustCrypto/utils#adfccfea2686ef191b607f653cc3587753b6ec66" +version = "0.4.0-rc.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e59c1aab3e6c5e56afe1b7e8650be9b5a791cb997bdea449194ae62e4bf8c73" dependencies = [ "hybrid-array", ] @@ -313,8 +315,9 @@ dependencies = [ [[package]] name = "inout" -version = "0.2.0-rc.5" -source = "git+https://github.com/RustCrypto/utils#adfccfea2686ef191b607f653cc3587753b6ec66" +version = "0.2.0-rc.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1603f76010ff924b616c8f44815a42eb10fb0b93d308b41deaa8da6d4251fd4b" dependencies = [ "block-padding", "hybrid-array", diff --git a/Cargo.toml b/Cargo.toml index 36002f89b..abdbea52c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,8 +23,5 @@ blobby = { git = "https://github.com/RustCrypto/utils" } # https://github.com/RustCrypto/utils/pull/1200 # https://github.com/RustCrypto/utils/pull/1201 # https://github.com/RustCrypto/utils/pull/1208 -block-buffer = { git = "https://github.com/RustCrypto/utils" } -block-padding = { git = "https://github.com/RustCrypto/utils" } crypto-bigint = { git = "https://github.com/RustCrypto/crypto-bigint" } -inout = { git = "https://github.com/RustCrypto/utils" } sec1 = { git = "https://github.com/RustCrypto/formats" } diff --git a/aead/Cargo.toml b/aead/Cargo.toml index fbfdc8023..f33fd4978 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -17,7 +17,7 @@ such as AES-GCM as ChaCha20Poly1305, which provide a high-level API [dependencies] crypto-common = { version = "0.2.0-rc.3", path = "../crypto-common" } -inout = "0.2.0-rc.4" +inout = "0.2.0-rc.6" # optional dependencies arrayvec = { version = "0.7", optional = true, default-features = false } diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index ac7cedecb..9758c735b 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -14,11 +14,11 @@ description = "Traits for describing block ciphers and stream ciphers" [dependencies] crypto-common = { version = "0.2.0-rc.3", path = "../crypto-common" } -inout = "0.2.0-rc.4" +inout = "0.2.0-rc.6" # optional dependencies blobby = { version = "0.4.0-pre.0", optional = true } -block-buffer = { version = "0.11.0-rc.4", optional = true} +block-buffer = { version = "0.11.0-rc.5", optional = true } zeroize = { version = "1.8", optional = true, default-features = false } [features] diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 3f527d7d9..3c4a344be 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -16,7 +16,7 @@ description = "Traits for cryptographic hash functions and message authenticatio crypto-common = { version = "0.2.0-rc.3", path = "../crypto-common" } # optional dependencies -block-buffer = { version = "0.11.0-rc.4", optional = true } +block-buffer = { version = "0.11.0-rc.5", optional = true } subtle = { version = "2.4", default-features = false, optional = true } blobby = { version = "0.4.0-pre.0", optional = true } const-oid = { version = "0.10", optional = true } From f146778044f147716dd313463aeb2dcce2486f4d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 2 Sep 2025 12:55:27 -0600 Subject: [PATCH 1458/1461] crypto-common v0.2.0-rc.4 (#1987) Notably includes `hybrid-array` v0.4 support --- Cargo.lock | 2 +- aead/Cargo.toml | 2 +- cipher/Cargo.toml | 2 +- crypto-common/Cargo.toml | 2 +- crypto/Cargo.toml | 2 +- digest/Cargo.toml | 2 +- universal-hash/Cargo.toml | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3514b42bd..3b55408a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -154,7 +154,7 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.2.0-rc.3" +version = "0.2.0-rc.4" dependencies = [ "hybrid-array", "rand_core", diff --git a/aead/Cargo.toml b/aead/Cargo.toml index f33fd4978..0b36bef37 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -16,7 +16,7 @@ such as AES-GCM as ChaCha20Poly1305, which provide a high-level API """ [dependencies] -crypto-common = { version = "0.2.0-rc.3", path = "../crypto-common" } +crypto-common = { version = "0.2.0-rc.4", path = "../crypto-common" } inout = "0.2.0-rc.6" # optional dependencies diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index 9758c735b..d2eaeddbe 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -13,7 +13,7 @@ categories = ["cryptography", "no-std"] description = "Traits for describing block ciphers and stream ciphers" [dependencies] -crypto-common = { version = "0.2.0-rc.3", path = "../crypto-common" } +crypto-common = { version = "0.2.0-rc.4", path = "../crypto-common" } inout = "0.2.0-rc.6" # optional dependencies diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index 7d34abe09..4ab7e8bf1 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "crypto-common" -version = "0.2.0-rc.3" +version = "0.2.0-rc.4" authors = ["RustCrypto Developers"] edition = "2024" rust-version = "1.85" diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index fbcf281f1..b7f627262 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -13,7 +13,7 @@ categories = ["cryptography", "no-std"] description = "Facade crate for all of the RustCrypto traits (e.g. `aead`, `cipher`, `digest`)" [dependencies] -crypto-common = { version = "0.2.0-rc.3", path = "../crypto-common", default-features = false } +crypto-common = { version = "0.2.0-rc.4", path = "../crypto-common", default-features = false } # optional dependencies aead = { version = "0.6.0-rc.0", path = "../aead", optional = true } diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 3c4a344be..90e4df3ae 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -13,7 +13,7 @@ categories = ["cryptography", "no-std"] description = "Traits for cryptographic hash functions and message authentication codes" [dependencies] -crypto-common = { version = "0.2.0-rc.3", path = "../crypto-common" } +crypto-common = { version = "0.2.0-rc.4", path = "../crypto-common" } # optional dependencies block-buffer = { version = "0.11.0-rc.5", optional = true } diff --git a/universal-hash/Cargo.toml b/universal-hash/Cargo.toml index 164fa7df7..2bdc12447 100644 --- a/universal-hash/Cargo.toml +++ b/universal-hash/Cargo.toml @@ -13,7 +13,7 @@ categories = ["cryptography", "no-std"] description = "Traits which describe the functionality of universal hash functions (UHFs)" [dependencies] -crypto-common = { version = "0.2.0-rc.3", path = "../crypto-common" } +crypto-common = { version = "0.2.0-rc.4", path = "../crypto-common" } subtle = { version = "2.4", default-features = false } [package.metadata.docs.rs] From da4ee572b7b4288ba4780f4e7424963c3e2d97c3 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 2 Sep 2025 13:16:32 -0600 Subject: [PATCH 1459/1461] elliptic-curve: bump `crypto-bigint` to v0.7.0-rc.3 (#1988) --- Cargo.lock | 5 +++-- Cargo.toml | 1 - 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3b55408a6..a1eb259ef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -142,8 +142,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.7.0-rc.2" -source = "git+https://github.com/RustCrypto/crypto-bigint#22ac4ade73a2e280972d67774ed5c5d8c95dbe33" +version = "0.7.0-rc.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "191664d1a454b91a62c539643b9742dd178357e50920060163bdbe72ed82fdfa" dependencies = [ "hybrid-array", "num-traits", diff --git a/Cargo.toml b/Cargo.toml index abdbea52c..51edba1f6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,5 +23,4 @@ blobby = { git = "https://github.com/RustCrypto/utils" } # https://github.com/RustCrypto/utils/pull/1200 # https://github.com/RustCrypto/utils/pull/1201 # https://github.com/RustCrypto/utils/pull/1208 -crypto-bigint = { git = "https://github.com/RustCrypto/crypto-bigint" } sec1 = { git = "https://github.com/RustCrypto/formats" } From ee32acede14a15275136164ffd88b8f5e0aca03b Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 2 Sep 2025 13:35:28 -0600 Subject: [PATCH 1460/1461] Cut prereleases with `hybrid-array` v0.4 support (#1989) Releases the following: - `aead` v0.6.0-rc.2 - `cipher` v0.5.0-rc.1 - `digest` v0.11.0-rc.1 - `signature` v3.0.0-rc.3 - `universal-hash` v0.6.0-rc.2 A separate `elliptic-curve` release is forthcoming --- Cargo.lock | 10 +++++----- aead/Cargo.toml | 2 +- cipher/Cargo.toml | 2 +- digest/Cargo.toml | 2 +- elliptic-curve/Cargo.toml | 4 ++-- signature/Cargo.toml | 4 ++-- universal-hash/Cargo.toml | 2 +- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a1eb259ef..2898f6bb0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15,7 +15,7 @@ dependencies = [ [[package]] name = "aead" -version = "0.6.0-rc.1" +version = "0.6.0-rc.2" dependencies = [ "arrayvec", "blobby", @@ -111,7 +111,7 @@ checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" [[package]] name = "cipher" -version = "0.5.0-rc.0" +version = "0.5.0-rc.1" dependencies = [ "blobby", "block-buffer", @@ -174,7 +174,7 @@ dependencies = [ [[package]] name = "digest" -version = "0.11.0-rc.0" +version = "0.11.0-rc.1" dependencies = [ "blobby", "block-buffer", @@ -479,7 +479,7 @@ dependencies = [ [[package]] name = "signature" -version = "3.0.0-rc.2" +version = "3.0.0-rc.3" dependencies = [ "digest", "rand_core", @@ -549,7 +549,7 @@ checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] name = "universal-hash" -version = "0.6.0-rc.1" +version = "0.6.0-rc.2" dependencies = [ "crypto-common", "subtle", diff --git a/aead/Cargo.toml b/aead/Cargo.toml index 0b36bef37..884ad61cb 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aead" -version = "0.6.0-rc.1" +version = "0.6.0-rc.2" authors = ["RustCrypto Developers"] edition = "2024" rust-version = "1.85" diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index d2eaeddbe..d5e24b470 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cipher" -version = "0.5.0-rc.0" +version = "0.5.0-rc.1" authors = ["RustCrypto Developers"] edition = "2024" rust-version = "1.85" diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 90e4df3ae..4f042b856 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "digest" -version = "0.11.0-rc.0" +version = "0.11.0-rc.1" authors = ["RustCrypto Developers"] edition = "2024" rust-version = "1.85" diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index c4f1537ea..cd8cebcd1 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -18,14 +18,14 @@ and public/secret keys composed thereof. [dependencies] base16ct = "0.3" -crypto-bigint = { version = "0.7.0-rc.1", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } +crypto-bigint = { version = "0.7.0-rc.3", default-features = false, features = ["rand_core", "hybrid-array", "zeroize"] } hybrid-array = { version = "0.4", default-features = false, features = ["zeroize"] } rand_core = { version = "0.9.0", default-features = false } subtle = { version = "2.6", default-features = false } zeroize = { version = "1.7", default-features = false } # optional dependencies -digest = { version = "0.11.0-rc.0", optional = true } +digest = { version = "0.11.0-rc.1", optional = true } ff = { version = "=0.14.0-pre.0", optional = true, default-features = false } group = { version = "=0.14.0-pre.0", optional = true, default-features = false } hkdf = { version = "0.13.0-rc.0", optional = true, default-features = false } diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 4e70a09fd..9b8b6d5b4 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "signature" -version = "3.0.0-rc.2" +version = "3.0.0-rc.3" authors = ["RustCrypto Developers"] edition = "2024" rust-version = "1.85" @@ -13,7 +13,7 @@ categories = ["cryptography", "no-std"] description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" [dependencies] -digest = { version = "0.11.0-rc.0", optional = true, default-features = false } +digest = { version = "0.11.0-rc.1", optional = true, default-features = false } rand_core = { version = "0.9", optional = true, default-features = false } [features] diff --git a/universal-hash/Cargo.toml b/universal-hash/Cargo.toml index 2bdc12447..62a3b3b1c 100644 --- a/universal-hash/Cargo.toml +++ b/universal-hash/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "universal-hash" -version = "0.6.0-rc.1" +version = "0.6.0-rc.2" authors = ["RustCrypto Developers"] edition = "2024" rust-version = "1.85" From 501b8854593a440a08fcb299a1ae421b16c76169 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 2 Sep 2025 14:09:35 -0600 Subject: [PATCH 1461/1461] elliptic-curve: bump `sec1` to v0.8.0-rc.9 (#1990) Notably this includes `hybrid-array` v0.4 support --- Cargo.lock | 5 +++-- Cargo.toml | 5 ----- elliptic-curve/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2898f6bb0..26f04204a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -436,8 +436,9 @@ dependencies = [ [[package]] name = "sec1" -version = "0.8.0-rc.8" -source = "git+https://github.com/RustCrypto/formats#4f55e5849921b1754f73903e612ca5ea3cb5cf69" +version = "0.8.0-rc.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5e67a3c9fb9a8f065af9fa30d65812fcc16a66cbf911eff1f6946957ce48f16" dependencies = [ "base16ct", "der", diff --git a/Cargo.toml b/Cargo.toml index 51edba1f6..6d7b09b62 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,8 +19,3 @@ signature = { path = "signature" } # https://github.com/RustCrypto/utils/pull/1187 blobby = { git = "https://github.com/RustCrypto/utils" } -# https://github.com/RustCrypto/utils/pull/1192 -# https://github.com/RustCrypto/utils/pull/1200 -# https://github.com/RustCrypto/utils/pull/1201 -# https://github.com/RustCrypto/utils/pull/1208 -sec1 = { git = "https://github.com/RustCrypto/formats" } diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index cd8cebcd1..2317ad846 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -32,7 +32,7 @@ hkdf = { version = "0.13.0-rc.0", optional = true, default-features = false } hex-literal = { version = "1", optional = true } pem-rfc7468 = { version = "1.0.0-rc.2", optional = true, features = ["alloc"] } pkcs8 = { version = "0.11.0-rc.6", optional = true, default-features = false } -sec1 = { version = "0.8.0-rc.8", optional = true, features = ["subtle", "zeroize"] } +sec1 = { version = "0.8.0-rc.9", optional = true, features = ["subtle", "zeroize"] } serdect = { version = "0.4", optional = true, default-features = false, features = ["alloc"] } [dev-dependencies]

, +} + +impl FromBlockCipherNonce for BlockModeDecryptWrapper +where + M: BlockModeDecrypt + FromBlockCipherNonce, + P: Padding, +{ + type BlockCipher = M::BlockCipher; + type NonceSize = M::NonceSize; + + fn from_block_cipher_nonce( + cipher: Self::BlockCipher, + nonce: &GenericArray, + ) -> Self { + Self { + inner: M::from_block_cipher_nonce(cipher, nonce), + buffer: Default::default(), + _p: Default::default(), + } + } +} + +impl BlockModeDecryptWrapper +where + M: BlockModeDecrypt, + P: Padding, +{ + /// Decrypt part of a ciphertext. + /// + /// This mehthod MUST be used in conjuction with the [`decrypt_final`] method, + /// otherwise plaintext will not be properly padded and may be truncated. + /// + /// The method decrypts `ciphertext`, writes the resulting plaintext + /// into `out_buf`, and returns it in the `Ok` variant. If a whole message + /// can not be processed, it caches ciphertext leftovers into inner buffer + /// for future use. + /// + /// It's recommended for `out_buf` to be at least one block longer than + /// `data`, otherwise the method can return `Err(BlockModeError)` if there is + /// not enough space for encrypted blocks. + /// + /// [`decrypt_final`]: Self::decrypt_final + #[inline] + pub fn decrypt_part<'a>( + &mut self, + ciphertext: &[u8], + out_buf: &'a mut [u8], + ) -> Result<&'a [u8], BlockModeError> { + let Self { inner, buffer, .. } = self; + buffer + .block_mode_processing(ciphertext, out_buf, |blocks| inner.decrypt_blocks(blocks)) + .map_err(|_| BlockModeError) + } + + /// Pad and decrypt plaintext. + /// + /// The method decrypts ciphertext, writes the resulting plaintext into + /// into `out_buf`, and unpads it. + /// + /// It's recommended for `out_buf` to be at least one block longer than + /// `data`, otherwise the method can return `Err(BlockModeError)` if there is + /// not enough space for encrypted blocks. + #[inline] + pub fn decrypt_final<'a>( + mut self, + ciphertext: &[u8], + out_buf: &'a mut [u8], + ) -> Result<&'a [u8], BlockModeError> { + let Self { inner, buffer, .. } = &mut self; + let res_len = buffer + .block_mode_processing(ciphertext, out_buf, |blocks| inner.decrypt_blocks(blocks)) + .map_err(|_| BlockModeError)? + .len(); + let final_block = buffer.get_full_block().ok_or(BlockModeError)?; + inner.decrypt_blocks(from_mut(final_block)); + let tail = P::unpad(final_block).map_err(|_| BlockModeError)?; + + let tail_len = tail.len(); + let final_len = res_len.checked_add(tail_len).ok_or(BlockModeError)?; + let buf = out_buf.get_mut(..final_len).ok_or(BlockModeError)?; + // note: even though `buf[t..]` and `buf[res_len..]` are guaranteed to be + // equivalent, compiler generates a panic branch for the latter. + let t = final_len - tail_len; + debug_assert_eq!(t, res_len); + buf[t..].copy_from_slice(tail); + Ok(buf) + } +} diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index 460aa92b6..fd1fdb780 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -13,7 +13,6 @@ categories = ["cryptography", "no-std"] [dependencies] generic-array = "0.14" -rand_core = { version = "0.6", optional = true } block-buffer = { version = "0.10.0-pre.2", optional = true } [features] diff --git a/crypto-common/src/lib.rs b/crypto-common/src/lib.rs index 0189872cc..5869bc677 100644 --- a/crypto-common/src/lib.rs +++ b/crypto-common/src/lib.rs @@ -12,10 +12,7 @@ #[cfg(feature = "std")] extern crate std; -use core::fmt; -use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; -#[cfg(feature = "rand_core")] -use rand_core::{CryptoRng, RngCore}; +use generic_array::{ArrayLength, GenericArray}; #[cfg(feature = "core-api")] #[cfg_attr(docsrs, doc(cfg(feature = "core-api")))] @@ -25,96 +22,6 @@ pub use block_buffer; #[cfg_attr(docsrs, doc(cfg(feature = "core-api")))] pub mod core_api; -/// Trait for types which can be created from key and nonce. -pub trait FromKeyNonce: Sized { - /// Key size in bytes. - type KeySize: ArrayLength; - - /// Nonce size in bytes. - type NonceSize: ArrayLength; - - /// Create new value from fixed length key and nonce. - fn new( - key: &GenericArray, - nonce: &GenericArray, - ) -> Self; - - /// Create new value from variable length key and nonce. - #[inline] - fn new_from_slices(key: &[u8], nonce: &[u8]) -> Result { - let kl = Self::KeySize::to_usize(); - let nl = Self::NonceSize::to_usize(); - if key.len() != kl || nonce.len() != nl { - Err(InvalidLength) - } else { - let key = GenericArray::from_slice(key); - let nonce = GenericArray::from_slice(nonce); - Ok(Self::new(key, nonce)) - } - } - - /// Generate a random key using the provided [`CryptoRng`]. - #[cfg(feature = "rand_core")] - #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] - #[inline] - fn generate_key(mut rng: impl CryptoRng + RngCore) -> GenericArray { - let mut key = GenericArray::::default(); - rng.fill_bytes(&mut key); - key - } - - /// Generate a random nonce using the provided [`CryptoRng`]. - #[cfg(feature = "rand_core")] - #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] - #[inline] - fn generate_nonce(mut rng: impl CryptoRng + RngCore) -> GenericArray { - let mut nonce = GenericArray::::default(); - rng.fill_bytes(&mut nonce); - nonce - } - - /// Generate random key and nonce using the provided [`CryptoRng`]. - #[cfg(feature = "rand_core")] - #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] - #[inline] - fn generate_key_nonce( - mut rng: impl CryptoRng + RngCore, - ) -> ( - GenericArray, - GenericArray, - ) { - (Self::generate_key(&mut rng), Self::generate_nonce(&mut rng)) - } -} - -/// Trait for types which can be created from key. -pub trait FromKey: Sized { - /// Key size in bytes. - type KeySize: ArrayLength; - - /// Create new value from fixed size key. - fn new(key: &GenericArray) -> Self; - - /// Create new value from variable size key. - fn new_from_slice(key: &[u8]) -> Result { - if key.len() != Self::KeySize::to_usize() { - Err(InvalidLength) - } else { - Ok(Self::new(GenericArray::from_slice(key))) - } - } - - /// Generate a random key using the provided [`CryptoRng`]. - #[cfg(feature = "rand_core")] - #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] - #[inline] - fn generate_key(mut rng: impl CryptoRng + RngCore) -> GenericArray { - let mut key = GenericArray::::default(); - rng.fill_bytes(&mut key); - key - } -} - /// Trait for types which consume data. pub trait Update { /// Update state using the provided data. @@ -158,17 +65,3 @@ pub trait Reset { /// Reset value to its initial state. fn reset(&mut self); } - -/// The error type returned when key and/or nonce used in [`FromKey`] -/// or [`FromKeyNonce`] slice-based methods had an invalid length. -#[derive(Copy, Clone, Eq, PartialEq, Debug)] -pub struct InvalidLength; - -impl fmt::Display for InvalidLength { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - f.write_str("Invalid Length") - } -} - -#[cfg(feature = "std")] -impl std::error::Error for InvalidLength {} diff --git a/crypto-mac/Cargo.toml b/crypto-mac/Cargo.toml index 8168c2bdc..4c367b963 100644 --- a/crypto-mac/Cargo.toml +++ b/crypto-mac/Cargo.toml @@ -14,6 +14,7 @@ categories = ["cryptography", "no-std"] [dependencies] generic-array = "0.14" crypto-common = { version = "0.1", path = "../crypto-common/" } +cipher = { version = "0.3.0-pre.4", path = "../cipher/" } subtle = { version = "2", default-features = false } blobby = { version = "0.3", optional = true } diff --git a/crypto-mac/src/lib.rs b/crypto-mac/src/lib.rs index e9db92242..5020bc7a9 100644 --- a/crypto-mac/src/lib.rs +++ b/crypto-mac/src/lib.rs @@ -25,7 +25,8 @@ pub mod dev; #[cfg_attr(docsrs, doc(cfg(feature = "core-api")))] pub mod core_api; -pub use crypto_common::{FixedOutput, FixedOutputReset, FromKey, InvalidLength, Reset, Update}; +pub use cipher::{errors::InvalidLength, FromKey}; +pub use crypto_common::{FixedOutput, FixedOutputReset, Reset, Update}; pub use generic_array::{self, typenum::consts}; use core::fmt; From 2436453238c7ebf0e0cf727ef6602551ec9741c8 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 17 Mar 2021 08:51:51 -0700 Subject: [PATCH 0463/1461] password-hash: bump base64ct to v1.0 (#579) --- Cargo.lock | 12 +++++++++--- password-hash/Cargo.toml | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a60ffc880..3db34ac8a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -49,6 +49,12 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b8a45dc8036c7e52889226a96edacd45831c0dbdb8b803a58b8e0e12613b1a6" +[[package]] +name = "base64ct" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0d27fb6b6f1e43147af148af49d49329413ba781aa0d5e10979831c210173b5" + [[package]] name = "bitvec" version = "0.20.1" @@ -193,7 +199,7 @@ dependencies = [ name = "elliptic-curve" version = "0.9.4" dependencies = [ - "base64ct", + "base64ct 0.2.1", "ff", "funty", "generic-array 0.14.4", @@ -325,7 +331,7 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" name = "password-hash" version = "0.1.1" dependencies = [ - "base64ct", + "base64ct 1.0.0", "rand_core", ] @@ -335,7 +341,7 @@ version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecfab38c6d0f60db6a80b1ee75f1fc980193f9963c43ee2d6f0ac6698e71d96" dependencies = [ - "base64ct", + "base64ct 0.2.1", "der", "spki", "zeroize", diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index e58e3b6b9..10b368429 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -16,7 +16,7 @@ categories = ["cryptography", "no-std"] keywords = ["crypt", "mcf", "password", "pbkdf", "phc"] [dependencies] -base64ct = "0.2" +base64ct = "1" rand_core = { version = "0.6", optional = true, default-features = false } [features] From e3588c1fc3a6529b908976a501ff41e85f17f5ec Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 17 Mar 2021 09:40:37 -0700 Subject: [PATCH 0464/1461] password-hash v0.1.2 (#580) --- Cargo.lock | 2 +- password-hash/CHANGELOG.md | 6 ++++++ password-hash/Cargo.toml | 2 +- password-hash/src/lib.rs | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3db34ac8a..e37a90a60 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -329,7 +329,7 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "password-hash" -version = "0.1.1" +version = "0.1.2" dependencies = [ "base64ct 1.0.0", "rand_core", diff --git a/password-hash/CHANGELOG.md b/password-hash/CHANGELOG.md index 1ece8840a..b72480261 100644 --- a/password-hash/CHANGELOG.md +++ b/password-hash/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.1.2 (2021-03-17) +### Changed +- Bump `base64ct` dependency to v1.0 ([#579]) + +[#579]: https://github.com/RustCrypto/traits/pull/579 + ## 0.1.1 (2021-02-01) ### Added - `Encoding` enum with bcrypt and `crypt(3)` Base64 support ([#515]) diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index 10b368429..2de7cdfa8 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -5,7 +5,7 @@ Traits which describe the functionality of password hashing algorithms, as well as a `no_std`-friendly implementation of the PHC string format (a well-defined subset of the Modular Crypt Format a.k.a. MCF) """ -version = "0.1.1" +version = "0.1.2" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index 77ee32b14..a09625aea 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -39,7 +39,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/password-hash/0.1.1" + html_root_url = "https://docs.rs/password-hash/0.1.2" )] #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] From f912ca9ffa3a72f40c7dc6d7a585476c48e03943 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 17 Mar 2021 10:46:15 -0700 Subject: [PATCH 0465/1461] elliptic-curve: bump base64ct dependency to v1.0 (#581) --- .github/workflows/elliptic-curve.yml | 4 ++-- Cargo.lock | 2 +- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/README.md | 4 ++-- elliptic-curve/src/lib.rs | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index 301ebb930..e4486a08b 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.46.0 # MSRV + - 1.47.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -50,7 +50,7 @@ jobs: strategy: matrix: rust: - - 1.46.0 # MSRV + - 1.47.0 # MSRV - stable - nightly steps: diff --git a/Cargo.lock b/Cargo.lock index e37a90a60..5493cb332 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -199,7 +199,7 @@ dependencies = [ name = "elliptic-curve" version = "0.9.4" dependencies = [ - "base64ct 0.2.1", + "base64ct 1.0.0", "ff", "funty", "generic-array 0.14.4", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 9f70f476b..59d08ac34 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -15,7 +15,7 @@ categories = ["cryptography", "no-std"] keywords = ["crypto", "ecc", "elliptic", "weierstrass"] [dependencies] -base64ct = { version = "0.2", optional = true, default-features = false } +base64ct = { version = "1", optional = true, default-features = false } ff = { version = "0.9", optional = true, default-features = false } funty = { version = "=1.1.0", default-features = false } # see https://github.com/bitvecto-rs/bitvec/issues/105 group = { version = "0.9", optional = true, default-features = false } diff --git a/elliptic-curve/README.md b/elliptic-curve/README.md index 247109ab3..59138d4f9 100644 --- a/elliptic-curve/README.md +++ b/elliptic-curve/README.md @@ -15,7 +15,7 @@ and public/secret keys composed thereof. ## Minimum Supported Rust Version -Requires Rust **1.46** or higher. +Requires Rust **1.47** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -47,7 +47,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/elliptic-curve/badge.svg [docs-link]: https://docs.rs/elliptic-curve/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.46+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.47+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260040-elliptic-curves [build-image]: https://github.com/RustCrypto/elliptic-curves/workflows/elliptic-curve%20crate/badge.svg?branch=master&event=push diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 78d3539c4..4f216f535 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -4,7 +4,7 @@ //! //! ## Minimum Supported Rust Version //! -//! Rust **1.46** or higher. +//! Rust **1.47** or higher. //! //! Minimum supported Rust version can be changed in the future, but it will be //! done with a minor version bump. From 5d295451b120660672479dca8c6e92e816c9cea4 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 17 Mar 2021 11:45:07 -0700 Subject: [PATCH 0466/1461] elliptic-curve v0.9.5 (#582) --- Cargo.lock | 2 +- elliptic-curve/CHANGELOG.md | 16 +++++++++++++++- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 2 +- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5493cb332..68850c167 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -197,7 +197,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.9.4" +version = "0.9.5" dependencies = [ "base64ct 1.0.0", "ff", diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index be4f4e3ba..ff83f157e 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,7 +4,21 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 0.9.4 (2021-02-18) +## 0.9.5 (2021-03-17) +### Added +- Implement `{to,char}_le_bits` for `MockCurve` ([#565]) +- Implement `one()` for mock `Scalar` ([#566]) + +### Changed +- Use string-based OID constants ([#561]) +- Bump `base64ct` dependency to v1.0 ([#581]) + +[#561]: https://github.com/RustCrypto/traits/pull/561 +[#565]: https://github.com/RustCrypto/traits/pull/565 +[#566]: https://github.com/RustCrypto/traits/pull/566 +[#581]: https://github.com/RustCrypto/traits/pull/581 + +## 0.9.4 (2021-02-18) [YANKED] ### Fixed - Breakage related to the `pkcs8` v0.5.1 crate ([#556]) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 59d08ac34..e48c80cea 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -5,7 +5,7 @@ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. """ -version = "0.9.4" # Also update html_root_url in lib.rs when bumping this +version = "0.9.5" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" repository = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve" diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 4f216f535..7da6ca488 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -16,7 +16,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.9.4" + html_root_url = "https://docs.rs/elliptic-curve/0.9.5" )] #[cfg(feature = "alloc")] From eeb3ea7b27a6dfe0c4aa1fe0868afa18e571b274 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 Mar 2021 06:58:36 -0700 Subject: [PATCH 0467/1461] build(deps): bump pkcs8 from 0.5.4 to 0.5.5 (#583) Bumps [pkcs8](https://github.com/RustCrypto/utils) from 0.5.4 to 0.5.5. - [Release notes](https://github.com/RustCrypto/utils/releases) - [Commits](https://github.com/RustCrypto/utils/compare/pkcs8-v0.5.4...pkcs8-v0.5.5) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 16 +++++----------- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 68850c167..59e61101e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -43,12 +43,6 @@ dependencies = [ "syn", ] -[[package]] -name = "base64ct" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b8a45dc8036c7e52889226a96edacd45831c0dbdb8b803a58b8e0e12613b1a6" - [[package]] name = "base64ct" version = "1.0.0" @@ -199,7 +193,7 @@ dependencies = [ name = "elliptic-curve" version = "0.9.5" dependencies = [ - "base64ct 1.0.0", + "base64ct", "ff", "funty", "generic-array 0.14.4", @@ -331,17 +325,17 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" name = "password-hash" version = "0.1.2" dependencies = [ - "base64ct 1.0.0", + "base64ct", "rand_core", ] [[package]] name = "pkcs8" -version = "0.5.4" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecfab38c6d0f60db6a80b1ee75f1fc980193f9963c43ee2d6f0ac6698e71d96" +checksum = "a9c455331e3393451bdf8d49f022442a6f45870b0442820548e921de155e18a7" dependencies = [ - "base64ct 0.2.1", + "base64ct", "der", "spki", "zeroize", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index e48c80cea..664c1bad3 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -21,7 +21,7 @@ funty = { version = "=1.1.0", default-features = false } # see https://github.c group = { version = "0.9", optional = true, default-features = false } hex-literal = { version = "0.3", optional = true } generic-array = { version = "0.14", default-features = false } -pkcs8 = { version = "0.5.4", optional = true } +pkcs8 = { version = "0.5.5", optional = true } rand_core = { version = "0.6", default-features = false } serde = { version = "1", optional = true, default-features = false } serde_json = { version = "1", optional = true, default-features = false, features = ["alloc"] } From 9e0afbc695390f18c2b243e8dcf369fe298b055e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 Mar 2021 07:03:15 -0700 Subject: [PATCH 0468/1461] build(deps): bump async-trait from 0.1.47 to 0.1.48 (#578) Bumps [async-trait](https://github.com/dtolnay/async-trait) from 0.1.47 to 0.1.48. - [Release notes](https://github.com/dtolnay/async-trait/releases) - [Commits](https://github.com/dtolnay/async-trait/compare/0.1.47...0.1.48) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 59e61101e..15f1e9fb1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -34,9 +34,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.47" +version = "0.1.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e098e9c493fdf92832223594d9a164f96bdf17ba81a42aff86f85c76768726a" +checksum = "36ea56748e10732c49404c153638a15ec3d6211ec5ff35d9bb20e13b93576adf" dependencies = [ "proc-macro2", "quote", From 1a0670ba2a5fbe49682dc90069f9997c001a78bb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 Mar 2021 07:25:24 -0700 Subject: [PATCH 0469/1461] build(deps): bump serde from 1.0.123 to 1.0.124 (#576) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.123 to 1.0.124. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.123...v1.0.124) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 15f1e9fb1..a323d7a10 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -385,9 +385,9 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "serde" -version = "1.0.123" +version = "1.0.124" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d5161132722baa40d802cc70b15262b98258453e85e5d1d365c757c73869ae" +checksum = "bd761ff957cb2a45fbb9ab3da6512de9de55872866160b23c25f1a841e99d29f" [[package]] name = "serde_json" From cbdbc921c5d46acf6e3c218e43871d4f9fd78051 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 22 Mar 2021 07:58:10 -0700 Subject: [PATCH 0470/1461] elliptic-curve: bump `pkcs8` to v0.6 (#585) --- Cargo.lock | 16 ++++++++-------- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/dev.rs | 2 +- elliptic-curve/src/lib.rs | 4 ++-- elliptic-curve/src/secret_key/pkcs8.rs | 10 +++++----- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a323d7a10..34db67376 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -118,9 +118,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.4.3" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb27bc55bac783b7cfd5eafba8a3e94ff6d420fc4e04970a207980683145af83" +checksum = "75b8aaf972a93eb4ce235ecea7825c68756361f7657407f4826cc2335ae9766d" [[package]] name = "cpuid-bool" @@ -164,9 +164,9 @@ dependencies = [ [[package]] name = "der" -version = "0.2.8" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff87fc4cc42439753d09185278bb1fdee4710b5b295159cdc0789563528e776f" +checksum = "7516ff8d4f25ddd138caba1b7836ceb3ddd07660213b50e83ae3165320257ba2" dependencies = [ "const-oid", ] @@ -331,9 +331,9 @@ dependencies = [ [[package]] name = "pkcs8" -version = "0.5.5" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9c455331e3393451bdf8d49f022442a6f45870b0442820548e921de155e18a7" +checksum = "b813f58dc6e5d1820868a3c3df3a7ae7852aa2d3d18e98f0d6b20ddd01fe25d7" dependencies = [ "base64ct", "der", @@ -436,9 +436,9 @@ dependencies = [ [[package]] name = "spki" -version = "0.2.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8b07e839e486ce2c6120ace6660ed71e4891eb8c88d52eecdf141e1b70effea" +checksum = "9dae7e047abc519c96350e9484a96c6bf1492348af912fd3446dd2dc323f6268" dependencies = [ "der", ] diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 664c1bad3..d7a0f0ed0 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -21,7 +21,7 @@ funty = { version = "=1.1.0", default-features = false } # see https://github.c group = { version = "0.9", optional = true, default-features = false } hex-literal = { version = "0.3", optional = true } generic-array = { version = "0.14", default-features = false } -pkcs8 = { version = "0.5.5", optional = true } +pkcs8 = { version = "0.6", optional = true } rand_core = { version = "0.6", default-features = false } serde = { version = "1", optional = true, default-features = false } serde_json = { version = "1", optional = true, default-features = false, features = ["alloc"] } diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 252c14019..56ac03bf0 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -49,7 +49,7 @@ impl ProjectiveArithmetic for MockCurve { impl AlgorithmParameters for MockCurve { /// OID for NIST P-256 - const OID: pkcs8::ObjectIdentifier = pkcs8::ObjectIdentifier::parse("1.2.840.10045.3.1.7"); + const OID: pkcs8::ObjectIdentifier = pkcs8::ObjectIdentifier::new("1.2.840.10045.3.1.7"); } #[cfg(feature = "jwk")] diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 7da6ca488..cdb6f92a9 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -93,7 +93,7 @@ use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; #[cfg(feature = "pkcs8")] #[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))] pub const ALGORITHM_OID: pkcs8::ObjectIdentifier = - pkcs8::ObjectIdentifier::parse("1.2.840.10045.2.1"); + pkcs8::ObjectIdentifier::new("1.2.840.10045.2.1"); /// Elliptic curve. /// @@ -131,7 +131,7 @@ pub trait AlgorithmParameters: Curve { fn algorithm_identifier() -> pkcs8::AlgorithmIdentifier<'static> { pkcs8::AlgorithmIdentifier { oid: ALGORITHM_OID, - parameters: Some(Self::OID.into()), + parameters: Some((&Self::OID).into()), } } } diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs index 603ba95e8..d42e0ef86 100644 --- a/elliptic-curve/src/secret_key/pkcs8.rs +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -5,7 +5,7 @@ use crate::{ sec1::{self, UncompressedPointSize, UntaggedPointSize, ValidatePublicKey}, weierstrass, AlgorithmParameters, FieldBytes, Result, ALGORITHM_OID, }; -use core::ops::Add; +use core::{convert::TryInto, ops::Add}; use generic_array::{typenum::U1, ArrayLength}; use pkcs8::{der, FromPrivateKey}; use zeroize::Zeroize; @@ -126,9 +126,9 @@ where let der_message_fields: &[&dyn Encodable] = &[&VERSION, &secret_key_field, &public_key_field]; - let encoded_len = der::sequence::encoded_len(der_message_fields) - .expect(ENCODING_ERROR_MSG) - .to_usize(); + let encoded_len = der::message::encoded_len(der_message_fields) + .and_then(TryInto::try_into) + .expect(ENCODING_ERROR_MSG); let mut der_message = Zeroizing::new(Vec::new()); der_message.reserve(encoded_len); @@ -136,7 +136,7 @@ where let mut encoder = der::Encoder::new(&mut der_message); encoder - .sequence(der_message_fields) + .message(der_message_fields) .expect(ENCODING_ERROR_MSG); encoder.finish().expect(ENCODING_ERROR_MSG); From a99bc2a92710165837080ce6d2098b4647dcc288 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 22 Mar 2021 08:08:21 -0700 Subject: [PATCH 0471/1461] elliptic-curve v0.9.6 (#586) --- Cargo.lock | 2 +- elliptic-curve/CHANGELOG.md | 8 +++++++- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 34db67376..ae0729e96 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -191,7 +191,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.9.5" +version = "0.9.6" dependencies = [ "base64ct", "ff", diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index ff83f157e..addb73387 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,7 +4,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 0.9.5 (2021-03-17) +## 0.9.6 (2021-03-22) +### Changed +- Bump `pkcs8` dependency to v0.6 ([#585]) + +[#585]: https://github.com/RustCrypto/traits/pull/585 + +## 0.9.5 (2021-03-17) [YANKED] ### Added - Implement `{to,char}_le_bits` for `MockCurve` ([#565]) - Implement `one()` for mock `Scalar` ([#566]) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index d7a0f0ed0..0bac6d953 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -5,7 +5,7 @@ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. """ -version = "0.9.5" # Also update html_root_url in lib.rs when bumping this +version = "0.9.6" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" repository = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve" diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index cdb6f92a9..18b93d7b7 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -16,7 +16,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.9.5" + html_root_url = "https://docs.rs/elliptic-curve/0.9.6" )] #[cfg(feature = "alloc")] From e922122260e8ed2f73094483b6e9e3238f73df36 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Mar 2021 10:39:36 -0700 Subject: [PATCH 0472/1461] build(deps): bump serde from 1.0.124 to 1.0.125 (#587) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.124 to 1.0.125. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.124...v1.0.125) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ae0729e96..7c838f6aa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -385,9 +385,9 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "serde" -version = "1.0.124" +version = "1.0.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd761ff957cb2a45fbb9ab3da6512de9de55872866160b23c25f1a841e99d29f" +checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171" [[package]] name = "serde_json" From aa1eaf5b1e4950cbba2a3e0292de6b253e55005a Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 17 Apr 2021 08:48:15 -0700 Subject: [PATCH 0473/1461] elliptic-curve: fix `SecretKey::from_bytes` slice parsing (#592) Closes #588 `SecretKey::from_bytes` was previously attempting to use `TryFrom<&[u8]>` on `GenericArray`, however `GenericArray` actually has a panicking `From` impl, and was therefore receiving panicking `TryFrom` via the blanket impl of `TryFrom` for `From`. This commit adds a regression test which captures the bug, and fixes the implementation to test that the slice is correctly sized. --- aead/src/stream.rs | 14 ++++++++------ elliptic-curve/src/secret_key.rs | 17 ++++++++++------- elliptic-curve/tests/secret_key.rs | 10 ++++++++++ 3 files changed, 28 insertions(+), 13 deletions(-) create mode 100644 elliptic-curve/tests/secret_key.rs diff --git a/aead/src/stream.rs b/aead/src/stream.rs index c61b76fb1..170904559 100644 --- a/aead/src/stream.rs +++ b/aead/src/stream.rs @@ -226,7 +226,7 @@ macro_rules! impl_stream_object { pub fn new(key: &Key, nonce: &Nonce) -> Self where A: NewAead, - S: NewStream + S: NewStream, { Self::from_stream_primitive(S::new(key, nonce)) } @@ -237,7 +237,7 @@ macro_rules! impl_stream_object { pub fn from_aead(aead: A, nonce: &Nonce) -> Self where A: NewAead, - S: NewStream + S: NewStream, { Self::from_stream_primitive(S::from_aead(aead, nonce)) } @@ -291,7 +291,8 @@ macro_rules! impl_stream_object { return Err(Error); } - self.stream.$in_place_op(self.position, false, associated_data, buffer)?; + self.stream + .$in_place_op(self.position, false, associated_data, buffer)?; // Note: overflow checked above self.position += S::COUNTER_INCR; @@ -322,12 +323,13 @@ macro_rules! impl_stream_object { pub fn $last_in_place_method( self, associated_data: &[u8], - buffer: &mut dyn Buffer + buffer: &mut dyn Buffer, ) -> Result<(), Error> { - self.stream.$in_place_op(self.position, true, associated_data, buffer) + self.stream + .$in_place_op(self.position, true, associated_data, buffer) } } - } + }; } impl_stream_object!( diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 54a211426..8f1c06b2b 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -12,10 +12,11 @@ mod pkcs8; use crate::{Curve, Error, FieldBytes, Result}; use core::{ - convert::{TryFrom, TryInto}, + convert::TryFrom, fmt::{self, Debug}, ops::Deref, }; +use generic_array::typenum::Unsigned; use zeroize::Zeroize; #[cfg(feature = "arithmetic")] @@ -103,11 +104,13 @@ where /// Deserialize raw private scalar as a big endian integer pub fn from_bytes(bytes: impl AsRef<[u8]>) -> Result { - bytes - .as_ref() - .try_into() - .ok() - .and_then(C::from_secret_bytes) + let bytes = bytes.as_ref(); + + if bytes.len() != C::FieldSize::to_usize() { + return Err(Error); + } + + C::from_secret_bytes(bytes.into()) .map(|secret_value| SecretKey { secret_value }) .ok_or(Error) } @@ -156,7 +159,7 @@ where UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { - jwk.try_into() + Self::try_from(jwk) } /// Parse a string containing a JSON Web Key (JWK) into a [`SecretKey`]. diff --git a/elliptic-curve/tests/secret_key.rs b/elliptic-curve/tests/secret_key.rs new file mode 100644 index 000000000..a0d1dd260 --- /dev/null +++ b/elliptic-curve/tests/secret_key.rs @@ -0,0 +1,10 @@ +//! Secret key tests + +#![cfg(feature = "dev")] + +use elliptic_curve::dev::SecretKey; + +#[test] +fn undersize_secret_key() { + assert!(SecretKey::from_bytes(&[]).is_err()); +} From d93daefb239d9386e3ef8fa8ec4d220ba599599d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 17 Apr 2021 12:04:20 -0700 Subject: [PATCH 0474/1461] password-hash: update docs for PHC string field (#593) The upstream PR to add this to the spec was merged: https://github.com/P-H-C/phc-string-format/pull/4 --- password-hash/src/lib.rs | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index a09625aea..e2dffe1d2 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -21,7 +21,7 @@ //! represents a parsed "PHC string" with the following format: //! //! ```text -//! $[$=(,=)*][$[$]] +//! $[$v=][$=(,=)*][$[$]] //! ``` //! //! For more information, please see the documentation for [`PasswordHash`]. @@ -185,12 +185,13 @@ pub trait McfHasher { /// PHC strings have the following format: /// /// ```text -/// $[$=(,=)*][$[$]] +/// $[$v=][$=(,=)*][$[$]] /// ``` /// /// where: /// /// - `` is the symbolic name for the function +/// - `` is the algorithm version /// - `` is a parameter name /// - `` is a parameter value /// - `` is an encoding of the salt @@ -200,6 +201,7 @@ pub trait McfHasher { /// /// - a `$` sign; /// - the function symbolic name; +/// - optionally, a `$` sign followed by the algorithm version with a `v=version` format; /// - optionally, a `$` sign followed by one or several parameters, each with a `name=value` format; /// the parameters are separated by commas; /// - optionally, a `$` sign followed by the (encoded) salt value; @@ -217,14 +219,7 @@ pub struct PasswordHash<'a> { /// Optional version field. /// - /// An augmented form of the PHC string format used by Argon2 includes - /// an additional version field out-of-band from other parameters: - /// - /// ```text - /// $[$v=][$=(,=)*][$[$]] - /// ``` - /// - /// See: + /// This corresponds to the `` field in a PHC string. pub version: Option, /// Algorithm-specific parameters. From 33351a1d6a64e4a40eaa1a9ef7ce74c58681dca6 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 17 Apr 2021 12:15:59 -0700 Subject: [PATCH 0475/1461] password-hash: fix broken `b64` links (#594) This module no-longer exists as it was replaced by the `base64ct` crate --- password-hash/src/output.rs | 8 ++++---- password-hash/src/salt.rs | 6 +++--- password-hash/src/value.rs | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/password-hash/src/output.rs b/password-hash/src/output.rs index f95e41bdb..9e715da35 100644 --- a/password-hash/src/output.rs +++ b/password-hash/src/output.rs @@ -87,7 +87,7 @@ impl Output { MAX_LENGTH } - /// Maximum length of [`Output`] when encoded as [`b64`] string: 86-bytes + /// Maximum length of [`Output`] when encoded as B64 string: 86-bytes /// (i.e. 86 ASCII characters) pub const fn b64_max_len() -> usize { ((MAX_LENGTH * 4) / 3) + 1 @@ -153,13 +153,13 @@ impl Output { usize::from(self.length) } - /// Parse [`b64`]-encoded [`Output`], i.e. using the PHC string + /// Parse B64-encoded [`Output`], i.e. using the PHC string /// specification's restricted interpretation of Base64. pub fn b64_decode(input: &str) -> Result { Self::decode(input, Encoding::B64) } - /// Write [`b64`]-encoded [`Output`] to the provided buffer, returning + /// Write B64-encoded [`Output`] to the provided buffer, returning /// a sub-slice containing the encoded data. /// /// Returns an error if the buffer is too short to contain the output. @@ -185,7 +185,7 @@ impl Output { Ok(encoding.encode(self.as_ref(), out)?) } - /// Get the length of this [`Output`] when encoded as [`b64`]. + /// Get the length of this [`Output`] when encoded as B64. pub fn b64_len(&self) -> usize { Encoding::B64.encoded_len(self.as_ref()) } diff --git a/password-hash/src/salt.rs b/password-hash/src/salt.rs index 6dc7876e1..0aa7438fa 100644 --- a/password-hash/src/salt.rs +++ b/password-hash/src/salt.rs @@ -117,9 +117,9 @@ impl<'a> Salt<'a> { Ok(Self(input.try_into()?)) } - /// Attempt to decode a [`b64`][`crate::b64`]-encoded [`Salt`], writing the - /// decoded result into the provided buffer, and returning a slice of the - /// buffer containing the decoded result on success. + /// Attempt to decode a B64-encoded [`Salt`], writing the decoded result + /// into the provided buffer, and returning a slice of the buffer + /// containing the decoded result on success. /// /// [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#argon2-encoding pub fn b64_decode<'b>(&self, buf: &'b mut [u8]) -> Result<&'b [u8], B64Error> { diff --git a/password-hash/src/value.rs b/password-hash/src/value.rs index 4e4e278a8..bb7d52b65 100644 --- a/password-hash/src/value.rs +++ b/password-hash/src/value.rs @@ -69,7 +69,7 @@ impl<'a> Value<'a> { Ok(Self(input)) } - /// Attempt to decode a [`b64`]-encoded [`Value`], writing the decoded + /// Attempt to decode a B64-encoded [`Value`], writing the decoded /// result into the provided buffer, and returning a slice of the buffer /// containing the decoded result on success. /// From c333b9f6ab56a5d36985b2cddb7a94cdd7d3a476 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 17 Apr 2021 12:28:33 -0700 Subject: [PATCH 0476/1461] password-hash v0.1.3 (#595) --- Cargo.lock | 2 +- password-hash/CHANGELOG.md | 10 ++++++++++ password-hash/Cargo.toml | 2 +- password-hash/src/lib.rs | 2 +- 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7c838f6aa..2445a9c82 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -323,7 +323,7 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "password-hash" -version = "0.1.2" +version = "0.1.3" dependencies = [ "base64ct", "rand_core", diff --git a/password-hash/CHANGELOG.md b/password-hash/CHANGELOG.md index b72480261..fdfaf191b 100644 --- a/password-hash/CHANGELOG.md +++ b/password-hash/CHANGELOG.md @@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.1.3 (2021-04-17) +### Changed +- Update docs for PHC string field ([#593]) + +### Fixed +- Broken `b64` links in rustdoc ([#594]) + +[#593]: https://github.com/RustCrypto/traits/pull/593 +[#594]: https://github.com/RustCrypto/traits/pull/594 + ## 0.1.2 (2021-03-17) ### Changed - Bump `base64ct` dependency to v1.0 ([#579]) diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index 2de7cdfa8..4e474866e 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -5,7 +5,7 @@ Traits which describe the functionality of password hashing algorithms, as well as a `no_std`-friendly implementation of the PHC string format (a well-defined subset of the Modular Crypt Format a.k.a. MCF) """ -version = "0.1.2" +version = "0.1.3" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index e2dffe1d2..5b310b1c0 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -39,7 +39,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/password-hash/0.1.2" + html_root_url = "https://docs.rs/password-hash/0.1.3" )] #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] From 67b596699042984e96459dae8f12b1558bed6b4a Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 17 Apr 2021 12:47:25 -0700 Subject: [PATCH 0477/1461] aead: require `heapless` v0.6.1 (#596) This is mostly to clear the https://deps.rs "insecure" warning from the repo. --- aead/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aead/Cargo.toml b/aead/Cargo.toml index 763141d97..adb1edc55 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -18,7 +18,7 @@ categories = ["cryptography", "no-std"] generic-array = { version = "0.14", default-features = false } blobby = { version = "0.3", optional = true } -heapless = { version = "0.6", optional = true, default-features = false } +heapless = { version = "0.6.1", optional = true, default-features = false } rand_core = { version = "0.6", optional = true } [features] From 0394df4417967adfcd23df80e1763fc8844247bc Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 18 Apr 2021 13:14:16 -0700 Subject: [PATCH 0478/1461] elliptic-curve: pin to patched bitvec (#597) With this `bitvec` patch, we no longer need to pin `funty`: https://github.com/bitvecto-rs/bitvec/issues/105 --- Cargo.lock | 6 +++--- elliptic-curve/Cargo.toml | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2445a9c82..fa366d6f5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -51,9 +51,9 @@ checksum = "d0d27fb6b6f1e43147af148af49d49329413ba781aa0d5e10979831c210173b5" [[package]] name = "bitvec" -version = "0.20.1" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5011ffc90248764d7005b0e10c7294f5aa1bd87d9dd7248f4ad475b347c294d" +checksum = "1f682656975d3a682daff957be4ddeb65d6ad656737cd821f2d00685ae466af1" dependencies = [ "funty", "radium", @@ -194,8 +194,8 @@ name = "elliptic-curve" version = "0.9.6" dependencies = [ "base64ct", + "bitvec", "ff", - "funty", "generic-array 0.14.4", "group", "hex-literal 0.3.1", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 0bac6d953..1041587b3 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -16,8 +16,8 @@ keywords = ["crypto", "ecc", "elliptic", "weierstrass"] [dependencies] base64ct = { version = "1", optional = true, default-features = false } +bitvec = { version = "0.20.2", optional = true, default-features = false } ff = { version = "0.9", optional = true, default-features = false } -funty = { version = "=1.1.0", default-features = false } # see https://github.com/bitvecto-rs/bitvec/issues/105 group = { version = "0.9", optional = true, default-features = false } hex-literal = { version = "0.3", optional = true } generic-array = { version = "0.14", default-features = false } @@ -34,7 +34,7 @@ hex-literal = "0.3" [features] default = ["arithmetic"] alloc = [] -arithmetic = ["ff", "group"] +arithmetic = ["bitvec", "ff", "group"] dev = ["arithmetic", "hex-literal", "pem", "zeroize"] ecdh = ["arithmetic", "zeroize"] hazmat = [] From 44f9de2ad242004e5428f49388971a82706e6ca0 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 19 Apr 2021 16:04:16 -0700 Subject: [PATCH 0479/1461] password-hash: replace length `const fn`s with constants (#600) Replaces functions with namespaced constant values. Deprecates the old functions, i.e. non-breaking change. --- password-hash/src/ident.rs | 17 ++++++++----- password-hash/src/output.rs | 38 ++++++++++++++++------------ password-hash/src/salt.rs | 49 ++++++++++++++++++------------------- password-hash/src/value.rs | 11 +++++---- 4 files changed, 64 insertions(+), 51 deletions(-) diff --git a/password-hash/src/ident.rs b/password-hash/src/ident.rs index 0092cfdec..50f6949ea 100644 --- a/password-hash/src/ident.rs +++ b/password-hash/src/ident.rs @@ -19,9 +19,6 @@ use crate::errors::ParseError; use core::{convert::TryFrom, fmt, ops::Deref, str}; -/// Maximum size of an identifier. -const MAX_LENGTH: usize = 32; - /// Algorithm or parameter identifier. /// /// This type encompasses both the "function symbolic name" and "parameter name" @@ -42,8 +39,16 @@ impl<'a> Ident<'a> { /// /// This value corresponds to the maximum size of a function symbolic names /// and parameter names according to the PHC string format. + /// Maximum length of an [`Ident`] - 32 ASCII characters (i.e. 32-bytes). + /// + /// This value corresponds to the maximum size of a function symbolic names + /// and parameter names according to the PHC string format. + const MAX_LENGTH: usize = 32; + + /// Maximum length of an [`Ident`] - 32 ASCII characters (i.e. 32-bytes). + #[deprecated(since = "0.1.4", note = "use Ident::MAX_LENGTH instead")] pub const fn max_len() -> usize { - MAX_LENGTH + Self::MAX_LENGTH } /// Parse an [`Ident`] from a string. @@ -71,7 +76,7 @@ impl<'a> Ident<'a> { } const_assert!(!input.is_empty(), "PHC ident string can't be empty"); - const_assert!(input.len() <= MAX_LENGTH, "PHC ident string too long"); + const_assert!(input.len() <= Self::MAX_LENGTH, "PHC ident string too long"); macro_rules! validate_chars { ($($pos:expr),+) => { @@ -125,7 +130,7 @@ impl<'a> TryFrom<&'a str> for Ident<'a> { } let bytes = s.as_bytes(); - let too_long = bytes.len() > MAX_LENGTH; + let too_long = bytes.len() > Self::MAX_LENGTH; for &c in bytes { if !is_char_valid(c) { diff --git a/password-hash/src/output.rs b/password-hash/src/output.rs index 9e715da35..68430a8b6 100644 --- a/password-hash/src/output.rs +++ b/password-hash/src/output.rs @@ -3,9 +3,6 @@ use crate::{Encoding, OutputError}; use core::{cmp::PartialEq, convert::TryFrom, fmt, str::FromStr}; -/// Maximum length of password hash function outputs. -const MAX_LENGTH: usize = 64; - /// Output from password hashing functions, i.e. the "hash" or "digest" /// as raw bytes. /// @@ -62,7 +59,7 @@ const MAX_LENGTH: usize = 64; #[derive(Copy, Clone, Eq)] pub struct Output { /// Byte array containing a password hashing function output. - bytes: [u8; MAX_LENGTH], + bytes: [u8; Self::MAX_LENGTH], /// Length of the password hashing function output in bytes. length: u8, @@ -73,24 +70,35 @@ pub struct Output { #[allow(clippy::len_without_is_empty)] impl Output { - /// Minimum length of [`Output`] string: 10-bytes. + /// Minimum length of a [`Output`] string: 10-bytes. + pub const MIN_LENGTH: usize = 10; + + /// Maximum length of [`Output`] string: 64-bytes. /// /// See type-level documentation about [`Output`] for more information. + pub const MAX_LENGTH: usize = 64; + + /// Maximum length of [`Output`] when encoded as B64 string: 86-bytes + /// (i.e. 86 ASCII characters) + pub const B64_MAX_LENGTH: usize = ((Self::MAX_LENGTH * 4) / 3) + 1; + + /// Minimum length of a [`Output`] string: 10-bytes. + #[deprecated(since = "0.1.4", note = "use Output::MIN_LENGTH instead")] pub const fn min_len() -> usize { - 10 + Self::MIN_LENGTH } /// Maximum length of [`Output`] string: 64-bytes. - /// - /// See type-level documentation about [`Output`] for more information. + #[deprecated(since = "0.1.4", note = "use Output::MAX_LENGTH instead")] pub const fn max_len() -> usize { - MAX_LENGTH + Self::MAX_LENGTH } /// Maximum length of [`Output`] when encoded as B64 string: 86-bytes /// (i.e. 86 ASCII characters) + #[deprecated(since = "0.1.4", note = "use Output::B64_MAX_LENGTH instead")] pub const fn b64_max_len() -> usize { - ((MAX_LENGTH * 4) / 3) + 1 + Self::B64_MAX_LENGTH } /// Create a [`Output`] from the given byte slice, validating it according @@ -120,15 +128,15 @@ impl Output { where F: FnOnce(&mut [u8]) -> Result<(), OutputError>, { - if output_size < Self::min_len() { + if output_size < Self::MIN_LENGTH { return Err(OutputError::TooShort); } - if output_size > Self::max_len() { + if output_size > Self::MAX_LENGTH { return Err(OutputError::TooLong); } - let mut bytes = [0u8; MAX_LENGTH]; + let mut bytes = [0u8; Self::MAX_LENGTH]; f(&mut bytes[..output_size])?; Ok(Self { @@ -169,7 +177,7 @@ impl Output { /// Decode the given input string using the specified [`Encoding`]. pub fn decode(input: &str, encoding: Encoding) -> Result { - let mut bytes = [0u8; MAX_LENGTH]; + let mut bytes = [0u8; Self::MAX_LENGTH]; encoding .decode(input, &mut bytes) .map_err(Into::into) @@ -231,7 +239,7 @@ impl TryFrom<&[u8]> for Output { impl fmt::Display for Output { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut buffer = [0u8; Self::b64_max_len()]; + let mut buffer = [0u8; Self::B64_MAX_LENGTH]; self.encode(&mut buffer, self.encoding) .map_err(|_| fmt::Error) .and_then(|encoded| f.write_str(encoded)) diff --git a/password-hash/src/salt.rs b/password-hash/src/salt.rs index 0aa7438fa..c69d8f37a 100644 --- a/password-hash/src/salt.rs +++ b/password-hash/src/salt.rs @@ -82,35 +82,43 @@ pub struct Salt<'a>(Value<'a>); #[allow(clippy::len_without_is_empty)] impl<'a> Salt<'a> { - /// Minimum length of a [`Salt`] string: 2-bytes. + /// Minimum length of a [`Salt`] string: 4-bytes. + pub const MIN_LENGTH: usize = 4; + + /// Maximum length of a [`Salt`] string: 64-bytes. /// - /// NOTE: this is below the recommended - // TODO(tarcieri): support shorter salts for MCF? + /// See type-level documentation about [`Salt`] for more information. + pub const MAX_LENGTH: usize = 64; + + /// Recommended length of a salt: 16-bytes. + pub const RECOMMENDED_LENGTH: usize = 16; + + /// Minimum length of a [`Salt`] string: 4-bytes. + #[deprecated(since = "0.1.4", note = "use Salt::MIN_LENGTH instead")] pub const fn min_len() -> usize { - 4 + Self::MIN_LENGTH } /// Maximum length of a [`Salt`] string: 64-bytes. - /// - /// See type-level documentation about [`Salt`] for more information. + #[deprecated(since = "0.1.4", note = "use Salt::MAX_LENGTH instead")] pub const fn max_len() -> usize { - 64 + Self::MAX_LENGTH } /// Recommended length of a salt: 16-bytes. + #[deprecated(since = "0.1.4", note = "use Salt::RECOMMENDED_LENGTH instead")] pub const fn recommended_len() -> usize { - 16 + Self::RECOMMENDED_LENGTH } /// Create a [`Salt`] from the given `str`, validating it according to /// [`Salt::min_len`] and [`Salt::max_len`] length restrictions. pub fn new(input: &'a str) -> Result { - // TODO(tarcieri): support shorter salts for MCF? - if input.len() < Self::min_len() { + if input.len() < Self::MIN_LENGTH { return Err(ParseError::TooShort); } - if input.len() > Self::max_len() { + if input.len() > Self::MAX_LENGTH { return Err(ParseError::TooLong); } @@ -172,7 +180,7 @@ impl<'a> fmt::Debug for Salt<'a> { #[derive(Clone, Debug, Eq)] pub struct SaltString { /// Byte array containing an ASCiI-encoded string. - bytes: [u8; Salt::max_len()], + bytes: [u8; Salt::MAX_LENGTH], /// Length of the string in ASCII characters (i.e. bytes). length: u8, @@ -184,7 +192,7 @@ impl SaltString { #[cfg(feature = "rand_core")] #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] pub fn generate(mut rng: impl CryptoRng + RngCore) -> Self { - let mut bytes = [0u8; Salt::recommended_len()]; + let mut bytes = [0u8; Salt::RECOMMENDED_LENGTH]; rng.fill_bytes(&mut bytes); Self::b64_encode(&bytes).expect(INVARIANT_VIOLATED_MSG) } @@ -196,8 +204,8 @@ impl SaltString { let length = s.as_bytes().len(); - if length < Salt::max_len() { - let mut bytes = [0u8; Salt::max_len()]; + if length < Salt::MAX_LENGTH { + let mut bytes = [0u8; Salt::MAX_LENGTH]; bytes[..length].copy_from_slice(s.as_bytes()); Ok(SaltString { bytes, @@ -212,7 +220,7 @@ impl SaltString { /// /// Returns `None` if the slice is too long. pub fn b64_encode(input: &[u8]) -> Result { - let mut bytes = [0u8; Salt::max_len()]; + let mut bytes = [0u8; Salt::MAX_LENGTH]; let length = Encoding::B64.encode(input, &mut bytes)?.len() as u8; Ok(Self { bytes, length }) } @@ -249,15 +257,6 @@ impl AsRef for SaltString { } } -impl Default for SaltString { - fn default() -> SaltString { - SaltString { - bytes: [0u8; Salt::max_len()], - length: 0, - } - } -} - impl PartialEq for SaltString { fn eq(&self, other: &Self) -> bool { // Ensure comparisons always honor the initialized portion of the buffer diff --git a/password-hash/src/value.rs b/password-hash/src/value.rs index bb7d52b65..3beb55718 100644 --- a/password-hash/src/value.rs +++ b/password-hash/src/value.rs @@ -16,9 +16,6 @@ use crate::{B64Error, Encoding, ParseError}; use core::{convert::TryFrom, fmt, str}; -/// Maximum size of a parameter value in ASCII characters. -const MAX_LENGTH: usize = 48; - /// Type used to represent decimal (i.e. integer) values. pub type Decimal = u32; @@ -53,14 +50,18 @@ impl<'a> Value<'a> { /// This implementation rounds that up to 48 as a safe maximum limit. /// /// [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#argon2-encoding + pub const MAX_LENGTH: usize = 48; + + /// Maximum length of an [`Value`] - 48 ASCII characters (i.e. 48-bytes). + #[deprecated(since = "0.1.4", note = "use Value::MAX_LENGTH instead")] pub const fn max_len() -> usize { - MAX_LENGTH + Self::MAX_LENGTH } /// Parse a [`Value`] from the provided `str`, validating it according to /// the PHC string format's rules. pub fn new(input: &'a str) -> Result { - if input.as_bytes().len() > MAX_LENGTH { + if input.as_bytes().len() > Self::MAX_LENGTH { return Err(ParseError::TooLong); } From b564f8be97f5edcbfc372cb50b1397204d885fc2 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 19 Apr 2021 16:13:55 -0700 Subject: [PATCH 0480/1461] password-hash v0.1.4 (#601) --- Cargo.lock | 2 +- password-hash/CHANGELOG.md | 9 +++++++++ password-hash/Cargo.toml | 2 +- password-hash/src/lib.rs | 2 +- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fa366d6f5..af727dd9b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -323,7 +323,7 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "password-hash" -version = "0.1.3" +version = "0.1.4" dependencies = [ "base64ct", "rand_core", diff --git a/password-hash/CHANGELOG.md b/password-hash/CHANGELOG.md index fdfaf191b..cd329b717 100644 --- a/password-hash/CHANGELOG.md +++ b/password-hash/CHANGELOG.md @@ -5,6 +5,15 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.1.4 (2021-04-19) +### Added +- Length constants ([#600]) + +### Changed +- Deprecate functions for obtaining length constants ([#600]) + +[#600]: https://github.com/RustCrypto/traits/pull/600 + ## 0.1.3 (2021-04-17) ### Changed - Update docs for PHC string field ([#593]) diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index 4e474866e..e1aa67ce1 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -5,7 +5,7 @@ Traits which describe the functionality of password hashing algorithms, as well as a `no_std`-friendly implementation of the PHC string format (a well-defined subset of the Modular Crypt Format a.k.a. MCF) """ -version = "0.1.3" +version = "0.1.4" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index 5b310b1c0..1c3fff54b 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -39,7 +39,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/password-hash/0.1.3" + html_root_url = "https://docs.rs/password-hash/0.1.4" )] #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] From 984b541d0287eb516dc8a5787bfbcf251c7b9c65 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 19 Apr 2021 16:30:29 -0700 Subject: [PATCH 0481/1461] Cargo.lock: bump dependencies (#602) --- Cargo.lock | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index af727dd9b..6b1244973 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -34,9 +34,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.48" +version = "0.1.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36ea56748e10732c49404c153638a15ec3d6211ec5ff35d9bb20e13b93576adf" +checksum = "0b98e84bbb4cbcdd97da190ba0c58a1bb0de2c1fdf67d159e192ed766aeca722" dependencies = [ "proc-macro2", "quote", @@ -79,7 +79,7 @@ dependencies = [ [[package]] name = "block-buffer" version = "0.10.0-pre.2" -source = "git+https://github.com/RustCrypto/utils?branch=block_mode#092f0d0ea4ee317d92fbaa5bfecc4433cdcdd196" +source = "git+https://github.com/RustCrypto/utils?branch=block_mode#39ee346fde26516678ca3700b88c53b288b39e1c" dependencies = [ "block-padding", "generic-array 0.14.4", @@ -88,16 +88,16 @@ dependencies = [ [[package]] name = "block-padding" version = "0.3.0-pre" -source = "git+https://github.com/RustCrypto/utils?branch=block_mode#092f0d0ea4ee317d92fbaa5bfecc4433cdcdd196" +source = "git+https://github.com/RustCrypto/utils?branch=block_mode#39ee346fde26516678ca3700b88c53b288b39e1c" dependencies = [ "generic-array 0.14.4", ] [[package]] name = "byteorder" -version = "1.4.2" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae44d1a3d5a19df61dd0c8beb138458ac2a53a7ac09eba97d55592540004306b" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "cfg-if" @@ -118,9 +118,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75b8aaf972a93eb4ce235ecea7825c68756361f7657407f4826cc2335ae9766d" +checksum = "af497ba993c3f3c416a0e1e1d84b81c3e0b131c4c67105a391920ba4dfa24d2d" [[package]] name = "cpuid-bool" @@ -164,9 +164,9 @@ dependencies = [ [[package]] name = "der" -version = "0.3.0" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7516ff8d4f25ddd138caba1b7836ceb3ddd07660213b50e83ae3165320257ba2" +checksum = "83dc83d0b59f92103d8e661e60526338ad3aeb0c15fa4a29a14b6a9b1ac8a43c" dependencies = [ "const-oid", ] @@ -349,9 +349,9 @@ checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" [[package]] name = "proc-macro2" -version = "1.0.24" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" +checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec" dependencies = [ "unicode-xid", ] @@ -457,9 +457,9 @@ checksum = "1e81da0851ada1f3e9d4312c704aa4f8806f0f9d69faaf8df2f3464b4a9437c2" [[package]] name = "syn" -version = "1.0.61" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed22b90a0e734a23a7610f4283ac9e5acfb96cbb30dfefa540d66f866f1c09c5" +checksum = "48fe99c6bd8b1cc636890bcc071842de909d902c81ac7dab53ba33c421ab8ffb" dependencies = [ "proc-macro2", "quote", @@ -486,9 +486,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "typenum" -version = "1.12.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" +checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" [[package]] name = "unicode-xid" @@ -506,9 +506,9 @@ dependencies = [ [[package]] name = "version_check" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" [[package]] name = "wyz" @@ -518,6 +518,6 @@ checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" [[package]] name = "zeroize" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81a974bcdd357f0dca4d41677db03436324d45a4c9ed2d0b873a5a360ce41c36" +checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" From b35bf9f610f267d49cf1992d037111db03bb512a Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 21 Apr 2021 07:23:48 -0700 Subject: [PATCH 0482/1461] elliptic-curve: add Order trait (#603) Adds a trait which notably does *not* depend on the `arithmetic` feature which allows associating a constant for the curve's order with a particular curve type. Since it stores the curve type as a constant, it's not possible to use `GenericArray`, so instead it has each curve specify a `Limbs` type which is used as the type for an `ORDER` constant. The longer-term goal will be to merge this with the `Curve` trait, ensuring that every curve implementation has a known order regardless of whether it provides an arithmetic backend or not. This can be used as the foundation for making certain functionality generic across curve implementations at a baseline, such as checking if scalars are in-range, and as such can simplify things which are presently conditionally defined based on the presence or absence of an arithmetic backend. --- elliptic-curve/src/lib.rs | 9 +++++++-- elliptic-curve/src/order.rs | 31 +++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 elliptic-curve/src/order.rs diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 18b93d7b7..37d4b2add 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -25,12 +25,14 @@ extern crate alloc; #[cfg(feature = "std")] extern crate std; -mod error; pub mod ops; pub mod sec1; pub mod util; pub mod weierstrass; +mod error; +mod order; + #[cfg(feature = "arithmetic")] mod point; #[cfg(feature = "arithmetic")] @@ -52,7 +54,10 @@ mod jwk; #[cfg(feature = "zeroize")] mod secret_key; -pub use self::error::{Error, Result}; +pub use self::{ + error::{Error, Result}, + order::Order, +}; pub use generic_array::{self, typenum::consts}; pub use rand_core; diff --git a/elliptic-curve/src/order.rs b/elliptic-curve/src/order.rs new file mode 100644 index 000000000..8a6937cea --- /dev/null +++ b/elliptic-curve/src/order.rs @@ -0,0 +1,31 @@ +//! Low-level elliptic curve parameters. + +use crate::Curve; +use core::fmt::Debug; + +/// Order of an elliptic curve group. +/// +/// This trait is available even when the `arithmetic` feature of the crate +/// is disabled and does not require any additional crate dependencies. +/// +/// This trait is useful for supporting a baseline level of functionality +/// across curve implementations, even ones which do not provide a field +/// arithmetic backend. +// TODO(tarcieri): merge this with the `Curve` type in the next release? +pub trait Order: Curve { + /// Type representing the "limbs" of the curves group's order on + /// 32-bit platforms. + #[cfg(target_pointer_width = "32")] + type Limbs: AsRef<[u32]> + Copy + Debug; + + /// Type representing the "limbs" of the curves group's order on + /// 64-bit platforms. + #[cfg(target_pointer_width = "64")] + type Limbs: AsRef<[u64]> + Copy + Debug; + + /// Order constant (a.k.a. `N`). + /// + /// Subdivided into either 32-bit or 64-bit "limbs" (depending on the + /// target CPU's word size), specified from least to most significant. + const ORDER: Self::Limbs; +} From 159714ea312f05779dc1104c511248ac3df68b50 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 21 Apr 2021 07:40:23 -0700 Subject: [PATCH 0483/1461] elliptic-curve: pkcs8 import fixes (#604) --- elliptic-curve/src/secret_key/pkcs8.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs index d42e0ef86..23f0a5ed6 100644 --- a/elliptic-curve/src/secret_key/pkcs8.rs +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -3,9 +3,9 @@ use super::{SecretKey, SecretValue}; use crate::{ sec1::{self, UncompressedPointSize, UntaggedPointSize, ValidatePublicKey}, - weierstrass, AlgorithmParameters, FieldBytes, Result, ALGORITHM_OID, + weierstrass, AlgorithmParameters, FieldBytes, ALGORITHM_OID, }; -use core::{convert::TryInto, ops::Add}; +use core::ops::Add; use generic_array::{typenum::U1, ArrayLength}; use pkcs8::{der, FromPrivateKey}; use zeroize::Zeroize; @@ -21,14 +21,17 @@ use { AffinePoint, ProjectiveArithmetic, ProjectivePoint, }, alloc::vec::Vec, - core::{fmt::Debug, iter}, + core::{convert::TryInto, fmt::Debug, iter}, pkcs8::{der::Encodable, ToPrivateKey}, zeroize::Zeroizing, }; // Imports for actual PEM support #[cfg(feature = "pem")] -use {crate::error::Error, core::str::FromStr}; +use { + crate::{error::Error, Result}, + core::str::FromStr, +}; /// Version const VERSION: u8 = 1; From 98a5266fb186ee8f138a448c24f90a9b2a8fe15d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 21 Apr 2021 07:58:45 -0700 Subject: [PATCH 0484/1461] elliptic-curve v0.9.7 (#605) --- Cargo.lock | 2 +- elliptic-curve/CHANGELOG.md | 10 ++++++++++ elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 2 +- 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6b1244973..677952a95 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -191,7 +191,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.9.6" +version = "0.9.7" dependencies = [ "base64ct", "bitvec", diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index addb73387..c23cd5c91 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.9.7 (2021-04-21) +### Added +- `Order` trait ([#603]) + +### Fixed +- Warnings from `pkcs8` imports ([#604]) + +[#603]: https://github.com/RustCrypto/traits/pull/603 +[#604]: https://github.com/RustCrypto/traits/pull/604 + ## 0.9.6 (2021-03-22) ### Changed - Bump `pkcs8` dependency to v0.6 ([#585]) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 1041587b3..73b60f28f 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -5,7 +5,7 @@ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. """ -version = "0.9.6" # Also update html_root_url in lib.rs when bumping this +version = "0.9.7" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" repository = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve" diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 37d4b2add..992b299b5 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -16,7 +16,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.9.6" + html_root_url = "https://docs.rs/elliptic-curve/0.9.7" )] #[cfg(feature = "alloc")] From 521ce3eb03a07dca4d0df97245840c803d2bcc45 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 21 Apr 2021 08:46:49 -0700 Subject: [PATCH 0485/1461] elliptic-curve: define Order for MockCurve (#606) --- elliptic-curve/src/dev.rs | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 56ac03bf0..388a95f98 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -13,7 +13,7 @@ use crate::{ util::sbb64, weierstrass, zeroize::Zeroize, - AlgorithmParameters, Curve, ProjectiveArithmetic, + AlgorithmParameters, Curve, Order, ProjectiveArithmetic, }; use core::{ convert::{TryFrom, TryInto}, @@ -41,6 +41,34 @@ impl Curve for MockCurve { type FieldSize = U32; } +#[cfg(target_pointer_width = "32")] +impl Order for MockCurve { + type Limbs = [u32; 8]; + + const ORDER: Self::Limbs = [ + 0xfc63_2551, + 0xf3b9_cac2, + 0xa717_9e84, + 0xbce6_faad, + 0xffff_ffff, + 0xffff_ffff, + 0x0000_0000, + 0xffff_ffff, + ]; +} + +#[cfg(target_pointer_width = "64")] +impl Order for MockCurve { + type Limbs = [u64; 4]; + + const ORDER: Self::Limbs = [ + 0xf3b9_cac2_fc63_2551, + 0xbce6_faad_a717_9e84, + 0xffff_ffff_ffff_ffff, + 0xffff_ffff_0000_0000, + ]; +} + impl weierstrass::Curve for MockCurve {} impl ProjectiveArithmetic for MockCurve { From 0a2611520fb8f40176db3281df09a5947c8282b5 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 21 Apr 2021 09:01:25 -0700 Subject: [PATCH 0486/1461] elliptic-curve v0.9.8 (#607) --- Cargo.lock | 2 +- elliptic-curve/CHANGELOG.md | 6 ++++++ elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 677952a95..91ffffa8e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -191,7 +191,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.9.7" +version = "0.9.8" dependencies = [ "base64ct", "bitvec", diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index c23cd5c91..3259bc922 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.9.8 (2021-04-21) +### Added +- Define `Order` for `MockCurve` ([#606]) + +[#606]: https://github.com/RustCrypto/traits/pull/606 + ## 0.9.7 (2021-04-21) ### Added - `Order` trait ([#603]) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 73b60f28f..187c1a8c4 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -5,7 +5,7 @@ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. """ -version = "0.9.7" # Also update html_root_url in lib.rs when bumping this +version = "0.9.8" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" repository = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve" diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 992b299b5..0cf72e281 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -16,7 +16,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.9.7" + html_root_url = "https://docs.rs/elliptic-curve/0.9.8" )] #[cfg(feature = "alloc")] From 933f4deefd742678fe21fdf89371591662db675c Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 21 Apr 2021 10:35:35 -0700 Subject: [PATCH 0487/1461] elliptic-curve: add `Order::is_scalar_repr_in_range` (#608) Adds a method for checking if `FieldBytes` is in range of `C::ORDER` when interpreted as a big endian integer. This is a generic implementation which does not require an arithmetic backend for a given curve. --- elliptic-curve/src/order.rs | 87 +++++++++++++++++++++++++++++++++++-- 1 file changed, 84 insertions(+), 3 deletions(-) diff --git a/elliptic-curve/src/order.rs b/elliptic-curve/src/order.rs index 8a6937cea..5a5ff5247 100644 --- a/elliptic-curve/src/order.rs +++ b/elliptic-curve/src/order.rs @@ -1,7 +1,14 @@ //! Low-level elliptic curve parameters. -use crate::Curve; -use core::fmt::Debug; +use crate::{Curve, FieldBytes}; +use core::{convert::TryInto, fmt::Debug, mem}; +use subtle::Choice; + +// TODO(tarcieri): unify these into a target-width gated `sbb` +#[cfg(target_pointer_width = "32")] +use crate::util::sbb32; +#[cfg(target_pointer_width = "64")] +use crate::util::sbb64; /// Order of an elliptic curve group. /// @@ -23,9 +30,83 @@ pub trait Order: Curve { #[cfg(target_pointer_width = "64")] type Limbs: AsRef<[u64]> + Copy + Debug; - /// Order constant (a.k.a. `N`). + /// Order constant. /// /// Subdivided into either 32-bit or 64-bit "limbs" (depending on the /// target CPU's word size), specified from least to most significant. const ORDER: Self::Limbs; + + /// Check that the given serialized scalar field element is in range. + /// + /// Field element must be serialized as a big endian integer. + #[cfg(target_pointer_width = "32")] + fn is_scalar_repr_in_range(fe_bytes: &FieldBytes) -> Choice { + assert_eq!( + mem::size_of::(), + mem::size_of::>() + ); + + let mut borrow = 0; + + for (i, chunk) in fe_bytes.as_ref().chunks(4).rev().enumerate() { + let limb = u32::from_be_bytes(chunk.try_into().unwrap()); + borrow = sbb32(limb, Self::ORDER.as_ref()[i], borrow).1; + } + + Choice::from((borrow as u8) & 1) + } + + /// Check that the given scalar field repr is in range. + /// + /// Field element must be serialized as a big endian integer. + #[cfg(target_pointer_width = "64")] + fn is_scalar_repr_in_range(fe_bytes: &FieldBytes) -> Choice { + assert_eq!( + mem::size_of::(), + mem::size_of::>() + ); + + let mut borrow = 0; + + for (i, chunk) in fe_bytes.as_ref().chunks(8).rev().enumerate() { + let limb = u64::from_be_bytes(chunk.try_into().unwrap()); + borrow = sbb64(limb, Self::ORDER.as_ref()[i], borrow).1; + } + + Choice::from((borrow as u8) & 1) + } +} + +#[cfg(all(test, feature = "dev"))] +mod tests { + use super::Order; + use crate::dev::MockCurve; + use hex_literal::hex; + + const SCALAR_REPR_IN_RANGE: [u8; 32] = + hex!("FFFFFFFF 00000000 FFFFFFFF FFFFFFFF BCE6FAAD A7179E84 F3B9CAC2 FC632550"); + + const SCALAR_REPR_ORDER: [u8; 32] = + hex!("FFFFFFFF 00000000 FFFFFFFF FFFFFFFF BCE6FAAD A7179E84 F3B9CAC2 FC632551"); + + const SCALAR_REPR_MAX: [u8; 32] = + hex!("FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF"); + + #[test] + fn scalar_in_range() { + let zero_in_range = MockCurve::is_scalar_repr_in_range(&Default::default()); + assert!(bool::from(zero_in_range)); + + let below_order_in_range = MockCurve::is_scalar_repr_in_range(&SCALAR_REPR_IN_RANGE.into()); + assert!(bool::from(below_order_in_range)); + } + + #[test] + fn scalar_with_overflow() { + let order_overflows = !MockCurve::is_scalar_repr_in_range(&SCALAR_REPR_ORDER.into()); + assert!(bool::from(order_overflows)); + + let max_overflows = !MockCurve::is_scalar_repr_in_range(&SCALAR_REPR_MAX.into()); + assert!(bool::from(max_overflows)); + } } From 025467eb13ea3988efb627e8d95d9b9bd1b7c80b Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 21 Apr 2021 10:52:10 -0700 Subject: [PATCH 0488/1461] elliptic-curve v0.9.9 (#609) --- Cargo.lock | 2 +- elliptic-curve/CHANGELOG.md | 6 ++++++ elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 91ffffa8e..707c11bc3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -191,7 +191,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.9.8" +version = "0.9.9" dependencies = [ "base64ct", "bitvec", diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index 3259bc922..31a306042 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.9.9 (2021-04-21) +### Added +- `Order::is_scalar_repr_in_range` ([#608]) + +[#608]: https://github.com/RustCrypto/traits/pull/608 + ## 0.9.8 (2021-04-21) ### Added - Define `Order` for `MockCurve` ([#606]) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 187c1a8c4..0c5e95390 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -5,7 +5,7 @@ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. """ -version = "0.9.8" # Also update html_root_url in lib.rs when bumping this +version = "0.9.9" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" repository = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve" diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 0cf72e281..240f8634b 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -16,7 +16,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.9.8" + html_root_url = "https://docs.rs/elliptic-curve/0.9.9" )] #[cfg(feature = "alloc")] From 9a3332320ac4947b61db3c4a5ed9b3a2da3cfbfe Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 21 Apr 2021 14:54:48 -0700 Subject: [PATCH 0489/1461] elliptic-curve: add `ScalarBytes` type (#610) Adds a type for representing `FieldBytes` which is always in range of the curve's `Order`. Does not require the `arithmetic` feature or a `ProjectiveArithmetic` implementation, however when those are enabled it supports infallible conversions to/from `Scalar`. --- elliptic-curve/src/dev.rs | 5 +- elliptic-curve/src/ecdh.rs | 4 +- elliptic-curve/src/lib.rs | 5 +- elliptic-curve/src/order.rs | 85 +---------- elliptic-curve/src/public_key.rs | 4 +- elliptic-curve/src/scalar.rs | 164 ++------------------- elliptic-curve/src/scalar/bytes.rs | 201 ++++++++++++++++++++++++++ elliptic-curve/src/scalar/non_zero.rs | 154 ++++++++++++++++++++ elliptic-curve/src/secret_key.rs | 5 +- 9 files changed, 379 insertions(+), 248 deletions(-) create mode 100644 elliptic-curve/src/scalar/bytes.rs create mode 100644 elliptic-curve/src/scalar/non_zero.rs diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 388a95f98..39b8e778c 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -7,13 +7,12 @@ use crate::{ ff::{Field, PrimeField}, group, rand_core::RngCore, - scalar::ScalarBits, sec1::{FromEncodedPoint, ToEncodedPoint}, subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}, util::sbb64, weierstrass, zeroize::Zeroize, - AlgorithmParameters, Curve, Order, ProjectiveArithmetic, + AlgorithmParameters, Curve, Order, ProjectiveArithmetic, ScalarBits, }; use core::{ convert::{TryFrom, TryInto}, @@ -93,7 +92,7 @@ pub type EncodedPoint = crate::sec1::EncodedPoint; pub type FieldBytes = crate::FieldBytes; /// Non-zero scalar value. -pub type NonZeroScalar = crate::scalar::NonZeroScalar; +pub type NonZeroScalar = crate::NonZeroScalar; /// Public key. pub type PublicKey = crate::PublicKey; diff --git a/elliptic-curve/src/ecdh.rs b/elliptic-curve/src/ecdh.rs index 207e80968..2538d31e2 100644 --- a/elliptic-curve/src/ecdh.rs +++ b/elliptic-curve/src/ecdh.rs @@ -27,8 +27,8 @@ //! [SIGMA]: https://webee.technion.ac.il/~hugo/sigma-pdf.pdf use crate::{ - public_key::PublicKey, scalar::NonZeroScalar, weierstrass::Curve, AffinePoint, FieldBytes, - ProjectiveArithmetic, ProjectivePoint, Scalar, + weierstrass::Curve, AffinePoint, FieldBytes, NonZeroScalar, ProjectiveArithmetic, + ProjectivePoint, PublicKey, Scalar, }; use core::{borrow::Borrow, fmt::Debug}; use ff::PrimeField; diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 240f8634b..311dcc348 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -32,13 +32,12 @@ pub mod weierstrass; mod error; mod order; +mod scalar; #[cfg(feature = "arithmetic")] mod point; #[cfg(feature = "arithmetic")] mod public_key; -#[cfg(feature = "arithmetic")] -mod scalar; #[cfg(feature = "dev")] #[cfg_attr(docsrs, doc(cfg(feature = "dev")))] @@ -68,7 +67,7 @@ pub use { crate::{ point::{AffinePoint, ProjectiveArithmetic, ProjectivePoint}, public_key::PublicKey, - scalar::{NonZeroScalar, Scalar, ScalarBits}, + scalar::{bytes::ScalarBytes, non_zero::NonZeroScalar, Scalar, ScalarBits}, }, ff::{self, Field}, group::{self, Group}, diff --git a/elliptic-curve/src/order.rs b/elliptic-curve/src/order.rs index 5a5ff5247..9252702cf 100644 --- a/elliptic-curve/src/order.rs +++ b/elliptic-curve/src/order.rs @@ -1,14 +1,7 @@ //! Low-level elliptic curve parameters. -use crate::{Curve, FieldBytes}; -use core::{convert::TryInto, fmt::Debug, mem}; -use subtle::Choice; - -// TODO(tarcieri): unify these into a target-width gated `sbb` -#[cfg(target_pointer_width = "32")] -use crate::util::sbb32; -#[cfg(target_pointer_width = "64")] -use crate::util::sbb64; +use crate::Curve; +use core::fmt::Debug; /// Order of an elliptic curve group. /// @@ -35,78 +28,4 @@ pub trait Order: Curve { /// Subdivided into either 32-bit or 64-bit "limbs" (depending on the /// target CPU's word size), specified from least to most significant. const ORDER: Self::Limbs; - - /// Check that the given serialized scalar field element is in range. - /// - /// Field element must be serialized as a big endian integer. - #[cfg(target_pointer_width = "32")] - fn is_scalar_repr_in_range(fe_bytes: &FieldBytes) -> Choice { - assert_eq!( - mem::size_of::(), - mem::size_of::>() - ); - - let mut borrow = 0; - - for (i, chunk) in fe_bytes.as_ref().chunks(4).rev().enumerate() { - let limb = u32::from_be_bytes(chunk.try_into().unwrap()); - borrow = sbb32(limb, Self::ORDER.as_ref()[i], borrow).1; - } - - Choice::from((borrow as u8) & 1) - } - - /// Check that the given scalar field repr is in range. - /// - /// Field element must be serialized as a big endian integer. - #[cfg(target_pointer_width = "64")] - fn is_scalar_repr_in_range(fe_bytes: &FieldBytes) -> Choice { - assert_eq!( - mem::size_of::(), - mem::size_of::>() - ); - - let mut borrow = 0; - - for (i, chunk) in fe_bytes.as_ref().chunks(8).rev().enumerate() { - let limb = u64::from_be_bytes(chunk.try_into().unwrap()); - borrow = sbb64(limb, Self::ORDER.as_ref()[i], borrow).1; - } - - Choice::from((borrow as u8) & 1) - } -} - -#[cfg(all(test, feature = "dev"))] -mod tests { - use super::Order; - use crate::dev::MockCurve; - use hex_literal::hex; - - const SCALAR_REPR_IN_RANGE: [u8; 32] = - hex!("FFFFFFFF 00000000 FFFFFFFF FFFFFFFF BCE6FAAD A7179E84 F3B9CAC2 FC632550"); - - const SCALAR_REPR_ORDER: [u8; 32] = - hex!("FFFFFFFF 00000000 FFFFFFFF FFFFFFFF BCE6FAAD A7179E84 F3B9CAC2 FC632551"); - - const SCALAR_REPR_MAX: [u8; 32] = - hex!("FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF"); - - #[test] - fn scalar_in_range() { - let zero_in_range = MockCurve::is_scalar_repr_in_range(&Default::default()); - assert!(bool::from(zero_in_range)); - - let below_order_in_range = MockCurve::is_scalar_repr_in_range(&SCALAR_REPR_IN_RANGE.into()); - assert!(bool::from(below_order_in_range)); - } - - #[test] - fn scalar_with_overflow() { - let order_overflows = !MockCurve::is_scalar_repr_in_range(&SCALAR_REPR_ORDER.into()); - assert!(bool::from(order_overflows)); - - let max_overflows = !MockCurve::is_scalar_repr_in_range(&SCALAR_REPR_MAX.into()); - assert!(bool::from(max_overflows)); - } } diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index 3d6ec106d..aa4cee273 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -2,12 +2,12 @@ use crate::{ consts::U1, - scalar::NonZeroScalar, sec1::{ EncodedPoint, FromEncodedPoint, ToEncodedPoint, UncompressedPointSize, UntaggedPointSize, }, weierstrass::{Curve, PointCompression}, - AffinePoint, Error, FieldBytes, ProjectiveArithmetic, ProjectivePoint, Result, Scalar, + AffinePoint, Error, FieldBytes, NonZeroScalar, ProjectiveArithmetic, ProjectivePoint, Result, + Scalar, }; use core::{ convert::{TryFrom, TryInto}, diff --git a/elliptic-curve/src/scalar.rs b/elliptic-curve/src/scalar.rs index 961ec4697..40c585707 100644 --- a/elliptic-curve/src/scalar.rs +++ b/elliptic-curve/src/scalar.rs @@ -1,163 +1,23 @@ //! Scalar types. -use crate::{ - ops::Invert, - rand_core::{CryptoRng, RngCore}, - Curve, Error, FieldBytes, ProjectiveArithmetic, Result, -}; -use core::{convert::TryFrom, ops::Deref}; -use ff::{Field, FieldBits, PrimeField}; -use generic_array::{typenum::Unsigned, GenericArray}; -use group::Group; -use subtle::{Choice, ConditionallySelectable, CtOption}; +pub(crate) mod bytes; + +#[cfg(feature = "arithmetic")] +pub(crate) mod non_zero; -#[cfg(feature = "zeroize")] -use zeroize::Zeroize; +#[cfg(feature = "arithmetic")] +use { + crate::ProjectiveArithmetic, + ff::{FieldBits, PrimeField}, + group::Group, +}; /// Scalar field element for a particular elliptic curve. +#[cfg(feature = "arithmetic")] #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub type Scalar = <::ProjectivePoint as Group>::Scalar; /// Bit representation of a scalar field element of a given curve. +#[cfg(feature = "arithmetic")] #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub type ScalarBits = FieldBits< as PrimeField>::ReprBits>; - -/// Non-zero scalar type. -/// -/// This type ensures that its value is not zero, ala `core::num::NonZero*`. -/// To do this, the generic `S` type must impl both `Default` and -/// `ConstantTimeEq`, with the requirement that `S::default()` returns 0. -/// -/// In the context of ECC, it's useful for ensuring that scalar multiplication -/// cannot result in the point at infinity. -#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] -#[derive(Clone)] -pub struct NonZeroScalar -where - C: Curve + ProjectiveArithmetic, - Scalar: PrimeField>, -{ - scalar: Scalar, -} - -impl NonZeroScalar -where - C: Curve + ProjectiveArithmetic, - Scalar: PrimeField>, -{ - /// Generate a random `NonZeroScalar` - pub fn random(mut rng: impl CryptoRng + RngCore) -> Self { - // Use rejection sampling to eliminate zero values - loop { - if let Some(result) = Self::new(Field::random(&mut rng)) { - break result; - } - } - } - - /// Decode a [`NonZeroScalar] from a serialized field element - pub fn from_repr(repr: FieldBytes) -> Option { - Scalar::::from_repr(repr).and_then(Self::new) - } - - /// Create a [`NonZeroScalar`] from a scalar. - // TODO(tarcieri): make this constant time? - pub fn new(scalar: Scalar) -> Option { - if scalar.is_zero() { - None - } else { - Some(Self { scalar }) - } - } -} - -impl AsRef> for NonZeroScalar -where - C: Curve + ProjectiveArithmetic, - Scalar: PrimeField>, -{ - fn as_ref(&self) -> &Scalar { - &self.scalar - } -} - -impl ConditionallySelectable for NonZeroScalar -where - C: Curve + ProjectiveArithmetic, - Scalar: PrimeField>, -{ - fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { - Self { - scalar: Scalar::::conditional_select(&a.scalar, &b.scalar, choice), - } - } -} - -impl Copy for NonZeroScalar -where - C: Curve + ProjectiveArithmetic, - Scalar: PrimeField>, -{ -} - -impl Deref for NonZeroScalar -where - C: Curve + ProjectiveArithmetic, - Scalar: PrimeField>, -{ - type Target = Scalar; - - fn deref(&self) -> &Scalar { - &self.scalar - } -} - -impl From> for FieldBytes -where - C: Curve + ProjectiveArithmetic, - Scalar: PrimeField>, -{ - fn from(scalar: NonZeroScalar) -> FieldBytes { - scalar.scalar.to_repr() - } -} - -impl Invert for NonZeroScalar -where - C: Curve + ProjectiveArithmetic, - Scalar: PrimeField> + Invert, -{ - type Output = Scalar; - - /// Perform a scalar inversion - fn invert(&self) -> CtOption { - ff::Field::invert(&self.scalar) - } -} - -impl TryFrom<&[u8]> for NonZeroScalar -where - C: Curve + ProjectiveArithmetic, - Scalar: PrimeField>, -{ - type Error = Error; - - fn try_from(bytes: &[u8]) -> Result { - if bytes.len() == C::FieldSize::to_usize() { - NonZeroScalar::from_repr(GenericArray::clone_from_slice(bytes)).ok_or(Error) - } else { - Err(Error) - } - } -} - -#[cfg(feature = "zeroize")] -impl Zeroize for NonZeroScalar -where - C: Curve + ProjectiveArithmetic, - Scalar: PrimeField> + Zeroize, -{ - fn zeroize(&mut self) { - self.scalar.zeroize(); - } -} diff --git a/elliptic-curve/src/scalar/bytes.rs b/elliptic-curve/src/scalar/bytes.rs new file mode 100644 index 000000000..aea2aa6cf --- /dev/null +++ b/elliptic-curve/src/scalar/bytes.rs @@ -0,0 +1,201 @@ +//! Scalar bytes. + +use crate::{Curve, Error, FieldBytes, Order, Result}; +use core::{ + convert::{TryFrom, TryInto}, + mem, +}; +use generic_array::{typenum::Unsigned, GenericArray}; +use subtle::{Choice, CtOption}; + +#[cfg(feature = "arithmetic")] +use crate::{ff::PrimeField, ProjectiveArithmetic, Scalar}; + +// TODO(tarcieri): unify these into a target-width gated `sbb` +#[cfg(target_pointer_width = "32")] +use crate::util::sbb32; +#[cfg(target_pointer_width = "64")] +use crate::util::sbb64; + +/// Scalar bytes: wrapper for [`FieldBytes`] which guarantees that the the +/// inner byte value is within range of the curve's [`Order`]. +/// +/// Does not require an arithmetic implementation. +#[derive(Clone, Debug)] +pub struct ScalarBytes { + /// Inner byte value; guaranteed to be in range of the curve's order. + inner: FieldBytes, +} + +impl ScalarBytes +where + C: Curve + Order, +{ + /// Create new [`ScalarBytes`], checking that the given input is within + /// range of the curve's [`Order`]. + #[cfg(target_pointer_width = "32")] + pub fn new(bytes: FieldBytes) -> CtOption { + assert_eq!( + mem::size_of::(), + mem::size_of::>(), + "malformed curve order" + ); + + let mut borrow = 0; + + for (i, chunk) in bytes.as_ref().chunks(4).rev().enumerate() { + let limb = u32::from_be_bytes(chunk.try_into().unwrap()); + borrow = sbb32(limb, C::ORDER.as_ref()[i], borrow).1; + } + + let is_some = Choice::from((borrow as u8) & 1); + CtOption::new(Self { inner: bytes }, is_some) + } + + /// Create new [`ScalarBytes`], checking that the given input is within + /// range of the curve's [`Order`]. + #[cfg(target_pointer_width = "64")] + pub fn new(bytes: FieldBytes) -> CtOption { + assert_eq!( + mem::size_of::(), + mem::size_of::>(), + "malformed curve order" + ); + + let mut borrow = 0; + + for (i, chunk) in bytes.as_ref().chunks(8).rev().enumerate() { + let limb = u64::from_be_bytes(chunk.try_into().unwrap()); + borrow = sbb64(limb, C::ORDER.as_ref()[i], borrow).1; + } + + let is_some = Choice::from((borrow as u8) & 1); + CtOption::new(Self { inner: bytes }, is_some) + } + + /// Convert from a [`Scalar`] type for this curve. + #[cfg(feature = "arithmetic")] + #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] + pub fn from_scalar(scalar: &Scalar) -> Self + where + C: ProjectiveArithmetic, + Scalar: PrimeField>, + { + Self { + inner: scalar.to_repr(), + } + } + + /// Convert to a [`Scalar`] type for this curve. + #[cfg(feature = "arithmetic")] + #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] + pub fn to_scalar(&self) -> Scalar + where + C: ProjectiveArithmetic, + Scalar: PrimeField>, + { + self.clone().into_scalar() + } + + /// Convert into a [`Scalar`] type for this curve. + #[cfg(feature = "arithmetic")] + #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] + pub fn into_scalar(self) -> Scalar + where + C: ProjectiveArithmetic, + Scalar: PrimeField>, + { + Scalar::::from_repr(self.inner).expect("ScalarBytes order invariant violated") + } + + /// Borrow the inner [`FieldBytes`] + pub fn as_bytes(&self) -> &FieldBytes { + &self.inner + } + + /// Convert into [`FieldBytes`] + pub fn into_bytes(self) -> FieldBytes { + self.inner + } +} + +impl AsRef> for ScalarBytes +where + C: Curve + Order, +{ + fn as_ref(&self) -> &FieldBytes { + &self.inner + } +} + +impl AsRef<[u8]> for ScalarBytes +where + C: Curve + Order, +{ + fn as_ref(&self) -> &[u8] { + self.inner.as_slice() + } +} + +impl Copy for ScalarBytes +where + C: Curve + Order, + FieldBytes: Copy, +{ +} + +impl From> for FieldBytes +where + C: Curve + Order, +{ + fn from(scalar_bytes: ScalarBytes) -> FieldBytes { + scalar_bytes.inner + } +} + +impl TryFrom<&[u8]> for ScalarBytes +where + C: Curve + Order, +{ + type Error = Error; + + fn try_from(bytes: &[u8]) -> Result { + if bytes.len() == C::FieldSize::to_usize() { + Option::from(ScalarBytes::new(GenericArray::clone_from_slice(bytes))).ok_or(Error) + } else { + Err(Error) + } + } +} + +#[cfg(all(test, feature = "dev"))] +mod tests { + use crate::dev::MockCurve; + use core::convert::TryFrom; + use hex_literal::hex; + + type ScalarBytes = super::ScalarBytes; + + const SCALAR_REPR_ZERO: [u8; 32] = [0u8; 32]; + + const SCALAR_REPR_IN_RANGE: [u8; 32] = + hex!("FFFFFFFF 00000000 FFFFFFFF FFFFFFFF BCE6FAAD A7179E84 F3B9CAC2 FC632550"); + + const SCALAR_REPR_ORDER: [u8; 32] = + hex!("FFFFFFFF 00000000 FFFFFFFF FFFFFFFF BCE6FAAD A7179E84 F3B9CAC2 FC632551"); + + const SCALAR_REPR_MAX: [u8; 32] = + hex!("FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF"); + + #[test] + fn scalar_in_range() { + assert!(ScalarBytes::try_from(SCALAR_REPR_ZERO.as_ref()).is_ok()); + assert!(ScalarBytes::try_from(SCALAR_REPR_IN_RANGE.as_ref()).is_ok()); + } + + #[test] + fn scalar_with_overflow() { + assert!(ScalarBytes::try_from(SCALAR_REPR_ORDER.as_ref()).is_err()); + assert!(ScalarBytes::try_from(SCALAR_REPR_MAX.as_ref()).is_err()); + } +} diff --git a/elliptic-curve/src/scalar/non_zero.rs b/elliptic-curve/src/scalar/non_zero.rs new file mode 100644 index 000000000..df0327ef2 --- /dev/null +++ b/elliptic-curve/src/scalar/non_zero.rs @@ -0,0 +1,154 @@ +//! Non-zero scalar type. + +use crate::{ + ops::Invert, + rand_core::{CryptoRng, RngCore}, + Curve, Error, FieldBytes, ProjectiveArithmetic, Result, Scalar, +}; +use core::{convert::TryFrom, ops::Deref}; +use ff::{Field, PrimeField}; +use generic_array::{typenum::Unsigned, GenericArray}; +use subtle::{Choice, ConditionallySelectable, CtOption}; + +#[cfg(feature = "zeroize")] +use zeroize::Zeroize; + +/// Non-zero scalar type. +/// +/// This type ensures that its value is not zero, ala `core::num::NonZero*`. +/// To do this, the generic `S` type must impl both `Default` and +/// `ConstantTimeEq`, with the requirement that `S::default()` returns 0. +/// +/// In the context of ECC, it's useful for ensuring that scalar multiplication +/// cannot result in the point at infinity. +#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] +#[derive(Clone)] +pub struct NonZeroScalar +where + C: Curve + ProjectiveArithmetic, + Scalar: PrimeField>, +{ + scalar: Scalar, +} + +impl NonZeroScalar +where + C: Curve + ProjectiveArithmetic, + Scalar: PrimeField>, +{ + /// Generate a random `NonZeroScalar` + pub fn random(mut rng: impl CryptoRng + RngCore) -> Self { + // Use rejection sampling to eliminate zero values + loop { + if let Some(result) = Self::new(Field::random(&mut rng)) { + break result; + } + } + } + + /// Decode a [`NonZeroScalar] from a serialized field element + pub fn from_repr(repr: FieldBytes) -> Option { + Scalar::::from_repr(repr).and_then(Self::new) + } + + /// Create a [`NonZeroScalar`] from a scalar. + // TODO(tarcieri): make this constant time? + pub fn new(scalar: Scalar) -> Option { + if scalar.is_zero() { + None + } else { + Some(Self { scalar }) + } + } +} + +impl AsRef> for NonZeroScalar +where + C: Curve + ProjectiveArithmetic, + Scalar: PrimeField>, +{ + fn as_ref(&self) -> &Scalar { + &self.scalar + } +} + +impl ConditionallySelectable for NonZeroScalar +where + C: Curve + ProjectiveArithmetic, + Scalar: PrimeField>, +{ + fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { + Self { + scalar: Scalar::::conditional_select(&a.scalar, &b.scalar, choice), + } + } +} + +impl Copy for NonZeroScalar +where + C: Curve + ProjectiveArithmetic, + Scalar: PrimeField>, +{ +} + +impl Deref for NonZeroScalar +where + C: Curve + ProjectiveArithmetic, + Scalar: PrimeField>, +{ + type Target = Scalar; + + fn deref(&self) -> &Scalar { + &self.scalar + } +} + +impl From> for FieldBytes +where + C: Curve + ProjectiveArithmetic, + Scalar: PrimeField>, +{ + fn from(scalar: NonZeroScalar) -> FieldBytes { + scalar.scalar.to_repr() + } +} + +impl Invert for NonZeroScalar +where + C: Curve + ProjectiveArithmetic, + Scalar: PrimeField> + Invert, +{ + type Output = Scalar; + + /// Perform a scalar inversion + fn invert(&self) -> CtOption { + ff::Field::invert(&self.scalar) + } +} + +impl TryFrom<&[u8]> for NonZeroScalar +where + C: Curve + ProjectiveArithmetic, + Scalar: PrimeField>, +{ + type Error = Error; + + fn try_from(bytes: &[u8]) -> Result { + if bytes.len() == C::FieldSize::to_usize() { + NonZeroScalar::from_repr(GenericArray::clone_from_slice(bytes)).ok_or(Error) + } else { + Err(Error) + } + } +} + +#[cfg(feature = "zeroize")] +impl Zeroize for NonZeroScalar +where + C: Curve + ProjectiveArithmetic, + Scalar: PrimeField> + Zeroize, +{ + fn zeroize(&mut self) { + self.scalar.zeroize(); + } +} diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 8f1c06b2b..cdf8ec335 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -22,10 +22,9 @@ use zeroize::Zeroize; #[cfg(feature = "arithmetic")] use crate::{ ff::PrimeField, - public_key::PublicKey, rand_core::{CryptoRng, RngCore}, - scalar::{NonZeroScalar, Scalar}, - weierstrass, AffinePoint, ProjectiveArithmetic, ProjectivePoint, + weierstrass, AffinePoint, NonZeroScalar, ProjectiveArithmetic, ProjectivePoint, PublicKey, + Scalar, }; #[cfg(feature = "jwk")] From 9680bf1ee743215da8e0f21c615cdbf043f19b34 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 21 Apr 2021 15:06:15 -0700 Subject: [PATCH 0490/1461] elliptic-curve v0.9.10 (#611) --- Cargo.lock | 2 +- elliptic-curve/CHANGELOG.md | 8 +++++++- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 707c11bc3..f5b98c447 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -191,7 +191,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.9.9" +version = "0.9.10" dependencies = [ "base64ct", "bitvec", diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index 31a306042..2758db1ae 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,7 +4,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 0.9.9 (2021-04-21) +## 0.9.10 (2021-04-21) +### Added +- `ScalarBytes` type ([#610]) + +[#610]: https://github.com/RustCrypto/traits/pull/610 + +## 0.9.9 (2021-04-21) [YANKED] ### Added - `Order::is_scalar_repr_in_range` ([#608]) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 0c5e95390..f773976f9 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -5,7 +5,7 @@ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. """ -version = "0.9.9" # Also update html_root_url in lib.rs when bumping this +version = "0.9.10" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" repository = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve" diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 311dcc348..4b6a25f75 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -16,7 +16,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.9.9" + html_root_url = "https://docs.rs/elliptic-curve/0.9.10" )] #[cfg(feature = "alloc")] From c696a7379f5da1b35885133e76007ba1cc100151 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 21 Apr 2021 15:35:50 -0700 Subject: [PATCH 0491/1461] elliptic-curve: impl `subtle` traits on `ScalarBytes` (#612) Adds impls of `ConditionallySelectable` and `ConstantTimeEq` --- elliptic-curve/src/scalar/bytes.rs | 62 +++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/elliptic-curve/src/scalar/bytes.rs b/elliptic-curve/src/scalar/bytes.rs index aea2aa6cf..6f8458aae 100644 --- a/elliptic-curve/src/scalar/bytes.rs +++ b/elliptic-curve/src/scalar/bytes.rs @@ -6,7 +6,7 @@ use core::{ mem, }; use generic_array::{typenum::Unsigned, GenericArray}; -use subtle::{Choice, CtOption}; +use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; #[cfg(feature = "arithmetic")] use crate::{ff::PrimeField, ProjectiveArithmetic, Scalar}; @@ -21,7 +21,7 @@ use crate::util::sbb64; /// inner byte value is within range of the curve's [`Order`]. /// /// Does not require an arithmetic implementation. -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Eq)] pub struct ScalarBytes { /// Inner byte value; guaranteed to be in range of the curve's order. inner: FieldBytes, @@ -117,6 +117,18 @@ where pub fn into_bytes(self) -> FieldBytes { self.inner } + + /// Create [`ScalarBytes`] representing a value of zero. + pub fn zero() -> Self { + Self { + inner: Default::default(), + } + } + + /// Is this [`ScalarBytes`] value all zeroes? + pub fn is_zero(&self) -> Choice { + self.ct_eq(&Self::zero()) + } } impl AsRef> for ScalarBytes @@ -137,6 +149,34 @@ where } } +impl ConditionallySelectable for ScalarBytes +where + Self: Copy, + C: Curve + Order, +{ + fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { + let mut inner = FieldBytes::::default(); + + for (i, (byte_a, byte_b)) in a.inner.iter().zip(b.inner.iter()).enumerate() { + inner[i] = u8::conditional_select(byte_a, byte_b, choice) + } + + Self { inner } + } +} + +impl ConstantTimeEq for ScalarBytes +where + C: Curve + Order, +{ + fn ct_eq(&self, other: &Self) -> Choice { + self.inner + .iter() + .zip(other.inner.iter()) + .fold(Choice::from(0u8), |acc, (a, b)| acc & a.ct_eq(b)) + } +} + impl Copy for ScalarBytes where C: Curve + Order, @@ -144,6 +184,15 @@ where { } +impl Default for ScalarBytes +where + C: Curve + Order, +{ + fn default() -> Self { + Self::zero() + } +} + impl From> for FieldBytes where C: Curve + Order, @@ -153,6 +202,15 @@ where } } +impl PartialEq for ScalarBytes +where + C: Curve + Order, +{ + fn eq(&self, other: &Self) -> bool { + self.ct_eq(other).into() + } +} + impl TryFrom<&[u8]> for ScalarBytes where C: Curve + Order, From 19cbed9493dd4ec1de1e884f7fa6ea7890ee3ca8 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 21 Apr 2021 15:49:28 -0700 Subject: [PATCH 0492/1461] elliptic-curve: always re-export ScalarBytes (#613) It was previously needlessly conditionally gated on the `arithmetic` feature by accident. --- elliptic-curve/src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 4b6a25f75..271dfc558 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -56,6 +56,7 @@ mod secret_key; pub use self::{ error::{Error, Result}, order::Order, + scalar::bytes::ScalarBytes, }; pub use generic_array::{self, typenum::consts}; @@ -67,7 +68,7 @@ pub use { crate::{ point::{AffinePoint, ProjectiveArithmetic, ProjectivePoint}, public_key::PublicKey, - scalar::{bytes::ScalarBytes, non_zero::NonZeroScalar, Scalar, ScalarBits}, + scalar::{non_zero::NonZeroScalar, Scalar, ScalarBits}, }, ff::{self, Field}, group::{self, Group}, From b96df693572a6834feaa86e1a0b27b25ba960017 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 21 Apr 2021 16:01:11 -0700 Subject: [PATCH 0493/1461] elliptic-curve v0.9.11 (#614) --- Cargo.lock | 2 +- elliptic-curve/CHANGELOG.md | 10 ++++++++++ elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 2 +- 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f5b98c447..85901dad4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -191,7 +191,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.9.10" +version = "0.9.11" dependencies = [ "base64ct", "bitvec", diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index 2758db1ae..67a5dc462 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.9.11 (2021-04-21) +### Added +- Impl `subtle` traits on `ScalarBytes` ([#612]) + +### Fixed +- Always re-export ScalarBytes ([#613]) + +[#612]: https://github.com/RustCrypto/traits/pull/612 +[#613]: https://github.com/RustCrypto/traits/pull/613 + ## 0.9.10 (2021-04-21) ### Added - `ScalarBytes` type ([#610]) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index f773976f9..3fe0aab1d 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -5,7 +5,7 @@ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. """ -version = "0.9.10" # Also update html_root_url in lib.rs when bumping this +version = "0.9.11" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" repository = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve" diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 271dfc558..182d69a30 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -16,7 +16,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.9.10" + html_root_url = "https://docs.rs/elliptic-curve/0.9.11" )] #[cfg(feature = "alloc")] From 08c3d733b51a86d5e9fbfee5e508474976066aba Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 26 Apr 2021 18:46:26 -0700 Subject: [PATCH 0494/1461] aead: forbid `clippy::unwrap_used` (#616) --- aead/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aead/src/lib.rs b/aead/src/lib.rs index eeadf59d3..b8e133935 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -15,7 +15,7 @@ #![no_std] #![cfg_attr(docsrs, feature(doc_cfg))] -#![forbid(unsafe_code)] +#![forbid(unsafe_code, clippy::unwrap_used)] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", From 26e5c58356071d1277f54b9fc3364744808cbbbb Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 26 Apr 2021 19:00:01 -0700 Subject: [PATCH 0495/1461] elliptic-curve: forbid `clippy::unwrap_used` (#617) --- elliptic-curve/src/dev.rs | 8 ++++---- elliptic-curve/src/lib.rs | 2 +- elliptic-curve/src/scalar/bytes.rs | 2 +- elliptic-curve/src/sec1.rs | 11 ++++++----- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 39b8e778c..e8f6ac740 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -189,10 +189,10 @@ impl PrimeField for Scalar { let mut w = [0u64; LIMBS]; // Interpret the bytes as a big-endian integer w. - w[3] = u64::from_be_bytes(bytes[0..8].try_into().unwrap()); - w[2] = u64::from_be_bytes(bytes[8..16].try_into().unwrap()); - w[1] = u64::from_be_bytes(bytes[16..24].try_into().unwrap()); - w[0] = u64::from_be_bytes(bytes[24..32].try_into().unwrap()); + w[3] = u64::from_be_bytes(bytes[0..8].try_into().expect("bad field size")); + w[2] = u64::from_be_bytes(bytes[8..16].try_into().expect("bad field size")); + w[1] = u64::from_be_bytes(bytes[16..24].try_into().expect("bad field size")); + w[0] = u64::from_be_bytes(bytes[24..32].try_into().expect("bad field size")); // If w is in the range [0, n) then w - n will overflow, resulting in a borrow // value of 2^64 - 1. diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 182d69a30..8c5ae6616 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -11,7 +11,7 @@ #![no_std] #![cfg_attr(docsrs, feature(doc_cfg))] -#![forbid(unsafe_code)] +#![forbid(unsafe_code, clippy::unwrap_used)] #![warn(missing_docs, rust_2018_idioms, unused_qualifications)] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", diff --git a/elliptic-curve/src/scalar/bytes.rs b/elliptic-curve/src/scalar/bytes.rs index 6f8458aae..60f182c00 100644 --- a/elliptic-curve/src/scalar/bytes.rs +++ b/elliptic-curve/src/scalar/bytes.rs @@ -65,7 +65,7 @@ where let mut borrow = 0; for (i, chunk) in bytes.as_ref().chunks(8).rev().enumerate() { - let limb = u64::from_be_bytes(chunk.try_into().unwrap()); + let limb = u64::from_be_bytes(chunk.try_into().expect("invalid chunk size")); borrow = sbb64(limb, C::ORDER.as_ref()[i], borrow).1; } diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index 530dca790..4f255818a 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -54,7 +54,7 @@ pub type UntaggedPointSize = <::FieldSize as Add>::Output; /// This type is an enum over the compressed and uncompressed encodings, /// useful for cases where either encoding can be supported, or conversions /// between the two forms. -#[derive(Clone, Eq, PartialEq, PartialOrd, Ord)] +#[derive(Clone, Default, Eq, PartialEq, PartialOrd, Ord)] pub struct EncodedPoint where C: Curve, @@ -146,7 +146,7 @@ where /// Return [`EncodedPoint`] representing the additive identity /// (a.k.a. point at infinity) pub fn identity() -> Self { - Self::from_bytes(&[0]).unwrap() + Self::default() } /// Get the length of the encoded point in bytes @@ -444,10 +444,8 @@ impl Tag { /// Compress the given y-coordinate, returning a `Tag::Compressed*` value fn compress_y(y: &[u8]) -> Self { - debug_assert!(!y.is_empty()); - // Is the y-coordinate odd in the SEC1 sense: `self mod 2 == 1`? - if y.as_ref().last().unwrap() & 1 == 1 { + if y.as_ref().last().expect("empty y-coordinate") & 1 == 1 { Tag::CompressedOddY } else { Tag::CompressedEvenY @@ -742,6 +740,9 @@ mod tests { assert_eq!(identity_point.tag(), Tag::Identity); assert_eq!(identity_point.len(), 1); assert_eq!(identity_point.as_bytes(), &IDENTITY_BYTES[..]); + + // identity is default + assert_eq!(identity_point, EncodedPoint::default()); } #[cfg(feature = "alloc")] From d6a1e128825113d29eb7fd2525a9bba161415717 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 28 Apr 2021 11:10:19 -0700 Subject: [PATCH 0496/1461] password-hash: v0.2 breaking changes (#615) This commit contains a set of breaking changes intended to be released as part of `password-hash` v0.2, addressing a number of currently open issues about the crate discovered when integrating it into the crates in the https://github.com/RustCrypto/password-hashes repo. This includes: - Allow specifying output length and version with params (#505) - Allow passing `&str`, `&Salt`, or `&SaltString` as salt (#529) - Simplify error handling (#547) --- Cargo.lock | 2 +- crypto/Cargo.toml | 2 +- password-hash/Cargo.toml | 2 +- password-hash/src/errors.rs | 260 +++++++-------------------------- password-hash/src/ident.rs | 28 ++-- password-hash/src/lib.rs | 62 ++++---- password-hash/src/output.rs | 68 ++++----- password-hash/src/params.rs | 43 +++--- password-hash/src/salt.rs | 49 ++----- password-hash/src/value.rs | 56 ++++--- password-hash/tests/hashing.rs | 23 ++- 11 files changed, 189 insertions(+), 406 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 85901dad4..81efd18b0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -323,7 +323,7 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "password-hash" -version = "0.1.4" +version = "0.2.0-pre" dependencies = [ "base64ct", "rand_core", diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index d668f56dd..96a5adb5b 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -17,7 +17,7 @@ cipher = { version = "=0.3.0-pre.4", optional = true, path = "../cipher" } digest = { version = "0.10.0-pre", optional = true, path = "../digest" } elliptic-curve = { version = "0.9", optional = true, path = "../elliptic-curve" } mac = { version = "=0.11.0-pre", package = "crypto-mac", optional = true, path = "../crypto-mac" } -password-hash = { version = "0.1", optional = true, path = "../password-hash" } +password-hash = { version = "=0.2.0-pre", optional = true, path = "../password-hash" } signature = { version = "1.3.0", optional = true, default-features = false, path = "../signature" } universal-hash = { version = "0.4", optional = true, path = "../universal-hash" } diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index e1aa67ce1..f6468f92c 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -5,7 +5,7 @@ Traits which describe the functionality of password hashing algorithms, as well as a `no_std`-friendly implementation of the PHC string format (a well-defined subset of the Modular Crypt Format a.k.a. MCF) """ -version = "0.1.4" +version = "0.2.0-pre" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/password-hash/src/errors.rs b/password-hash/src/errors.rs index b75c7613a..8f63cd857 100644 --- a/password-hash/src/errors.rs +++ b/password-hash/src/errors.rs @@ -4,59 +4,12 @@ pub use base64ct::Error as B64Error; use core::fmt; -#[cfg(docsrs)] -use crate::PasswordHasher; +/// Result type. +pub type Result = core::result::Result; -/// Password hash errors. +/// Password hashing errors. #[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum HashError { - /// Hash output error. - Hash(OutputError), - - /// Params error. - Params(ParamsError), - - /// Parse error. - Parse(ParseError), -} - -impl fmt::Display for HashError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - match self { - Self::Hash(err) => write!(f, "invalid password hash: {}", err), - Self::Params(err) => write!(f, "invalid params: {}", err), - Self::Parse(err) => write!(f, "parse error: {}", err), - } - } -} - -impl From for HashError { - fn from(err: OutputError) -> HashError { - HashError::Hash(err) - } -} - -impl From for HashError { - fn from(err: ParamsError) -> HashError { - match err { - ParamsError::Parse(e) => e.into(), - _ => HashError::Params(err), - } - } -} - -impl From for HashError { - fn from(err: ParseError) -> HashError { - HashError::Parse(err) - } -} - -#[cfg(feature = "std")] -impl std::error::Error for HashError {} - -/// Errors generating password hashes using a [`PasswordHasher`]. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum HasherError { +pub enum Error { /// Unsupported algorithm. Algorithm, @@ -66,193 +19,80 @@ pub enum HasherError { /// Cryptographic error. Crypto, - /// Error generating output. - Output(OutputError), - - /// Invalid parameter. - Params(ParamsError), - - /// Parse error. - Parse(ParseError), - - /// Invalid password. - Password, - - /// Invalid algorithm version. - Version, -} - -impl fmt::Display for HasherError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - match self { - Self::Algorithm => write!(f, "unsupported algorithm"), - Self::B64(err) => write!(f, "{}", err), - Self::Crypto => write!(f, "cryptographic error"), - Self::Output(err) => write!(f, "PHF output error: {}", err), - Self::Params(err) => write!(f, "{}", err), - Self::Parse(err) => write!(f, "{}", err), - Self::Password => write!(f, "invalid password"), - Self::Version => write!(f, "invalid algorithm version"), - } - } -} - -impl From for HasherError { - fn from(err: B64Error) -> HasherError { - HasherError::B64(err) - } -} - -impl From for HasherError { - fn from(_: base64ct::InvalidLengthError) -> HasherError { - HasherError::B64(B64Error::InvalidLength) - } -} - -impl From for HasherError { - fn from(err: OutputError) -> HasherError { - HasherError::Output(err) - } -} - -impl From for HasherError { - fn from(err: ParamsError) -> HasherError { - HasherError::Params(err) - } -} - -impl From for HasherError { - fn from(err: ParseError) -> HasherError { - HasherError::Parse(err) - } -} + /// Output too short (min 10-bytes). + OutputTooShort, -#[cfg(feature = "std")] -impl std::error::Error for HasherError {} + /// Output too long (max 64-bytes). + OutputTooLong, -/// Parameter-related errors. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum ParamsError { /// Duplicate parameter name encountered. - DuplicateName, + ParamNameDuplicated, /// Invalid parameter name. - InvalidName, + ParamNameInvalid, /// Invalid parameter value. - InvalidValue, + ParamValueInvalid, /// Maximum number of parameters exceeded. - MaxExceeded, - - /// Parse errors. - Parse(ParseError), -} - -impl fmt::Display for ParamsError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - match self { - Self::DuplicateName => f.write_str("duplicate parameter"), - Self::InvalidName => f.write_str("invalid parameter name"), - Self::InvalidValue => f.write_str("invalid parameter value"), - Self::MaxExceeded => f.write_str("maximum number of parameters reached"), - Self::Parse(err) => write!(f, "{}", err), - } - } -} - -impl From for ParamsError { - fn from(err: ParseError) -> ParamsError { - Self::Parse(err) - } -} - -#[cfg(feature = "std")] -impl std::error::Error for ParamsError {} + ParamsMaxExceeded, -/// Parse errors. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum ParseError { - /// Invalid empty input. - Empty, - - /// Input contains invalid character. - InvalidChar(char), - - /// Input too short. - TooShort, + /// Invalid password. + Password, - /// Input too long. - TooLong, -} + /// Password hash string contains invalid characters. + PhcStringInvalid, -impl fmt::Display for ParseError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - match self { - Self::Empty => f.write_str("invalid empty input"), - Self::InvalidChar(char) => write!(f, "invalid character '{}'", char), - Self::TooShort => f.write_str("too short"), - Self::TooLong => f.write_str("too long"), - } - } -} + /// Password hash string too short. + PhcStringTooShort, -#[cfg(feature = "std")] -impl std::error::Error for ParseError {} + /// Password hash string too long. + PhcStringTooLong, -/// Password hash function output (i.e. hash/digest) errors. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum OutputError { - /// "B64" encoding error. - B64(B64Error), + /// Salt too short. + SaltTooShort, - /// Output too short (min 10-bytes). - TooShort, + /// Salt too long. + SaltTooLong, - /// Output too long (max 64-bytes). - TooLong, + /// Invalid algorithm version. + Version, } -impl fmt::Display for OutputError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> core::result::Result<(), fmt::Error> { match self { + Self::Algorithm => write!(f, "unsupported algorithm"), Self::B64(err) => write!(f, "{}", err), - Self::TooShort => f.write_str("PHF output too short (min 10-bytes)"), - Self::TooLong => f.write_str("PHF output too long (max 64-bytes)"), + Self::Crypto => write!(f, "cryptographic error"), + Self::OutputTooShort => f.write_str("PHF output too short (min 10-bytes)"), + Self::OutputTooLong => f.write_str("PHF output too long (max 64-bytes)"), + Self::ParamNameDuplicated => f.write_str("duplicate parameter"), + Self::ParamNameInvalid => f.write_str("invalid parameter name"), + Self::ParamValueInvalid => f.write_str("invalid parameter value"), + Self::ParamsMaxExceeded => f.write_str("maximum number of parameters reached"), + Self::Password => write!(f, "invalid password"), + Self::PhcStringInvalid => write!(f, "password hash string invalid"), + Self::PhcStringTooShort => write!(f, "password hash string too short"), + Self::PhcStringTooLong => write!(f, "password hash string too long"), + Self::SaltTooShort => write!(f, "salt too short"), + Self::SaltTooLong => write!(f, "salt too long"), + Self::Version => write!(f, "invalid algorithm version"), } } } -impl From for OutputError { - fn from(err: B64Error) -> OutputError { - OutputError::B64(err) - } -} - -impl From for OutputError { - fn from(_: base64ct::InvalidLengthError) -> OutputError { - OutputError::B64(B64Error::InvalidLength) - } -} - #[cfg(feature = "std")] -impl std::error::Error for OutputError {} - -/// Password verification errors. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub struct VerifyError; +impl std::error::Error for Error {} -impl fmt::Display for VerifyError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - f.write_str("password verification error") +impl From for Error { + fn from(err: B64Error) -> Error { + Error::B64(err) } } -impl From for VerifyError { - fn from(_: HasherError) -> VerifyError { - VerifyError +impl From for Error { + fn from(_: base64ct::InvalidLengthError) -> Error { + Error::B64(B64Error::InvalidLength) } } - -#[cfg(feature = "std")] -impl std::error::Error for VerifyError {} diff --git a/password-hash/src/ident.rs b/password-hash/src/ident.rs index 50f6949ea..48f18c471 100644 --- a/password-hash/src/ident.rs +++ b/password-hash/src/ident.rs @@ -16,7 +16,7 @@ //! //! [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md -use crate::errors::ParseError; +use crate::{Error, Result}; use core::{convert::TryFrom, fmt, ops::Deref, str}; /// Algorithm or parameter identifier. @@ -45,12 +45,6 @@ impl<'a> Ident<'a> { /// and parameter names according to the PHC string format. const MAX_LENGTH: usize = 32; - /// Maximum length of an [`Ident`] - 32 ASCII characters (i.e. 32-bytes). - #[deprecated(since = "0.1.4", note = "use Ident::MAX_LENGTH instead")] - pub const fn max_len() -> usize { - Self::MAX_LENGTH - } - /// Parse an [`Ident`] from a string. /// /// # Panics @@ -122,11 +116,11 @@ impl<'a> Deref for Ident<'a> { // Note: this uses `TryFrom` instead of `FromStr` to support a lifetime on // the `str` the value is being parsed from. impl<'a> TryFrom<&'a str> for Ident<'a> { - type Error = ParseError; + type Error = Error; - fn try_from(s: &'a str) -> Result { + fn try_from(s: &'a str) -> Result { if s.is_empty() { - return Err(ParseError::Empty); + return Err(Error::ParamNameInvalid); } let bytes = s.as_bytes(); @@ -134,12 +128,12 @@ impl<'a> TryFrom<&'a str> for Ident<'a> { for &c in bytes { if !is_char_valid(c) { - return Err(ParseError::InvalidChar(c.into())); + return Err(Error::ParamNameInvalid); } } if too_long { - return Err(ParseError::TooLong); + return Err(Error::ParamNameInvalid); } Ok(Self::new(s)) @@ -165,7 +159,7 @@ const fn is_char_valid(c: u8) -> bool { #[cfg(test)] mod tests { - use super::{Ident, ParseError}; + use super::{Error, Ident}; use core::convert::TryFrom; // Invalid ident examples @@ -195,7 +189,7 @@ mod tests { #[test] fn reject_empty_fallible() { let err = Ident::try_from(INVALID_EMPTY).err().unwrap(); - assert_eq!(err, ParseError::Empty); + assert_eq!(err, Error::ParamNameInvalid); } #[test] @@ -207,7 +201,7 @@ mod tests { #[test] fn reject_invalid_char_fallible() { let err = Ident::try_from(INVALID_CHAR).err().unwrap(); - assert_eq!(err, ParseError::InvalidChar(';')); + assert_eq!(err, Error::ParamNameInvalid); } #[test] @@ -219,7 +213,7 @@ mod tests { #[test] fn reject_too_long_fallible() { let err = Ident::try_from(INVALID_TOO_LONG).err().unwrap(); - assert_eq!(err, ParseError::TooLong); + assert_eq!(err, Error::ParamNameInvalid); } #[test] @@ -231,6 +225,6 @@ mod tests { #[test] fn reject_invalid_char_and_too_long_fallible() { let err = Ident::try_from(INVALID_CHAR_AND_TOO_LONG).err().unwrap(); - assert_eq!(err, ParseError::InvalidChar('!')); + assert_eq!(err, Error::ParamNameInvalid); } } diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index 1c3fff54b..bf9efc628 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -39,7 +39,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/password-hash/0.1.4" + html_root_url = "https://docs.rs/password-hash/0.2.0-pre" )] #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] @@ -60,7 +60,7 @@ mod value; pub use crate::{ encoding::Encoding, - errors::{B64Error, HashError, HasherError, OutputError, ParamsError, ParseError, VerifyError}, + errors::{B64Error, Error, Result}, ident::Ident, output::Output, params::ParamsString, @@ -82,24 +82,22 @@ pub trait PasswordHasher { type Params: Clone + Debug + Default - + for<'a> TryFrom<&'a ParamsString, Error = HasherError> - + for<'a> TryInto; + + for<'a> TryFrom<&'a PasswordHash<'a>, Error = Error> + + for<'a> TryInto; /// Simple API for computing a [`PasswordHash`] from a password and /// [`Salt`] value. /// /// Uses the default recommended parameters for a given algorithm. - fn hash_password_simple<'a>( - &self, - password: &[u8], - salt: &'a str, - ) -> Result, HasherError> { + fn hash_password_simple<'a, S>(&self, password: &[u8], salt: &'a S) -> Result> + where + S: AsRef + ?Sized, + { self.hash_password( password, None, - None, Self::Params::default(), - salt.try_into()?, + Salt::try_from(salt.as_ref())?, ) } @@ -110,10 +108,9 @@ pub trait PasswordHasher { &self, password: &[u8], algorithm: Option>, - version: Option, params: Self::Params, - salt: Salt<'a>, - ) -> Result, HasherError>; + salt: impl Into>, + ) -> Result>; } /// Trait for password verification. @@ -127,17 +124,16 @@ pub trait PasswordVerifier { /// Compute this password hashing function against the provided password /// using the parameters from the provided password hash and see if the /// computed output matches. - fn verify_password(&self, password: &[u8], hash: &PasswordHash<'_>) -> Result<(), VerifyError>; + fn verify_password(&self, password: &[u8], hash: &PasswordHash<'_>) -> Result<()>; } impl PasswordVerifier for T { - fn verify_password(&self, password: &[u8], hash: &PasswordHash<'_>) -> Result<(), VerifyError> { + fn verify_password(&self, password: &[u8], hash: &PasswordHash<'_>) -> Result<()> { if let (Some(salt), Some(expected_output)) = (&hash.salt, &hash.hash) { let computed_hash = self.hash_password( password, Some(hash.algorithm), - hash.version, - T::Params::try_from(&hash.params)?, + T::Params::try_from(&hash)?, *salt, )?; @@ -149,7 +145,7 @@ impl PasswordVerifier for T { } } - Err(VerifyError) + Err(Error::Password) } } @@ -166,10 +162,10 @@ pub trait McfHasher { /// /// MCF hashes are otherwise largely unstructured and parsed according to /// algorithm-specific rules so hashers must parse a raw string themselves. - fn upgrade_mcf_hash<'a>(&self, hash: &'a str) -> Result, HasherError>; + fn upgrade_mcf_hash<'a>(&self, hash: &'a str) -> Result>; /// Verify a password hash in MCF format against the provided password. - fn verify_mcf_hash(&self, password: &[u8], mcf_hash: &str) -> Result<(), VerifyError> + fn verify_mcf_hash(&self, password: &[u8], mcf_hash: &str) -> Result<()> where Self: PasswordVerifier, { @@ -241,26 +237,26 @@ pub struct PasswordHash<'a> { impl<'a> PasswordHash<'a> { /// Parse a password hash from a string in the PHC string format. - pub fn new(s: &'a str) -> Result { + pub fn new(s: &'a str) -> Result { Self::parse(s, Encoding::B64) } /// Parse a password hash from the given [`Encoding`]. - pub fn parse(s: &'a str, encoding: Encoding) -> Result { + pub fn parse(s: &'a str, encoding: Encoding) -> Result { if s.is_empty() { - return Err(ParseError::Empty.into()); + return Err(Error::PhcStringTooShort); } let mut fields = s.split(PASSWORD_HASH_SEPARATOR); let beginning = fields.next().expect("no first field"); - if let Some(first_char) = beginning.chars().next() { - return Err(ParseError::InvalidChar(first_char).into()); + if beginning.chars().next().is_some() { + return Err(Error::PhcStringInvalid); } let algorithm = fields .next() - .ok_or(ParseError::TooShort) + .ok_or(Error::PhcStringTooShort) .and_then(Ident::try_from)?; let mut version = None; @@ -303,7 +299,7 @@ impl<'a> PasswordHash<'a> { } if fields.next().is_some() { - return Err(ParseError::TooLong.into()); + return Err(Error::PhcStringTooLong); } Ok(Self { @@ -320,7 +316,7 @@ impl<'a> PasswordHash<'a> { phf: impl PasswordHasher, password: impl AsRef<[u8]>, salt: &'a str, - ) -> Result { + ) -> Result { phf.hash_password_simple(password.as_ref(), salt) } @@ -330,14 +326,14 @@ impl<'a> PasswordHash<'a> { &self, phfs: &[&dyn PasswordVerifier], password: impl AsRef<[u8]>, - ) -> Result<(), VerifyError> { + ) -> Result<()> { for &phf in phfs { if phf.verify_password(password.as_ref(), self).is_ok() { return Ok(()); } } - Err(VerifyError) + Err(Error::Password) } /// Get the [`Encoding`] that this [`PasswordHash`] is serialized with. @@ -349,9 +345,9 @@ impl<'a> PasswordHash<'a> { // Note: this uses `TryFrom` instead of `FromStr` to support a lifetime on // the `str` the value is being parsed from. impl<'a> TryFrom<&'a str> for PasswordHash<'a> { - type Error = HashError; + type Error = Error; - fn try_from(s: &'a str) -> Result { + fn try_from(s: &'a str) -> Result { Self::new(s) } } diff --git a/password-hash/src/output.rs b/password-hash/src/output.rs index 68430a8b6..8bc4c66c1 100644 --- a/password-hash/src/output.rs +++ b/password-hash/src/output.rs @@ -1,6 +1,6 @@ //! Outputs from password hashing functions. -use crate::{Encoding, OutputError}; +use crate::{Encoding, Error, Result}; use core::{cmp::PartialEq, convert::TryFrom, fmt, str::FromStr}; /// Output from password hashing functions, i.e. the "hash" or "digest" @@ -46,11 +46,16 @@ use core::{cmp::PartialEq, convert::TryFrom, fmt, str::FromStr}; /// this crate does not loop in additional dependencies for /// constant-time comparisons (e.g. `subtle`). /// -/// The extent to which constant-time comparisons of password hashes is -/// actually helpful in practical contexts [topic of considerable debate][3]. +/// The extent to which constant-time comparisons of password hashes provides +/// meaningful protections in practical contexts is a +/// [topic of considerable debate][3]. /// This library has elected to use a non-short-circuiting comparison as a /// safer ("belt-and-suspenders") default, and also to /// [head off any potential debates around the issue][4]. +/// Our main suggestion to avoid such attacks is to use a unique, randomly +/// generated salt per password which is unpredictable by the attacker. +/// The [`SaltString::generate`] function randomly generates high-entropy +/// salt values. /// /// [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#function-duties /// [2]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#argon2-encoding @@ -82,28 +87,9 @@ impl Output { /// (i.e. 86 ASCII characters) pub const B64_MAX_LENGTH: usize = ((Self::MAX_LENGTH * 4) / 3) + 1; - /// Minimum length of a [`Output`] string: 10-bytes. - #[deprecated(since = "0.1.4", note = "use Output::MIN_LENGTH instead")] - pub const fn min_len() -> usize { - Self::MIN_LENGTH - } - - /// Maximum length of [`Output`] string: 64-bytes. - #[deprecated(since = "0.1.4", note = "use Output::MAX_LENGTH instead")] - pub const fn max_len() -> usize { - Self::MAX_LENGTH - } - - /// Maximum length of [`Output`] when encoded as B64 string: 86-bytes - /// (i.e. 86 ASCII characters) - #[deprecated(since = "0.1.4", note = "use Output::B64_MAX_LENGTH instead")] - pub const fn b64_max_len() -> usize { - Self::B64_MAX_LENGTH - } - /// Create a [`Output`] from the given byte slice, validating it according /// to [`Output::min_len`] and [`Output::max_len`] length restrictions. - pub fn new(input: &[u8]) -> Result { + pub fn new(input: &[u8]) -> Result { Self::init_with(input.len(), |bytes| { bytes.copy_from_slice(input); Ok(()) @@ -113,7 +99,7 @@ impl Output { /// Create a [`Output`] from the given byte slice and [`Encoding`], /// validating it according to [`Output::min_len`] and [`Output::max_len`] /// length restrictions. - pub fn new_with_encoding(input: &[u8], encoding: Encoding) -> Result { + pub fn new_with_encoding(input: &[u8], encoding: Encoding) -> Result { let mut result = Self::new(input)?; result.encoding = encoding; Ok(result) @@ -124,16 +110,16 @@ impl Output { /// /// The `output_size` (in bytes) must be known in advance, as well as at /// least [`Output::min_len`] bytes and at most [`Output::max_len`] bytes. - pub fn init_with(output_size: usize, f: F) -> Result + pub fn init_with(output_size: usize, f: F) -> Result where - F: FnOnce(&mut [u8]) -> Result<(), OutputError>, + F: FnOnce(&mut [u8]) -> Result<()>, { if output_size < Self::MIN_LENGTH { - return Err(OutputError::TooShort); + return Err(Error::OutputTooShort); } if output_size > Self::MAX_LENGTH { - return Err(OutputError::TooLong); + return Err(Error::OutputTooLong); } let mut bytes = [0u8; Self::MAX_LENGTH]; @@ -163,7 +149,7 @@ impl Output { /// Parse B64-encoded [`Output`], i.e. using the PHC string /// specification's restricted interpretation of Base64. - pub fn b64_decode(input: &str) -> Result { + pub fn b64_decode(input: &str) -> Result { Self::decode(input, Encoding::B64) } @@ -171,12 +157,12 @@ impl Output { /// a sub-slice containing the encoded data. /// /// Returns an error if the buffer is too short to contain the output. - pub fn b64_encode<'a>(&self, out: &'a mut [u8]) -> Result<&'a str, OutputError> { + pub fn b64_encode<'a>(&self, out: &'a mut [u8]) -> Result<&'a str> { self.encode(out, Encoding::B64) } /// Decode the given input string using the specified [`Encoding`]. - pub fn decode(input: &str, encoding: Encoding) -> Result { + pub fn decode(input: &str, encoding: Encoding) -> Result { let mut bytes = [0u8; Self::MAX_LENGTH]; encoding .decode(input, &mut bytes) @@ -185,11 +171,7 @@ impl Output { } /// Encode this [`Output`] using the specified [`Encoding`]. - pub fn encode<'a>( - &self, - out: &'a mut [u8], - encoding: Encoding, - ) -> Result<&'a str, OutputError> { + pub fn encode<'a>(&self, out: &'a mut [u8], encoding: Encoding) -> Result<&'a str> { Ok(encoding.encode(self.as_ref(), out)?) } @@ -206,9 +188,9 @@ impl AsRef<[u8]> for Output { } impl FromStr for Output { - type Err = OutputError; + type Err = Error; - fn from_str(s: &str) -> Result { + fn from_str(s: &str) -> Result { Self::b64_decode(s) } } @@ -230,9 +212,9 @@ impl PartialEq for Output { } impl TryFrom<&[u8]> for Output { - type Error = OutputError; + type Error = Error; - fn try_from(input: &[u8]) -> Result { + fn try_from(input: &[u8]) -> Result { Self::new(input) } } @@ -254,7 +236,7 @@ impl fmt::Debug for Output { #[cfg(test)] mod tests { - use super::{Output, OutputError}; + use super::{Error, Output}; #[test] fn new_with_valid_min_length_input() { @@ -274,14 +256,14 @@ mod tests { fn reject_new_too_short() { let bytes = [9u8; 9]; let err = Output::new(&bytes).err().unwrap(); - assert_eq!(err, OutputError::TooShort); + assert_eq!(err, Error::OutputTooShort); } #[test] fn reject_new_too_long() { let bytes = [65u8; 65]; let err = Output::new(&bytes).err().unwrap(); - assert_eq!(err, OutputError::TooLong); + assert_eq!(err, Error::OutputTooLong); } #[test] diff --git a/password-hash/src/params.rs b/password-hash/src/params.rs index 07db0f70d..66767dafd 100644 --- a/password-hash/src/params.rs +++ b/password-hash/src/params.rs @@ -1,13 +1,12 @@ //! Algorithm parameters. use crate::{ - errors::{ParamsError, ParseError}, value::{Decimal, Value}, - Ident, + Error, Ident, Result, }; use core::{ convert::{TryFrom, TryInto}, - fmt::{self, Write}, + fmt::{self, Debug, Write}, iter::FromIterator, str::{self, FromStr}, }; @@ -55,19 +54,15 @@ impl ParamsString { &mut self, name: impl TryInto>, value: impl TryInto>, - ) -> Result<(), ParamsError> { - let name = name.try_into().map_err(|_| ParamsError::InvalidName)?; - let value = value.try_into().map_err(|_| ParamsError::InvalidValue)?; + ) -> Result<()> { + let name = name.try_into().map_err(|_| Error::ParamNameInvalid)?; + let value = value.try_into().map_err(|_| Error::ParamValueInvalid)?; self.add(name, value) } /// Add a key/value pair with a decimal value to the [`ParamsString`]. - pub fn add_decimal<'a>( - &mut self, - name: impl TryInto>, - value: Decimal, - ) -> Result<(), ParamsError> { - let name = name.try_into().map_err(|_| ParamsError::InvalidName)?; + pub fn add_decimal<'a>(&mut self, name: impl TryInto>, value: Decimal) -> Result<()> { + let name = name.try_into().map_err(|_| Error::ParamNameInvalid)?; self.add(name, value) } @@ -122,9 +117,9 @@ impl ParamsString { } /// Add a value to this [`ParamsString`] using the provided callback. - fn add(&mut self, name: Ident<'_>, value: impl fmt::Display) -> Result<(), ParamsError> { + fn add(&mut self, name: Ident<'_>, value: impl fmt::Display) -> Result<()> { if self.get(name).is_some() { - return Err(ParamsError::DuplicateName); + return Err(Error::ParamNameDuplicated); } let orig_len = self.0.length; @@ -132,12 +127,12 @@ impl ParamsString { if !self.is_empty() { self.0 .write_char(PARAMS_DELIMITER) - .map_err(|_| ParamsError::MaxExceeded)? + .map_err(|_| Error::ParamsMaxExceeded)? } if write!(self.0, "{}={}", name, value).is_err() { self.0.length = orig_len; - return Err(ParamsError::MaxExceeded); + return Err(Error::ParamsMaxExceeded); } Ok(()) @@ -145,11 +140,11 @@ impl ParamsString { } impl FromStr for ParamsString { - type Err = ParamsError; + type Err = Error; - fn from_str(s: &str) -> Result { + fn from_str(s: &str) -> Result { if s.as_bytes().len() > MAX_LENGTH { - return Err(ParamsError::MaxExceeded); + return Err(Error::ParamsMaxExceeded); } if s.is_empty() { @@ -161,17 +156,17 @@ impl FromStr for ParamsString { // Validate name param .next() - .ok_or(ParseError::InvalidChar(PAIR_DELIMITER)) + .ok_or(Error::ParamNameInvalid) .and_then(Ident::try_from)?; // Validate value param .next() - .ok_or(ParseError::InvalidChar(PAIR_DELIMITER)) + .ok_or(Error::ParamValueInvalid) .and_then(Value::try_from)?; if param.next().is_some() { - return Err(ParseError::TooLong.into()); + return Err(Error::ParamValueInvalid); } } @@ -294,7 +289,7 @@ impl Write for Buffer { #[cfg(test)] mod tests { - use super::{FromIterator, Ident, ParamsError, ParamsString, Value}; + use super::{Error, FromIterator, Ident, ParamsString, Value}; #[cfg(feature = "alloc")] use alloc::string::ToString; @@ -320,7 +315,7 @@ mod tests { params.add_decimal(name, 1).unwrap(); let err = params.add_decimal(name, 2u32.into()).err().unwrap(); - assert_eq!(err, ParamsError::DuplicateName); + assert_eq!(err, Error::ParamNameDuplicated); } #[test] diff --git a/password-hash/src/salt.rs b/password-hash/src/salt.rs index c69d8f37a..486b3b8e0 100644 --- a/password-hash/src/salt.rs +++ b/password-hash/src/salt.rs @@ -1,6 +1,6 @@ //! Salt string support. -use crate::{B64Error, Encoding, ParseError, Value}; +use crate::{Encoding, Error, Result, Value}; use core::{ convert::{TryFrom, TryInto}, fmt, str, @@ -93,36 +93,19 @@ impl<'a> Salt<'a> { /// Recommended length of a salt: 16-bytes. pub const RECOMMENDED_LENGTH: usize = 16; - /// Minimum length of a [`Salt`] string: 4-bytes. - #[deprecated(since = "0.1.4", note = "use Salt::MIN_LENGTH instead")] - pub const fn min_len() -> usize { - Self::MIN_LENGTH - } - - /// Maximum length of a [`Salt`] string: 64-bytes. - #[deprecated(since = "0.1.4", note = "use Salt::MAX_LENGTH instead")] - pub const fn max_len() -> usize { - Self::MAX_LENGTH - } - - /// Recommended length of a salt: 16-bytes. - #[deprecated(since = "0.1.4", note = "use Salt::RECOMMENDED_LENGTH instead")] - pub const fn recommended_len() -> usize { - Self::RECOMMENDED_LENGTH - } - /// Create a [`Salt`] from the given `str`, validating it according to /// [`Salt::min_len`] and [`Salt::max_len`] length restrictions. - pub fn new(input: &'a str) -> Result { + pub fn new(input: &'a str) -> Result { if input.len() < Self::MIN_LENGTH { - return Err(ParseError::TooShort); + return Err(Error::SaltTooShort); } if input.len() > Self::MAX_LENGTH { - return Err(ParseError::TooLong); + return Err(Error::SaltTooLong); } - Ok(Self(input.try_into()?)) + // TODO(tarcieri): revisit potentially bogus error handling + input.try_into().map(Self).map_err(|_| Error::SaltTooLong) } /// Attempt to decode a B64-encoded [`Salt`], writing the decoded result @@ -130,7 +113,7 @@ impl<'a> Salt<'a> { /// containing the decoded result on success. /// /// [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#argon2-encoding - pub fn b64_decode<'b>(&self, buf: &'b mut [u8]) -> Result<&'b [u8], B64Error> { + pub fn b64_decode<'b>(&self, buf: &'b mut [u8]) -> Result<&'b [u8]> { self.0.b64_decode(buf) } @@ -157,9 +140,9 @@ impl<'a> AsRef for Salt<'a> { } impl<'a> TryFrom<&'a str> for Salt<'a> { - type Error = ParseError; + type Error = Error; - fn try_from(input: &'a str) -> Result { + fn try_from(input: &'a str) -> Result { Self::new(input) } } @@ -198,7 +181,7 @@ impl SaltString { } /// Create a new [`SaltString`]. - pub fn new(s: &str) -> Result { + pub fn new(s: &str) -> Result { // Assert `s` parses successifully as a `Salt` Salt::new(s)?; @@ -212,21 +195,21 @@ impl SaltString { length: length as u8, }) } else { - Err(ParseError::TooLong) + Err(Error::SaltTooLong) } } /// Encode the given byte slice as B64 into a new [`SaltString`]. /// /// Returns `None` if the slice is too long. - pub fn b64_encode(input: &[u8]) -> Result { + pub fn b64_encode(input: &[u8]) -> Result { let mut bytes = [0u8; Salt::MAX_LENGTH]; let length = Encoding::B64.encode(input, &mut bytes)?.len() as u8; Ok(Self { bytes, length }) } /// Decode this [`SaltString`] from B64 into the provided output buffer. - pub fn b64_decode<'a>(&self, buf: &'a mut [u8]) -> Result<&'a [u8], B64Error> { + pub fn b64_decode<'a>(&self, buf: &'a mut [u8]) -> Result<&'a [u8]> { self.as_salt().b64_decode(buf) } @@ -272,7 +255,7 @@ impl<'a> From<&'a SaltString> for Salt<'a> { #[cfg(test)] mod tests { - use super::{ParseError, Salt}; + use super::{Error, Salt}; #[test] fn new_with_valid_min_length_input() { @@ -292,7 +275,7 @@ mod tests { fn reject_new_too_short() { for &too_short in &["", "a", "ab", "abc"] { let err = Salt::new(too_short).err().unwrap(); - assert_eq!(err, ParseError::TooShort); + assert_eq!(err, Error::SaltTooShort); } } @@ -300,6 +283,6 @@ mod tests { fn reject_new_too_long() { let s = "0123456789112345678921234567893123456789412345678"; let err = Salt::new(s).err().unwrap(); - assert_eq!(err, ParseError::TooLong); + assert_eq!(err, Error::SaltTooLong); } } diff --git a/password-hash/src/value.rs b/password-hash/src/value.rs index 3beb55718..854ee0d9c 100644 --- a/password-hash/src/value.rs +++ b/password-hash/src/value.rs @@ -13,7 +13,7 @@ //! //! [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md -use crate::{B64Error, Encoding, ParseError}; +use crate::{Encoding, Error, Result}; use core::{convert::TryFrom, fmt, str}; /// Type used to represent decimal (i.e. integer) values. @@ -52,17 +52,11 @@ impl<'a> Value<'a> { /// [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#argon2-encoding pub const MAX_LENGTH: usize = 48; - /// Maximum length of an [`Value`] - 48 ASCII characters (i.e. 48-bytes). - #[deprecated(since = "0.1.4", note = "use Value::MAX_LENGTH instead")] - pub const fn max_len() -> usize { - Self::MAX_LENGTH - } - /// Parse a [`Value`] from the provided `str`, validating it according to /// the PHC string format's rules. - pub fn new(input: &'a str) -> Result { + pub fn new(input: &'a str) -> Result { if input.as_bytes().len() > Self::MAX_LENGTH { - return Err(ParseError::TooLong); + return Err(Error::ParamValueInvalid); } // Check that the characters are permitted in a PHC parameter value. @@ -79,8 +73,8 @@ impl<'a> Value<'a> { /// PHC string format specification. /// /// [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#argon2-encoding - pub fn b64_decode<'b>(&self, buf: &'b mut [u8]) -> Result<&'b [u8], B64Error> { - Encoding::B64.decode(self.as_str(), buf) + pub fn b64_decode<'b>(&self, buf: &'b mut [u8]) -> Result<&'b [u8]> { + Ok(Encoding::B64.decode(self.as_str(), buf)?) } /// Borrow this value as a `str`. @@ -131,31 +125,31 @@ impl<'a> Value<'a> { /// `value.as_str().parse::()` /// /// [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#decimal-encoding - pub fn decimal(&self) -> Result { + pub fn decimal(&self) -> Result { let value = self.as_str(); // Empty strings aren't decimals if value.is_empty() { - return Err(ParseError::Empty); + return Err(Error::ParamValueInvalid); } // Ensure all characters are digits for c in value.chars() { if !matches!(c, '0'..='9') { - return Err(ParseError::InvalidChar(c)); + return Err(Error::ParamValueInvalid); } } // Disallow leading zeroes if value.starts_with('0') && value.len() > 1 { - return Err(ParseError::InvalidChar('0')); + return Err(Error::ParamValueInvalid); } value.parse().map_err(|_| { // In theory a value overflow should be the only potential error here. // When `ParseIntError::kind` is stable it might be good to double check: // - ParseError::TooLong + Error::ParamValueInvalid }) } @@ -172,25 +166,25 @@ impl<'a> AsRef for Value<'a> { } impl<'a> TryFrom<&'a str> for Value<'a> { - type Error = ParseError; + type Error = Error; - fn try_from(input: &'a str) -> Result { + fn try_from(input: &'a str) -> Result { Self::new(input) } } impl<'a> TryFrom> for Decimal { - type Error = ParseError; + type Error = Error; - fn try_from(value: Value<'a>) -> Result { + fn try_from(value: Value<'a>) -> Result { Decimal::try_from(&value) } } impl<'a> TryFrom<&Value<'a>> for Decimal { - type Error = ParseError; + type Error = Error; - fn try_from(value: &Value<'a>) -> Result { + fn try_from(value: &Value<'a>) -> Result { value.decimal() } } @@ -202,10 +196,10 @@ impl<'a> fmt::Display for Value<'a> { } /// Are all of the given bytes allowed in a [`Value`]? -fn assert_valid_value(input: &str) -> Result<(), ParseError> { +fn assert_valid_value(input: &str) -> Result<()> { for c in input.chars() { if !is_char_valid(c) { - return Err(ParseError::InvalidChar(c)); + return Err(Error::ParamValueInvalid); } } @@ -219,7 +213,7 @@ fn is_char_valid(c: char) -> bool { #[cfg(test)] mod tests { - use super::{ParseError, Value}; + use super::{Error, Value}; use core::convert::TryFrom; // Invalid value examples @@ -246,21 +240,21 @@ mod tests { fn reject_decimal_with_leading_zero() { let value = Value::new("01").unwrap(); let err = u32::try_from(value).err().unwrap(); - assert!(matches!(err, ParseError::InvalidChar('0'))); + assert!(matches!(err, Error::ParamValueInvalid)); } #[test] fn reject_overlong_decimal() { let value = Value::new("4294967296").unwrap(); let err = u32::try_from(value).err().unwrap(); - assert_eq!(err, ParseError::TooLong); + assert_eq!(err, Error::ParamValueInvalid); } #[test] fn reject_negative() { let value = Value::new("-1").unwrap(); let err = u32::try_from(value).err().unwrap(); - assert!(matches!(err, ParseError::InvalidChar('-'))); + assert!(matches!(err, Error::ParamValueInvalid)); } // @@ -288,18 +282,18 @@ mod tests { #[test] fn reject_invalid_char() { let err = Value::new(INVALID_CHAR).err().unwrap(); - assert!(matches!(err, ParseError::InvalidChar(';'))); + assert!(matches!(err, Error::ParamValueInvalid)); } #[test] fn reject_too_long() { let err = Value::new(INVALID_TOO_LONG).err().unwrap(); - assert_eq!(err, ParseError::TooLong); + assert_eq!(err, Error::ParamValueInvalid); } #[test] fn reject_invalid_char_and_too_long() { let err = Value::new(INVALID_CHAR_AND_TOO_LONG).err().unwrap(); - assert_eq!(err, ParseError::TooLong); + assert_eq!(err, Error::ParamValueInvalid); } } diff --git a/password-hash/tests/hashing.rs b/password-hash/tests/hashing.rs index bdd69205d..532a43cac 100644 --- a/password-hash/tests/hashing.rs +++ b/password-hash/tests/hashing.rs @@ -1,8 +1,7 @@ //! Password hashing tests pub use password_hash::{ - Decimal, HasherError, Ident, Output, ParamsString, PasswordHash, PasswordHasher, Salt, - VerifyError, + Decimal, Error, Ident, Output, ParamsString, PasswordHash, PasswordHasher, Result, Salt, }; use std::convert::{TryFrom, TryInto}; @@ -18,15 +17,15 @@ impl PasswordHasher for StubPasswordHasher { &self, password: &[u8], algorithm: Option>, - _version: Option, params: StubParams, - salt: Salt<'a>, - ) -> Result, HasherError> { + salt: impl Into>, + ) -> Result> { + let salt = salt.into(); let mut output = Vec::new(); if let Some(alg) = algorithm { if alg != ALG { - return Err(HasherError::Algorithm); + return Err(Error::Algorithm); } } @@ -50,18 +49,18 @@ impl PasswordHasher for StubPasswordHasher { #[derive(Clone, Debug, Default)] pub struct StubParams; -impl<'a> TryFrom<&'a ParamsString> for StubParams { - type Error = HasherError; +impl<'a> TryFrom<&PasswordHash<'a>> for StubParams { + type Error = Error; - fn try_from(_: &'a ParamsString) -> Result { + fn try_from(_: &PasswordHash<'a>) -> Result { Ok(Self) } } impl<'a> TryFrom for ParamsString { - type Error = HasherError; + type Error = Error; - fn try_from(_: StubParams) -> Result { + fn try_from(_: StubParams) -> Result { Ok(Self::default()) } } @@ -84,6 +83,6 @@ fn verify_password_hash() { assert_eq!( hash.verify_password(&[&StubPasswordHasher], "wrong password"), - Err(VerifyError) + Err(Error::Password) ); } From 92668869e2fea6ff3de6a5a531e1615c3efd61ae Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 28 Apr 2021 12:31:15 -0700 Subject: [PATCH 0497/1461] crypto-common v0.1.0-pre (#618) --- Cargo.lock | 2 +- cipher/Cargo.toml | 2 +- crypto-common/Cargo.toml | 2 +- crypto-mac/Cargo.toml | 4 ++-- digest/Cargo.toml | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 81efd18b0..75fd5e3a0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -144,7 +144,7 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.1.0" +version = "0.1.0-pre" dependencies = [ "block-buffer 0.10.0-pre.2", "generic-array 0.14.4", diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index d01e925b3..0e3e79289 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -13,7 +13,7 @@ categories = ["cryptography", "no-std"] [dependencies] generic-array = "0.14" -crypto-common = { version = "0.1", path = "../crypto-common/" } +crypto-common = { version = "=0.1.0-pre", path = "../crypto-common" } block-buffer = { version = "0.10.0-pre.2", features = ["block-padding"], optional = true } blobby = { version = "0.3", optional = true } diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index fd1fdb780..3fa429be3 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crypto-common" description = "Common cryptographic traits" -version = "0.1.0" +version = "0.1.0-pre" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/crypto-mac/Cargo.toml b/crypto-mac/Cargo.toml index 4c367b963..310c8be8f 100644 --- a/crypto-mac/Cargo.toml +++ b/crypto-mac/Cargo.toml @@ -13,8 +13,8 @@ categories = ["cryptography", "no-std"] [dependencies] generic-array = "0.14" -crypto-common = { version = "0.1", path = "../crypto-common/" } -cipher = { version = "0.3.0-pre.4", path = "../cipher/" } +crypto-common = { version = "=0.1.0-pre", path = "../crypto-common" } +cipher = { version = "=0.3.0-pre.4", path = "../cipher" } subtle = { version = "2", default-features = false } blobby = { version = "0.3", optional = true } diff --git a/digest/Cargo.toml b/digest/Cargo.toml index d1a884dee..61852b9d9 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -13,7 +13,7 @@ categories = ["cryptography", "no-std"] [dependencies] generic-array = "0.14" -crypto-common = { version = "0.1", path = "../crypto-common/" } +crypto-common = { version = "=0.1.0-pre", path = "../crypto-common" } blobby = { version = "0.3", optional = true } From 80918dd5bbb8694f6ec30ea33a23dcca283ed07f Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 28 Apr 2021 14:13:27 -0700 Subject: [PATCH 0498/1461] cipher v0.3.0-pre.5 (#619) --- Cargo.lock | 15 +++++++++------ Cargo.toml | 4 ---- cipher/Cargo.toml | 4 ++-- crypto-mac/Cargo.toml | 2 +- crypto/Cargo.toml | 3 ++- crypto/src/lib.rs | 2 ++ 6 files changed, 16 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 75fd5e3a0..6432cc5c3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -78,8 +78,9 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.10.0-pre.2" -source = "git+https://github.com/RustCrypto/utils?branch=block_mode#39ee346fde26516678ca3700b88c53b288b39e1c" +version = "0.10.0-pre.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4b13c429c0b48d55a541108e23c7795eb821ee65b50c2f719f4f7fc5a022dcf" dependencies = [ "block-padding", "generic-array 0.14.4", @@ -88,7 +89,8 @@ dependencies = [ [[package]] name = "block-padding" version = "0.3.0-pre" -source = "git+https://github.com/RustCrypto/utils?branch=block_mode#39ee346fde26516678ca3700b88c53b288b39e1c" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3992d179d1dd2fa87869057217d43cf88ad31d4e44738d159a5a6caafdf63ae6" dependencies = [ "generic-array 0.14.4", ] @@ -107,10 +109,10 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cipher" -version = "0.3.0-pre.4" +version = "0.3.0-pre.5" dependencies = [ "blobby", - "block-buffer 0.10.0-pre.2", + "block-buffer 0.10.0-pre.4", "crypto-common", "generic-array 0.14.4", "rand_core", @@ -134,6 +136,7 @@ version = "0.2.0-pre" dependencies = [ "aead", "cipher", + "crypto-common", "crypto-mac", "digest 0.10.0-pre.3", "elliptic-curve", @@ -146,7 +149,7 @@ dependencies = [ name = "crypto-common" version = "0.1.0-pre" dependencies = [ - "block-buffer 0.10.0-pre.2", + "block-buffer 0.10.0-pre.4", "generic-array 0.14.4", ] diff --git a/Cargo.toml b/Cargo.toml index b9c153fbe..ebf9e0985 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,3 @@ members = [ "signature/async", "universal-hash", ] - -[patch.crates-io] -block-buffer = { git = "https://github.com/RustCrypto/utils", branch = "block_mode" } -block-padding = { git = "https://github.com/RustCrypto/utils", branch = "block_mode" } diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index 0e3e79289..c53cdca00 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "cipher" description = "Traits for describing block ciphers and stream ciphers" -version = "0.3.0-pre.4" +version = "0.3.0-pre.5" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" @@ -15,7 +15,7 @@ categories = ["cryptography", "no-std"] generic-array = "0.14" crypto-common = { version = "=0.1.0-pre", path = "../crypto-common" } -block-buffer = { version = "0.10.0-pre.2", features = ["block-padding"], optional = true } +block-buffer = { version = "=0.10.0-pre.4", features = ["block-padding"], optional = true } blobby = { version = "0.3", optional = true } rand_core = { version = "0.6", optional = true } diff --git a/crypto-mac/Cargo.toml b/crypto-mac/Cargo.toml index 310c8be8f..ccda47797 100644 --- a/crypto-mac/Cargo.toml +++ b/crypto-mac/Cargo.toml @@ -14,7 +14,7 @@ categories = ["cryptography", "no-std"] [dependencies] generic-array = "0.14" crypto-common = { version = "=0.1.0-pre", path = "../crypto-common" } -cipher = { version = "=0.3.0-pre.4", path = "../cipher" } +cipher = { version = "=0.3.0-pre.5", path = "../cipher" } subtle = { version = "2", default-features = false } blobby = { version = "0.3", optional = true } diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 96a5adb5b..ce4184654 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -13,7 +13,8 @@ edition = "2018" [dependencies] aead = { version = "0.4", optional = true, path = "../aead" } -cipher = { version = "=0.3.0-pre.4", optional = true, path = "../cipher" } +cipher = { version = "=0.3.0-pre.5", optional = true, path = "../cipher" } +common = { version = "=0.1.0-pre", package = "crypto-common", path = "../crypto-common" } digest = { version = "0.10.0-pre", optional = true, path = "../digest" } elliptic-curve = { version = "0.9", optional = true, path = "../elliptic-curve" } mac = { version = "=0.11.0-pre", package = "crypto-mac", optional = true, path = "../crypto-mac" } diff --git a/crypto/src/lib.rs b/crypto/src/lib.rs index b52b4b9f9..cc11a12aa 100644 --- a/crypto/src/lib.rs +++ b/crypto/src/lib.rs @@ -43,6 +43,8 @@ #![forbid(unsafe_code)] #![warn(rust_2018_idioms)] +pub use common; + #[cfg(feature = "aead")] pub use aead; From d90db056e44ae4d6d7b60d0d8fb9a1242de3971c Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 28 Apr 2021 14:24:41 -0700 Subject: [PATCH 0499/1461] crypto-mac v0.11.0-pre.1 (#620) --- Cargo.lock | 2 +- crypto-mac/Cargo.toml | 2 +- crypto/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6432cc5c3..255b405a7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -155,7 +155,7 @@ dependencies = [ [[package]] name = "crypto-mac" -version = "0.11.0-pre" +version = "0.11.0-pre.1" dependencies = [ "blobby", "cipher", diff --git a/crypto-mac/Cargo.toml b/crypto-mac/Cargo.toml index ccda47797..bb04f65de 100644 --- a/crypto-mac/Cargo.toml +++ b/crypto-mac/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crypto-mac" description = "Trait for Message Authentication Code (MAC) algorithms" -version = "0.11.0-pre" +version = "0.11.0-pre.1" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index ce4184654..d88c09398 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -17,7 +17,7 @@ cipher = { version = "=0.3.0-pre.5", optional = true, path = "../cipher" } common = { version = "=0.1.0-pre", package = "crypto-common", path = "../crypto-common" } digest = { version = "0.10.0-pre", optional = true, path = "../digest" } elliptic-curve = { version = "0.9", optional = true, path = "../elliptic-curve" } -mac = { version = "=0.11.0-pre", package = "crypto-mac", optional = true, path = "../crypto-mac" } +mac = { version = "=0.11.0-pre.1", package = "crypto-mac", optional = true, path = "../crypto-mac" } password-hash = { version = "=0.2.0-pre", optional = true, path = "../password-hash" } signature = { version = "1.3.0", optional = true, default-features = false, path = "../signature" } universal-hash = { version = "0.4", optional = true, path = "../universal-hash" } From 1f724476585b9c3d53c917a047c966ae9c949e37 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 28 Apr 2021 15:29:56 -0700 Subject: [PATCH 0500/1461] `cipher` v0.3.0 and `crypto-mac` v0.11.0 release rollup (#623) * cipher v0.3.0 * crypto-mac v0.11.0 --- Cargo.lock | 46 +++++++++++++++++++++++++++-------------- cipher/CHANGELOG.md | 18 ++++++++++++++++ cipher/Cargo.toml | 2 +- crypto-mac/CHANGELOG.md | 6 ++++++ crypto-mac/Cargo.toml | 4 ++-- crypto/Cargo.toml | 9 ++++---- crypto/src/lib.rs | 2 -- 7 files changed, 62 insertions(+), 25 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 255b405a7..e541e1150 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,7 +1,5 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 - [[package]] name = "aead" version = "0.4.0" @@ -51,9 +49,9 @@ checksum = "d0d27fb6b6f1e43147af148af49d49329413ba781aa0d5e10979831c210173b5" [[package]] name = "bitvec" -version = "0.20.2" +version = "0.20.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f682656975d3a682daff957be4ddeb65d6ad656737cd821f2d00685ae466af1" +checksum = "7774144344a4faa177370406a7ff5f1da24303817368584c6206c8303eb07848" dependencies = [ "funty", "radium", @@ -109,7 +107,16 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cipher" -version = "0.3.0-pre.5" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" +dependencies = [ + "generic-array 0.14.4", +] + +[[package]] +name = "cipher" +version = "0.4.0-pre" dependencies = [ "blobby", "block-buffer 0.10.0-pre.4", @@ -120,9 +127,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af497ba993c3f3c416a0e1e1d84b81c3e0b131c4c67105a391920ba4dfa24d2d" +checksum = "279bc8fc53f788a75c7804af68237d1fce02cde1e275a886a4b320604dc2aeda" [[package]] name = "cpuid-bool" @@ -135,10 +142,9 @@ name = "crypto" version = "0.2.0-pre" dependencies = [ "aead", - "cipher", - "crypto-common", - "crypto-mac", - "digest 0.10.0-pre.3", + "cipher 0.3.0", + "crypto-mac 0.11.0", + "digest 0.9.0", "elliptic-curve", "password-hash", "signature", @@ -155,10 +161,20 @@ dependencies = [ [[package]] name = "crypto-mac" -version = "0.11.0-pre.1" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25fab6889090c8133f3deb8f73ba3c65a7f456f66436fc012a1b1e272b1e103e" +dependencies = [ + "generic-array 0.14.4", + "subtle", +] + +[[package]] +name = "crypto-mac" +version = "0.12.0-pre" dependencies = [ "blobby", - "cipher", + "cipher 0.4.0-pre", "crypto-common", "generic-array 0.14.4", "rand_core", @@ -460,9 +476,9 @@ checksum = "1e81da0851ada1f3e9d4312c704aa4f8806f0f9d69faaf8df2f3464b4a9437c2" [[package]] name = "syn" -version = "1.0.69" +version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48fe99c6bd8b1cc636890bcc071842de909d902c81ac7dab53ba33c421ab8ffb" +checksum = "ad184cc9470f9117b2ac6817bfe297307418819ba40552f9b3846f05c33d5373" dependencies = [ "proc-macro2", "quote", diff --git a/cipher/CHANGELOG.md b/cipher/CHANGELOG.md index e7743e965..426cc83c6 100644 --- a/cipher/CHANGELOG.md +++ b/cipher/CHANGELOG.md @@ -5,6 +5,24 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.3.0 (2021-04-28) +### Added +- Encrypt/decrypt-only block cipher traits ([#352]) +- Re-export `blobby` from root ([#435]) +- Block cipher trait blanket impls for refs ([#441]) + +### Changed +- Consolidate error types ([#373]) +- Change `SeekNum` impls to fit with the new `BlockBuffer` ([#435]) +- Reorganize modules ([#435]) +- Renamed `new_var` to `new_from_slice(s)` ([#442]) + +[#352]: https://github.com/RustCrypto/traits/pull/352 +[#373]: https://github.com/RustCrypto/traits/pull/373 +[#435]: https://github.com/RustCrypto/traits/pull/435 +[#441]: https://github.com/RustCrypto/traits/pull/441 +[#442]: https://github.com/RustCrypto/traits/pull/442 + ## 0.2.5 (2020-11-01) ### Fixed - Nested macros used old deprecated names ([#360]) diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index c53cdca00..803b017eb 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "cipher" description = "Traits for describing block ciphers and stream ciphers" -version = "0.3.0-pre.5" +version = "0.4.0-pre" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/crypto-mac/CHANGELOG.md b/crypto-mac/CHANGELOG.md index 9d4f0b24c..d63daa7b7 100644 --- a/crypto-mac/CHANGELOG.md +++ b/crypto-mac/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.11.0 (2021-04-28) +### Changed +- Bump `cipher` dependency to v0.3 ([#621]) + +[#621]: https://github.com/RustCrypto/traits/pull/621 + ## 0.10.0 (2020-10-15) ### Changed - Replace `block-cipher` crate with new `cipher` crate ([#337], [#338]) diff --git a/crypto-mac/Cargo.toml b/crypto-mac/Cargo.toml index bb04f65de..259c6bdb2 100644 --- a/crypto-mac/Cargo.toml +++ b/crypto-mac/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crypto-mac" description = "Trait for Message Authentication Code (MAC) algorithms" -version = "0.11.0-pre.1" +version = "0.12.0-pre" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" @@ -14,7 +14,7 @@ categories = ["cryptography", "no-std"] [dependencies] generic-array = "0.14" crypto-common = { version = "=0.1.0-pre", path = "../crypto-common" } -cipher = { version = "=0.3.0-pre.5", path = "../cipher" } +cipher = { version = "=0.4.0-pre", path = "../cipher" } subtle = { version = "2", default-features = false } blobby = { version = "0.3", optional = true } diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index d88c09398..63fe856bf 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -13,13 +13,12 @@ edition = "2018" [dependencies] aead = { version = "0.4", optional = true, path = "../aead" } -cipher = { version = "=0.3.0-pre.5", optional = true, path = "../cipher" } -common = { version = "=0.1.0-pre", package = "crypto-common", path = "../crypto-common" } -digest = { version = "0.10.0-pre", optional = true, path = "../digest" } +cipher = { version = "0.3", optional = true } +digest = { version = "0.9", optional = true } elliptic-curve = { version = "0.9", optional = true, path = "../elliptic-curve" } -mac = { version = "=0.11.0-pre.1", package = "crypto-mac", optional = true, path = "../crypto-mac" } +mac = { version = "0.11", package = "crypto-mac", optional = true } password-hash = { version = "=0.2.0-pre", optional = true, path = "../password-hash" } -signature = { version = "1.3.0", optional = true, default-features = false, path = "../signature" } +signature = { version = "1.2.0", optional = true, default-features = false, path = "../signature" } universal-hash = { version = "0.4", optional = true, path = "../universal-hash" } [features] diff --git a/crypto/src/lib.rs b/crypto/src/lib.rs index cc11a12aa..b52b4b9f9 100644 --- a/crypto/src/lib.rs +++ b/crypto/src/lib.rs @@ -43,8 +43,6 @@ #![forbid(unsafe_code)] #![warn(rust_2018_idioms)] -pub use common; - #[cfg(feature = "aead")] pub use aead; From a0662579802db6fbe4a68caa1d1113917210209d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 29 Apr 2021 08:03:46 -0700 Subject: [PATCH 0501/1461] password-hash v0.2.0 (#624) --- Cargo.lock | 2 +- crypto/Cargo.toml | 2 +- password-hash/CHANGELOG.md | 8 ++++++++ password-hash/Cargo.toml | 4 ++-- password-hash/src/lib.rs | 2 +- 5 files changed, 13 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e541e1150..a6586354f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -342,7 +342,7 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "password-hash" -version = "0.2.0-pre" +version = "0.2.0" dependencies = [ "base64ct", "rand_core", diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 63fe856bf..1ccb46631 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -17,7 +17,7 @@ cipher = { version = "0.3", optional = true } digest = { version = "0.9", optional = true } elliptic-curve = { version = "0.9", optional = true, path = "../elliptic-curve" } mac = { version = "0.11", package = "crypto-mac", optional = true } -password-hash = { version = "=0.2.0-pre", optional = true, path = "../password-hash" } +password-hash = { version = "0.2", optional = true, path = "../password-hash" } signature = { version = "1.2.0", optional = true, default-features = false, path = "../signature" } universal-hash = { version = "0.4", optional = true, path = "../universal-hash" } diff --git a/password-hash/CHANGELOG.md b/password-hash/CHANGELOG.md index cd329b717..18e98c5c0 100644 --- a/password-hash/CHANGELOG.md +++ b/password-hash/CHANGELOG.md @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.2.0 (2021-04-29) +### Changed +- Allow specifying output length and version with params ([#615]) +- Allow passing `&str`, `&Salt`, or `&SaltString` as salt ([#615]) +- Simplify error handling ([#615]) + +[#615]: https://github.com/RustCrypto/traits/pull/615 + ## 0.1.4 (2021-04-19) ### Added - Length constants ([#600]) diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index f6468f92c..b2f90f5f2 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -5,7 +5,7 @@ Traits which describe the functionality of password hashing algorithms, as well as a `no_std`-friendly implementation of the PHC string format (a well-defined subset of the Modular Crypt Format a.k.a. MCF) """ -version = "0.2.0-pre" +version = "0.2.0" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" @@ -25,4 +25,4 @@ std = ["alloc", "base64ct/std"] [package.metadata.docs.rs] rustc-args = ["--cfg", "docsrs"] -features = ["rand_core"] +all-features = true diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index bf9efc628..7acbbaccf 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -39,7 +39,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/password-hash/0.2.0-pre" + html_root_url = "https://docs.rs/password-hash/0.2.0" )] #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] From 5c2a660b800b2551108bf38d399400d3dbe255fa Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 29 Apr 2021 19:21:54 -0700 Subject: [PATCH 0502/1461] crypto v0.2.0 (#625) Initial (re-)release of the `cryptography` crate as `crypto` --- Cargo.lock | 2 +- crypto/CHANGELOG.md | 71 ++++----------------------------------------- crypto/Cargo.toml | 6 ++-- crypto/src/lib.rs | 3 +- 4 files changed, 13 insertions(+), 69 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a6586354f..7cf5fb40c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -139,7 +139,7 @@ checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634" [[package]] name = "crypto" -version = "0.2.0-pre" +version = "0.2.0" dependencies = [ "aead", "cipher 0.3.0", diff --git a/crypto/CHANGELOG.md b/crypto/CHANGELOG.md index e4b0f40c3..986d0470c 100644 --- a/crypto/CHANGELOG.md +++ b/crypto/CHANGELOG.md @@ -5,72 +5,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 0.5.0 (2020-10-15) -### Changed -- Bump `crypto-mac` to v0.10 ([#339]) -- Unify `block-cipher`/`stream-cipher` into `cipher` ([#337], [#338]) +## 0.2.0 (2021-04-29) +- Initial (re-)release of the `cryptography` crate as `crypto` -[#339]: https://github.com/RustCrypto/traits/pull/339 -[#338]: https://github.com/RustCrypto/traits/pull/338 -[#337]: https://github.com/RustCrypto/traits/pull/337 +## 0.1.2 (2020-06-19) [YANKED] -## 0.4.1 (2020-09-29) -### Added -- `std` feature ([#317]) +## 0.1.1 (2020-06-19) [YANKED] -[#317]: https://github.com/RustCrypto/traits/pull/317 +## 0.1.0 (2020-05-21) [YANKED] -## 0.4.0 (2020-09-25) -### Changed -- Bump `signature` dependency to 1.2.0 ([#314]) -- Bump `elliptic-curve` dependency to 0.6 ([#302]) -- Bump `stream-cipher` dependency to 0.7 ([#260]) - -[#314]: https://github.com/RustCrypto/traits/pull/314 -[#302]: https://github.com/RustCrypto/traits/pull/302 -[#260]: https://github.com/RustCrypto/traits/pull/260 - -## 0.3.0 (2020-08-10) -### Added -- `elliptic-curve` feature ([#213]) - -### Changed -- Bump `crypto-mac` to v0.9 ([#217]) - -[#213]: https://github.com/RustCrypto/traits/pull/213 -[#217]: https://github.com/RustCrypto/traits/pull/217 - -## 0.2.0 (2020-07-03) -### Changed -- Bump `stream-cipher` to v0.5 ([#209]) - -[#209]: https://github.com/RustCrypto/traits/pull/209 - -## 0.1.4 (2020-06-21) -### Added -- rustdoc improvements ([#205]) -- `mac` feature ([#204]) - -[#205]: https://github.com/RustCrypto/traits/pull/205 -[#204]: https://github.com/RustCrypto/traits/pull/204 - -## 0.1.3 (2020-06-21) -### Fixed -- Link rendering on https://docs.rs ([#202]) - -[#202]: https://github.com/RustCrypto/traits/pull/202 - -## 0.1.2 (2020-06-21) -### Fixed -- (Attempted) fix link rendering on https://docs.rs ([#200]) - -[#200]: https://github.com/RustCrypto/traits/pull/200 - -## 0.1.2 (2020-06-21) -### Fixed -- Rustdoc link rendering for https://docs.rs ([#200]) - -[#200]: https://github.com/RustCrypto/traits/pull/200 - -## 0.1.1 (2020-06-21) -- Initial release +## 0.0.2 (2014-11-21) [YANKED] diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 1ccb46631..a17fb663b 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -1,9 +1,11 @@ [package] name = "crypto" -version = "0.2.0-pre" +version = "0.2.0" # Also update html_root_url in lib.rs when bumping this +description = """ +Resources for building cryptosystems in Rust using the RustCrypto project's ecosystem. +""" authors = ["The RustCrypto Project Developers"] license = "Apache-2.0 OR MIT" -description = "Facade crate for the RustCrypto project's traits" documentation = "https://docs.rs/crypto" repository = "https://github.com/RustCrypto/traits" keywords = ["crypto", "encryption", "rustcrypto"] diff --git a/crypto/src/lib.rs b/crypto/src/lib.rs index b52b4b9f9..62143d08b 100644 --- a/crypto/src/lib.rs +++ b/crypto/src/lib.rs @@ -38,7 +38,8 @@ #![no_std] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg" + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", + html_root_url = "https://docs.rs/crypto/0.2.0" )] #![forbid(unsafe_code)] #![warn(rust_2018_idioms)] From 54200c5f8497b641c0fbca8ff3720e436ff3725b Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 3 May 2021 07:06:51 -0700 Subject: [PATCH 0503/1461] Bump `heapless` dependency to v0.7 (#628) --- .github/workflows/aead.yml | 22 +++- .github/workflows/workspace.yml | 2 +- Cargo.lock | 173 +++++++++++++++++++++++--------- aead/Cargo.toml | 2 +- aead/src/lib.rs | 5 +- aead/src/stream.rs | 2 + cipher/src/stream.rs | 1 + 7 files changed, 151 insertions(+), 56 deletions(-) diff --git a/.github/workflows/aead.yml b/.github/workflows/aead.yml index f62d2d9fd..4a1e675c8 100644 --- a/.github/workflows/aead.yml +++ b/.github/workflows/aead.yml @@ -40,6 +40,26 @@ jobs: - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features rand_core - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features stream + heapless: + runs-on: ubuntu-latest + strategy: + matrix: + rust: + - 1.51.0 # MSRV for `heapless` + - stable + target: + - thumbv7em-none-eabi + - wasm32-unknown-unknown + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.rust }} + target: ${{ matrix.target }} + override: true + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features heapless + test: runs-on: ubuntu-latest strategy: @@ -56,4 +76,4 @@ jobs: - run: cargo check --all-features - run: cargo test --release --no-default-features - run: cargo test --release - - run: cargo test --release --all-features + - run: cargo test --release --features dev,rand_core,stream,std diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index a90364c20..74d9c7419 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -16,7 +16,7 @@ jobs: - uses: actions/checkout@v1 - uses: actions-rs/toolchain@v1 with: - toolchain: 1.47.0 # Highest MSRV in repo + toolchain: 1.51.0 # Highest MSRV in repo components: clippy override: true profile: minimal diff --git a/Cargo.lock b/Cargo.lock index 7cf5fb40c..0e3c7b258 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5,23 +5,11 @@ name = "aead" version = "0.4.0" dependencies = [ "blobby", - "generic-array 0.14.4", + "generic-array", "heapless", "rand_core", ] -[[package]] -name = "as-slice" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45403b49e3954a4b8428a0ac21a4b7afadccf92bfd96273f1a58cd4812496ae0" -dependencies = [ - "generic-array 0.12.4", - "generic-array 0.13.3", - "generic-array 0.14.4", - "stable_deref_trait", -] - [[package]] name = "async-signature" version = "0.0.1" @@ -41,12 +29,36 @@ dependencies = [ "syn", ] +[[package]] +name = "atomic-polyfill" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30302dda7a66f8c55932ebf208f7def840743ff64d495e9ceffcd97c18f11d39" +dependencies = [ + "cortex-m", +] + +[[package]] +name = "bare-metal" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3" +dependencies = [ + "rustc_version", +] + [[package]] name = "base64ct" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0d27fb6b6f1e43147af148af49d49329413ba781aa0d5e10979831c210173b5" +[[package]] +name = "bitfield" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719" + [[package]] name = "bitvec" version = "0.20.4" @@ -71,7 +83,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "generic-array 0.14.4", + "generic-array", ] [[package]] @@ -81,7 +93,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4b13c429c0b48d55a541108e23c7795eb821ee65b50c2f719f4f7fc5a022dcf" dependencies = [ "block-padding", - "generic-array 0.14.4", + "generic-array", ] [[package]] @@ -90,7 +102,7 @@ version = "0.3.0-pre" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3992d179d1dd2fa87869057217d43cf88ad31d4e44738d159a5a6caafdf63ae6" dependencies = [ - "generic-array 0.14.4", + "generic-array", ] [[package]] @@ -111,7 +123,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" dependencies = [ - "generic-array 0.14.4", + "generic-array", ] [[package]] @@ -121,7 +133,7 @@ dependencies = [ "blobby", "block-buffer 0.10.0-pre.4", "crypto-common", - "generic-array 0.14.4", + "generic-array", "rand_core", ] @@ -131,6 +143,18 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "279bc8fc53f788a75c7804af68237d1fce02cde1e275a886a4b320604dc2aeda" +[[package]] +name = "cortex-m" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "643a210c1bdc23d0db511e2a576082f4ff4dcae9d0c37f50b431b8f8439d6d6b" +dependencies = [ + "bare-metal", + "bitfield", + "embedded-hal", + "volatile-register", +] + [[package]] name = "cpuid-bool" version = "0.1.2" @@ -156,7 +180,7 @@ name = "crypto-common" version = "0.1.0-pre" dependencies = [ "block-buffer 0.10.0-pre.4", - "generic-array 0.14.4", + "generic-array", ] [[package]] @@ -165,7 +189,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25fab6889090c8133f3deb8f73ba3c65a7f456f66436fc012a1b1e272b1e103e" dependencies = [ - "generic-array 0.14.4", + "generic-array", "subtle", ] @@ -176,7 +200,7 @@ dependencies = [ "blobby", "cipher 0.4.0-pre", "crypto-common", - "generic-array 0.14.4", + "generic-array", "rand_core", "subtle", ] @@ -196,7 +220,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ - "generic-array 0.14.4", + "generic-array", ] [[package]] @@ -205,7 +229,7 @@ version = "0.10.0-pre.3" dependencies = [ "blobby", "crypto-common", - "generic-array 0.14.4", + "generic-array", ] [[package]] @@ -215,7 +239,7 @@ dependencies = [ "base64ct", "bitvec", "ff", - "generic-array 0.14.4", + "generic-array", "group", "hex-literal 0.3.1", "pkcs8", @@ -226,6 +250,16 @@ dependencies = [ "zeroize", ] +[[package]] +name = "embedded-hal" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db184d3fa27bc7a2344250394c0264144dfe0bc81a4401801dcb964b8dd172ad" +dependencies = [ + "nb 0.1.3", + "void", +] + [[package]] name = "ff" version = "0.9.0" @@ -243,24 +277,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" -[[package]] -name = "generic-array" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" -dependencies = [ - "typenum", -] - -[[package]] -name = "generic-array" -version = "0.13.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f797e67af32588215eaaab8327027ee8e71b9dd0b2b26996aedf20c030fce309" -dependencies = [ - "typenum", -] - [[package]] name = "generic-array" version = "0.14.4" @@ -284,21 +300,20 @@ dependencies = [ [[package]] name = "hash32" -version = "0.1.1" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4041af86e63ac4298ce40e5cca669066e75b6f1aa3390fe2561ffa5e1d9f4cc" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" dependencies = [ "byteorder", ] [[package]] name = "heapless" -version = "0.6.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634bd4d29cbf24424d0a4bfcbf80c6960129dc24424752a7d1d1390607023422" +checksum = "e94c13b78b595d2adbd708bce276664f1047f98fc32ddbf463b4c191158334a6" dependencies = [ - "as-slice", - "generic-array 0.14.4", + "atomic-polyfill", "hash32", "stable_deref_trait", ] @@ -334,6 +349,21 @@ version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" +[[package]] +name = "nb" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f" +dependencies = [ + "nb 1.0.0", +] + +[[package]] +name = "nb" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "546c37ac5d9e56f55e73b677106873d9d9f5190605e41a856503623648488cae" + [[package]] name = "opaque-debug" version = "0.3.0" @@ -396,12 +426,36 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver", +] + [[package]] name = "ryu" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + [[package]] name = "serde" version = "1.0.125" @@ -519,16 +573,37 @@ checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" name = "universal-hash" version = "0.4.0" dependencies = [ - "generic-array 0.14.4", + "generic-array", "subtle", ] +[[package]] +name = "vcell" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002" + [[package]] name = "version_check" version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "volatile-register" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d67cb4616d99b940db1d6bd28844ff97108b498a6ca850e5b6191a532063286" +dependencies = [ + "vcell", +] + [[package]] name = "wyz" version = "0.2.0" diff --git a/aead/Cargo.toml b/aead/Cargo.toml index adb1edc55..f43e67c8b 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -18,7 +18,7 @@ categories = ["cryptography", "no-std"] generic-array = { version = "0.14", default-features = false } blobby = { version = "0.3", optional = true } -heapless = { version = "0.6.1", optional = true, default-features = false } +heapless = { version = "0.7", optional = true, default-features = false } rand_core = { version = "0.6", optional = true } [features] diff --git a/aead/src/lib.rs b/aead/src/lib.rs index b8e133935..af137a669 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -499,10 +499,7 @@ impl Buffer for Vec { } #[cfg(feature = "heapless")] -impl Buffer for heapless::Vec -where - N: heapless::ArrayLength, -{ +impl Buffer for heapless::Vec { fn extend_from_slice(&mut self, other: &[u8]) -> Result<(), Error> { heapless::Vec::extend_from_slice(self, other).map_err(|_| Error) } diff --git a/aead/src/stream.rs b/aead/src/stream.rs index 170904559..73c9c63c8 100644 --- a/aead/src/stream.rs +++ b/aead/src/stream.rs @@ -30,6 +30,8 @@ //! //! [1]: https://eprint.iacr.org/2015/189.pdf +#![allow(clippy::upper_case_acronyms)] + use crate::{AeadCore, AeadInPlace, Buffer, Error, Key, NewAead}; use core::ops::{AddAssign, Sub}; use generic_array::{ diff --git a/cipher/src/stream.rs b/cipher/src/stream.rs index 3bea72828..e33dd15a1 100644 --- a/cipher/src/stream.rs +++ b/cipher/src/stream.rs @@ -105,6 +105,7 @@ pub trait SeekNum: fn from_block_byte(block: T, byte: u8, bs: u8) -> Result; /// Try to get block number and bytes position for given block size `bs`. + #[allow(clippy::wrong_self_convention)] fn to_block_byte(self, bs: u8) -> Result<(T, u8), OverflowError>; } From 17583600b1da12f3328ee4118d1874e239b15cda Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 3 May 2021 07:23:16 -0700 Subject: [PATCH 0504/1461] aead v0.4.1 (#629) --- Cargo.lock | 2 +- aead/CHANGELOG.md | 8 +++++++- aead/Cargo.toml | 2 +- aead/src/lib.rs | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0e3c7b258..0b92e1c80 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,7 +2,7 @@ # It is not intended for manual editing. [[package]] name = "aead" -version = "0.4.0" +version = "0.4.1" dependencies = [ "blobby", "generic-array", diff --git a/aead/CHANGELOG.md b/aead/CHANGELOG.md index 0480de39f..90e7e925b 100644 --- a/aead/CHANGELOG.md +++ b/aead/CHANGELOG.md @@ -5,7 +5,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 0.4.0 +## 0.4.1 (2021-05-03) +### Changed +- Bump `heapless` dependency to v0.7 ([#628]) + +[#628]: https://github.com/RustCrypto/traits/pull/628 + +## 0.4.0 (2021-02-05) [YANKED] ### Added - `stream` module ([#436], [#445], [#447]) - `NewAead::generate_key` method gated under `rand_core` feature ([#513]) diff --git a/aead/Cargo.toml b/aead/Cargo.toml index f43e67c8b..a0eda058c 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aead" -version = "0.4.0" # Also update html_root_url in lib.rs when bumping this +version = "0.4.1" # Also update html_root_url in lib.rs when bumping this description = """ Traits for Authenticated Encryption with Associated Data (AEAD) algorithms, such as AES-GCM as ChaCha20Poly1305, which provide a high-level API diff --git a/aead/src/lib.rs b/aead/src/lib.rs index af137a669..9ddcec352 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -19,7 +19,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/aead/0.4.0" + html_root_url = "https://docs.rs/aead/0.4.1" )] #![warn(missing_docs, rust_2018_idioms)] From d54267c28b191264b29d25d54543021dd5db9a8b Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 3 May 2021 09:47:32 -0700 Subject: [PATCH 0505/1461] cipher + crypto-mac: CHANGELOG fixups (#630) - Document `generate_key` - Add `new_from_slice` docs to `crypto-mac` (closes #626) --- cipher/CHANGELOG.md | 2 ++ crypto-mac/CHANGELOG.md | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/cipher/CHANGELOG.md b/cipher/CHANGELOG.md index 426cc83c6..63af8392d 100644 --- a/cipher/CHANGELOG.md +++ b/cipher/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Encrypt/decrypt-only block cipher traits ([#352]) - Re-export `blobby` from root ([#435]) - Block cipher trait blanket impls for refs ([#441]) +- `generate_key` method to `New*` trait ([#513]) ### Changed - Consolidate error types ([#373]) @@ -22,6 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [#435]: https://github.com/RustCrypto/traits/pull/435 [#441]: https://github.com/RustCrypto/traits/pull/441 [#442]: https://github.com/RustCrypto/traits/pull/442 +[#513]: https://github.com/RustCrypto/traits/pull/513 ## 0.2.5 (2020-11-01) ### Fixed diff --git a/crypto-mac/CHANGELOG.md b/crypto-mac/CHANGELOG.md index d63daa7b7..874f5ae88 100644 --- a/crypto-mac/CHANGELOG.md +++ b/crypto-mac/CHANGELOG.md @@ -6,9 +6,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## 0.11.0 (2021-04-28) +### Added +- `generate_key` method to `New*` trait ([#513]) + ### Changed +- Renamed `new_var` to `new_from_slice` ([#442]) - Bump `cipher` dependency to v0.3 ([#621]) +[#442]: https://github.com/RustCrypto/traits/pull/442 +[#513]: https://github.com/RustCrypto/traits/pull/513 [#621]: https://github.com/RustCrypto/traits/pull/621 ## 0.10.0 (2020-10-15) From 72b37fecaeef78835b34a22bdf9c27cb7de920ab Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 5 May 2021 07:39:17 -0700 Subject: [PATCH 0506/1461] password-hash: use `subtle` crate for comparing hash `Output` (#631) Previously a non-short-circuiting comparison was used, however the `subtle` crate provides a more robust option in this regard with the `ConstantTimeEq` trait and its associated impls on byte slices. This commit also includes an updated rationale for why password hashes benefit from constant time comparisons, including a description of a timing attack on password hash verification. --- .github/workflows/password-hash.yml | 1 + Cargo.lock | 1 + password-hash/Cargo.toml | 4 ++ password-hash/src/output.rs | 98 +++++++++++++++++++---------- password-hash/src/salt.rs | 2 +- password-hash/src/value.rs | 2 +- 6 files changed, 72 insertions(+), 36 deletions(-) diff --git a/.github/workflows/password-hash.yml b/.github/workflows/password-hash.yml index 326cad572..b5c09addb 100644 --- a/.github/workflows/password-hash.yml +++ b/.github/workflows/password-hash.yml @@ -54,5 +54,6 @@ jobs: profile: minimal override: true - run: cargo check --all-features + - run: cargo test --release --no-default-features - run: cargo test --release - run: cargo test --release --all-features diff --git a/Cargo.lock b/Cargo.lock index 0b92e1c80..873fc4c3d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -376,6 +376,7 @@ version = "0.2.0" dependencies = [ "base64ct", "rand_core", + "subtle", ] [[package]] diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index b2f90f5f2..b14d767b4 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -17,9 +17,13 @@ keywords = ["crypt", "mcf", "password", "pbkdf", "phc"] [dependencies] base64ct = "1" +subtle = { version = "2", default-features = false } + +# optional features rand_core = { version = "0.6", optional = true, default-features = false } [features] +default = ["rand_core"] alloc = ["base64ct/alloc"] std = ["alloc", "base64ct/std"] diff --git a/password-hash/src/output.rs b/password-hash/src/output.rs index 8bc4c66c1..786e6ae62 100644 --- a/password-hash/src/output.rs +++ b/password-hash/src/output.rs @@ -2,6 +2,7 @@ use crate::{Encoding, Error, Result}; use core::{cmp::PartialEq, convert::TryFrom, fmt, str::FromStr}; +use subtle::{Choice, ConstantTimeEq}; /// Output from password hashing functions, i.e. the "hash" or "digest" /// as raw bytes. @@ -37,30 +38,62 @@ use core::{cmp::PartialEq, convert::TryFrom, fmt, str::FromStr}; /// as a reasonable maximum, and recommends using 32-bytes. /// /// # Constant-time comparisons -/// The [`PartialEq`] and [`Eq`] trait impls for [`Output`] provide a -/// non-short-circuiting equality comparison. +/// The [`Output`] type impls the [`ConstantTimeEq`] trait from the [`subtle`] +/// crate and uses it to perform constant-time comparisons. /// -/// There are few cases where this may actually helpful from a practical -/// perspective, namely cases where salts are predictable by an attacker. -/// Due to the limited degree in which such comparisons may be helpful, -/// this crate does not loop in additional dependencies for -/// constant-time comparisons (e.g. `subtle`). +/// Additionally the [`PartialEq`] and [`Eq`] trait impls for [`Output`] use +/// [`ConstantTimeEq`] when performing comparisons. /// -/// The extent to which constant-time comparisons of password hashes provides -/// meaningful protections in practical contexts is a -/// [topic of considerable debate][3]. -/// This library has elected to use a non-short-circuiting comparison as a -/// safer ("belt-and-suspenders") default, and also to -/// [head off any potential debates around the issue][4]. -/// Our main suggestion to avoid such attacks is to use a unique, randomly -/// generated salt per password which is unpredictable by the attacker. -/// The [`SaltString::generate`] function randomly generates high-entropy -/// salt values. +/// ## Attacks on non-constant-time password hash comparisons +/// Comparing password hashes in constant-time is known to mitigate at least +/// one [poorly understood attack][3] involving an adversary with the following +/// knowledge/capabilities: +/// +/// - full knowledge of what password hashing algorithm is being used +/// including any relevant configurable parameters +/// - knowledge of the salt for a particular victim +/// - ability to accurately measure a timing side-channel on comparisons +/// of the password hash over the network +/// +/// An attacker with the above is able to perform an offline computation of +/// the hash for any chosen password in such a way that it will match the +/// hash computed by the server. +/// +/// As noted above, they also measure timing variability in the server's +/// comparison of the hash it computes for a given password and a target hash +/// the attacker is trying to learn. +/// +/// When the attacker observes a hash comparison that takes longer than their +/// previous attempts, they learn that they guessed another byte in the +/// password hash correctly. They can leverage repeated measurements and +/// observations with different candidate passwords to learn the password +/// hash a byte-at-a-time in a manner similar to other such timing side-channel +/// attacks. +/// +/// The attack may seem somewhat counterintuitive since learning prefixes of a +/// password hash does not reveal any additional information about the password +/// itself. However, the above can be combined with an offline dictionary +/// attack where the attacker is able to determine candidate passwords to send +/// to the server by performing a brute force search offline and selecting +/// candidate passwords whose hashes match the portion of the prefix they have +/// learned so far. +/// +/// As the attacker learns a longer and longer prefix of the password hash, +/// they are able to more effectively eliminate candidate passwords offline as +/// part of a dictionary attack, until they eventually guess the correct +/// password or exhaust their set of candidate passwords. +/// +/// ## Mitigations +/// While we have taken care to ensure password hashes are compared in constant +/// time, we would also suggest preventing such attacks by using randomly +/// generated salts and keeping those salts secret. +/// +/// The [`SaltString::generate`][`crate::SaltString::generate`] function can be +/// used to generate random high-entropy salt values. /// /// [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#function-duties /// [2]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#argon2-encoding -/// [3]: https://github.com/codahale/bcrypt-ruby/issues/42 -/// [4]: https://twitter.com/coda/status/866310352606068736 +/// [3]: https://web.archive.org/web/20130208100210/http://security-assessment.com/files/documents/presentations/TimingAttackPresentation2012.pdf #[derive(Copy, Clone, Eq)] pub struct Output { /// Byte array containing a password hashing function output. @@ -88,7 +121,7 @@ impl Output { pub const B64_MAX_LENGTH: usize = ((Self::MAX_LENGTH * 4) / 3) + 1; /// Create a [`Output`] from the given byte slice, validating it according - /// to [`Output::min_len`] and [`Output::max_len`] length restrictions. + /// to [`Output::MIN_LENGTH`] and [`Output::MAX_LENGTH`] restrictions. pub fn new(input: &[u8]) -> Result { Self::init_with(input.len(), |bytes| { bytes.copy_from_slice(input); @@ -97,8 +130,8 @@ impl Output { } /// Create a [`Output`] from the given byte slice and [`Encoding`], - /// validating it according to [`Output::min_len`] and [`Output::max_len`] - /// length restrictions. + /// validating it according to [`Output::MIN_LENGTH`] and + /// [`Output::MAX_LENGTH`] restrictions. pub fn new_with_encoding(input: &[u8], encoding: Encoding) -> Result { let mut result = Self::new(input)?; result.encoding = encoding; @@ -109,7 +142,8 @@ impl Output { /// a mutable byte slice into which it should write the output. /// /// The `output_size` (in bytes) must be known in advance, as well as at - /// least [`Output::min_len`] bytes and at most [`Output::max_len`] bytes. + /// least [`Output::MIN_LENGTH`] bytes and at most [`Output::MAX_LENGTH`] + /// bytes. pub fn init_with(output_size: usize, f: F) -> Result where F: FnOnce(&mut [u8]) -> Result<()>, @@ -187,6 +221,12 @@ impl AsRef<[u8]> for Output { } } +impl ConstantTimeEq for Output { + fn ct_eq(&self, other: &Self) -> Choice { + self.as_ref().ct_eq(other.as_ref()) + } +} + impl FromStr for Output { type Err = Error; @@ -197,17 +237,7 @@ impl FromStr for Output { impl PartialEq for Output { fn eq(&self, other: &Self) -> bool { - if self.len() != other.len() { - return false; - } - - // Non-short-circuiting comparison. - // See "Constant-time comparisons" documentation above. - self.as_ref() - .iter() - .zip(other.as_ref().iter()) - .fold(0, |acc, (a, b)| acc | (a ^ b)) - == 0 + self.ct_eq(other).into() } } diff --git a/password-hash/src/salt.rs b/password-hash/src/salt.rs index 486b3b8e0..d73001980 100644 --- a/password-hash/src/salt.rs +++ b/password-hash/src/salt.rs @@ -94,7 +94,7 @@ impl<'a> Salt<'a> { pub const RECOMMENDED_LENGTH: usize = 16; /// Create a [`Salt`] from the given `str`, validating it according to - /// [`Salt::min_len`] and [`Salt::max_len`] length restrictions. + /// [`Salt::MIN_LENGTH`] and [`Salt::MAX_LENGTH`] length restrictions. pub fn new(input: &'a str) -> Result { if input.len() < Self::MIN_LENGTH { return Err(Error::SaltTooShort); diff --git a/password-hash/src/value.rs b/password-hash/src/value.rs index 854ee0d9c..456aa3295 100644 --- a/password-hash/src/value.rs +++ b/password-hash/src/value.rs @@ -32,7 +32,7 @@ pub type Decimal = u32; /// # Additional Notes /// The PHC spec allows for algorithm-defined maximum lengths for parameter /// values, however in the interest of interoperability this library defines a -/// [`Value::max_len`] of 48 ASCII characters. +/// [`Value::MAX_LENGTH`] of 48 ASCII characters. /// /// [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md /// [2]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#argon2-encoding From 3058a55a19449eb408bffca0763c550f2a7b71b4 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 5 May 2021 07:57:34 -0700 Subject: [PATCH 0507/1461] password-hash v0.2.1 (#632) --- Cargo.lock | 2 +- password-hash/CHANGELOG.md | 6 ++++++ password-hash/Cargo.toml | 2 +- password-hash/src/lib.rs | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 873fc4c3d..c75efe434 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -372,7 +372,7 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "password-hash" -version = "0.2.0" +version = "0.2.1" dependencies = [ "base64ct", "rand_core", diff --git a/password-hash/CHANGELOG.md b/password-hash/CHANGELOG.md index 18e98c5c0..edf13dc96 100644 --- a/password-hash/CHANGELOG.md +++ b/password-hash/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.2.1 (2021-05-05) +### Changed +- Use `subtle` crate for comparing hash `Output` ([#631]) + +[#631]: https://github.com/RustCrypto/traits/pull/631 + ## 0.2.0 (2021-04-29) ### Changed - Allow specifying output length and version with params ([#615]) diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index b14d767b4..ac64a9e70 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -5,7 +5,7 @@ Traits which describe the functionality of password hashing algorithms, as well as a `no_std`-friendly implementation of the PHC string format (a well-defined subset of the Modular Crypt Format a.k.a. MCF) """ -version = "0.2.0" # Also update html_root_url in lib.rs when bumping this +version = "0.2.1" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index 7acbbaccf..1083415b4 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -39,7 +39,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/password-hash/0.2.0" + html_root_url = "https://docs.rs/password-hash/0.2.1" )] #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] From 6fb4cd354ffd3af8b4ea64a3f0fbb3e48d3ce6f6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 May 2021 22:25:36 -0700 Subject: [PATCH 0508/1461] build(deps): bump sha2 from 0.9.3 to 0.9.4 (#633) Bumps [sha2](https://github.com/RustCrypto/hashes) from 0.9.3 to 0.9.4. - [Release notes](https://github.com/RustCrypto/hashes/releases) - [Commits](https://github.com/RustCrypto/hashes/compare/sha2-v0.9.3...sha2-v0.9.4) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c75efe434..df4ff13de 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -156,10 +156,10 @@ dependencies = [ ] [[package]] -name = "cpuid-bool" -version = "0.1.2" +name = "cpufeatures" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634" +checksum = "5cd5a7748210e7ec1a9696610b1015e6e31fbf58f77a160801f124bd1c36592a" [[package]] name = "crypto" @@ -476,13 +476,13 @@ dependencies = [ [[package]] name = "sha2" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa827a14b29ab7f44778d14a88d3cb76e949c45083f7dbfa507d0cb699dc12de" +checksum = "d8f6b75b17576b792bef0db1bcc4b8b8bcdf9506744cf34b974195487af6cff2" dependencies = [ "block-buffer 0.9.0", "cfg-if", - "cpuid-bool", + "cpufeatures", "digest 0.9.0", "opaque-debug", ] From ba5b6d4d1083d4f4b7e764a7af386b1e9749e2b2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 May 2021 22:30:46 -0700 Subject: [PATCH 0509/1461] build(deps): bump sha2 from 0.9.4 to 0.9.5 (#634) Bumps [sha2](https://github.com/RustCrypto/hashes) from 0.9.4 to 0.9.5. - [Release notes](https://github.com/RustCrypto/hashes/releases) - [Commits](https://github.com/RustCrypto/hashes/compare/sha2-v0.9.4...sha2-v0.9.5) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index df4ff13de..329b13870 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -157,9 +157,12 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cd5a7748210e7ec1a9696610b1015e6e31fbf58f77a160801f124bd1c36592a" +checksum = "dec1028182c380cc45a2e2c5ec841134f2dfd0f8f5f0a5bcd68004f81b5efdf4" +dependencies = [ + "libc", +] [[package]] name = "crypto" @@ -349,6 +352,12 @@ version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" +[[package]] +name = "libc" +version = "0.2.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18794a8ad5b29321f790b55d93dfba91e125cb1a9edbd4f8e3150acc771c1a5e" + [[package]] name = "nb" version = "0.1.3" @@ -476,9 +485,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8f6b75b17576b792bef0db1bcc4b8b8bcdf9506744cf34b974195487af6cff2" +checksum = "b362ae5752fd2137731f9fa25fd4d9058af34666ca1966fb969119cc35719f12" dependencies = [ "block-buffer 0.9.0", "cfg-if", From ff738a6d6baa482ca0bbe2fd2e2a246e35314faa Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 17 May 2021 07:55:45 -0700 Subject: [PATCH 0510/1461] crypto: fix `password_hash` module name in rustdoc (#636) It previously had a hyphen (i.e. crate name, not module name) --- crypto/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto/src/lib.rs b/crypto/src/lib.rs index 62143d08b..8eaa150be 100644 --- a/crypto/src/lib.rs +++ b/crypto/src/lib.rs @@ -28,7 +28,7 @@ //! | [`digest`](https://docs.rs/digest) | `digest` | Cryptographic hash functions | //! | [`elliptic_curve`](https://docs.rs/elliptic-curve) | `elliptic-curve` | Elliptic curve cryptography | //! | [`mac`](https://docs.rs/crypto-mac) | `mac` | Message Authentication Codes (i.e. symmetric message authentication) | -//! | [`password-hash`](https://docs.rs/password-hash) | `password-hash` | Password hashing functions | +//! | [`password_hash`](https://docs.rs/password-hash) | `password-hash` | Password hashing functions | //! | [`signature`](https://docs.rs/signature) | `signature` | Digital signatures (i.e. public key-based message authentication) | //! | [`universal_hash`](https://docs.rs/universal-hash) | `universal‑hash` | Universal Hash Functions (used to build MACs) | //! From 1df3500020c1a45eb70bfd548ce6d346c55580b6 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 18 May 2021 16:19:11 -0700 Subject: [PATCH 0511/1461] elliptic-curve: add Ord and PartialOrd impls on PublicKey (#637) --- elliptic-curve/src/public_key.rs | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index aa4cee273..b90a7c6b8 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -10,6 +10,7 @@ use crate::{ Scalar, }; use core::{ + cmp::Ordering, convert::{TryFrom, TryInto}, fmt::Debug, ops::Add, @@ -310,9 +311,38 @@ where UncompressedPointSize: ArrayLength, { fn eq(&self, other: &Self) -> bool { + self.cmp(other) == Ordering::Equal + } +} + +impl PartialOrd for PublicKey +where + C: Curve + ProjectiveArithmetic, + Scalar: PrimeField>, + AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, + ProjectivePoint: From>, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for PublicKey +where + C: Curve + ProjectiveArithmetic, + Scalar: PrimeField>, + AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, + ProjectivePoint: From>, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + fn cmp(&self, other: &Self) -> Ordering { // TODO(tarcieri): more efficient implementation? // This is implemented this way to reduce bounds for `AffinePoint` - self.to_encoded_point(false) == other.to_encoded_point(false) + self.to_encoded_point(false) + .cmp(&other.to_encoded_point(false)) } } From 694610a55fac9b9d0f23cecae03dfed0d1831a8d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 18 May 2021 17:15:33 -0700 Subject: [PATCH 0512/1461] elliptic-curve v0.9.12 (#638) --- Cargo.lock | 2 +- elliptic-curve/CHANGELOG.md | 6 ++++++ elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 329b13870..cedba19a5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -237,7 +237,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.9.11" +version = "0.9.12" dependencies = [ "base64ct", "bitvec", diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index 67a5dc462..cbcc46332 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.9.12 (2021-05-18) +### Added +- `Ord` and `PartialOrd` impls on `PublicKey` ([#637]) + +[#637]: https://github.com/RustCrypto/traits/pull/637 + ## 0.9.11 (2021-04-21) ### Added - Impl `subtle` traits on `ScalarBytes` ([#612]) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 3fe0aab1d..e70b2d76a 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -5,7 +5,7 @@ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. """ -version = "0.9.11" # Also update html_root_url in lib.rs when bumping this +version = "0.9.12" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" repository = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve" diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 8c5ae6616..0acf2715f 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -16,7 +16,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.9.11" + html_root_url = "https://docs.rs/elliptic-curve/0.9.12" )] #[cfg(feature = "alloc")] From 5f0d5f633d27e2d2ee1b122e9d24badbd31041f0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 May 2021 16:35:43 -0700 Subject: [PATCH 0513/1461] build(deps): bump heapless from 0.7.0 to 0.7.1 (#639) Bumps [heapless](https://github.com/japaric/heapless) from 0.7.0 to 0.7.1. - [Release notes](https://github.com/japaric/heapless/releases) - [Changelog](https://github.com/japaric/heapless/blob/master/CHANGELOG.md) - [Commits](https://github.com/japaric/heapless/compare/v0.7.0...v0.7.1) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cedba19a5..f0e46e868 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -312,9 +312,9 @@ dependencies = [ [[package]] name = "heapless" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94c13b78b595d2adbd708bce276664f1047f98fc32ddbf463b4c191158334a6" +checksum = "c7ee8a997d259962217f40279f34201fdf06e669bafa69d7c1f4c7ff1893b5f6" dependencies = [ "atomic-polyfill", "hash32", From 1e9597280a499a27d839488beba3ccecfabf3aaa Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 24 May 2021 17:33:24 -0700 Subject: [PATCH 0514/1461] Cargo.lock: bump dependencies (#640) --- Cargo.lock | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f0e46e868..9bcc1bb1b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -157,9 +157,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.1.1" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec1028182c380cc45a2e2c5ec841134f2dfd0f8f5f0a5bcd68004f81b5efdf4" +checksum = "ed00c67cb5d0a7d64a44f6ad2668db7e7530311dd53ea79bcd4fb022c64911c8" dependencies = [ "libc", ] @@ -210,9 +210,9 @@ dependencies = [ [[package]] name = "der" -version = "0.3.3" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83dc83d0b59f92103d8e661e60526338ad3aeb0c15fa4a29a14b6a9b1ac8a43c" +checksum = "2eeb9d92785d1facb50567852ce75d0858630630e7eabea59cf7eb7474051087" dependencies = [ "const-oid", ] @@ -390,9 +390,9 @@ dependencies = [ [[package]] name = "pkcs8" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b813f58dc6e5d1820868a3c3df3a7ae7852aa2d3d18e98f0d6b20ddd01fe25d7" +checksum = "c9c2f795bc591cb3384cb64082a578b89207ac92bb89c9d98c1ea2ace7cd8110" dependencies = [ "base64ct", "der", @@ -408,9 +408,9 @@ checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" [[package]] name = "proc-macro2" -version = "1.0.26" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec" +checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038" dependencies = [ "unicode-xid", ] @@ -468,9 +468,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.125" +version = "1.0.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171" +checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03" [[package]] name = "serde_json" @@ -540,9 +540,9 @@ checksum = "1e81da0851ada1f3e9d4312c704aa4f8806f0f9d69faaf8df2f3464b4a9437c2" [[package]] name = "syn" -version = "1.0.71" +version = "1.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad184cc9470f9117b2ac6817bfe297307418819ba40552f9b3846f05c33d5373" +checksum = "a1e8cdbefb79a9a5a65e0db8b47b723ee907b7c7f8496c76a1770b5c310bab82" dependencies = [ "proc-macro2", "quote", @@ -575,9 +575,9 @@ checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" [[package]] name = "unicode-xid" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" [[package]] name = "universal-hash" From 45fcb3db884b5baa01cb35fe13fbe999cbefdf14 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 1 Jun 2021 17:49:07 -0700 Subject: [PATCH 0515/1461] elliptic-curve: bump `ff` and `group` to v0.10; MSRV 1.51+ (#643) Bumps the `ff` and `group` crate dependencies to the latest releases. Changelogs: - `ff`: https://github.com/zkcrypto/ff/blob/main/CHANGELOG.md#0100---2021-06-01 - `group`: https://github.com/zkcrypto/group/blob/main/CHANGELOG.md#0100---2021-06-01 Additionally, this commit removes the re-export of the `ff` crate, with the expectation it be accessed as `group::ff`. --- .github/workflows/elliptic-curve.yml | 5 +-- Cargo.lock | 26 +++++++++------- crypto/Cargo.toml | 2 +- elliptic-curve/Cargo.toml | 10 +++--- elliptic-curve/README.md | 4 +-- elliptic-curve/src/dev.rs | 43 ++++++++++++++------------ elliptic-curve/src/jwk.rs | 2 +- elliptic-curve/src/lib.rs | 9 ++++-- elliptic-curve/src/scalar.rs | 12 +++---- elliptic-curve/src/scalar/bytes.rs | 2 +- elliptic-curve/src/sec1.rs | 2 +- elliptic-curve/src/secret_key.rs | 2 +- elliptic-curve/src/secret_key/pkcs8.rs | 2 +- 13 files changed, 64 insertions(+), 57 deletions(-) diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index e4486a08b..e8d4d2944 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.47.0 # MSRV + - 1.51.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -37,6 +37,7 @@ jobs: override: true - run: cargo build --no-default-features --release --target ${{ matrix.target }} - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features arithmetic + - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features bits - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features dev - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features ecdh - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features hazmat @@ -50,7 +51,7 @@ jobs: strategy: matrix: rust: - - 1.47.0 # MSRV + - 1.51.0 # MSRV - stable - nightly steps: diff --git a/Cargo.lock b/Cargo.lock index 9bcc1bb1b..b2109b7c1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -61,9 +61,9 @@ checksum = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719" [[package]] name = "bitvec" -version = "0.20.4" +version = "0.22.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7774144344a4faa177370406a7ff5f1da24303817368584c6206c8303eb07848" +checksum = "5237f00a8c86130a0cc317830e558b966dd7850d48a953d998c813f01a41b527" dependencies = [ "funty", "radium", @@ -237,10 +237,9 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.9.12" +version = "0.10.0-pre" dependencies = [ "base64ct", - "bitvec", "ff", "generic-array", "group", @@ -265,9 +264,9 @@ dependencies = [ [[package]] name = "ff" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72a4d941a5b7c2a75222e2d44fcdf634a67133d9db31e177ae5ff6ecda852bfe" +checksum = "63eec06c61e487eecf0f7e6e6372e596a81922c28d33e645d6983ca6493a1af0" dependencies = [ "bitvec", "rand_core", @@ -276,9 +275,9 @@ dependencies = [ [[package]] name = "funty" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" +checksum = "1847abb9cb65d566acd5942e94aea9c8f547ad02c98e1649326fc0e8910b8b1e" [[package]] name = "generic-array" @@ -292,9 +291,9 @@ dependencies = [ [[package]] name = "group" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61b3c1e8b4f1ca07e6605ea1be903a5f6956aec5c8a67fd44d56076631675ed8" +checksum = "1c363a5301b8f153d80747126a04b3c82073b9fe3130571a9d170cacdeaf7912" dependencies = [ "ff", "rand_core", @@ -616,9 +615,12 @@ dependencies = [ [[package]] name = "wyz" -version = "0.2.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" +checksum = "129e027ad65ce1453680623c3fb5163cbf7107bfe1aa32257e7d0e63f9ced188" +dependencies = [ + "tap", +] [[package]] name = "zeroize" diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index a17fb663b..87a00c180 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -17,7 +17,7 @@ edition = "2018" aead = { version = "0.4", optional = true, path = "../aead" } cipher = { version = "0.3", optional = true } digest = { version = "0.9", optional = true } -elliptic-curve = { version = "0.9", optional = true, path = "../elliptic-curve" } +elliptic-curve = { version = "=0.10.0-pre", optional = true, path = "../elliptic-curve" } mac = { version = "0.11", package = "crypto-mac", optional = true } password-hash = { version = "0.2", optional = true, path = "../password-hash" } signature = { version = "1.2.0", optional = true, default-features = false, path = "../signature" } diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index e70b2d76a..dc0efbb6c 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -5,7 +5,7 @@ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. """ -version = "0.9.12" # Also update html_root_url in lib.rs when bumping this +version = "0.10.0-pre" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" repository = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve" @@ -16,9 +16,8 @@ keywords = ["crypto", "ecc", "elliptic", "weierstrass"] [dependencies] base64ct = { version = "1", optional = true, default-features = false } -bitvec = { version = "0.20.2", optional = true, default-features = false } -ff = { version = "0.9", optional = true, default-features = false } -group = { version = "0.9", optional = true, default-features = false } +ff = { version = "0.10", optional = true, default-features = false } +group = { version = "0.10", optional = true, default-features = false } hex-literal = { version = "0.3", optional = true } generic-array = { version = "0.14", default-features = false } pkcs8 = { version = "0.6", optional = true } @@ -34,7 +33,8 @@ hex-literal = "0.3" [features] default = ["arithmetic"] alloc = [] -arithmetic = ["bitvec", "ff", "group"] +arithmetic = ["ff", "group"] +bits = ["arithmetic", "ff/bits"] dev = ["arithmetic", "hex-literal", "pem", "zeroize"] ecdh = ["arithmetic", "zeroize"] hazmat = [] diff --git a/elliptic-curve/README.md b/elliptic-curve/README.md index 59138d4f9..e8fe6d340 100644 --- a/elliptic-curve/README.md +++ b/elliptic-curve/README.md @@ -15,7 +15,7 @@ and public/secret keys composed thereof. ## Minimum Supported Rust Version -Requires Rust **1.47** or higher. +Requires Rust **1.51** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -47,7 +47,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/elliptic-curve/badge.svg [docs-link]: https://docs.rs/elliptic-curve/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.47+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.51+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260040-elliptic-curves [build-image]: https://github.com/RustCrypto/elliptic-curves/workflows/elliptic-curve%20crate/badge.svg?branch=master&event=push diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index e8f6ac740..50482c7e0 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -4,23 +4,25 @@ use crate::{ consts::U32, error::{Error, Result}, - ff::{Field, PrimeField}, - group, rand_core::RngCore, sec1::{FromEncodedPoint, ToEncodedPoint}, subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}, util::sbb64, weierstrass, zeroize::Zeroize, - AlgorithmParameters, Curve, Order, ProjectiveArithmetic, ScalarBits, + AlgorithmParameters, Curve, Order, ProjectiveArithmetic, }; use core::{ convert::{TryFrom, TryInto}, iter::Sum, ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign}, }; +use ff::{Field, PrimeField}; use hex_literal::hex; +#[cfg(feature = "bits")] +use crate::{group::ff::PrimeFieldBits, ScalarBits}; + #[cfg(feature = "jwk")] use crate::JwkParameters; @@ -152,12 +154,12 @@ impl Field for Scalar { } } -#[cfg(target_pointer_width = "64")] +#[cfg(all(feature = "bits", target_pointer_width = "64"))] fn pack_bits(native: U256) -> ScalarBits { native.into() } -#[cfg(target_pointer_width = "32")] +#[cfg(all(feature = "bits", target_pointer_width = "32"))] fn pack_bits(native: U256) -> ScalarBits { [ (native[0] & 0xffff_ffff) as u32, @@ -175,12 +177,6 @@ fn pack_bits(native: U256) -> ScalarBits { impl PrimeField for Scalar { type Repr = FieldBytes; - #[cfg(target_pointer_width = "32")] - type ReprBits = [u32; 8]; - - #[cfg(target_pointer_width = "64")] - type ReprBits = [u64; 4]; - const NUM_BITS: u32 = 256; const CAPACITY: u32 = 255; const S: u32 = 4; @@ -217,18 +213,10 @@ impl PrimeField for Scalar { ret } - fn to_le_bits(&self) -> ScalarBits { - pack_bits(self.0) - } - fn is_odd(&self) -> bool { unimplemented!(); } - fn char_le_bits() -> ScalarBits { - pack_bits(MODULUS) - } - fn multiplicative_generator() -> Self { unimplemented!(); } @@ -238,6 +226,23 @@ impl PrimeField for Scalar { } } +#[cfg(feature = "bits")] +impl PrimeFieldBits for Scalar { + #[cfg(target_pointer_width = "32")] + type ReprBits = [u32; 8]; + + #[cfg(target_pointer_width = "64")] + type ReprBits = [u64; 4]; + + fn to_le_bits(&self) -> ScalarBits { + pack_bits(self.0) + } + + fn char_le_bits() -> ScalarBits { + pack_bits(MODULUS) + } +} + impl TryFrom<[u64; 4]> for Scalar { type Error = Error; diff --git a/elliptic-curve/src/jwk.rs b/elliptic-curve/src/jwk.rs index d84667c16..55ea1e8f2 100644 --- a/elliptic-curve/src/jwk.rs +++ b/elliptic-curve/src/jwk.rs @@ -30,7 +30,7 @@ use zeroize::Zeroize; #[cfg(feature = "arithmetic")] use crate::{ - ff::PrimeField, + group::ff::PrimeField, public_key::PublicKey, sec1::{FromEncodedPoint, ToEncodedPoint}, AffinePoint, ProjectiveArithmetic, ProjectivePoint, Scalar, diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 0acf2715f..0d8420f5e 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -4,7 +4,7 @@ //! //! ## Minimum Supported Rust Version //! -//! Rust **1.47** or higher. +//! Rust **1.51** or higher. //! //! Minimum supported Rust version can be changed in the future, but it will be //! done with a minor version bump. @@ -68,12 +68,15 @@ pub use { crate::{ point::{AffinePoint, ProjectiveArithmetic, ProjectivePoint}, public_key::PublicKey, - scalar::{non_zero::NonZeroScalar, Scalar, ScalarBits}, + scalar::{non_zero::NonZeroScalar, Scalar}, }, - ff::{self, Field}, + ff::Field, group::{self, Group}, }; +#[cfg(feature = "bits")] +pub use crate::scalar::ScalarBits; + #[cfg(all(feature = "hazmat", feature = "zeroize"))] pub use secret_key::{SecretBytes, SecretValue}; diff --git a/elliptic-curve/src/scalar.rs b/elliptic-curve/src/scalar.rs index 40c585707..4d7a788d3 100644 --- a/elliptic-curve/src/scalar.rs +++ b/elliptic-curve/src/scalar.rs @@ -6,11 +6,7 @@ pub(crate) mod bytes; pub(crate) mod non_zero; #[cfg(feature = "arithmetic")] -use { - crate::ProjectiveArithmetic, - ff::{FieldBits, PrimeField}, - group::Group, -}; +use {crate::ProjectiveArithmetic, group::Group}; /// Scalar field element for a particular elliptic curve. #[cfg(feature = "arithmetic")] @@ -18,6 +14,6 @@ use { pub type Scalar = <::ProjectivePoint as Group>::Scalar; /// Bit representation of a scalar field element of a given curve. -#[cfg(feature = "arithmetic")] -#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] -pub type ScalarBits = FieldBits< as PrimeField>::ReprBits>; +#[cfg(feature = "bits")] +#[cfg_attr(docsrs, doc(cfg(feature = "bits")))] +pub type ScalarBits = ff::FieldBits< as ff::PrimeFieldBits>::ReprBits>; diff --git a/elliptic-curve/src/scalar/bytes.rs b/elliptic-curve/src/scalar/bytes.rs index 60f182c00..68a95fc51 100644 --- a/elliptic-curve/src/scalar/bytes.rs +++ b/elliptic-curve/src/scalar/bytes.rs @@ -9,7 +9,7 @@ use generic_array::{typenum::Unsigned, GenericArray}; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; #[cfg(feature = "arithmetic")] -use crate::{ff::PrimeField, ProjectiveArithmetic, Scalar}; +use crate::{group::ff::PrimeField, ProjectiveArithmetic, Scalar}; // TODO(tarcieri): unify these into a target-width gated `sbb` #[cfg(target_pointer_width = "32")] diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index 4f255818a..1dc4326b8 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -21,7 +21,7 @@ use alloc::boxed::Box; #[cfg(feature = "arithmetic")] use crate::{ - ff::PrimeField, weierstrass::DecompressPoint, AffinePoint, ProjectiveArithmetic, Scalar, + group::ff::PrimeField, weierstrass::DecompressPoint, AffinePoint, ProjectiveArithmetic, Scalar, }; #[cfg(all(feature = "arithmetic", feature = "zeroize"))] diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index cdf8ec335..604fda9de 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -21,7 +21,7 @@ use zeroize::Zeroize; #[cfg(feature = "arithmetic")] use crate::{ - ff::PrimeField, + group::ff::PrimeField, rand_core::{CryptoRng, RngCore}, weierstrass, AffinePoint, NonZeroScalar, ProjectiveArithmetic, ProjectivePoint, PublicKey, Scalar, diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs index 23f0a5ed6..d64715a52 100644 --- a/elliptic-curve/src/secret_key/pkcs8.rs +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -15,13 +15,13 @@ use zeroize::Zeroize; #[cfg(all(feature = "arithmetic", feature = "pem"))] use { crate::{ - ff::PrimeField, scalar::Scalar, sec1::{FromEncodedPoint, ToEncodedPoint}, AffinePoint, ProjectiveArithmetic, ProjectivePoint, }, alloc::vec::Vec, core::{convert::TryInto, fmt::Debug, iter}, + ff::PrimeField, pkcs8::{der::Encodable, ToPrivateKey}, zeroize::Zeroizing, }; From 9091f6e8fbc2ac1d061db0cfbd8627e5ef03792d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 1 Jun 2021 22:12:36 -0700 Subject: [PATCH 0516/1461] elliptic-curve: merge `Curve` and `Order` traits (#644) The `Order` trait was additively retrofitted in a non-breaking way. However all of the https://github.com/rustcrypto/elliptic-curves crates now impl it, and thus it's ready to merge into the `Curve` trait proper as a mandatory-to-impl feature. The current form is also a stopgap: now that the `crypto-bigint` crate has an initial release, it can be used as the type to store the `Curve::ORDER` in a const-friendly way, and also it can leverage the `crypto-bigint` crate's `generic-array` interop to replace the `FieldSize` constant as well. This is the first step towards those refactorings. --- elliptic-curve/src/dev.rs | 15 ++++++--------- elliptic-curve/src/lib.rs | 18 +++++++++++++++-- elliptic-curve/src/order.rs | 31 ------------------------------ elliptic-curve/src/scalar/bytes.rs | 30 ++++++++++++++--------------- elliptic-curve/src/sec1.rs | 17 ++++------------ 5 files changed, 41 insertions(+), 70 deletions(-) delete mode 100644 elliptic-curve/src/order.rs diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 50482c7e0..959d3b044 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -10,7 +10,7 @@ use crate::{ util::sbb64, weierstrass, zeroize::Zeroize, - AlgorithmParameters, Curve, Order, ProjectiveArithmetic, + AlgorithmParameters, Curve, ProjectiveArithmetic, }; use core::{ convert::{TryFrom, TryInto}, @@ -40,12 +40,13 @@ pub struct MockCurve; impl Curve for MockCurve { type FieldSize = U32; -} -#[cfg(target_pointer_width = "32")] -impl Order for MockCurve { + #[cfg(target_pointer_width = "32")] type Limbs = [u32; 8]; + #[cfg(target_pointer_width = "64")] + type Limbs = [u64; 4]; + #[cfg(target_pointer_width = "32")] const ORDER: Self::Limbs = [ 0xfc63_2551, 0xf3b9_cac2, @@ -56,12 +57,8 @@ impl Order for MockCurve { 0x0000_0000, 0xffff_ffff, ]; -} - -#[cfg(target_pointer_width = "64")] -impl Order for MockCurve { - type Limbs = [u64; 4]; + #[cfg(target_pointer_width = "64")] const ORDER: Self::Limbs = [ 0xf3b9_cac2_fc63_2551, 0xbce6_faad_a717_9e84, diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 0d8420f5e..866048602 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -31,7 +31,6 @@ pub mod util; pub mod weierstrass; mod error; -mod order; mod scalar; #[cfg(feature = "arithmetic")] @@ -55,7 +54,6 @@ mod secret_key; pub use self::{ error::{Error, Result}, - order::Order, scalar::bytes::ScalarBytes, }; @@ -112,6 +110,22 @@ pub const ALGORITHM_OID: pkcs8::ObjectIdentifier = /// be impl'd by these ZSTs, facilitating types which are generic over elliptic /// curves (e.g. [`SecretKey`]). pub trait Curve: Clone + Debug + Default + Eq + Ord + Send + Sync { + /// Type representing the "limbs" of the curves group's order on + /// 32-bit platforms. + #[cfg(target_pointer_width = "32")] + type Limbs: AsRef<[u32]> + Copy + Debug; + + /// Type representing the "limbs" of the curves group's order on + /// 64-bit platforms. + #[cfg(target_pointer_width = "64")] + type Limbs: AsRef<[u64]> + Copy + Debug; + + /// Order constant. + /// + /// Subdivided into either 32-bit or 64-bit "limbs" (depending on the + /// target CPU's word size), specified from least to most significant. + const ORDER: Self::Limbs; + /// Size of this curve's field in *bytes*, i.e. the number of bytes needed /// to serialize a field element. /// diff --git a/elliptic-curve/src/order.rs b/elliptic-curve/src/order.rs deleted file mode 100644 index 9252702cf..000000000 --- a/elliptic-curve/src/order.rs +++ /dev/null @@ -1,31 +0,0 @@ -//! Low-level elliptic curve parameters. - -use crate::Curve; -use core::fmt::Debug; - -/// Order of an elliptic curve group. -/// -/// This trait is available even when the `arithmetic` feature of the crate -/// is disabled and does not require any additional crate dependencies. -/// -/// This trait is useful for supporting a baseline level of functionality -/// across curve implementations, even ones which do not provide a field -/// arithmetic backend. -// TODO(tarcieri): merge this with the `Curve` type in the next release? -pub trait Order: Curve { - /// Type representing the "limbs" of the curves group's order on - /// 32-bit platforms. - #[cfg(target_pointer_width = "32")] - type Limbs: AsRef<[u32]> + Copy + Debug; - - /// Type representing the "limbs" of the curves group's order on - /// 64-bit platforms. - #[cfg(target_pointer_width = "64")] - type Limbs: AsRef<[u64]> + Copy + Debug; - - /// Order constant. - /// - /// Subdivided into either 32-bit or 64-bit "limbs" (depending on the - /// target CPU's word size), specified from least to most significant. - const ORDER: Self::Limbs; -} diff --git a/elliptic-curve/src/scalar/bytes.rs b/elliptic-curve/src/scalar/bytes.rs index 68a95fc51..1c2ff6dbd 100644 --- a/elliptic-curve/src/scalar/bytes.rs +++ b/elliptic-curve/src/scalar/bytes.rs @@ -1,6 +1,6 @@ //! Scalar bytes. -use crate::{Curve, Error, FieldBytes, Order, Result}; +use crate::{Curve, Error, FieldBytes, Result}; use core::{ convert::{TryFrom, TryInto}, mem, @@ -18,21 +18,21 @@ use crate::util::sbb32; use crate::util::sbb64; /// Scalar bytes: wrapper for [`FieldBytes`] which guarantees that the the -/// inner byte value is within range of the curve's [`Order`]. +/// inner byte value is within range of the [`Curve::ORDER`]. /// /// Does not require an arithmetic implementation. #[derive(Clone, Debug, Eq)] -pub struct ScalarBytes { +pub struct ScalarBytes { /// Inner byte value; guaranteed to be in range of the curve's order. inner: FieldBytes, } impl ScalarBytes where - C: Curve + Order, + C: Curve, { /// Create new [`ScalarBytes`], checking that the given input is within - /// range of the curve's [`Order`]. + /// range of the [`Curve::ORDER`]. #[cfg(target_pointer_width = "32")] pub fn new(bytes: FieldBytes) -> CtOption { assert_eq!( @@ -53,7 +53,7 @@ where } /// Create new [`ScalarBytes`], checking that the given input is within - /// range of the curve's [`Order`]. + /// range of the [`Curve::ORDER`]. #[cfg(target_pointer_width = "64")] pub fn new(bytes: FieldBytes) -> CtOption { assert_eq!( @@ -133,7 +133,7 @@ where impl AsRef> for ScalarBytes where - C: Curve + Order, + C: Curve, { fn as_ref(&self) -> &FieldBytes { &self.inner @@ -142,7 +142,7 @@ where impl AsRef<[u8]> for ScalarBytes where - C: Curve + Order, + C: Curve, { fn as_ref(&self) -> &[u8] { self.inner.as_slice() @@ -152,7 +152,7 @@ where impl ConditionallySelectable for ScalarBytes where Self: Copy, - C: Curve + Order, + C: Curve, { fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { let mut inner = FieldBytes::::default(); @@ -167,7 +167,7 @@ where impl ConstantTimeEq for ScalarBytes where - C: Curve + Order, + C: Curve, { fn ct_eq(&self, other: &Self) -> Choice { self.inner @@ -179,14 +179,14 @@ where impl Copy for ScalarBytes where - C: Curve + Order, + C: Curve, FieldBytes: Copy, { } impl Default for ScalarBytes where - C: Curve + Order, + C: Curve, { fn default() -> Self { Self::zero() @@ -195,7 +195,7 @@ where impl From> for FieldBytes where - C: Curve + Order, + C: Curve, { fn from(scalar_bytes: ScalarBytes) -> FieldBytes { scalar_bytes.inner @@ -204,7 +204,7 @@ where impl PartialEq for ScalarBytes where - C: Curve + Order, + C: Curve, { fn eq(&self, other: &Self) -> bool { self.ct_eq(other).into() @@ -213,7 +213,7 @@ where impl TryFrom<&[u8]> for ScalarBytes where - C: Curve + Order, + C: Curve, { type Error = Error; diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index 1dc4326b8..c71bb5da8 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -545,24 +545,15 @@ where } } -#[cfg(test)] +#[cfg(all(test, feature = "dev"))] mod tests { use super::{Coordinates, Tag}; - use crate::{weierstrass, Curve}; - use generic_array::{typenum::U32, GenericArray}; + use crate::dev::MockCurve; + use generic_array::GenericArray; use hex_literal::hex; use subtle::ConditionallySelectable; - #[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Ord)] - struct ExampleCurve; - - impl Curve for ExampleCurve { - type FieldSize = U32; - } - - impl weierstrass::Curve for ExampleCurve {} - - type EncodedPoint = super::EncodedPoint; + type EncodedPoint = super::EncodedPoint; /// Identity point const IDENTITY_BYTES: [u8; 1] = [0]; From a7bd3d27dd34cade41b61990baacd23b29c4532c Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 2 Jun 2021 12:28:17 -0700 Subject: [PATCH 0517/1461] elliptic-curve: use `crypto-bigint` to represent `Curve::Order` (#645) The `crypto_bigint::UInt` type has const-friendly initializers that can parse the curve order from e.g. hexadecimal. This commit changes the `Order` to be represented as a `UInt` type. This also permits things like simplified (and constant time, if needed) comparisons to ensure a given value is in range. Additionally, this commit reimplements the `dev` module's `Scalar` type for `MockCurve` to use a `crypto_bigint::U256` internally. --- .github/workflows/crypto.yml | 4 +- Cargo.lock | 10 +++ Cargo.toml | 3 + crypto/README.md | 4 +- elliptic-curve/Cargo.toml | 1 + elliptic-curve/src/dev.rs | 139 +++++------------------------ elliptic-curve/src/lib.rs | 15 +--- elliptic-curve/src/scalar/bytes.rs | 4 +- 8 files changed, 48 insertions(+), 132 deletions(-) diff --git a/.github/workflows/crypto.yml b/.github/workflows/crypto.yml index c8aea08ed..971957c06 100644 --- a/.github/workflows/crypto.yml +++ b/.github/workflows/crypto.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.44.0 # MSRV + - 1.51.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -43,7 +43,7 @@ jobs: strategy: matrix: rust: - - 1.44.0 # MSRV + - 1.51.0 # MSRV - stable steps: - uses: actions/checkout@v1 diff --git a/Cargo.lock b/Cargo.lock index b2109b7c1..13d8a9e37 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -178,6 +178,15 @@ dependencies = [ "universal-hash", ] +[[package]] +name = "crypto-bigint" +version = "0.1.0" +source = "git+https://github.com/rustcrypto/utils.git#01c945e05d86cd36b7222f0a8628cf51410eebc7" +dependencies = [ + "generic-array", + "subtle", +] + [[package]] name = "crypto-common" version = "0.1.0-pre" @@ -240,6 +249,7 @@ name = "elliptic-curve" version = "0.10.0-pre" dependencies = [ "base64ct", + "crypto-bigint", "ff", "generic-array", "group", diff --git a/Cargo.toml b/Cargo.toml index ebf9e0985..f6f42786d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,3 +12,6 @@ members = [ "signature/async", "universal-hash", ] + +[patch.crates-io] +crypto-bigint = { git = "https://github.com/rustcrypto/utils.git" } diff --git a/crypto/README.md b/crypto/README.md index 0a512fc8e..c64787660 100644 --- a/crypto/README.md +++ b/crypto/README.md @@ -14,7 +14,7 @@ access compatible versions of all traits from the Rust Crypto project. ## Minimum Supported Rust Version -Rust **1.44** or higher. +Rust **1.51** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -46,7 +46,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/crypto/badge.svg [docs-link]: https://docs.rs/crypto/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.44+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.51+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260050-Traits [build-image]: https://github.com/RustCrypto/traits/workflows/crypto/badge.svg?branch=master&event=push diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index dc0efbb6c..24547109e 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -16,6 +16,7 @@ keywords = ["crypto", "ecc", "elliptic", "weierstrass"] [dependencies] base64ct = { version = "1", optional = true, default-features = false } +crypto-bigint = { version = "0.1", features = ["generic-array"] } ff = { version = "0.10", optional = true, default-features = false } group = { version = "0.10", optional = true, default-features = false } hex-literal = { version = "0.3", optional = true } diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 959d3b044..3605c7cd9 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -2,12 +2,12 @@ //! against concrete implementations of the traits in this crate. use crate::{ + bigint::{ArrayEncoding, U256}, consts::U32, error::{Error, Result}, rand_core::RngCore, sec1::{FromEncodedPoint, ToEncodedPoint}, subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}, - util::sbb64, weierstrass, zeroize::Zeroize, AlgorithmParameters, Curve, ProjectiveArithmetic, @@ -21,7 +21,7 @@ use ff::{Field, PrimeField}; use hex_literal::hex; #[cfg(feature = "bits")] -use crate::{group::ff::PrimeFieldBits, ScalarBits}; +use crate::{bigint, group::ff::PrimeFieldBits, ScalarBits}; #[cfg(feature = "jwk")] use crate::JwkParameters; @@ -40,31 +40,10 @@ pub struct MockCurve; impl Curve for MockCurve { type FieldSize = U32; + type UInt = U256; - #[cfg(target_pointer_width = "32")] - type Limbs = [u32; 8]; - #[cfg(target_pointer_width = "64")] - type Limbs = [u64; 4]; - - #[cfg(target_pointer_width = "32")] - const ORDER: Self::Limbs = [ - 0xfc63_2551, - 0xf3b9_cac2, - 0xa717_9e84, - 0xbce6_faad, - 0xffff_ffff, - 0xffff_ffff, - 0x0000_0000, - 0xffff_ffff, - ]; - - #[cfg(target_pointer_width = "64")] - const ORDER: Self::Limbs = [ - 0xf3b9_cac2_fc63_2551, - 0xbce6_faad_a717_9e84, - 0xffff_ffff_ffff_ffff, - 0xffff_ffff_0000_0000, - ]; + const ORDER: U256 = + U256::from_be_hex("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551"); } impl weierstrass::Curve for MockCurve {} @@ -99,21 +78,9 @@ pub type PublicKey = crate::PublicKey; /// Secret key. pub type SecretKey = crate::SecretKey; -const LIMBS: usize = 4; - -type U256 = [u64; LIMBS]; - -/// P-256 modulus -pub const MODULUS: U256 = [ - 0xf3b9_cac2_fc63_2551, - 0xbce6_faad_a717_9e84, - 0xffff_ffff_ffff_ffff, - 0xffff_ffff_0000_0000, -]; - /// Example scalar type #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] -pub struct Scalar([u64; LIMBS]); +pub struct Scalar(U256); impl Field for Scalar { fn random(_rng: impl RngCore) -> Self { @@ -121,15 +88,15 @@ impl Field for Scalar { } fn zero() -> Self { - Self(Default::default()) + Self(U256::ZERO) } fn one() -> Self { - Self([1, 0, 0, 0]) + Self(U256::ONE) } fn is_zero(&self) -> bool { - self.ct_eq(&Self::zero()).into() + self.0.is_zero().into() } #[must_use] @@ -151,26 +118,6 @@ impl Field for Scalar { } } -#[cfg(all(feature = "bits", target_pointer_width = "64"))] -fn pack_bits(native: U256) -> ScalarBits { - native.into() -} - -#[cfg(all(feature = "bits", target_pointer_width = "32"))] -fn pack_bits(native: U256) -> ScalarBits { - [ - (native[0] & 0xffff_ffff) as u32, - (native[0] >> 32) as u32, - (native[1] & 0xffff_ffff) as u32, - (native[1] >> 32) as u32, - (native[2] & 0xffff_ffff) as u32, - (native[2] >> 32) as u32, - (native[3] & 0xffff_ffff) as u32, - (native[3] >> 32) as u32, - ] - .into() -} - impl PrimeField for Scalar { type Repr = FieldBytes; @@ -179,35 +126,11 @@ impl PrimeField for Scalar { const S: u32 = 4; fn from_repr(bytes: FieldBytes) -> Option { - let mut w = [0u64; LIMBS]; - - // Interpret the bytes as a big-endian integer w. - w[3] = u64::from_be_bytes(bytes[0..8].try_into().expect("bad field size")); - w[2] = u64::from_be_bytes(bytes[8..16].try_into().expect("bad field size")); - w[1] = u64::from_be_bytes(bytes[16..24].try_into().expect("bad field size")); - w[0] = u64::from_be_bytes(bytes[24..32].try_into().expect("bad field size")); - - // If w is in the range [0, n) then w - n will overflow, resulting in a borrow - // value of 2^64 - 1. - let (_, borrow) = sbb64(w[0], MODULUS[0], 0); - let (_, borrow) = sbb64(w[1], MODULUS[1], borrow); - let (_, borrow) = sbb64(w[2], MODULUS[2], borrow); - let (_, borrow) = sbb64(w[3], MODULUS[3], borrow); - - if (borrow as u8) & 1 == 1 { - Some(Scalar(w)) - } else { - None - } + U256::from_be_bytes(&bytes).try_into().ok() } fn to_repr(&self) -> FieldBytes { - let mut ret = FieldBytes::default(); - ret[0..8].copy_from_slice(&self.0[3].to_be_bytes()); - ret[8..16].copy_from_slice(&self.0[2].to_be_bytes()); - ret[16..24].copy_from_slice(&self.0[1].to_be_bytes()); - ret[24..32].copy_from_slice(&self.0[0].to_be_bytes()); - ret + self.0.to_be_byte_array() } fn is_odd(&self) -> bool { @@ -225,47 +148,38 @@ impl PrimeField for Scalar { #[cfg(feature = "bits")] impl PrimeFieldBits for Scalar { - #[cfg(target_pointer_width = "32")] - type ReprBits = [u32; 8]; - - #[cfg(target_pointer_width = "64")] - type ReprBits = [u64; 4]; + type ReprBits = [bigint::Limb; 32 / bigint::LIMB_BYTES]; fn to_le_bits(&self) -> ScalarBits { - pack_bits(self.0) + (*self.0.limbs()).into() } fn char_le_bits() -> ScalarBits { - pack_bits(MODULUS) + (*MockCurve::ORDER.limbs()).into() } } -impl TryFrom<[u64; 4]> for Scalar { +impl TryFrom for Scalar { type Error = Error; - fn try_from(limbs: [u64; 4]) -> Result { - // TODO(tarcieri): reject values that overflow the order - Ok(Scalar(limbs)) + fn try_from(w: U256) -> Result { + if w < MockCurve::ORDER { + Ok(Scalar(w)) + } else { + Err(Error) + } } } impl ConditionallySelectable for Scalar { fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { - Scalar([ - u64::conditional_select(&a.0[0], &b.0[0], choice), - u64::conditional_select(&a.0[1], &b.0[1], choice), - u64::conditional_select(&a.0[2], &b.0[2], choice), - u64::conditional_select(&a.0[3], &b.0[3], choice), - ]) + Scalar(U256::conditional_select(&a.0, &b.0, choice)) } } impl ConstantTimeEq for Scalar { fn ct_eq(&self, other: &Self) -> Choice { - self.0[0].ct_eq(&other.0[0]) - & self.0[1].ct_eq(&other.0[1]) - & self.0[2].ct_eq(&other.0[2]) - & self.0[3].ct_eq(&other.0[3]) + self.0.ct_eq(&other.0) } } @@ -375,12 +289,7 @@ impl From for FieldBytes { impl From<&Scalar> for FieldBytes { fn from(scalar: &Scalar) -> Self { - let mut ret = FieldBytes::default(); - ret[0..8].copy_from_slice(&scalar.0[3].to_be_bytes()); - ret[8..16].copy_from_slice(&scalar.0[2].to_be_bytes()); - ret[16..24].copy_from_slice(&scalar.0[1].to_be_bytes()); - ret[24..32].copy_from_slice(&scalar.0[0].to_be_bytes()); - ret + scalar.to_repr() } } diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 866048602..407905f7f 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -56,7 +56,7 @@ pub use self::{ error::{Error, Result}, scalar::bytes::ScalarBytes, }; - +pub use crypto_bigint::{self as bigint, ArrayEncoding, NumBits, NumBytes}; pub use generic_array::{self, typenum::consts}; pub use rand_core; pub use subtle; @@ -110,21 +110,14 @@ pub const ALGORITHM_OID: pkcs8::ObjectIdentifier = /// be impl'd by these ZSTs, facilitating types which are generic over elliptic /// curves (e.g. [`SecretKey`]). pub trait Curve: Clone + Debug + Default + Eq + Ord + Send + Sync { - /// Type representing the "limbs" of the curves group's order on - /// 32-bit platforms. - #[cfg(target_pointer_width = "32")] - type Limbs: AsRef<[u32]> + Copy + Debug; - - /// Type representing the "limbs" of the curves group's order on - /// 64-bit platforms. - #[cfg(target_pointer_width = "64")] - type Limbs: AsRef<[u64]> + Copy + Debug; + /// Integer type used to represent field elements of this elliptic curve. + type UInt: AsRef<[bigint::Limb]> + ArrayEncoding + Copy + Debug + NumBits + NumBytes; /// Order constant. /// /// Subdivided into either 32-bit or 64-bit "limbs" (depending on the /// target CPU's word size), specified from least to most significant. - const ORDER: Self::Limbs; + const ORDER: Self::UInt; /// Size of this curve's field in *bytes*, i.e. the number of bytes needed /// to serialize a field element. diff --git a/elliptic-curve/src/scalar/bytes.rs b/elliptic-curve/src/scalar/bytes.rs index 1c2ff6dbd..7544a4936 100644 --- a/elliptic-curve/src/scalar/bytes.rs +++ b/elliptic-curve/src/scalar/bytes.rs @@ -36,7 +36,7 @@ where #[cfg(target_pointer_width = "32")] pub fn new(bytes: FieldBytes) -> CtOption { assert_eq!( - mem::size_of::(), + mem::size_of::(), mem::size_of::>(), "malformed curve order" ); @@ -57,7 +57,7 @@ where #[cfg(target_pointer_width = "64")] pub fn new(bytes: FieldBytes) -> CtOption { assert_eq!( - mem::size_of::(), + mem::size_of::(), mem::size_of::>(), "malformed curve order" ); From 49bdec537bceed24b30392b16cf84a6badf0e035 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 2 Jun 2021 14:00:48 -0700 Subject: [PATCH 0518/1461] elliptic-curve: source FieldSize from Curve::UInt type (#646) The `crypto-bigint` library defines an associated `ArrayLength` for every `UInt` type as part of the `ArrayEncoding` trait. This means we don't need to define both: we can now source what was previously `C::FieldSize` via `C::UInt::ByteSize`. This commit performs that replacement, adding a `FieldSize` type alias which can be used anywhere `C::FieldSize` was previously used which sources the `ArrayLength` from `C::UInt` instead. --- Cargo.lock | 2 +- elliptic-curve/src/dev.rs | 2 -- elliptic-curve/src/lib.rs | 16 ++++++---------- elliptic-curve/src/scalar/bytes.rs | 6 +++--- elliptic-curve/src/scalar/non_zero.rs | 5 +++-- elliptic-curve/src/sec1.rs | 24 ++++++++++-------------- elliptic-curve/src/secret_key.rs | 5 ++--- 7 files changed, 25 insertions(+), 35 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 13d8a9e37..337f4c40c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -181,7 +181,7 @@ dependencies = [ [[package]] name = "crypto-bigint" version = "0.1.0" -source = "git+https://github.com/rustcrypto/utils.git#01c945e05d86cd36b7222f0a8628cf51410eebc7" +source = "git+https://github.com/rustcrypto/utils.git#4ff54f79d5c478720d5e6297e53208365aabbf07" dependencies = [ "generic-array", "subtle", diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 3605c7cd9..313c3f69c 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -3,7 +3,6 @@ use crate::{ bigint::{ArrayEncoding, U256}, - consts::U32, error::{Error, Result}, rand_core::RngCore, sec1::{FromEncodedPoint, ToEncodedPoint}, @@ -39,7 +38,6 @@ pub const PSEUDO_COORDINATE_FIXED_BASE_MUL: [u8; 32] = pub struct MockCurve; impl Curve for MockCurve { - type FieldSize = U32; type UInt = U256; const ORDER: U256 = diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 407905f7f..1717b4704 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -89,8 +89,8 @@ pub use secret_key::SecretKey; #[cfg(feature = "zeroize")] pub use zeroize; -use core::{fmt::Debug, ops::Add}; -use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; +use core::fmt::Debug; +use generic_array::GenericArray; /// Algorithm [`ObjectIdentifier`][`pkcs8::ObjectIdentifier`] for elliptic /// curve public key cryptography. @@ -118,17 +118,13 @@ pub trait Curve: Clone + Debug + Default + Eq + Ord + Send + Sync { /// Subdivided into either 32-bit or 64-bit "limbs" (depending on the /// target CPU's word size), specified from least to most significant. const ORDER: Self::UInt; - - /// Size of this curve's field in *bytes*, i.e. the number of bytes needed - /// to serialize a field element. - /// - /// This is used for computing the sizes of field element types related to - /// this curve and other types composed from them (e.g. signatures). - type FieldSize: ArrayLength + Add + Eq + Ord + Unsigned; } +/// Size of field elements of this elliptic curve. +pub type FieldSize = <::UInt as ArrayEncoding>::ByteSize; + /// Byte representation of a base/scalar field element of a given curve. -pub type FieldBytes = GenericArray::FieldSize>; +pub type FieldBytes = GenericArray>; /// Associate an [`ObjectIdentifier`][`pkcs8::ObjectIdentifier`] (OID) with an /// elliptic curve algorithm implementation. diff --git a/elliptic-curve/src/scalar/bytes.rs b/elliptic-curve/src/scalar/bytes.rs index 7544a4936..87d23b699 100644 --- a/elliptic-curve/src/scalar/bytes.rs +++ b/elliptic-curve/src/scalar/bytes.rs @@ -1,11 +1,11 @@ //! Scalar bytes. -use crate::{Curve, Error, FieldBytes, Result}; +use crate::{bigint::NumBytes, Curve, Error, FieldBytes, Result}; use core::{ convert::{TryFrom, TryInto}, mem, }; -use generic_array::{typenum::Unsigned, GenericArray}; +use generic_array::GenericArray; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; #[cfg(feature = "arithmetic")] @@ -218,7 +218,7 @@ where type Error = Error; fn try_from(bytes: &[u8]) -> Result { - if bytes.len() == C::FieldSize::to_usize() { + if bytes.len() == C::UInt::NUM_BYTES { Option::from(ScalarBytes::new(GenericArray::clone_from_slice(bytes))).ok_or(Error) } else { Err(Error) diff --git a/elliptic-curve/src/scalar/non_zero.rs b/elliptic-curve/src/scalar/non_zero.rs index df0327ef2..ad76e86b8 100644 --- a/elliptic-curve/src/scalar/non_zero.rs +++ b/elliptic-curve/src/scalar/non_zero.rs @@ -1,13 +1,14 @@ //! Non-zero scalar type. use crate::{ + bigint::NumBytes, ops::Invert, rand_core::{CryptoRng, RngCore}, Curve, Error, FieldBytes, ProjectiveArithmetic, Result, Scalar, }; use core::{convert::TryFrom, ops::Deref}; use ff::{Field, PrimeField}; -use generic_array::{typenum::Unsigned, GenericArray}; +use generic_array::GenericArray; use subtle::{Choice, ConditionallySelectable, CtOption}; #[cfg(feature = "zeroize")] @@ -134,7 +135,7 @@ where type Error = Error; fn try_from(bytes: &[u8]) -> Result { - if bytes.len() == C::FieldSize::to_usize() { + if bytes.len() == C::UInt::NUM_BYTES { NonZeroScalar::from_repr(GenericArray::clone_from_slice(bytes)).ok_or(Error) } else { Err(Error) diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index c71bb5da8..3e67a5b3c 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -5,15 +5,12 @@ //! //! -use crate::{weierstrass::Curve, Error, FieldBytes, Result}; +use crate::{bigint::NumBytes, weierstrass::Curve, Error, FieldBytes, FieldSize, Result}; use core::{ fmt::{self, Debug}, ops::Add, }; -use generic_array::{ - typenum::{Unsigned, U1}, - ArrayLength, GenericArray, -}; +use generic_array::{typenum::U1, ArrayLength, GenericArray}; use subtle::{Choice, ConditionallySelectable}; #[cfg(feature = "alloc")] @@ -39,7 +36,7 @@ use crate::{ /// Size of a compressed point for the given elliptic curve when encoded /// using the SEC1 `Elliptic-Curve-Point-to-Octet-String` algorithm /// (including leading `0x02` or `0x03` tag byte). -pub type CompressedPointSize = <::FieldSize as Add>::Output; +pub type CompressedPointSize = as Add>::Output; /// Size of an uncompressed point for the given elliptic curve when encoded /// using the SEC1 `Elliptic-Curve-Point-to-Octet-String` algorithm @@ -47,7 +44,7 @@ pub type CompressedPointSize = <::FieldSize as Add>::O pub type UncompressedPointSize = as Add>::Output; /// Size of an untagged point for given elliptic curve. -pub type UntaggedPointSize = <::FieldSize as Add>::Output; +pub type UntaggedPointSize = as Add>::Output; /// SEC1 encoded curve point. /// @@ -84,7 +81,7 @@ where let tag = input.first().cloned().ok_or(Error).and_then(Tag::from_u8)?; // Validate length - let expected_len = tag.message_len(C::FieldSize::to_usize()); + let expected_len = tag.message_len(C::UInt::NUM_BYTES); if input.len() != expected_len { return Err(Error); @@ -99,7 +96,7 @@ where /// encoded as the concatenated `x || y` coordinates with no leading SEC1 /// tag byte (which would otherwise be `0x04` for an uncompressed point). pub fn from_untagged_bytes(bytes: &GenericArray>) -> Self { - let (x, y) = bytes.split_at(C::FieldSize::to_usize()); + let (x, y) = bytes.split_at(C::UInt::NUM_BYTES); Self::from_affine_coordinates(x.into(), y.into(), false) } @@ -115,11 +112,10 @@ where let mut bytes = GenericArray::default(); bytes[0] = tag.into(); - let element_size = C::FieldSize::to_usize(); - bytes[1..(element_size + 1)].copy_from_slice(x); + bytes[1..(C::UInt::NUM_BYTES + 1)].copy_from_slice(x); if !compress { - bytes[(element_size + 1)..].copy_from_slice(y); + bytes[(C::UInt::NUM_BYTES + 1)..].copy_from_slice(y); } Self { bytes } @@ -151,7 +147,7 @@ where /// Get the length of the encoded point in bytes pub fn len(&self) -> usize { - self.tag().message_len(C::FieldSize::to_usize()) + self.tag().message_len(C::UInt::NUM_BYTES) } /// Get byte slice containing the serialized [`EncodedPoint`]. @@ -250,7 +246,7 @@ where return Coordinates::Identity; } - let (x, y) = self.bytes[1..].split_at(C::FieldSize::to_usize()); + let (x, y) = self.bytes[1..].split_at(C::UInt::NUM_BYTES); if self.is_compressed() { Coordinates::Compressed { diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 604fda9de..cad09836b 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -10,13 +10,12 @@ #[cfg(feature = "pkcs8")] mod pkcs8; -use crate::{Curve, Error, FieldBytes, Result}; +use crate::{bigint::NumBytes, Curve, Error, FieldBytes, Result}; use core::{ convert::TryFrom, fmt::{self, Debug}, ops::Deref, }; -use generic_array::typenum::Unsigned; use zeroize::Zeroize; #[cfg(feature = "arithmetic")] @@ -105,7 +104,7 @@ where pub fn from_bytes(bytes: impl AsRef<[u8]>) -> Result { let bytes = bytes.as_ref(); - if bytes.len() != C::FieldSize::to_usize() { + if bytes.len() != C::UInt::NUM_BYTES { return Err(Error); } From 3418d1ad153bdde5693a52bd692befdaea37e95a Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 2 Jun 2021 14:16:25 -0700 Subject: [PATCH 0519/1461] elliptic-curve: impl ScalarBytes using C::UInt (#647) Uses the `ConstantTimeLess` impl on `UInt` to ensure that a bigint parsed from the inner byte array does not overflow the curve's order. --- elliptic-curve/src/lib.rs | 12 ++++++- elliptic-curve/src/scalar/bytes.rs | 53 ++++-------------------------- 2 files changed, 17 insertions(+), 48 deletions(-) diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 1717b4704..271a49dc9 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -91,6 +91,7 @@ pub use zeroize; use core::fmt::Debug; use generic_array::GenericArray; +use subtle::{ConstantTimeEq, ConstantTimeGreater, ConstantTimeLess}; /// Algorithm [`ObjectIdentifier`][`pkcs8::ObjectIdentifier`] for elliptic /// curve public key cryptography. @@ -111,7 +112,16 @@ pub const ALGORITHM_OID: pkcs8::ObjectIdentifier = /// curves (e.g. [`SecretKey`]). pub trait Curve: Clone + Debug + Default + Eq + Ord + Send + Sync { /// Integer type used to represent field elements of this elliptic curve. - type UInt: AsRef<[bigint::Limb]> + ArrayEncoding + Copy + Debug + NumBits + NumBytes; + type UInt: AsRef<[bigint::Limb]> + + ArrayEncoding + + Copy + + Debug + + Default + + NumBits + + NumBytes + + ConstantTimeEq + + ConstantTimeGreater + + ConstantTimeLess; /// Order constant. /// diff --git a/elliptic-curve/src/scalar/bytes.rs b/elliptic-curve/src/scalar/bytes.rs index 87d23b699..a57f5f49d 100644 --- a/elliptic-curve/src/scalar/bytes.rs +++ b/elliptic-curve/src/scalar/bytes.rs @@ -1,22 +1,16 @@ //! Scalar bytes. -use crate::{bigint::NumBytes, Curve, Error, FieldBytes, Result}; -use core::{ - convert::{TryFrom, TryInto}, - mem, +use crate::{ + bigint::{ArrayEncoding, NumBytes}, + Curve, Error, FieldBytes, Result, }; +use core::convert::TryFrom; use generic_array::GenericArray; -use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; +use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeLess, CtOption}; #[cfg(feature = "arithmetic")] use crate::{group::ff::PrimeField, ProjectiveArithmetic, Scalar}; -// TODO(tarcieri): unify these into a target-width gated `sbb` -#[cfg(target_pointer_width = "32")] -use crate::util::sbb32; -#[cfg(target_pointer_width = "64")] -use crate::util::sbb64; - /// Scalar bytes: wrapper for [`FieldBytes`] which guarantees that the the /// inner byte value is within range of the [`Curve::ORDER`]. /// @@ -33,43 +27,8 @@ where { /// Create new [`ScalarBytes`], checking that the given input is within /// range of the [`Curve::ORDER`]. - #[cfg(target_pointer_width = "32")] pub fn new(bytes: FieldBytes) -> CtOption { - assert_eq!( - mem::size_of::(), - mem::size_of::>(), - "malformed curve order" - ); - - let mut borrow = 0; - - for (i, chunk) in bytes.as_ref().chunks(4).rev().enumerate() { - let limb = u32::from_be_bytes(chunk.try_into().unwrap()); - borrow = sbb32(limb, C::ORDER.as_ref()[i], borrow).1; - } - - let is_some = Choice::from((borrow as u8) & 1); - CtOption::new(Self { inner: bytes }, is_some) - } - - /// Create new [`ScalarBytes`], checking that the given input is within - /// range of the [`Curve::ORDER`]. - #[cfg(target_pointer_width = "64")] - pub fn new(bytes: FieldBytes) -> CtOption { - assert_eq!( - mem::size_of::(), - mem::size_of::>(), - "malformed curve order" - ); - - let mut borrow = 0; - - for (i, chunk) in bytes.as_ref().chunks(8).rev().enumerate() { - let limb = u64::from_be_bytes(chunk.try_into().expect("invalid chunk size")); - borrow = sbb64(limb, C::ORDER.as_ref()[i], borrow).1; - } - - let is_some = Choice::from((borrow as u8) & 1); + let is_some = C::UInt::from_be_byte_array(&bytes).ct_lt(&C::ORDER); CtOption::new(Self { inner: bytes }, is_some) } From cc442aca7e4013f3d8e3c5c5db334ed8d1e73fb1 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 2 Jun 2021 14:25:34 -0700 Subject: [PATCH 0520/1461] elliptic-curve: remove `util` module (#648) This module previously contained 32-bit and 64-bit implementations of functions which lower to the `adc`, `sbb`, and `mac` intrinsics. This functionality has been subsumed into the `crypto-bigint` crate, which provides much higher-level types with operations built on these functions, so this module is no longer necessary. --- elliptic-curve/src/lib.rs | 1 - elliptic-curve/src/util.rs | 55 -------------------------------------- 2 files changed, 56 deletions(-) delete mode 100644 elliptic-curve/src/util.rs diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 271a49dc9..8e8054d45 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -27,7 +27,6 @@ extern crate std; pub mod ops; pub mod sec1; -pub mod util; pub mod weierstrass; mod error; diff --git a/elliptic-curve/src/util.rs b/elliptic-curve/src/util.rs deleted file mode 100644 index 15e933c0f..000000000 --- a/elliptic-curve/src/util.rs +++ /dev/null @@ -1,55 +0,0 @@ -//! Arithmetic helper functions designed for efficient LLVM lowering. -//! -//! These functions are intended for supporting arithmetic on field elements -//! modeled as multiple "limbs" (e.g. carry chains). - -// TODO(tarcieri): enforce 64-bit versions are only available on 64-bit arches -// i.e. add: #[cfg(target_pointer_width = "64")] - -/// Computes `a + b + carry`, returning the result along with the new carry. -/// 32-bit version. -#[inline(always)] -pub const fn adc32(a: u32, b: u32, carry: u32) -> (u32, u32) { - let ret = (a as u64) + (b as u64) + (carry as u64); - (ret as u32, (ret >> 32) as u32) -} - -/// Computes `a + b + carry`, returning the result along with the new carry. -/// 64-bit version. -#[inline(always)] -pub const fn adc64(a: u64, b: u64, carry: u64) -> (u64, u64) { - let ret = (a as u128) + (b as u128) + (carry as u128); - (ret as u64, (ret >> 64) as u64) -} - -/// Computes `a - (b + borrow)`, returning the result along with the new borrow. -/// 32-bit version. -#[inline(always)] -pub const fn sbb32(a: u32, b: u32, borrow: u32) -> (u32, u32) { - let ret = (a as u64).wrapping_sub((b as u64) + ((borrow >> 31) as u64)); - (ret as u32, (ret >> 32) as u32) -} - -/// Computes `a - (b + borrow)`, returning the result along with the new borrow. -/// 64-bit version. -#[inline(always)] -pub const fn sbb64(a: u64, b: u64, borrow: u64) -> (u64, u64) { - let ret = (a as u128).wrapping_sub((b as u128) + ((borrow >> 63) as u128)); - (ret as u64, (ret >> 64) as u64) -} - -/// Computes `a + (b * c) + carry`, returning the result along with the new carry. -/// 32-bit version. -#[inline(always)] -pub const fn mac32(a: u32, b: u32, c: u32, carry: u32) -> (u32, u32) { - let ret = (a as u64) + ((b as u64) * (c as u64)) + (carry as u64); - (ret as u32, (ret >> 32) as u32) -} - -/// Computes `a + (b * c) + carry`, returning the result along with the new carry. -/// 64-bit version. -#[inline(always)] -pub const fn mac64(a: u64, b: u64, c: u64, carry: u64) -> (u64, u64) { - let ret = (a as u128) + ((b as u128) * (c as u128)) + (carry as u128); - (ret as u64, (ret >> 64) as u64) -} From 79f14e4e1d2b6642bcfbbd34b04e391b8e1b9ef8 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 2 Jun 2021 20:01:47 -0700 Subject: [PATCH 0521/1461] elliptic-curve: make ScalarBytes the SecretKey internal repr (#649) Previously SecretKey had a generic internal value, depending on whether or not the `arithmetic` feature was activated. This was mostly trying to work around the fact that there wasn't a baseline arithmetic impl available to validate secret keys. Now there is! SecretBytes uses C::UInt and its may features as a `crypto-bigint` to always validate the internal bytes. This means we can simply use `SecretBytes` as the inner value of a `SecretKey`, and still provide infallible conversions to `NonZeroScalar`. --- elliptic-curve/src/jwk.rs | 14 +-- elliptic-curve/src/lib.rs | 3 - elliptic-curve/src/scalar/bytes.rs | 41 +++++++- elliptic-curve/src/scalar/non_zero.rs | 16 ++- elliptic-curve/src/sec1.rs | 9 +- elliptic-curve/src/secret_key.rs | 140 +++++-------------------- elliptic-curve/src/secret_key/pkcs8.rs | 10 +- 7 files changed, 94 insertions(+), 139 deletions(-) diff --git a/elliptic-curve/src/jwk.rs b/elliptic-curve/src/jwk.rs index 55ea1e8f2..c2b33c5ea 100644 --- a/elliptic-curve/src/jwk.rs +++ b/elliptic-curve/src/jwk.rs @@ -7,7 +7,7 @@ use crate::{ sec1::{ Coordinates, EncodedPoint, UncompressedPointSize, UntaggedPointSize, ValidatePublicKey, }, - secret_key::{SecretKey, SecretValue}, + secret_key::SecretKey, weierstrass::Curve, Error, FieldBytes, }; @@ -135,9 +135,7 @@ impl JwkEcKey { #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub fn to_secret_key(&self) -> Result, Error> where - C: Curve + JwkParameters + ValidatePublicKey + SecretValue, - C::Secret: Clone + Zeroize, - FieldBytes: From, + C: Curve + JwkParameters + ValidatePublicKey, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -232,9 +230,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] impl TryFrom for SecretKey where - C: Curve + JwkParameters + ValidatePublicKey + SecretValue, - C::Secret: Clone + Zeroize, - FieldBytes: From, + C: Curve + JwkParameters + ValidatePublicKey, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -248,9 +244,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] impl TryFrom<&JwkEcKey> for SecretKey where - C: Curve + JwkParameters + ValidatePublicKey + SecretValue, - C::Secret: Clone + Zeroize, - FieldBytes: From, + C: Curve + JwkParameters + ValidatePublicKey, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 8e8054d45..7de7e38db 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -74,9 +74,6 @@ pub use { #[cfg(feature = "bits")] pub use crate::scalar::ScalarBits; -#[cfg(all(feature = "hazmat", feature = "zeroize"))] -pub use secret_key::{SecretBytes, SecretValue}; - #[cfg(feature = "jwk")] pub use crate::jwk::{JwkEcKey, JwkParameters}; diff --git a/elliptic-curve/src/scalar/bytes.rs b/elliptic-curve/src/scalar/bytes.rs index a57f5f49d..16230bda1 100644 --- a/elliptic-curve/src/scalar/bytes.rs +++ b/elliptic-curve/src/scalar/bytes.rs @@ -9,7 +9,10 @@ use generic_array::GenericArray; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeLess, CtOption}; #[cfg(feature = "arithmetic")] -use crate::{group::ff::PrimeField, ProjectiveArithmetic, Scalar}; +use crate::{group::ff::PrimeField, NonZeroScalar, ProjectiveArithmetic, Scalar}; + +#[cfg(feature = "zeroize")] +use zeroize::Zeroize; /// Scalar bytes: wrapper for [`FieldBytes`] which guarantees that the the /// inner byte value is within range of the [`Curve::ORDER`]. @@ -161,6 +164,32 @@ where } } +#[cfg(feature = "arithmetic")] +impl From> for ScalarBytes +where + C: Curve + ProjectiveArithmetic, + Scalar: PrimeField>, +{ + fn from(scalar: NonZeroScalar) -> ScalarBytes { + ScalarBytes { + inner: scalar.into(), + } + } +} + +#[cfg(feature = "arithmetic")] +impl TryFrom> for NonZeroScalar +where + C: Curve + ProjectiveArithmetic, + Scalar: PrimeField>, +{ + type Error = Error; + + fn try_from(bytes: ScalarBytes) -> Result> { + NonZeroScalar::::from_repr(bytes.inner).ok_or(Error) + } +} + impl PartialEq for ScalarBytes where C: Curve, @@ -185,6 +214,16 @@ where } } +#[cfg(feature = "zeroize")] +impl Zeroize for ScalarBytes +where + C: Curve, +{ + fn zeroize(&mut self) { + self.inner.zeroize(); + } +} + #[cfg(all(test, feature = "dev"))] mod tests { use crate::dev::MockCurve; diff --git a/elliptic-curve/src/scalar/non_zero.rs b/elliptic-curve/src/scalar/non_zero.rs index ad76e86b8..3d9818833 100644 --- a/elliptic-curve/src/scalar/non_zero.rs +++ b/elliptic-curve/src/scalar/non_zero.rs @@ -12,7 +12,7 @@ use generic_array::GenericArray; use subtle::{Choice, ConditionallySelectable, CtOption}; #[cfg(feature = "zeroize")] -use zeroize::Zeroize; +use {crate::SecretKey, zeroize::Zeroize}; /// Non-zero scalar type. /// @@ -114,6 +114,20 @@ where } } +#[cfg(feature = "zeroize")] +#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] +impl From<&SecretKey> for NonZeroScalar +where + C: Curve + ProjectiveArithmetic, + Scalar: PrimeField>, +{ + fn from(sk: &SecretKey) -> NonZeroScalar { + let scalar = sk.as_scalar_bytes().to_scalar(); + debug_assert!(!scalar.is_zero()); + Self { scalar } + } +} + impl Invert for NonZeroScalar where C: Curve + ProjectiveArithmetic, diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index 3e67a5b3c..91a7b335b 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -28,10 +28,7 @@ use crate::{ }; #[cfg(feature = "zeroize")] -use crate::{ - secret_key::{SecretKey, SecretValue}, - zeroize::Zeroize, -}; +use crate::{secret_key::SecretKey, zeroize::Zeroize}; /// Size of a compressed point for the given elliptic curve when encoded /// using the SEC1 `Elliptic-Curve-Point-to-Octet-String` algorithm @@ -134,7 +131,7 @@ where AffinePoint: ToEncodedPoint, Scalar: PrimeField> + Zeroize, { - (C::ProjectivePoint::generator() * secret_key.secret_scalar().as_ref()) + (C::ProjectivePoint::generator() * secret_key.to_secret_scalar().as_ref()) .to_affine() .to_encoded_point(compress) } @@ -496,7 +493,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] pub trait ValidatePublicKey where - Self: Curve + SecretValue, + Self: Curve, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index cad09836b..ce83f8c30 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -10,11 +10,10 @@ #[cfg(feature = "pkcs8")] mod pkcs8; -use crate::{bigint::NumBytes, Curve, Error, FieldBytes, Result}; +use crate::{Curve, Error, FieldBytes, Result, ScalarBytes}; use core::{ convert::TryFrom, fmt::{self, Debug}, - ops::Deref, }; use zeroize::Zeroize; @@ -71,68 +70,69 @@ use {crate::pkcs8::FromPrivateKey, core::str::FromStr}; /// curve crate) is enabled, a [`FromStr`] impl is also available. #[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] #[derive(Clone)] -pub struct SecretKey { - /// Secret value (i.e. secret scalar) - secret_value: C::Secret, +pub struct SecretKey { + /// Serialized scalar value + inner: ScalarBytes, } impl SecretKey where - C: Curve + SecretValue, - C::Secret: Clone + Zeroize, - FieldBytes: From, + C: Curve, { /// Generate a random [`SecretKey`] #[cfg(feature = "arithmetic")] #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub fn random(rng: impl CryptoRng + RngCore) -> Self where - C: ProjectiveArithmetic + SecretValue>, + C: ProjectiveArithmetic, Scalar: PrimeField> + Zeroize, { Self { - secret_value: NonZeroScalar::::random(rng), + inner: NonZeroScalar::::random(rng).into(), } } /// Create a new secret key from a serialized scalar value - pub fn new(secret_value: C::Secret) -> Self { - Self { secret_value } + pub fn new(scalar: ScalarBytes) -> Self { + Self { inner: scalar } } /// Deserialize raw private scalar as a big endian integer pub fn from_bytes(bytes: impl AsRef<[u8]>) -> Result { - let bytes = bytes.as_ref(); + let scalar = ScalarBytes::try_from(bytes.as_ref())?; - if bytes.len() != C::UInt::NUM_BYTES { + if scalar.is_zero().into() { return Err(Error); } - C::from_secret_bytes(bytes.into()) - .map(|secret_value| SecretKey { secret_value }) - .ok_or(Error) + Ok(Self { inner: scalar }) } /// Expose the byte serialization of the value this [`SecretKey`] wraps pub fn to_bytes(&self) -> FieldBytes { - self.secret_value.clone().into() + self.inner.clone().into() } - /// Borrow the inner secret [`Scalar`] value. + /// Borrow the inner secret [`ScalarBytes`] value. /// /// # Warning /// /// This value is key material. /// /// Please treat it with the care it deserves! + pub fn as_scalar_bytes(&self) -> &ScalarBytes { + &self.inner + } + + /// Get the secret scalar value for this key.. #[cfg(feature = "arithmetic")] #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] - pub fn secret_scalar(&self) -> &NonZeroScalar + pub fn to_secret_scalar(&self) -> NonZeroScalar where - C: ProjectiveArithmetic + SecretValue>, + C: ProjectiveArithmetic, Scalar: PrimeField> + Zeroize, { - &self.secret_value + self.into() } /// Get the [`PublicKey`] which corresponds to this secret key @@ -140,12 +140,13 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub fn public_key(&self) -> PublicKey where - C: weierstrass::Curve + ProjectiveArithmetic + SecretValue>, + C: weierstrass::Curve + ProjectiveArithmetic, AffinePoint: Copy + Clone + Debug + Default, ProjectivePoint: From>, Scalar: PrimeField> + Zeroize, { - PublicKey::from_secret_scalar(self.secret_scalar()) + // TODO(tarcieri): simplify conversion + PublicKey::from_secret_scalar(&self.to_secret_scalar()) } /// Parse a [`JwkEcKey`] JSON Web Key (JWK) into a [`SecretKey`]. @@ -207,9 +208,7 @@ where impl TryFrom<&[u8]> for SecretKey where - C: Curve + SecretValue, - C::Secret: Clone + Zeroize, - FieldBytes: From, + C: Curve, { type Error = Error; @@ -220,7 +219,7 @@ where impl Debug for SecretKey where - C: Curve + SecretValue, + C: Curve, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { // TODO(tarcieri): use `debug_struct` and `finish_non_exhaustive` when stable @@ -230,90 +229,9 @@ where impl Drop for SecretKey where - C: Curve + SecretValue, + C: Curve, { fn drop(&mut self) { - self.secret_value.zeroize(); - } -} - -/// Inner value stored by a [`SecretKey`]. -#[cfg_attr(docsrs, doc(cfg(feature = "hazmat")))] -#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] -pub trait SecretValue: Curve { - /// Inner secret value. - /// - /// ⚠️ WARNING ⚠️ - /// - /// This type is not intended to be part of the public API and in future - /// versions of this crate we will try to explore ways to hide it. - /// - /// Crates such as `k256` and `p256` conditionally define this type - /// differently depending on what cargo features are enabled. - /// This means any consumers of this crate attempting to use this type - /// may experience breakages if the cargo features are not what are - /// expected. - /// - /// We regret exposing it as part of the public API for now, however if - /// you do reference this type as a downstream consumer of a curve crate, - /// be aware you will experience breakages! - type Secret: Into> + Zeroize; - - /// Parse the secret value from bytes - // TODO(tarcieri): make this a `CtOption`? - fn from_secret_bytes(bytes: &FieldBytes) -> Option; -} - -#[cfg(feature = "arithmetic")] -#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] -impl SecretValue for C -where - C: Curve + ProjectiveArithmetic, - Scalar: PrimeField> + Zeroize, -{ - type Secret = NonZeroScalar; - - fn from_secret_bytes(repr: &FieldBytes) -> Option> { - NonZeroScalar::from_repr(repr.clone()) - } -} - -/// Newtype wrapper for [`FieldBytes`] which impls [`Zeroize`]. -/// -/// This allows it to fulfill the [`Zeroize`] bound on [`SecretValue::Secret`]. -#[cfg_attr(docsrs, doc(cfg(feature = "hazmat")))] -#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] -#[derive(Clone)] -pub struct SecretBytes(FieldBytes); - -impl From> for SecretBytes { - fn from(bytes: FieldBytes) -> SecretBytes { - Self(bytes) - } -} - -impl From> for FieldBytes { - fn from(bytes: SecretBytes) -> FieldBytes { - bytes.0 - } -} - -impl AsRef<[u8]> for SecretBytes { - fn as_ref(&self) -> &[u8] { - &self.0 - } -} - -impl Deref for SecretBytes { - type Target = FieldBytes; - - fn deref(&self) -> &FieldBytes { - &self.0 - } -} - -impl Zeroize for SecretBytes { - fn zeroize(&mut self) { - self.0.as_mut().zeroize(); + self.inner.zeroize(); } } diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs index d64715a52..b6ca4491a 100644 --- a/elliptic-curve/src/secret_key/pkcs8.rs +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -1,6 +1,6 @@ //! PKCS#8 encoding/decoding support -use super::{SecretKey, SecretValue}; +use super::SecretKey; use crate::{ sec1::{self, UncompressedPointSize, UntaggedPointSize, ValidatePublicKey}, weierstrass, AlgorithmParameters, FieldBytes, ALGORITHM_OID, @@ -43,9 +43,7 @@ const ENCODING_ERROR_MSG: &str = "DER encoding error"; #[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))] impl FromPrivateKey for SecretKey where - C: weierstrass::Curve + AlgorithmParameters + ValidatePublicKey + SecretValue, - C::Secret: Clone + Zeroize, - FieldBytes: From, + C: weierstrass::Curve + AlgorithmParameters + ValidatePublicKey, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -157,9 +155,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "pem")))] impl FromStr for SecretKey where - C: weierstrass::Curve + AlgorithmParameters + ValidatePublicKey + SecretValue, - C::Secret: Clone + Zeroize, - FieldBytes: From, + C: weierstrass::Curve + AlgorithmParameters + ValidatePublicKey, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { From 3733484bbb94cb50cae4609faf22c47350bd8981 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 4 Jun 2021 19:24:09 -0700 Subject: [PATCH 0522/1461] elliptic-curve: bump PKCS#8 to v0.7.0-pre (#650) Patched in via git. This version includes the merger of PublicKeyInfo and OneAsymmetricKey into a single type. Additionally, it bumps the `der` crate, which simplifies handling of context-sensitive fields. It also makes encoding fallible, which eliminates a lot of previous usages of `expect. --- Cargo.lock | 33 +++++----- Cargo.toml | 1 + elliptic-curve/Cargo.toml | 12 ++-- elliptic-curve/src/lib.rs | 2 + elliptic-curve/src/public_key.rs | 28 ++++++--- elliptic-curve/src/secret_key/pkcs8.rs | 87 +++++++++++++------------- elliptic-curve/tests/pkcs8.rs | 1 + 7 files changed, 91 insertions(+), 73 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 337f4c40c..e821861b0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -53,6 +53,11 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0d27fb6b6f1e43147af148af49d49329413ba781aa0d5e10979831c210173b5" +[[package]] +name = "base64ct" +version = "1.0.0" +source = "git+https://github.com/rustcrypto/utils.git#fa026e3850abedd70371107d1f78e8034e49b742" + [[package]] name = "bitfield" version = "0.13.2" @@ -139,9 +144,8 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "279bc8fc53f788a75c7804af68237d1fce02cde1e275a886a4b320604dc2aeda" +version = "0.6.0" +source = "git+https://github.com/rustcrypto/utils.git#fa026e3850abedd70371107d1f78e8034e49b742" [[package]] name = "cortex-m" @@ -181,7 +185,7 @@ dependencies = [ [[package]] name = "crypto-bigint" version = "0.1.0" -source = "git+https://github.com/rustcrypto/utils.git#4ff54f79d5c478720d5e6297e53208365aabbf07" +source = "git+https://github.com/rustcrypto/utils.git#fa026e3850abedd70371107d1f78e8034e49b742" dependencies = [ "generic-array", "subtle", @@ -219,9 +223,8 @@ dependencies = [ [[package]] name = "der" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eeb9d92785d1facb50567852ce75d0858630630e7eabea59cf7eb7474051087" +version = "0.4.0-pre" +source = "git+https://github.com/rustcrypto/utils.git#fa026e3850abedd70371107d1f78e8034e49b742" dependencies = [ "const-oid", ] @@ -248,7 +251,7 @@ dependencies = [ name = "elliptic-curve" version = "0.10.0-pre" dependencies = [ - "base64ct", + "base64ct 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "crypto-bigint", "ff", "generic-array", @@ -392,18 +395,17 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" name = "password-hash" version = "0.2.1" dependencies = [ - "base64ct", + "base64ct 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core", "subtle", ] [[package]] name = "pkcs8" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9c2f795bc591cb3384cb64082a578b89207ac92bb89c9d98c1ea2ace7cd8110" +version = "0.7.0-pre" +source = "git+https://github.com/rustcrypto/utils.git#fa026e3850abedd70371107d1f78e8034e49b742" dependencies = [ - "base64ct", + "base64ct 1.0.0 (git+https://github.com/rustcrypto/utils.git)", "der", "spki", "zeroize", @@ -528,9 +530,8 @@ dependencies = [ [[package]] name = "spki" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dae7e047abc519c96350e9484a96c6bf1492348af912fd3446dd2dc323f6268" +version = "0.4.0-pre" +source = "git+https://github.com/rustcrypto/utils.git#fa026e3850abedd70371107d1f78e8034e49b742" dependencies = [ "der", ] diff --git a/Cargo.toml b/Cargo.toml index f6f42786d..3febe0478 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,3 +15,4 @@ members = [ [patch.crates-io] crypto-bigint = { git = "https://github.com/rustcrypto/utils.git" } +pkcs8 = { git = "https://github.com/rustcrypto/utils.git" } diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 24547109e..8f8af178b 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -15,17 +15,19 @@ categories = ["cryptography", "no-std"] keywords = ["crypto", "ecc", "elliptic", "weierstrass"] [dependencies] -base64ct = { version = "1", optional = true, default-features = false } crypto-bigint = { version = "0.1", features = ["generic-array"] } +generic-array = { version = "0.14", default-features = false } +rand_core = { version = "0.6", default-features = false } +subtle = { version = "2.4", default-features = false } + +# optional dependencies +base64ct = { version = "1", optional = true, default-features = false } ff = { version = "0.10", optional = true, default-features = false } group = { version = "0.10", optional = true, default-features = false } hex-literal = { version = "0.3", optional = true } -generic-array = { version = "0.14", default-features = false } -pkcs8 = { version = "0.6", optional = true } -rand_core = { version = "0.6", default-features = false } +pkcs8 = { version = "=0.7.0-pre", optional = true } serde = { version = "1", optional = true, default-features = false } serde_json = { version = "1", optional = true, default-features = false, features = ["alloc"] } -subtle = { version = "2.4", default-features = false } zeroize = { version = "1", optional = true, default-features = false } [dev-dependencies] diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 7de7e38db..4e728baa4 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -20,6 +20,8 @@ )] #[cfg(feature = "alloc")] +#[allow(unused_imports)] +#[macro_use] extern crate alloc; #[cfg(feature = "std")] diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index b90a7c6b8..7c2b074da 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -359,11 +359,25 @@ where UncompressedPointSize: ArrayLength, { fn from_spki(spki: pkcs8::SubjectPublicKeyInfo<'_>) -> pkcs8::Result { - if spki.algorithm.oid != ALGORITHM_OID || spki.algorithm.parameters_oid()? != C::OID { - return Err(pkcs8::Error::Decode); + if spki.algorithm.oid != ALGORITHM_OID { + return Err(pkcs8::der::ErrorKind::UnknownOid { + oid: spki.algorithm.oid, + } + .into()); } - Self::from_sec1_bytes(&spki.subject_public_key).map_err(|_| pkcs8::Error::Decode) + let params_oid = spki.algorithm.parameters_oid()?; + + if params_oid != C::OID { + return Err(pkcs8::der::ErrorKind::UnknownOid { oid: params_oid }.into()); + } + + Self::from_sec1_bytes(&spki.subject_public_key).map_err(|_| { + pkcs8::der::ErrorKind::Value { + tag: pkcs8::der::Tag::BitString, + } + .into() + }) } } @@ -378,14 +392,14 @@ where UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { - fn to_public_key_der(&self) -> pkcs8::PublicKeyDocument { + fn to_public_key_der(&self) -> pkcs8::Result { let public_key_bytes = self.to_encoded_point(false); - pkcs8::SubjectPublicKeyInfo { + Ok(pkcs8::SubjectPublicKeyInfo { algorithm: C::algorithm_identifier(), subject_public_key: public_key_bytes.as_ref(), } - .into() + .into()) } } @@ -420,7 +434,7 @@ where UncompressedPointSize: ArrayLength, { fn to_string(&self) -> String { - self.to_public_key_pem() + self.to_public_key_pem().expect("PEM encoding error") } } diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs index b6ca4491a..dd6858316 100644 --- a/elliptic-curve/src/secret_key/pkcs8.rs +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -7,7 +7,14 @@ use crate::{ }; use core::ops::Add; use generic_array::{typenum::U1, ArrayLength}; -use pkcs8::{der, FromPrivateKey}; +use pkcs8::{ + der::{ + self, + asn1::{BitString, ContextSpecific, OctetString}, + TagNumber, + }, + FromPrivateKey, +}; use zeroize::Zeroize; // Imports for the `ToPrivateKey` impl @@ -19,8 +26,7 @@ use { sec1::{FromEncodedPoint, ToEncodedPoint}, AffinePoint, ProjectiveArithmetic, ProjectivePoint, }, - alloc::vec::Vec, - core::{convert::TryInto, fmt::Debug, iter}, + core::{convert::TryInto, fmt::Debug}, ff::PrimeField, pkcs8::{der::Encodable, ToPrivateKey}, zeroize::Zeroizing, @@ -36,9 +42,8 @@ use { /// Version const VERSION: u8 = 1; -/// Encoding error message -#[cfg(all(feature = "arithmetic", feature = "pem"))] -const ENCODING_ERROR_MSG: &str = "DER encoding error"; +/// Context-specific tag number for the public key. +const PUBLIC_KEY_TAG: TagNumber = TagNumber::new(1); #[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))] impl FromPrivateKey for SecretKey @@ -50,10 +55,17 @@ where fn from_pkcs8_private_key_info( private_key_info: pkcs8::PrivateKeyInfo<'_>, ) -> pkcs8::Result { - if private_key_info.algorithm.oid != ALGORITHM_OID - || private_key_info.algorithm.parameters_oid()? != C::OID - { - return Err(pkcs8::Error::Decode); + if private_key_info.algorithm.oid != ALGORITHM_OID { + return Err(pkcs8::der::ErrorKind::UnknownOid { + oid: private_key_info.algorithm.oid, + } + .into()); + } + + let params_oid = private_key_info.algorithm.parameters_oid()?; + + if params_oid != C::OID { + return Err(pkcs8::der::ErrorKind::UnknownOid { oid: params_oid }.into()); } let mut decoder = der::Decoder::new(private_key_info.private_key); @@ -72,15 +84,14 @@ where }) })?; - let public_key_field = decoder.any()?; - - public_key_field - .tag() - .assert_eq(der::Tag::ContextSpecific1)?; + let public_key = decoder + .context_specific(PUBLIC_KEY_TAG)? + .ok_or(der::ErrorKind::Value { + tag: der::Tag::ContextSpecific(PUBLIC_KEY_TAG), + })? + .bit_string()?; - let public_key_bytes = der::Decoder::new(public_key_field.as_bytes()).bit_string()?; - - if let Ok(pk) = sec1::EncodedPoint::::from_bytes(public_key_bytes.as_ref()) { + if let Ok(pk) = sec1::EncodedPoint::::from_bytes(public_key.as_ref()) { if C::validate_public_key(&secret_key, &pk).is_ok() { return Ok(secret_key); } @@ -111,43 +122,29 @@ where UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { - fn to_pkcs8_der(&self) -> pkcs8::PrivateKeyDocument { + fn to_pkcs8_der(&self) -> pkcs8::Result { // TODO(tarcieri): wrap `secret_key_bytes` in `Zeroizing` let mut secret_key_bytes = self.to_bytes(); - let secret_key_field = der::OctetString::new(&secret_key_bytes).expect(ENCODING_ERROR_MSG); - - let public_key_body = self.public_key().to_encoded_point(false); - let public_key_bytes = der::BitString::new(public_key_body.as_ref()) - .and_then(|bit_string| bit_string.to_vec()) - .expect("DER encoding error"); - - let public_key_field = - der::Any::new(der::Tag::ContextSpecific1, &public_key_bytes).expect(ENCODING_ERROR_MSG); + let secret_key_field = OctetString::new(&secret_key_bytes)?; + let public_key_bytes = self.public_key().to_encoded_point(false); + let public_key_field = ContextSpecific { + tag_number: PUBLIC_KEY_TAG, + value: BitString::new(public_key_bytes.as_ref())?.into(), + }; let der_message_fields: &[&dyn Encodable] = &[&VERSION, &secret_key_field, &public_key_field]; - let encoded_len = der::message::encoded_len(der_message_fields) - .and_then(TryInto::try_into) - .expect(ENCODING_ERROR_MSG); - - let mut der_message = Zeroizing::new(Vec::new()); - der_message.reserve(encoded_len); - der_message.extend(iter::repeat(0).take(encoded_len)); - + let encoded_len = der::message::encoded_len(der_message_fields)?.try_into()?; + let mut der_message = Zeroizing::new(vec![0u8; encoded_len]); let mut encoder = der::Encoder::new(&mut der_message); - encoder - .message(der_message_fields) - .expect(ENCODING_ERROR_MSG); + encoder.message(der_message_fields)?; + encoder.finish()?; - encoder.finish().expect(ENCODING_ERROR_MSG); + // TODO(tarcieri): wrap `secret_key_bytes` in `Zeroizing` secret_key_bytes.zeroize(); - pkcs8::PrivateKeyInfo { - algorithm: C::algorithm_identifier(), - private_key: &der_message, - } - .to_der() + Ok(pkcs8::PrivateKeyInfo::new(C::algorithm_identifier(), &der_message).to_der()) } } diff --git a/elliptic-curve/tests/pkcs8.rs b/elliptic-curve/tests/pkcs8.rs index 8f028e056..14c0fb5d1 100644 --- a/elliptic-curve/tests/pkcs8.rs +++ b/elliptic-curve/tests/pkcs8.rs @@ -25,6 +25,7 @@ fn example_private_key() -> PrivateKeyDocument { SecretKey::from_bytes(&EXAMPLE_SCALAR) .unwrap() .to_pkcs8_der() + .unwrap() } #[test] From 7f9fba12c375460b0fe385f9c2d741c8c22c5fc8 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 4 Jun 2021 20:16:18 -0700 Subject: [PATCH 0523/1461] elliptic-curve: ScalarBytes::from_uint (#651) Support for decoding scalar bytes from the bigint type for a given elliptic curve. --- elliptic-curve/src/scalar/bytes.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/elliptic-curve/src/scalar/bytes.rs b/elliptic-curve/src/scalar/bytes.rs index 16230bda1..aa531bfca 100644 --- a/elliptic-curve/src/scalar/bytes.rs +++ b/elliptic-curve/src/scalar/bytes.rs @@ -31,8 +31,14 @@ where /// Create new [`ScalarBytes`], checking that the given input is within /// range of the [`Curve::ORDER`]. pub fn new(bytes: FieldBytes) -> CtOption { - let is_some = C::UInt::from_be_byte_array(&bytes).ct_lt(&C::ORDER); - CtOption::new(Self { inner: bytes }, is_some) + Self::from_uint(&C::UInt::from_be_byte_array(&bytes)) + } + + /// Create [`ScalarBytes`] from the provided `C::UInt`. + pub fn from_uint(uint: &C::UInt) -> CtOption { + let inner = uint.to_be_byte_array(); + let in_range = uint.ct_lt(&C::ORDER); + CtOption::new(Self { inner }, in_range) } /// Convert from a [`Scalar`] type for this curve. From ed1581897e2516f34e5195cb18eeb03fc31386f2 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 4 Jun 2021 21:12:59 -0700 Subject: [PATCH 0524/1461] elliptic-curve: add dev::ScalarBytes (#652) Alias for `ScalarBytes` --- elliptic-curve/src/dev.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 313c3f69c..0dc86a1d3 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -76,6 +76,9 @@ pub type PublicKey = crate::PublicKey; /// Secret key. pub type SecretKey = crate::SecretKey; +/// Scalar bytes. +pub type ScalarBytes = crate::ScalarBytes; + /// Example scalar type #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] pub struct Scalar(U256); From 618645970a3c6d98d016edc129bba32c843883ef Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 5 Jun 2021 10:04:41 -0700 Subject: [PATCH 0525/1461] elliptic-curve: use value error helpers (#653) --- Cargo.lock | 12 ++++++------ elliptic-curve/src/public_key.rs | 8 ++------ elliptic-curve/src/secret_key.rs | 1 - elliptic-curve/src/secret_key/pkcs8.rs | 21 +++++---------------- 4 files changed, 13 insertions(+), 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e821861b0..df9d6277a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -56,7 +56,7 @@ checksum = "d0d27fb6b6f1e43147af148af49d49329413ba781aa0d5e10979831c210173b5" [[package]] name = "base64ct" version = "1.0.0" -source = "git+https://github.com/rustcrypto/utils.git#fa026e3850abedd70371107d1f78e8034e49b742" +source = "git+https://github.com/rustcrypto/utils.git#c1f7fd345e112b2f363a5b8a3ab3d321df4fed7c" [[package]] name = "bitfield" @@ -145,7 +145,7 @@ dependencies = [ [[package]] name = "const-oid" version = "0.6.0" -source = "git+https://github.com/rustcrypto/utils.git#fa026e3850abedd70371107d1f78e8034e49b742" +source = "git+https://github.com/rustcrypto/utils.git#c1f7fd345e112b2f363a5b8a3ab3d321df4fed7c" [[package]] name = "cortex-m" @@ -185,7 +185,7 @@ dependencies = [ [[package]] name = "crypto-bigint" version = "0.1.0" -source = "git+https://github.com/rustcrypto/utils.git#fa026e3850abedd70371107d1f78e8034e49b742" +source = "git+https://github.com/rustcrypto/utils.git#c1f7fd345e112b2f363a5b8a3ab3d321df4fed7c" dependencies = [ "generic-array", "subtle", @@ -224,7 +224,7 @@ dependencies = [ [[package]] name = "der" version = "0.4.0-pre" -source = "git+https://github.com/rustcrypto/utils.git#fa026e3850abedd70371107d1f78e8034e49b742" +source = "git+https://github.com/rustcrypto/utils.git#c1f7fd345e112b2f363a5b8a3ab3d321df4fed7c" dependencies = [ "const-oid", ] @@ -403,7 +403,7 @@ dependencies = [ [[package]] name = "pkcs8" version = "0.7.0-pre" -source = "git+https://github.com/rustcrypto/utils.git#fa026e3850abedd70371107d1f78e8034e49b742" +source = "git+https://github.com/rustcrypto/utils.git#c1f7fd345e112b2f363a5b8a3ab3d321df4fed7c" dependencies = [ "base64ct 1.0.0 (git+https://github.com/rustcrypto/utils.git)", "der", @@ -531,7 +531,7 @@ dependencies = [ [[package]] name = "spki" version = "0.4.0-pre" -source = "git+https://github.com/rustcrypto/utils.git#fa026e3850abedd70371107d1f78e8034e49b742" +source = "git+https://github.com/rustcrypto/utils.git#c1f7fd345e112b2f363a5b8a3ab3d321df4fed7c" dependencies = [ "der", ] diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index 7c2b074da..ea648f08e 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -372,12 +372,8 @@ where return Err(pkcs8::der::ErrorKind::UnknownOid { oid: params_oid }.into()); } - Self::from_sec1_bytes(&spki.subject_public_key).map_err(|_| { - pkcs8::der::ErrorKind::Value { - tag: pkcs8::der::Tag::BitString, - } - .into() - }) + Self::from_sec1_bytes(&spki.subject_public_key) + .map_err(|_| pkcs8::der::Tag::BitString.value_error().into()) } } diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index ce83f8c30..58640e06d 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -145,7 +145,6 @@ where ProjectivePoint: From>, Scalar: PrimeField> + Zeroize, { - // TODO(tarcieri): simplify conversion PublicKey::from_secret_scalar(&self.to_secret_scalar()) } diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs index dd6858316..da7321d03 100644 --- a/elliptic-curve/src/secret_key/pkcs8.rs +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -72,23 +72,15 @@ where let result = decoder.sequence(|decoder| { if decoder.uint8()? != VERSION { - return Err(der::ErrorKind::Value { - tag: der::Tag::Integer, - } - .into()); + return Err(der::Tag::Integer.value_error()); } - let secret_key = Self::from_bytes(decoder.octet_string()?).map_err(|_| { - der::Error::from(der::ErrorKind::Value { - tag: der::Tag::Sequence, - }) - })?; + let secret_key = Self::from_bytes(decoder.octet_string()?) + .map_err(|_| der::Tag::Sequence.value_error())?; let public_key = decoder .context_specific(PUBLIC_KEY_TAG)? - .ok_or(der::ErrorKind::Value { - tag: der::Tag::ContextSpecific(PUBLIC_KEY_TAG), - })? + .ok_or_else(|| der::Tag::ContextSpecific(PUBLIC_KEY_TAG).value_error())? .bit_string()?; if let Ok(pk) = sec1::EncodedPoint::::from_bytes(public_key.as_ref()) { @@ -97,10 +89,7 @@ where } } - Err(der::ErrorKind::Value { - tag: der::Tag::BitString, - } - .into()) + Err(der::Tag::BitString.value_error()) })?; Ok(decoder.finish(result)?) From 840a60393296983bf941f38758d086b95d33d622 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 5 Jun 2021 16:27:32 -0700 Subject: [PATCH 0526/1461] elliptic-curve: add ScalarArithmetic trait (#654) Add a trait with an associated scalar type which can be used to control the bounds required by this library. --- .github/workflows/elliptic-curve.yml | 22 +++++++++++----------- elliptic-curve/src/dev.rs | 6 +++++- elliptic-curve/src/ecdh.rs | 13 ++++++------- elliptic-curve/src/jwk.rs | 10 ++-------- elliptic-curve/src/lib.rs | 2 +- elliptic-curve/src/point.rs | 9 +++------ elliptic-curve/src/public_key.rs | 23 ++--------------------- elliptic-curve/src/scalar.rs | 12 ++++++++++-- elliptic-curve/src/scalar/bytes.rs | 5 ----- elliptic-curve/src/scalar/non_zero.rs | 18 ++---------------- elliptic-curve/src/sec1.rs | 12 ++++-------- elliptic-curve/src/secret_key.rs | 11 +++++------ elliptic-curve/src/secret_key/pkcs8.rs | 5 ++--- 13 files changed, 53 insertions(+), 95 deletions(-) diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index e8d4d2944..5414dae84 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -35,17 +35,17 @@ jobs: toolchain: ${{ matrix.rust }} target: ${{ matrix.target }} override: true - - run: cargo build --no-default-features --release --target ${{ matrix.target }} - - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features arithmetic - - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features bits - - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features dev - - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features ecdh - - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features hazmat - - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features jwk - - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features pem - - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features pkcs8 - - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features zeroize - - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features ecdh,hazmat,jwk,pem + - run: cargo build --target ${{ matrix.target }} --release --no-default-features + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features arithmetic + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features bits + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features dev + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features ecdh + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features hazmat + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features jwk + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features pem + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features pkcs8 + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features zeroize + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features ecdh,hazmat,jwk,pem test: runs-on: ubuntu-latest strategy: diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 0dc86a1d3..f1482098f 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -9,7 +9,7 @@ use crate::{ subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}, weierstrass, zeroize::Zeroize, - AlgorithmParameters, Curve, ProjectiveArithmetic, + AlgorithmParameters, Curve, ProjectiveArithmetic, ScalarArithmetic, }; use core::{ convert::{TryFrom, TryInto}, @@ -46,6 +46,10 @@ impl Curve for MockCurve { impl weierstrass::Curve for MockCurve {} +impl ScalarArithmetic for MockCurve { + type Scalar = Scalar; +} + impl ProjectiveArithmetic for MockCurve { type ProjectivePoint = ProjectivePoint; } diff --git a/elliptic-curve/src/ecdh.rs b/elliptic-curve/src/ecdh.rs index 2538d31e2..c48f4c730 100644 --- a/elliptic-curve/src/ecdh.rs +++ b/elliptic-curve/src/ecdh.rs @@ -31,7 +31,6 @@ use crate::{ ProjectivePoint, PublicKey, Scalar, }; use core::{borrow::Borrow, fmt::Debug}; -use ff::PrimeField; use group::Curve as _; use rand_core::{CryptoRng, RngCore}; use zeroize::Zeroize; @@ -64,7 +63,7 @@ where C: Curve + ProjectiveArithmetic, AffinePoint: Copy + Clone + Debug + Zeroize, ProjectivePoint: From>, - Scalar: PrimeField> + Clone + Zeroize, + Scalar: Zeroize, SharedSecret: for<'a> From<&'a AffinePoint>, { let public_point = ProjectivePoint::::from(*public_key.borrow()); @@ -98,7 +97,7 @@ where pub struct EphemeralSecret where C: Curve + ProjectiveArithmetic, - Scalar: PrimeField> + Zeroize, + Scalar: Zeroize, { scalar: NonZeroScalar, } @@ -108,7 +107,7 @@ where C: Curve + ProjectiveArithmetic, AffinePoint: Copy + Clone + Debug + Zeroize, ProjectivePoint: From>, - Scalar: PrimeField> + Clone + Zeroize, + Scalar: Zeroize, SharedSecret: for<'a> From<&'a AffinePoint>, { /// Generate a cryptographically random [`EphemeralSecret`]. @@ -137,7 +136,7 @@ where C: Curve + ProjectiveArithmetic, AffinePoint: Copy + Clone + Debug + Zeroize, ProjectivePoint: From>, - Scalar: PrimeField> + Clone + Zeroize, + Scalar: Zeroize, SharedSecret: for<'a> From<&'a AffinePoint>, { fn from(ephemeral_secret: &EphemeralSecret) -> Self { @@ -148,7 +147,7 @@ where impl Zeroize for EphemeralSecret where C: Curve + ProjectiveArithmetic, - Scalar: PrimeField> + Zeroize, + Scalar: Zeroize, { fn zeroize(&mut self) { self.scalar.zeroize() @@ -158,7 +157,7 @@ where impl Drop for EphemeralSecret where C: Curve + ProjectiveArithmetic, - Scalar: PrimeField> + Zeroize, + Scalar: Zeroize, { fn drop(&mut self) { self.zeroize(); diff --git a/elliptic-curve/src/jwk.rs b/elliptic-curve/src/jwk.rs index c2b33c5ea..02f7617b1 100644 --- a/elliptic-curve/src/jwk.rs +++ b/elliptic-curve/src/jwk.rs @@ -30,7 +30,6 @@ use zeroize::Zeroize; #[cfg(feature = "arithmetic")] use crate::{ - group::ff::PrimeField, public_key::PublicKey, sec1::{FromEncodedPoint, ToEncodedPoint}, AffinePoint, ProjectiveArithmetic, ProjectivePoint, Scalar, @@ -123,7 +122,6 @@ impl JwkEcKey { C: Curve + JwkParameters + ProjectiveArithmetic, AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, ProjectivePoint: From>, - Scalar: PrimeField>, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -275,7 +273,7 @@ where C: Curve + JwkParameters + ProjectiveArithmetic, AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, ProjectivePoint: From>, - Scalar: PrimeField> + Zeroize, + Scalar: Zeroize, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -292,7 +290,7 @@ where C: Curve + JwkParameters + ProjectiveArithmetic, AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, ProjectivePoint: From>, - Scalar: PrimeField> + Zeroize, + Scalar: Zeroize, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -313,7 +311,6 @@ where C: Curve + JwkParameters + ProjectiveArithmetic, AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, ProjectivePoint: From>, - Scalar: PrimeField>, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -332,7 +329,6 @@ where C: Curve + JwkParameters + ProjectiveArithmetic, AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, ProjectivePoint: From>, - Scalar: PrimeField>, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -351,7 +347,6 @@ where C: Curve + JwkParameters + ProjectiveArithmetic, AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, ProjectivePoint: From>, - Scalar: PrimeField>, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -368,7 +363,6 @@ where C: Curve + JwkParameters + ProjectiveArithmetic, AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, ProjectivePoint: From>, - Scalar: PrimeField>, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 4e728baa4..e38fa24ff 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -67,7 +67,7 @@ pub use { crate::{ point::{AffinePoint, ProjectiveArithmetic, ProjectivePoint}, public_key::PublicKey, - scalar::{non_zero::NonZeroScalar, Scalar}, + scalar::{non_zero::NonZeroScalar, Scalar, ScalarArithmetic}, }, ff::Field, group::{self, Group}, diff --git a/elliptic-curve/src/point.rs b/elliptic-curve/src/point.rs index 0365fd2af..6a50c6352 100644 --- a/elliptic-curve/src/point.rs +++ b/elliptic-curve/src/point.rs @@ -1,15 +1,12 @@ //! Elliptic curve points. -use crate::{Curve, FieldBytes, Scalar}; +use crate::{Curve, ScalarArithmetic}; /// Elliptic curve with projective arithmetic implementation. #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] -pub trait ProjectiveArithmetic: Curve -where - Scalar: ff::PrimeField>, -{ +pub trait ProjectiveArithmetic: Curve + ScalarArithmetic { /// Elliptic curve point in projective coordinates. - type ProjectivePoint: group::Curve; + type ProjectivePoint: group::Curve + group::Group; } /// Affine point type for a given curve with a [`ProjectiveArithmetic`] diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index ea648f08e..e31f22ee2 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -6,8 +6,7 @@ use crate::{ EncodedPoint, FromEncodedPoint, ToEncodedPoint, UncompressedPointSize, UntaggedPointSize, }, weierstrass::{Curve, PointCompression}, - AffinePoint, Error, FieldBytes, NonZeroScalar, ProjectiveArithmetic, ProjectivePoint, Result, - Scalar, + AffinePoint, Error, NonZeroScalar, ProjectiveArithmetic, ProjectivePoint, Result, }; use core::{ cmp::Ordering, @@ -15,7 +14,6 @@ use core::{ fmt::Debug, ops::Add, }; -use ff::PrimeField; use generic_array::ArrayLength; use group::{Curve as _, Group}; @@ -66,7 +64,6 @@ pub struct PublicKey where C: Curve + ProjectiveArithmetic, AffinePoint: Copy + Clone + Debug, - Scalar: PrimeField>, { point: AffinePoint, } @@ -76,7 +73,6 @@ where C: Curve + ProjectiveArithmetic, AffinePoint: Copy + Clone + Debug, ProjectivePoint: From>, - Scalar: PrimeField>, { /// Convert an [`AffinePoint`] into a [`PublicKey`] pub fn from_affine(point: AffinePoint) -> Result { @@ -181,7 +177,6 @@ where impl AsRef> for PublicKey where C: Curve + ProjectiveArithmetic, - Scalar: PrimeField>, AffinePoint: Copy + Clone + Debug, ProjectivePoint: From>, { @@ -193,7 +188,6 @@ where impl TryFrom> for PublicKey where C: Curve + ProjectiveArithmetic, - Scalar: PrimeField>, AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, ProjectivePoint: From>, UntaggedPointSize: Add + ArrayLength, @@ -209,7 +203,6 @@ where impl TryFrom<&EncodedPoint> for PublicKey where C: Curve + ProjectiveArithmetic, - Scalar: PrimeField>, AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, ProjectivePoint: From>, UntaggedPointSize: Add + ArrayLength, @@ -225,7 +218,6 @@ where impl From> for EncodedPoint where C: Curve + ProjectiveArithmetic + PointCompression, - Scalar: PrimeField>, AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, ProjectivePoint: From>, UntaggedPointSize: Add + ArrayLength, @@ -239,7 +231,6 @@ where impl From<&PublicKey> for EncodedPoint where C: Curve + ProjectiveArithmetic + PointCompression, - Scalar: PrimeField>, AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, ProjectivePoint: From>, UntaggedPointSize: Add + ArrayLength, @@ -253,7 +244,6 @@ where impl FromEncodedPoint for PublicKey where C: Curve + ProjectiveArithmetic, - Scalar: PrimeField>, AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, ProjectivePoint: From>, UntaggedPointSize: Add + ArrayLength, @@ -269,7 +259,6 @@ where impl ToEncodedPoint for PublicKey where C: Curve + ProjectiveArithmetic, - Scalar: PrimeField>, AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, ProjectivePoint: From>, UntaggedPointSize: Add + ArrayLength, @@ -285,7 +274,7 @@ where impl Copy for PublicKey where C: Curve + ProjectiveArithmetic, - Scalar: PrimeField>, + AffinePoint: Copy + Clone + Debug, { } @@ -293,7 +282,6 @@ where impl Eq for PublicKey where C: Curve + ProjectiveArithmetic, - Scalar: PrimeField>, AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, ProjectivePoint: From>, UntaggedPointSize: Add + ArrayLength, @@ -304,7 +292,6 @@ where impl PartialEq for PublicKey where C: Curve + ProjectiveArithmetic, - Scalar: PrimeField>, AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, ProjectivePoint: From>, UntaggedPointSize: Add + ArrayLength, @@ -318,7 +305,6 @@ where impl PartialOrd for PublicKey where C: Curve + ProjectiveArithmetic, - Scalar: PrimeField>, AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, ProjectivePoint: From>, UntaggedPointSize: Add + ArrayLength, @@ -332,7 +318,6 @@ where impl Ord for PublicKey where C: Curve + ProjectiveArithmetic, - Scalar: PrimeField>, AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, ProjectivePoint: From>, UntaggedPointSize: Add + ArrayLength, @@ -352,7 +337,6 @@ impl FromPublicKey for PublicKey where Self: TryFrom, Error = Error>, C: Curve + AlgorithmParameters + ProjectiveArithmetic, - Scalar: PrimeField>, AffinePoint: Copy + Clone + Debug, ProjectivePoint: From>, UntaggedPointSize: Add + ArrayLength, @@ -382,7 +366,6 @@ where impl ToPublicKey for PublicKey where C: Curve + AlgorithmParameters + ProjectiveArithmetic, - Scalar: PrimeField>, AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, ProjectivePoint: From>, UntaggedPointSize: Add + ArrayLength, @@ -405,7 +388,6 @@ impl FromStr for PublicKey where Self: TryFrom, Error = Error>, C: Curve + AlgorithmParameters + ProjectiveArithmetic, - Scalar: PrimeField>, AffinePoint: Copy + Clone + Debug, ProjectivePoint: From>, UntaggedPointSize: Add + ArrayLength, @@ -423,7 +405,6 @@ where impl ToString for PublicKey where C: Curve + AlgorithmParameters + ProjectiveArithmetic, - Scalar: PrimeField>, AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, ProjectivePoint: From>, UntaggedPointSize: Add + ArrayLength, diff --git a/elliptic-curve/src/scalar.rs b/elliptic-curve/src/scalar.rs index 4d7a788d3..07441823f 100644 --- a/elliptic-curve/src/scalar.rs +++ b/elliptic-curve/src/scalar.rs @@ -2,16 +2,24 @@ pub(crate) mod bytes; +#[cfg(feature = "arithmetic")] +use crate::{Curve, FieldBytes}; + #[cfg(feature = "arithmetic")] pub(crate) mod non_zero; +/// Scalar arithmetic. #[cfg(feature = "arithmetic")] -use {crate::ProjectiveArithmetic, group::Group}; +#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] +pub trait ScalarArithmetic: Curve { + /// Scalar field type. + type Scalar: ff::Field + ff::PrimeField>; +} /// Scalar field element for a particular elliptic curve. #[cfg(feature = "arithmetic")] #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] -pub type Scalar = <::ProjectivePoint as Group>::Scalar; +pub type Scalar = ::Scalar; /// Bit representation of a scalar field element of a given curve. #[cfg(feature = "bits")] diff --git a/elliptic-curve/src/scalar/bytes.rs b/elliptic-curve/src/scalar/bytes.rs index aa531bfca..f3ad07022 100644 --- a/elliptic-curve/src/scalar/bytes.rs +++ b/elliptic-curve/src/scalar/bytes.rs @@ -47,7 +47,6 @@ where pub fn from_scalar(scalar: &Scalar) -> Self where C: ProjectiveArithmetic, - Scalar: PrimeField>, { Self { inner: scalar.to_repr(), @@ -60,7 +59,6 @@ where pub fn to_scalar(&self) -> Scalar where C: ProjectiveArithmetic, - Scalar: PrimeField>, { self.clone().into_scalar() } @@ -71,7 +69,6 @@ where pub fn into_scalar(self) -> Scalar where C: ProjectiveArithmetic, - Scalar: PrimeField>, { Scalar::::from_repr(self.inner).expect("ScalarBytes order invariant violated") } @@ -174,7 +171,6 @@ where impl From> for ScalarBytes where C: Curve + ProjectiveArithmetic, - Scalar: PrimeField>, { fn from(scalar: NonZeroScalar) -> ScalarBytes { ScalarBytes { @@ -187,7 +183,6 @@ where impl TryFrom> for NonZeroScalar where C: Curve + ProjectiveArithmetic, - Scalar: PrimeField>, { type Error = Error; diff --git a/elliptic-curve/src/scalar/non_zero.rs b/elliptic-curve/src/scalar/non_zero.rs index 3d9818833..96c697647 100644 --- a/elliptic-curve/src/scalar/non_zero.rs +++ b/elliptic-curve/src/scalar/non_zero.rs @@ -27,7 +27,6 @@ use {crate::SecretKey, zeroize::Zeroize}; pub struct NonZeroScalar where C: Curve + ProjectiveArithmetic, - Scalar: PrimeField>, { scalar: Scalar, } @@ -35,7 +34,6 @@ where impl NonZeroScalar where C: Curve + ProjectiveArithmetic, - Scalar: PrimeField>, { /// Generate a random `NonZeroScalar` pub fn random(mut rng: impl CryptoRng + RngCore) -> Self { @@ -66,7 +64,6 @@ where impl AsRef> for NonZeroScalar where C: Curve + ProjectiveArithmetic, - Scalar: PrimeField>, { fn as_ref(&self) -> &Scalar { &self.scalar @@ -76,7 +73,6 @@ where impl ConditionallySelectable for NonZeroScalar where C: Curve + ProjectiveArithmetic, - Scalar: PrimeField>, { fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { Self { @@ -85,17 +81,11 @@ where } } -impl Copy for NonZeroScalar -where - C: Curve + ProjectiveArithmetic, - Scalar: PrimeField>, -{ -} +impl Copy for NonZeroScalar where C: Curve + ProjectiveArithmetic {} impl Deref for NonZeroScalar where C: Curve + ProjectiveArithmetic, - Scalar: PrimeField>, { type Target = Scalar; @@ -107,7 +97,6 @@ where impl From> for FieldBytes where C: Curve + ProjectiveArithmetic, - Scalar: PrimeField>, { fn from(scalar: NonZeroScalar) -> FieldBytes { scalar.scalar.to_repr() @@ -119,7 +108,6 @@ where impl From<&SecretKey> for NonZeroScalar where C: Curve + ProjectiveArithmetic, - Scalar: PrimeField>, { fn from(sk: &SecretKey) -> NonZeroScalar { let scalar = sk.as_scalar_bytes().to_scalar(); @@ -131,7 +119,6 @@ where impl Invert for NonZeroScalar where C: Curve + ProjectiveArithmetic, - Scalar: PrimeField> + Invert, { type Output = Scalar; @@ -144,7 +131,6 @@ where impl TryFrom<&[u8]> for NonZeroScalar where C: Curve + ProjectiveArithmetic, - Scalar: PrimeField>, { type Error = Error; @@ -161,7 +147,7 @@ where impl Zeroize for NonZeroScalar where C: Curve + ProjectiveArithmetic, - Scalar: PrimeField> + Zeroize, + Scalar: Zeroize, { fn zeroize(&mut self) { self.scalar.zeroize(); diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index 91a7b335b..64290a74b 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -17,14 +17,12 @@ use subtle::{Choice, ConditionallySelectable}; use alloc::boxed::Box; #[cfg(feature = "arithmetic")] -use crate::{ - group::ff::PrimeField, weierstrass::DecompressPoint, AffinePoint, ProjectiveArithmetic, Scalar, -}; +use crate::{weierstrass::DecompressPoint, AffinePoint, ProjectiveArithmetic}; #[cfg(all(feature = "arithmetic", feature = "zeroize"))] use crate::{ group::{Curve as _, Group}, - ProjectivePoint, + ProjectivePoint, Scalar, }; #[cfg(feature = "zeroize")] @@ -129,7 +127,7 @@ where where C: Curve + ProjectiveArithmetic, AffinePoint: ToEncodedPoint, - Scalar: PrimeField> + Zeroize, + Scalar: Zeroize, { (C::ProjectivePoint::generator() * secret_key.to_secret_scalar().as_ref()) .to_affine() @@ -167,7 +165,6 @@ where where C: Curve + ProjectiveArithmetic, AffinePoint: ConditionallySelectable + Default + DecompressPoint + ToEncodedPoint, - Scalar: PrimeField>, { self.decompress().map(|point| { let mut bytes = GenericArray::>::default(); @@ -200,7 +197,6 @@ where pub fn decompress(&self) -> Option where C: Curve + ProjectiveArithmetic, - Scalar: PrimeField>, AffinePoint: ConditionallySelectable + Default + DecompressPoint + ToEncodedPoint, { match self.coordinates() { @@ -521,7 +517,7 @@ where C: Curve + ProjectiveArithmetic, AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, ProjectivePoint: From>, - Scalar: PrimeField> + Zeroize, + Scalar: Zeroize, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 58640e06d..169f25ac7 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -19,7 +19,6 @@ use zeroize::Zeroize; #[cfg(feature = "arithmetic")] use crate::{ - group::ff::PrimeField, rand_core::{CryptoRng, RngCore}, weierstrass, AffinePoint, NonZeroScalar, ProjectiveArithmetic, ProjectivePoint, PublicKey, Scalar, @@ -85,7 +84,7 @@ where pub fn random(rng: impl CryptoRng + RngCore) -> Self where C: ProjectiveArithmetic, - Scalar: PrimeField> + Zeroize, + Scalar: Zeroize, { Self { inner: NonZeroScalar::::random(rng).into(), @@ -130,7 +129,7 @@ where pub fn to_secret_scalar(&self) -> NonZeroScalar where C: ProjectiveArithmetic, - Scalar: PrimeField> + Zeroize, + Scalar: Zeroize, { self.into() } @@ -143,7 +142,7 @@ where C: weierstrass::Curve + ProjectiveArithmetic, AffinePoint: Copy + Clone + Debug + Default, ProjectivePoint: From>, - Scalar: PrimeField> + Zeroize, + Scalar: Zeroize, { PublicKey::from_secret_scalar(&self.to_secret_scalar()) } @@ -181,7 +180,7 @@ where C: JwkParameters + ProjectiveArithmetic, AffinePoint: Copy + Debug + Default + FromEncodedPoint + ToEncodedPoint, ProjectivePoint: From>, - Scalar: PrimeField> + Zeroize, + Scalar: Zeroize, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -197,7 +196,7 @@ where C: JwkParameters + ProjectiveArithmetic, AffinePoint: Copy + Debug + Default + FromEncodedPoint + ToEncodedPoint, ProjectivePoint: From>, - Scalar: PrimeField> + Zeroize, + Scalar: Zeroize, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs index da7321d03..1646cef6c 100644 --- a/elliptic-curve/src/secret_key/pkcs8.rs +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -3,7 +3,7 @@ use super::SecretKey; use crate::{ sec1::{self, UncompressedPointSize, UntaggedPointSize, ValidatePublicKey}, - weierstrass, AlgorithmParameters, FieldBytes, ALGORITHM_OID, + weierstrass, AlgorithmParameters, ALGORITHM_OID, }; use core::ops::Add; use generic_array::{typenum::U1, ArrayLength}; @@ -27,7 +27,6 @@ use { AffinePoint, ProjectiveArithmetic, ProjectivePoint, }, core::{convert::TryInto, fmt::Debug}, - ff::PrimeField, pkcs8::{der::Encodable, ToPrivateKey}, zeroize::Zeroizing, }; @@ -107,7 +106,7 @@ where C: weierstrass::Curve + AlgorithmParameters + ProjectiveArithmetic, AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, ProjectivePoint: From>, - Scalar: PrimeField> + Zeroize, + Scalar: Zeroize, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { From 9c0e0ed2526bcdab8b041acea79410aebdcb4427 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 7 Jun 2021 07:30:44 -0700 Subject: [PATCH 0527/1461] elliptic-curve: add additional SecretKey conversions (#655) --- elliptic-curve/src/scalar/bytes.rs | 19 +++++++++++++++++++ elliptic-curve/src/scalar/non_zero.rs | 20 ++++++++++++++++++++ elliptic-curve/src/secret_key.rs | 26 +++++++++++++++++++++++++- 3 files changed, 64 insertions(+), 1 deletion(-) diff --git a/elliptic-curve/src/scalar/bytes.rs b/elliptic-curve/src/scalar/bytes.rs index f3ad07022..abcff856d 100644 --- a/elliptic-curve/src/scalar/bytes.rs +++ b/elliptic-curve/src/scalar/bytes.rs @@ -167,12 +167,31 @@ where } } +impl From<&ScalarBytes> for FieldBytes +where + C: Curve, +{ + fn from(scalar_bytes: &ScalarBytes) -> FieldBytes { + scalar_bytes.inner.clone() + } +} + #[cfg(feature = "arithmetic")] impl From> for ScalarBytes where C: Curve + ProjectiveArithmetic, { fn from(scalar: NonZeroScalar) -> ScalarBytes { + Self::from(&scalar) + } +} + +#[cfg(feature = "arithmetic")] +impl From<&NonZeroScalar> for ScalarBytes +where + C: Curve + ProjectiveArithmetic, +{ + fn from(scalar: &NonZeroScalar) -> ScalarBytes { ScalarBytes { inner: scalar.into(), } diff --git a/elliptic-curve/src/scalar/non_zero.rs b/elliptic-curve/src/scalar/non_zero.rs index 96c697647..7b42ec9b5 100644 --- a/elliptic-curve/src/scalar/non_zero.rs +++ b/elliptic-curve/src/scalar/non_zero.rs @@ -99,10 +99,30 @@ where C: Curve + ProjectiveArithmetic, { fn from(scalar: NonZeroScalar) -> FieldBytes { + Self::from(&scalar) + } +} + +impl From<&NonZeroScalar> for FieldBytes +where + C: Curve + ProjectiveArithmetic, +{ + fn from(scalar: &NonZeroScalar) -> FieldBytes { scalar.scalar.to_repr() } } +#[cfg(feature = "zeroize")] +#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] +impl From> for NonZeroScalar +where + C: Curve + ProjectiveArithmetic, +{ + fn from(sk: SecretKey) -> NonZeroScalar { + Self::from(&sk) + } +} + #[cfg(feature = "zeroize")] #[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] impl From<&SecretKey> for NonZeroScalar diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 169f25ac7..6bbb300b9 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -128,7 +128,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub fn to_secret_scalar(&self) -> NonZeroScalar where - C: ProjectiveArithmetic, + C: Curve + ProjectiveArithmetic, Scalar: Zeroize, { self.into() @@ -204,6 +204,30 @@ where } } +#[cfg(feature = "arithmetic")] +#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] +impl From> for SecretKey +where + C: Curve + ProjectiveArithmetic, +{ + fn from(scalar: NonZeroScalar) -> SecretKey { + SecretKey::from(&scalar) + } +} + +#[cfg(feature = "arithmetic")] +#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] +impl From<&NonZeroScalar> for SecretKey +where + C: Curve + ProjectiveArithmetic, +{ + fn from(scalar: &NonZeroScalar) -> SecretKey { + SecretKey { + inner: scalar.into(), + } + } +} + impl TryFrom<&[u8]> for SecretKey where C: Curve, From 884ef53c17981ff8bf1407bd6a4455ba14451184 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 7 Jun 2021 10:31:34 -0700 Subject: [PATCH 0528/1461] elliptic-curve: use `AlgorithmIdentifier::assert_oids` helper (#657) Simplifies checking of SPKI OIDs --- Cargo.lock | 16 ++++++++-------- elliptic-curve/src/secret_key/pkcs8.rs | 15 +++------------ 2 files changed, 11 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index df9d6277a..47c0f79cb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -56,7 +56,7 @@ checksum = "d0d27fb6b6f1e43147af148af49d49329413ba781aa0d5e10979831c210173b5" [[package]] name = "base64ct" version = "1.0.0" -source = "git+https://github.com/rustcrypto/utils.git#c1f7fd345e112b2f363a5b8a3ab3d321df4fed7c" +source = "git+https://github.com/rustcrypto/utils.git#3fc828a86a31b2b5016dd64e4f3b38a858f9d070" [[package]] name = "bitfield" @@ -145,7 +145,7 @@ dependencies = [ [[package]] name = "const-oid" version = "0.6.0" -source = "git+https://github.com/rustcrypto/utils.git#c1f7fd345e112b2f363a5b8a3ab3d321df4fed7c" +source = "git+https://github.com/rustcrypto/utils.git#3fc828a86a31b2b5016dd64e4f3b38a858f9d070" [[package]] name = "cortex-m" @@ -185,7 +185,7 @@ dependencies = [ [[package]] name = "crypto-bigint" version = "0.1.0" -source = "git+https://github.com/rustcrypto/utils.git#c1f7fd345e112b2f363a5b8a3ab3d321df4fed7c" +source = "git+https://github.com/rustcrypto/utils.git#3fc828a86a31b2b5016dd64e4f3b38a858f9d070" dependencies = [ "generic-array", "subtle", @@ -224,7 +224,7 @@ dependencies = [ [[package]] name = "der" version = "0.4.0-pre" -source = "git+https://github.com/rustcrypto/utils.git#c1f7fd345e112b2f363a5b8a3ab3d321df4fed7c" +source = "git+https://github.com/rustcrypto/utils.git#3fc828a86a31b2b5016dd64e4f3b38a858f9d070" dependencies = [ "const-oid", ] @@ -366,9 +366,9 @@ checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" [[package]] name = "libc" -version = "0.2.94" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18794a8ad5b29321f790b55d93dfba91e125cb1a9edbd4f8e3150acc771c1a5e" +checksum = "789da6d93f1b866ffe175afc5322a4d76c038605a1c3319bb57b06967ca98a36" [[package]] name = "nb" @@ -403,7 +403,7 @@ dependencies = [ [[package]] name = "pkcs8" version = "0.7.0-pre" -source = "git+https://github.com/rustcrypto/utils.git#c1f7fd345e112b2f363a5b8a3ab3d321df4fed7c" +source = "git+https://github.com/rustcrypto/utils.git#3fc828a86a31b2b5016dd64e4f3b38a858f9d070" dependencies = [ "base64ct 1.0.0 (git+https://github.com/rustcrypto/utils.git)", "der", @@ -531,7 +531,7 @@ dependencies = [ [[package]] name = "spki" version = "0.4.0-pre" -source = "git+https://github.com/rustcrypto/utils.git#c1f7fd345e112b2f363a5b8a3ab3d321df4fed7c" +source = "git+https://github.com/rustcrypto/utils.git#3fc828a86a31b2b5016dd64e4f3b38a858f9d070" dependencies = [ "der", ] diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs index 1646cef6c..0e8b66120 100644 --- a/elliptic-curve/src/secret_key/pkcs8.rs +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -54,18 +54,9 @@ where fn from_pkcs8_private_key_info( private_key_info: pkcs8::PrivateKeyInfo<'_>, ) -> pkcs8::Result { - if private_key_info.algorithm.oid != ALGORITHM_OID { - return Err(pkcs8::der::ErrorKind::UnknownOid { - oid: private_key_info.algorithm.oid, - } - .into()); - } - - let params_oid = private_key_info.algorithm.parameters_oid()?; - - if params_oid != C::OID { - return Err(pkcs8::der::ErrorKind::UnknownOid { oid: params_oid }.into()); - } + private_key_info + .algorithm + .assert_oids(ALGORITHM_OID, C::OID)?; let mut decoder = der::Decoder::new(private_key_info.private_key); From 6dced063c1d943e04ee52e5e53bba5e08b83b450 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 7 Jun 2021 11:36:41 -0700 Subject: [PATCH 0529/1461] elliptic-curve: add AffineArithmetic trait (#658) This allows us to specify a baseline set of bounds for `AffinePoint` so they don't have to redundantly be specified in `where` clauses. --- elliptic-curve/src/arithmetic.rs | 60 ++++++++++++++++++++++++++ elliptic-curve/src/dev.rs | 34 +++++++++++++-- elliptic-curve/src/ecdh.rs | 11 ++--- elliptic-curve/src/jwk.rs | 23 ++++------ elliptic-curve/src/lib.rs | 18 ++++++-- elliptic-curve/src/point.rs | 21 --------- elliptic-curve/src/public_key.rs | 53 +++++++---------------- elliptic-curve/src/scalar.rs | 10 +---- elliptic-curve/src/sec1.rs | 9 ++-- elliptic-curve/src/secret_key.rs | 16 +++---- elliptic-curve/src/secret_key/pkcs8.rs | 7 ++- 11 files changed, 149 insertions(+), 113 deletions(-) create mode 100644 elliptic-curve/src/arithmetic.rs delete mode 100644 elliptic-curve/src/point.rs diff --git a/elliptic-curve/src/arithmetic.rs b/elliptic-curve/src/arithmetic.rs new file mode 100644 index 000000000..fc7c1cf5e --- /dev/null +++ b/elliptic-curve/src/arithmetic.rs @@ -0,0 +1,60 @@ +//! Elliptic curve arithmetic traits. + +use crate::{Curve, FieldBytes}; +use core::fmt::Debug; +use subtle::{ConditionallySelectable, ConstantTimeEq}; + +/// Elliptic curve with affine arithmetic implementation. +#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] +pub trait AffineArithmetic: Curve + ScalarArithmetic { + /// Elliptic curve point in affine coordinates. + type AffinePoint: Copy + + Clone + + ConditionallySelectable + + ConstantTimeEq + + Debug + + Default + + Sized + + Send + + Sync + + 'static; +} + +/// Elliptic curve with projective arithmetic implementation. +#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] +pub trait ProjectiveArithmetic: Curve + AffineArithmetic { + /// Elliptic curve point in projective coordinates. + /// + /// Note: the following bounds are enforced by [`group::Group`]: + /// - `Copy` + /// - `Clone` + /// - `Debug` + /// - `Eq` + /// - `Sized` + /// - `Send` + /// - `Sync` + type ProjectivePoint: ConditionallySelectable + + ConstantTimeEq + + Default + + From + + Into + + group::Curve + + group::Group; +} + +/// Scalar arithmetic. +#[cfg(feature = "arithmetic")] +#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] +pub trait ScalarArithmetic: Curve { + /// Scalar field type. + /// + /// Note: the following bounds are enforced by [`ff::Field`]: + /// - `Copy` + /// - `Clone` + /// - `ConditionallySelectable` + /// - `Debug` + /// - `Default` + /// - `Send` + /// - `Sync` + type Scalar: ConstantTimeEq + ff::Field + ff::PrimeField>; +} diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index f1482098f..1c02ac59b 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -9,7 +9,7 @@ use crate::{ subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}, weierstrass, zeroize::Zeroize, - AlgorithmParameters, Curve, ProjectiveArithmetic, ScalarArithmetic, + AffineArithmetic, AlgorithmParameters, Curve, ProjectiveArithmetic, ScalarArithmetic, }; use core::{ convert::{TryFrom, TryInto}, @@ -46,14 +46,18 @@ impl Curve for MockCurve { impl weierstrass::Curve for MockCurve {} -impl ScalarArithmetic for MockCurve { - type Scalar = Scalar; +impl AffineArithmetic for MockCurve { + type AffinePoint = AffinePoint; } impl ProjectiveArithmetic for MockCurve { type ProjectivePoint = ProjectivePoint; } +impl ScalarArithmetic for MockCurve { + type Scalar = Scalar; +} + impl AlgorithmParameters for MockCurve { /// OID for NIST P-256 const OID: pkcs8::ObjectIdentifier = pkcs8::ObjectIdentifier::new("1.2.840.10045.3.1.7"); @@ -320,6 +324,12 @@ pub enum AffinePoint { Other(EncodedPoint), } +impl ConstantTimeEq for AffinePoint { + fn ct_eq(&self, _other: &Self) -> Choice { + unimplemented!(); + } +} + impl ConditionallySelectable for AffinePoint { fn conditional_select(_a: &Self, _b: &Self, _choice: Choice) -> Self { unimplemented!(); @@ -386,6 +396,18 @@ pub enum ProjectivePoint { Other(AffinePoint), } +impl ConstantTimeEq for ProjectivePoint { + fn ct_eq(&self, _other: &Self) -> Choice { + unimplemented!(); + } +} + +impl ConditionallySelectable for ProjectivePoint { + fn conditional_select(_a: &Self, _b: &Self, _choice: Choice) -> Self { + unimplemented!(); + } +} + impl Default for ProjectivePoint { fn default() -> Self { Self::Identity @@ -403,6 +425,12 @@ impl From for ProjectivePoint { } } +impl From for AffinePoint { + fn from(point: ProjectivePoint) -> AffinePoint { + group::Curve::to_affine(&point) + } +} + impl FromEncodedPoint for ProjectivePoint { fn from_encoded_point(_point: &EncodedPoint) -> Option { unimplemented!(); diff --git a/elliptic-curve/src/ecdh.rs b/elliptic-curve/src/ecdh.rs index c48f4c730..6a670c01d 100644 --- a/elliptic-curve/src/ecdh.rs +++ b/elliptic-curve/src/ecdh.rs @@ -30,7 +30,7 @@ use crate::{ weierstrass::Curve, AffinePoint, FieldBytes, NonZeroScalar, ProjectiveArithmetic, ProjectivePoint, PublicKey, Scalar, }; -use core::{borrow::Borrow, fmt::Debug}; +use core::borrow::Borrow; use group::Curve as _; use rand_core::{CryptoRng, RngCore}; use zeroize::Zeroize; @@ -61,8 +61,7 @@ pub fn diffie_hellman( ) -> SharedSecret where C: Curve + ProjectiveArithmetic, - AffinePoint: Copy + Clone + Debug + Zeroize, - ProjectivePoint: From>, + AffinePoint: Zeroize, Scalar: Zeroize, SharedSecret: for<'a> From<&'a AffinePoint>, { @@ -105,8 +104,7 @@ where impl EphemeralSecret where C: Curve + ProjectiveArithmetic, - AffinePoint: Copy + Clone + Debug + Zeroize, - ProjectivePoint: From>, + AffinePoint: Zeroize, Scalar: Zeroize, SharedSecret: for<'a> From<&'a AffinePoint>, { @@ -134,8 +132,7 @@ where impl From<&EphemeralSecret> for PublicKey where C: Curve + ProjectiveArithmetic, - AffinePoint: Copy + Clone + Debug + Zeroize, - ProjectivePoint: From>, + AffinePoint: Zeroize, Scalar: Zeroize, SharedSecret: for<'a> From<&'a AffinePoint>, { diff --git a/elliptic-curve/src/jwk.rs b/elliptic-curve/src/jwk.rs index 02f7617b1..3c2bceec4 100644 --- a/elliptic-curve/src/jwk.rs +++ b/elliptic-curve/src/jwk.rs @@ -32,7 +32,7 @@ use zeroize::Zeroize; use crate::{ public_key::PublicKey, sec1::{FromEncodedPoint, ToEncodedPoint}, - AffinePoint, ProjectiveArithmetic, ProjectivePoint, Scalar, + AffinePoint, ProjectiveArithmetic, Scalar, }; /// Key Type (`kty`) for elliptic curve keys. @@ -120,8 +120,7 @@ impl JwkEcKey { pub fn to_public_key(&self) -> Result, Error> where C: Curve + JwkParameters + ProjectiveArithmetic, - AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, - ProjectivePoint: From>, + AffinePoint: FromEncodedPoint + ToEncodedPoint, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -271,8 +270,7 @@ where impl From> for JwkEcKey where C: Curve + JwkParameters + ProjectiveArithmetic, - AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, - ProjectivePoint: From>, + AffinePoint: FromEncodedPoint + ToEncodedPoint, Scalar: Zeroize, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, @@ -288,8 +286,7 @@ where impl From<&SecretKey> for JwkEcKey where C: Curve + JwkParameters + ProjectiveArithmetic, - AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, - ProjectivePoint: From>, + AffinePoint: FromEncodedPoint + ToEncodedPoint, Scalar: Zeroize, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, @@ -309,8 +306,7 @@ where impl TryFrom for PublicKey where C: Curve + JwkParameters + ProjectiveArithmetic, - AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, - ProjectivePoint: From>, + AffinePoint: FromEncodedPoint + ToEncodedPoint, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -327,8 +323,7 @@ where impl TryFrom<&JwkEcKey> for PublicKey where C: Curve + JwkParameters + ProjectiveArithmetic, - AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, - ProjectivePoint: From>, + AffinePoint: FromEncodedPoint + ToEncodedPoint, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -345,8 +340,7 @@ where impl From> for JwkEcKey where C: Curve + JwkParameters + ProjectiveArithmetic, - AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, - ProjectivePoint: From>, + AffinePoint: FromEncodedPoint + ToEncodedPoint, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -361,8 +355,7 @@ where impl From<&PublicKey> for JwkEcKey where C: Curve + JwkParameters + ProjectiveArithmetic, - AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, - ProjectivePoint: From>, + AffinePoint: FromEncodedPoint + ToEncodedPoint, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index e38fa24ff..cd1f1e06f 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -35,7 +35,7 @@ mod error; mod scalar; #[cfg(feature = "arithmetic")] -mod point; +mod arithmetic; #[cfg(feature = "arithmetic")] mod public_key; @@ -65,9 +65,9 @@ pub use subtle; #[cfg(feature = "arithmetic")] pub use { crate::{ - point::{AffinePoint, ProjectiveArithmetic, ProjectivePoint}, + arithmetic::{AffineArithmetic, ProjectiveArithmetic, ScalarArithmetic}, public_key::PublicKey, - scalar::{non_zero::NonZeroScalar, Scalar, ScalarArithmetic}, + scalar::{non_zero::NonZeroScalar, Scalar}, }, ff::Field, group::{self, Group}, @@ -134,6 +134,18 @@ pub type FieldSize = <::UInt as ArrayEncoding>::ByteSize; /// Byte representation of a base/scalar field element of a given curve. pub type FieldBytes = GenericArray>; +/// Affine point type for a given curve with a [`ProjectiveArithmetic`] +/// implementation. +#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] +#[cfg(feature = "arithmetic")] +pub type AffinePoint = ::AffinePoint; + +/// Projective point type for a given curve with a [`ProjectiveArithmetic`] +/// implementation. +#[cfg(feature = "arithmetic")] +#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] +pub type ProjectivePoint = ::ProjectivePoint; + /// Associate an [`ObjectIdentifier`][`pkcs8::ObjectIdentifier`] (OID) with an /// elliptic curve algorithm implementation. /// diff --git a/elliptic-curve/src/point.rs b/elliptic-curve/src/point.rs deleted file mode 100644 index 6a50c6352..000000000 --- a/elliptic-curve/src/point.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Elliptic curve points. - -use crate::{Curve, ScalarArithmetic}; - -/// Elliptic curve with projective arithmetic implementation. -#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] -pub trait ProjectiveArithmetic: Curve + ScalarArithmetic { - /// Elliptic curve point in projective coordinates. - type ProjectivePoint: group::Curve + group::Group; -} - -/// Affine point type for a given curve with a [`ProjectiveArithmetic`] -/// implementation. -#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] -pub type AffinePoint = - <::ProjectivePoint as group::Curve>::AffineRepr; - -/// Projective point type for a given curve with a [`ProjectiveArithmetic`] -/// implementation. -#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] -pub type ProjectivePoint = ::ProjectivePoint; diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index e31f22ee2..85c6581c2 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -63,7 +63,6 @@ use alloc::string::{String, ToString}; pub struct PublicKey where C: Curve + ProjectiveArithmetic, - AffinePoint: Copy + Clone + Debug, { point: AffinePoint, } @@ -71,8 +70,6 @@ where impl PublicKey where C: Curve + ProjectiveArithmetic, - AffinePoint: Copy + Clone + Debug, - ProjectivePoint: From>, { /// Convert an [`AffinePoint`] into a [`PublicKey`] pub fn from_affine(point: AffinePoint) -> Result { @@ -127,7 +124,7 @@ where pub fn from_jwk(jwk: &JwkEcKey) -> Result where C: JwkParameters, - AffinePoint: Default + FromEncodedPoint + ToEncodedPoint, + AffinePoint: FromEncodedPoint + ToEncodedPoint, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -140,7 +137,7 @@ where pub fn from_jwk_str(jwk: &str) -> Result where C: JwkParameters, - AffinePoint: Default + FromEncodedPoint + ToEncodedPoint, + AffinePoint: FromEncodedPoint + ToEncodedPoint, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -153,7 +150,7 @@ where pub fn to_jwk(&self) -> JwkEcKey where C: JwkParameters, - AffinePoint: Default + FromEncodedPoint + ToEncodedPoint, + AffinePoint: FromEncodedPoint + ToEncodedPoint, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -166,7 +163,7 @@ where pub fn to_jwk_string(&self) -> String where C: JwkParameters, - AffinePoint: Default + FromEncodedPoint + ToEncodedPoint, + AffinePoint: FromEncodedPoint + ToEncodedPoint, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -177,8 +174,6 @@ where impl AsRef> for PublicKey where C: Curve + ProjectiveArithmetic, - AffinePoint: Copy + Clone + Debug, - ProjectivePoint: From>, { fn as_ref(&self) -> &AffinePoint { self.as_affine() @@ -188,8 +183,7 @@ where impl TryFrom> for PublicKey where C: Curve + ProjectiveArithmetic, - AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, - ProjectivePoint: From>, + AffinePoint: FromEncodedPoint + ToEncodedPoint, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -203,8 +197,7 @@ where impl TryFrom<&EncodedPoint> for PublicKey where C: Curve + ProjectiveArithmetic, - AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, - ProjectivePoint: From>, + AffinePoint: FromEncodedPoint + ToEncodedPoint, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -218,8 +211,7 @@ where impl From> for EncodedPoint where C: Curve + ProjectiveArithmetic + PointCompression, - AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, - ProjectivePoint: From>, + AffinePoint: FromEncodedPoint + ToEncodedPoint, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -231,8 +223,7 @@ where impl From<&PublicKey> for EncodedPoint where C: Curve + ProjectiveArithmetic + PointCompression, - AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, - ProjectivePoint: From>, + AffinePoint: FromEncodedPoint + ToEncodedPoint, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -244,8 +235,7 @@ where impl FromEncodedPoint for PublicKey where C: Curve + ProjectiveArithmetic, - AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, - ProjectivePoint: From>, + AffinePoint: FromEncodedPoint + ToEncodedPoint, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -259,8 +249,7 @@ where impl ToEncodedPoint for PublicKey where C: Curve + ProjectiveArithmetic, - AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, - ProjectivePoint: From>, + AffinePoint: FromEncodedPoint + ToEncodedPoint, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -282,8 +271,7 @@ where impl Eq for PublicKey where C: Curve + ProjectiveArithmetic, - AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, - ProjectivePoint: From>, + AffinePoint: FromEncodedPoint + ToEncodedPoint, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -292,8 +280,7 @@ where impl PartialEq for PublicKey where C: Curve + ProjectiveArithmetic, - AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, - ProjectivePoint: From>, + AffinePoint: FromEncodedPoint + ToEncodedPoint, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -305,8 +292,7 @@ where impl PartialOrd for PublicKey where C: Curve + ProjectiveArithmetic, - AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, - ProjectivePoint: From>, + AffinePoint: FromEncodedPoint + ToEncodedPoint, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -318,8 +304,7 @@ where impl Ord for PublicKey where C: Curve + ProjectiveArithmetic, - AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, - ProjectivePoint: From>, + AffinePoint: FromEncodedPoint + ToEncodedPoint, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -337,8 +322,6 @@ impl FromPublicKey for PublicKey where Self: TryFrom, Error = Error>, C: Curve + AlgorithmParameters + ProjectiveArithmetic, - AffinePoint: Copy + Clone + Debug, - ProjectivePoint: From>, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -366,8 +349,7 @@ where impl ToPublicKey for PublicKey where C: Curve + AlgorithmParameters + ProjectiveArithmetic, - AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, - ProjectivePoint: From>, + AffinePoint: FromEncodedPoint + ToEncodedPoint, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -388,8 +370,6 @@ impl FromStr for PublicKey where Self: TryFrom, Error = Error>, C: Curve + AlgorithmParameters + ProjectiveArithmetic, - AffinePoint: Copy + Clone + Debug, - ProjectivePoint: From>, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -405,8 +385,7 @@ where impl ToString for PublicKey where C: Curve + AlgorithmParameters + ProjectiveArithmetic, - AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, - ProjectivePoint: From>, + AffinePoint: FromEncodedPoint + ToEncodedPoint, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { diff --git a/elliptic-curve/src/scalar.rs b/elliptic-curve/src/scalar.rs index 07441823f..c2d5aba50 100644 --- a/elliptic-curve/src/scalar.rs +++ b/elliptic-curve/src/scalar.rs @@ -3,19 +3,11 @@ pub(crate) mod bytes; #[cfg(feature = "arithmetic")] -use crate::{Curve, FieldBytes}; +use crate::ScalarArithmetic; #[cfg(feature = "arithmetic")] pub(crate) mod non_zero; -/// Scalar arithmetic. -#[cfg(feature = "arithmetic")] -#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] -pub trait ScalarArithmetic: Curve { - /// Scalar field type. - type Scalar: ff::Field + ff::PrimeField>; -} - /// Scalar field element for a particular elliptic curve. #[cfg(feature = "arithmetic")] #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index 64290a74b..7d8e481be 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -22,7 +22,7 @@ use crate::{weierstrass::DecompressPoint, AffinePoint, ProjectiveArithmetic}; #[cfg(all(feature = "arithmetic", feature = "zeroize"))] use crate::{ group::{Curve as _, Group}, - ProjectivePoint, Scalar, + Scalar, }; #[cfg(feature = "zeroize")] @@ -164,7 +164,7 @@ where pub fn to_untagged_bytes(&self) -> Option>> where C: Curve + ProjectiveArithmetic, - AffinePoint: ConditionallySelectable + Default + DecompressPoint + ToEncodedPoint, + AffinePoint: DecompressPoint + ToEncodedPoint, { self.decompress().map(|point| { let mut bytes = GenericArray::>::default(); @@ -197,7 +197,7 @@ where pub fn decompress(&self) -> Option where C: Curve + ProjectiveArithmetic, - AffinePoint: ConditionallySelectable + Default + DecompressPoint + ToEncodedPoint, + AffinePoint: DecompressPoint + ToEncodedPoint, { match self.coordinates() { Coordinates::Identity => None, @@ -515,8 +515,7 @@ where impl ValidatePublicKey for C where C: Curve + ProjectiveArithmetic, - AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, - ProjectivePoint: From>, + AffinePoint: FromEncodedPoint + ToEncodedPoint, Scalar: Zeroize, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 6bbb300b9..ebe992f6a 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -20,8 +20,7 @@ use zeroize::Zeroize; #[cfg(feature = "arithmetic")] use crate::{ rand_core::{CryptoRng, RngCore}, - weierstrass, AffinePoint, NonZeroScalar, ProjectiveArithmetic, ProjectivePoint, PublicKey, - Scalar, + weierstrass, NonZeroScalar, ProjectiveArithmetic, PublicKey, Scalar, }; #[cfg(feature = "jwk")] @@ -34,7 +33,10 @@ use crate::{ #[cfg(all(feature = "arithmetic", feature = "jwk"))] use { - crate::sec1::{FromEncodedPoint, ToEncodedPoint}, + crate::{ + sec1::{FromEncodedPoint, ToEncodedPoint}, + AffinePoint, + }, alloc::string::{String, ToString}, }; @@ -140,8 +142,6 @@ where pub fn public_key(&self) -> PublicKey where C: weierstrass::Curve + ProjectiveArithmetic, - AffinePoint: Copy + Clone + Debug + Default, - ProjectivePoint: From>, Scalar: Zeroize, { PublicKey::from_secret_scalar(&self.to_secret_scalar()) @@ -178,8 +178,7 @@ where pub fn to_jwk(&self) -> JwkEcKey where C: JwkParameters + ProjectiveArithmetic, - AffinePoint: Copy + Debug + Default + FromEncodedPoint + ToEncodedPoint, - ProjectivePoint: From>, + AffinePoint: FromEncodedPoint + ToEncodedPoint, Scalar: Zeroize, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, @@ -194,8 +193,7 @@ where pub fn to_jwk_string(&self) -> String where C: JwkParameters + ProjectiveArithmetic, - AffinePoint: Copy + Debug + Default + FromEncodedPoint + ToEncodedPoint, - ProjectivePoint: From>, + AffinePoint: FromEncodedPoint + ToEncodedPoint, Scalar: Zeroize, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs index 0e8b66120..e6e044eb7 100644 --- a/elliptic-curve/src/secret_key/pkcs8.rs +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -24,9 +24,9 @@ use { crate::{ scalar::Scalar, sec1::{FromEncodedPoint, ToEncodedPoint}, - AffinePoint, ProjectiveArithmetic, ProjectivePoint, + AffinePoint, ProjectiveArithmetic, }, - core::{convert::TryInto, fmt::Debug}, + core::convert::TryInto, pkcs8::{der::Encodable, ToPrivateKey}, zeroize::Zeroizing, }; @@ -95,8 +95,7 @@ where impl ToPrivateKey for SecretKey where C: weierstrass::Curve + AlgorithmParameters + ProjectiveArithmetic, - AffinePoint: Copy + Clone + Debug + Default + FromEncodedPoint + ToEncodedPoint, - ProjectivePoint: From>, + AffinePoint: FromEncodedPoint + ToEncodedPoint, Scalar: Zeroize, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, From 5708e791d43b9597abf90f75a55761a8b80a79d3 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 7 Jun 2021 17:06:02 -0700 Subject: [PATCH 0530/1461] Add compact to sec1 (#659) Co-authored-by: Rahul Garg --- elliptic-curve/src/sec1.rs | 64 +++++++++++++++++++++++++------ elliptic-curve/src/weierstrass.rs | 12 ++++++ 2 files changed, 65 insertions(+), 11 deletions(-) diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index 7d8e481be..f24cfdc35 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -173,9 +173,9 @@ where }) } - /// Is this [`EncodedPoint`] the additive identity? (a.k.a. point at infinity) - pub fn is_identity(&self) -> bool { - self.tag().is_identity() + /// Is this [`EncodedPoint`] compact? + pub fn is_compact(&self) -> bool { + self.tag().is_compact() } /// Is this [`EncodedPoint`] compressed? @@ -183,10 +183,17 @@ where self.tag().is_compressed() } + /// Is this [`EncodedPoint`] the additive identity? (a.k.a. point at infinity) + pub fn is_identity(&self) -> bool { + self.tag().is_identity() + } + /// Compress this [`EncodedPoint`], returning a new [`EncodedPoint`]. pub fn compress(&self) -> Self { match self.coordinates() { - Coordinates::Identity | Coordinates::Compressed { .. } => self.clone(), + Coordinates::Compressed { .. } + | Coordinates::Compact { .. } + | Coordinates::Identity => self.clone(), Coordinates::Uncompressed { x, y } => Self::from_affine_coordinates(x, y, true), } } @@ -200,12 +207,12 @@ where AffinePoint: DecompressPoint + ToEncodedPoint, { match self.coordinates() { - Coordinates::Identity => None, Coordinates::Compressed { x, y_is_odd } => { AffinePoint::::decompress(x, Choice::from(y_is_odd as u8)) .map(|s| s.to_encoded_point(false)) .into() } + Coordinates::Compact { .. } | Coordinates::Identity => None, Coordinates::Uncompressed { .. } => Some(self.clone()), } } @@ -246,6 +253,8 @@ where x: x.into(), y_is_odd: self.tag() as u8 & 1 == 1, } + } else if self.is_compact() { + Coordinates::Compact { x: x.into() } } else { Coordinates::Uncompressed { x: x.into(), @@ -262,6 +271,7 @@ where Coordinates::Identity => None, Coordinates::Compressed { x, .. } => Some(x), Coordinates::Uncompressed { x, .. } => Some(x), + Coordinates::Compact { x } => Some(x), } } @@ -272,6 +282,7 @@ where match self.coordinates() { Coordinates::Compressed { .. } | Coordinates::Identity => None, Coordinates::Uncompressed { y, .. } => Some(y), + Coordinates::Compact { .. } => None, } } } @@ -345,6 +356,12 @@ pub enum Coordinates<'a, C: Curve> { /// Identity point (a.k.a. point at infinity) Identity, + /// Compact curve point + Compact { + /// x-coordinate + x: &'a FieldBytes, + }, + /// Compressed curve point Compressed { /// x-coordinate @@ -365,10 +382,10 @@ pub enum Coordinates<'a, C: Curve> { } impl<'a, C: Curve> Coordinates<'a, C> { - /// Get the tag value needed to encode this set of [`Coordinates`] + /// Get the tag octet needed to encode this set of [`Coordinates`] pub fn tag(&self) -> Tag { match self { - Coordinates::Identity => Tag::Identity, + Coordinates::Compact { .. } => Tag::Compact, Coordinates::Compressed { y_is_odd, .. } => { if *y_is_odd { Tag::CompressedOddY @@ -376,6 +393,7 @@ impl<'a, C: Curve> Coordinates<'a, C> { Tag::CompressedEvenY } } + Coordinates::Identity => Tag::Identity, Coordinates::Uncompressed { .. } => Tag::Uncompressed, } } @@ -396,6 +414,9 @@ pub enum Tag { /// Uncompressed point (`0x04`) Uncompressed = 4, + + /// Compact point (`0x05`) + Compact = 5, } impl Tag { @@ -406,13 +427,14 @@ impl Tag { 2 => Ok(Tag::CompressedEvenY), 3 => Ok(Tag::CompressedOddY), 4 => Ok(Tag::Uncompressed), + 5 => Ok(Tag::Compact), _ => Err(Error), } } - /// Is this point the identity point? - pub fn is_identity(self) -> bool { - self == Tag::Identity + /// Is this point compact? + pub fn is_compact(self) -> bool { + matches!(self, Tag::Compact) } /// Is this point compressed? @@ -420,6 +442,11 @@ impl Tag { matches!(self, Tag::CompressedEvenY | Tag::CompressedOddY) } + /// Is this point the identity point? + pub fn is_identity(self) -> bool { + self == Tag::Identity + } + /// Compute the expected total message length for a message prefixed /// with this tag (including the tag byte), given the field element size /// (in bytes) for a particular elliptic curve. @@ -428,6 +455,7 @@ impl Tag { Tag::Identity => 0, Tag::CompressedEvenY | Tag::CompressedOddY => field_element_size, Tag::Uncompressed => field_element_size * 2, + Tag::Compact => field_element_size, } } @@ -480,6 +508,20 @@ where fn to_encoded_point(&self, compress: bool) -> EncodedPoint; } +/// Trait for serializing a value to a SEC1 encoded curve point with compaction. +/// +/// This is intended for use with the `AffinePoint` type for a given elliptic curve. +pub trait ToCompactEncodedPoint +where + C: Curve, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + /// Serialize this value as a SEC1 [`EncodedPoint`], optionally applying + /// point compression. + fn to_compact_encoded_point(&self) -> Option>; +} + /// Validate that the given [`EncodedPoint`] represents the encoded public key /// value of the given secret. /// @@ -653,7 +695,7 @@ mod tests { for bytes in &mut [&mut compressed_bytes[..], &mut uncompressed_bytes[..]] { for tag in 0..=0xFF { // valid tags - if tag == 2 || tag == 3 || tag == 4 { + if tag == 2 || tag == 3 || tag == 4 || tag == 5 { continue; } diff --git a/elliptic-curve/src/weierstrass.rs b/elliptic-curve/src/weierstrass.rs index b998ea1e2..e6c1c0ace 100644 --- a/elliptic-curve/src/weierstrass.rs +++ b/elliptic-curve/src/weierstrass.rs @@ -12,9 +12,21 @@ pub trait PointCompression { const COMPRESS_POINTS: bool; } +/// Point compaction settings +pub trait PointCompaction { + /// Should point compaction be applied by default? + const COMPACT_POINTS: bool; +} + /// Attempt to decompress an elliptic curve point from its x-coordinate and /// a boolean flag indicating whether or not the y-coordinate is odd. pub trait DecompressPoint: Sized { /// Attempt to decompress an elliptic curve point. fn decompress(x: &FieldBytes, y_is_odd: Choice) -> CtOption; } + +/// Attempt to decompact an elliptic curve point from an x-coordinate +pub trait DecompactPoint: Sized { + /// Attempt to decompact an elliptic curve point + fn decompact(x: &FieldBytes) -> CtOption; +} From 23fb60e731179833bf8b0da51dbc51bbd5531dc7 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 7 Jun 2021 17:22:09 -0700 Subject: [PATCH 0531/1461] elliptic-curve: bump `crypto-bigint` to v0.2.0-pre (#660) --- Cargo.lock | 14 +++++++------- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/dev.rs | 4 ++-- elliptic-curve/src/lib.rs | 9 ++++----- elliptic-curve/src/scalar/bytes.rs | 6 +++--- elliptic-curve/src/scalar/non_zero.rs | 4 ++-- elliptic-curve/src/sec1.rs | 15 +++++++-------- 7 files changed, 26 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 47c0f79cb..1dd994c5d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -56,7 +56,7 @@ checksum = "d0d27fb6b6f1e43147af148af49d49329413ba781aa0d5e10979831c210173b5" [[package]] name = "base64ct" version = "1.0.0" -source = "git+https://github.com/rustcrypto/utils.git#3fc828a86a31b2b5016dd64e4f3b38a858f9d070" +source = "git+https://github.com/rustcrypto/utils.git#dd17922cba2798f9a002850acf455cf2d6215483" [[package]] name = "bitfield" @@ -145,7 +145,7 @@ dependencies = [ [[package]] name = "const-oid" version = "0.6.0" -source = "git+https://github.com/rustcrypto/utils.git#3fc828a86a31b2b5016dd64e4f3b38a858f9d070" +source = "git+https://github.com/rustcrypto/utils.git#dd17922cba2798f9a002850acf455cf2d6215483" [[package]] name = "cortex-m" @@ -184,8 +184,8 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.1.0" -source = "git+https://github.com/rustcrypto/utils.git#3fc828a86a31b2b5016dd64e4f3b38a858f9d070" +version = "0.2.0-pre" +source = "git+https://github.com/rustcrypto/utils.git#dd17922cba2798f9a002850acf455cf2d6215483" dependencies = [ "generic-array", "subtle", @@ -224,7 +224,7 @@ dependencies = [ [[package]] name = "der" version = "0.4.0-pre" -source = "git+https://github.com/rustcrypto/utils.git#3fc828a86a31b2b5016dd64e4f3b38a858f9d070" +source = "git+https://github.com/rustcrypto/utils.git#dd17922cba2798f9a002850acf455cf2d6215483" dependencies = [ "const-oid", ] @@ -403,7 +403,7 @@ dependencies = [ [[package]] name = "pkcs8" version = "0.7.0-pre" -source = "git+https://github.com/rustcrypto/utils.git#3fc828a86a31b2b5016dd64e4f3b38a858f9d070" +source = "git+https://github.com/rustcrypto/utils.git#dd17922cba2798f9a002850acf455cf2d6215483" dependencies = [ "base64ct 1.0.0 (git+https://github.com/rustcrypto/utils.git)", "der", @@ -531,7 +531,7 @@ dependencies = [ [[package]] name = "spki" version = "0.4.0-pre" -source = "git+https://github.com/rustcrypto/utils.git#3fc828a86a31b2b5016dd64e4f3b38a858f9d070" +source = "git+https://github.com/rustcrypto/utils.git#dd17922cba2798f9a002850acf455cf2d6215483" dependencies = [ "der", ] diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 8f8af178b..a1f498fb2 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -15,7 +15,7 @@ categories = ["cryptography", "no-std"] keywords = ["crypto", "ecc", "elliptic", "weierstrass"] [dependencies] -crypto-bigint = { version = "0.1", features = ["generic-array"] } +crypto-bigint = { version = "=0.2.0-pre", features = ["generic-array"] } generic-array = { version = "0.14", default-features = false } rand_core = { version = "0.6", default-features = false } subtle = { version = "2.4", default-features = false } diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 1c02ac59b..b4a955133 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -2,7 +2,7 @@ //! against concrete implementations of the traits in this crate. use crate::{ - bigint::{ArrayEncoding, U256}, + bigint::{ArrayEncoding as _, U256}, error::{Error, Result}, rand_core::RngCore, sec1::{FromEncodedPoint, ToEncodedPoint}, @@ -135,7 +135,7 @@ impl PrimeField for Scalar { const S: u32 = 4; fn from_repr(bytes: FieldBytes) -> Option { - U256::from_be_bytes(&bytes).try_into().ok() + U256::from_be_byte_array(bytes).try_into().ok() } fn to_repr(&self) -> FieldBytes { diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index cd1f1e06f..748a27250 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -57,7 +57,7 @@ pub use self::{ error::{Error, Result}, scalar::bytes::ScalarBytes, }; -pub use crypto_bigint::{self as bigint, ArrayEncoding, NumBits, NumBytes}; +pub use crypto_bigint as bigint; pub use generic_array::{self, typenum::consts}; pub use rand_core; pub use subtle; @@ -111,12 +111,11 @@ pub const ALGORITHM_OID: pkcs8::ObjectIdentifier = pub trait Curve: Clone + Debug + Default + Eq + Ord + Send + Sync { /// Integer type used to represent field elements of this elliptic curve. type UInt: AsRef<[bigint::Limb]> - + ArrayEncoding + + bigint::ArrayEncoding + + bigint::Encoding + Copy + Debug + Default - + NumBits - + NumBytes + ConstantTimeEq + ConstantTimeGreater + ConstantTimeLess; @@ -129,7 +128,7 @@ pub trait Curve: Clone + Debug + Default + Eq + Ord + Send + Sync { } /// Size of field elements of this elliptic curve. -pub type FieldSize = <::UInt as ArrayEncoding>::ByteSize; +pub type FieldSize = <::UInt as bigint::ArrayEncoding>::ByteSize; /// Byte representation of a base/scalar field element of a given curve. pub type FieldBytes = GenericArray>; diff --git a/elliptic-curve/src/scalar/bytes.rs b/elliptic-curve/src/scalar/bytes.rs index abcff856d..3d264603f 100644 --- a/elliptic-curve/src/scalar/bytes.rs +++ b/elliptic-curve/src/scalar/bytes.rs @@ -1,7 +1,7 @@ //! Scalar bytes. use crate::{ - bigint::{ArrayEncoding, NumBytes}, + bigint::{ArrayEncoding as _, Encoding as _}, Curve, Error, FieldBytes, Result, }; use core::convert::TryFrom; @@ -31,7 +31,7 @@ where /// Create new [`ScalarBytes`], checking that the given input is within /// range of the [`Curve::ORDER`]. pub fn new(bytes: FieldBytes) -> CtOption { - Self::from_uint(&C::UInt::from_be_byte_array(&bytes)) + Self::from_uint(&C::UInt::from_be_byte_array(bytes)) } /// Create [`ScalarBytes`] from the provided `C::UInt`. @@ -226,7 +226,7 @@ where type Error = Error; fn try_from(bytes: &[u8]) -> Result { - if bytes.len() == C::UInt::NUM_BYTES { + if bytes.len() == C::UInt::BYTE_SIZE { Option::from(ScalarBytes::new(GenericArray::clone_from_slice(bytes))).ok_or(Error) } else { Err(Error) diff --git a/elliptic-curve/src/scalar/non_zero.rs b/elliptic-curve/src/scalar/non_zero.rs index 7b42ec9b5..8a35b40d4 100644 --- a/elliptic-curve/src/scalar/non_zero.rs +++ b/elliptic-curve/src/scalar/non_zero.rs @@ -1,7 +1,7 @@ //! Non-zero scalar type. use crate::{ - bigint::NumBytes, + bigint::Encoding as _, ops::Invert, rand_core::{CryptoRng, RngCore}, Curve, Error, FieldBytes, ProjectiveArithmetic, Result, Scalar, @@ -155,7 +155,7 @@ where type Error = Error; fn try_from(bytes: &[u8]) -> Result { - if bytes.len() == C::UInt::NUM_BYTES { + if bytes.len() == C::UInt::BYTE_SIZE { NonZeroScalar::from_repr(GenericArray::clone_from_slice(bytes)).ok_or(Error) } else { Err(Error) diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index f24cfdc35..00621dff7 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -5,7 +5,7 @@ //! //! -use crate::{bigint::NumBytes, weierstrass::Curve, Error, FieldBytes, FieldSize, Result}; +use crate::{bigint::Encoding as _, weierstrass::Curve, Error, FieldBytes, FieldSize, Result}; use core::{ fmt::{self, Debug}, ops::Add, @@ -76,7 +76,7 @@ where let tag = input.first().cloned().ok_or(Error).and_then(Tag::from_u8)?; // Validate length - let expected_len = tag.message_len(C::UInt::NUM_BYTES); + let expected_len = tag.message_len(C::UInt::BYTE_SIZE); if input.len() != expected_len { return Err(Error); @@ -91,7 +91,7 @@ where /// encoded as the concatenated `x || y` coordinates with no leading SEC1 /// tag byte (which would otherwise be `0x04` for an uncompressed point). pub fn from_untagged_bytes(bytes: &GenericArray>) -> Self { - let (x, y) = bytes.split_at(C::UInt::NUM_BYTES); + let (x, y) = bytes.split_at(C::UInt::BYTE_SIZE); Self::from_affine_coordinates(x.into(), y.into(), false) } @@ -106,11 +106,10 @@ where let mut bytes = GenericArray::default(); bytes[0] = tag.into(); - - bytes[1..(C::UInt::NUM_BYTES + 1)].copy_from_slice(x); + bytes[1..(C::UInt::BYTE_SIZE + 1)].copy_from_slice(x); if !compress { - bytes[(C::UInt::NUM_BYTES + 1)..].copy_from_slice(y); + bytes[(C::UInt::BYTE_SIZE + 1)..].copy_from_slice(y); } Self { bytes } @@ -142,7 +141,7 @@ where /// Get the length of the encoded point in bytes pub fn len(&self) -> usize { - self.tag().message_len(C::UInt::NUM_BYTES) + self.tag().message_len(C::UInt::BYTE_SIZE) } /// Get byte slice containing the serialized [`EncodedPoint`]. @@ -246,7 +245,7 @@ where return Coordinates::Identity; } - let (x, y) = self.bytes[1..].split_at(C::UInt::NUM_BYTES); + let (x, y) = self.bytes[1..].split_at(C::UInt::BYTE_SIZE); if self.is_compressed() { Coordinates::Compressed { From 2470bef665cc8d340576c59850224f589b140277 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 7 Jun 2021 18:14:09 -0700 Subject: [PATCH 0532/1461] elliptic-curve: add TODO for replacing UInt with an associated constant (#661) Ideally instead of specifying a `Curve::UInt` associated type, we could instead specify a constant, and then pass that as a const generic parameter to `crypto_bigint::UInt`. Unfortunately that requires a lot more functionality than is implemented in `min_const_generics`: https://github.com/rust-lang/rust/issues/60551 This commit makes a note of as much in the comments, calling it out as future work. --- elliptic-curve/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 748a27250..74b75add6 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -110,6 +110,8 @@ pub const ALGORITHM_OID: pkcs8::ObjectIdentifier = /// curves (e.g. [`SecretKey`]). pub trait Curve: Clone + Debug + Default + Eq + Ord + Send + Sync { /// Integer type used to represent field elements of this elliptic curve. + // TODO(tarcieri): replace this with an e.g. `const Curve::MODULUS: uint`. + // Requires rust-lang/rust#60551, i.e. `const_evaluatable_checked` type UInt: AsRef<[bigint::Limb]> + bigint::ArrayEncoding + bigint::Encoding From 06a7765602b21ae74db0be6312398cf5b323aa8f Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 7 Jun 2021 19:54:14 -0700 Subject: [PATCH 0533/1461] elliptic-curve: bump `crypto-bitint` to v0.2; `pkcs8` to v0.7 (#662) --- Cargo.lock | 34 +++++++++++++++++----------------- Cargo.toml | 4 ---- elliptic-curve/Cargo.toml | 4 ++-- 3 files changed, 19 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1dd994c5d..b382db993 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -53,11 +53,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0d27fb6b6f1e43147af148af49d49329413ba781aa0d5e10979831c210173b5" -[[package]] -name = "base64ct" -version = "1.0.0" -source = "git+https://github.com/rustcrypto/utils.git#dd17922cba2798f9a002850acf455cf2d6215483" - [[package]] name = "bitfield" version = "0.13.2" @@ -145,7 +140,8 @@ dependencies = [ [[package]] name = "const-oid" version = "0.6.0" -source = "git+https://github.com/rustcrypto/utils.git#dd17922cba2798f9a002850acf455cf2d6215483" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c32f031ea41b4291d695026c023b95d59db2d8a2c7640800ed56bc8f510f22" [[package]] name = "cortex-m" @@ -184,8 +180,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.2.0-pre" -source = "git+https://github.com/rustcrypto/utils.git#dd17922cba2798f9a002850acf455cf2d6215483" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "281d926f72b42bf3ba840b88cd53e39f36be9f66e34c8df3fb336372b3753d41" dependencies = [ "generic-array", "subtle", @@ -223,8 +220,9 @@ dependencies = [ [[package]] name = "der" -version = "0.4.0-pre" -source = "git+https://github.com/rustcrypto/utils.git#dd17922cba2798f9a002850acf455cf2d6215483" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f215f706081a44cb702c71c39a52c05da637822e9c1645a50b7202689e982d" dependencies = [ "const-oid", ] @@ -251,7 +249,7 @@ dependencies = [ name = "elliptic-curve" version = "0.10.0-pre" dependencies = [ - "base64ct 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "base64ct", "crypto-bigint", "ff", "generic-array", @@ -395,17 +393,18 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" name = "password-hash" version = "0.2.1" dependencies = [ - "base64ct 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "base64ct", "rand_core", "subtle", ] [[package]] name = "pkcs8" -version = "0.7.0-pre" -source = "git+https://github.com/rustcrypto/utils.git#dd17922cba2798f9a002850acf455cf2d6215483" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09d156817ae0125e8aa5067710b0db24f0984830614f99875a70aa5e3b74db69" dependencies = [ - "base64ct 1.0.0 (git+https://github.com/rustcrypto/utils.git)", + "base64ct", "der", "spki", "zeroize", @@ -530,8 +529,9 @@ dependencies = [ [[package]] name = "spki" -version = "0.4.0-pre" -source = "git+https://github.com/rustcrypto/utils.git#dd17922cba2798f9a002850acf455cf2d6215483" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "987637c5ae6b3121aba9d513f869bd2bff11c4cc086c22473befd6649c0bd521" dependencies = [ "der", ] diff --git a/Cargo.toml b/Cargo.toml index 3febe0478..ebf9e0985 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,3 @@ members = [ "signature/async", "universal-hash", ] - -[patch.crates-io] -crypto-bigint = { git = "https://github.com/rustcrypto/utils.git" } -pkcs8 = { git = "https://github.com/rustcrypto/utils.git" } diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index a1f498fb2..dfc8a8f3e 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -15,7 +15,7 @@ categories = ["cryptography", "no-std"] keywords = ["crypto", "ecc", "elliptic", "weierstrass"] [dependencies] -crypto-bigint = { version = "=0.2.0-pre", features = ["generic-array"] } +crypto-bigint = { version = "0.2", features = ["generic-array"] } generic-array = { version = "0.14", default-features = false } rand_core = { version = "0.6", default-features = false } subtle = { version = "2.4", default-features = false } @@ -25,7 +25,7 @@ base64ct = { version = "1", optional = true, default-features = false } ff = { version = "0.10", optional = true, default-features = false } group = { version = "0.10", optional = true, default-features = false } hex-literal = { version = "0.3", optional = true } -pkcs8 = { version = "=0.7.0-pre", optional = true } +pkcs8 = { version = "0.7", optional = true } serde = { version = "1", optional = true, default-features = false } serde_json = { version = "1", optional = true, default-features = false, features = ["alloc"] } zeroize = { version = "1", optional = true, default-features = false } From 542fcb6f32bbb22d8933e5623fe1da55fb18df83 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 7 Jun 2021 20:16:59 -0700 Subject: [PATCH 0534/1461] elliptic-curve v0.10.0 (#663) --- Cargo.lock | 2 +- crypto/Cargo.toml | 2 +- elliptic-curve/CHANGELOG.md | 35 +++++++++++++++++++++++++++++++++++ elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 2 +- 5 files changed, 39 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b382db993..a86e1c4be 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -247,7 +247,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.10.0-pre" +version = "0.10.0" dependencies = [ "base64ct", "crypto-bigint", diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 87a00c180..1eba6c985 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -17,7 +17,7 @@ edition = "2018" aead = { version = "0.4", optional = true, path = "../aead" } cipher = { version = "0.3", optional = true } digest = { version = "0.9", optional = true } -elliptic-curve = { version = "=0.10.0-pre", optional = true, path = "../elliptic-curve" } +elliptic-curve = { version = "0.10", optional = true, path = "../elliptic-curve" } mac = { version = "0.11", package = "crypto-mac", optional = true } password-hash = { version = "0.2", optional = true, path = "../password-hash" } signature = { version = "1.2.0", optional = true, default-features = false, path = "../signature" } diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index cbcc46332..2edc1ddfc 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,41 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.10.0 (2021-06-07) +### Added +- `ScalarBytes::from_uint` ([#651]) +- `dev::ScalarBytes` ([#652]) +- `ScalarArithmetic` trait ([#654]) +- `AffineArithmetic` trait ([#658]) +- `PointCompaction` trait and SEC1 tag support ([#659]) + +### Changed +- Bump `ff` and `group` to v0.10; MSRV 1.51+ ([#643]) +- Merge `Curve` and `Order` traits ([#644]) +- Use `crypto-bigint` to represent `Curve::ORDER` ([#645]) +- Source `FieldSize` from `C::UInt` type ([#646]) +- Impl `ScalarBytes` using `C::UInt` ([#647]) +- Make `ScalarBytes` the `SecretKey` internal repr ([#649]) +- Bump `crypto-bigint` to v0.2 ([#662]) +- Bump `pkcs8` to v0.7 ([#662]) + +### Removed +- `util` module ([#648]) + +[#643]: https://github.com/RustCrypto/traits/pull/643 +[#644]: https://github.com/RustCrypto/traits/pull/644 +[#645]: https://github.com/RustCrypto/traits/pull/645 +[#646]: https://github.com/RustCrypto/traits/pull/646 +[#647]: https://github.com/RustCrypto/traits/pull/647 +[#648]: https://github.com/RustCrypto/traits/pull/648 +[#649]: https://github.com/RustCrypto/traits/pull/649 +[#651]: https://github.com/RustCrypto/traits/pull/651 +[#652]: https://github.com/RustCrypto/traits/pull/652 +[#654]: https://github.com/RustCrypto/traits/pull/654 +[#658]: https://github.com/RustCrypto/traits/pull/658 +[#659]: https://github.com/RustCrypto/traits/pull/659 +[#662]: https://github.com/RustCrypto/traits/pull/662 + ## 0.9.12 (2021-05-18) ### Added - `Ord` and `PartialOrd` impls on `PublicKey` ([#637]) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index dfc8a8f3e..6a62de8c1 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -5,7 +5,7 @@ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. """ -version = "0.10.0-pre" # Also update html_root_url in lib.rs when bumping this +version = "0.10.0" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" repository = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve" diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 74b75add6..e4cbf25cb 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -16,7 +16,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.9.12" + html_root_url = "https://docs.rs/elliptic-curve/0.10.0" )] #[cfg(feature = "alloc")] From 424e135b753862c2e2a0a99a2d1e78d2b37ad2ec Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 8 Jun 2021 11:37:59 -0700 Subject: [PATCH 0535/1461] crypto: bump `signature` crate dependency to v1.3.0 (#664) --- crypto/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 1eba6c985..ed8e636b3 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -20,7 +20,7 @@ digest = { version = "0.9", optional = true } elliptic-curve = { version = "0.10", optional = true, path = "../elliptic-curve" } mac = { version = "0.11", package = "crypto-mac", optional = true } password-hash = { version = "0.2", optional = true, path = "../password-hash" } -signature = { version = "1.2.0", optional = true, default-features = false, path = "../signature" } +signature = { version = "1.3.0", optional = true, default-features = false, path = "../signature" } universal-hash = { version = "0.4", optional = true, path = "../universal-hash" } [features] From 7b9a41619382d1cb3430fdd4be13eb6f70369b50 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 8 Jun 2021 11:51:29 -0700 Subject: [PATCH 0536/1461] crypto v0.3.0 (#665) --- Cargo.lock | 2 +- crypto/CHANGELOG.md | 8 ++++++++ crypto/Cargo.toml | 2 +- crypto/src/lib.rs | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a86e1c4be..ed830a13d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -166,7 +166,7 @@ dependencies = [ [[package]] name = "crypto" -version = "0.2.0" +version = "0.3.0" dependencies = [ "aead", "cipher 0.3.0", diff --git a/crypto/CHANGELOG.md b/crypto/CHANGELOG.md index 986d0470c..e004b7865 100644 --- a/crypto/CHANGELOG.md +++ b/crypto/CHANGELOG.md @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.3.0 (2021-06-08) +### Changed +- Bump `elliptic-curve` crate dependency to v0.10 ([#663]) +- Bump `signature` crate dependency to v1.3.0 ([#664]) + +[#663]: https://github.com/RustCrypto/traits/pull/663 +[#664]: https://github.com/RustCrypto/traits/pull/664 + ## 0.2.0 (2021-04-29) - Initial (re-)release of the `cryptography` crate as `crypto` diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index ed8e636b3..fbe9fc58c 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "crypto" -version = "0.2.0" # Also update html_root_url in lib.rs when bumping this +version = "0.3.0" # Also update html_root_url in lib.rs when bumping this description = """ Resources for building cryptosystems in Rust using the RustCrypto project's ecosystem. """ diff --git a/crypto/src/lib.rs b/crypto/src/lib.rs index 8eaa150be..0dc4ea083 100644 --- a/crypto/src/lib.rs +++ b/crypto/src/lib.rs @@ -39,7 +39,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/crypto/0.2.0" + html_root_url = "https://docs.rs/crypto/0.3.0" )] #![forbid(unsafe_code)] #![warn(rust_2018_idioms)] From 7d4e9162e6879a0325db23f636c22f072c302041 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 9 Jun 2021 13:20:35 -0700 Subject: [PATCH 0537/1461] elliptic-curve: derive `Copy` on `PublicKey` (#666) The new trait bounds on `AffineArithmetic` ensure that `AffinePoint` is always `Copy`. So the previously imposed trait bounds prevent `Copy` impls which should be available by default. --- elliptic-curve/src/public_key.rs | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index 85c6581c2..281dcf902 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -59,7 +59,7 @@ use alloc::string::{String, ToString}; /// When the `pem` feature of this crate (or a specific RustCrypto elliptic /// curve crate) is enabled, a [`FromStr`] impl is also available. #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] -#[derive(Clone, Debug)] +#[derive(Copy, Clone, Debug)] pub struct PublicKey where C: Curve + ProjectiveArithmetic, @@ -260,14 +260,6 @@ where } } -impl Copy for PublicKey -where - C: Curve + ProjectiveArithmetic, - - AffinePoint: Copy + Clone + Debug, -{ -} - impl Eq for PublicKey where C: Curve + ProjectiveArithmetic, From 9831d28e8f6e90ecec2ed512ef4e9ba1c35efb3d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 9 Jun 2021 13:48:33 -0700 Subject: [PATCH 0538/1461] elliptic-cure: add explicit `Copy` bounds on public key (#667) The derived `Copy` impl appears to be adding additional undesired trait bounds. This explicit impl ensures it's always available. --- elliptic-curve/src/public_key.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index 281dcf902..5fff558b5 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -59,7 +59,7 @@ use alloc::string::{String, ToString}; /// When the `pem` feature of this crate (or a specific RustCrypto elliptic /// curve crate) is enabled, a [`FromStr`] impl is also available. #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] -#[derive(Copy, Clone, Debug)] +#[derive(Clone, Debug)] pub struct PublicKey where C: Curve + ProjectiveArithmetic, @@ -180,6 +180,8 @@ where } } +impl Copy for PublicKey where C: Curve + ProjectiveArithmetic {} + impl TryFrom> for PublicKey where C: Curve + ProjectiveArithmetic, From 8502ce442ab912925aac4143ccc5d08bf5d939aa Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 9 Jun 2021 14:10:37 -0700 Subject: [PATCH 0539/1461] elliptic-curve v0.10.1 (#668) --- Cargo.lock | 2 +- elliptic-curve/CHANGELOG.md | 6 ++++++ elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ed830a13d..e6d025237 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -247,7 +247,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.10.0" +version = "0.10.1" dependencies = [ "base64ct", "crypto-bigint", diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index 2edc1ddfc..104bb2df3 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.10.1 (2021-06-09) +### Added +- Explicit `Copy` bounds on `PublicKey` ([#667]) + +[#667]: https://github.com/RustCrypto/traits/pull/667 + ## 0.10.0 (2021-06-07) ### Added - `ScalarBytes::from_uint` ([#651]) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 6a62de8c1..c41885f97 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -5,7 +5,7 @@ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. """ -version = "0.10.0" # Also update html_root_url in lib.rs when bumping this +version = "0.10.1" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" repository = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve" diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index e4cbf25cb..f111a5bc8 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -16,7 +16,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.10.0" + html_root_url = "https://docs.rs/elliptic-curve/0.10.1" )] #[cfg(feature = "alloc")] From d95413b749f0d82252ebd2fb547ccbd2a17e204f Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 14 Jun 2021 10:23:51 -0700 Subject: [PATCH 0540/1461] elliptic-curve: impl `ConstantTimeEq` for `NonZeroScalar` (#669) --- elliptic-curve/src/scalar/non_zero.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/elliptic-curve/src/scalar/non_zero.rs b/elliptic-curve/src/scalar/non_zero.rs index 8a35b40d4..33f33c15f 100644 --- a/elliptic-curve/src/scalar/non_zero.rs +++ b/elliptic-curve/src/scalar/non_zero.rs @@ -1,4 +1,5 @@ //! Non-zero scalar type. +// TODO(tarcieri): change bounds to `ScalarArithmetic` instead of `ProjectiveArithmetic` use crate::{ bigint::Encoding as _, @@ -9,7 +10,7 @@ use crate::{ use core::{convert::TryFrom, ops::Deref}; use ff::{Field, PrimeField}; use generic_array::GenericArray; -use subtle::{Choice, ConditionallySelectable, CtOption}; +use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; #[cfg(feature = "zeroize")] use {crate::SecretKey, zeroize::Zeroize}; @@ -45,7 +46,7 @@ where } } - /// Decode a [`NonZeroScalar] from a serialized field element + /// Decode a [`NonZeroScalar`] from a serialized field element pub fn from_repr(repr: FieldBytes) -> Option { Scalar::::from_repr(repr).and_then(Self::new) } @@ -81,6 +82,15 @@ where } } +impl ConstantTimeEq for NonZeroScalar +where + C: Curve + ProjectiveArithmetic, +{ + fn ct_eq(&self, other: &Self) -> Choice { + self.scalar.ct_eq(&other.scalar) + } +} + impl Copy for NonZeroScalar where C: Curve + ProjectiveArithmetic {} impl Deref for NonZeroScalar From 81d1341134c3caf5e0b2d8f25688d9fd3a788e4e Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 14 Jun 2021 10:37:28 -0700 Subject: [PATCH 0541/1461] elliptic-curve v0.10.2 (#670) --- Cargo.lock | 2 +- elliptic-curve/CHANGELOG.md | 6 ++++++ elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e6d025237..118e6daad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -247,7 +247,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.10.1" +version = "0.10.2" dependencies = [ "base64ct", "crypto-bigint", diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index 104bb2df3..01fba2e08 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.10.2 (2021-06-14) +### Added +- `ConstantTimeEq` impl for `NonZeroScalar` ([#669]) + +[#669]: https://github.com/RustCrypto/traits/pull/669 + ## 0.10.1 (2021-06-09) ### Added - Explicit `Copy` bounds on `PublicKey` ([#667]) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index c41885f97..a15dfa163 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -5,7 +5,7 @@ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. """ -version = "0.10.1" # Also update html_root_url in lib.rs when bumping this +version = "0.10.2" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" repository = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve" diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index f111a5bc8..659a77365 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -16,7 +16,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.10.1" + html_root_url = "https://docs.rs/elliptic-curve/0.10.2" )] #[cfg(feature = "alloc")] From c8369abcef85f031f7efef99ae38e89d0952f539 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 21 Jun 2021 23:00:40 -0700 Subject: [PATCH 0542/1461] elliptic-curve: bump `crypto-bigint` to v0.2.1 (#673) --- Cargo.lock | 7 +++++-- elliptic-curve/Cargo.toml | 6 +++--- elliptic-curve/src/dev.rs | 25 ++++++++++++++++++++----- 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 118e6daad..b50a7255a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,7 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "aead" version = "0.4.1" @@ -180,12 +182,13 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "281d926f72b42bf3ba840b88cd53e39f36be9f66e34c8df3fb336372b3753d41" +checksum = "bdc9968be9247fb330af911b91a58a267cbbcfcb8dea88debaf977738950dce5" dependencies = [ "generic-array", "subtle", + "zeroize", ] [[package]] diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index a15dfa163..a4988ce04 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -15,7 +15,7 @@ categories = ["cryptography", "no-std"] keywords = ["crypto", "ecc", "elliptic", "weierstrass"] [dependencies] -crypto-bigint = { version = "0.2", features = ["generic-array"] } +crypto-bigint = { version = "0.2.1", features = ["generic-array"] } generic-array = { version = "0.14", default-features = false } rand_core = { version = "0.6", default-features = false } subtle = { version = "2.4", default-features = false } @@ -35,8 +35,8 @@ hex-literal = "0.3" [features] default = ["arithmetic"] -alloc = [] -arithmetic = ["ff", "group"] +alloc = [] # todo: activate `group/alloc` when weak feature activation is available +arithmetic = ["crypto-bigint/zeroize", "ff", "group", "zeroize"] bits = ["arithmetic", "ff/bits"] dev = ["arithmetic", "hex-literal", "pem", "zeroize"] ecdh = ["arithmetic", "zeroize"] diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index b4a955133..995378694 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -20,7 +20,7 @@ use ff::{Field, PrimeField}; use hex_literal::hex; #[cfg(feature = "bits")] -use crate::{bigint, group::ff::PrimeFieldBits, ScalarBits}; +use crate::{group::ff::PrimeFieldBits, ScalarBits}; #[cfg(feature = "jwk")] use crate::JwkParameters; @@ -157,14 +157,29 @@ impl PrimeField for Scalar { #[cfg(feature = "bits")] impl PrimeFieldBits for Scalar { - type ReprBits = [bigint::Limb; 32 / bigint::LIMB_BYTES]; + #[cfg(target_pointer_width = "32")] + type ReprBits = [u32; 8]; + #[cfg(target_pointer_width = "64")] + type ReprBits = [u64; 4]; fn to_le_bits(&self) -> ScalarBits { - (*self.0.limbs()).into() + let mut limbs = Self::ReprBits::default(); + + for (i, limb) in self.0.limbs().iter().cloned().enumerate() { + limbs[i] = limb.into(); + } + + limbs.into() } fn char_le_bits() -> ScalarBits { - (*MockCurve::ORDER.limbs()).into() + let mut limbs = Self::ReprBits::default(); + + for (i, limb) in MockCurve::ORDER.limbs().iter().cloned().enumerate() { + limbs[i] = limb.into(); + } + + limbs.into() } } @@ -304,7 +319,7 @@ impl From<&Scalar> for FieldBytes { impl Zeroize for Scalar { fn zeroize(&mut self) { - self.0.as_mut().zeroize() + self.0.as_mut().zeroize(); } } From 89301708b02dbe59b87b2b4d228194aad7a218ca Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Jun 2021 23:03:27 -0700 Subject: [PATCH 0543/1461] build(deps): bump rand_core from 0.6.2 to 0.6.3 (#672) Bumps [rand_core](https://github.com/rust-random/rand) from 0.6.2 to 0.6.3. - [Release notes](https://github.com/rust-random/rand/releases) - [Changelog](https://github.com/rust-random/rand/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-random/rand/compare/rand_core-0.6.2...rand_core-0.6.3) --- updated-dependencies: - dependency-name: rand_core dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b50a7255a..b58f6dda7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -445,9 +445,9 @@ checksum = "643f8f41a8ebc4c5dc4515c82bb8abd397b527fc20fd681b7c011c2aee5d44fb" [[package]] name = "rand_core" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" [[package]] name = "rustc_version" From 5732f2d8dca9559356a8fb0f28d92deaee28ad73 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 21 Jun 2021 23:30:43 -0700 Subject: [PATCH 0544/1461] elliptic-curve v0.10.3 (#674) --- Cargo.lock | 2 +- elliptic-curve/CHANGELOG.md | 12 +++++++++--- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 2 +- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b58f6dda7..b8c0b2817 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -250,7 +250,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.10.2" +version = "0.10.3" dependencies = [ "base64ct", "crypto-bigint", diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index 01fba2e08..4b9aea09f 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,19 +4,25 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 0.10.2 (2021-06-14) +## 0.10.3 (2021-06-21) +### Changed +- Bump `crypto-bigint` to v0.2.1 ([#673]) + +[#673]: https://github.com/RustCrypto/traits/pull/673 + +## 0.10.2 (2021-06-14) [YANKED] ### Added - `ConstantTimeEq` impl for `NonZeroScalar` ([#669]) [#669]: https://github.com/RustCrypto/traits/pull/669 -## 0.10.1 (2021-06-09) +## 0.10.1 (2021-06-09) [YANKED] ### Added - Explicit `Copy` bounds on `PublicKey` ([#667]) [#667]: https://github.com/RustCrypto/traits/pull/667 -## 0.10.0 (2021-06-07) +## 0.10.0 (2021-06-07) [YANKED] ### Added - `ScalarBytes::from_uint` ([#651]) - `dev::ScalarBytes` ([#652]) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index a4988ce04..57a6af13b 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -5,7 +5,7 @@ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. """ -version = "0.10.2" # Also update html_root_url in lib.rs when bumping this +version = "0.10.3" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" repository = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve" diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 659a77365..4bd36bc2b 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -16,7 +16,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.10.2" + html_root_url = "https://docs.rs/elliptic-curve/0.10.3" )] #[cfg(feature = "alloc")] From 7aa25e61c6ed0fba7a092e499c3c0b9410fed254 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 29 Jun 2021 06:59:03 -0700 Subject: [PATCH 0545/1461] signature: add Result alias (#676) Adds a `Result` alias with `signature::Error` in the error position which can be used as `signature::Result` by other crates. --- signature/src/error.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/signature/src/error.rs b/signature/src/error.rs index 9fba1e601..31e58c801 100644 --- a/signature/src/error.rs +++ b/signature/src/error.rs @@ -5,6 +5,11 @@ use core::fmt::{self, Debug, Display}; #[cfg(feature = "std")] use std::boxed::Box; +/// Result type. +/// +/// A result with the `signature` crate's [`Error`] type. +pub type Result = core::result::Result; + /// Signature errors. /// /// This type is deliberately opaque as to avoid sidechannel leakage which From 37717c1e76aa1bbc4fedda65cdef98fc759f232f Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 29 Jun 2021 07:21:13 -0700 Subject: [PATCH 0546/1461] signature v1.3.1 (#677) --- Cargo.lock | 2 +- signature/CHANGELOG.md | 6 ++++++ signature/Cargo.toml | 2 +- signature/src/lib.rs | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b8c0b2817..1dba37bb8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -511,7 +511,7 @@ dependencies = [ [[package]] name = "signature" -version = "1.3.0" +version = "1.3.1" dependencies = [ "digest 0.9.0", "hex-literal 0.2.1", diff --git a/signature/CHANGELOG.md b/signature/CHANGELOG.md index fc4f8ef4a..baa3e4768 100644 --- a/signature/CHANGELOG.md +++ b/signature/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 1.3.1 (2021-06-29) +### Added +- `Result` alias ([#676]) + +[#676]: https://github.com/RustCrypto/traits/pull/676 + ## 1.3.0 (2021-01-06) ### Changed - Bump `rand_core` to v0.6 ([#457]) diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 4bbe927b1..dc9e70cff 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "1.3.0" # Also update html_root_url in lib.rs when bumping this +version = "1.3.1" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/signature" diff --git a/signature/src/lib.rs b/signature/src/lib.rs index 7057b65d1..92f99f54f 100644 --- a/signature/src/lib.rs +++ b/signature/src/lib.rs @@ -160,7 +160,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/signature/1.3.0" + html_root_url = "https://docs.rs/signature/1.3.1" )] #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms, unused_qualifications)] From 141292cec27f1fc1a3005e9850c3bf679e8dc7c7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Jul 2021 11:56:38 -0600 Subject: [PATCH 0547/1461] build(deps): bump heapless from 0.7.1 to 0.7.2 (#678) Bumps [heapless](https://github.com/japaric/heapless) from 0.7.1 to 0.7.2. - [Release notes](https://github.com/japaric/heapless/releases) - [Changelog](https://github.com/japaric/heapless/blob/master/CHANGELOG.md) - [Commits](https://github.com/japaric/heapless/compare/v0.7.1...v0.7.2) --- updated-dependencies: - dependency-name: heapless dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1dba37bb8..15b9d2ee2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -325,9 +325,9 @@ dependencies = [ [[package]] name = "heapless" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7ee8a997d259962217f40279f34201fdf06e669bafa69d7c1f4c7ff1893b5f6" +checksum = "e44a9fba8877c568fc30457f5639d0aa7f57e494e4cdbc464150740a66c6613a" dependencies = [ "atomic-polyfill", "hash32", From 1d361a5315646d4d49de515a6b4c4e8dea0fd6c2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Jul 2021 16:08:19 -0600 Subject: [PATCH 0548/1461] build(deps): bump heapless from 0.7.2 to 0.7.3 (#679) Bumps [heapless](https://github.com/japaric/heapless) from 0.7.2 to 0.7.3. - [Release notes](https://github.com/japaric/heapless/releases) - [Changelog](https://github.com/japaric/heapless/blob/master/CHANGELOG.md) - [Commits](https://github.com/japaric/heapless/compare/v0.7.2...v0.7.3) --- updated-dependencies: - dependency-name: heapless dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 15b9d2ee2..1821b4b99 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -325,9 +325,9 @@ dependencies = [ [[package]] name = "heapless" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e44a9fba8877c568fc30457f5639d0aa7f57e494e4cdbc464150740a66c6613a" +checksum = "34e26526e7168021f34243a3c8faac4dc4f938cde75a0f9b8e373cca5eb4e7ce" dependencies = [ "atomic-polyfill", "hash32", From 3d5967f175d6e27bbcf3a30952e306a8d28271e9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 2 Jul 2021 16:07:40 -0600 Subject: [PATCH 0549/1461] build(deps): bump hex-literal from 0.3.1 to 0.3.2 (#680) Bumps [hex-literal](https://github.com/RustCrypto/utils) from 0.3.1 to 0.3.2. - [Release notes](https://github.com/RustCrypto/utils/releases) - [Commits](https://github.com/RustCrypto/utils/compare/hex-literal-v0.3.1...hex-literal-v0.3.2) --- updated-dependencies: - dependency-name: hex-literal dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 33 ++++----------------------------- signature/Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 30 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1821b4b99..2a93db68f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -257,7 +257,7 @@ dependencies = [ "ff", "generic-array", "group", - "hex-literal 0.3.1", + "hex-literal", "pkcs8", "rand_core", "serde", @@ -336,28 +336,9 @@ dependencies = [ [[package]] name = "hex-literal" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "961de220ec9a91af2e1e5bd80d02109155695e516771762381ef8581317066e0" -dependencies = [ - "hex-literal-impl", - "proc-macro-hack", -] - -[[package]] -name = "hex-literal" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5af1f635ef1bc545d78392b136bfe1c9809e029023c84a3638a864a10b8819c8" - -[[package]] -name = "hex-literal-impl" -version = "0.2.2" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "853f769599eb31de176303197b7ba4973299c38c7a7604a6bc88c3eef05b9b46" -dependencies = [ - "proc-macro-hack", -] +checksum = "76505e26b6ca3bbdbbb360b68472abbb80998c5fa5dc43672eca34f28258e138" [[package]] name = "itoa" @@ -413,12 +394,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "proc-macro-hack" -version = "0.5.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" - [[package]] name = "proc-macro2" version = "1.0.27" @@ -514,7 +489,7 @@ name = "signature" version = "1.3.1" dependencies = [ "digest 0.9.0", - "hex-literal 0.2.1", + "hex-literal", "rand_core", "sha2", "signature_derive", diff --git a/signature/Cargo.toml b/signature/Cargo.toml index dc9e70cff..aa5363d8c 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -27,7 +27,7 @@ optional = true path = "derive" [dev-dependencies] -hex-literal = "0.2" +hex-literal = "0.3" sha2 = { version = "0.9", default-features = false } [features] From 24252155df0af3570f490dfa31cc0296af3882d4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 8 Jul 2021 21:42:58 +0000 Subject: [PATCH 0550/1461] build(deps): bump crypto-bigint from 0.2.1 to 0.2.2 (#675) --- Cargo.lock | 5 +++-- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2a93db68f..8d509c552 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -182,11 +182,12 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdc9968be9247fb330af911b91a58a267cbbcfcb8dea88debaf977738950dce5" +checksum = "b32a398eb1ccfbe7e4f452bc749c44d38dd732e9a253f19da224c416f00ee7f4" dependencies = [ "generic-array", + "rand_core", "subtle", "zeroize", ] diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 57a6af13b..c1cdd7a99 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -15,7 +15,7 @@ categories = ["cryptography", "no-std"] keywords = ["crypto", "ecc", "elliptic", "weierstrass"] [dependencies] -crypto-bigint = { version = "0.2.1", features = ["generic-array"] } +crypto-bigint = { version = "0.2.2", features = ["generic-array"] } generic-array = { version = "0.14", default-features = false } rand_core = { version = "0.6", default-features = false } subtle = { version = "2.4", default-features = false } From 628fe827d67d7750af7d19262c41fa4b195fb78a Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 10 Jul 2021 13:40:16 -0700 Subject: [PATCH 0551/1461] aead: re-export `rand_core` (#682) This implements the changes proposed in #681 to simplify access to the `rand_core` traits and `OsRng`. `rand_core` is conditionally re-exported when the eponymous crate feature is enabled. Additionally, the `std` crate feature enables `rand_core/std`, which permits access to `OsRng` as `aead::rand_core::OsRng`. --- Cargo.lock | 20 ++++++++++++++++++++ aead/Cargo.toml | 3 ++- aead/src/lib.rs | 7 ++++++- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8d509c552..624cd8f19 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -304,6 +304,17 @@ dependencies = [ "version_check", ] +[[package]] +name = "getrandom" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + [[package]] name = "group" version = "0.10.0" @@ -424,6 +435,9 @@ name = "rand_core" version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom", +] [[package]] name = "rustc_version" @@ -603,6 +617,12 @@ dependencies = [ "vcell", ] +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + [[package]] name = "wyz" version = "0.4.0" diff --git a/aead/Cargo.toml b/aead/Cargo.toml index a0eda058c..5660ff0ee 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -17,13 +17,14 @@ categories = ["cryptography", "no-std"] [dependencies] generic-array = { version = "0.14", default-features = false } +# optional dependencies blobby = { version = "0.3", optional = true } heapless = { version = "0.7", optional = true, default-features = false } rand_core = { version = "0.6", optional = true } [features] -std = ["alloc"] alloc = [] +std = ["alloc", "rand_core/std"] dev = ["blobby"] stream = [] diff --git a/aead/src/lib.rs b/aead/src/lib.rs index 9ddcec352..0ff10d41f 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -40,10 +40,12 @@ pub mod stream; pub use generic_array::{self, typenum::consts}; #[cfg(feature = "heapless")] +#[cfg_attr(docsrs, doc(cfg(feature = "heapless")))] pub use heapless; #[cfg(feature = "rand_core")] -use rand_core::{CryptoRng, RngCore}; +#[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] +pub use rand_core; use core::fmt; use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; @@ -51,6 +53,9 @@ use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; #[cfg(feature = "alloc")] use alloc::vec::Vec; +#[cfg(feature = "rand_core")] +use rand_core::{CryptoRng, RngCore}; + /// Error type. /// /// This type is deliberately opaque as to avoid potential side-channel From f4ce223a6122d73e0262df666363c39dc34b6b45 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Sun, 11 Jul 2021 00:31:48 +0000 Subject: [PATCH 0552/1461] re-export rand_core (#683) --- aead/CHANGELOG.md | 6 ++++++ cipher/CHANGELOG.md | 6 ++++++ cipher/Cargo.toml | 3 ++- cipher/src/lib.rs | 4 ++++ crypto-mac/CHANGELOG.md | 6 ++++++ crypto-mac/Cargo.toml | 2 +- crypto-mac/src/lib.rs | 4 ++++ elliptic-curve/CHANGELOG.md | 6 ++++++ elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 4 ++++ password-hash/CHANGELOG.md | 6 ++++++ password-hash/Cargo.toml | 2 +- password-hash/src/lib.rs | 4 ++++ signature/CHANGELOG.md | 7 +++++++ signature/src/lib.rs | 21 ++++++++++++++++++++- 15 files changed, 78 insertions(+), 5 deletions(-) diff --git a/aead/CHANGELOG.md b/aead/CHANGELOG.md index 90e7e925b..ca9ceeb37 100644 --- a/aead/CHANGELOG.md +++ b/aead/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] +### Added +- Re-export `rand_core` ([#682]) + +[#682]: https://github.com/RustCrypto/traits/pull/682 + ## 0.4.1 (2021-05-03) ### Changed - Bump `heapless` dependency to v0.7 ([#628]) diff --git a/cipher/CHANGELOG.md b/cipher/CHANGELOG.md index 63af8392d..77b955f1f 100644 --- a/cipher/CHANGELOG.md +++ b/cipher/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] +### Added +- Re-export `rand_core` ([#683]) + +[#683]: https://github.com/RustCrypto/traits/pull/683 + ## 0.3.0 (2021-04-28) ### Added - Encrypt/decrypt-only block cipher traits ([#352]) diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index 803b017eb..017e3c028 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -15,13 +15,14 @@ categories = ["cryptography", "no-std"] generic-array = "0.14" crypto-common = { version = "=0.1.0-pre", path = "../crypto-common" } +# optional dependencies block-buffer = { version = "=0.10.0-pre.4", features = ["block-padding"], optional = true } blobby = { version = "0.3", optional = true } rand_core = { version = "0.6", optional = true } [features] default = ["mode_wrapper"] -std = ["crypto-common/std"] +std = ["crypto-common/std", "rand_core/std"] mode_wrapper = ["block-buffer"] dev = ["blobby"] diff --git a/cipher/src/lib.rs b/cipher/src/lib.rs index da2951d87..4a9a3ebe1 100644 --- a/cipher/src/lib.rs +++ b/cipher/src/lib.rs @@ -16,6 +16,10 @@ #[cfg(feature = "std")] extern crate std; +#[cfg(feature = "rand_core")] +#[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] +pub use rand_core; + #[cfg(feature = "dev")] pub use blobby; diff --git a/crypto-mac/CHANGELOG.md b/crypto-mac/CHANGELOG.md index 874f5ae88..95b1b7beb 100644 --- a/crypto-mac/CHANGELOG.md +++ b/crypto-mac/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] +### Added +- Re-export `rand_core` ([#683]) + +[#683]: https://github.com/RustCrypto/traits/pull/683 + ## 0.11.0 (2021-04-28) ### Added - `generate_key` method to `New*` trait ([#513]) diff --git a/crypto-mac/Cargo.toml b/crypto-mac/Cargo.toml index 259c6bdb2..414951a82 100644 --- a/crypto-mac/Cargo.toml +++ b/crypto-mac/Cargo.toml @@ -23,7 +23,7 @@ rand_core = { version = "0.6", optional = true } [features] dev = ["blobby"] core-api = ["crypto-common/core-api"] -std = ["crypto-common/std"] +std = ["crypto-common/std", "rand_core/std"] [package.metadata.docs.rs] all-features = true diff --git a/crypto-mac/src/lib.rs b/crypto-mac/src/lib.rs index 5020bc7a9..1bcf13f9b 100644 --- a/crypto-mac/src/lib.rs +++ b/crypto-mac/src/lib.rs @@ -12,6 +12,10 @@ #[cfg(feature = "std")] extern crate std; +#[cfg(feature = "rand_core")] +#[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] +pub use rand_core; + #[cfg(feature = "cipher")] pub use cipher; #[cfg(feature = "cipher")] diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index 4b9aea09f..124cd9015 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] +### Added +- Re-export `rand_core` ([#683]) + +[#683]: https://github.com/RustCrypto/traits/pull/683 + ## 0.10.3 (2021-06-21) ### Changed - Bump `crypto-bigint` to v0.2.1 ([#673]) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index c1cdd7a99..8788d9d32 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -43,7 +43,7 @@ ecdh = ["arithmetic", "zeroize"] hazmat = [] jwk = ["alloc", "base64ct/alloc", "serde", "serde_json", "zeroize/alloc"] pem = ["alloc", "pkcs8/pem"] -std = ["alloc"] +std = ["alloc", "rand_core/std"] [package.metadata.docs.rs] features = ["arithmetic", "ecdh", "jwk", "pem", "std"] diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 4bd36bc2b..244fdfe6c 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -27,6 +27,10 @@ extern crate alloc; #[cfg(feature = "std")] extern crate std; +#[cfg(feature = "rand_core")] +#[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] +pub use rand_core; + pub mod ops; pub mod sec1; pub mod weierstrass; diff --git a/password-hash/CHANGELOG.md b/password-hash/CHANGELOG.md index edf13dc96..e7994b0d3 100644 --- a/password-hash/CHANGELOG.md +++ b/password-hash/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] +### Added +- Re-export `rand_core` ([#683]) + +[#683]: https://github.com/RustCrypto/traits/pull/683 + ## 0.2.1 (2021-05-05) ### Changed - Use `subtle` crate for comparing hash `Output` ([#631]) diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index ac64a9e70..cf2c972b2 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -25,7 +25,7 @@ rand_core = { version = "0.6", optional = true, default-features = false } [features] default = ["rand_core"] alloc = ["base64ct/alloc"] -std = ["alloc", "base64ct/std"] +std = ["alloc", "base64ct/std", "rand_core/std"] [package.metadata.docs.rs] rustc-args = ["--cfg", "docsrs"] diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index 1083415b4..73cd21b14 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -50,6 +50,10 @@ extern crate alloc; #[cfg(feature = "std")] extern crate std; +#[cfg(feature = "rand_core")] +#[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] +pub use rand_core; + mod encoding; mod errors; mod ident; diff --git a/signature/CHANGELOG.md b/signature/CHANGELOG.md index baa3e4768..847134ef8 100644 --- a/signature/CHANGELOG.md +++ b/signature/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] +### Added +- Re-export `rand_core`. Emit compilation error if unstable functionality +is enabled by bypassing the preview features. ([#683]) + +[#683]: https://github.com/RustCrypto/traits/pull/683 + ## 1.3.1 (2021-06-29) ### Added - `Result` alias ([#676]) diff --git a/signature/src/lib.rs b/signature/src/lib.rs index 92f99f54f..a65f31b58 100644 --- a/signature/src/lib.rs +++ b/signature/src/lib.rs @@ -168,6 +168,24 @@ #[cfg(feature = "std")] extern crate std; +#[cfg(all(feature = "signature_derive", not(feature = "derive-preview")))] +compile_error!( + "The `signature_derive` feature should not be enabled directly. \ + Use the `derive-preview` feature instead." +); + +#[cfg(all(feature = "digest", not(feature = "digest-preview")))] +compile_error!( + "The `digest` feature should not be enabled directly. \ + Use the `digest-preview` feature instead." +); + +#[cfg(all(feature = "rand_core", not(feature = "rand-preview")))] +compile_error!( + "The `rand_core` feature should not be enabled directly. \ + Use the `rand-preview` feature instead." +); + #[cfg(feature = "derive-preview")] #[cfg_attr(docsrs, doc(cfg(feature = "derive-preview")))] pub use signature_derive::{Signer, Verifier}; @@ -175,7 +193,8 @@ pub use signature_derive::{Signer, Verifier}; #[cfg(feature = "digest-preview")] pub use digest; -#[cfg(feature = "rand-preview")] +#[cfg(feature = "rand_core")] +#[cfg_attr(docsrs, doc(cfg(feature = "rand-preview")))] pub use rand_core; mod error; From a39283d09de56cc8cfc810a80ad74ab454e538e9 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 12 Jul 2021 08:52:19 -0700 Subject: [PATCH 0553/1461] aead v0.4.2 (#684) --- aead/CHANGELOG.md | 2 +- aead/Cargo.toml | 2 +- aead/src/lib.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/aead/CHANGELOG.md b/aead/CHANGELOG.md index ca9ceeb37..09e9de176 100644 --- a/aead/CHANGELOG.md +++ b/aead/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [Unreleased] +## v0.4.2 (2021-07-12) ### Added - Re-export `rand_core` ([#682]) diff --git a/aead/Cargo.toml b/aead/Cargo.toml index 5660ff0ee..b0f2ca01b 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aead" -version = "0.4.1" # Also update html_root_url in lib.rs when bumping this +version = "0.4.2" # Also update html_root_url in lib.rs when bumping this description = """ Traits for Authenticated Encryption with Associated Data (AEAD) algorithms, such as AES-GCM as ChaCha20Poly1305, which provide a high-level API diff --git a/aead/src/lib.rs b/aead/src/lib.rs index 0ff10d41f..05ad57dd2 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -19,7 +19,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/aead/0.4.1" + html_root_url = "https://docs.rs/aead/0.4.2" )] #![warn(missing_docs, rust_2018_idioms)] From 46f3ac30fdbe36dad30b4c16f636bcc338f22608 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 12 Jul 2021 09:05:20 -0700 Subject: [PATCH 0554/1461] elliptic-curve v0.10.4 (#685) --- Cargo.lock | 4 ++-- aead/CHANGELOG.md | 2 +- elliptic-curve/CHANGELOG.md | 2 +- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 624cd8f19..ca3a5c20d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,7 +4,7 @@ version = 3 [[package]] name = "aead" -version = "0.4.1" +version = "0.4.2" dependencies = [ "blobby", "generic-array", @@ -251,7 +251,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.10.3" +version = "0.10.4" dependencies = [ "base64ct", "crypto-bigint", diff --git a/aead/CHANGELOG.md b/aead/CHANGELOG.md index 09e9de176..71a0e9820 100644 --- a/aead/CHANGELOG.md +++ b/aead/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## v0.4.2 (2021-07-12) +## 0.4.2 (2021-07-12) ### Added - Re-export `rand_core` ([#682]) diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index 124cd9015..c8f86c4c0 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [Unreleased] +## 0.10.4 (2021-07-12) ### Added - Re-export `rand_core` ([#683]) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 8788d9d32..c5783642a 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -5,7 +5,7 @@ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. """ -version = "0.10.3" # Also update html_root_url in lib.rs when bumping this +version = "0.10.4" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" repository = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve" diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 244fdfe6c..20d924b7e 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -16,7 +16,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.10.3" + html_root_url = "https://docs.rs/elliptic-curve/0.10.4" )] #[cfg(feature = "alloc")] From 1bebac113287749475c1c3f01ecbc5931a0e2a8d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Jul 2021 22:11:34 +0000 Subject: [PATCH 0555/1461] build(deps): bump subtle from 2.4.0 to 2.4.1 (#686) --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ca3a5c20d..04d8d008a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -537,9 +537,9 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "subtle" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e81da0851ada1f3e9d4312c704aa4f8806f0f9d69faaf8df2f3464b4a9437c2" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" From 3c5c848826bf62a505ac553236cb7f0a85a8c41b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Jul 2021 15:59:55 -0700 Subject: [PATCH 0556/1461] build(deps): bump hex-literal from 0.3.2 to 0.3.3 (#687) Bumps [hex-literal](https://github.com/RustCrypto/utils) from 0.3.2 to 0.3.3. - [Release notes](https://github.com/RustCrypto/utils/releases) - [Commits](https://github.com/RustCrypto/utils/compare/hex-literal-v0.3.2...hex-literal-v0.3.3) --- updated-dependencies: - dependency-name: hex-literal dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 04d8d008a..ab77a2f6f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -348,9 +348,9 @@ dependencies = [ [[package]] name = "hex-literal" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76505e26b6ca3bbdbbb360b68472abbb80998c5fa5dc43672eca34f28258e138" +checksum = "21e4590e13640f19f249fe3e4eca5113bc4289f2497710378190e7f4bd96f45b" [[package]] name = "itoa" From 3c3051df89db7827bd7bbc435869c3badfb7fcfb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Jul 2021 16:00:19 -0700 Subject: [PATCH 0557/1461] build(deps): bump zeroize from 1.3.0 to 1.4.0 (#688) Bumps [zeroize](https://github.com/iqlusioninc/crates) from 1.3.0 to 1.4.0. - [Release notes](https://github.com/iqlusioninc/crates/releases) - [Commits](https://github.com/iqlusioninc/crates/compare/zeroize/v1.3.0...zeroize/v1.4.0) --- updated-dependencies: - dependency-name: zeroize dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ab77a2f6f..dadff4e31 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -634,6 +634,6 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" +checksum = "eeafe61337cb2c879d328b74aa6cd9d794592c82da6be559fdf11493f02a2d18" From f5a24d8fdd45cf17f64c8c72586bc609ac60a03b Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Tue, 20 Jul 2021 13:20:40 +0000 Subject: [PATCH 0558/1461] Pin zeroize dependency to v1.4 and subtle to v2.4 (#689) * Pin zeroize dependency to v1.4 and subtle to v2.4 * update Cargo.lock * cherry-pick crypto-mac changes from #691 --- Cargo.lock | 26 +++++++++++++------------- crypto-mac/CHANGELOG.md | 12 ++++++++++++ crypto-mac/Cargo.toml | 4 ++-- crypto-mac/src/lib.rs | 3 ++- elliptic-curve/CHANGELOG.md | 6 ++++++ elliptic-curve/Cargo.toml | 6 +++--- elliptic-curve/src/lib.rs | 2 +- password-hash/CHANGELOG.md | 6 +++++- password-hash/Cargo.toml | 4 ++-- password-hash/src/lib.rs | 2 +- universal-hash/CHANGELOG.md | 6 ++++++ universal-hash/Cargo.toml | 4 ++-- universal-hash/src/lib.rs | 3 ++- 13 files changed, 57 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dadff4e31..78f5691ff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -147,9 +147,9 @@ checksum = "44c32f031ea41b4291d695026c023b95d59db2d8a2c7640800ed56bc8f510f22" [[package]] name = "cortex-m" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "643a210c1bdc23d0db511e2a576082f4ff4dcae9d0c37f50b431b8f8439d6d6b" +checksum = "2ac919ef424449ec8c08d515590ce15d9262c0ca5f0da5b0c901e971a3b783b3" dependencies = [ "bare-metal", "bitfield", @@ -159,9 +159,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed00c67cb5d0a7d64a44f6ad2668db7e7530311dd53ea79bcd4fb022c64911c8" +checksum = "66c99696f6c9dd7f35d486b9d04d7e6e202aa3e8c40d553f2fdf5e7e0c6a71ef" dependencies = [ "libc", ] @@ -251,7 +251,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.10.4" +version = "0.10.5" dependencies = [ "base64ct", "crypto-bigint", @@ -360,9 +360,9 @@ checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" [[package]] name = "libc" -version = "0.2.95" +version = "0.2.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "789da6d93f1b866ffe175afc5322a4d76c038605a1c3319bb57b06967ca98a36" +checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790" [[package]] name = "nb" @@ -387,7 +387,7 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "password-hash" -version = "0.2.1" +version = "0.2.2" dependencies = [ "base64ct", "rand_core", @@ -543,9 +543,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.72" +version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1e8cdbefb79a9a5a65e0db8b47b723ee907b7c7f8496c76a1770b5c310bab82" +checksum = "f71489ff30030d2ae598524f61326b902466f72a0fb1a8564c001cc63425bcc7" dependencies = [ "proc-macro2", "quote", @@ -554,9 +554,9 @@ dependencies = [ [[package]] name = "synstructure" -version = "0.12.4" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701" +checksum = "474aaa926faa1603c40b7885a9eaea29b444d1cb2850cb7c0e37bb1a4182f4fa" dependencies = [ "proc-macro2", "quote", @@ -584,7 +584,7 @@ checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" [[package]] name = "universal-hash" -version = "0.4.0" +version = "0.4.1" dependencies = [ "generic-array", "subtle", diff --git a/crypto-mac/CHANGELOG.md b/crypto-mac/CHANGELOG.md index 95b1b7beb..7488081b1 100644 --- a/crypto-mac/CHANGELOG.md +++ b/crypto-mac/CHANGELOG.md @@ -11,6 +11,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [#683]: https://github.com/RustCrypto/traits/pull/683 +## 0.11.1 (2021-07-20) +### Changed +- Pin `subtle` dependency to v2.4 ([#691]) + +[#691]: https://github.com/RustCrypto/traits/pull/691 + ## 0.11.0 (2021-04-28) ### Added - `generate_key` method to `New*` trait ([#513]) @@ -23,6 +29,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [#513]: https://github.com/RustCrypto/traits/pull/513 [#621]: https://github.com/RustCrypto/traits/pull/621 +## 0.10.1 (2021-07-20) +### Changed +- Pin `subtle` dependency to v2.4 ([#690]) + +[#690]: https://github.com/RustCrypto/traits/pull/690 + ## 0.10.0 (2020-10-15) ### Changed - Replace `block-cipher` crate with new `cipher` crate ([#337], [#338]) diff --git a/crypto-mac/Cargo.toml b/crypto-mac/Cargo.toml index 414951a82..725f75fa4 100644 --- a/crypto-mac/Cargo.toml +++ b/crypto-mac/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crypto-mac" description = "Trait for Message Authentication Code (MAC) algorithms" -version = "0.12.0-pre" +version = "0.12.0-pre" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" @@ -15,7 +15,7 @@ categories = ["cryptography", "no-std"] generic-array = "0.14" crypto-common = { version = "=0.1.0-pre", path = "../crypto-common" } cipher = { version = "=0.4.0-pre", path = "../cipher" } -subtle = { version = "2", default-features = false } +subtle = { version = "=2.4", default-features = false } blobby = { version = "0.3", optional = true } rand_core = { version = "0.6", optional = true } diff --git a/crypto-mac/src/lib.rs b/crypto-mac/src/lib.rs index 1bcf13f9b..e5e2f2ba7 100644 --- a/crypto-mac/src/lib.rs +++ b/crypto-mac/src/lib.rs @@ -4,7 +4,8 @@ #![cfg_attr(docsrs, feature(doc_cfg))] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg" + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", + html_root_url = "https://docs.rs/crypto-mac/0.12.0-pre" )] #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index c8f86c4c0..7717b1f7b 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.10.5 (2021-07-20) +### Changed +- Pin `zeroize` dependency to v1.4 and `subtle` to v2.4 ([#349]) + +[#689]: https://github.com/RustCrypto/traits/pull/689 + ## 0.10.4 (2021-07-12) ### Added - Re-export `rand_core` ([#683]) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index c5783642a..5f7ae6abe 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -5,7 +5,7 @@ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. """ -version = "0.10.4" # Also update html_root_url in lib.rs when bumping this +version = "0.10.5" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" repository = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve" @@ -18,7 +18,7 @@ keywords = ["crypto", "ecc", "elliptic", "weierstrass"] crypto-bigint = { version = "0.2.2", features = ["generic-array"] } generic-array = { version = "0.14", default-features = false } rand_core = { version = "0.6", default-features = false } -subtle = { version = "2.4", default-features = false } +subtle = { version = "=2.4", default-features = false } # optional dependencies base64ct = { version = "1", optional = true, default-features = false } @@ -28,7 +28,7 @@ hex-literal = { version = "0.3", optional = true } pkcs8 = { version = "0.7", optional = true } serde = { version = "1", optional = true, default-features = false } serde_json = { version = "1", optional = true, default-features = false, features = ["alloc"] } -zeroize = { version = "1", optional = true, default-features = false } +zeroize = { version = "=1.4", optional = true, default-features = false } [dev-dependencies] hex-literal = "0.3" diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 20d924b7e..aa14d7ace 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -16,7 +16,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.10.4" + html_root_url = "https://docs.rs/elliptic-curve/0.10.5" )] #[cfg(feature = "alloc")] diff --git a/password-hash/CHANGELOG.md b/password-hash/CHANGELOG.md index e7994b0d3..534c2747f 100644 --- a/password-hash/CHANGELOG.md +++ b/password-hash/CHANGELOG.md @@ -5,11 +5,15 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [Unreleased] +## 0.2.2 (2021-07-20) +### Changed +- Pin `subtle` dependency to v2.4 ([#689]) + ### Added - Re-export `rand_core` ([#683]) [#683]: https://github.com/RustCrypto/traits/pull/683 +[#689]: https://github.com/RustCrypto/traits/pull/689 ## 0.2.1 (2021-05-05) ### Changed diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index cf2c972b2..88f2fbbeb 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -5,7 +5,7 @@ Traits which describe the functionality of password hashing algorithms, as well as a `no_std`-friendly implementation of the PHC string format (a well-defined subset of the Modular Crypt Format a.k.a. MCF) """ -version = "0.2.1" # Also update html_root_url in lib.rs when bumping this +version = "0.2.2" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" @@ -17,7 +17,7 @@ keywords = ["crypt", "mcf", "password", "pbkdf", "phc"] [dependencies] base64ct = "1" -subtle = { version = "2", default-features = false } +subtle = { version = "=2.4", default-features = false } # optional features rand_core = { version = "0.6", optional = true, default-features = false } diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index 73cd21b14..4f7c3bc0a 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -39,7 +39,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/password-hash/0.2.1" + html_root_url = "https://docs.rs/password-hash/0.2.2" )] #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] diff --git a/universal-hash/CHANGELOG.md b/universal-hash/CHANGELOG.md index 1879015a6..7959f756e 100644 --- a/universal-hash/CHANGELOG.md +++ b/universal-hash/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.4.1 (2021-07-20) +### Changed +- Pin `subtle` dependency to v2.4 ([#689]) + +[#689]: https://github.com/RustCrypto/traits/pull/689 + ## 0.4.0 (2020-06-04) ### Added - `Key` and `Block` type aliases ([#128]) diff --git a/universal-hash/Cargo.toml b/universal-hash/Cargo.toml index 143e5f8cd..2c15823ef 100644 --- a/universal-hash/Cargo.toml +++ b/universal-hash/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "universal-hash" -version = "0.4.0" +version = "0.4.1" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" description = "Trait for universal hash functions" @@ -13,7 +13,7 @@ edition = "2018" [dependencies] generic-array = "0.14" -subtle = { version = "2", default-features = false } +subtle = { version = "=2.4", default-features = false } [features] std = [] diff --git a/universal-hash/src/lib.rs b/universal-hash/src/lib.rs index 635cc1166..dc802c815 100644 --- a/universal-hash/src/lib.rs +++ b/universal-hash/src/lib.rs @@ -21,7 +21,8 @@ #![forbid(unsafe_code)] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg" + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", + html_root_url = "https://docs.rs/universal-hash/0.4.1" )] #![warn(missing_docs, rust_2018_idioms)] From d1635037043bef8b3053f55bf17083d4e7911583 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Jul 2021 22:10:43 +0000 Subject: [PATCH 0559/1461] build(deps): bump zeroize from 1.4.0 to 1.4.1 (#692) --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 78f5691ff..1828fa55b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -634,6 +634,6 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eeafe61337cb2c879d328b74aa6cd9d794592c82da6be559fdf11493f02a2d18" +checksum = "377db0846015f7ae377174787dd452e1c5f5a9050bc6f954911d01f116daa0cd" From a710726d32cff1b6a24200bd5b4996d373d4a984 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Jul 2021 22:11:04 +0000 Subject: [PATCH 0560/1461] build(deps): bump pkcs8 from 0.7.0 to 0.7.2 (#693) --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1828fa55b..00446a3aa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -396,9 +396,9 @@ dependencies = [ [[package]] name = "pkcs8" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09d156817ae0125e8aa5067710b0db24f0984830614f99875a70aa5e3b74db69" +checksum = "87bb2d5c68b7505a3a89eb2f3583a4d56303863005226c2ef99319930a262be4" dependencies = [ "base64ct", "der", From da87cddc90937397ee094f9005b0913e968d1a07 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 26 Jul 2021 13:38:30 -0700 Subject: [PATCH 0561/1461] Cargo.lock: bump dependencies (#695) --- Cargo.lock | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 00446a3aa..f5647b41f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -172,7 +172,7 @@ version = "0.3.0" dependencies = [ "aead", "cipher 0.3.0", - "crypto-mac 0.11.0", + "crypto-mac 0.11.1", "digest 0.9.0", "elliptic-curve", "password-hash", @@ -202,9 +202,9 @@ dependencies = [ [[package]] name = "crypto-mac" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25fab6889090c8133f3deb8f73ba3c65a7f456f66436fc012a1b1e272b1e103e" +checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" dependencies = [ "generic-array", "subtle", @@ -395,22 +395,31 @@ dependencies = [ ] [[package]] -name = "pkcs8" -version = "0.7.2" +name = "pem-rfc7468" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87bb2d5c68b7505a3a89eb2f3583a4d56303863005226c2ef99319930a262be4" +checksum = "b8fe90c78c9a17442665a41a1a45dcd24bbab0e1794748edc19b27fffb146c13" dependencies = [ "base64ct", +] + +[[package]] +name = "pkcs8" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbee84ed13e44dd82689fa18348a49934fa79cc774a344c42fc9b301c71b140a" +dependencies = [ "der", + "pem-rfc7468", "spki", "zeroize", ] [[package]] name = "proc-macro2" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038" +checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" dependencies = [ "unicode-xid", ] @@ -543,9 +552,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.73" +version = "1.0.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f71489ff30030d2ae598524f61326b902466f72a0fb1a8564c001cc63425bcc7" +checksum = "1873d832550d4588c3dbc20f01361ab00bfe741048f71e3fecf145a7cc18b29c" dependencies = [ "proc-macro2", "quote", From b82e2418b5db30d1cb20b740a604e8b937b0f263 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 Jul 2021 08:34:23 +0000 Subject: [PATCH 0562/1461] build(deps): bump serde_json from 1.0.64 to 1.0.65 (#696) --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f5647b41f..b466ad23e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -486,9 +486,9 @@ checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03" [[package]] name = "serde_json" -version = "1.0.64" +version = "1.0.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" +checksum = "28c5e91e4240b46c4c19219d6cc84784444326131a4210f496f948d5cc827a29" dependencies = [ "itoa", "ryu", From 78fba4ad4a63ff98375a2bbf53f58ab9f26d2cac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 Jul 2021 22:06:46 +0000 Subject: [PATCH 0563/1461] build(deps): bump async-trait from 0.1.50 to 0.1.51 (#697) --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b466ad23e..980461bbe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -22,9 +22,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.50" +version = "0.1.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b98e84bbb4cbcdd97da190ba0c58a1bb0de2c1fdf67d159e192ed766aeca722" +checksum = "44318e776df68115a881de9a8fd1b9e53368d7a4a5ce4cc48517da3393233a5e" dependencies = [ "proc-macro2", "quote", From 028eef5c4a2950f89ece26d24237afb3faf5d21d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 Jul 2021 22:10:26 +0000 Subject: [PATCH 0564/1461] build(deps): bump serde_json from 1.0.65 to 1.0.66 (#698) --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 980461bbe..0aecc9cd4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -486,9 +486,9 @@ checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03" [[package]] name = "serde_json" -version = "1.0.65" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28c5e91e4240b46c4c19219d6cc84784444326131a4210f496f948d5cc827a29" +checksum = "336b10da19a12ad094b59d870ebde26a45402e5b470add4b5fd03c5048a32127" dependencies = [ "itoa", "ryu", From fbe55392b2b6e2cfa5bcd46b3195c76ee1500011 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Aug 2021 15:07:49 -0700 Subject: [PATCH 0565/1461] build(deps): bump serde from 1.0.126 to 1.0.127 (#700) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.126 to 1.0.127. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.126...v1.0.127) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0aecc9cd4..61ea62cd4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -480,9 +480,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.126" +version = "1.0.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03" +checksum = "f03b9878abf6d14e6779d3f24f07b2cfa90352cfec4acc5aab8f1ac7f146fae8" [[package]] name = "serde_json" From 3b4ff66008f3525c2843824197ed66a2aa674d23 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Aug 2021 15:08:26 -0700 Subject: [PATCH 0566/1461] build(deps): bump heapless from 0.7.3 to 0.7.4 (#701) Bumps [heapless](https://github.com/japaric/heapless) from 0.7.3 to 0.7.4. - [Release notes](https://github.com/japaric/heapless/releases) - [Changelog](https://github.com/japaric/heapless/blob/master/CHANGELOG.md) - [Commits](https://github.com/japaric/heapless/compare/v0.7.3...v0.7.4) --- updated-dependencies: - dependency-name: heapless dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 111 +---------------------------------------------------- 1 file changed, 2 insertions(+), 109 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 61ea62cd4..1c5b30336 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -31,36 +31,12 @@ dependencies = [ "syn", ] -[[package]] -name = "atomic-polyfill" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30302dda7a66f8c55932ebf208f7def840743ff64d495e9ceffcd97c18f11d39" -dependencies = [ - "cortex-m", -] - -[[package]] -name = "bare-metal" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3" -dependencies = [ - "rustc_version", -] - [[package]] name = "base64ct" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0d27fb6b6f1e43147af148af49d49329413ba781aa0d5e10979831c210173b5" -[[package]] -name = "bitfield" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719" - [[package]] name = "bitvec" version = "0.22.3" @@ -145,18 +121,6 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44c32f031ea41b4291d695026c023b95d59db2d8a2c7640800ed56bc8f510f22" -[[package]] -name = "cortex-m" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ac919ef424449ec8c08d515590ce15d9262c0ca5f0da5b0c901e971a3b783b3" -dependencies = [ - "bare-metal", - "bitfield", - "embedded-hal", - "volatile-register", -] - [[package]] name = "cpufeatures" version = "0.1.5" @@ -267,16 +231,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "embedded-hal" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db184d3fa27bc7a2344250394c0264144dfe0bc81a4401801dcb964b8dd172ad" -dependencies = [ - "nb 0.1.3", - "void", -] - [[package]] name = "ff" version = "0.10.0" @@ -337,11 +291,10 @@ dependencies = [ [[package]] name = "heapless" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34e26526e7168021f34243a3c8faac4dc4f938cde75a0f9b8e373cca5eb4e7ce" +checksum = "767c746c1943728fb6f2cdb24b2cbe292dd4d6976640758060adf4bb9855a7ca" dependencies = [ - "atomic-polyfill", "hash32", "stable_deref_trait", ] @@ -364,21 +317,6 @@ version = "0.2.98" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790" -[[package]] -name = "nb" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f" -dependencies = [ - "nb 1.0.0", -] - -[[package]] -name = "nb" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "546c37ac5d9e56f55e73b677106873d9d9f5190605e41a856503623648488cae" - [[package]] name = "opaque-debug" version = "0.3.0" @@ -448,36 +386,12 @@ dependencies = [ "getrandom", ] -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -dependencies = [ - "semver", -] - [[package]] name = "ryu" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" -[[package]] -name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser", -] - -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" - [[package]] name = "serde" version = "1.0.127" @@ -599,33 +513,12 @@ dependencies = [ "subtle", ] -[[package]] -name = "vcell" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002" - [[package]] name = "version_check" version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" -[[package]] -name = "void" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" - -[[package]] -name = "volatile-register" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d67cb4616d99b940db1d6bd28844ff97108b498a6ca850e5b6191a532063286" -dependencies = [ - "vcell", -] - [[package]] name = "wasi" version = "0.10.2+wasi-snapshot-preview1" From 1a123c4d1c69ac3b5508f1a53dd0cd3c916ca013 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 12 Aug 2021 08:15:28 -0600 Subject: [PATCH 0567/1461] build(deps): bump ff from 0.10.0 to 0.10.1 (#702) Bumps [ff](https://github.com/zkcrypto/ff) from 0.10.0 to 0.10.1. - [Release notes](https://github.com/zkcrypto/ff/releases) - [Changelog](https://github.com/zkcrypto/ff/blob/main/CHANGELOG.md) - [Commits](https://github.com/zkcrypto/ff/commits) --- updated-dependencies: - dependency-name: ff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1c5b30336..07f2bb081 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -233,9 +233,9 @@ dependencies = [ [[package]] name = "ff" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63eec06c61e487eecf0f7e6e6372e596a81922c28d33e645d6983ca6493a1af0" +checksum = "d0f40b2dcd8bc322217a5f6559ae5f9e9d1de202a2ecee2e9eafcbece7562a4f" dependencies = [ "bitvec", "rand_core", From be0114a14464dba41d70836c6f31c05f037ba717 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Aug 2021 16:08:36 -0600 Subject: [PATCH 0568/1461] build(deps): bump crypto-bigint from 0.2.2 to 0.2.3 (#703) Bumps [crypto-bigint](https://github.com/RustCrypto/utils) from 0.2.2 to 0.2.3. - [Release notes](https://github.com/RustCrypto/utils/releases) - [Commits](https://github.com/RustCrypto/utils/compare/crypto-bigint-v0.2.2...crypto-bigint-v0.2.3) --- updated-dependencies: - dependency-name: crypto-bigint dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 07f2bb081..e6b1b2d7e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -146,9 +146,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b32a398eb1ccfbe7e4f452bc749c44d38dd732e9a253f19da224c416f00ee7f4" +checksum = "09910f0830248af4499907177608b81d640c8c404526f8770b87b765fbd8c9a5" dependencies = [ "generic-array", "rand_core", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 5f7ae6abe..b9d717e87 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -15,7 +15,7 @@ categories = ["cryptography", "no-std"] keywords = ["crypto", "ecc", "elliptic", "weierstrass"] [dependencies] -crypto-bigint = { version = "0.2.2", features = ["generic-array"] } +crypto-bigint = { version = "0.2.3", features = ["generic-array"] } generic-array = { version = "0.14", default-features = false } rand_core = { version = "0.6", default-features = false } subtle = { version = "=2.4", default-features = false } From 639a1cc41d2ffa9b4ed1280122506818c148fa44 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Aug 2021 16:10:42 -0600 Subject: [PATCH 0569/1461] build(deps): bump base64ct from 1.0.0 to 1.0.1 (#704) Bumps [base64ct](https://github.com/RustCrypto/utils) from 1.0.0 to 1.0.1. - [Release notes](https://github.com/RustCrypto/utils/releases) - [Commits](https://github.com/RustCrypto/utils/compare/base64ct-v1.0.0...base64ct-v1.0.1) --- updated-dependencies: - dependency-name: base64ct dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e6b1b2d7e..841f58c38 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -33,9 +33,9 @@ dependencies = [ [[package]] name = "base64ct" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0d27fb6b6f1e43147af148af49d49329413ba781aa0d5e10979831c210173b5" +checksum = "8a32fd6af2b5827bce66c29053ba0e7c42b9dcab01835835058558c10851a46b" [[package]] name = "bitvec" From c0b7a16ec6609a2b7074c7d877eb4319289e7893 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Aug 2021 16:14:27 -0600 Subject: [PATCH 0570/1461] build(deps): bump heapless from 0.7.4 to 0.7.5 (#705) Bumps [heapless](https://github.com/japaric/heapless) from 0.7.4 to 0.7.5. - [Release notes](https://github.com/japaric/heapless/releases) - [Changelog](https://github.com/japaric/heapless/blob/master/CHANGELOG.md) - [Commits](https://github.com/japaric/heapless/compare/v0.7.4...v0.7.5) --- updated-dependencies: - dependency-name: heapless dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 841f58c38..dd117e929 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -291,9 +291,9 @@ dependencies = [ [[package]] name = "heapless" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "767c746c1943728fb6f2cdb24b2cbe292dd4d6976640758060adf4bb9855a7ca" +checksum = "50530280e9a947b192e3a30a9d7bcead527b22da30ff7cbd334233d820aaf82a" dependencies = [ "hash32", "stable_deref_trait", From 66fa43641ba4129f5beea960469ab4332c8c806a Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 22 Aug 2021 17:26:57 -0600 Subject: [PATCH 0571/1461] password-hash: make value and salt lengths the same (#707) Without this `Salt` cannot represent the full possible length of a salt value as defined in the PHC string format spec. --- password-hash/src/errors.rs | 1 + password-hash/src/salt.rs | 11 ++++++----- password-hash/src/value.rs | 26 +++++++++++--------------- 3 files changed, 18 insertions(+), 20 deletions(-) diff --git a/password-hash/src/errors.rs b/password-hash/src/errors.rs index 8f63cd857..ceb317797 100644 --- a/password-hash/src/errors.rs +++ b/password-hash/src/errors.rs @@ -9,6 +9,7 @@ pub type Result = core::result::Result; /// Password hashing errors. #[derive(Copy, Clone, Debug, Eq, PartialEq)] +// #[non_exhaustive] TODO(tarcieri): make non-exhaustive in next breaking release pub enum Error { /// Unsupported algorithm. Algorithm, diff --git a/password-hash/src/salt.rs b/password-hash/src/salt.rs index d73001980..ecdee2766 100644 --- a/password-hash/src/salt.rs +++ b/password-hash/src/salt.rs @@ -96,16 +96,17 @@ impl<'a> Salt<'a> { /// Create a [`Salt`] from the given `str`, validating it according to /// [`Salt::MIN_LENGTH`] and [`Salt::MAX_LENGTH`] length restrictions. pub fn new(input: &'a str) -> Result { - if input.len() < Self::MIN_LENGTH { + let length = input.as_bytes().len(); + + if length < Self::MIN_LENGTH { return Err(Error::SaltTooShort); } - if input.len() > Self::MAX_LENGTH { + if length > Self::MAX_LENGTH { return Err(Error::SaltTooLong); } - // TODO(tarcieri): revisit potentially bogus error handling - input.try_into().map(Self).map_err(|_| Error::SaltTooLong) + input.try_into().map(Self) } /// Attempt to decode a B64-encoded [`Salt`], writing the decoded result @@ -281,7 +282,7 @@ mod tests { #[test] fn reject_new_too_long() { - let s = "0123456789112345678921234567893123456789412345678"; + let s = "01234567891123456789212345678931234567894123456785234567896234567"; let err = Salt::new(s).err().unwrap(); assert_eq!(err, Error::SaltTooLong); } diff --git a/password-hash/src/value.rs b/password-hash/src/value.rs index 456aa3295..c97c23816 100644 --- a/password-hash/src/value.rs +++ b/password-hash/src/value.rs @@ -27,12 +27,12 @@ pub type Decimal = u32; /// - ASCII-encoded string consisting of the characters `[a-zA-Z0-9/+.-]` /// (lowercase letters, digits, and the minus sign) /// - Minimum length: 0 (i.e. empty values are allowed) -/// - Maximum length: 48 ASCII characters (i.e. 48-bytes) +/// - Maximum length: 64 ASCII characters (i.e. 64-bytes) /// /// # Additional Notes /// The PHC spec allows for algorithm-defined maximum lengths for parameter -/// values, however in the interest of interoperability this library defines a -/// [`Value::MAX_LENGTH`] of 48 ASCII characters. +/// values, however this library defines a [`Value::MAX_LENGTH`] of 64 ASCII +/// characters. /// /// [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md /// [2]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#argon2-encoding @@ -40,17 +40,11 @@ pub type Decimal = u32; pub struct Value<'a>(&'a str); impl<'a> Value<'a> { - /// Maximum length of an [`Value`] - 48 ASCII characters (i.e. 48-bytes). + /// Maximum length of an [`Value`] - 64 ASCII characters (i.e. 64-bytes). /// - /// This value is selected based on the maximum value size used in the - /// [Argon2 Encoding][1] as described in the PHC string format specification. - /// Namely the `data` parameter, when encoded as B64, can be up to 43 - /// characters. - /// - /// This implementation rounds that up to 48 as a safe maximum limit. - /// - /// [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md#argon2-encoding - pub const MAX_LENGTH: usize = 48; + /// This value is selected to match the maximum length of a [`Salt`], as this + /// library internally uses this type to represent salts. + pub const MAX_LENGTH: usize = 64; /// Parse a [`Value`] from the provided `str`, validating it according to /// the PHC string format's rules. @@ -218,8 +212,10 @@ mod tests { // Invalid value examples const INVALID_CHAR: &str = "x;y"; - const INVALID_TOO_LONG: &str = "0123456789112345678921234567893123456789412345678"; - const INVALID_CHAR_AND_TOO_LONG: &str = "0!23456789112345678921234567893123456789412345678"; + const INVALID_TOO_LONG: &str = + "01234567891123456789212345678931234567894123456785234567896234567"; + const INVALID_CHAR_AND_TOO_LONG: &str = + "0!234567891123456789212345678931234567894123456785234567896234567"; // // Decimal parsing tests From 7cf97d85c02eb21d895f930a2dae5c3f9c00a51b Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 23 Aug 2021 13:01:52 -0600 Subject: [PATCH 0572/1461] password-hash v0.2.3 (#708) --- Cargo.lock | 2 +- password-hash/CHANGELOG.md | 6 ++++++ password-hash/Cargo.toml | 4 ++-- password-hash/src/lib.rs | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dd117e929..fb8998997 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -325,7 +325,7 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "password-hash" -version = "0.2.2" +version = "0.2.3" dependencies = [ "base64ct", "rand_core", diff --git a/password-hash/CHANGELOG.md b/password-hash/CHANGELOG.md index 534c2747f..5e62d2bfa 100644 --- a/password-hash/CHANGELOG.md +++ b/password-hash/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.2.3 (2021-08-23) +### Changed +- Make max lengths of `Value` and `Salt` both 64 ([#707]) + +[#707]: https://github.com/RustCrypto/traits/pull/707 + ## 0.2.2 (2021-07-20) ### Changed - Pin `subtle` dependency to v2.4 ([#689]) diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index 88f2fbbeb..ab33b0679 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -5,7 +5,7 @@ Traits which describe the functionality of password hashing algorithms, as well as a `no_std`-friendly implementation of the PHC string format (a well-defined subset of the Modular Crypt Format a.k.a. MCF) """ -version = "0.2.2" # Also update html_root_url in lib.rs when bumping this +version = "0.2.3" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" @@ -17,7 +17,7 @@ keywords = ["crypt", "mcf", "password", "pbkdf", "phc"] [dependencies] base64ct = "1" -subtle = { version = "=2.4", default-features = false } +subtle = { version = ">=2, <2.5", default-features = false } # optional features rand_core = { version = "0.6", optional = true, default-features = false } diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index 4f7c3bc0a..054c9319a 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -39,7 +39,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/password-hash/0.2.2" + html_root_url = "https://docs.rs/password-hash/0.2.3" )] #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] From 08ac8c6f76db6a8eae9dd28402717d5bbef20b39 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 23 Aug 2021 18:19:11 -0600 Subject: [PATCH 0573/1461] elliptic-curve: bump `crypto-bigint` dependency to v0.2.4 (#710) This release includes some new features which can be used to calculate various constants from an elliptic curve's order using `const fn`s. Bumping the minimum release allows for elliptic curve libs to pin to a release of the `elliptic-curve` crate which includes this new version, allowing them to ensure the transitive dependency is up-to-date without explicitly pinning to it. --- Cargo.lock | 4 ++-- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fb8998997..3dbf5a3bd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -146,9 +146,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09910f0830248af4499907177608b81d640c8c404526f8770b87b765fbd8c9a5" +checksum = "cc209804a22c34a98fe26a32d997ac64d4284816f65cf1a529c4e31a256218a0" dependencies = [ "generic-array", "rand_core", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index b9d717e87..9ae402c0a 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -15,7 +15,7 @@ categories = ["cryptography", "no-std"] keywords = ["crypto", "ecc", "elliptic", "weierstrass"] [dependencies] -crypto-bigint = { version = "0.2.3", features = ["generic-array"] } +crypto-bigint = { version = "0.2.4", features = ["generic-array"] } generic-array = { version = "0.14", default-features = false } rand_core = { version = "0.6", default-features = false } subtle = { version = "=2.4", default-features = false } From 2df6e6c282eb32c267e5c3b42aa471e67386715d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 23 Aug 2021 18:49:51 -0600 Subject: [PATCH 0574/1461] elliptic-curve v0.10.6 (#711) --- Cargo.lock | 2 +- elliptic-curve/CHANGELOG.md | 6 ++++++ elliptic-curve/Cargo.toml | 4 ++-- elliptic-curve/src/lib.rs | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3dbf5a3bd..51f8cb2e2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -215,7 +215,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.10.5" +version = "0.10.6" dependencies = [ "base64ct", "crypto-bigint", diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index 7717b1f7b..a7e520862 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.10.6 (2021-08-23) +### Changed +- Bump `crypto-bigint` dependency to v0.2.4 ([#710]) + +[#710]: https://github.com/RustCrypto/traits/pull/710 + ## 0.10.5 (2021-07-20) ### Changed - Pin `zeroize` dependency to v1.4 and `subtle` to v2.4 ([#349]) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 9ae402c0a..eca853b34 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -5,7 +5,7 @@ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. """ -version = "0.10.5" # Also update html_root_url in lib.rs when bumping this +version = "0.10.6" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" repository = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve" @@ -28,7 +28,7 @@ hex-literal = { version = "0.3", optional = true } pkcs8 = { version = "0.7", optional = true } serde = { version = "1", optional = true, default-features = false } serde_json = { version = "1", optional = true, default-features = false, features = ["alloc"] } -zeroize = { version = "=1.4", optional = true, default-features = false } +zeroize = { version = ">=1, <1.5", optional = true, default-features = false } [dev-dependencies] hex-literal = "0.3" diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index aa14d7ace..0ebc96a89 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -16,7 +16,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.10.5" + html_root_url = "https://docs.rs/elliptic-curve/0.10.6" )] #[cfg(feature = "alloc")] From a92e5cd725cdd7695be6dc6faa96b41e79d9b8bc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Aug 2021 03:02:40 +0000 Subject: [PATCH 0575/1461] build(deps): bump serde from 1.0.127 to 1.0.129 (#712) --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 51f8cb2e2..45f43ebd7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -394,9 +394,9 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "serde" -version = "1.0.127" +version = "1.0.129" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f03b9878abf6d14e6779d3f24f07b2cfa90352cfec4acc5aab8f1ac7f146fae8" +checksum = "d1f72836d2aa753853178eda473a3b9d8e4eefdaf20523b919677e6de489f8f1" [[package]] name = "serde_json" From 67f2cb48e2ae7988403c0fa511a60b2eb8e1dbd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szymon=20Giba=C5=82a?= Date: Wed, 25 Aug 2021 21:12:02 +0200 Subject: [PATCH 0576/1461] feat: Add more details to `ParamValueInvalid` and introduce `SaltInvalid` error (#713) --- password-hash/src/errors.rs | 36 +++++++++++++++++++++++++++--------- password-hash/src/params.rs | 9 ++++++--- password-hash/src/salt.rs | 26 +++++++++++++++++++------- password-hash/src/value.rs | 36 +++++++++++++++++++++++------------- 4 files changed, 75 insertions(+), 32 deletions(-) diff --git a/password-hash/src/errors.rs b/password-hash/src/errors.rs index ceb317797..3da58f7ad 100644 --- a/password-hash/src/errors.rs +++ b/password-hash/src/errors.rs @@ -33,7 +33,7 @@ pub enum Error { ParamNameInvalid, /// Invalid parameter value. - ParamValueInvalid, + ParamValueInvalid(InvalidValue), /// Maximum number of parameters exceeded. ParamsMaxExceeded, @@ -50,11 +50,8 @@ pub enum Error { /// Password hash string too long. PhcStringTooLong, - /// Salt too short. - SaltTooShort, - - /// Salt too long. - SaltTooLong, + /// Salt invalid. + SaltInvalid(InvalidValue), /// Invalid algorithm version. Version, @@ -70,14 +67,13 @@ impl fmt::Display for Error { Self::OutputTooLong => f.write_str("PHF output too long (max 64-bytes)"), Self::ParamNameDuplicated => f.write_str("duplicate parameter"), Self::ParamNameInvalid => f.write_str("invalid parameter name"), - Self::ParamValueInvalid => f.write_str("invalid parameter value"), + Self::ParamValueInvalid(val_err) => write!(f, "invalid parameter value: {}", val_err), Self::ParamsMaxExceeded => f.write_str("maximum number of parameters reached"), Self::Password => write!(f, "invalid password"), Self::PhcStringInvalid => write!(f, "password hash string invalid"), Self::PhcStringTooShort => write!(f, "password hash string too short"), Self::PhcStringTooLong => write!(f, "password hash string too long"), - Self::SaltTooShort => write!(f, "salt too short"), - Self::SaltTooLong => write!(f, "salt too long"), + Self::SaltInvalid(val_err) => write!(f, "salt invalid: {}", val_err), Self::Version => write!(f, "invalid algorithm version"), } } @@ -97,3 +93,25 @@ impl From for Error { Error::B64(B64Error::InvalidLength) } } + +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[non_exhaustive] +pub enum InvalidValue { + ToLong, + ToShort, + NotProvided, + InvalidChar, + InvalidFormat, +} + +impl fmt::Display for InvalidValue { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> core::result::Result<(), fmt::Error> { + match self { + Self::ToLong => f.write_str("value to long"), + Self::ToShort => f.write_str("value to short"), + Self::NotProvided => f.write_str("required value not provided"), + Self::InvalidChar => f.write_str("contains invalid character"), + Self::InvalidFormat => f.write_str("value format is invalid"), + } + } +} diff --git a/password-hash/src/params.rs b/password-hash/src/params.rs index 66767dafd..0b71926f1 100644 --- a/password-hash/src/params.rs +++ b/password-hash/src/params.rs @@ -1,5 +1,6 @@ //! Algorithm parameters. +use crate::errors::InvalidValue; use crate::{ value::{Decimal, Value}, Error, Ident, Result, @@ -56,7 +57,9 @@ impl ParamsString { value: impl TryInto>, ) -> Result<()> { let name = name.try_into().map_err(|_| Error::ParamNameInvalid)?; - let value = value.try_into().map_err(|_| Error::ParamValueInvalid)?; + let value = value + .try_into() + .map_err(|_| Error::ParamValueInvalid(InvalidValue::InvalidFormat))?; self.add(name, value) } @@ -162,11 +165,11 @@ impl FromStr for ParamsString { // Validate value param .next() - .ok_or(Error::ParamValueInvalid) + .ok_or(Error::ParamValueInvalid(InvalidValue::NotProvided)) .and_then(Value::try_from)?; if param.next().is_some() { - return Err(Error::ParamValueInvalid); + return Err(Error::ParamValueInvalid(InvalidValue::NotProvided)); } } diff --git a/password-hash/src/salt.rs b/password-hash/src/salt.rs index ecdee2766..af56865e3 100644 --- a/password-hash/src/salt.rs +++ b/password-hash/src/salt.rs @@ -6,6 +6,7 @@ use core::{ fmt, str, }; +use crate::errors::InvalidValue; #[cfg(feature = "rand_core")] use rand_core::{CryptoRng, RngCore}; @@ -99,14 +100,17 @@ impl<'a> Salt<'a> { let length = input.as_bytes().len(); if length < Self::MIN_LENGTH { - return Err(Error::SaltTooShort); + return Err(Error::SaltInvalid(InvalidValue::ToShort)); } if length > Self::MAX_LENGTH { - return Err(Error::SaltTooLong); + return Err(Error::SaltInvalid(InvalidValue::ToLong)); } - input.try_into().map(Self) + input.try_into().map(Self).map_err(|e| match e { + Error::ParamValueInvalid(value_err) => Error::SaltInvalid(value_err), + err => err, + }) } /// Attempt to decode a B64-encoded [`Salt`], writing the decoded result @@ -183,7 +187,7 @@ impl SaltString { /// Create a new [`SaltString`]. pub fn new(s: &str) -> Result { - // Assert `s` parses successifully as a `Salt` + // Assert `s` parses successfully as a `Salt` Salt::new(s)?; let length = s.as_bytes().len(); @@ -196,7 +200,7 @@ impl SaltString { length: length as u8, }) } else { - Err(Error::SaltTooLong) + Err(Error::SaltInvalid(InvalidValue::ToLong)) } } @@ -257,6 +261,7 @@ impl<'a> From<&'a SaltString> for Salt<'a> { #[cfg(test)] mod tests { use super::{Error, Salt}; + use crate::errors::InvalidValue; #[test] fn new_with_valid_min_length_input() { @@ -276,7 +281,7 @@ mod tests { fn reject_new_too_short() { for &too_short in &["", "a", "ab", "abc"] { let err = Salt::new(too_short).err().unwrap(); - assert_eq!(err, Error::SaltTooShort); + assert_eq!(err, Error::SaltInvalid(InvalidValue::ToShort)); } } @@ -284,6 +289,13 @@ mod tests { fn reject_new_too_long() { let s = "01234567891123456789212345678931234567894123456785234567896234567"; let err = Salt::new(s).err().unwrap(); - assert_eq!(err, Error::SaltTooLong); + assert_eq!(err, Error::SaltInvalid(InvalidValue::ToLong)); + } + + #[test] + fn reject_new_invalid_char() { + let s = "01234_abcd"; + let err = Salt::new(s).err().unwrap(); + assert_eq!(err, Error::SaltInvalid(InvalidValue::InvalidChar)); } } diff --git a/password-hash/src/value.rs b/password-hash/src/value.rs index c97c23816..ae54945a8 100644 --- a/password-hash/src/value.rs +++ b/password-hash/src/value.rs @@ -13,6 +13,7 @@ //! //! [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md +use crate::errors::InvalidValue; use crate::{Encoding, Error, Result}; use core::{convert::TryFrom, fmt, str}; @@ -50,7 +51,7 @@ impl<'a> Value<'a> { /// the PHC string format's rules. pub fn new(input: &'a str) -> Result { if input.as_bytes().len() > Self::MAX_LENGTH { - return Err(Error::ParamValueInvalid); + return Err(Error::ParamValueInvalid(InvalidValue::ToLong)); } // Check that the characters are permitted in a PHC parameter value. @@ -124,26 +125,26 @@ impl<'a> Value<'a> { // Empty strings aren't decimals if value.is_empty() { - return Err(Error::ParamValueInvalid); + return Err(Error::ParamValueInvalid(InvalidValue::NotProvided)); } // Ensure all characters are digits for c in value.chars() { if !matches!(c, '0'..='9') { - return Err(Error::ParamValueInvalid); + return Err(Error::ParamValueInvalid(InvalidValue::InvalidChar)); } } // Disallow leading zeroes if value.starts_with('0') && value.len() > 1 { - return Err(Error::ParamValueInvalid); + return Err(Error::ParamValueInvalid(InvalidValue::InvalidFormat)); } value.parse().map_err(|_| { // In theory a value overflow should be the only potential error here. // When `ParseIntError::kind` is stable it might be good to double check: // - Error::ParamValueInvalid + Error::ParamValueInvalid(InvalidValue::InvalidFormat) }) } @@ -193,7 +194,7 @@ impl<'a> fmt::Display for Value<'a> { fn assert_valid_value(input: &str) -> Result<()> { for c in input.chars() { if !is_char_valid(c) { - return Err(Error::ParamValueInvalid); + return Err(Error::ParamValueInvalid(InvalidValue::InvalidChar)); } } @@ -207,7 +208,7 @@ fn is_char_valid(c: char) -> bool { #[cfg(test)] mod tests { - use super::{Error, Value}; + use super::{Error, InvalidValue, Value}; use core::convert::TryFrom; // Invalid value examples @@ -236,21 +237,27 @@ mod tests { fn reject_decimal_with_leading_zero() { let value = Value::new("01").unwrap(); let err = u32::try_from(value).err().unwrap(); - assert!(matches!(err, Error::ParamValueInvalid)); + assert!(matches!( + err, + Error::ParamValueInvalid(InvalidValue::InvalidFormat) + )); } #[test] fn reject_overlong_decimal() { let value = Value::new("4294967296").unwrap(); let err = u32::try_from(value).err().unwrap(); - assert_eq!(err, Error::ParamValueInvalid); + assert_eq!(err, Error::ParamValueInvalid(InvalidValue::InvalidFormat)); } #[test] fn reject_negative() { let value = Value::new("-1").unwrap(); let err = u32::try_from(value).err().unwrap(); - assert!(matches!(err, Error::ParamValueInvalid)); + assert!(matches!( + err, + Error::ParamValueInvalid(InvalidValue::InvalidChar) + )); } // @@ -278,18 +285,21 @@ mod tests { #[test] fn reject_invalid_char() { let err = Value::new(INVALID_CHAR).err().unwrap(); - assert!(matches!(err, Error::ParamValueInvalid)); + assert!(matches!( + err, + Error::ParamValueInvalid(InvalidValue::InvalidChar) + )); } #[test] fn reject_too_long() { let err = Value::new(INVALID_TOO_LONG).err().unwrap(); - assert_eq!(err, Error::ParamValueInvalid); + assert_eq!(err, Error::ParamValueInvalid(InvalidValue::ToLong)); } #[test] fn reject_invalid_char_and_too_long() { let err = Value::new(INVALID_CHAR_AND_TOO_LONG).err().unwrap(); - assert_eq!(err, Error::ParamValueInvalid); + assert_eq!(err, Error::ParamValueInvalid(InvalidValue::ToLong)); } } From e807f026cd47a16b85e8eceee1f9b2f8b7a4f48e Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 25 Aug 2021 23:27:22 -0600 Subject: [PATCH 0577/1461] password-hash: minor fixes for `InvalidValue` (#714) - Make `errors` module public, allowing access to `InvalidValue` - Add rustdoc documentation for `InvalidValue` - Don't re-export `B64Error` at the toplevel now that `errors` is pub - Fix a few typos --- password-hash/src/encoding.rs | 5 +++-- password-hash/src/errors.rs | 21 ++++++++++++++++----- password-hash/src/lib.rs | 5 +++-- password-hash/src/salt.rs | 10 +++++----- password-hash/src/value.rs | 10 +++++----- 5 files changed, 32 insertions(+), 19 deletions(-) diff --git a/password-hash/src/encoding.rs b/password-hash/src/encoding.rs index 56fa4643b..a2689999c 100644 --- a/password-hash/src/encoding.rs +++ b/password-hash/src/encoding.rs @@ -1,7 +1,8 @@ //! Base64 encoding variants. -use crate::B64Error; -use base64ct::{Base64Bcrypt, Base64Crypt, Base64Unpadded as B64, Encoding as _}; +use base64ct::{ + Base64Bcrypt, Base64Crypt, Base64Unpadded as B64, Encoding as _, Error as B64Error, +}; /// Base64 encoding variants. #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] diff --git a/password-hash/src/errors.rs b/password-hash/src/errors.rs index 3da58f7ad..4d183ebbc 100644 --- a/password-hash/src/errors.rs +++ b/password-hash/src/errors.rs @@ -9,7 +9,7 @@ pub type Result = core::result::Result; /// Password hashing errors. #[derive(Copy, Clone, Debug, Eq, PartialEq)] -// #[non_exhaustive] TODO(tarcieri): make non-exhaustive in next breaking release +#[non_exhaustive] pub enum Error { /// Unsupported algorithm. Algorithm, @@ -94,21 +94,32 @@ impl From for Error { } } +/// Parse errors relating to invalid parameter values or salts. #[derive(Copy, Clone, Debug, Eq, PartialEq)] #[non_exhaustive] pub enum InvalidValue { - ToLong, - ToShort, + /// Value exceeds the maximum allowed length. + TooLong, + + /// Value does not satisfy the minimum length. + TooShort, + + /// Unspecified error. + // TODO(tarcieri): specify all error cases NotProvided, + + /// Character is not in the allowed set. InvalidChar, + + /// Format is invalid. InvalidFormat, } impl fmt::Display for InvalidValue { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> core::result::Result<(), fmt::Error> { match self { - Self::ToLong => f.write_str("value to long"), - Self::ToShort => f.write_str("value to short"), + Self::TooLong => f.write_str("value to long"), + Self::TooShort => f.write_str("value to short"), Self::NotProvided => f.write_str("required value not provided"), Self::InvalidChar => f.write_str("contains invalid character"), Self::InvalidFormat => f.write_str("value format is invalid"), diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index 054c9319a..446a1c53f 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -54,8 +54,9 @@ extern crate std; #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] pub use rand_core; +pub mod errors; + mod encoding; -mod errors; mod ident; mod output; mod params; @@ -64,7 +65,7 @@ mod value; pub use crate::{ encoding::Encoding, - errors::{B64Error, Error, Result}, + errors::{Error, Result}, ident::Ident, output::Output, params::ParamsString, diff --git a/password-hash/src/salt.rs b/password-hash/src/salt.rs index af56865e3..5d9b78be9 100644 --- a/password-hash/src/salt.rs +++ b/password-hash/src/salt.rs @@ -100,11 +100,11 @@ impl<'a> Salt<'a> { let length = input.as_bytes().len(); if length < Self::MIN_LENGTH { - return Err(Error::SaltInvalid(InvalidValue::ToShort)); + return Err(Error::SaltInvalid(InvalidValue::TooShort)); } if length > Self::MAX_LENGTH { - return Err(Error::SaltInvalid(InvalidValue::ToLong)); + return Err(Error::SaltInvalid(InvalidValue::TooLong)); } input.try_into().map(Self).map_err(|e| match e { @@ -200,7 +200,7 @@ impl SaltString { length: length as u8, }) } else { - Err(Error::SaltInvalid(InvalidValue::ToLong)) + Err(Error::SaltInvalid(InvalidValue::TooLong)) } } @@ -281,7 +281,7 @@ mod tests { fn reject_new_too_short() { for &too_short in &["", "a", "ab", "abc"] { let err = Salt::new(too_short).err().unwrap(); - assert_eq!(err, Error::SaltInvalid(InvalidValue::ToShort)); + assert_eq!(err, Error::SaltInvalid(InvalidValue::TooShort)); } } @@ -289,7 +289,7 @@ mod tests { fn reject_new_too_long() { let s = "01234567891123456789212345678931234567894123456785234567896234567"; let err = Salt::new(s).err().unwrap(); - assert_eq!(err, Error::SaltInvalid(InvalidValue::ToLong)); + assert_eq!(err, Error::SaltInvalid(InvalidValue::TooLong)); } #[test] diff --git a/password-hash/src/value.rs b/password-hash/src/value.rs index ae54945a8..ea735c602 100644 --- a/password-hash/src/value.rs +++ b/password-hash/src/value.rs @@ -43,15 +43,15 @@ pub struct Value<'a>(&'a str); impl<'a> Value<'a> { /// Maximum length of an [`Value`] - 64 ASCII characters (i.e. 64-bytes). /// - /// This value is selected to match the maximum length of a [`Salt`], as this - /// library internally uses this type to represent salts. + /// This value is selected to match the maximum length of a [`Salt`][`crate::Salt`] + /// as this library internally uses this type to represent salts. pub const MAX_LENGTH: usize = 64; /// Parse a [`Value`] from the provided `str`, validating it according to /// the PHC string format's rules. pub fn new(input: &'a str) -> Result { if input.as_bytes().len() > Self::MAX_LENGTH { - return Err(Error::ParamValueInvalid(InvalidValue::ToLong)); + return Err(Error::ParamValueInvalid(InvalidValue::TooLong)); } // Check that the characters are permitted in a PHC parameter value. @@ -294,12 +294,12 @@ mod tests { #[test] fn reject_too_long() { let err = Value::new(INVALID_TOO_LONG).err().unwrap(); - assert_eq!(err, Error::ParamValueInvalid(InvalidValue::ToLong)); + assert_eq!(err, Error::ParamValueInvalid(InvalidValue::TooLong)); } #[test] fn reject_invalid_char_and_too_long() { let err = Value::new(INVALID_CHAR_AND_TOO_LONG).err().unwrap(); - assert_eq!(err, Error::ParamValueInvalid(InvalidValue::ToLong)); + assert_eq!(err, Error::ParamValueInvalid(InvalidValue::TooLong)); } } From 94a31d77a77a986925a9ada35271319f178d0ed0 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 25 Aug 2021 23:44:19 -0600 Subject: [PATCH 0578/1461] password-hash: `error::InvalidValue` improvements (#715) - Rename `NotProvided` variant to `Malformed` - Have `InvalidChar` include the character which was considered invalid --- password-hash/src/errors.rs | 25 ++++++++++++------------- password-hash/src/params.rs | 4 ++-- password-hash/src/salt.rs | 2 +- password-hash/src/value.rs | 10 +++++----- 4 files changed, 20 insertions(+), 21 deletions(-) diff --git a/password-hash/src/errors.rs b/password-hash/src/errors.rs index 4d183ebbc..7b03ff07e 100644 --- a/password-hash/src/errors.rs +++ b/password-hash/src/errors.rs @@ -98,31 +98,30 @@ impl From for Error { #[derive(Copy, Clone, Debug, Eq, PartialEq)] #[non_exhaustive] pub enum InvalidValue { + /// Character is not in the allowed set. + InvalidChar(char), + + /// Format is invalid. + InvalidFormat, + + /// Value is malformed. + Malformed, + /// Value exceeds the maximum allowed length. TooLong, /// Value does not satisfy the minimum length. TooShort, - - /// Unspecified error. - // TODO(tarcieri): specify all error cases - NotProvided, - - /// Character is not in the allowed set. - InvalidChar, - - /// Format is invalid. - InvalidFormat, } impl fmt::Display for InvalidValue { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> core::result::Result<(), fmt::Error> { match self { + Self::InvalidChar(c) => write!(f, "contains invalid character: '{}'", c), + Self::InvalidFormat => f.write_str("value format is invalid"), + Self::Malformed => f.write_str("value malformed"), Self::TooLong => f.write_str("value to long"), Self::TooShort => f.write_str("value to short"), - Self::NotProvided => f.write_str("required value not provided"), - Self::InvalidChar => f.write_str("contains invalid character"), - Self::InvalidFormat => f.write_str("value format is invalid"), } } } diff --git a/password-hash/src/params.rs b/password-hash/src/params.rs index 0b71926f1..49cf774ee 100644 --- a/password-hash/src/params.rs +++ b/password-hash/src/params.rs @@ -165,11 +165,11 @@ impl FromStr for ParamsString { // Validate value param .next() - .ok_or(Error::ParamValueInvalid(InvalidValue::NotProvided)) + .ok_or(Error::ParamValueInvalid(InvalidValue::Malformed)) .and_then(Value::try_from)?; if param.next().is_some() { - return Err(Error::ParamValueInvalid(InvalidValue::NotProvided)); + return Err(Error::ParamValueInvalid(InvalidValue::Malformed)); } } diff --git a/password-hash/src/salt.rs b/password-hash/src/salt.rs index 5d9b78be9..bf5bf8137 100644 --- a/password-hash/src/salt.rs +++ b/password-hash/src/salt.rs @@ -296,6 +296,6 @@ mod tests { fn reject_new_invalid_char() { let s = "01234_abcd"; let err = Salt::new(s).err().unwrap(); - assert_eq!(err, Error::SaltInvalid(InvalidValue::InvalidChar)); + assert_eq!(err, Error::SaltInvalid(InvalidValue::InvalidChar('_'))); } } diff --git a/password-hash/src/value.rs b/password-hash/src/value.rs index ea735c602..5a453c0f8 100644 --- a/password-hash/src/value.rs +++ b/password-hash/src/value.rs @@ -125,13 +125,13 @@ impl<'a> Value<'a> { // Empty strings aren't decimals if value.is_empty() { - return Err(Error::ParamValueInvalid(InvalidValue::NotProvided)); + return Err(Error::ParamValueInvalid(InvalidValue::Malformed)); } // Ensure all characters are digits for c in value.chars() { if !matches!(c, '0'..='9') { - return Err(Error::ParamValueInvalid(InvalidValue::InvalidChar)); + return Err(Error::ParamValueInvalid(InvalidValue::InvalidChar(c))); } } @@ -194,7 +194,7 @@ impl<'a> fmt::Display for Value<'a> { fn assert_valid_value(input: &str) -> Result<()> { for c in input.chars() { if !is_char_valid(c) { - return Err(Error::ParamValueInvalid(InvalidValue::InvalidChar)); + return Err(Error::ParamValueInvalid(InvalidValue::InvalidChar(c))); } } @@ -256,7 +256,7 @@ mod tests { let err = u32::try_from(value).err().unwrap(); assert!(matches!( err, - Error::ParamValueInvalid(InvalidValue::InvalidChar) + Error::ParamValueInvalid(InvalidValue::InvalidChar(_)) )); } @@ -287,7 +287,7 @@ mod tests { let err = Value::new(INVALID_CHAR).err().unwrap(); assert!(matches!( err, - Error::ParamValueInvalid(InvalidValue::InvalidChar) + Error::ParamValueInvalid(InvalidValue::InvalidChar(_)) )); } From d8d3a5531f9495b0fa0b73ce4635c540d8b26202 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 25 Aug 2021 23:53:27 -0600 Subject: [PATCH 0579/1461] password-hash v0.3.0-pre.1 (#716) --- Cargo.lock | 2 +- crypto/Cargo.toml | 2 +- password-hash/Cargo.toml | 2 +- password-hash/src/lib.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 45f43ebd7..62f86a23f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -325,7 +325,7 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "password-hash" -version = "0.2.3" +version = "0.3.0-pre.1" dependencies = [ "base64ct", "rand_core", diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index fbe9fc58c..439e8bd06 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -19,7 +19,7 @@ cipher = { version = "0.3", optional = true } digest = { version = "0.9", optional = true } elliptic-curve = { version = "0.10", optional = true, path = "../elliptic-curve" } mac = { version = "0.11", package = "crypto-mac", optional = true } -password-hash = { version = "0.2", optional = true, path = "../password-hash" } +password-hash = { version = "=0.3.0-pre.1", optional = true, path = "../password-hash" } signature = { version = "1.3.0", optional = true, default-features = false, path = "../signature" } universal-hash = { version = "0.4", optional = true, path = "../universal-hash" } diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index ab33b0679..cf15029ed 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -5,7 +5,7 @@ Traits which describe the functionality of password hashing algorithms, as well as a `no_std`-friendly implementation of the PHC string format (a well-defined subset of the Modular Crypt Format a.k.a. MCF) """ -version = "0.2.3" # Also update html_root_url in lib.rs when bumping this +version = "0.3.0-pre.1" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index 446a1c53f..f04b33423 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -39,7 +39,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/password-hash/0.2.3" + html_root_url = "https://docs.rs/password-hash/0.3.0-pre.1" )] #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] From d2186f94f53eee706248e54bf014973872ce6281 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 26 Aug 2021 14:06:16 -0600 Subject: [PATCH 0580/1461] password-hash: move traits to module (#717) Clean up lib.rs by factoring trait definitions under a module --- password-hash/src/lib.rs | 99 +--------------------------------- password-hash/src/traits.rs | 104 ++++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+), 97 deletions(-) create mode 100644 password-hash/src/traits.rs diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index f04b33423..d5bc7faab 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -61,6 +61,7 @@ mod ident; mod output; mod params; mod salt; +mod traits; mod value; pub use crate::{ @@ -70,6 +71,7 @@ pub use crate::{ output::Output, params::ParamsString, salt::{Salt, SaltString}, + traits::{McfHasher, PasswordHasher, PasswordVerifier}, value::{Decimal, Value}, }; @@ -81,103 +83,6 @@ use core::{ /// Separator character used in password hashes (e.g. `$6$...`). const PASSWORD_HASH_SEPARATOR: char = '$'; -/// Trait for password hashing functions. -pub trait PasswordHasher { - /// Algorithm-specific parameters. - type Params: Clone - + Debug - + Default - + for<'a> TryFrom<&'a PasswordHash<'a>, Error = Error> - + for<'a> TryInto; - - /// Simple API for computing a [`PasswordHash`] from a password and - /// [`Salt`] value. - /// - /// Uses the default recommended parameters for a given algorithm. - fn hash_password_simple<'a, S>(&self, password: &[u8], salt: &'a S) -> Result> - where - S: AsRef + ?Sized, - { - self.hash_password( - password, - None, - Self::Params::default(), - Salt::try_from(salt.as_ref())?, - ) - } - - /// Compute a [`PasswordHash`] with the given algorithm [`Ident`] - /// (or `None` for the recommended default), password, salt, and - /// parameters. - fn hash_password<'a>( - &self, - password: &[u8], - algorithm: Option>, - params: Self::Params, - salt: impl Into>, - ) -> Result>; -} - -/// Trait for password verification. -/// -/// Automatically impl'd for any type that impls [`PasswordHasher`]. -/// -/// This trait is object safe and can be used to implement abstractions over -/// multiple password hashing algorithms. One such abstraction is provided by -/// the [`PasswordHash::verify_password`] method. -pub trait PasswordVerifier { - /// Compute this password hashing function against the provided password - /// using the parameters from the provided password hash and see if the - /// computed output matches. - fn verify_password(&self, password: &[u8], hash: &PasswordHash<'_>) -> Result<()>; -} - -impl PasswordVerifier for T { - fn verify_password(&self, password: &[u8], hash: &PasswordHash<'_>) -> Result<()> { - if let (Some(salt), Some(expected_output)) = (&hash.salt, &hash.hash) { - let computed_hash = self.hash_password( - password, - Some(hash.algorithm), - T::Params::try_from(&hash)?, - *salt, - )?; - - if let Some(computed_output) = &computed_hash.hash { - // See notes on `Output` about the use of a constant-time comparison - if expected_output == computed_output { - return Ok(()); - } - } - } - - Err(Error::Password) - } -} - -/// Trait for password hashing algorithms which support the legacy -/// [Modular Crypt Format (MCF)][MCF]. -/// -/// [MCF]: https://passlib.readthedocs.io/en/stable/modular_crypt_format.html -pub trait McfHasher { - /// Upgrade an MCF hash to a PHC hash. MCF follow this rough format: - /// - /// ```text - /// $$ - /// ``` - /// - /// MCF hashes are otherwise largely unstructured and parsed according to - /// algorithm-specific rules so hashers must parse a raw string themselves. - fn upgrade_mcf_hash<'a>(&self, hash: &'a str) -> Result>; - - /// Verify a password hash in MCF format against the provided password. - fn verify_mcf_hash(&self, password: &[u8], mcf_hash: &str) -> Result<()> - where - Self: PasswordVerifier, - { - self.verify_password(password, &self.upgrade_mcf_hash(mcf_hash)?) - } -} - /// Password hash. /// /// This type corresponds to the parsed representation of a PHC string as diff --git a/password-hash/src/traits.rs b/password-hash/src/traits.rs new file mode 100644 index 000000000..12e244164 --- /dev/null +++ b/password-hash/src/traits.rs @@ -0,0 +1,104 @@ +//! Trait definitions. + +use crate::{Error, Ident, ParamsString, PasswordHash, Result, Salt}; +use core::{ + convert::{TryFrom, TryInto}, + fmt::Debug, +}; + +/// Trait for password hashing functions. +pub trait PasswordHasher { + /// Algorithm-specific parameters. + type Params: Clone + + Debug + + Default + + for<'a> TryFrom<&'a PasswordHash<'a>, Error = Error> + + for<'a> TryInto; + + /// Simple API for computing a [`PasswordHash`] from a password and + /// [`Salt`] value. + /// + /// Uses the default recommended parameters for a given algorithm. + fn hash_password_simple<'a, S>(&self, password: &[u8], salt: &'a S) -> Result> + where + S: AsRef + ?Sized, + { + self.hash_password( + password, + None, + Self::Params::default(), + Salt::try_from(salt.as_ref())?, + ) + } + + /// Compute a [`PasswordHash`] with the given algorithm [`Ident`] + /// (or `None` for the recommended default), password, salt, and + /// parameters. + fn hash_password<'a>( + &self, + password: &[u8], + algorithm: Option>, + params: Self::Params, + salt: impl Into>, + ) -> Result>; +} + +/// Trait for password verification. +/// +/// Automatically impl'd for any type that impls [`PasswordHasher`]. +/// +/// This trait is object safe and can be used to implement abstractions over +/// multiple password hashing algorithms. One such abstraction is provided by +/// the [`PasswordHash::verify_password`] method. +pub trait PasswordVerifier { + /// Compute this password hashing function against the provided password + /// using the parameters from the provided password hash and see if the + /// computed output matches. + fn verify_password(&self, password: &[u8], hash: &PasswordHash<'_>) -> Result<()>; +} + +impl PasswordVerifier for T { + fn verify_password(&self, password: &[u8], hash: &PasswordHash<'_>) -> Result<()> { + if let (Some(salt), Some(expected_output)) = (&hash.salt, &hash.hash) { + let computed_hash = self.hash_password( + password, + Some(hash.algorithm), + T::Params::try_from(&hash)?, + *salt, + )?; + + if let Some(computed_output) = &computed_hash.hash { + // See notes on `Output` about the use of a constant-time comparison + if expected_output == computed_output { + return Ok(()); + } + } + } + + Err(Error::Password) + } +} + +/// Trait for password hashing algorithms which support the legacy +/// [Modular Crypt Format (MCF)][MCF]. +/// +/// [MCF]: https://passlib.readthedocs.io/en/stable/modular_crypt_format.html +pub trait McfHasher { + /// Upgrade an MCF hash to a PHC hash. MCF follow this rough format: + /// + /// ```text + /// $$ + /// ``` + /// + /// MCF hashes are otherwise largely unstructured and parsed according to + /// algorithm-specific rules so hashers must parse a raw string themselves. + fn upgrade_mcf_hash<'a>(&self, hash: &'a str) -> Result>; + + /// Verify a password hash in MCF format against the provided password. + fn verify_mcf_hash(&self, password: &[u8], mcf_hash: &str) -> Result<()> + where + Self: PasswordVerifier, + { + self.verify_password(password, &self.upgrade_mcf_hash(mcf_hash)?) + } +} From 4d348fb1559933493fd45717c5da42c83969f5c8 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 26 Aug 2021 14:17:29 -0600 Subject: [PATCH 0581/1461] password-hash: add helper methods to `InvalidValue` (#718) Simplifies constructing an appropriate `password_hash::Error` from an `InvalidValue` enum. --- password-hash/src/errors.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/password-hash/src/errors.rs b/password-hash/src/errors.rs index 7b03ff07e..552fab5ef 100644 --- a/password-hash/src/errors.rs +++ b/password-hash/src/errors.rs @@ -114,6 +114,18 @@ pub enum InvalidValue { TooShort, } +impl InvalidValue { + /// Create an [`Error::ParamValueInvalid`] which warps this error. + pub fn param_error(self) -> Error { + Error::ParamValueInvalid(self) + } + + /// Create an [`Error::SaltInvalid`] which wraps this error. + pub fn salt_error(self) -> Error { + Error::SaltInvalid(self) + } +} + impl fmt::Display for InvalidValue { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> core::result::Result<(), fmt::Error> { match self { From 82c343a50b90b9080b29ee023f4c12bfb488c46b Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 26 Aug 2021 21:29:57 -0600 Subject: [PATCH 0582/1461] password-hash: add `version` param to `PasswordHasher` (#719) This makes the `hash_password` method reflect all of the potential parameters to a `PasswordHash`. --- password-hash/src/traits.rs | 5 ++++- password-hash/tests/hashing.rs | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/password-hash/src/traits.rs b/password-hash/src/traits.rs index 12e244164..ab20a1f25 100644 --- a/password-hash/src/traits.rs +++ b/password-hash/src/traits.rs @@ -1,6 +1,6 @@ //! Trait definitions. -use crate::{Error, Ident, ParamsString, PasswordHash, Result, Salt}; +use crate::{Decimal, Error, Ident, ParamsString, PasswordHash, Result, Salt}; use core::{ convert::{TryFrom, TryInto}, fmt::Debug, @@ -26,6 +26,7 @@ pub trait PasswordHasher { self.hash_password( password, None, + None, Self::Params::default(), Salt::try_from(salt.as_ref())?, ) @@ -38,6 +39,7 @@ pub trait PasswordHasher { &self, password: &[u8], algorithm: Option>, + version: Option, params: Self::Params, salt: impl Into>, ) -> Result>; @@ -63,6 +65,7 @@ impl PasswordVerifier for T { let computed_hash = self.hash_password( password, Some(hash.algorithm), + hash.version, T::Params::try_from(&hash)?, *salt, )?; diff --git a/password-hash/tests/hashing.rs b/password-hash/tests/hashing.rs index 532a43cac..b0b29ab51 100644 --- a/password-hash/tests/hashing.rs +++ b/password-hash/tests/hashing.rs @@ -17,6 +17,7 @@ impl PasswordHasher for StubPasswordHasher { &self, password: &[u8], algorithm: Option>, + version: Option, params: StubParams, salt: impl Into>, ) -> Result> { @@ -37,7 +38,7 @@ impl PasswordHasher for StubPasswordHasher { Ok(PasswordHash { algorithm: ALG, - version: None, + version, params: params.try_into()?, salt: Some(salt), hash: Some(hash), From 9e0de9d0aa33f0a7c687d7ae0809e3194027ba6c Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 26 Aug 2021 21:52:13 -0600 Subject: [PATCH 0583/1461] password-hash: refactor `PasswordHasher` (#720) - Renames `hash_password` => `hash_password_customized` - Renames `hash_password_simple` => `hash_password` - Adds a `version` param to `hash_password_customized` A main goal of this commit is to make the method with the shortest name the recommended a simplest to use. --- password-hash/src/lib.rs | 2 +- password-hash/src/traits.rs | 34 ++++++++++++++++++---------------- password-hash/tests/hashing.rs | 2 +- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index d5bc7faab..f8a82c7dc 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -227,7 +227,7 @@ impl<'a> PasswordHash<'a> { password: impl AsRef<[u8]>, salt: &'a str, ) -> Result { - phf.hash_password_simple(password.as_ref(), salt) + phf.hash_password(password.as_ref(), salt) } /// Verify this password hash using the specified set of supported diff --git a/password-hash/src/traits.rs b/password-hash/src/traits.rs index ab20a1f25..2501fdc15 100644 --- a/password-hash/src/traits.rs +++ b/password-hash/src/traits.rs @@ -15,15 +15,29 @@ pub trait PasswordHasher { + for<'a> TryFrom<&'a PasswordHash<'a>, Error = Error> + for<'a> TryInto; + /// Compute a [`PasswordHash`] from the provided password using an + /// explicit set of customized algorithm parameters as opposed to the + /// defaults. + /// + /// When in doubt, use [`PasswordHasher::hash_password`] instead. + fn hash_password_customized<'a>( + &self, + password: &[u8], + algorithm: Option>, + version: Option, + params: Self::Params, + salt: impl Into>, + ) -> Result>; + /// Simple API for computing a [`PasswordHash`] from a password and - /// [`Salt`] value. + /// salt value. /// /// Uses the default recommended parameters for a given algorithm. - fn hash_password_simple<'a, S>(&self, password: &[u8], salt: &'a S) -> Result> + fn hash_password<'a, S>(&self, password: &[u8], salt: &'a S) -> Result> where S: AsRef + ?Sized, { - self.hash_password( + self.hash_password_customized( password, None, None, @@ -31,18 +45,6 @@ pub trait PasswordHasher { Salt::try_from(salt.as_ref())?, ) } - - /// Compute a [`PasswordHash`] with the given algorithm [`Ident`] - /// (or `None` for the recommended default), password, salt, and - /// parameters. - fn hash_password<'a>( - &self, - password: &[u8], - algorithm: Option>, - version: Option, - params: Self::Params, - salt: impl Into>, - ) -> Result>; } /// Trait for password verification. @@ -62,7 +64,7 @@ pub trait PasswordVerifier { impl PasswordVerifier for T { fn verify_password(&self, password: &[u8], hash: &PasswordHash<'_>) -> Result<()> { if let (Some(salt), Some(expected_output)) = (&hash.salt, &hash.hash) { - let computed_hash = self.hash_password( + let computed_hash = self.hash_password_customized( password, Some(hash.algorithm), hash.version, diff --git a/password-hash/tests/hashing.rs b/password-hash/tests/hashing.rs index b0b29ab51..496b4cd00 100644 --- a/password-hash/tests/hashing.rs +++ b/password-hash/tests/hashing.rs @@ -13,7 +13,7 @@ pub struct StubPasswordHasher; impl PasswordHasher for StubPasswordHasher { type Params = StubParams; - fn hash_password<'a>( + fn hash_password_customized<'a>( &self, password: &[u8], algorithm: Option>, From 24f1d830303b800fabc95bcb74780fe62a589476 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 27 Aug 2021 14:38:01 -0600 Subject: [PATCH 0584/1461] password-hash: rename `Error::B64` => `Error::B64Encoding` (#721) --- password-hash/src/errors.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/password-hash/src/errors.rs b/password-hash/src/errors.rs index 552fab5ef..48ff66b0b 100644 --- a/password-hash/src/errors.rs +++ b/password-hash/src/errors.rs @@ -15,7 +15,7 @@ pub enum Error { Algorithm, /// "B64" encoding error. - B64(B64Error), + B64Encoding(B64Error), /// Cryptographic error. Crypto, @@ -61,7 +61,7 @@ impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> core::result::Result<(), fmt::Error> { match self { Self::Algorithm => write!(f, "unsupported algorithm"), - Self::B64(err) => write!(f, "{}", err), + Self::B64Encoding(err) => write!(f, "{}", err), Self::Crypto => write!(f, "cryptographic error"), Self::OutputTooShort => f.write_str("PHF output too short (min 10-bytes)"), Self::OutputTooLong => f.write_str("PHF output too long (max 64-bytes)"), @@ -84,13 +84,13 @@ impl std::error::Error for Error {} impl From for Error { fn from(err: B64Error) -> Error { - Error::B64(err) + Error::B64Encoding(err) } } impl From for Error { fn from(_: base64ct::InvalidLengthError) -> Error { - Error::B64(B64Error::InvalidLength) + Error::B64Encoding(B64Error::InvalidLength) } } From c759117b348ec195fab4ec835c260f0b4c402389 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 27 Aug 2021 15:01:55 -0600 Subject: [PATCH 0585/1461] password-hash: add `ParamsString::add_b64_bytes` method (#722) Adds a helper method for encoding bytes into a `ParamsString` as "B64". --- password-hash/src/params.rs | 51 ++++++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 6 deletions(-) diff --git a/password-hash/src/params.rs b/password-hash/src/params.rs index 49cf774ee..5dc3c996c 100644 --- a/password-hash/src/params.rs +++ b/password-hash/src/params.rs @@ -3,7 +3,7 @@ use crate::errors::InvalidValue; use crate::{ value::{Decimal, Value}, - Error, Ident, Result, + Encoding, Error, Ident, Result, }; use core::{ convert::{TryFrom, TryInto}, @@ -50,6 +50,39 @@ impl ParamsString { Self::default() } + /// Add the given byte value to the [`ParamsString`], encoding it as "B64". + pub fn add_b64_bytes<'a>(&mut self, name: impl TryInto>, bytes: &[u8]) -> Result<()> { + if !self.is_empty() { + self.0 + .write_char(PARAMS_DELIMITER) + .map_err(|_| Error::ParamsMaxExceeded)? + } + + let name = name.try_into().map_err(|_| Error::ParamNameInvalid)?; + + // Add param name + let offset = self.0.length; + if write!(self.0, "{}=", name).is_err() { + self.0.length = offset; + return Err(Error::ParamsMaxExceeded); + } + + // Encode B64 value + let offset = self.0.length as usize; + let written = Encoding::B64 + .encode(bytes, &mut self.0.bytes[offset..])? + .len(); + + self.0.length += written as u8; + Ok(()) + } + + /// Add a key/value pair with a decimal value to the [`ParamsString`]. + pub fn add_decimal<'a>(&mut self, name: impl TryInto>, value: Decimal) -> Result<()> { + let name = name.try_into().map_err(|_| Error::ParamNameInvalid)?; + self.add(name, value) + } + /// Add a key/value pair with a string value to the [`ParamsString`]. pub fn add_str<'a>( &mut self, @@ -57,15 +90,11 @@ impl ParamsString { value: impl TryInto>, ) -> Result<()> { let name = name.try_into().map_err(|_| Error::ParamNameInvalid)?; + let value = value .try_into() .map_err(|_| Error::ParamValueInvalid(InvalidValue::InvalidFormat))?; - self.add(name, value) - } - /// Add a key/value pair with a decimal value to the [`ParamsString`]. - pub fn add_decimal<'a>(&mut self, name: impl TryInto>, value: Decimal) -> Result<()> { - let name = name.try_into().map_err(|_| Error::ParamNameInvalid)?; self.add(name, value) } @@ -311,6 +340,16 @@ mod tests { assert_eq!(params.get_decimal("c").unwrap(), 3); } + #[test] + #[cfg(feature = "alloc")] + fn add_b64_bytes() { + let mut params = ParamsString::new(); + params.add_b64_bytes("a", &[1]).unwrap(); + params.add_b64_bytes("b", &[2, 3]).unwrap(); + params.add_b64_bytes("c", &[4, 5, 6]).unwrap(); + assert_eq!(params.to_string(), "a=AQ,b=AgM,c=BAUG"); + } + #[test] fn duplicate_names() { let name = Ident::new("a"); From de154ba549058b07c8bacae0027341c483067285 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 27 Aug 2021 16:17:43 -0600 Subject: [PATCH 0586/1461] password-hash v0.3.0 (#724) --- Cargo.lock | 2 +- crypto/Cargo.toml | 2 +- password-hash/CHANGELOG.md | 18 ++++++++++++++++++ password-hash/Cargo.toml | 2 +- password-hash/src/lib.rs | 2 +- 5 files changed, 22 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 62f86a23f..c576df0e8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -325,7 +325,7 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "password-hash" -version = "0.3.0-pre.1" +version = "0.3.0" dependencies = [ "base64ct", "rand_core", diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 439e8bd06..46f8c370d 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -19,7 +19,7 @@ cipher = { version = "0.3", optional = true } digest = { version = "0.9", optional = true } elliptic-curve = { version = "0.10", optional = true, path = "../elliptic-curve" } mac = { version = "0.11", package = "crypto-mac", optional = true } -password-hash = { version = "=0.3.0-pre.1", optional = true, path = "../password-hash" } +password-hash = { version = "0.3", optional = true, path = "../password-hash" } signature = { version = "1.3.0", optional = true, default-features = false, path = "../signature" } universal-hash = { version = "0.4", optional = true, path = "../universal-hash" } diff --git a/password-hash/CHANGELOG.md b/password-hash/CHANGELOG.md index 5e62d2bfa..bf752df06 100644 --- a/password-hash/CHANGELOG.md +++ b/password-hash/CHANGELOG.md @@ -5,6 +5,24 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.3.0 (2021-08-27) +### Added +- More details to `ParamValueInvalid` ([#713]) +- `SaltInvalid` error ([#713]) +- `version` param to `PasswordHasher` ([#719]) +- `ParamsString::add_b64_bytes` method ([#722]) + +### Changed +- Rename `PasswordHash::hash_password_simple` => `PasswordHash::hash_password` ([#720]) +- Rename `PasswordHash::hash_password` => `PasswordHash::hash_password_customized` ([#720]) +- Rename `Error::B64` => `Error::B64Encoding` ([#721]) + +[#713]: https://github.com/RustCrypto/traits/pull/713 +[#719]: https://github.com/RustCrypto/traits/pull/719 +[#720]: https://github.com/RustCrypto/traits/pull/720 +[#721]: https://github.com/RustCrypto/traits/pull/721 +[#722]: https://github.com/RustCrypto/traits/pull/722 + ## 0.2.3 (2021-08-23) ### Changed - Make max lengths of `Value` and `Salt` both 64 ([#707]) diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index cf15029ed..563ff5749 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -5,7 +5,7 @@ Traits which describe the functionality of password hashing algorithms, as well as a `no_std`-friendly implementation of the PHC string format (a well-defined subset of the Modular Crypt Format a.k.a. MCF) """ -version = "0.3.0-pre.1" # Also update html_root_url in lib.rs when bumping this +version = "0.3.0" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index f8a82c7dc..59a867392 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -39,7 +39,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/password-hash/0.3.0-pre.1" + html_root_url = "https://docs.rs/password-hash/0.3.0" )] #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] From baf5de6a27215b562cb52b0abbd2ed288658df88 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Aug 2021 16:57:58 -0600 Subject: [PATCH 0587/1461] build(deps): bump sha2 from 0.9.5 to 0.9.6 (#723) Bumps [sha2](https://github.com/RustCrypto/hashes) from 0.9.5 to 0.9.6. - [Release notes](https://github.com/RustCrypto/hashes/releases) - [Commits](https://github.com/RustCrypto/hashes/compare/sha2-v0.9.5...sha2-v0.9.6) --- updated-dependencies: - dependency-name: sha2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c576df0e8..6e0d6e7b6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -123,9 +123,9 @@ checksum = "44c32f031ea41b4291d695026c023b95d59db2d8a2c7640800ed56bc8f510f22" [[package]] name = "cpufeatures" -version = "0.1.5" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66c99696f6c9dd7f35d486b9d04d7e6e202aa3e8c40d553f2fdf5e7e0c6a71ef" +checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" dependencies = [ "libc", ] @@ -313,9 +313,9 @@ checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" [[package]] name = "libc" -version = "0.2.98" +version = "0.2.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790" +checksum = "3cb00336871be5ed2c8ed44b60ae9959dc5b9f08539422ed43f09e34ecaeba21" [[package]] name = "opaque-debug" @@ -411,9 +411,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.9.5" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b362ae5752fd2137731f9fa25fd4d9058af34666ca1966fb969119cc35719f12" +checksum = "9204c41a1597a8c5af23c82d1c921cb01ec0a4c59e07a9c7306062829a3903f3" dependencies = [ "block-buffer 0.9.0", "cfg-if", From 24fe124436d326a976710f37aa4e8dea98d98d9d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 29 Aug 2021 08:17:28 -0600 Subject: [PATCH 0588/1461] aead: add `Result` type alias (#725) Allows AEAD-related results to be abbreviated as `aead::Result`. --- aead/src/lib.rs | 51 ++++++++++++++++++++++++---------------------- aead/src/stream.rs | 28 ++++++++++++------------- 2 files changed, 41 insertions(+), 38 deletions(-) diff --git a/aead/src/lib.rs b/aead/src/lib.rs index 05ad57dd2..7b3485480 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -63,6 +63,9 @@ use rand_core::{CryptoRng, RngCore}; #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] pub struct Error; +/// Result type alias with [`Error`]. +pub type Result = core::result::Result; + impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str("aead::Error") @@ -93,7 +96,7 @@ pub trait NewAead { /// Create new AEAD instance from key given as a byte slice.. /// /// Default implementation will accept only keys with length equal to `KeySize`. - fn new_from_slice(key: &[u8]) -> Result + fn new_from_slice(key: &[u8]) -> Result where Self: Sized, { @@ -164,7 +167,7 @@ pub trait Aead: AeadCore { &self, nonce: &Nonce, plaintext: impl Into>, - ) -> Result, Error>; + ) -> Result>; /// Decrypt the given ciphertext slice, and return the resulting plaintext /// as a vector of bytes. @@ -187,7 +190,7 @@ pub trait Aead: AeadCore { &self, nonce: &Nonce, ciphertext: impl Into>, - ) -> Result, Error>; + ) -> Result>; } /// Stateful Authenticated Encryption with Associated Data algorithm. @@ -203,7 +206,7 @@ pub trait AeadMut: AeadCore { &mut self, nonce: &Nonce, plaintext: impl Into>, - ) -> Result, Error>; + ) -> Result>; /// Decrypt the given ciphertext slice, and return the resulting plaintext /// as a vector of bytes. @@ -214,7 +217,7 @@ pub trait AeadMut: AeadCore { &mut self, nonce: &Nonce, ciphertext: impl Into>, - ) -> Result, Error>; + ) -> Result>; } /// Implement the `decrypt_in_place` method on [`AeadInPlace`] and @@ -254,7 +257,7 @@ pub trait AeadInPlace: AeadCore { nonce: &Nonce, associated_data: &[u8], buffer: &mut dyn Buffer, - ) -> Result<(), Error> { + ) -> Result<()> { let tag = self.encrypt_in_place_detached(nonce, associated_data, buffer.as_mut())?; buffer.extend_from_slice(tag.as_slice())?; Ok(()) @@ -266,7 +269,7 @@ pub trait AeadInPlace: AeadCore { nonce: &Nonce, associated_data: &[u8], buffer: &mut [u8], - ) -> Result, Error>; + ) -> Result>; /// Decrypt the message in-place, returning an error in the event the /// provided authentication tag does not match the given ciphertext. @@ -278,7 +281,7 @@ pub trait AeadInPlace: AeadCore { nonce: &Nonce, associated_data: &[u8], buffer: &mut dyn Buffer, - ) -> Result<(), Error> { + ) -> Result<()> { impl_decrypt_in_place!(self, nonce, associated_data, buffer) } @@ -291,7 +294,7 @@ pub trait AeadInPlace: AeadCore { associated_data: &[u8], buffer: &mut [u8], tag: &Tag, - ) -> Result<(), Error>; + ) -> Result<()>; } /// In-place stateful AEAD trait. @@ -312,7 +315,7 @@ pub trait AeadMutInPlace: AeadCore { nonce: &Nonce, associated_data: &[u8], buffer: &mut impl Buffer, - ) -> Result<(), Error> { + ) -> Result<()> { let tag = self.encrypt_in_place_detached(nonce, associated_data, buffer.as_mut())?; buffer.extend_from_slice(tag.as_slice())?; Ok(()) @@ -324,7 +327,7 @@ pub trait AeadMutInPlace: AeadCore { nonce: &Nonce, associated_data: &[u8], buffer: &mut [u8], - ) -> Result, Error>; + ) -> Result>; /// Decrypt the message in-place, returning an error in the event the /// provided authentication tag does not match the given ciphertext. @@ -336,7 +339,7 @@ pub trait AeadMutInPlace: AeadCore { nonce: &Nonce, associated_data: &[u8], buffer: &mut impl Buffer, - ) -> Result<(), Error> { + ) -> Result<()> { impl_decrypt_in_place!(self, nonce, associated_data, buffer) } @@ -349,7 +352,7 @@ pub trait AeadMutInPlace: AeadCore { associated_data: &[u8], buffer: &mut [u8], tag: &Tag, - ) -> Result<(), Error>; + ) -> Result<()>; } #[cfg(feature = "alloc")] @@ -358,7 +361,7 @@ impl Aead for Alg { &self, nonce: &Nonce, plaintext: impl Into>, - ) -> Result, Error> { + ) -> Result> { let payload = plaintext.into(); let mut buffer = Vec::with_capacity(payload.msg.len() + Self::TagSize::to_usize()); buffer.extend_from_slice(payload.msg); @@ -370,7 +373,7 @@ impl Aead for Alg { &self, nonce: &Nonce, ciphertext: impl Into>, - ) -> Result, Error> { + ) -> Result> { let payload = ciphertext.into(); let mut buffer = Vec::from(payload.msg); self.decrypt_in_place(nonce, payload.aad, &mut buffer)?; @@ -384,7 +387,7 @@ impl AeadMut for Alg { &mut self, nonce: &Nonce, plaintext: impl Into>, - ) -> Result, Error> { + ) -> Result> { let payload = plaintext.into(); let mut buffer = Vec::with_capacity(payload.msg.len() + Self::TagSize::to_usize()); buffer.extend_from_slice(payload.msg); @@ -396,7 +399,7 @@ impl AeadMut for Alg { &mut self, nonce: &Nonce, ciphertext: impl Into>, - ) -> Result, Error> { + ) -> Result> { let payload = ciphertext.into(); let mut buffer = Vec::from(payload.msg); self.decrypt_in_place(nonce, payload.aad, &mut buffer)?; @@ -410,7 +413,7 @@ impl AeadMutInPlace for Alg { nonce: &Nonce, associated_data: &[u8], buffer: &mut impl Buffer, - ) -> Result<(), Error> { + ) -> Result<()> { ::encrypt_in_place(self, nonce, associated_data, buffer) } @@ -419,7 +422,7 @@ impl AeadMutInPlace for Alg { nonce: &Nonce, associated_data: &[u8], buffer: &mut [u8], - ) -> Result, Error> { + ) -> Result> { ::encrypt_in_place_detached(self, nonce, associated_data, buffer) } @@ -428,7 +431,7 @@ impl AeadMutInPlace for Alg { nonce: &Nonce, associated_data: &[u8], buffer: &mut impl Buffer, - ) -> Result<(), Error> { + ) -> Result<()> { ::decrypt_in_place(self, nonce, associated_data, buffer) } @@ -438,7 +441,7 @@ impl AeadMutInPlace for Alg { associated_data: &[u8], buffer: &mut [u8], tag: &Tag, - ) -> Result<(), Error> { + ) -> Result<()> { ::decrypt_in_place_detached(self, nonce, associated_data, buffer, tag) } } @@ -485,7 +488,7 @@ pub trait Buffer: AsRef<[u8]> + AsMut<[u8]> { } /// Extend this buffer from the given slice - fn extend_from_slice(&mut self, other: &[u8]) -> Result<(), Error>; + fn extend_from_slice(&mut self, other: &[u8]) -> Result<()>; /// Truncate this buffer to the given size fn truncate(&mut self, len: usize); @@ -493,7 +496,7 @@ pub trait Buffer: AsRef<[u8]> + AsMut<[u8]> { #[cfg(feature = "alloc")] impl Buffer for Vec { - fn extend_from_slice(&mut self, other: &[u8]) -> Result<(), Error> { + fn extend_from_slice(&mut self, other: &[u8]) -> Result<()> { Vec::extend_from_slice(self, other); Ok(()) } @@ -505,7 +508,7 @@ impl Buffer for Vec { #[cfg(feature = "heapless")] impl Buffer for heapless::Vec { - fn extend_from_slice(&mut self, other: &[u8]) -> Result<(), Error> { + fn extend_from_slice(&mut self, other: &[u8]) -> Result<()> { heapless::Vec::extend_from_slice(self, other).map_err(|_| Error) } diff --git a/aead/src/stream.rs b/aead/src/stream.rs index 73c9c63c8..d3ccf113a 100644 --- a/aead/src/stream.rs +++ b/aead/src/stream.rs @@ -32,7 +32,7 @@ #![allow(clippy::upper_case_acronyms)] -use crate::{AeadCore, AeadInPlace, Buffer, Error, Key, NewAead}; +use crate::{AeadCore, AeadInPlace, Buffer, Error, Key, NewAead, Result}; use core::ops::{AddAssign, Sub}; use generic_array::{ typenum::{Unsigned, U4, U5}, @@ -117,7 +117,7 @@ where last_block: bool, associated_data: &[u8], buffer: &mut dyn Buffer, - ) -> Result<(), Error>; + ) -> Result<()>; /// Decrypt an AEAD message in-place at the given position in the STREAM. fn decrypt_in_place( @@ -126,7 +126,7 @@ where last_block: bool, associated_data: &[u8], buffer: &mut dyn Buffer, - ) -> Result<(), Error>; + ) -> Result<()>; /// Encrypt the given plaintext payload, and return the resulting /// ciphertext as a vector of bytes. @@ -137,7 +137,7 @@ where position: Self::Counter, last_block: bool, plaintext: impl Into>, - ) -> Result, Error> { + ) -> Result> { let payload = plaintext.into(); let mut buffer = Vec::with_capacity(payload.msg.len() + A::TagSize::to_usize()); buffer.extend_from_slice(payload.msg); @@ -154,7 +154,7 @@ where position: Self::Counter, last_block: bool, ciphertext: impl Into>, - ) -> Result, Error> { + ) -> Result> { let payload = ciphertext.into(); let mut buffer = Vec::from(payload.msg); self.decrypt_in_place(position, last_block, payload.aad, &mut buffer)?; @@ -263,7 +263,7 @@ macro_rules! impl_stream_object { pub fn $next_method<'msg, 'aad>( &mut self, payload: impl Into>, - ) -> Result, Error> { + ) -> Result> { if self.position == S::COUNTER_MAX { // Counter overflow. Note that the maximum counter value is // deliberately disallowed, as it would preclude being able @@ -285,7 +285,7 @@ macro_rules! impl_stream_object { &mut self, associated_data: &[u8], buffer: &mut dyn Buffer, - ) -> Result<(), Error> { + ) -> Result<()> { if self.position == S::COUNTER_MAX { // Counter overflow. Note that the maximum counter value is // deliberately disallowed, as it would preclude being able @@ -312,7 +312,7 @@ macro_rules! impl_stream_object { pub fn $last_method<'msg, 'aad>( self, payload: impl Into>, - ) -> Result, Error> { + ) -> Result> { self.stream.$op(self.position, true, payload) } @@ -326,7 +326,7 @@ macro_rules! impl_stream_object { self, associated_data: &[u8], buffer: &mut dyn Buffer, - ) -> Result<(), Error> { + ) -> Result<()> { self.stream .$in_place_op(self.position, true, associated_data, buffer) } @@ -409,7 +409,7 @@ where last_block: bool, associated_data: &[u8], buffer: &mut dyn Buffer, - ) -> Result<(), Error> { + ) -> Result<()> { let nonce = self.aead_nonce(position, last_block); self.aead.encrypt_in_place(&nonce, associated_data, buffer) } @@ -420,7 +420,7 @@ where last_block: bool, associated_data: &[u8], buffer: &mut dyn Buffer, - ) -> Result<(), Error> { + ) -> Result<()> { let nonce = self.aead_nonce(position, last_block); self.aead.decrypt_in_place(&nonce, associated_data, buffer) } @@ -498,7 +498,7 @@ where last_block: bool, associated_data: &[u8], buffer: &mut dyn Buffer, - ) -> Result<(), Error> { + ) -> Result<()> { let nonce = self.aead_nonce(position, last_block)?; self.aead.encrypt_in_place(&nonce, associated_data, buffer) } @@ -509,7 +509,7 @@ where last_block: bool, associated_data: &[u8], buffer: &mut dyn Buffer, - ) -> Result<(), Error> { + ) -> Result<()> { let nonce = self.aead_nonce(position, last_block)?; self.aead.decrypt_in_place(&nonce, associated_data, buffer) } @@ -523,7 +523,7 @@ where { /// Compute the full AEAD nonce including the STREAM counter and last /// block flag. - fn aead_nonce(&self, position: u32, last_block: bool) -> Result, Error> { + fn aead_nonce(&self, position: u32, last_block: bool) -> Result> { if position > Self::COUNTER_MAX { return Err(Error); } From ad2328c06a6f2606d1eb05d5e38f3a86a9911031 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 29 Aug 2021 08:35:47 -0600 Subject: [PATCH 0589/1461] aead v0.4.3 (#726) --- Cargo.lock | 2 +- aead/CHANGELOG.md | 6 ++++++ aead/Cargo.toml | 2 +- aead/src/lib.rs | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6e0d6e7b6..f2713aac4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,7 +4,7 @@ version = 3 [[package]] name = "aead" -version = "0.4.2" +version = "0.4.3" dependencies = [ "blobby", "generic-array", diff --git a/aead/CHANGELOG.md b/aead/CHANGELOG.md index 71a0e9820..90e7874da 100644 --- a/aead/CHANGELOG.md +++ b/aead/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.4.3 (2021-08-29) +### Added +- `Result` type alias ([#725]) + +[#725]: https://github.com/RustCrypto/traits/pull/725 + ## 0.4.2 (2021-07-12) ### Added - Re-export `rand_core` ([#682]) diff --git a/aead/Cargo.toml b/aead/Cargo.toml index b0f2ca01b..f5c7d00c4 100644 --- a/aead/Cargo.toml +++ b/aead/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aead" -version = "0.4.2" # Also update html_root_url in lib.rs when bumping this +version = "0.4.3" # Also update html_root_url in lib.rs when bumping this description = """ Traits for Authenticated Encryption with Associated Data (AEAD) algorithms, such as AES-GCM as ChaCha20Poly1305, which provide a high-level API diff --git a/aead/src/lib.rs b/aead/src/lib.rs index 7b3485480..fb67f6899 100644 --- a/aead/src/lib.rs +++ b/aead/src/lib.rs @@ -19,7 +19,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/aead/0.4.2" + html_root_url = "https://docs.rs/aead/0.4.3" )] #![warn(missing_docs, rust_2018_idioms)] From 7371293ebdc2f163c95399aec7932b0ff88ddb35 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Aug 2021 22:13:11 +0000 Subject: [PATCH 0590/1461] build(deps): bump serde_json from 1.0.66 to 1.0.67 (#729) --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f2713aac4..fc14f21c5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -400,9 +400,9 @@ checksum = "d1f72836d2aa753853178eda473a3b9d8e4eefdaf20523b919677e6de489f8f1" [[package]] name = "serde_json" -version = "1.0.66" +version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "336b10da19a12ad094b59d870ebde26a45402e5b470add4b5fd03c5048a32127" +checksum = "a7f9e390c27c3c0ce8bc5d725f6e4d30a29d26659494aa4b17535f7522c5c950" dependencies = [ "itoa", "ryu", From c61beec256dccc5bda7963e3c92d6e804eab31b2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Aug 2021 22:13:21 +0000 Subject: [PATCH 0591/1461] build(deps): bump serde from 1.0.129 to 1.0.130 (#728) --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fc14f21c5..db9ebf387 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -394,9 +394,9 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "serde" -version = "1.0.129" +version = "1.0.130" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1f72836d2aa753853178eda473a3b9d8e4eefdaf20523b919677e6de489f8f1" +checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" [[package]] name = "serde_json" From 133f12ad8368ba1d31973d88d7c6986a57ca3351 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 2 Sep 2021 09:44:06 -0600 Subject: [PATCH 0592/1461] elliptic-curve: bump `ff` + `group` to v0.11 (#730) Release notes: - `ff`: https://github.com/zkcrypto/ff/blob/main/CHANGELOG.md#0110---2021-09-02 - `group`: https://github.com/zkcrypto/group/blob/main/CHANGELOG.md#0110---2021-09-02 --- Cargo.lock | 10 ++++---- crypto/Cargo.toml | 2 +- elliptic-curve/Cargo.toml | 6 ++--- elliptic-curve/src/arithmetic.rs | 37 +++++++++++++++------------ elliptic-curve/src/dev.rs | 15 ++++++----- elliptic-curve/src/lib.rs | 2 +- elliptic-curve/src/scalar/bytes.rs | 4 +-- elliptic-curve/src/scalar/non_zero.rs | 24 ++++++++--------- 8 files changed, 52 insertions(+), 48 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index db9ebf387..119630765 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -215,7 +215,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.10.6" +version = "0.11.0-pre" dependencies = [ "base64ct", "crypto-bigint", @@ -233,9 +233,9 @@ dependencies = [ [[package]] name = "ff" -version = "0.10.1" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0f40b2dcd8bc322217a5f6559ae5f9e9d1de202a2ecee2e9eafcbece7562a4f" +checksum = "b2958d04124b9f27f175eaeb9a9f383d026098aa837eadd8ba22c11f13a05b9e" dependencies = [ "bitvec", "rand_core", @@ -271,9 +271,9 @@ dependencies = [ [[package]] name = "group" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c363a5301b8f153d80747126a04b3c82073b9fe3130571a9d170cacdeaf7912" +checksum = "bc5ac374b108929de78460075f3dc439fa66df9d8fc77e8f12caa5165fcf0c89" dependencies = [ "ff", "rand_core", diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 46f8c370d..4f4138357 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -17,7 +17,7 @@ edition = "2018" aead = { version = "0.4", optional = true, path = "../aead" } cipher = { version = "0.3", optional = true } digest = { version = "0.9", optional = true } -elliptic-curve = { version = "0.10", optional = true, path = "../elliptic-curve" } +elliptic-curve = { version = "=0.11.0-pre", optional = true, path = "../elliptic-curve" } mac = { version = "0.11", package = "crypto-mac", optional = true } password-hash = { version = "0.3", optional = true, path = "../password-hash" } signature = { version = "1.3.0", optional = true, default-features = false, path = "../signature" } diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index eca853b34..d3de59f88 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -5,7 +5,7 @@ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. """ -version = "0.10.6" # Also update html_root_url in lib.rs when bumping this +version = "0.11.0-pre" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" repository = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve" @@ -22,8 +22,8 @@ subtle = { version = "=2.4", default-features = false } # optional dependencies base64ct = { version = "1", optional = true, default-features = false } -ff = { version = "0.10", optional = true, default-features = false } -group = { version = "0.10", optional = true, default-features = false } +ff = { version = "0.11", optional = true, default-features = false } +group = { version = "0.11", optional = true, default-features = false } hex-literal = { version = "0.3", optional = true } pkcs8 = { version = "0.7", optional = true } serde = { version = "1", optional = true, default-features = false } diff --git a/elliptic-curve/src/arithmetic.rs b/elliptic-curve/src/arithmetic.rs index fc7c1cf5e..db377d680 100644 --- a/elliptic-curve/src/arithmetic.rs +++ b/elliptic-curve/src/arithmetic.rs @@ -25,14 +25,15 @@ pub trait AffineArithmetic: Curve + ScalarArithmetic { pub trait ProjectiveArithmetic: Curve + AffineArithmetic { /// Elliptic curve point in projective coordinates. /// - /// Note: the following bounds are enforced by [`group::Group`]: - /// - `Copy` - /// - `Clone` - /// - `Debug` - /// - `Eq` - /// - `Sized` - /// - `Send` - /// - `Sync` + /// Note: the following bounds are provided by [`group::Group`]: + /// - `'static` + /// - [`Copy`] + /// - [`Clone`] + /// - [`Debug`] + /// - [`Eq`] + /// - [`Sized`] + /// - [`Send`] + /// - [`Sync`] type ProjectivePoint: ConditionallySelectable + ConstantTimeEq + Default @@ -48,13 +49,15 @@ pub trait ProjectiveArithmetic: Curve + AffineArithmetic { pub trait ScalarArithmetic: Curve { /// Scalar field type. /// - /// Note: the following bounds are enforced by [`ff::Field`]: - /// - `Copy` - /// - `Clone` - /// - `ConditionallySelectable` - /// - `Debug` - /// - `Default` - /// - `Send` - /// - `Sync` - type Scalar: ConstantTimeEq + ff::Field + ff::PrimeField>; + /// Note: the following bounds are provided by [`ff::Field`]: + /// - `'static` + /// - [`Copy`] + /// - [`Clone`] + /// - [`ConditionallySelectable`] + /// - [`ConstantTimeEq`] + /// - [`Debug`] + /// - [`Default`] + /// - [`Send`] + /// - [`Sync`] + type Scalar: ff::Field + ff::PrimeField>; } diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 995378694..027278db1 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -6,13 +6,13 @@ use crate::{ error::{Error, Result}, rand_core::RngCore, sec1::{FromEncodedPoint, ToEncodedPoint}, - subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}, + subtle::{Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeLess, CtOption}, weierstrass, zeroize::Zeroize, AffineArithmetic, AlgorithmParameters, Curve, ProjectiveArithmetic, ScalarArithmetic, }; use core::{ - convert::{TryFrom, TryInto}, + convert::TryFrom, iter::Sum, ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign}, }; @@ -104,8 +104,8 @@ impl Field for Scalar { Self(U256::ONE) } - fn is_zero(&self) -> bool { - self.0.is_zero().into() + fn is_zero(&self) -> Choice { + self.0.is_zero() } #[must_use] @@ -134,15 +134,16 @@ impl PrimeField for Scalar { const CAPACITY: u32 = 255; const S: u32 = 4; - fn from_repr(bytes: FieldBytes) -> Option { - U256::from_be_byte_array(bytes).try_into().ok() + fn from_repr(bytes: FieldBytes) -> CtOption { + let inner = U256::from_be_byte_array(bytes); + CtOption::new(Scalar(inner), inner.ct_lt(&MockCurve::ORDER)) } fn to_repr(&self) -> FieldBytes { self.0.to_be_byte_array() } - fn is_odd(&self) -> bool { + fn is_odd(&self) -> Choice { unimplemented!(); } diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 0ebc96a89..b8cacae1e 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -16,7 +16,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.10.6" + html_root_url = "https://docs.rs/elliptic-curve/0.11.0-pre" )] #[cfg(feature = "alloc")] diff --git a/elliptic-curve/src/scalar/bytes.rs b/elliptic-curve/src/scalar/bytes.rs index 3d264603f..1c8e0eede 100644 --- a/elliptic-curve/src/scalar/bytes.rs +++ b/elliptic-curve/src/scalar/bytes.rs @@ -70,7 +70,7 @@ where where C: ProjectiveArithmetic, { - Scalar::::from_repr(self.inner).expect("ScalarBytes order invariant violated") + Scalar::::from_repr(self.inner).unwrap() } /// Borrow the inner [`FieldBytes`] @@ -206,7 +206,7 @@ where type Error = Error; fn try_from(bytes: ScalarBytes) -> Result> { - NonZeroScalar::::from_repr(bytes.inner).ok_or(Error) + Option::from(NonZeroScalar::::from_repr(bytes.inner)).ok_or(Error) } } diff --git a/elliptic-curve/src/scalar/non_zero.rs b/elliptic-curve/src/scalar/non_zero.rs index 33f33c15f..db74fed91 100644 --- a/elliptic-curve/src/scalar/non_zero.rs +++ b/elliptic-curve/src/scalar/non_zero.rs @@ -38,27 +38,24 @@ where { /// Generate a random `NonZeroScalar` pub fn random(mut rng: impl CryptoRng + RngCore) -> Self { - // Use rejection sampling to eliminate zero values + // Use rejection sampling to eliminate zero values. + // While this method isn't constant-time, the attacker shouldn't learn + // anything about unrelated outputs so long as `rng` is a secure `CryptoRng`. loop { - if let Some(result) = Self::new(Field::random(&mut rng)) { + if let Some(result) = Self::new(Field::random(&mut rng)).into() { break result; } } } /// Decode a [`NonZeroScalar`] from a serialized field element - pub fn from_repr(repr: FieldBytes) -> Option { + pub fn from_repr(repr: FieldBytes) -> CtOption { Scalar::::from_repr(repr).and_then(Self::new) } /// Create a [`NonZeroScalar`] from a scalar. - // TODO(tarcieri): make this constant time? - pub fn new(scalar: Scalar) -> Option { - if scalar.is_zero() { - None - } else { - Some(Self { scalar }) - } + pub fn new(scalar: Scalar) -> CtOption { + CtOption::new(Self { scalar }, !scalar.is_zero()) } } @@ -141,7 +138,7 @@ where { fn from(sk: &SecretKey) -> NonZeroScalar { let scalar = sk.as_scalar_bytes().to_scalar(); - debug_assert!(!scalar.is_zero()); + debug_assert!(!bool::from(scalar.is_zero())); Self { scalar } } } @@ -166,7 +163,10 @@ where fn try_from(bytes: &[u8]) -> Result { if bytes.len() == C::UInt::BYTE_SIZE { - NonZeroScalar::from_repr(GenericArray::clone_from_slice(bytes)).ok_or(Error) + Option::from(NonZeroScalar::from_repr(GenericArray::clone_from_slice( + bytes, + ))) + .ok_or(Error) } else { Err(Error) } From cadefe34305026330e43e41fb4d18e9fe0d56c2c Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 2 Sep 2021 13:00:58 -0600 Subject: [PATCH 0593/1461] elliptic-curve: bump `crypto-bigint` to v0.2.5 (#731) Also adds smoke tests that `NonZeroScalar` and `dev::Scalar` round trip successfully to their reprs. --- Cargo.lock | 4 ++-- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/dev.rs | 14 ++++++++++++++ elliptic-curve/src/scalar/non_zero.rs | 26 ++++++++++++++++++++------ 4 files changed, 37 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 119630765..c094cb77c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -146,9 +146,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc209804a22c34a98fe26a32d997ac64d4284816f65cf1a529c4e31a256218a0" +checksum = "8658c15c5d921ddf980f7fe25b1e82f4b7a4083b2c4985fea4922edb8e43e07d" dependencies = [ "generic-array", "rand_core", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index d3de59f88..94233d891 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -15,7 +15,7 @@ categories = ["cryptography", "no-std"] keywords = ["crypto", "ecc", "elliptic", "weierstrass"] [dependencies] -crypto-bigint = { version = "0.2.4", features = ["generic-array"] } +crypto-bigint = { version = "0.2.5", features = ["generic-array"] } generic-array = { version = "0.14", default-features = false } rand_core = { version = "0.6", default-features = false } subtle = { version = "=2.4", default-features = false } diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 027278db1..198c6e679 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -658,3 +658,17 @@ impl Neg for ProjectivePoint { unimplemented!(); } } + +#[cfg(test)] +mod tests { + use super::Scalar; + use ff::PrimeField; + use hex_literal::hex; + + #[test] + fn round_trip() { + let bytes = hex!("c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721"); + let scalar = Scalar::from_repr(bytes.into()).unwrap(); + assert_eq!(&bytes, scalar.to_repr().as_slice()); + } +} diff --git a/elliptic-curve/src/scalar/non_zero.rs b/elliptic-curve/src/scalar/non_zero.rs index db74fed91..bc49c80b2 100644 --- a/elliptic-curve/src/scalar/non_zero.rs +++ b/elliptic-curve/src/scalar/non_zero.rs @@ -36,7 +36,7 @@ impl NonZeroScalar where C: Curve + ProjectiveArithmetic, { - /// Generate a random `NonZeroScalar` + /// Generate a random `NonZeroScalar`. pub fn random(mut rng: impl CryptoRng + RngCore) -> Self { // Use rejection sampling to eliminate zero values. // While this method isn't constant-time, the attacker shouldn't learn @@ -48,15 +48,15 @@ where } } - /// Decode a [`NonZeroScalar`] from a serialized field element - pub fn from_repr(repr: FieldBytes) -> CtOption { - Scalar::::from_repr(repr).and_then(Self::new) - } - /// Create a [`NonZeroScalar`] from a scalar. pub fn new(scalar: Scalar) -> CtOption { CtOption::new(Self { scalar }, !scalar.is_zero()) } + + /// Decode a [`NonZeroScalar`] from a big endian-serialized field element. + pub fn from_repr(repr: FieldBytes) -> CtOption { + Scalar::::from_repr(repr).and_then(Self::new) + } } impl AsRef> for NonZeroScalar @@ -183,3 +183,17 @@ where self.scalar.zeroize(); } } + +#[cfg(all(test, feature = "dev"))] +mod tests { + use crate::dev::NonZeroScalar; + use ff::PrimeField; + use hex_literal::hex; + + #[test] + fn round_trip() { + let bytes = hex!("c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721"); + let scalar = NonZeroScalar::from_repr(bytes.into()).unwrap(); + assert_eq!(&bytes, scalar.to_repr().as_slice()); + } +} From c7c63d39dbd9c9d5fc0dfd32e3ac0d58535dc500 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 3 Sep 2021 11:36:45 -0600 Subject: [PATCH 0594/1461] elliptic-curve: add `ScalarCore` type (#732) This is incremental work towards having a "one true scalar" type which is generic over elliptic curves, using `crypto-bigint` for the backing arithmetic. It's presently called `ScalarCore` to prevent it from conflicting with the existing `Scalar`, however the goal is to completely replace the current `Scalar`. This commit also does the following: - Removes the `ScalarBytes` type as `ScalarCore` can subsume its previous use cases - Makes the `zeroize` crate a hard dependency (i.e. removes the `zeroize` feature, making it mandatory) --- .github/workflows/elliptic-curve.yml | 1 - Cargo.lock | 3 +- Cargo.toml | 3 + elliptic-curve/Cargo.toml | 12 +- elliptic-curve/src/dev.rs | 7 +- elliptic-curve/src/jwk.rs | 4 +- elliptic-curve/src/lib.rs | 33 ++- elliptic-curve/src/public_key.rs | 4 +- elliptic-curve/src/scalar.rs | 286 ++++++++++++++++++++++++- elliptic-curve/src/scalar/bytes.rs | 277 ------------------------ elliptic-curve/src/scalar/non_zero.rs | 33 ++- elliptic-curve/src/sec1.rs | 21 +- elliptic-curve/src/secret_key.rs | 116 ++++++---- elliptic-curve/src/secret_key/pkcs8.rs | 21 +- elliptic-curve/tests/pkcs8.rs | 4 +- elliptic-curve/tests/secret_key.rs | 2 +- 16 files changed, 430 insertions(+), 397 deletions(-) delete mode 100644 elliptic-curve/src/scalar/bytes.rs diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index 5414dae84..84649ef9f 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -44,7 +44,6 @@ jobs: - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features jwk - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features pem - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features pkcs8 - - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features zeroize - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features ecdh,hazmat,jwk,pem test: runs-on: ubuntu-latest diff --git a/Cargo.lock b/Cargo.lock index c094cb77c..9ce4b50be 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -147,8 +147,7 @@ dependencies = [ [[package]] name = "crypto-bigint" version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8658c15c5d921ddf980f7fe25b1e82f4b7a4083b2c4985fea4922edb8e43e07d" +source = "git+https://github.com/RustCrypto/utils.git#8fa1b4fb22789fb5afd51bc1fad08ebf95789965" dependencies = [ "generic-array", "rand_core", diff --git a/Cargo.toml b/Cargo.toml index ebf9e0985..5ed356b7b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,3 +12,6 @@ members = [ "signature/async", "universal-hash", ] + +[patch.crates-io] +crypto-bigint = { git = "https://github.com/RustCrypto/utils.git" } diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 94233d891..8ed0e6ceb 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -15,10 +15,11 @@ categories = ["cryptography", "no-std"] keywords = ["crypto", "ecc", "elliptic", "weierstrass"] [dependencies] -crypto-bigint = { version = "0.2.5", features = ["generic-array"] } +crypto-bigint = { version = "0.2.5", features = ["generic-array", "zeroize"] } generic-array = { version = "0.14", default-features = false } rand_core = { version = "0.6", default-features = false } -subtle = { version = "=2.4", default-features = false } +subtle = { version = ">=2, <2.5", default-features = false } +zeroize = { version = ">=1, <1.5", default-features = false } # optional dependencies base64ct = { version = "1", optional = true, default-features = false } @@ -28,7 +29,6 @@ hex-literal = { version = "0.3", optional = true } pkcs8 = { version = "0.7", optional = true } serde = { version = "1", optional = true, default-features = false } serde_json = { version = "1", optional = true, default-features = false, features = ["alloc"] } -zeroize = { version = ">=1, <1.5", optional = true, default-features = false } [dev-dependencies] hex-literal = "0.3" @@ -36,10 +36,10 @@ hex-literal = "0.3" [features] default = ["arithmetic"] alloc = [] # todo: activate `group/alloc` when weak feature activation is available -arithmetic = ["crypto-bigint/zeroize", "ff", "group", "zeroize"] +arithmetic = ["ff", "group"] bits = ["arithmetic", "ff/bits"] -dev = ["arithmetic", "hex-literal", "pem", "zeroize"] -ecdh = ["arithmetic", "zeroize"] +dev = ["arithmetic", "hex-literal", "pem"] +ecdh = ["arithmetic"] hazmat = [] jwk = ["alloc", "base64ct/alloc", "serde", "serde_json", "zeroize/alloc"] pem = ["alloc", "pkcs8/pem"] diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 198c6e679..4a9a25ece 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -34,7 +34,7 @@ pub const PSEUDO_COORDINATE_FIXED_BASE_MUL: [u8; 32] = /// /// Note: this type is roughly modeled off of NIST P-256, but does not provide /// an actual cure arithmetic implementation. -#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Ord)] +#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, PartialOrd, Ord)] pub struct MockCurve; impl Curve for MockCurve { @@ -84,8 +84,9 @@ pub type PublicKey = crate::PublicKey; /// Secret key. pub type SecretKey = crate::SecretKey; -/// Scalar bytes. -pub type ScalarBytes = crate::ScalarBytes; +/// Scalar core. +// TODO(tarcieri): make this the scalar type +pub type ScalarCore = crate::ScalarCore; /// Example scalar type #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] diff --git a/elliptic-curve/src/jwk.rs b/elliptic-curve/src/jwk.rs index 3c2bceec4..00eb9b06b 100644 --- a/elliptic-curve/src/jwk.rs +++ b/elliptic-curve/src/jwk.rs @@ -251,7 +251,7 @@ where if let Some(d_base64) = &jwk.d { let pk = EncodedPoint::::try_from(jwk)?; let mut d_bytes = decode_base64url_fe::(d_base64)?; - let result = SecretKey::from_bytes(&d_bytes); + let result = SecretKey::from_bytes_be(&d_bytes); d_bytes.zeroize(); result.and_then(|secret_key| { @@ -293,7 +293,7 @@ where { fn from(sk: &SecretKey) -> JwkEcKey { let mut jwk = sk.public_key().to_jwk(); - let mut d = sk.to_bytes(); + let mut d = sk.to_bytes_be(); jwk.d = Some(Base64Url::encode_string(&d)); d.zeroize(); jwk diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index b8cacae1e..7a4f9cc06 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -37,6 +37,7 @@ pub mod weierstrass; mod error; mod scalar; +mod secret_key; #[cfg(feature = "arithmetic")] mod arithmetic; @@ -54,17 +55,16 @@ pub mod ecdh; #[cfg(feature = "jwk")] mod jwk; -#[cfg(feature = "zeroize")] -mod secret_key; - -pub use self::{ +pub use crate::{ error::{Error, Result}, - scalar::bytes::ScalarBytes, + scalar::ScalarCore, + secret_key::SecretKey, }; pub use crypto_bigint as bigint; pub use generic_array::{self, typenum::consts}; pub use rand_core; pub use subtle; +pub use zeroize; #[cfg(feature = "arithmetic")] pub use { @@ -86,14 +86,8 @@ pub use crate::jwk::{JwkEcKey, JwkParameters}; #[cfg(feature = "pkcs8")] pub use pkcs8; -#[cfg(feature = "zeroize")] -pub use secret_key::SecretKey; -#[cfg(feature = "zeroize")] -pub use zeroize; - use core::fmt::Debug; use generic_array::GenericArray; -use subtle::{ConstantTimeEq, ConstantTimeGreater, ConstantTimeLess}; /// Algorithm [`ObjectIdentifier`][`pkcs8::ObjectIdentifier`] for elliptic /// curve public key cryptography. @@ -112,19 +106,18 @@ pub const ALGORITHM_OID: pkcs8::ObjectIdentifier = /// Other traits in this crate which are bounded by [`Curve`] are intended to /// be impl'd by these ZSTs, facilitating types which are generic over elliptic /// curves (e.g. [`SecretKey`]). -pub trait Curve: Clone + Debug + Default + Eq + Ord + Send + Sync { +pub trait Curve: 'static + Copy + Clone + Debug + Default + Eq + Ord + Send + Sync { /// Integer type used to represent field elements of this elliptic curve. // TODO(tarcieri): replace this with an e.g. `const Curve::MODULUS: uint`. // Requires rust-lang/rust#60551, i.e. `const_evaluatable_checked` - type UInt: AsRef<[bigint::Limb]> + type UInt: bigint::AddMod + bigint::ArrayEncoding - + bigint::Encoding - + Copy - + Debug - + Default - + ConstantTimeEq - + ConstantTimeGreater - + ConstantTimeLess; + + bigint::Integer + + bigint::NegMod + + bigint::Random + + bigint::RandomMod + + bigint::SubMod + + zeroize::Zeroize; /// Order constant. /// diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index 5fff558b5..1c430d65b 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -115,7 +115,7 @@ where /// Convert this [`PublicKey`] to a [`ProjectivePoint`] for the given curve pub fn to_projective(&self) -> ProjectivePoint { - self.point.clone().into() + self.point.into() } /// Parse a [`JwkEcKey`] JSON Web Key (JWK) into a [`PublicKey`]. @@ -333,7 +333,7 @@ where return Err(pkcs8::der::ErrorKind::UnknownOid { oid: params_oid }.into()); } - Self::from_sec1_bytes(&spki.subject_public_key) + Self::from_sec1_bytes(spki.subject_public_key) .map_err(|_| pkcs8::der::Tag::BitString.value_error().into()) } } diff --git a/elliptic-curve/src/scalar.rs b/elliptic-curve/src/scalar.rs index c2d5aba50..77fdb92ef 100644 --- a/elliptic-curve/src/scalar.rs +++ b/elliptic-curve/src/scalar.rs @@ -1,12 +1,25 @@ //! Scalar types. -pub(crate) mod bytes; - #[cfg(feature = "arithmetic")] -use crate::ScalarArithmetic; +pub(crate) mod non_zero; + +use crate::{ + bigint::{AddMod, ArrayEncoding, Integer, Limb, NegMod, RandomMod, SubMod}, + rand_core::{CryptoRng, RngCore}, + subtle::{ + Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeGreater, ConstantTimeLess, + CtOption, + }, + Curve, FieldBytes, +}; +use core::{ + cmp::Ordering, + ops::{Add, AddAssign, Neg, Sub, SubAssign}, +}; +use zeroize::DefaultIsZeroes; #[cfg(feature = "arithmetic")] -pub(crate) mod non_zero; +use crate::{group::ff::PrimeField, ScalarArithmetic}; /// Scalar field element for a particular elliptic curve. #[cfg(feature = "arithmetic")] @@ -17,3 +30,268 @@ pub type Scalar = ::Scalar; #[cfg(feature = "bits")] #[cfg_attr(docsrs, doc(cfg(feature = "bits")))] pub type ScalarBits = ff::FieldBits< as ff::PrimeFieldBits>::ReprBits>; + +/// Generic core scalar type. +// TODO(tarcieri): make this a fully generic `Scalar` type +#[derive(Copy, Clone, Debug, Default)] +#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] +pub struct ScalarCore { + /// Inner unsigned integer type. + inner: C::UInt, +} + +impl ScalarCore +where + C: Curve, +{ + /// Zero scalar. + pub const ZERO: Self = Self { + inner: C::UInt::ZERO, + }; + + /// Multiplicative identity. + pub const ONE: Self = Self { + inner: C::UInt::ONE, + }; + + /// Scalar modulus. + pub const MODULUS: C::UInt = C::ORDER; + + /// Generate a random [`ScalarCore`]. + pub fn random(rng: impl CryptoRng + RngCore) -> Self { + Self { + inner: C::UInt::random_mod(rng, &Self::MODULUS), + } + } + + /// Create a new scalar from [`Curve::UInt`]. + pub fn new(uint: C::UInt) -> CtOption { + CtOption::new(Self { inner: uint }, uint.ct_lt(&Self::MODULUS)) + } + + /// Decode [`ScalarCore`] from big endian bytes. + pub fn from_bytes_be(bytes: FieldBytes) -> CtOption { + Self::new(C::UInt::from_be_byte_array(bytes)) + } + + /// Decode [`ScalarCore`] from little endian bytes. + pub fn from_bytes_le(bytes: FieldBytes) -> CtOption { + Self::new(C::UInt::from_le_byte_array(bytes)) + } + + /// Is this [`ScalarCore`] value equal to zero? + pub fn is_zero(&self) -> Choice { + self.inner.is_zero() + } + + /// Encode [`ScalarCore`] as big endian bytes. + pub fn to_bytes_be(self) -> FieldBytes { + self.inner.to_be_byte_array() + } + + /// Encode [`ScalarCore`] as little endian bytes. + pub fn to_bytes_le(self) -> FieldBytes { + self.inner.to_le_byte_array() + } +} + +#[cfg(feature = "arithmetic")] +impl ScalarCore +where + C: Curve + ScalarArithmetic, +{ + /// Convert [`ScalarCore`] into a given curve's scalar type + // TODO(tarcieri): replace curve-specific scalars with `ScalarCore` + fn to_scalar(self) -> Scalar { + Scalar::::from_repr(self.to_bytes_be()).unwrap() + } +} + +// TODO(tarcieri): better encapsulate this? +impl AsRef<[Limb]> for ScalarCore +where + C: Curve, +{ + fn as_ref(&self) -> &[Limb] { + self.inner.as_ref() + } +} + +impl ConditionallySelectable for ScalarCore +where + C: Curve, +{ + fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { + Self { + inner: C::UInt::conditional_select(&a.inner, &b.inner, choice), + } + } +} + +impl ConstantTimeEq for ScalarCore +where + C: Curve, +{ + fn ct_eq(&self, other: &Self) -> Choice { + self.inner.ct_eq(&other.inner) + } +} + +impl ConstantTimeLess for ScalarCore +where + C: Curve, +{ + fn ct_lt(&self, other: &Self) -> Choice { + self.inner.ct_lt(&other.inner) + } +} + +impl ConstantTimeGreater for ScalarCore +where + C: Curve, +{ + fn ct_gt(&self, other: &Self) -> Choice { + self.inner.ct_gt(&other.inner) + } +} + +impl DefaultIsZeroes for ScalarCore {} + +impl Eq for ScalarCore {} + +impl PartialEq for ScalarCore +where + C: Curve, +{ + fn eq(&self, other: &Self) -> bool { + self.ct_eq(other).into() + } +} + +impl PartialOrd for ScalarCore +where + C: Curve, +{ + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.inner.cmp(&other.inner)) + } +} + +impl From for ScalarCore +where + C: Curve, +{ + fn from(n: u64) -> Self { + Self { + inner: C::UInt::from(n), + } + } +} + +impl Add> for ScalarCore +where + C: Curve, +{ + type Output = Self; + + fn add(self, other: Self) -> Self { + self.add(&other) + } +} + +impl Add<&ScalarCore> for ScalarCore +where + C: Curve, +{ + type Output = Self; + + fn add(self, other: &Self) -> Self { + Self { + inner: self.inner.add_mod(&other.inner, &Self::MODULUS), + } + } +} + +impl AddAssign> for ScalarCore +where + C: Curve, +{ + fn add_assign(&mut self, other: Self) { + *self = *self + other; + } +} + +impl AddAssign<&ScalarCore> for ScalarCore +where + C: Curve, +{ + fn add_assign(&mut self, other: &Self) { + *self = *self + other; + } +} + +impl Sub> for ScalarCore +where + C: Curve, +{ + type Output = Self; + + fn sub(self, other: Self) -> Self { + self.sub(&other) + } +} + +impl Sub<&ScalarCore> for ScalarCore +where + C: Curve, +{ + type Output = Self; + + fn sub(self, other: &Self) -> Self { + Self { + inner: self.inner.sub_mod(&other.inner, &Self::MODULUS), + } + } +} + +impl SubAssign> for ScalarCore +where + C: Curve, +{ + fn sub_assign(&mut self, other: Self) { + *self = *self - other; + } +} + +impl SubAssign<&ScalarCore> for ScalarCore +where + C: Curve, +{ + fn sub_assign(&mut self, other: &Self) { + *self = *self - other; + } +} + +impl Neg for ScalarCore +where + C: Curve, +{ + type Output = Self; + + fn neg(self) -> Self { + Self { + inner: self.inner.neg_mod(&Self::MODULUS), + } + } +} + +impl Neg for &ScalarCore +where + C: Curve, +{ + type Output = ScalarCore; + + fn neg(self) -> ScalarCore { + -*self + } +} diff --git a/elliptic-curve/src/scalar/bytes.rs b/elliptic-curve/src/scalar/bytes.rs deleted file mode 100644 index 1c8e0eede..000000000 --- a/elliptic-curve/src/scalar/bytes.rs +++ /dev/null @@ -1,277 +0,0 @@ -//! Scalar bytes. - -use crate::{ - bigint::{ArrayEncoding as _, Encoding as _}, - Curve, Error, FieldBytes, Result, -}; -use core::convert::TryFrom; -use generic_array::GenericArray; -use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeLess, CtOption}; - -#[cfg(feature = "arithmetic")] -use crate::{group::ff::PrimeField, NonZeroScalar, ProjectiveArithmetic, Scalar}; - -#[cfg(feature = "zeroize")] -use zeroize::Zeroize; - -/// Scalar bytes: wrapper for [`FieldBytes`] which guarantees that the the -/// inner byte value is within range of the [`Curve::ORDER`]. -/// -/// Does not require an arithmetic implementation. -#[derive(Clone, Debug, Eq)] -pub struct ScalarBytes { - /// Inner byte value; guaranteed to be in range of the curve's order. - inner: FieldBytes, -} - -impl ScalarBytes -where - C: Curve, -{ - /// Create new [`ScalarBytes`], checking that the given input is within - /// range of the [`Curve::ORDER`]. - pub fn new(bytes: FieldBytes) -> CtOption { - Self::from_uint(&C::UInt::from_be_byte_array(bytes)) - } - - /// Create [`ScalarBytes`] from the provided `C::UInt`. - pub fn from_uint(uint: &C::UInt) -> CtOption { - let inner = uint.to_be_byte_array(); - let in_range = uint.ct_lt(&C::ORDER); - CtOption::new(Self { inner }, in_range) - } - - /// Convert from a [`Scalar`] type for this curve. - #[cfg(feature = "arithmetic")] - #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] - pub fn from_scalar(scalar: &Scalar) -> Self - where - C: ProjectiveArithmetic, - { - Self { - inner: scalar.to_repr(), - } - } - - /// Convert to a [`Scalar`] type for this curve. - #[cfg(feature = "arithmetic")] - #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] - pub fn to_scalar(&self) -> Scalar - where - C: ProjectiveArithmetic, - { - self.clone().into_scalar() - } - - /// Convert into a [`Scalar`] type for this curve. - #[cfg(feature = "arithmetic")] - #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] - pub fn into_scalar(self) -> Scalar - where - C: ProjectiveArithmetic, - { - Scalar::::from_repr(self.inner).unwrap() - } - - /// Borrow the inner [`FieldBytes`] - pub fn as_bytes(&self) -> &FieldBytes { - &self.inner - } - - /// Convert into [`FieldBytes`] - pub fn into_bytes(self) -> FieldBytes { - self.inner - } - - /// Create [`ScalarBytes`] representing a value of zero. - pub fn zero() -> Self { - Self { - inner: Default::default(), - } - } - - /// Is this [`ScalarBytes`] value all zeroes? - pub fn is_zero(&self) -> Choice { - self.ct_eq(&Self::zero()) - } -} - -impl AsRef> for ScalarBytes -where - C: Curve, -{ - fn as_ref(&self) -> &FieldBytes { - &self.inner - } -} - -impl AsRef<[u8]> for ScalarBytes -where - C: Curve, -{ - fn as_ref(&self) -> &[u8] { - self.inner.as_slice() - } -} - -impl ConditionallySelectable for ScalarBytes -where - Self: Copy, - C: Curve, -{ - fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { - let mut inner = FieldBytes::::default(); - - for (i, (byte_a, byte_b)) in a.inner.iter().zip(b.inner.iter()).enumerate() { - inner[i] = u8::conditional_select(byte_a, byte_b, choice) - } - - Self { inner } - } -} - -impl ConstantTimeEq for ScalarBytes -where - C: Curve, -{ - fn ct_eq(&self, other: &Self) -> Choice { - self.inner - .iter() - .zip(other.inner.iter()) - .fold(Choice::from(0u8), |acc, (a, b)| acc & a.ct_eq(b)) - } -} - -impl Copy for ScalarBytes -where - C: Curve, - FieldBytes: Copy, -{ -} - -impl Default for ScalarBytes -where - C: Curve, -{ - fn default() -> Self { - Self::zero() - } -} - -impl From> for FieldBytes -where - C: Curve, -{ - fn from(scalar_bytes: ScalarBytes) -> FieldBytes { - scalar_bytes.inner - } -} - -impl From<&ScalarBytes> for FieldBytes -where - C: Curve, -{ - fn from(scalar_bytes: &ScalarBytes) -> FieldBytes { - scalar_bytes.inner.clone() - } -} - -#[cfg(feature = "arithmetic")] -impl From> for ScalarBytes -where - C: Curve + ProjectiveArithmetic, -{ - fn from(scalar: NonZeroScalar) -> ScalarBytes { - Self::from(&scalar) - } -} - -#[cfg(feature = "arithmetic")] -impl From<&NonZeroScalar> for ScalarBytes -where - C: Curve + ProjectiveArithmetic, -{ - fn from(scalar: &NonZeroScalar) -> ScalarBytes { - ScalarBytes { - inner: scalar.into(), - } - } -} - -#[cfg(feature = "arithmetic")] -impl TryFrom> for NonZeroScalar -where - C: Curve + ProjectiveArithmetic, -{ - type Error = Error; - - fn try_from(bytes: ScalarBytes) -> Result> { - Option::from(NonZeroScalar::::from_repr(bytes.inner)).ok_or(Error) - } -} - -impl PartialEq for ScalarBytes -where - C: Curve, -{ - fn eq(&self, other: &Self) -> bool { - self.ct_eq(other).into() - } -} - -impl TryFrom<&[u8]> for ScalarBytes -where - C: Curve, -{ - type Error = Error; - - fn try_from(bytes: &[u8]) -> Result { - if bytes.len() == C::UInt::BYTE_SIZE { - Option::from(ScalarBytes::new(GenericArray::clone_from_slice(bytes))).ok_or(Error) - } else { - Err(Error) - } - } -} - -#[cfg(feature = "zeroize")] -impl Zeroize for ScalarBytes -where - C: Curve, -{ - fn zeroize(&mut self) { - self.inner.zeroize(); - } -} - -#[cfg(all(test, feature = "dev"))] -mod tests { - use crate::dev::MockCurve; - use core::convert::TryFrom; - use hex_literal::hex; - - type ScalarBytes = super::ScalarBytes; - - const SCALAR_REPR_ZERO: [u8; 32] = [0u8; 32]; - - const SCALAR_REPR_IN_RANGE: [u8; 32] = - hex!("FFFFFFFF 00000000 FFFFFFFF FFFFFFFF BCE6FAAD A7179E84 F3B9CAC2 FC632550"); - - const SCALAR_REPR_ORDER: [u8; 32] = - hex!("FFFFFFFF 00000000 FFFFFFFF FFFFFFFF BCE6FAAD A7179E84 F3B9CAC2 FC632551"); - - const SCALAR_REPR_MAX: [u8; 32] = - hex!("FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF"); - - #[test] - fn scalar_in_range() { - assert!(ScalarBytes::try_from(SCALAR_REPR_ZERO.as_ref()).is_ok()); - assert!(ScalarBytes::try_from(SCALAR_REPR_IN_RANGE.as_ref()).is_ok()); - } - - #[test] - fn scalar_with_overflow() { - assert!(ScalarBytes::try_from(SCALAR_REPR_ORDER.as_ref()).is_err()); - assert!(ScalarBytes::try_from(SCALAR_REPR_MAX.as_ref()).is_err()); - } -} diff --git a/elliptic-curve/src/scalar/non_zero.rs b/elliptic-curve/src/scalar/non_zero.rs index bc49c80b2..209e10dab 100644 --- a/elliptic-curve/src/scalar/non_zero.rs +++ b/elliptic-curve/src/scalar/non_zero.rs @@ -5,15 +5,13 @@ use crate::{ bigint::Encoding as _, ops::Invert, rand_core::{CryptoRng, RngCore}, - Curve, Error, FieldBytes, ProjectiveArithmetic, Result, Scalar, + Curve, Error, FieldBytes, ProjectiveArithmetic, Result, Scalar, ScalarCore, SecretKey, }; use core::{convert::TryFrom, ops::Deref}; use ff::{Field, PrimeField}; use generic_array::GenericArray; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; - -#[cfg(feature = "zeroize")] -use {crate::SecretKey, zeroize::Zeroize}; +use zeroize::Zeroize; /// Non-zero scalar type. /// @@ -115,12 +113,28 @@ where C: Curve + ProjectiveArithmetic, { fn from(scalar: &NonZeroScalar) -> FieldBytes { - scalar.scalar.to_repr() + scalar.to_repr() + } +} + +impl From> for ScalarCore +where + C: Curve + ProjectiveArithmetic, +{ + fn from(scalar: NonZeroScalar) -> ScalarCore { + ScalarCore::from_bytes_be(scalar.to_repr()).unwrap() + } +} + +impl From<&NonZeroScalar> for ScalarCore +where + C: Curve + ProjectiveArithmetic, +{ + fn from(scalar: &NonZeroScalar) -> ScalarCore { + ScalarCore::from_bytes_be(scalar.to_repr()).unwrap() } } -#[cfg(feature = "zeroize")] -#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] impl From> for NonZeroScalar where C: Curve + ProjectiveArithmetic, @@ -130,14 +144,12 @@ where } } -#[cfg(feature = "zeroize")] -#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] impl From<&SecretKey> for NonZeroScalar where C: Curve + ProjectiveArithmetic, { fn from(sk: &SecretKey) -> NonZeroScalar { - let scalar = sk.as_scalar_bytes().to_scalar(); + let scalar = sk.as_secret_scalar().to_scalar(); debug_assert!(!bool::from(scalar.is_zero())); Self { scalar } } @@ -173,7 +185,6 @@ where } } -#[cfg(feature = "zeroize")] impl Zeroize for NonZeroScalar where C: Curve + ProjectiveArithmetic, diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index 00621dff7..df5e9633a 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -5,13 +5,16 @@ //! //! -use crate::{bigint::Encoding as _, weierstrass::Curve, Error, FieldBytes, FieldSize, Result}; +use crate::{ + bigint::Encoding as _, weierstrass::Curve, Error, FieldBytes, FieldSize, Result, SecretKey, +}; use core::{ fmt::{self, Debug}, ops::Add, }; use generic_array::{typenum::U1, ArrayLength, GenericArray}; use subtle::{Choice, ConditionallySelectable}; +use zeroize::Zeroize; #[cfg(feature = "alloc")] use alloc::boxed::Box; @@ -19,15 +22,12 @@ use alloc::boxed::Box; #[cfg(feature = "arithmetic")] use crate::{weierstrass::DecompressPoint, AffinePoint, ProjectiveArithmetic}; -#[cfg(all(feature = "arithmetic", feature = "zeroize"))] +#[cfg(all(feature = "arithmetic"))] use crate::{ group::{Curve as _, Group}, Scalar, }; -#[cfg(feature = "zeroize")] -use crate::{secret_key::SecretKey, zeroize::Zeroize}; - /// Size of a compressed point for the given elliptic curve when encoded /// using the SEC1 `Elliptic-Curve-Point-to-Octet-String` algorithm /// (including leading `0x02` or `0x03` tag byte). @@ -119,9 +119,8 @@ where /// [`SecretKey`]. /// /// The `compress` flag requests point compression. - #[cfg(all(feature = "arithmetic", feature = "zeroize"))] + #[cfg(all(feature = "arithmetic"))] #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] - #[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] pub fn from_secret_key(secret_key: &SecretKey, compress: bool) -> Self where C: Curve + ProjectiveArithmetic, @@ -336,7 +335,6 @@ where } } -#[cfg(feature = "zeroize")] impl Zeroize for EncodedPoint where C: Curve, @@ -344,7 +342,8 @@ where UncompressedPointSize: ArrayLength, { fn zeroize(&mut self) { - self.bytes.zeroize() + self.bytes.zeroize(); + *self = Self::identity(); } } @@ -526,8 +525,6 @@ where /// /// Curve implementations which also impl [`ProjectiveArithmetic`] will receive /// a blanket default impl of this trait. -#[cfg(feature = "zeroize")] -#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] pub trait ValidatePublicKey where Self: Curve, @@ -552,7 +549,7 @@ where } } -#[cfg(all(feature = "arithmetic", feature = "zeroize"))] +#[cfg(all(feature = "arithmetic"))] impl ValidatePublicKey for C where C: Curve + ProjectiveArithmetic, diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index ebe992f6a..60e69618e 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -10,11 +10,14 @@ #[cfg(feature = "pkcs8")] mod pkcs8; -use crate::{Curve, Error, FieldBytes, Result, ScalarBytes}; +use crate::{Curve, Error, FieldBytes, Result, ScalarCore}; use core::{ convert::TryFrom, fmt::{self, Debug}, }; +use crypto_bigint::Encoding; +use generic_array::GenericArray; +use subtle::{Choice, ConstantTimeEq}; use zeroize::Zeroize; #[cfg(feature = "arithmetic")] @@ -46,8 +49,7 @@ use {crate::pkcs8::FromPrivateKey, core::str::FromStr}; /// Elliptic curve secret keys. /// /// This type wraps a secret scalar value, helping to prevent accidental -/// exposure and securely erasing the value from memory when dropped -/// (when the `zeroize` feature of this crate is enabled). +/// exposure and securely erasing the value from memory when dropped. /// /// # Parsing PKCS#8 Keys /// @@ -69,18 +71,17 @@ use {crate::pkcs8::FromPrivateKey, core::str::FromStr}; /// /// When the `pem` feature of this crate (or a specific RustCrypto elliptic /// curve crate) is enabled, a [`FromStr`] impl is also available. -#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))] #[derive(Clone)] pub struct SecretKey { - /// Serialized scalar value - inner: ScalarBytes, + /// Scalar value + inner: ScalarCore, } impl SecretKey where C: Curve, { - /// Generate a random [`SecretKey`] + /// Generate a random [`SecretKey`]. #[cfg(feature = "arithmetic")] #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub fn random(rng: impl CryptoRng + RngCore) -> Self @@ -93,39 +94,46 @@ where } } - /// Create a new secret key from a serialized scalar value - pub fn new(scalar: ScalarBytes) -> Self { + /// Create a new secret key from a scalar value. + pub fn new(scalar: ScalarCore) -> Self { Self { inner: scalar } } - /// Deserialize raw private scalar as a big endian integer - pub fn from_bytes(bytes: impl AsRef<[u8]>) -> Result { - let scalar = ScalarBytes::try_from(bytes.as_ref())?; + /// Deserialize raw private scalar as a big endian integer. + pub fn from_bytes_be(bytes: &[u8]) -> Result { + if bytes.len() != C::UInt::BYTE_SIZE { + return Err(Error); + } - if scalar.is_zero().into() { + let inner: ScalarCore = Option::from(ScalarCore::from_bytes_be( + GenericArray::clone_from_slice(bytes), + )) + .ok_or(Error)?; + + if inner.is_zero().into() { return Err(Error); } - Ok(Self { inner: scalar }) + Ok(Self { inner }) } - /// Expose the byte serialization of the value this [`SecretKey`] wraps - pub fn to_bytes(&self) -> FieldBytes { - self.inner.clone().into() + /// Expose the byte serialization of the value this [`SecretKey`] wraps. + pub fn to_bytes_be(&self) -> FieldBytes { + self.inner.to_bytes_be() } - /// Borrow the inner secret [`ScalarBytes`] value. + /// Borrow the inner secret [`ScalarCore`] value. /// /// # Warning /// /// This value is key material. /// /// Please treat it with the care it deserves! - pub fn as_scalar_bytes(&self) -> &ScalarBytes { + pub fn as_secret_scalar(&self) -> &ScalarCore { &self.inner } - /// Get the secret scalar value for this key.. + /// Get the secret scalar value for this key. #[cfg(feature = "arithmetic")] #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub fn to_secret_scalar(&self) -> NonZeroScalar @@ -202,27 +210,42 @@ where } } -#[cfg(feature = "arithmetic")] -#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] -impl From> for SecretKey +impl ConstantTimeEq for SecretKey where - C: Curve + ProjectiveArithmetic, + C: Curve, { - fn from(scalar: NonZeroScalar) -> SecretKey { - SecretKey::from(&scalar) + fn ct_eq(&self, other: &Self) -> Choice { + self.inner.ct_eq(&other.inner) } } -#[cfg(feature = "arithmetic")] -#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] -impl From<&NonZeroScalar> for SecretKey +impl Debug for SecretKey where - C: Curve + ProjectiveArithmetic, + C: Curve, { - fn from(scalar: &NonZeroScalar) -> SecretKey { - SecretKey { - inner: scalar.into(), - } + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // TODO(tarcieri): use `debug_struct` and `finish_non_exhaustive` when stable + write!(f, "SecretKey<{:?}>{{ ... }}", C::default()) + } +} + +impl Drop for SecretKey +where + C: Curve, +{ + fn drop(&mut self) { + self.inner.zeroize(); + } +} + +impl Eq for SecretKey {} + +impl PartialEq for SecretKey +where + C: Curve, +{ + fn eq(&self, other: &Self) -> bool { + self.ct_eq(other).into() } } @@ -233,25 +256,30 @@ where type Error = Error; fn try_from(slice: &[u8]) -> Result { - Self::from_bytes(slice) + Self::from_bytes_be(slice) } } -impl Debug for SecretKey +#[cfg(feature = "arithmetic")] +#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] +impl From> for SecretKey where - C: Curve, + C: Curve + ProjectiveArithmetic, { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - // TODO(tarcieri): use `debug_struct` and `finish_non_exhaustive` when stable - write!(f, "SecretKey<{:?}>{{ ... }}", C::default()) + fn from(scalar: NonZeroScalar) -> SecretKey { + SecretKey::from(&scalar) } } -impl Drop for SecretKey +#[cfg(feature = "arithmetic")] +#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] +impl From<&NonZeroScalar> for SecretKey where - C: Curve, + C: Curve + ProjectiveArithmetic, { - fn drop(&mut self) { - self.inner.zeroize(); + fn from(scalar: &NonZeroScalar) -> SecretKey { + SecretKey { + inner: scalar.into(), + } } } diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs index e6e044eb7..911486a52 100644 --- a/elliptic-curve/src/secret_key/pkcs8.rs +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -8,14 +8,9 @@ use crate::{ use core::ops::Add; use generic_array::{typenum::U1, ArrayLength}; use pkcs8::{ - der::{ - self, - asn1::{BitString, ContextSpecific, OctetString}, - TagNumber, - }, + der::{self, TagNumber}, FromPrivateKey, }; -use zeroize::Zeroize; // Imports for the `ToPrivateKey` impl // TODO(tarcieri): use weak activation of `pkcs8/alloc` for gating `ToPrivateKey` impl @@ -27,8 +22,14 @@ use { AffinePoint, ProjectiveArithmetic, }, core::convert::TryInto, - pkcs8::{der::Encodable, ToPrivateKey}, - zeroize::Zeroizing, + pkcs8::{ + der::{ + asn1::{BitString, ContextSpecific, OctetString}, + Encodable, + }, + ToPrivateKey, + }, + zeroize::{Zeroize, Zeroizing}, }; // Imports for actual PEM support @@ -65,7 +66,7 @@ where return Err(der::Tag::Integer.value_error()); } - let secret_key = Self::from_bytes(decoder.octet_string()?) + let secret_key = Self::from_bytes_be(decoder.octet_string()?.as_ref()) .map_err(|_| der::Tag::Sequence.value_error())?; let public_key = decoder @@ -102,7 +103,7 @@ where { fn to_pkcs8_der(&self) -> pkcs8::Result { // TODO(tarcieri): wrap `secret_key_bytes` in `Zeroizing` - let mut secret_key_bytes = self.to_bytes(); + let mut secret_key_bytes = self.to_bytes_be(); let secret_key_field = OctetString::new(&secret_key_bytes)?; let public_key_bytes = self.public_key().to_encoded_point(false); let public_key_field = ContextSpecific { diff --git a/elliptic-curve/tests/pkcs8.rs b/elliptic-curve/tests/pkcs8.rs index 14c0fb5d1..0e74676d6 100644 --- a/elliptic-curve/tests/pkcs8.rs +++ b/elliptic-curve/tests/pkcs8.rs @@ -22,7 +22,7 @@ const EXAMPLE_SCALAR: [u8; 32] = /// Example PKCS#8 private key fn example_private_key() -> PrivateKeyDocument { - SecretKey::from_bytes(&EXAMPLE_SCALAR) + SecretKey::from_bytes_be(&EXAMPLE_SCALAR) .unwrap() .to_pkcs8_der() .unwrap() @@ -31,7 +31,7 @@ fn example_private_key() -> PrivateKeyDocument { #[test] fn decode_pkcs8_private_key_from_der() { let secret_key = SecretKey::from_pkcs8_der(example_private_key().as_ref()).unwrap(); - assert_eq!(secret_key.to_bytes().as_slice(), &EXAMPLE_SCALAR); + assert_eq!(secret_key.to_bytes_be().as_slice(), &EXAMPLE_SCALAR); } #[test] diff --git a/elliptic-curve/tests/secret_key.rs b/elliptic-curve/tests/secret_key.rs index a0d1dd260..99476c239 100644 --- a/elliptic-curve/tests/secret_key.rs +++ b/elliptic-curve/tests/secret_key.rs @@ -6,5 +6,5 @@ use elliptic_curve::dev::SecretKey; #[test] fn undersize_secret_key() { - assert!(SecretKey::from_bytes(&[]).is_err()); + assert!(SecretKey::from_bytes_be(&[]).is_err()); } From 09d9ea6eedbf317680a07d68667ec40856b08ef2 Mon Sep 17 00:00:00 2001 From: Michael Rosenberg Date: Sun, 5 Sep 2021 10:31:34 -0400 Subject: [PATCH 0595/1461] Defined the SignerMut trait (#734) --- signature/CHANGELOG.md | 1 + signature/src/signer.rs | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/signature/CHANGELOG.md b/signature/CHANGELOG.md index 847134ef8..b21101d9e 100644 --- a/signature/CHANGELOG.md +++ b/signature/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Re-export `rand_core`. Emit compilation error if unstable functionality is enabled by bypassing the preview features. ([#683]) +- Defined the `SignerMut` trait [#683]: https://github.com/RustCrypto/traits/pull/683 diff --git a/signature/src/signer.rs b/signature/src/signer.rs index 0031b73a7..8ec1099c3 100644 --- a/signature/src/signer.rs +++ b/signature/src/signer.rs @@ -24,6 +24,33 @@ pub trait Signer { fn try_sign(&self, msg: &[u8]) -> Result; } +/// Sign the provided message bytestring using `&mut Self` (e.g., an evolving +/// cryptographic key), returning a digital signature. +pub trait SignerMut { + /// Sign the given message, update the state, and return a digital signature + fn sign(&mut self, msg: &[u8]) -> S { + self.try_sign(msg).expect("signature operation failed") + } + + /// Attempt to sign the given message, updating the state, and returning a + /// digital signature on success, or an error if something went wrong. + /// + /// Signing can fail, e.g., if the number of time periods allowed by the + /// current key is exceeded. + fn try_sign(&mut self, msg: &[u8]) -> Result; +} + +// Blanket impl of SignerMut for all Signer types +impl SignerMut for T +where + T: Signer, + S: Signature, +{ + fn try_sign(&mut self, msg: &[u8]) -> Result { + T::try_sign(&self, msg) + } +} + /// Sign the given prehashed message [`Digest`] using `Self`. /// /// ## Notes From 128ae1def5abcf39ac5f3d35c63ab951d29cc4ff Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 7 Sep 2021 18:33:16 -0600 Subject: [PATCH 0596/1461] elliptic-curve: additional `ScalarCore` methods (#736) --- elliptic-curve/src/scalar.rs | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/elliptic-curve/src/scalar.rs b/elliptic-curve/src/scalar.rs index 77fdb92ef..ad49cea39 100644 --- a/elliptic-curve/src/scalar.rs +++ b/elliptic-curve/src/scalar.rs @@ -79,11 +79,31 @@ where Self::new(C::UInt::from_le_byte_array(bytes)) } + /// Borrow the inner [`UInt`]. + pub fn as_uint(&self) -> &C::UInt { + &self.inner + } + + /// Borrow the inner limbs as a slice. + pub fn as_limbs(&self) -> &[Limb] { + self.inner.as_ref() + } + /// Is this [`ScalarCore`] value equal to zero? pub fn is_zero(&self) -> Choice { self.inner.is_zero() } + /// Is this [`ScalarCore`] value even? + pub fn is_even(&self) -> Choice { + self.inner.is_even() + } + + /// Is this [`ScalarCore`] value odd? + pub fn is_odd(&self) -> Choice { + self.inner.is_odd() + } + /// Encode [`ScalarCore`] as big endian bytes. pub fn to_bytes_be(self) -> FieldBytes { self.inner.to_be_byte_array() @@ -113,7 +133,7 @@ where C: Curve, { fn as_ref(&self) -> &[Limb] { - self.inner.as_ref() + self.as_limbs() } } @@ -173,7 +193,16 @@ where C: Curve, { fn partial_cmp(&self, other: &Self) -> Option { - Some(self.inner.cmp(&other.inner)) + Some(self.cmp(other)) + } +} + +impl Ord for ScalarCore +where + C: Curve, +{ + fn cmp(&self, other: &Self) -> Ordering { + self.inner.cmp(&other.inner) } } From 405c176ce5e9d4007f6f87ae7fc89348ffdc930b Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 7 Sep 2021 19:50:11 -0600 Subject: [PATCH 0597/1461] elliptic-curve: refactor `PrimeCurve` crate (#737) Renames `weierstrass::Curve` to `PrimeCurve`, a marker trait for curves of prime order. The `weierstrass` module is otherwise removed/renamed internally, with the traits previously contained re-exported from the toplevel. --- elliptic-curve/src/dev.rs | 6 +-- elliptic-curve/src/ecdh.rs | 4 +- elliptic-curve/src/jwk.rs | 33 +++++++-------- elliptic-curve/src/lib.rs | 6 ++- .../src/{weierstrass.rs => point.rs} | 11 ++--- elliptic-curve/src/public_key.rs | 42 ++++++++++--------- elliptic-curve/src/scalar.rs | 2 +- elliptic-curve/src/sec1.rs | 40 +++++++++--------- elliptic-curve/src/secret_key.rs | 10 ++--- elliptic-curve/src/secret_key/pkcs8.rs | 10 ++--- 10 files changed, 82 insertions(+), 82 deletions(-) rename elliptic-curve/src/{weierstrass.rs => point.rs} (80%) diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 4a9a25ece..9eebde023 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -7,9 +7,9 @@ use crate::{ rand_core::RngCore, sec1::{FromEncodedPoint, ToEncodedPoint}, subtle::{Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeLess, CtOption}, - weierstrass, zeroize::Zeroize, - AffineArithmetic, AlgorithmParameters, Curve, ProjectiveArithmetic, ScalarArithmetic, + AffineArithmetic, AlgorithmParameters, Curve, PrimeCurve, ProjectiveArithmetic, + ScalarArithmetic, }; use core::{ convert::TryFrom, @@ -44,7 +44,7 @@ impl Curve for MockCurve { U256::from_be_hex("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551"); } -impl weierstrass::Curve for MockCurve {} +impl PrimeCurve for MockCurve {} impl AffineArithmetic for MockCurve { type AffinePoint = AffinePoint; diff --git a/elliptic-curve/src/ecdh.rs b/elliptic-curve/src/ecdh.rs index 6a670c01d..db403f0fc 100644 --- a/elliptic-curve/src/ecdh.rs +++ b/elliptic-curve/src/ecdh.rs @@ -27,8 +27,8 @@ //! [SIGMA]: https://webee.technion.ac.il/~hugo/sigma-pdf.pdf use crate::{ - weierstrass::Curve, AffinePoint, FieldBytes, NonZeroScalar, ProjectiveArithmetic, - ProjectivePoint, PublicKey, Scalar, + AffinePoint, Curve, FieldBytes, NonZeroScalar, ProjectiveArithmetic, ProjectivePoint, + PublicKey, Scalar, }; use core::borrow::Borrow; use group::Curve as _; diff --git a/elliptic-curve/src/jwk.rs b/elliptic-curve/src/jwk.rs index 00eb9b06b..48558513b 100644 --- a/elliptic-curve/src/jwk.rs +++ b/elliptic-curve/src/jwk.rs @@ -8,8 +8,7 @@ use crate::{ Coordinates, EncodedPoint, UncompressedPointSize, UntaggedPointSize, ValidatePublicKey, }, secret_key::SecretKey, - weierstrass::Curve, - Error, FieldBytes, + Curve, Error, FieldBytes, PrimeCurve, }; use alloc::{ borrow::ToOwned, @@ -119,7 +118,7 @@ impl JwkEcKey { #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub fn to_public_key(&self) -> Result, Error> where - C: Curve + JwkParameters + ProjectiveArithmetic, + C: PrimeCurve + JwkParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, @@ -132,7 +131,7 @@ impl JwkEcKey { #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub fn to_secret_key(&self) -> Result, Error> where - C: Curve + JwkParameters + ValidatePublicKey, + C: PrimeCurve + JwkParameters + ValidatePublicKey, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -157,7 +156,7 @@ impl ToString for JwkEcKey { #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] impl TryFrom for EncodedPoint where - C: Curve + JwkParameters, + C: PrimeCurve + JwkParameters, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -171,7 +170,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] impl TryFrom<&JwkEcKey> for EncodedPoint where - C: Curve + JwkParameters, + C: PrimeCurve + JwkParameters, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -191,7 +190,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] impl TryFrom> for JwkEcKey where - C: Curve + JwkParameters, + C: PrimeCurve + JwkParameters, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -205,7 +204,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] impl TryFrom<&EncodedPoint> for JwkEcKey where - C: Curve + JwkParameters, + C: PrimeCurve + JwkParameters, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -227,7 +226,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] impl TryFrom for SecretKey where - C: Curve + JwkParameters + ValidatePublicKey, + C: PrimeCurve + JwkParameters + ValidatePublicKey, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -241,7 +240,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] impl TryFrom<&JwkEcKey> for SecretKey where - C: Curve + JwkParameters + ValidatePublicKey, + C: PrimeCurve + JwkParameters + ValidatePublicKey, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -269,7 +268,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] impl From> for JwkEcKey where - C: Curve + JwkParameters + ProjectiveArithmetic, + C: PrimeCurve + JwkParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, Scalar: Zeroize, UntaggedPointSize: Add + ArrayLength, @@ -285,7 +284,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] impl From<&SecretKey> for JwkEcKey where - C: Curve + JwkParameters + ProjectiveArithmetic, + C: PrimeCurve + JwkParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, Scalar: Zeroize, UntaggedPointSize: Add + ArrayLength, @@ -305,7 +304,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] impl TryFrom for PublicKey where - C: Curve + JwkParameters + ProjectiveArithmetic, + C: PrimeCurve + JwkParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, @@ -322,7 +321,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] impl TryFrom<&JwkEcKey> for PublicKey where - C: Curve + JwkParameters + ProjectiveArithmetic, + C: PrimeCurve + JwkParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, @@ -339,7 +338,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] impl From> for JwkEcKey where - C: Curve + JwkParameters + ProjectiveArithmetic, + C: PrimeCurve + JwkParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, @@ -354,7 +353,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] impl From<&PublicKey> for JwkEcKey where - C: Curve + JwkParameters + ProjectiveArithmetic, + C: PrimeCurve + JwkParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, @@ -631,7 +630,7 @@ impl Serialize for JwkEcKey { } /// Decode a Base64url-encoded field element -fn decode_base64url_fe(s: &str) -> Result, Error> { +fn decode_base64url_fe(s: &str) -> Result, Error> { let mut result = FieldBytes::::default(); Base64Url::decode(s, &mut result).map_err(|_| Error)?; Ok(result) diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 7a4f9cc06..ba8c7dcc2 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -33,9 +33,9 @@ pub use rand_core; pub mod ops; pub mod sec1; -pub mod weierstrass; mod error; +mod point; mod scalar; mod secret_key; @@ -57,6 +57,7 @@ mod jwk; pub use crate::{ error::{Error, Result}, + point::{DecompactPoint, DecompressPoint, PointCompaction, PointCompression}, scalar::ScalarCore, secret_key::SecretKey, }; @@ -126,6 +127,9 @@ pub trait Curve: 'static + Copy + Clone + Debug + Default + Eq + Ord + Send + Sy const ORDER: Self::UInt; } +/// Marker trait for elliptic curves with prime order. +pub trait PrimeCurve: Curve {} + /// Size of field elements of this elliptic curve. pub type FieldSize = <::UInt as bigint::ArrayEncoding>::ByteSize; diff --git a/elliptic-curve/src/weierstrass.rs b/elliptic-curve/src/point.rs similarity index 80% rename from elliptic-curve/src/weierstrass.rs rename to elliptic-curve/src/point.rs index e6c1c0ace..4ff58aeee 100644 --- a/elliptic-curve/src/weierstrass.rs +++ b/elliptic-curve/src/point.rs @@ -1,18 +1,15 @@ -//! Elliptic curves in short Weierstrass form. +//! Traits for elliptic curve points. -use crate::FieldBytes; +use crate::{Curve, FieldBytes}; use subtle::{Choice, CtOption}; -/// Marker trait for elliptic curves in short Weierstrass form. -pub trait Curve: super::Curve {} - /// Point compression settings. pub trait PointCompression { /// Should point compression be applied by default? const COMPRESS_POINTS: bool; } -/// Point compaction settings +/// Point compaction settings. pub trait PointCompaction { /// Should point compaction be applied by default? const COMPACT_POINTS: bool; @@ -25,7 +22,7 @@ pub trait DecompressPoint: Sized { fn decompress(x: &FieldBytes, y_is_odd: Choice) -> CtOption; } -/// Attempt to decompact an elliptic curve point from an x-coordinate +/// Attempt to decompact an elliptic curve point from an x-coordinate. pub trait DecompactPoint: Sized { /// Attempt to decompact an elliptic curve point fn decompact(x: &FieldBytes) -> CtOption; diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index 1c430d65b..767ee578f 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -2,11 +2,12 @@ use crate::{ consts::U1, + point::PointCompression, sec1::{ EncodedPoint, FromEncodedPoint, ToEncodedPoint, UncompressedPointSize, UntaggedPointSize, }, - weierstrass::{Curve, PointCompression}, - AffinePoint, Error, NonZeroScalar, ProjectiveArithmetic, ProjectivePoint, Result, + AffinePoint, Curve, Error, NonZeroScalar, PrimeCurve, ProjectiveArithmetic, ProjectivePoint, + Result, }; use core::{ cmp::Ordering, @@ -98,6 +99,7 @@ where pub fn from_sec1_bytes(bytes: &[u8]) -> Result where Self: TryFrom, Error = Error>, + C: PrimeCurve, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -123,7 +125,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] pub fn from_jwk(jwk: &JwkEcKey) -> Result where - C: JwkParameters, + C: PrimeCurve + JwkParameters, AffinePoint: FromEncodedPoint + ToEncodedPoint, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, @@ -136,7 +138,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] pub fn from_jwk_str(jwk: &str) -> Result where - C: JwkParameters, + C: PrimeCurve + JwkParameters, AffinePoint: FromEncodedPoint + ToEncodedPoint, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, @@ -149,7 +151,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] pub fn to_jwk(&self) -> JwkEcKey where - C: JwkParameters, + C: PrimeCurve + JwkParameters, AffinePoint: FromEncodedPoint + ToEncodedPoint, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, @@ -162,7 +164,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] pub fn to_jwk_string(&self) -> String where - C: JwkParameters, + C: PrimeCurve + JwkParameters, AffinePoint: FromEncodedPoint + ToEncodedPoint, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, @@ -184,7 +186,7 @@ impl Copy for PublicKey where C: Curve + ProjectiveArithmetic {} impl TryFrom> for PublicKey where - C: Curve + ProjectiveArithmetic, + C: PrimeCurve + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, @@ -198,7 +200,7 @@ where impl TryFrom<&EncodedPoint> for PublicKey where - C: Curve + ProjectiveArithmetic, + C: PrimeCurve + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, @@ -212,7 +214,7 @@ where impl From> for EncodedPoint where - C: Curve + ProjectiveArithmetic + PointCompression, + C: PrimeCurve + ProjectiveArithmetic + PointCompression, AffinePoint: FromEncodedPoint + ToEncodedPoint, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, @@ -224,7 +226,7 @@ where impl From<&PublicKey> for EncodedPoint where - C: Curve + ProjectiveArithmetic + PointCompression, + C: PrimeCurve + ProjectiveArithmetic + PointCompression, AffinePoint: FromEncodedPoint + ToEncodedPoint, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, @@ -236,7 +238,7 @@ where impl FromEncodedPoint for PublicKey where - C: Curve + ProjectiveArithmetic, + C: PrimeCurve + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, @@ -250,7 +252,7 @@ where impl ToEncodedPoint for PublicKey where - C: Curve + ProjectiveArithmetic, + C: PrimeCurve + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, @@ -264,7 +266,7 @@ where impl Eq for PublicKey where - C: Curve + ProjectiveArithmetic, + C: PrimeCurve + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, @@ -273,7 +275,7 @@ where impl PartialEq for PublicKey where - C: Curve + ProjectiveArithmetic, + C: PrimeCurve + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, @@ -285,7 +287,7 @@ where impl PartialOrd for PublicKey where - C: Curve + ProjectiveArithmetic, + C: PrimeCurve + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, @@ -297,7 +299,7 @@ where impl Ord for PublicKey where - C: Curve + ProjectiveArithmetic, + C: PrimeCurve + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, @@ -315,7 +317,7 @@ where impl FromPublicKey for PublicKey where Self: TryFrom, Error = Error>, - C: Curve + AlgorithmParameters + ProjectiveArithmetic, + C: PrimeCurve + AlgorithmParameters + ProjectiveArithmetic, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -342,7 +344,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "pem")))] impl ToPublicKey for PublicKey where - C: Curve + AlgorithmParameters + ProjectiveArithmetic, + C: PrimeCurve + AlgorithmParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, @@ -363,7 +365,7 @@ where impl FromStr for PublicKey where Self: TryFrom, Error = Error>, - C: Curve + AlgorithmParameters + ProjectiveArithmetic, + C: PrimeCurve + AlgorithmParameters + ProjectiveArithmetic, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -378,7 +380,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "pem")))] impl ToString for PublicKey where - C: Curve + AlgorithmParameters + ProjectiveArithmetic, + C: PrimeCurve + AlgorithmParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, diff --git a/elliptic-curve/src/scalar.rs b/elliptic-curve/src/scalar.rs index ad49cea39..bcb394a7b 100644 --- a/elliptic-curve/src/scalar.rs +++ b/elliptic-curve/src/scalar.rs @@ -79,7 +79,7 @@ where Self::new(C::UInt::from_le_byte_array(bytes)) } - /// Borrow the inner [`UInt`]. + /// Borrow the inner `C::UInt`. pub fn as_uint(&self) -> &C::UInt { &self.inner } diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index df5e9633a..89589375b 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -5,9 +5,7 @@ //! //! -use crate::{ - bigint::Encoding as _, weierstrass::Curve, Error, FieldBytes, FieldSize, Result, SecretKey, -}; +use crate::{bigint::Encoding as _, Error, FieldBytes, FieldSize, PrimeCurve, Result, SecretKey}; use core::{ fmt::{self, Debug}, ops::Add, @@ -20,7 +18,7 @@ use zeroize::Zeroize; use alloc::boxed::Box; #[cfg(feature = "arithmetic")] -use crate::{weierstrass::DecompressPoint, AffinePoint, ProjectiveArithmetic}; +use crate::{point::DecompressPoint, AffinePoint, ProjectiveArithmetic}; #[cfg(all(feature = "arithmetic"))] use crate::{ @@ -49,7 +47,7 @@ pub type UntaggedPointSize = as Add>::Output; #[derive(Clone, Default, Eq, PartialEq, PartialOrd, Ord)] pub struct EncodedPoint where - C: Curve, + C: PrimeCurve, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -59,7 +57,7 @@ where #[allow(clippy::len_without_is_empty)] impl EncodedPoint where - C: Curve, + C: PrimeCurve, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -123,7 +121,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub fn from_secret_key(secret_key: &SecretKey, compress: bool) -> Self where - C: Curve + ProjectiveArithmetic, + C: PrimeCurve + ProjectiveArithmetic, AffinePoint: ToEncodedPoint, Scalar: Zeroize, { @@ -161,7 +159,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub fn to_untagged_bytes(&self) -> Option>> where - C: Curve + ProjectiveArithmetic, + C: PrimeCurve + ProjectiveArithmetic, AffinePoint: DecompressPoint + ToEncodedPoint, { self.decompress().map(|point| { @@ -201,7 +199,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub fn decompress(&self) -> Option where - C: Curve + ProjectiveArithmetic, + C: PrimeCurve + ProjectiveArithmetic, AffinePoint: DecompressPoint + ToEncodedPoint, { match self.coordinates() { @@ -287,7 +285,7 @@ where impl AsRef<[u8]> for EncodedPoint where - C: Curve, + C: PrimeCurve, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -299,7 +297,7 @@ where impl ConditionallySelectable for EncodedPoint where - C: Curve, + C: PrimeCurve, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, as ArrayLength>::ArrayType: Copy, @@ -317,7 +315,7 @@ where impl Copy for EncodedPoint where - C: Curve, + C: PrimeCurve, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, as ArrayLength>::ArrayType: Copy, @@ -326,7 +324,7 @@ where impl Debug for EncodedPoint where - C: Curve, + C: PrimeCurve, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -337,7 +335,7 @@ where impl Zeroize for EncodedPoint where - C: Curve, + C: PrimeCurve, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -350,7 +348,7 @@ where /// Enum representing the coordinates of either compressed or uncompressed /// SEC1-encoded elliptic curve points. #[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum Coordinates<'a, C: Curve> { +pub enum Coordinates<'a, C: PrimeCurve> { /// Identity point (a.k.a. point at infinity) Identity, @@ -379,7 +377,7 @@ pub enum Coordinates<'a, C: Curve> { }, } -impl<'a, C: Curve> Coordinates<'a, C> { +impl<'a, C: PrimeCurve> Coordinates<'a, C> { /// Get the tag octet needed to encode this set of [`Coordinates`] pub fn tag(&self) -> Tag { match self { @@ -480,7 +478,7 @@ impl From for u8 { pub trait FromEncodedPoint where Self: Sized, - C: Curve, + C: PrimeCurve, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -497,7 +495,7 @@ where /// This is intended for use with the `AffinePoint` type for a given elliptic curve. pub trait ToEncodedPoint where - C: Curve, + C: PrimeCurve, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -511,7 +509,7 @@ where /// This is intended for use with the `AffinePoint` type for a given elliptic curve. pub trait ToCompactEncodedPoint where - C: Curve, + C: PrimeCurve, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -527,7 +525,7 @@ where /// a blanket default impl of this trait. pub trait ValidatePublicKey where - Self: Curve, + Self: PrimeCurve, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -552,7 +550,7 @@ where #[cfg(all(feature = "arithmetic"))] impl ValidatePublicKey for C where - C: Curve + ProjectiveArithmetic, + C: PrimeCurve + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, Scalar: Zeroize, UntaggedPointSize: Add + ArrayLength, diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 60e69618e..d674fd2ad 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -23,7 +23,7 @@ use zeroize::Zeroize; #[cfg(feature = "arithmetic")] use crate::{ rand_core::{CryptoRng, RngCore}, - weierstrass, NonZeroScalar, ProjectiveArithmetic, PublicKey, Scalar, + NonZeroScalar, ProjectiveArithmetic, PublicKey, Scalar, }; #[cfg(feature = "jwk")] @@ -38,7 +38,7 @@ use crate::{ use { crate::{ sec1::{FromEncodedPoint, ToEncodedPoint}, - AffinePoint, + AffinePoint, PrimeCurve, }, alloc::string::{String, ToString}, }; @@ -149,7 +149,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub fn public_key(&self) -> PublicKey where - C: weierstrass::Curve + ProjectiveArithmetic, + C: Curve + ProjectiveArithmetic, Scalar: Zeroize, { PublicKey::from_secret_scalar(&self.to_secret_scalar()) @@ -185,7 +185,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] pub fn to_jwk(&self) -> JwkEcKey where - C: JwkParameters + ProjectiveArithmetic, + C: PrimeCurve + JwkParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, Scalar: Zeroize, UntaggedPointSize: Add + ArrayLength, @@ -200,7 +200,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] pub fn to_jwk_string(&self) -> String where - C: JwkParameters + ProjectiveArithmetic, + C: PrimeCurve + JwkParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, Scalar: Zeroize, UntaggedPointSize: Add + ArrayLength, diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs index 911486a52..40287f96a 100644 --- a/elliptic-curve/src/secret_key/pkcs8.rs +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -3,7 +3,7 @@ use super::SecretKey; use crate::{ sec1::{self, UncompressedPointSize, UntaggedPointSize, ValidatePublicKey}, - weierstrass, AlgorithmParameters, ALGORITHM_OID, + AlgorithmParameters, Curve, ALGORITHM_OID, }; use core::ops::Add; use generic_array::{typenum::U1, ArrayLength}; @@ -35,7 +35,7 @@ use { // Imports for actual PEM support #[cfg(feature = "pem")] use { - crate::{error::Error, Result}, + crate::{error::Error, PrimeCurve, Result}, core::str::FromStr, }; @@ -48,7 +48,7 @@ const PUBLIC_KEY_TAG: TagNumber = TagNumber::new(1); #[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))] impl FromPrivateKey for SecretKey where - C: weierstrass::Curve + AlgorithmParameters + ValidatePublicKey, + C: Curve + AlgorithmParameters + ValidatePublicKey, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -95,7 +95,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "pem")))] impl ToPrivateKey for SecretKey where - C: weierstrass::Curve + AlgorithmParameters + ProjectiveArithmetic, + C: PrimeCurve + AlgorithmParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, Scalar: Zeroize, UntaggedPointSize: Add + ArrayLength, @@ -131,7 +131,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "pem")))] impl FromStr for SecretKey where - C: weierstrass::Curve + AlgorithmParameters + ValidatePublicKey, + C: PrimeCurve + AlgorithmParameters + ValidatePublicKey, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { From 9d916903fa715b52f8fe80e72f621bf9632a9e8a Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 7 Sep 2021 20:39:22 -0600 Subject: [PATCH 0598/1461] elliptic-curve: mandatory `DefaultIsZeroes` bounds (#738) Makes `DefaultIsZeroes` a mandatory bound for all `*Arithmetic` traits (i.e. scalar, affine, projective) --- elliptic-curve/src/arithmetic.rs | 11 +++++++---- elliptic-curve/src/dev.rs | 14 +++++++------- elliptic-curve/src/ecdh.rs | 12 +----------- elliptic-curve/src/jwk.rs | 4 +--- elliptic-curve/src/scalar/non_zero.rs | 1 - elliptic-curve/src/sec1.rs | 7 +------ elliptic-curve/src/secret_key.rs | 9 +++------ elliptic-curve/src/secret_key/pkcs8.rs | 2 -- 8 files changed, 20 insertions(+), 40 deletions(-) diff --git a/elliptic-curve/src/arithmetic.rs b/elliptic-curve/src/arithmetic.rs index db377d680..935727dcc 100644 --- a/elliptic-curve/src/arithmetic.rs +++ b/elliptic-curve/src/arithmetic.rs @@ -3,21 +3,23 @@ use crate::{Curve, FieldBytes}; use core::fmt::Debug; use subtle::{ConditionallySelectable, ConstantTimeEq}; +use zeroize::DefaultIsZeroes; /// Elliptic curve with affine arithmetic implementation. #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub trait AffineArithmetic: Curve + ScalarArithmetic { /// Elliptic curve point in affine coordinates. - type AffinePoint: Copy + type AffinePoint: 'static + + Copy + Clone + ConditionallySelectable + ConstantTimeEq + Debug + Default + + DefaultIsZeroes + Sized + Send - + Sync - + 'static; + + Sync; } /// Elliptic curve with projective arithmetic implementation. @@ -37,6 +39,7 @@ pub trait ProjectiveArithmetic: Curve + AffineArithmetic { type ProjectivePoint: ConditionallySelectable + ConstantTimeEq + Default + + DefaultIsZeroes + From + Into + group::Curve @@ -59,5 +62,5 @@ pub trait ScalarArithmetic: Curve { /// - [`Default`] /// - [`Send`] /// - [`Sync`] - type Scalar: ff::Field + ff::PrimeField>; + type Scalar: DefaultIsZeroes + ff::Field + ff::PrimeField>; } diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 9eebde023..cde377f6d 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -7,7 +7,7 @@ use crate::{ rand_core::RngCore, sec1::{FromEncodedPoint, ToEncodedPoint}, subtle::{Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeLess, CtOption}, - zeroize::Zeroize, + zeroize::DefaultIsZeroes, AffineArithmetic, AlgorithmParameters, Curve, PrimeCurve, ProjectiveArithmetic, ScalarArithmetic, }; @@ -209,6 +209,8 @@ impl ConstantTimeEq for Scalar { } } +impl DefaultIsZeroes for Scalar {} + impl Add for Scalar { type Output = Scalar; @@ -319,12 +321,6 @@ impl From<&Scalar> for FieldBytes { } } -impl Zeroize for Scalar { - fn zeroize(&mut self) { - self.0.as_mut().zeroize(); - } -} - /// Example affine point type #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum AffinePoint { @@ -359,6 +355,8 @@ impl Default for AffinePoint { } } +impl DefaultIsZeroes for AffinePoint {} + impl FromEncodedPoint for AffinePoint { fn from_encoded_point(point: &EncodedPoint) -> Option { if point.is_identity() { @@ -431,6 +429,8 @@ impl Default for ProjectivePoint { } } +impl DefaultIsZeroes for ProjectivePoint {} + impl From for ProjectivePoint { fn from(point: AffinePoint) -> ProjectivePoint { match point { diff --git a/elliptic-curve/src/ecdh.rs b/elliptic-curve/src/ecdh.rs index db403f0fc..5af896e78 100644 --- a/elliptic-curve/src/ecdh.rs +++ b/elliptic-curve/src/ecdh.rs @@ -27,8 +27,7 @@ //! [SIGMA]: https://webee.technion.ac.il/~hugo/sigma-pdf.pdf use crate::{ - AffinePoint, Curve, FieldBytes, NonZeroScalar, ProjectiveArithmetic, ProjectivePoint, - PublicKey, Scalar, + AffinePoint, Curve, FieldBytes, NonZeroScalar, ProjectiveArithmetic, ProjectivePoint, PublicKey, }; use core::borrow::Borrow; use group::Curve as _; @@ -61,8 +60,6 @@ pub fn diffie_hellman( ) -> SharedSecret where C: Curve + ProjectiveArithmetic, - AffinePoint: Zeroize, - Scalar: Zeroize, SharedSecret: for<'a> From<&'a AffinePoint>, { let public_point = ProjectivePoint::::from(*public_key.borrow()); @@ -96,7 +93,6 @@ where pub struct EphemeralSecret where C: Curve + ProjectiveArithmetic, - Scalar: Zeroize, { scalar: NonZeroScalar, } @@ -104,8 +100,6 @@ where impl EphemeralSecret where C: Curve + ProjectiveArithmetic, - AffinePoint: Zeroize, - Scalar: Zeroize, SharedSecret: for<'a> From<&'a AffinePoint>, { /// Generate a cryptographically random [`EphemeralSecret`]. @@ -132,8 +126,6 @@ where impl From<&EphemeralSecret> for PublicKey where C: Curve + ProjectiveArithmetic, - AffinePoint: Zeroize, - Scalar: Zeroize, SharedSecret: for<'a> From<&'a AffinePoint>, { fn from(ephemeral_secret: &EphemeralSecret) -> Self { @@ -144,7 +136,6 @@ where impl Zeroize for EphemeralSecret where C: Curve + ProjectiveArithmetic, - Scalar: Zeroize, { fn zeroize(&mut self) { self.scalar.zeroize() @@ -154,7 +145,6 @@ where impl Drop for EphemeralSecret where C: Curve + ProjectiveArithmetic, - Scalar: Zeroize, { fn drop(&mut self) { self.zeroize(); diff --git a/elliptic-curve/src/jwk.rs b/elliptic-curve/src/jwk.rs index 48558513b..a6d7372df 100644 --- a/elliptic-curve/src/jwk.rs +++ b/elliptic-curve/src/jwk.rs @@ -31,7 +31,7 @@ use zeroize::Zeroize; use crate::{ public_key::PublicKey, sec1::{FromEncodedPoint, ToEncodedPoint}, - AffinePoint, ProjectiveArithmetic, Scalar, + AffinePoint, ProjectiveArithmetic, }; /// Key Type (`kty`) for elliptic curve keys. @@ -270,7 +270,6 @@ impl From> for JwkEcKey where C: PrimeCurve + JwkParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, - Scalar: Zeroize, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -286,7 +285,6 @@ impl From<&SecretKey> for JwkEcKey where C: PrimeCurve + JwkParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, - Scalar: Zeroize, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { diff --git a/elliptic-curve/src/scalar/non_zero.rs b/elliptic-curve/src/scalar/non_zero.rs index 209e10dab..8194f7df4 100644 --- a/elliptic-curve/src/scalar/non_zero.rs +++ b/elliptic-curve/src/scalar/non_zero.rs @@ -188,7 +188,6 @@ where impl Zeroize for NonZeroScalar where C: Curve + ProjectiveArithmetic, - Scalar: Zeroize, { fn zeroize(&mut self) { self.scalar.zeroize(); diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index 89589375b..70f7d8558 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -21,10 +21,7 @@ use alloc::boxed::Box; use crate::{point::DecompressPoint, AffinePoint, ProjectiveArithmetic}; #[cfg(all(feature = "arithmetic"))] -use crate::{ - group::{Curve as _, Group}, - Scalar, -}; +use crate::group::{Curve as _, Group}; /// Size of a compressed point for the given elliptic curve when encoded /// using the SEC1 `Elliptic-Curve-Point-to-Octet-String` algorithm @@ -123,7 +120,6 @@ where where C: PrimeCurve + ProjectiveArithmetic, AffinePoint: ToEncodedPoint, - Scalar: Zeroize, { (C::ProjectivePoint::generator() * secret_key.to_secret_scalar().as_ref()) .to_affine() @@ -552,7 +548,6 @@ impl ValidatePublicKey for C where C: PrimeCurve + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, - Scalar: Zeroize, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index d674fd2ad..8bfbbd3ee 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -23,7 +23,7 @@ use zeroize::Zeroize; #[cfg(feature = "arithmetic")] use crate::{ rand_core::{CryptoRng, RngCore}, - NonZeroScalar, ProjectiveArithmetic, PublicKey, Scalar, + NonZeroScalar, ProjectiveArithmetic, PublicKey, }; #[cfg(feature = "jwk")] @@ -87,7 +87,6 @@ where pub fn random(rng: impl CryptoRng + RngCore) -> Self where C: ProjectiveArithmetic, - Scalar: Zeroize, { Self { inner: NonZeroScalar::::random(rng).into(), @@ -139,7 +138,6 @@ where pub fn to_secret_scalar(&self) -> NonZeroScalar where C: Curve + ProjectiveArithmetic, - Scalar: Zeroize, { self.into() } @@ -150,7 +148,6 @@ where pub fn public_key(&self) -> PublicKey where C: Curve + ProjectiveArithmetic, - Scalar: Zeroize, { PublicKey::from_secret_scalar(&self.to_secret_scalar()) } @@ -187,7 +184,7 @@ where where C: PrimeCurve + JwkParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, - Scalar: Zeroize, + UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -202,7 +199,7 @@ where where C: PrimeCurve + JwkParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, - Scalar: Zeroize, + UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs index 40287f96a..1a0ba6d39 100644 --- a/elliptic-curve/src/secret_key/pkcs8.rs +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -17,7 +17,6 @@ use pkcs8::{ #[cfg(all(feature = "arithmetic", feature = "pem"))] use { crate::{ - scalar::Scalar, sec1::{FromEncodedPoint, ToEncodedPoint}, AffinePoint, ProjectiveArithmetic, }, @@ -97,7 +96,6 @@ impl ToPrivateKey for SecretKey where C: PrimeCurve + AlgorithmParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, - Scalar: Zeroize, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { From 50564e5d59dceab04909a71e2aec43af12b8bc90 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 7 Sep 2021 21:18:04 -0600 Subject: [PATCH 0599/1461] elliptic-curve: add `PrimeCurveArithmetic` trait; MSRV 1.52+ (#739) Adds a trait for elliptic curves with a prime order curve group which bounds on the corresponding traits from `group::prime`. --- .github/workflows/crypto.yml | 4 ++-- .github/workflows/elliptic-curve.yml | 4 ++-- .github/workflows/workspace.yml | 2 +- crypto/README.md | 4 ++-- elliptic-curve/README.md | 4 ++-- elliptic-curve/src/arithmetic.rs | 10 +++++++++- elliptic-curve/src/lib.rs | 6 ++++-- 7 files changed, 22 insertions(+), 12 deletions(-) diff --git a/.github/workflows/crypto.yml b/.github/workflows/crypto.yml index 971957c06..57084f8b3 100644 --- a/.github/workflows/crypto.yml +++ b/.github/workflows/crypto.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.51.0 # MSRV + - 1.52.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -43,7 +43,7 @@ jobs: strategy: matrix: rust: - - 1.51.0 # MSRV + - 1.52.0 # MSRV - stable steps: - uses: actions/checkout@v1 diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index 84649ef9f..bfc530822 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.51.0 # MSRV + - 1.52.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -50,7 +50,7 @@ jobs: strategy: matrix: rust: - - 1.51.0 # MSRV + - 1.52.0 # MSRV - stable - nightly steps: diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index 74d9c7419..bf3bed285 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -16,7 +16,7 @@ jobs: - uses: actions/checkout@v1 - uses: actions-rs/toolchain@v1 with: - toolchain: 1.51.0 # Highest MSRV in repo + toolchain: 1.52.0 components: clippy override: true profile: minimal diff --git a/crypto/README.md b/crypto/README.md index c64787660..dcf008e79 100644 --- a/crypto/README.md +++ b/crypto/README.md @@ -14,7 +14,7 @@ access compatible versions of all traits from the Rust Crypto project. ## Minimum Supported Rust Version -Rust **1.51** or higher. +Rust **1.52** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -46,7 +46,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/crypto/badge.svg [docs-link]: https://docs.rs/crypto/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.51+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.52+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260050-Traits [build-image]: https://github.com/RustCrypto/traits/workflows/crypto/badge.svg?branch=master&event=push diff --git a/elliptic-curve/README.md b/elliptic-curve/README.md index e8fe6d340..da1e44b60 100644 --- a/elliptic-curve/README.md +++ b/elliptic-curve/README.md @@ -15,7 +15,7 @@ and public/secret keys composed thereof. ## Minimum Supported Rust Version -Requires Rust **1.51** or higher. +Requires Rust **1.52** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -47,7 +47,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/elliptic-curve/badge.svg [docs-link]: https://docs.rs/elliptic-curve/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.51+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.52+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260040-elliptic-curves [build-image]: https://github.com/RustCrypto/elliptic-curves/workflows/elliptic-curve%20crate/badge.svg?branch=master&event=push diff --git a/elliptic-curve/src/arithmetic.rs b/elliptic-curve/src/arithmetic.rs index 935727dcc..46c01e917 100644 --- a/elliptic-curve/src/arithmetic.rs +++ b/elliptic-curve/src/arithmetic.rs @@ -1,6 +1,6 @@ //! Elliptic curve arithmetic traits. -use crate::{Curve, FieldBytes}; +use crate::{Curve, FieldBytes, PrimeCurve}; use core::fmt::Debug; use subtle::{ConditionallySelectable, ConstantTimeEq}; use zeroize::DefaultIsZeroes; @@ -22,6 +22,14 @@ pub trait AffineArithmetic: Curve + ScalarArithmetic { + Sync; } +/// Prime order elliptic curve with projective arithmetic implementation. +pub trait PrimeCurveArithmetic: + PrimeCurve + ProjectiveArithmetic +{ + /// Prime order elliptic curve group. + type CurveGroup: group::prime::PrimeCurve::AffinePoint>; +} + /// Elliptic curve with projective arithmetic implementation. #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub trait ProjectiveArithmetic: Curve + AffineArithmetic { diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index ba8c7dcc2..314b97ba0 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -4,7 +4,7 @@ //! //! ## Minimum Supported Rust Version //! -//! Rust **1.51** or higher. +//! Rust **1.52** or higher. //! //! Minimum supported Rust version can be changed in the future, but it will be //! done with a minor version bump. @@ -70,7 +70,9 @@ pub use zeroize; #[cfg(feature = "arithmetic")] pub use { crate::{ - arithmetic::{AffineArithmetic, ProjectiveArithmetic, ScalarArithmetic}, + arithmetic::{ + AffineArithmetic, PrimeCurveArithmetic, ProjectiveArithmetic, ScalarArithmetic, + }, public_key::PublicKey, scalar::{non_zero::NonZeroScalar, Scalar}, }, From e433b13bab2f96279fa7bd630bed1f6dc239ef02 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 8 Sep 2021 06:55:05 -0600 Subject: [PATCH 0600/1461] elliptic-curve: additional `ScalarArithmetic::Scalar` bounds (#740) Adds more `From` and `Into` bounds: - From>` - Into - Into> --- elliptic-curve/src/arithmetic.rs | 9 +++++++-- elliptic-curve/src/dev.rs | 12 ++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/elliptic-curve/src/arithmetic.rs b/elliptic-curve/src/arithmetic.rs index 46c01e917..be45448a3 100644 --- a/elliptic-curve/src/arithmetic.rs +++ b/elliptic-curve/src/arithmetic.rs @@ -1,6 +1,6 @@ //! Elliptic curve arithmetic traits. -use crate::{Curve, FieldBytes, PrimeCurve}; +use crate::{Curve, FieldBytes, PrimeCurve, ScalarCore}; use core::fmt::Debug; use subtle::{ConditionallySelectable, ConstantTimeEq}; use zeroize::DefaultIsZeroes; @@ -70,5 +70,10 @@ pub trait ScalarArithmetic: Curve { /// - [`Default`] /// - [`Send`] /// - [`Sync`] - type Scalar: DefaultIsZeroes + ff::Field + ff::PrimeField>; + type Scalar: DefaultIsZeroes + + From> + + Into + + Into> + + ff::Field + + ff::PrimeField>; } diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index cde377f6d..a99112cff 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -197,6 +197,12 @@ impl TryFrom for Scalar { } } +impl From for U256 { + fn from(scalar: Scalar) -> U256 { + scalar.0 + } +} + impl ConditionallySelectable for Scalar { fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { Scalar(U256::conditional_select(&a.0, &b.0, choice)) @@ -309,6 +315,12 @@ impl From for Scalar { } } +impl From for Scalar { + fn from(scalar: ScalarCore) -> Scalar { + Scalar(*scalar.as_uint()) + } +} + impl From for FieldBytes { fn from(scalar: Scalar) -> Self { Self::from(&scalar) From c2d2c05b9aee24d822f25ed15629e7d05b9ab170 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 8 Sep 2021 11:12:01 -0600 Subject: [PATCH 0601/1461] elliptic-curve: rename `from_be_bytes`/`from_le_bytes` and `to_be_bytes` (#741) Changes the names to be consistent with the `core` methods on unsigned integer types as well as the names in the `crypto-bigint` crate. --- Cargo.lock | 5 +++-- Cargo.toml | 3 --- elliptic-curve/src/jwk.rs | 4 ++-- elliptic-curve/src/scalar.rs | 8 ++++---- elliptic-curve/src/scalar/non_zero.rs | 4 ++-- elliptic-curve/src/secret_key.rs | 10 +++++----- elliptic-curve/src/secret_key/pkcs8.rs | 4 ++-- elliptic-curve/tests/pkcs8.rs | 4 ++-- elliptic-curve/tests/secret_key.rs | 2 +- 9 files changed, 21 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9ce4b50be..dfa34fe52 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -146,8 +146,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.2.5" -source = "git+https://github.com/RustCrypto/utils.git#8fa1b4fb22789fb5afd51bc1fad08ebf95789965" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e49339137316df1914fdb54a5eae75a73f45068fd0d2178fe235b11d93238a6e" dependencies = [ "generic-array", "rand_core", diff --git a/Cargo.toml b/Cargo.toml index 5ed356b7b..ebf9e0985 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,3 @@ members = [ "signature/async", "universal-hash", ] - -[patch.crates-io] -crypto-bigint = { git = "https://github.com/RustCrypto/utils.git" } diff --git a/elliptic-curve/src/jwk.rs b/elliptic-curve/src/jwk.rs index a6d7372df..6d10e843f 100644 --- a/elliptic-curve/src/jwk.rs +++ b/elliptic-curve/src/jwk.rs @@ -250,7 +250,7 @@ where if let Some(d_base64) = &jwk.d { let pk = EncodedPoint::::try_from(jwk)?; let mut d_bytes = decode_base64url_fe::(d_base64)?; - let result = SecretKey::from_bytes_be(&d_bytes); + let result = SecretKey::from_be_bytes(&d_bytes); d_bytes.zeroize(); result.and_then(|secret_key| { @@ -290,7 +290,7 @@ where { fn from(sk: &SecretKey) -> JwkEcKey { let mut jwk = sk.public_key().to_jwk(); - let mut d = sk.to_bytes_be(); + let mut d = sk.to_be_bytes(); jwk.d = Some(Base64Url::encode_string(&d)); d.zeroize(); jwk diff --git a/elliptic-curve/src/scalar.rs b/elliptic-curve/src/scalar.rs index bcb394a7b..543c89c02 100644 --- a/elliptic-curve/src/scalar.rs +++ b/elliptic-curve/src/scalar.rs @@ -70,12 +70,12 @@ where } /// Decode [`ScalarCore`] from big endian bytes. - pub fn from_bytes_be(bytes: FieldBytes) -> CtOption { + pub fn from_be_bytes(bytes: FieldBytes) -> CtOption { Self::new(C::UInt::from_be_byte_array(bytes)) } /// Decode [`ScalarCore`] from little endian bytes. - pub fn from_bytes_le(bytes: FieldBytes) -> CtOption { + pub fn from_le_bytes(bytes: FieldBytes) -> CtOption { Self::new(C::UInt::from_le_byte_array(bytes)) } @@ -105,7 +105,7 @@ where } /// Encode [`ScalarCore`] as big endian bytes. - pub fn to_bytes_be(self) -> FieldBytes { + pub fn to_be_bytes(self) -> FieldBytes { self.inner.to_be_byte_array() } @@ -123,7 +123,7 @@ where /// Convert [`ScalarCore`] into a given curve's scalar type // TODO(tarcieri): replace curve-specific scalars with `ScalarCore` fn to_scalar(self) -> Scalar { - Scalar::::from_repr(self.to_bytes_be()).unwrap() + Scalar::::from_repr(self.to_be_bytes()).unwrap() } } diff --git a/elliptic-curve/src/scalar/non_zero.rs b/elliptic-curve/src/scalar/non_zero.rs index 8194f7df4..b755ad4af 100644 --- a/elliptic-curve/src/scalar/non_zero.rs +++ b/elliptic-curve/src/scalar/non_zero.rs @@ -122,7 +122,7 @@ where C: Curve + ProjectiveArithmetic, { fn from(scalar: NonZeroScalar) -> ScalarCore { - ScalarCore::from_bytes_be(scalar.to_repr()).unwrap() + ScalarCore::from_be_bytes(scalar.to_repr()).unwrap() } } @@ -131,7 +131,7 @@ where C: Curve + ProjectiveArithmetic, { fn from(scalar: &NonZeroScalar) -> ScalarCore { - ScalarCore::from_bytes_be(scalar.to_repr()).unwrap() + ScalarCore::from_be_bytes(scalar.to_repr()).unwrap() } } diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 8bfbbd3ee..219abf279 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -99,12 +99,12 @@ where } /// Deserialize raw private scalar as a big endian integer. - pub fn from_bytes_be(bytes: &[u8]) -> Result { + pub fn from_be_bytes(bytes: &[u8]) -> Result { if bytes.len() != C::UInt::BYTE_SIZE { return Err(Error); } - let inner: ScalarCore = Option::from(ScalarCore::from_bytes_be( + let inner: ScalarCore = Option::from(ScalarCore::from_be_bytes( GenericArray::clone_from_slice(bytes), )) .ok_or(Error)?; @@ -117,8 +117,8 @@ where } /// Expose the byte serialization of the value this [`SecretKey`] wraps. - pub fn to_bytes_be(&self) -> FieldBytes { - self.inner.to_bytes_be() + pub fn to_be_bytes(&self) -> FieldBytes { + self.inner.to_be_bytes() } /// Borrow the inner secret [`ScalarCore`] value. @@ -253,7 +253,7 @@ where type Error = Error; fn try_from(slice: &[u8]) -> Result { - Self::from_bytes_be(slice) + Self::from_be_bytes(slice) } } diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs index 1a0ba6d39..d682ec81e 100644 --- a/elliptic-curve/src/secret_key/pkcs8.rs +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -65,7 +65,7 @@ where return Err(der::Tag::Integer.value_error()); } - let secret_key = Self::from_bytes_be(decoder.octet_string()?.as_ref()) + let secret_key = Self::from_be_bytes(decoder.octet_string()?.as_ref()) .map_err(|_| der::Tag::Sequence.value_error())?; let public_key = decoder @@ -101,7 +101,7 @@ where { fn to_pkcs8_der(&self) -> pkcs8::Result { // TODO(tarcieri): wrap `secret_key_bytes` in `Zeroizing` - let mut secret_key_bytes = self.to_bytes_be(); + let mut secret_key_bytes = self.to_be_bytes(); let secret_key_field = OctetString::new(&secret_key_bytes)?; let public_key_bytes = self.public_key().to_encoded_point(false); let public_key_field = ContextSpecific { diff --git a/elliptic-curve/tests/pkcs8.rs b/elliptic-curve/tests/pkcs8.rs index 0e74676d6..c43a323d6 100644 --- a/elliptic-curve/tests/pkcs8.rs +++ b/elliptic-curve/tests/pkcs8.rs @@ -22,7 +22,7 @@ const EXAMPLE_SCALAR: [u8; 32] = /// Example PKCS#8 private key fn example_private_key() -> PrivateKeyDocument { - SecretKey::from_bytes_be(&EXAMPLE_SCALAR) + SecretKey::from_be_bytes(&EXAMPLE_SCALAR) .unwrap() .to_pkcs8_der() .unwrap() @@ -31,7 +31,7 @@ fn example_private_key() -> PrivateKeyDocument { #[test] fn decode_pkcs8_private_key_from_der() { let secret_key = SecretKey::from_pkcs8_der(example_private_key().as_ref()).unwrap(); - assert_eq!(secret_key.to_bytes_be().as_slice(), &EXAMPLE_SCALAR); + assert_eq!(secret_key.to_be_bytes().as_slice(), &EXAMPLE_SCALAR); } #[test] diff --git a/elliptic-curve/tests/secret_key.rs b/elliptic-curve/tests/secret_key.rs index 99476c239..50e5a95cb 100644 --- a/elliptic-curve/tests/secret_key.rs +++ b/elliptic-curve/tests/secret_key.rs @@ -6,5 +6,5 @@ use elliptic_curve::dev::SecretKey; #[test] fn undersize_secret_key() { - assert!(SecretKey::from_bytes_be(&[]).is_err()); + assert!(SecretKey::from_be_bytes(&[]).is_err()); } From 9dcf5ea82d4c4e4f9f1f802a60879e21c2564fd9 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 8 Sep 2021 11:41:09 -0600 Subject: [PATCH 0602/1461] elliptic-curve: makes `SecretKey::to_jwk_string` self-zeroizing (#742) Returns `Zeroizing` instead of just `String`, ensuring that a string containing a JWK secret is zeroized on drop. --- elliptic-curve/src/secret_key.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 219abf279..898f00234 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -41,6 +41,7 @@ use { AffinePoint, PrimeCurve, }, alloc::string::{String, ToString}, + zeroize::Zeroizing, }; #[cfg(all(docsrs, feature = "pkcs8"))] @@ -184,7 +185,6 @@ where where C: PrimeCurve + JwkParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, - UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -195,15 +195,14 @@ where #[cfg(all(feature = "arithmetic", feature = "jwk"))] #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] - pub fn to_jwk_string(&self) -> String + pub fn to_jwk_string(&self) -> Zeroizing where C: PrimeCurve + JwkParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, - UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { - self.to_jwk().to_string() + Zeroizing::new(self.to_jwk().to_string()) } } From 30c65cc9cdcd2c16ce724f0b65c98ed30368b771 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 8 Sep 2021 12:01:10 -0600 Subject: [PATCH 0603/1461] elliptic-curve: rename `SecretKey` scalar accessors (#743) Renames the following: - `SecretKey::as_secret_scalar` => `::as_scalar_core` - `SecretKey::to_secret_scalar` => `::to_nonzero_scalar` --- elliptic-curve/src/arithmetic.rs | 1 + elliptic-curve/src/scalar/non_zero.rs | 2 +- elliptic-curve/src/sec1.rs | 2 +- elliptic-curve/src/secret_key.rs | 16 +++++++++++----- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/elliptic-curve/src/arithmetic.rs b/elliptic-curve/src/arithmetic.rs index be45448a3..b43c3b8a2 100644 --- a/elliptic-curve/src/arithmetic.rs +++ b/elliptic-curve/src/arithmetic.rs @@ -23,6 +23,7 @@ pub trait AffineArithmetic: Curve + ScalarArithmetic { } /// Prime order elliptic curve with projective arithmetic implementation. +#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub trait PrimeCurveArithmetic: PrimeCurve + ProjectiveArithmetic { diff --git a/elliptic-curve/src/scalar/non_zero.rs b/elliptic-curve/src/scalar/non_zero.rs index b755ad4af..cdee0e2cb 100644 --- a/elliptic-curve/src/scalar/non_zero.rs +++ b/elliptic-curve/src/scalar/non_zero.rs @@ -149,7 +149,7 @@ where C: Curve + ProjectiveArithmetic, { fn from(sk: &SecretKey) -> NonZeroScalar { - let scalar = sk.as_secret_scalar().to_scalar(); + let scalar = sk.as_scalar_core().to_scalar(); debug_assert!(!bool::from(scalar.is_zero())); Self { scalar } } diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index 70f7d8558..c18d181e8 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -121,7 +121,7 @@ where C: PrimeCurve + ProjectiveArithmetic, AffinePoint: ToEncodedPoint, { - (C::ProjectivePoint::generator() * secret_key.to_secret_scalar().as_ref()) + (C::ProjectivePoint::generator() * secret_key.to_nonzero_scalar().as_ref()) .to_affine() .to_encoded_point(compress) } diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 898f00234..586c5000f 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -124,19 +124,25 @@ where /// Borrow the inner secret [`ScalarCore`] value. /// - /// # Warning + /// # ⚠️ Warning /// /// This value is key material. /// /// Please treat it with the care it deserves! - pub fn as_secret_scalar(&self) -> &ScalarCore { + pub fn as_scalar_core(&self) -> &ScalarCore { &self.inner } - /// Get the secret scalar value for this key. + /// Get the secret [`NonZeroScalar`] value for this key. + /// + /// # ⚠️ Warning + /// + /// This value is key material. + /// + /// Please treat it with the care it deserves! #[cfg(feature = "arithmetic")] #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] - pub fn to_secret_scalar(&self) -> NonZeroScalar + pub fn to_nonzero_scalar(&self) -> NonZeroScalar where C: Curve + ProjectiveArithmetic, { @@ -150,7 +156,7 @@ where where C: Curve + ProjectiveArithmetic, { - PublicKey::from_secret_scalar(&self.to_secret_scalar()) + PublicKey::from_secret_scalar(&self.to_nonzero_scalar()) } /// Parse a [`JwkEcKey`] JSON Web Key (JWK) into a [`SecretKey`]. From 07ab9ac1b020ba5ad9eb7f2ee643a26bf1f10b1b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Sep 2021 22:29:13 +0000 Subject: [PATCH 0604/1461] build(deps): bump sha2 from 0.9.6 to 0.9.7 (#744) --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dfa34fe52..b10936a8b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -411,9 +411,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.9.6" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9204c41a1597a8c5af23c82d1c921cb01ec0a4c59e07a9c7306062829a3903f3" +checksum = "91e36fa7752016a6c4483706d634fd82c48860dd2df17a0cfaaebc714f23b2dd" dependencies = [ "block-buffer 0.9.0", "cfg-if", From 012b8a457a20d6b8a1f09efd0be9f7c098d7b0f2 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 8 Sep 2021 19:18:52 -0600 Subject: [PATCH 0605/1461] elliptic-curve: factor `ScalarCore` into its own module (#745) --- elliptic-curve/src/lib.rs | 2 +- elliptic-curve/src/scalar.rs | 313 +---------------------------- elliptic-curve/src/scalar/core.rs | 320 ++++++++++++++++++++++++++++++ 3 files changed, 324 insertions(+), 311 deletions(-) create mode 100644 elliptic-curve/src/scalar/core.rs diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 314b97ba0..518a68a55 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -58,7 +58,7 @@ mod jwk; pub use crate::{ error::{Error, Result}, point::{DecompactPoint, DecompressPoint, PointCompaction, PointCompression}, - scalar::ScalarCore, + scalar::core::ScalarCore, secret_key::SecretKey, }; pub use crypto_bigint as bigint; diff --git a/elliptic-curve/src/scalar.rs b/elliptic-curve/src/scalar.rs index 543c89c02..8e04ee497 100644 --- a/elliptic-curve/src/scalar.rs +++ b/elliptic-curve/src/scalar.rs @@ -1,25 +1,12 @@ //! Scalar types. +pub(crate) mod core; + #[cfg(feature = "arithmetic")] pub(crate) mod non_zero; -use crate::{ - bigint::{AddMod, ArrayEncoding, Integer, Limb, NegMod, RandomMod, SubMod}, - rand_core::{CryptoRng, RngCore}, - subtle::{ - Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeGreater, ConstantTimeLess, - CtOption, - }, - Curve, FieldBytes, -}; -use core::{ - cmp::Ordering, - ops::{Add, AddAssign, Neg, Sub, SubAssign}, -}; -use zeroize::DefaultIsZeroes; - #[cfg(feature = "arithmetic")] -use crate::{group::ff::PrimeField, ScalarArithmetic}; +use crate::ScalarArithmetic; /// Scalar field element for a particular elliptic curve. #[cfg(feature = "arithmetic")] @@ -30,297 +17,3 @@ pub type Scalar = ::Scalar; #[cfg(feature = "bits")] #[cfg_attr(docsrs, doc(cfg(feature = "bits")))] pub type ScalarBits = ff::FieldBits< as ff::PrimeFieldBits>::ReprBits>; - -/// Generic core scalar type. -// TODO(tarcieri): make this a fully generic `Scalar` type -#[derive(Copy, Clone, Debug, Default)] -#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] -pub struct ScalarCore { - /// Inner unsigned integer type. - inner: C::UInt, -} - -impl ScalarCore -where - C: Curve, -{ - /// Zero scalar. - pub const ZERO: Self = Self { - inner: C::UInt::ZERO, - }; - - /// Multiplicative identity. - pub const ONE: Self = Self { - inner: C::UInt::ONE, - }; - - /// Scalar modulus. - pub const MODULUS: C::UInt = C::ORDER; - - /// Generate a random [`ScalarCore`]. - pub fn random(rng: impl CryptoRng + RngCore) -> Self { - Self { - inner: C::UInt::random_mod(rng, &Self::MODULUS), - } - } - - /// Create a new scalar from [`Curve::UInt`]. - pub fn new(uint: C::UInt) -> CtOption { - CtOption::new(Self { inner: uint }, uint.ct_lt(&Self::MODULUS)) - } - - /// Decode [`ScalarCore`] from big endian bytes. - pub fn from_be_bytes(bytes: FieldBytes) -> CtOption { - Self::new(C::UInt::from_be_byte_array(bytes)) - } - - /// Decode [`ScalarCore`] from little endian bytes. - pub fn from_le_bytes(bytes: FieldBytes) -> CtOption { - Self::new(C::UInt::from_le_byte_array(bytes)) - } - - /// Borrow the inner `C::UInt`. - pub fn as_uint(&self) -> &C::UInt { - &self.inner - } - - /// Borrow the inner limbs as a slice. - pub fn as_limbs(&self) -> &[Limb] { - self.inner.as_ref() - } - - /// Is this [`ScalarCore`] value equal to zero? - pub fn is_zero(&self) -> Choice { - self.inner.is_zero() - } - - /// Is this [`ScalarCore`] value even? - pub fn is_even(&self) -> Choice { - self.inner.is_even() - } - - /// Is this [`ScalarCore`] value odd? - pub fn is_odd(&self) -> Choice { - self.inner.is_odd() - } - - /// Encode [`ScalarCore`] as big endian bytes. - pub fn to_be_bytes(self) -> FieldBytes { - self.inner.to_be_byte_array() - } - - /// Encode [`ScalarCore`] as little endian bytes. - pub fn to_bytes_le(self) -> FieldBytes { - self.inner.to_le_byte_array() - } -} - -#[cfg(feature = "arithmetic")] -impl ScalarCore -where - C: Curve + ScalarArithmetic, -{ - /// Convert [`ScalarCore`] into a given curve's scalar type - // TODO(tarcieri): replace curve-specific scalars with `ScalarCore` - fn to_scalar(self) -> Scalar { - Scalar::::from_repr(self.to_be_bytes()).unwrap() - } -} - -// TODO(tarcieri): better encapsulate this? -impl AsRef<[Limb]> for ScalarCore -where - C: Curve, -{ - fn as_ref(&self) -> &[Limb] { - self.as_limbs() - } -} - -impl ConditionallySelectable for ScalarCore -where - C: Curve, -{ - fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { - Self { - inner: C::UInt::conditional_select(&a.inner, &b.inner, choice), - } - } -} - -impl ConstantTimeEq for ScalarCore -where - C: Curve, -{ - fn ct_eq(&self, other: &Self) -> Choice { - self.inner.ct_eq(&other.inner) - } -} - -impl ConstantTimeLess for ScalarCore -where - C: Curve, -{ - fn ct_lt(&self, other: &Self) -> Choice { - self.inner.ct_lt(&other.inner) - } -} - -impl ConstantTimeGreater for ScalarCore -where - C: Curve, -{ - fn ct_gt(&self, other: &Self) -> Choice { - self.inner.ct_gt(&other.inner) - } -} - -impl DefaultIsZeroes for ScalarCore {} - -impl Eq for ScalarCore {} - -impl PartialEq for ScalarCore -where - C: Curve, -{ - fn eq(&self, other: &Self) -> bool { - self.ct_eq(other).into() - } -} - -impl PartialOrd for ScalarCore -where - C: Curve, -{ - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -impl Ord for ScalarCore -where - C: Curve, -{ - fn cmp(&self, other: &Self) -> Ordering { - self.inner.cmp(&other.inner) - } -} - -impl From for ScalarCore -where - C: Curve, -{ - fn from(n: u64) -> Self { - Self { - inner: C::UInt::from(n), - } - } -} - -impl Add> for ScalarCore -where - C: Curve, -{ - type Output = Self; - - fn add(self, other: Self) -> Self { - self.add(&other) - } -} - -impl Add<&ScalarCore> for ScalarCore -where - C: Curve, -{ - type Output = Self; - - fn add(self, other: &Self) -> Self { - Self { - inner: self.inner.add_mod(&other.inner, &Self::MODULUS), - } - } -} - -impl AddAssign> for ScalarCore -where - C: Curve, -{ - fn add_assign(&mut self, other: Self) { - *self = *self + other; - } -} - -impl AddAssign<&ScalarCore> for ScalarCore -where - C: Curve, -{ - fn add_assign(&mut self, other: &Self) { - *self = *self + other; - } -} - -impl Sub> for ScalarCore -where - C: Curve, -{ - type Output = Self; - - fn sub(self, other: Self) -> Self { - self.sub(&other) - } -} - -impl Sub<&ScalarCore> for ScalarCore -where - C: Curve, -{ - type Output = Self; - - fn sub(self, other: &Self) -> Self { - Self { - inner: self.inner.sub_mod(&other.inner, &Self::MODULUS), - } - } -} - -impl SubAssign> for ScalarCore -where - C: Curve, -{ - fn sub_assign(&mut self, other: Self) { - *self = *self - other; - } -} - -impl SubAssign<&ScalarCore> for ScalarCore -where - C: Curve, -{ - fn sub_assign(&mut self, other: &Self) { - *self = *self - other; - } -} - -impl Neg for ScalarCore -where - C: Curve, -{ - type Output = Self; - - fn neg(self) -> Self { - Self { - inner: self.inner.neg_mod(&Self::MODULUS), - } - } -} - -impl Neg for &ScalarCore -where - C: Curve, -{ - type Output = ScalarCore; - - fn neg(self) -> ScalarCore { - -*self - } -} diff --git a/elliptic-curve/src/scalar/core.rs b/elliptic-curve/src/scalar/core.rs new file mode 100644 index 000000000..cee776265 --- /dev/null +++ b/elliptic-curve/src/scalar/core.rs @@ -0,0 +1,320 @@ +//! Generic scalar type with core functionality. + +use crate::{ + bigint::{AddMod, ArrayEncoding, Integer, Limb, NegMod, RandomMod, SubMod}, + rand_core::{CryptoRng, RngCore}, + subtle::{ + Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeGreater, ConstantTimeLess, + CtOption, + }, + Curve, FieldBytes, +}; +use core::{ + cmp::Ordering, + ops::{Add, AddAssign, Neg, Sub, SubAssign}, +}; +use zeroize::DefaultIsZeroes; + +#[cfg(feature = "arithmetic")] +use { + super::{Scalar, ScalarArithmetic}, + group::ff::PrimeField, +}; + +/// Generic scalar type with core functionality. +/// +/// This type provides a baseline level of scalar arithmetic functionality +/// which is always available for all curves, regardless of if they implement +/// any arithmetic traits. +// TODO(tarcieri): make this a fully generic `Scalar` type and use it for `ScalarArithmetic` +#[derive(Copy, Clone, Debug, Default)] +#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] +pub struct ScalarCore { + /// Inner unsigned integer type. + inner: C::UInt, +} + +impl ScalarCore +where + C: Curve, +{ + /// Zero scalar. + pub const ZERO: Self = Self { + inner: C::UInt::ZERO, + }; + + /// Multiplicative identity. + pub const ONE: Self = Self { + inner: C::UInt::ONE, + }; + + /// Scalar modulus. + pub const MODULUS: C::UInt = C::ORDER; + + /// Generate a random [`ScalarCore`]. + pub fn random(rng: impl CryptoRng + RngCore) -> Self { + Self { + inner: C::UInt::random_mod(rng, &Self::MODULUS), + } + } + + /// Create a new scalar from [`Curve::UInt`]. + pub fn new(uint: C::UInt) -> CtOption { + CtOption::new(Self { inner: uint }, uint.ct_lt(&Self::MODULUS)) + } + + /// Decode [`ScalarCore`] from big endian bytes. + pub fn from_be_bytes(bytes: FieldBytes) -> CtOption { + Self::new(C::UInt::from_be_byte_array(bytes)) + } + + /// Decode [`ScalarCore`] from little endian bytes. + pub fn from_le_bytes(bytes: FieldBytes) -> CtOption { + Self::new(C::UInt::from_le_byte_array(bytes)) + } + + /// Borrow the inner `C::UInt`. + pub fn as_uint(&self) -> &C::UInt { + &self.inner + } + + /// Borrow the inner limbs as a slice. + pub fn as_limbs(&self) -> &[Limb] { + self.inner.as_ref() + } + + /// Is this [`ScalarCore`] value equal to zero? + pub fn is_zero(&self) -> Choice { + self.inner.is_zero() + } + + /// Is this [`ScalarCore`] value even? + pub fn is_even(&self) -> Choice { + self.inner.is_even() + } + + /// Is this [`ScalarCore`] value odd? + pub fn is_odd(&self) -> Choice { + self.inner.is_odd() + } + + /// Encode [`ScalarCore`] as big endian bytes. + pub fn to_be_bytes(self) -> FieldBytes { + self.inner.to_be_byte_array() + } + + /// Encode [`ScalarCore`] as little endian bytes. + pub fn to_bytes_le(self) -> FieldBytes { + self.inner.to_le_byte_array() + } +} + +#[cfg(feature = "arithmetic")] +impl ScalarCore +where + C: Curve + ScalarArithmetic, +{ + /// Convert [`ScalarCore`] into a given curve's scalar type + // TODO(tarcieri): replace curve-specific scalars with `ScalarCore` + pub(super) fn to_scalar(self) -> Scalar { + Scalar::::from_repr(self.to_be_bytes()).unwrap() + } +} + +// TODO(tarcieri): better encapsulate this? +impl AsRef<[Limb]> for ScalarCore +where + C: Curve, +{ + fn as_ref(&self) -> &[Limb] { + self.as_limbs() + } +} + +impl ConditionallySelectable for ScalarCore +where + C: Curve, +{ + fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { + Self { + inner: C::UInt::conditional_select(&a.inner, &b.inner, choice), + } + } +} + +impl ConstantTimeEq for ScalarCore +where + C: Curve, +{ + fn ct_eq(&self, other: &Self) -> Choice { + self.inner.ct_eq(&other.inner) + } +} + +impl ConstantTimeLess for ScalarCore +where + C: Curve, +{ + fn ct_lt(&self, other: &Self) -> Choice { + self.inner.ct_lt(&other.inner) + } +} + +impl ConstantTimeGreater for ScalarCore +where + C: Curve, +{ + fn ct_gt(&self, other: &Self) -> Choice { + self.inner.ct_gt(&other.inner) + } +} + +impl DefaultIsZeroes for ScalarCore {} + +impl Eq for ScalarCore {} + +impl PartialEq for ScalarCore +where + C: Curve, +{ + fn eq(&self, other: &Self) -> bool { + self.ct_eq(other).into() + } +} + +impl PartialOrd for ScalarCore +where + C: Curve, +{ + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for ScalarCore +where + C: Curve, +{ + fn cmp(&self, other: &Self) -> Ordering { + self.inner.cmp(&other.inner) + } +} + +impl From for ScalarCore +where + C: Curve, +{ + fn from(n: u64) -> Self { + Self { + inner: C::UInt::from(n), + } + } +} + +impl Add> for ScalarCore +where + C: Curve, +{ + type Output = Self; + + fn add(self, other: Self) -> Self { + self.add(&other) + } +} + +impl Add<&ScalarCore> for ScalarCore +where + C: Curve, +{ + type Output = Self; + + fn add(self, other: &Self) -> Self { + Self { + inner: self.inner.add_mod(&other.inner, &Self::MODULUS), + } + } +} + +impl AddAssign> for ScalarCore +where + C: Curve, +{ + fn add_assign(&mut self, other: Self) { + *self = *self + other; + } +} + +impl AddAssign<&ScalarCore> for ScalarCore +where + C: Curve, +{ + fn add_assign(&mut self, other: &Self) { + *self = *self + other; + } +} + +impl Sub> for ScalarCore +where + C: Curve, +{ + type Output = Self; + + fn sub(self, other: Self) -> Self { + self.sub(&other) + } +} + +impl Sub<&ScalarCore> for ScalarCore +where + C: Curve, +{ + type Output = Self; + + fn sub(self, other: &Self) -> Self { + Self { + inner: self.inner.sub_mod(&other.inner, &Self::MODULUS), + } + } +} + +impl SubAssign> for ScalarCore +where + C: Curve, +{ + fn sub_assign(&mut self, other: Self) { + *self = *self - other; + } +} + +impl SubAssign<&ScalarCore> for ScalarCore +where + C: Curve, +{ + fn sub_assign(&mut self, other: &Self) { + *self = *self - other; + } +} + +impl Neg for ScalarCore +where + C: Curve, +{ + type Output = Self; + + fn neg(self) -> Self { + Self { + inner: self.inner.neg_mod(&Self::MODULUS), + } + } +} + +impl Neg for &ScalarCore +where + C: Curve, +{ + type Output = ScalarCore; + + fn neg(self) -> ScalarCore { + -*self + } +} From fd2a01411ae308ae6654a59594d63d84091f8381 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 8 Sep 2021 20:18:57 -0600 Subject: [PATCH 0606/1461] elliptic-curve: add `ScalarCore::from_*_slice` (#746) Adds support for decoding `ScalarCore` from a byte slice --- elliptic-curve/src/scalar/core.rs | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/elliptic-curve/src/scalar/core.rs b/elliptic-curve/src/scalar/core.rs index cee776265..db0593a90 100644 --- a/elliptic-curve/src/scalar/core.rs +++ b/elliptic-curve/src/scalar/core.rs @@ -1,18 +1,19 @@ //! Generic scalar type with core functionality. use crate::{ - bigint::{AddMod, ArrayEncoding, Integer, Limb, NegMod, RandomMod, SubMod}, + bigint::{AddMod, ArrayEncoding, Encoding, Integer, Limb, NegMod, RandomMod, SubMod}, rand_core::{CryptoRng, RngCore}, subtle::{ Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeGreater, ConstantTimeLess, CtOption, }, - Curve, FieldBytes, + Curve, Error, FieldBytes, Result, }; use core::{ cmp::Ordering, ops::{Add, AddAssign, Neg, Sub, SubAssign}, }; +use generic_array::GenericArray; use zeroize::DefaultIsZeroes; #[cfg(feature = "arithmetic")] @@ -68,11 +69,29 @@ where Self::new(C::UInt::from_be_byte_array(bytes)) } + /// Decode [`ScalarCore`] from a big endian byte slice. + pub fn from_be_slice(slice: &[u8]) -> Result { + if slice.len() == C::UInt::BYTE_SIZE { + Option::from(Self::from_be_bytes(GenericArray::clone_from_slice(slice))).ok_or(Error) + } else { + Err(Error) + } + } + /// Decode [`ScalarCore`] from little endian bytes. pub fn from_le_bytes(bytes: FieldBytes) -> CtOption { Self::new(C::UInt::from_le_byte_array(bytes)) } + /// Decode [`ScalarCore`] from a little endian byte slice. + pub fn from_le_slice(slice: &[u8]) -> Result { + if slice.len() == C::UInt::BYTE_SIZE { + Option::from(Self::from_le_bytes(GenericArray::clone_from_slice(slice))).ok_or(Error) + } else { + Err(Error) + } + } + /// Borrow the inner `C::UInt`. pub fn as_uint(&self) -> &C::UInt { &self.inner From cc684ed300cd76893909b525972738af9a6ed2a5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Sep 2021 07:20:33 +0000 Subject: [PATCH 0607/1461] build(deps): bump sha2 from 0.9.7 to 0.9.8 (#747) --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b10936a8b..53391bbb0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -411,9 +411,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.9.7" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e36fa7752016a6c4483706d634fd82c48860dd2df17a0cfaaebc714f23b2dd" +checksum = "b69f9a4c9740d74c5baa3fd2e547f9525fa8088a8a958e0ca2409a514e33f5fa" dependencies = [ "block-buffer 0.9.0", "cfg-if", From d24dfb22d1c2bf065b530739ab2a15c661354913 Mon Sep 17 00:00:00 2001 From: ZSchoen Date: Fri, 10 Sep 2021 20:54:27 +0200 Subject: [PATCH 0608/1461] changed fmt::Display for PasswordHash (#748) --- password-hash/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index 59a867392..839035b2c 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -276,10 +276,10 @@ impl<'a> fmt::Display for PasswordHash<'a> { if let Some(salt) = &self.salt { write!(f, "{}{}", PASSWORD_HASH_SEPARATOR, salt)?; - } - if let Some(hash) = &self.hash { - write!(f, "{}{}", PASSWORD_HASH_SEPARATOR, hash)?; + if let Some(hash) = &self.hash { + write!(f, "{}{}", PASSWORD_HASH_SEPARATOR, hash)?; + } } Ok(()) From 4ebec89c615d4d1651a81017d4487358f9a9027e Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 12 Sep 2021 11:11:27 -0600 Subject: [PATCH 0609/1461] elliptic-curve: bump `crypto-bigint` to v0.2.7 (#749) This includes a bugfix for modular addition which is needed for `ScalarCore::add` to be correct. --- Cargo.lock | 4 ++-- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 53391bbb0..c164c7f10 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -146,9 +146,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e49339137316df1914fdb54a5eae75a73f45068fd0d2178fe235b11d93238a6e" +checksum = "9f3e92bef8f9520d23f056674efde37622a5185c4103ca106de82f8f966ece4d" dependencies = [ "generic-array", "rand_core", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 8ed0e6ceb..08735193a 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -15,7 +15,7 @@ categories = ["cryptography", "no-std"] keywords = ["crypto", "ecc", "elliptic", "weierstrass"] [dependencies] -crypto-bigint = { version = "0.2.5", features = ["generic-array", "zeroize"] } +crypto-bigint = { version = "0.2.7", features = ["generic-array", "zeroize"] } generic-array = { version = "0.14", default-features = false } rand_core = { version = "0.6", default-features = false } subtle = { version = ">=2, <2.5", default-features = false } From b645434a82400400247f4d8e4574ed9ae0dbb79e Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 12 Sep 2021 11:26:27 -0600 Subject: [PATCH 0610/1461] elliptic-curve: `dev` module improvements (#750) Uses `ScalarCore` as the internal representation of the `dev::Scalar` newtype, and implements more functionality in terms of it. --- elliptic-curve/src/dev.rs | 163 +++++++++++++++++++------------------- 1 file changed, 82 insertions(+), 81 deletions(-) diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index a99112cff..c390b4836 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -2,11 +2,11 @@ //! against concrete implementations of the traits in this crate. use crate::{ - bigint::{ArrayEncoding as _, U256}, + bigint::U256, error::{Error, Result}, rand_core::RngCore, sec1::{FromEncodedPoint, ToEncodedPoint}, - subtle::{Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeLess, CtOption}, + subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}, zeroize::DefaultIsZeroes, AffineArithmetic, AlgorithmParameters, Curve, PrimeCurve, ProjectiveArithmetic, ScalarArithmetic, @@ -17,10 +17,11 @@ use core::{ ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign}, }; use ff::{Field, PrimeField}; +use generic_array::arr; use hex_literal::hex; #[cfg(feature = "bits")] -use crate::{group::ff::PrimeFieldBits, ScalarBits}; +use crate::group::ff::PrimeFieldBits; #[cfg(feature = "jwk")] use crate::JwkParameters; @@ -29,6 +30,29 @@ use crate::JwkParameters; pub const PSEUDO_COORDINATE_FIXED_BASE_MUL: [u8; 32] = hex!("deadbeef00000000000000000000000000000000000000000000000000000001"); +/// SEC1 encoded point. +pub type EncodedPoint = crate::sec1::EncodedPoint; + +/// Field element bytes. +pub type FieldBytes = crate::FieldBytes; + +/// Non-zero scalar value. +pub type NonZeroScalar = crate::NonZeroScalar; + +/// Public key. +pub type PublicKey = crate::PublicKey; + +/// Secret key. +pub type SecretKey = crate::SecretKey; + +/// Scalar core. +// TODO(tarcieri): make this the scalar type +pub type ScalarCore = crate::ScalarCore; + +/// Scalar bits. +#[cfg(feature = "bits")] +pub type ScalarBits = crate::ScalarBits; + /// Mock elliptic curve type useful for writing tests which require a concrete /// curve type. /// @@ -69,40 +93,28 @@ impl JwkParameters for MockCurve { const CRV: &'static str = "P-256"; } -/// SEC1 encoded point. -pub type EncodedPoint = crate::sec1::EncodedPoint; - -/// Field element bytes. -pub type FieldBytes = crate::FieldBytes; - -/// Non-zero scalar value. -pub type NonZeroScalar = crate::NonZeroScalar; - -/// Public key. -pub type PublicKey = crate::PublicKey; - -/// Secret key. -pub type SecretKey = crate::SecretKey; - -/// Scalar core. -// TODO(tarcieri): make this the scalar type -pub type ScalarCore = crate::ScalarCore; - /// Example scalar type #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] -pub struct Scalar(U256); +pub struct Scalar(ScalarCore); impl Field for Scalar { - fn random(_rng: impl RngCore) -> Self { - unimplemented!(); + fn random(mut rng: impl RngCore) -> Self { + let mut bytes = FieldBytes::default(); + + loop { + rng.fill_bytes(&mut bytes); + if let Some(scalar) = Self::from_repr(bytes).into() { + return scalar; + } + } } fn zero() -> Self { - Self(U256::ZERO) + Self(ScalarCore::ZERO) } fn one() -> Self { - Self(U256::ONE) + Self(ScalarCore::ONE) } fn is_zero(&self) -> Choice { @@ -116,7 +128,7 @@ impl Field for Scalar { #[must_use] fn double(&self) -> Self { - unimplemented!(); + self.add(self) } fn invert(&self) -> CtOption { @@ -136,24 +148,28 @@ impl PrimeField for Scalar { const S: u32 = 4; fn from_repr(bytes: FieldBytes) -> CtOption { - let inner = U256::from_be_byte_array(bytes); - CtOption::new(Scalar(inner), inner.ct_lt(&MockCurve::ORDER)) + ScalarCore::from_be_bytes(bytes).map(Self) } fn to_repr(&self) -> FieldBytes { - self.0.to_be_byte_array() + self.0.to_be_bytes() } fn is_odd(&self) -> Choice { - unimplemented!(); + self.0.is_odd() } fn multiplicative_generator() -> Self { - unimplemented!(); + 7u64.into() } fn root_of_unity() -> Self { - unimplemented!(); + Self::from_repr(arr![u8; + 0xff, 0xc9, 0x7f, 0x06, 0x2a, 0x77, 0x09, 0x92, 0xba, 0x80, 0x7a, 0xce, 0x84, 0x2a, + 0x3d, 0xfc, 0x15, 0x46, 0xca, 0xd0, 0x04, 0x37, 0x8d, 0xaf, 0x05, 0x92, 0xd7, 0xfb, + 0xb4, 0x1e, 0x66, 0x02, + ]) + .unwrap() } } @@ -161,27 +177,16 @@ impl PrimeField for Scalar { impl PrimeFieldBits for Scalar { #[cfg(target_pointer_width = "32")] type ReprBits = [u32; 8]; + #[cfg(target_pointer_width = "64")] type ReprBits = [u64; 4]; - fn to_le_bits(&self) -> ScalarBits { - let mut limbs = Self::ReprBits::default(); - - for (i, limb) in self.0.limbs().iter().cloned().enumerate() { - limbs[i] = limb.into(); - } - - limbs.into() + fn to_le_bits(&self) -> ScalarBits { + self.0.as_uint().to_uint_array().into() } - fn char_le_bits() -> ScalarBits { - let mut limbs = Self::ReprBits::default(); - - for (i, limb) in MockCurve::ORDER.limbs().iter().cloned().enumerate() { - limbs[i] = limb.into(); - } - - limbs.into() + fn char_le_bits() -> ScalarBits { + MockCurve::ORDER.to_uint_array().into() } } @@ -189,23 +194,19 @@ impl TryFrom for Scalar { type Error = Error; fn try_from(w: U256) -> Result { - if w < MockCurve::ORDER { - Ok(Scalar(w)) - } else { - Err(Error) - } + Option::from(ScalarCore::new(w)).map(Self).ok_or(Error) } } impl From for U256 { fn from(scalar: Scalar) -> U256 { - scalar.0 + *scalar.0.as_uint() } } impl ConditionallySelectable for Scalar { fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { - Scalar(U256::conditional_select(&a.0, &b.0, choice)) + Self(ScalarCore::conditional_select(&a.0, &b.0, choice)) } } @@ -220,56 +221,56 @@ impl DefaultIsZeroes for Scalar {} impl Add for Scalar { type Output = Scalar; - fn add(self, _other: Scalar) -> Scalar { - unimplemented!(); + fn add(self, other: Scalar) -> Scalar { + self.add(&other) } } impl Add<&Scalar> for Scalar { type Output = Scalar; - fn add(self, _other: &Scalar) -> Scalar { - unimplemented!(); + fn add(self, other: &Scalar) -> Scalar { + Self(self.0.add(&other.0)) } } impl AddAssign for Scalar { - fn add_assign(&mut self, _rhs: Scalar) { - unimplemented!(); + fn add_assign(&mut self, other: Scalar) { + *self = *self + other; } } impl AddAssign<&Scalar> for Scalar { - fn add_assign(&mut self, _rhs: &Scalar) { - unimplemented!(); + fn add_assign(&mut self, other: &Scalar) { + *self = *self + other; } } impl Sub for Scalar { type Output = Scalar; - fn sub(self, _other: Scalar) -> Scalar { - unimplemented!(); + fn sub(self, other: Scalar) -> Scalar { + self.sub(&other) } } impl Sub<&Scalar> for Scalar { type Output = Scalar; - fn sub(self, _other: &Scalar) -> Scalar { - unimplemented!(); + fn sub(self, other: &Scalar) -> Scalar { + Self(self.0.sub(&other.0)) } } impl SubAssign for Scalar { - fn sub_assign(&mut self, _rhs: Scalar) { - unimplemented!(); + fn sub_assign(&mut self, other: Scalar) { + *self = *self - other; } } impl SubAssign<&Scalar> for Scalar { - fn sub_assign(&mut self, _rhs: &Scalar) { - unimplemented!(); + fn sub_assign(&mut self, other: &Scalar) { + *self = *self - other; } } @@ -305,19 +306,19 @@ impl Neg for Scalar { type Output = Scalar; fn neg(self) -> Scalar { - unimplemented!(); + Self(self.0.neg()) } } impl From for Scalar { - fn from(_: u64) -> Scalar { - unimplemented!(); + fn from(n: u64) -> Scalar { + Self(n.into()) } } impl From for Scalar { fn from(scalar: ScalarCore) -> Scalar { - Scalar(*scalar.as_uint()) + Self(scalar) } } @@ -336,16 +337,16 @@ impl From<&Scalar> for FieldBytes { /// Example affine point type #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum AffinePoint { - /// Result of fixed-based scalar multiplication + /// Result of fixed-based scalar multiplication. FixedBaseOutput(Scalar), - /// Is this point the identity point? + /// Identity. Identity, - /// Is this point the generator point? + /// Base point. Generator, - /// Is this point a different point corresponding to a given [`EncodedPoint`] + /// Point corresponding to a given [`EncodedPoint`]. Other(EncodedPoint), } From 3f7ec6ce4423d5550d3c9559ea79a29b8dac8d93 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 14 Sep 2021 16:47:12 -0600 Subject: [PATCH 0611/1461] elliptic-curve: RFC5915 docs (#755) --- elliptic-curve/src/secret_key/pkcs8.rs | 33 +++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs index d682ec81e..d530596f0 100644 --- a/elliptic-curve/src/secret_key/pkcs8.rs +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -1,4 +1,35 @@ -//! PKCS#8 encoding/decoding support +//! PKCS#8 encoding/decoding support. +//! +//! This module implements the `ECPrivateKey` schema as described in +//! [RFC5915 Section 3](https://datatracker.ietf.org/doc/html/rfc5915#section-3): +//! +//! ```text +//! ECPrivateKey ::= SEQUENCE { +//! version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), +//! privateKey OCTET STRING, +//! parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, +//! publicKey [1] BIT STRING OPTIONAL +//! } +//! ``` +//! +//! It is presently only supported for use with PKCS#8, i.e. keys which begin +//! with the following: +//! +//! ```text +//! -----BEGIN PRIVATE KEY----- +//! ``` +//! +//! The following format is *NOT* presently supported: +//! +//! ```text +//! -----BEGIN EC PRIVATE KEY----- +//! ``` +//! +//! Supporting the above format (the "SECG" format as described in RFC5919) +//! would be fairly simple, as it's a PEM encoding of the aforementioned +//! ASN.1 data structure. Please open an issue if you are interested. +//! +//! That said, we recommend using PKCS#8 in new applications. use super::SecretKey; use crate::{ From edb55c969e1d7f816d870ed39cd17c331345454f Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 14 Sep 2021 18:23:11 -0600 Subject: [PATCH 0612/1461] password-hash: pin `base64ct` to <1.1 (#757) Prevents an MSRV bump --- password-hash/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index 563ff5749..8694ccc19 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -16,7 +16,7 @@ categories = ["cryptography", "no-std"] keywords = ["crypt", "mcf", "password", "pbkdf", "phc"] [dependencies] -base64ct = "1" +base64ct = ">=1, <1.1.0" subtle = { version = ">=2, <2.5", default-features = false } # optional features From d3858047730dbf621102c9b494fb75edffbe07b7 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 14 Sep 2021 18:36:34 -0600 Subject: [PATCH 0613/1461] Cargo.lock: bump dependencies (#756) --- Cargo.lock | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c164c7f10..be73830ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -117,9 +117,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c32f031ea41b4291d695026c023b95d59db2d8a2c7640800ed56bc8f510f22" +checksum = "fdab415d6744056100f40250a66bc430c1a46f7a02e20bc11c94c79a0f0464df" [[package]] name = "cpufeatures" @@ -146,9 +146,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f3e92bef8f9520d23f056674efde37622a5185c4103ca106de82f8f966ece4d" +checksum = "43b0ca41e2a75a407a44812f110ecd40e1efacb8993f612746491e12d5b929fe" dependencies = [ "generic-array", "rand_core", @@ -188,9 +188,9 @@ dependencies = [ [[package]] name = "der" -version = "0.4.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f215f706081a44cb702c71c39a52c05da637822e9c1645a50b7202689e982d" +checksum = "d7044a442ff01698f9ba0b8c3282057eaa04bdc85a1d8bd72627761f19ff080a" dependencies = [ "const-oid", ] @@ -307,9 +307,9 @@ checksum = "21e4590e13640f19f249fe3e4eca5113bc4289f2497710378190e7f4bd96f45b" [[package]] name = "itoa" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" [[package]] name = "libc" @@ -334,18 +334,18 @@ dependencies = [ [[package]] name = "pem-rfc7468" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fe90c78c9a17442665a41a1a45dcd24bbab0e1794748edc19b27fffb146c13" +checksum = "2ca8e0557253e074b4b42a32959384bca4fa69e40680032dba133baeed6cafd5" dependencies = [ "base64ct", ] [[package]] name = "pkcs8" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbee84ed13e44dd82689fa18348a49934fa79cc774a344c42fc9b301c71b140a" +checksum = "ee3ef9b64d26bad0536099c816c6734379e45bbd5f14798def6809e5cc350447" dependencies = [ "der", "pem-rfc7468", @@ -355,9 +355,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.28" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" +checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d" dependencies = [ "unicode-xid", ] @@ -400,9 +400,9 @@ checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" [[package]] name = "serde_json" -version = "1.0.67" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7f9e390c27c3c0ce8bc5d725f6e4d30a29d26659494aa4b17535f7522c5c950" +checksum = "0f690853975602e1bfe1ccbf50504d67174e3bcf340f23b5ea9992e0587a52d8" dependencies = [ "itoa", "ryu", @@ -445,9 +445,9 @@ dependencies = [ [[package]] name = "spki" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "987637c5ae6b3121aba9d513f869bd2bff11c4cc086c22473befd6649c0bd521" +checksum = "5c01a0c15da1b0b0e1494112e7af814a678fec9bd157881b49beac661e9b6f32" dependencies = [ "der", ] @@ -466,9 +466,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.74" +version = "1.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1873d832550d4588c3dbc20f01361ab00bfe741048f71e3fecf145a7cc18b29c" +checksum = "c6f107db402c2c2055242dbf4d2af0e69197202e9faacbef9571bbe47f5a1b84" dependencies = [ "proc-macro2", "quote", @@ -495,9 +495,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "typenum" -version = "1.13.0" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" +checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" [[package]] name = "unicode-xid" From 03902da8ee39eeb042f5f34dfc8940735e67a383 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 14 Sep 2021 20:14:19 -0600 Subject: [PATCH 0614/1461] password-hash: add `PasswordHashString` (#758) Adds an owned form of the `PasswordHash` type containing a serialized password hash string, gated on the `alloc` feature. --- password-hash/src/lib.rs | 136 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 134 insertions(+), 2 deletions(-) diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index 839035b2c..2879940b0 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -44,9 +44,8 @@ #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] -#[cfg(all(feature = "alloc", test))] +#[cfg(feature = "alloc")] extern crate alloc; - #[cfg(feature = "std")] extern crate std; @@ -80,6 +79,12 @@ use core::{ fmt::{self, Debug}, }; +#[cfg(feature = "alloc")] +use alloc::{ + str::FromStr, + string::{String, ToString}, +}; + /// Separator character used in password hashes (e.g. `$6$...`). const PASSWORD_HASH_SEPARATOR: char = '$'; @@ -250,6 +255,13 @@ impl<'a> PasswordHash<'a> { pub fn encoding(&self) -> Encoding { self.hash.map(|h| h.encoding()).unwrap_or_default() } + + /// Serialize this [`PasswordHash`] as a [`PasswordHashString`]. + #[cfg(feature = "alloc")] + #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] + pub fn serialize(&self) -> PasswordHashString { + self.into() + } } // Note: this uses `TryFrom` instead of `FromStr` to support a lifetime on @@ -285,3 +297,123 @@ impl<'a> fmt::Display for PasswordHash<'a> { Ok(()) } } + +/// Serialized [`PasswordHash`]. +/// +/// This type contains a serialized password hash string which is ensured to +/// parse successfully. +// TODO(tarcieri): cached parsed representations? or at least structural data +#[cfg(feature = "alloc")] +#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct PasswordHashString { + /// String value + string: String, + + /// String encoding + encoding: Encoding, +} + +#[cfg(feature = "alloc")] +#[allow(clippy::len_without_is_empty)] +impl PasswordHashString { + /// Parse a password hash from a string in the PHC string format. + pub fn new(s: &str) -> Result { + Self::parse(s, Encoding::B64) + } + + /// Parse a password hash from the given [`Encoding`]. + pub fn parse(s: &str, encoding: Encoding) -> Result { + Ok(PasswordHash::parse(s, encoding)?.into()) + } + + /// Parse this owned string as a [`PasswordHash`]. + pub fn password_hash(&self) -> PasswordHash<'_> { + PasswordHash::parse(&self.string, self.encoding).expect("malformed password hash") + } + + /// Get the [`Encoding`] that this [`PasswordHashString`] is serialized with. + pub fn encoding(&self) -> Encoding { + self.encoding + } + + /// Borrow this value as a `str`. + pub fn as_str(&self) -> &str { + self.string.as_str() + } + + /// Borrow this value as bytes. + pub fn as_bytes(&self) -> &[u8] { + self.as_str().as_bytes() + } + + /// Get the length of this value in ASCII characters. + pub fn len(&self) -> usize { + self.as_str().len() + } + + /// Password hashing algorithm identifier. + pub fn algorithm(&self) -> Ident<'_> { + self.password_hash().algorithm + } + + /// Optional version field. + pub fn version(&self) -> Option { + self.password_hash().version + } + + /// Algorithm-specific parameters. + pub fn params(&self) -> ParamsString { + self.password_hash().params + } + + /// [`Salt`] string for personalizing a password hash output. + pub fn salt(&self) -> Option> { + self.password_hash().salt + } + + /// Password hashing function [`Output`], a.k.a. hash/digest. + pub fn hash(&self) -> Option { + self.password_hash().hash + } +} + +#[cfg(feature = "alloc")] +impl AsRef for PasswordHashString { + fn as_ref(&self) -> &str { + self.as_str() + } +} + +#[cfg(feature = "alloc")] +impl From> for PasswordHashString { + fn from(hash: PasswordHash<'_>) -> PasswordHashString { + PasswordHashString::from(&hash) + } +} + +#[cfg(feature = "alloc")] +impl From<&PasswordHash<'_>> for PasswordHashString { + fn from(hash: &PasswordHash<'_>) -> PasswordHashString { + PasswordHashString { + string: hash.to_string(), + encoding: hash.encoding(), + } + } +} + +#[cfg(feature = "alloc")] +impl FromStr for PasswordHashString { + type Err = Error; + + fn from_str(s: &str) -> Result { + Self::new(s) + } +} + +#[cfg(feature = "alloc")] +impl<'a> fmt::Display for PasswordHashString { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.as_str()) + } +} From 35c1b8fb51acb8790aeb961147c7b44af4259a15 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 14 Sep 2021 20:32:46 -0600 Subject: [PATCH 0615/1461] password-hash v0.3.1 (#759) --- Cargo.lock | 2 +- password-hash/CHANGELOG.md | 12 ++++++++++++ password-hash/Cargo.toml | 2 +- password-hash/src/lib.rs | 6 +++--- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index be73830ee..d5b949b9a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -325,7 +325,7 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "password-hash" -version = "0.3.0" +version = "0.3.1" dependencies = [ "base64ct", "rand_core", diff --git a/password-hash/CHANGELOG.md b/password-hash/CHANGELOG.md index bf752df06..18cea172e 100644 --- a/password-hash/CHANGELOG.md +++ b/password-hash/CHANGELOG.md @@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.3.1 (2021-09-14) +### Added +- `PasswordHashString` ([#758]) + +### Fixed +- Handling of empty salts in `fmt::Display` impl for PasswordHash ([#748]) +- MSRV regression from `base64ct` ([#757]) + +[#748]: https://github.com/RustCrypto/traits/pull/748 +[#757]: https://github.com/RustCrypto/traits/pull/757 +[#758]: https://github.com/RustCrypto/traits/pull/758 + ## 0.3.0 (2021-08-27) ### Added - More details to `ParamValueInvalid` ([#713]) diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index 8694ccc19..f11134291 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -5,7 +5,7 @@ Traits which describe the functionality of password hashing algorithms, as well as a `no_std`-friendly implementation of the PHC string format (a well-defined subset of the Modular Crypt Format a.k.a. MCF) """ -version = "0.3.0" # Also update html_root_url in lib.rs when bumping this +version = "0.3.1" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index 2879940b0..eb5cfc608 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -39,7 +39,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/password-hash/0.3.0" + html_root_url = "https://docs.rs/password-hash/0.3.1" )] #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] @@ -153,7 +153,7 @@ pub struct PasswordHash<'a> { impl<'a> PasswordHash<'a> { /// Parse a password hash from a string in the PHC string format. pub fn new(s: &'a str) -> Result { - Self::parse(s, Encoding::B64) + Self::parse(s, Encoding::default()) } /// Parse a password hash from the given [`Encoding`]. @@ -319,7 +319,7 @@ pub struct PasswordHashString { impl PasswordHashString { /// Parse a password hash from a string in the PHC string format. pub fn new(s: &str) -> Result { - Self::parse(s, Encoding::B64) + Self::parse(s, Encoding::default()) } /// Parse a password hash from the given [`Encoding`]. From 5107689661620306390322608ad0994c278ddf59 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 15 Sep 2021 06:19:21 -0600 Subject: [PATCH 0616/1461] password-hash: remove unused lifetimes (#760) Also adds a `warn(unused_lifetimes)` lint to prevent this going forward --- password-hash/src/lib.rs | 4 ++-- password-hash/src/traits.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index eb5cfc608..a6802ea24 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -42,7 +42,7 @@ html_root_url = "https://docs.rs/password-hash/0.3.1" )] #![forbid(unsafe_code)] -#![warn(missing_docs, rust_2018_idioms)] +#![warn(missing_docs, rust_2018_idioms, unused_lifetimes)] #[cfg(feature = "alloc")] extern crate alloc; @@ -412,7 +412,7 @@ impl FromStr for PasswordHashString { } #[cfg(feature = "alloc")] -impl<'a> fmt::Display for PasswordHashString { +impl fmt::Display for PasswordHashString { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(self.as_str()) } diff --git a/password-hash/src/traits.rs b/password-hash/src/traits.rs index 2501fdc15..472cd2b95 100644 --- a/password-hash/src/traits.rs +++ b/password-hash/src/traits.rs @@ -13,7 +13,7 @@ pub trait PasswordHasher { + Debug + Default + for<'a> TryFrom<&'a PasswordHash<'a>, Error = Error> - + for<'a> TryInto; + + TryInto; /// Compute a [`PasswordHash`] from the provided password using an /// explicit set of customized algorithm parameters as opposed to the From 3cd3e80d6bc4594532aa62873b36c1b3435caf10 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 15 Sep 2021 07:03:20 -0600 Subject: [PATCH 0617/1461] password-hash v0.3.2 (#761) --- Cargo.lock | 2 +- password-hash/CHANGELOG.md | 10 ++++++++-- password-hash/Cargo.toml | 2 +- password-hash/src/lib.rs | 2 +- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d5b949b9a..a887af43d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -325,7 +325,7 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "password-hash" -version = "0.3.1" +version = "0.3.2" dependencies = [ "base64ct", "rand_core", diff --git a/password-hash/CHANGELOG.md b/password-hash/CHANGELOG.md index 18cea172e..b4be72b68 100644 --- a/password-hash/CHANGELOG.md +++ b/password-hash/CHANGELOG.md @@ -5,7 +5,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 0.3.1 (2021-09-14) +## 0.3.2 (2021-09-15) +### Fixed +- Remove unused lifetimes ([#760]) + +[#760]: https://github.com/RustCrypto/traits/pull/760 + +## 0.3.1 (2021-09-14) [YANKED] ### Added - `PasswordHashString` ([#758]) @@ -17,7 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [#757]: https://github.com/RustCrypto/traits/pull/757 [#758]: https://github.com/RustCrypto/traits/pull/758 -## 0.3.0 (2021-08-27) +## 0.3.0 (2021-08-27) [YANKED] ### Added - More details to `ParamValueInvalid` ([#713]) - `SaltInvalid` error ([#713]) diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index f11134291..dd74c22b7 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -5,7 +5,7 @@ Traits which describe the functionality of password hashing algorithms, as well as a `no_std`-friendly implementation of the PHC string format (a well-defined subset of the Modular Crypt Format a.k.a. MCF) """ -version = "0.3.1" # Also update html_root_url in lib.rs when bumping this +version = "0.3.2" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index a6802ea24..317b7fe65 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -39,7 +39,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/password-hash/0.3.1" + html_root_url = "https://docs.rs/password-hash/0.3.2" )] #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms, unused_lifetimes)] From fb4c26cf88ac22eabbc5f69c6f316ec6a3e2f281 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 15 Sep 2021 15:19:36 -0600 Subject: [PATCH 0618/1461] elliptic-curve: SEC1 private key support (#762) Adds the following methods to `SecretKey`: - `from_sec1_der` - `from_sec1_pem` (requires `pem` feature) - `to_sec1_der` - `to_sec1_pem` (requires `pem` feature) These implement the SEC1 (RFC5915) ASN.1 DER encoding for elliptic curve private keys. These methods are extracted from and now consumed by the PKCS#8 implementation, as PKCS#8 is just a wrapper for this format when used with elliptic curve keys. It seems like it might be a good idea to eventually extract this into a `sec1` crate as a followup, providing a similar role to the `pkcs1` crate. This would allow a setup that works much more like the `rsa` crate does now, where impling `sec1` traits provides a blanket impl of PKCS#8 support. --- Cargo.lock | 6 +- elliptic-curve/Cargo.toml | 6 +- elliptic-curve/src/public_key.rs | 6 +- elliptic-curve/src/sec1.rs | 673 +--------------------- elliptic-curve/src/sec1/ec_private_key.rs | 208 +++++++ elliptic-curve/src/sec1/encoded_point.rs | 669 +++++++++++++++++++++ elliptic-curve/src/secret_key.rs | 202 +++++-- elliptic-curve/src/secret_key/pkcs8.rs | 113 +--- 8 files changed, 1069 insertions(+), 814 deletions(-) create mode 100644 elliptic-curve/src/sec1/ec_private_key.rs create mode 100644 elliptic-curve/src/sec1/encoded_point.rs diff --git a/Cargo.lock b/Cargo.lock index a887af43d..5b29cd847 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -188,9 +188,9 @@ dependencies = [ [[package]] name = "der" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7044a442ff01698f9ba0b8c3282057eaa04bdc85a1d8bd72627761f19ff080a" +checksum = "2adca118c71ecd9ae094d4b68257b3fdfcb711a612b9eec7b5a0d27a5a70a5b4" dependencies = [ "const-oid", ] @@ -219,10 +219,12 @@ version = "0.11.0-pre" dependencies = [ "base64ct", "crypto-bigint", + "der", "ff", "generic-array", "group", "hex-literal", + "pem-rfc7468", "pkcs8", "rand_core", "serde", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 08735193a..c9215f03a 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -16,6 +16,7 @@ keywords = ["crypto", "ecc", "elliptic", "weierstrass"] [dependencies] crypto-bigint = { version = "0.2.7", features = ["generic-array", "zeroize"] } +der = { version = "0.4.3", default-features = false, features = ["oid"] } generic-array = { version = "0.14", default-features = false } rand_core = { version = "0.6", default-features = false } subtle = { version = ">=2, <2.5", default-features = false } @@ -26,6 +27,7 @@ base64ct = { version = "1", optional = true, default-features = false } ff = { version = "0.11", optional = true, default-features = false } group = { version = "0.11", optional = true, default-features = false } hex-literal = { version = "0.3", optional = true } +pem-rfc7468 = { version = "0.2", optional = true } pkcs8 = { version = "0.7", optional = true } serde = { version = "1", optional = true, default-features = false } serde_json = { version = "1", optional = true, default-features = false, features = ["alloc"] } @@ -35,14 +37,14 @@ hex-literal = "0.3" [features] default = ["arithmetic"] -alloc = [] # todo: activate `group/alloc` when weak feature activation is available +alloc = ["der/alloc", "zeroize/alloc"] # todo: activate `group/alloc` when weak feature activation is available arithmetic = ["ff", "group"] bits = ["arithmetic", "ff/bits"] dev = ["arithmetic", "hex-literal", "pem"] ecdh = ["arithmetic"] hazmat = [] jwk = ["alloc", "base64ct/alloc", "serde", "serde_json", "zeroize/alloc"] -pem = ["alloc", "pkcs8/pem"] +pem = ["alloc", "arithmetic", "pem-rfc7468/alloc", "pkcs8/pem"] std = ["alloc", "rand_core/std"] [package.metadata.docs.rs] diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index 767ee578f..11ec37642 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -323,7 +323,7 @@ where { fn from_spki(spki: pkcs8::SubjectPublicKeyInfo<'_>) -> pkcs8::Result { if spki.algorithm.oid != ALGORITHM_OID { - return Err(pkcs8::der::ErrorKind::UnknownOid { + return Err(der::ErrorKind::UnknownOid { oid: spki.algorithm.oid, } .into()); @@ -332,11 +332,11 @@ where let params_oid = spki.algorithm.parameters_oid()?; if params_oid != C::OID { - return Err(pkcs8::der::ErrorKind::UnknownOid { oid: params_oid }.into()); + return Err(der::ErrorKind::UnknownOid { oid: params_oid }.into()); } Self::from_sec1_bytes(spki.subject_public_key) - .map_err(|_| pkcs8::der::Tag::BitString.value_error().into()) + .map_err(|_| der::Tag::BitString.value_error().into()) } } diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index c18d181e8..c08ea7214 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -1,472 +1,22 @@ -//! SEC1 encoding support. -//! -//! Support for the `Elliptic-Curve-Point-to-Octet-String` encoding described -//! in SEC1: Elliptic Curve Cryptography (Version 2.0) section 2.3.3 (p.10): +//! Support for SEC1 elliptic curve encoding formats. //! //! -use crate::{bigint::Encoding as _, Error, FieldBytes, FieldSize, PrimeCurve, Result, SecretKey}; -use core::{ - fmt::{self, Debug}, - ops::Add, -}; -use generic_array::{typenum::U1, ArrayLength, GenericArray}; -use subtle::{Choice, ConditionallySelectable}; -use zeroize::Zeroize; - -#[cfg(feature = "alloc")] -use alloc::boxed::Box; - -#[cfg(feature = "arithmetic")] -use crate::{point::DecompressPoint, AffinePoint, ProjectiveArithmetic}; - -#[cfg(all(feature = "arithmetic"))] -use crate::group::{Curve as _, Group}; - -/// Size of a compressed point for the given elliptic curve when encoded -/// using the SEC1 `Elliptic-Curve-Point-to-Octet-String` algorithm -/// (including leading `0x02` or `0x03` tag byte). -pub type CompressedPointSize = as Add>::Output; - -/// Size of an uncompressed point for the given elliptic curve when encoded -/// using the SEC1 `Elliptic-Curve-Point-to-Octet-String` algorithm -/// (including leading `0x04` tag byte). -pub type UncompressedPointSize = as Add>::Output; - -/// Size of an untagged point for given elliptic curve. -pub type UntaggedPointSize = as Add>::Output; - -/// SEC1 encoded curve point. -/// -/// This type is an enum over the compressed and uncompressed encodings, -/// useful for cases where either encoding can be supported, or conversions -/// between the two forms. -#[derive(Clone, Default, Eq, PartialEq, PartialOrd, Ord)] -pub struct EncodedPoint -where - C: PrimeCurve, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, -{ - bytes: GenericArray>, -} - -#[allow(clippy::len_without_is_empty)] -impl EncodedPoint -where - C: PrimeCurve, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, -{ - /// Decode elliptic curve point (compressed or uncompressed) from the - /// `Elliptic-Curve-Point-to-Octet-String` encoding described in - /// SEC 1: Elliptic Curve Cryptography (Version 2.0) section - /// 2.3.3 (page 10). - /// - /// - pub fn from_bytes(input: impl AsRef<[u8]>) -> Result { - let input = input.as_ref(); - - // Validate tag - let tag = input.first().cloned().ok_or(Error).and_then(Tag::from_u8)?; - - // Validate length - let expected_len = tag.message_len(C::UInt::BYTE_SIZE); +mod ec_private_key; +mod encoded_point; - if input.len() != expected_len { - return Err(Error); - } - - let mut bytes = GenericArray::default(); - bytes[..expected_len].copy_from_slice(input); - Ok(Self { bytes }) - } - - /// Decode elliptic curve point from raw uncompressed coordinates, i.e. - /// encoded as the concatenated `x || y` coordinates with no leading SEC1 - /// tag byte (which would otherwise be `0x04` for an uncompressed point). - pub fn from_untagged_bytes(bytes: &GenericArray>) -> Self { - let (x, y) = bytes.split_at(C::UInt::BYTE_SIZE); - Self::from_affine_coordinates(x.into(), y.into(), false) - } - - /// Encode an elliptic curve point from big endian serialized coordinates - /// (with optional point compression) - pub fn from_affine_coordinates(x: &FieldBytes, y: &FieldBytes, compress: bool) -> Self { - let tag = if compress { - Tag::compress_y(y.as_slice()) - } else { - Tag::Uncompressed - }; - - let mut bytes = GenericArray::default(); - bytes[0] = tag.into(); - bytes[1..(C::UInt::BYTE_SIZE + 1)].copy_from_slice(x); - - if !compress { - bytes[(C::UInt::BYTE_SIZE + 1)..].copy_from_slice(y); - } - - Self { bytes } - } - - /// Compute [`EncodedPoint`] representing the public key for the provided - /// [`SecretKey`]. - /// - /// The `compress` flag requests point compression. - #[cfg(all(feature = "arithmetic"))] - #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] - pub fn from_secret_key(secret_key: &SecretKey, compress: bool) -> Self - where - C: PrimeCurve + ProjectiveArithmetic, - AffinePoint: ToEncodedPoint, - { - (C::ProjectivePoint::generator() * secret_key.to_nonzero_scalar().as_ref()) - .to_affine() - .to_encoded_point(compress) - } - - /// Return [`EncodedPoint`] representing the additive identity - /// (a.k.a. point at infinity) - pub fn identity() -> Self { - Self::default() - } - - /// Get the length of the encoded point in bytes - pub fn len(&self) -> usize { - self.tag().message_len(C::UInt::BYTE_SIZE) - } - - /// Get byte slice containing the serialized [`EncodedPoint`]. - pub fn as_bytes(&self) -> &[u8] { - &self.bytes[..self.len()] - } - - /// Get boxed byte slice containing the serialized [`EncodedPoint`] - #[cfg(feature = "alloc")] - #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] - pub fn to_bytes(&self) -> Box<[u8]> { - self.as_bytes().to_vec().into_boxed_slice() - } - - /// Serialize point as raw uncompressed coordinates without tag byte, i.e. - /// encoded as the concatenated `x || y` coordinates. - #[cfg(feature = "arithmetic")] - #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] - pub fn to_untagged_bytes(&self) -> Option>> - where - C: PrimeCurve + ProjectiveArithmetic, - AffinePoint: DecompressPoint + ToEncodedPoint, - { - self.decompress().map(|point| { - let mut bytes = GenericArray::>::default(); - bytes.copy_from_slice(&point.as_bytes()[1..]); - bytes - }) - } - - /// Is this [`EncodedPoint`] compact? - pub fn is_compact(&self) -> bool { - self.tag().is_compact() - } - - /// Is this [`EncodedPoint`] compressed? - pub fn is_compressed(&self) -> bool { - self.tag().is_compressed() - } - - /// Is this [`EncodedPoint`] the additive identity? (a.k.a. point at infinity) - pub fn is_identity(&self) -> bool { - self.tag().is_identity() - } - - /// Compress this [`EncodedPoint`], returning a new [`EncodedPoint`]. - pub fn compress(&self) -> Self { - match self.coordinates() { - Coordinates::Compressed { .. } - | Coordinates::Compact { .. } - | Coordinates::Identity => self.clone(), - Coordinates::Uncompressed { x, y } => Self::from_affine_coordinates(x, y, true), - } - } - - /// Decompress this [`EncodedPoint`], returning a new [`EncodedPoint`]. - #[cfg(feature = "arithmetic")] - #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] - pub fn decompress(&self) -> Option - where - C: PrimeCurve + ProjectiveArithmetic, - AffinePoint: DecompressPoint + ToEncodedPoint, - { - match self.coordinates() { - Coordinates::Compressed { x, y_is_odd } => { - AffinePoint::::decompress(x, Choice::from(y_is_odd as u8)) - .map(|s| s.to_encoded_point(false)) - .into() - } - Coordinates::Compact { .. } | Coordinates::Identity => None, - Coordinates::Uncompressed { .. } => Some(self.clone()), - } - } - - /// Encode an [`EncodedPoint`] from the desired type - pub fn encode(encodable: T, compress: bool) -> Self - where - T: ToEncodedPoint, - { - encodable.to_encoded_point(compress) - } - - /// Decode this [`EncodedPoint`] into the desired type - pub fn decode(&self) -> Result - where - T: FromEncodedPoint, - { - T::from_encoded_point(self).ok_or(Error) - } - - /// Get the SEC1 tag for this [`EncodedPoint`] - pub fn tag(&self) -> Tag { - // Tag is ensured valid by the constructor - Tag::from_u8(self.bytes[0]).expect("invalid tag") - } - - /// Get the [`Coordinates`] for this [`EncodedPoint`]. - #[inline] - pub fn coordinates(&self) -> Coordinates<'_, C> { - if self.is_identity() { - return Coordinates::Identity; - } - - let (x, y) = self.bytes[1..].split_at(C::UInt::BYTE_SIZE); - - if self.is_compressed() { - Coordinates::Compressed { - x: x.into(), - y_is_odd: self.tag() as u8 & 1 == 1, - } - } else if self.is_compact() { - Coordinates::Compact { x: x.into() } - } else { - Coordinates::Uncompressed { - x: x.into(), - y: y.into(), - } - } - } - - /// Get the x-coordinate for this [`EncodedPoint`]. - /// - /// Returns `None` if this point is the identity point. - pub fn x(&self) -> Option<&FieldBytes> { - match self.coordinates() { - Coordinates::Identity => None, - Coordinates::Compressed { x, .. } => Some(x), - Coordinates::Uncompressed { x, .. } => Some(x), - Coordinates::Compact { x } => Some(x), - } - } - - /// Get the y-coordinate for this [`EncodedPoint`]. - /// - /// Returns `None` if this point is compressed or the identity point. - pub fn y(&self) -> Option<&FieldBytes> { - match self.coordinates() { - Coordinates::Compressed { .. } | Coordinates::Identity => None, - Coordinates::Uncompressed { y, .. } => Some(y), - Coordinates::Compact { .. } => None, - } - } -} - -impl AsRef<[u8]> for EncodedPoint -where - C: PrimeCurve, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, -{ - #[inline] - fn as_ref(&self) -> &[u8] { - self.as_bytes() - } -} - -impl ConditionallySelectable for EncodedPoint -where - C: PrimeCurve, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, - as ArrayLength>::ArrayType: Copy, -{ - fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { - let mut bytes = GenericArray::default(); - - for (i, byte) in bytes.iter_mut().enumerate() { - *byte = u8::conditional_select(&a.bytes[i], &b.bytes[i], choice); - } - - Self { bytes } - } -} - -impl Copy for EncodedPoint -where - C: PrimeCurve, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, - as ArrayLength>::ArrayType: Copy, -{ -} - -impl Debug for EncodedPoint -where - C: PrimeCurve, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "EncodedPoint<{:?}>({:?})", C::default(), &self.bytes) - } -} - -impl Zeroize for EncodedPoint -where - C: PrimeCurve, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, -{ - fn zeroize(&mut self) { - self.bytes.zeroize(); - *self = Self::identity(); - } -} - -/// Enum representing the coordinates of either compressed or uncompressed -/// SEC1-encoded elliptic curve points. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum Coordinates<'a, C: PrimeCurve> { - /// Identity point (a.k.a. point at infinity) - Identity, - - /// Compact curve point - Compact { - /// x-coordinate - x: &'a FieldBytes, - }, - - /// Compressed curve point - Compressed { - /// x-coordinate - x: &'a FieldBytes, - - /// Is the y-coordinate odd? - y_is_odd: bool, - }, - - /// Uncompressed curve point - Uncompressed { - /// x-coordinate - x: &'a FieldBytes, - - /// y-coordinate - y: &'a FieldBytes, - }, -} - -impl<'a, C: PrimeCurve> Coordinates<'a, C> { - /// Get the tag octet needed to encode this set of [`Coordinates`] - pub fn tag(&self) -> Tag { - match self { - Coordinates::Compact { .. } => Tag::Compact, - Coordinates::Compressed { y_is_odd, .. } => { - if *y_is_odd { - Tag::CompressedOddY - } else { - Tag::CompressedEvenY - } - } - Coordinates::Identity => Tag::Identity, - Coordinates::Uncompressed { .. } => Tag::Uncompressed, - } - } -} - -/// Tag byte used by the `Elliptic-Curve-Point-to-Octet-String` encoding. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -#[repr(u8)] -pub enum Tag { - /// Identity point (`0x00`) - Identity = 0, - - /// Compressed point with even y-coordinate (`0x02`) - CompressedEvenY = 2, - - /// Compressed point with odd y-coordinate (`0x03`) - CompressedOddY = 3, - - /// Uncompressed point (`0x04`) - Uncompressed = 4, - - /// Compact point (`0x05`) - Compact = 5, -} - -impl Tag { - /// Parse a tag value from a byte - pub fn from_u8(byte: u8) -> Result { - match byte { - 0 => Ok(Tag::Identity), - 2 => Ok(Tag::CompressedEvenY), - 3 => Ok(Tag::CompressedOddY), - 4 => Ok(Tag::Uncompressed), - 5 => Ok(Tag::Compact), - _ => Err(Error), - } - } - - /// Is this point compact? - pub fn is_compact(self) -> bool { - matches!(self, Tag::Compact) - } - - /// Is this point compressed? - pub fn is_compressed(self) -> bool { - matches!(self, Tag::CompressedEvenY | Tag::CompressedOddY) - } - - /// Is this point the identity point? - pub fn is_identity(self) -> bool { - self == Tag::Identity - } +pub use self::encoded_point::{ + CompressedPointSize, Coordinates, EncodedPoint, UncompressedPointSize, UntaggedPointSize, +}; - /// Compute the expected total message length for a message prefixed - /// with this tag (including the tag byte), given the field element size - /// (in bytes) for a particular elliptic curve. - pub fn message_len(self, field_element_size: usize) -> usize { - 1 + match self { - Tag::Identity => 0, - Tag::CompressedEvenY | Tag::CompressedOddY => field_element_size, - Tag::Uncompressed => field_element_size * 2, - Tag::Compact => field_element_size, - } - } +pub(crate) use self::ec_private_key::EcPrivateKey; - /// Compress the given y-coordinate, returning a `Tag::Compressed*` value - fn compress_y(y: &[u8]) -> Self { - // Is the y-coordinate odd in the SEC1 sense: `self mod 2 == 1`? - if y.as_ref().last().expect("empty y-coordinate") & 1 == 1 { - Tag::CompressedOddY - } else { - Tag::CompressedEvenY - } - } -} +use crate::{PrimeCurve, Result, SecretKey}; +use core::ops::Add; +use generic_array::{typenum::U1, ArrayLength}; -impl From for u8 { - fn from(tag: Tag) -> u8 { - tag as u8 - } -} +#[cfg(feature = "arithmetic")] +use crate::{AffinePoint, Error, ProjectiveArithmetic}; /// Trait for deserializing a value from a SEC1 encoded curve point. /// @@ -563,202 +113,3 @@ where } } } - -#[cfg(all(test, feature = "dev"))] -mod tests { - use super::{Coordinates, Tag}; - use crate::dev::MockCurve; - use generic_array::GenericArray; - use hex_literal::hex; - use subtle::ConditionallySelectable; - - type EncodedPoint = super::EncodedPoint; - - /// Identity point - const IDENTITY_BYTES: [u8; 1] = [0]; - - /// Example uncompressed point - const UNCOMPRESSED_BYTES: [u8; 65] = hex!("0411111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222"); - - /// Example compressed point: `UNCOMPRESSED_BYTES` after point compression - const COMPRESSED_BYTES: [u8; 33] = - hex!("021111111111111111111111111111111111111111111111111111111111111111"); - - #[test] - fn decode_compressed_point() { - // Even y-coordinate - let compressed_even_y_bytes = - hex!("020100000000000000000000000000000000000000000000000000000000000000"); - - let compressed_even_y = EncodedPoint::from_bytes(&compressed_even_y_bytes[..]).unwrap(); - - assert!(compressed_even_y.is_compressed()); - assert_eq!(compressed_even_y.tag(), Tag::CompressedEvenY); - assert_eq!(compressed_even_y.len(), 33); - assert_eq!(compressed_even_y.as_bytes(), &compressed_even_y_bytes[..]); - - assert_eq!( - compressed_even_y.coordinates(), - Coordinates::Compressed { - x: &hex!("0100000000000000000000000000000000000000000000000000000000000000").into(), - y_is_odd: false - } - ); - - assert_eq!( - compressed_even_y.x().unwrap(), - &hex!("0100000000000000000000000000000000000000000000000000000000000000").into() - ); - assert_eq!(compressed_even_y.y(), None); - - // Odd y-coordinate - let compressed_odd_y_bytes = - hex!("030200000000000000000000000000000000000000000000000000000000000000"); - - let compressed_odd_y = EncodedPoint::from_bytes(&compressed_odd_y_bytes[..]).unwrap(); - - assert!(compressed_odd_y.is_compressed()); - assert_eq!(compressed_odd_y.tag(), Tag::CompressedOddY); - assert_eq!(compressed_odd_y.len(), 33); - assert_eq!(compressed_odd_y.as_bytes(), &compressed_odd_y_bytes[..]); - - assert_eq!( - compressed_odd_y.coordinates(), - Coordinates::Compressed { - x: &hex!("0200000000000000000000000000000000000000000000000000000000000000").into(), - y_is_odd: true - } - ); - - assert_eq!( - compressed_odd_y.x().unwrap(), - &hex!("0200000000000000000000000000000000000000000000000000000000000000").into() - ); - assert_eq!(compressed_odd_y.y(), None); - } - - #[test] - fn decode_uncompressed_point() { - let uncompressed_point = EncodedPoint::from_bytes(&UNCOMPRESSED_BYTES[..]).unwrap(); - - assert!(!uncompressed_point.is_compressed()); - assert_eq!(uncompressed_point.tag(), Tag::Uncompressed); - assert_eq!(uncompressed_point.len(), 65); - assert_eq!(uncompressed_point.as_bytes(), &UNCOMPRESSED_BYTES[..]); - - assert_eq!( - uncompressed_point.coordinates(), - Coordinates::Uncompressed { - x: &hex!("1111111111111111111111111111111111111111111111111111111111111111").into(), - y: &hex!("2222222222222222222222222222222222222222222222222222222222222222").into() - } - ); - - assert_eq!( - uncompressed_point.x().unwrap(), - &hex!("1111111111111111111111111111111111111111111111111111111111111111").into() - ); - assert_eq!( - uncompressed_point.y().unwrap(), - &hex!("2222222222222222222222222222222222222222222222222222222222222222").into() - ); - } - - #[test] - fn decode_identity() { - let identity_point = EncodedPoint::from_bytes(&IDENTITY_BYTES[..]).unwrap(); - assert!(identity_point.is_identity()); - assert_eq!(identity_point.tag(), Tag::Identity); - assert_eq!(identity_point.len(), 1); - assert_eq!(identity_point.as_bytes(), &IDENTITY_BYTES[..]); - assert_eq!(identity_point.coordinates(), Coordinates::Identity); - assert_eq!(identity_point.x(), None); - assert_eq!(identity_point.y(), None); - } - - #[test] - fn decode_invalid_tag() { - let mut compressed_bytes = COMPRESSED_BYTES.clone(); - let mut uncompressed_bytes = UNCOMPRESSED_BYTES.clone(); - - for bytes in &mut [&mut compressed_bytes[..], &mut uncompressed_bytes[..]] { - for tag in 0..=0xFF { - // valid tags - if tag == 2 || tag == 3 || tag == 4 || tag == 5 { - continue; - } - - (*bytes)[0] = tag; - let decode_result = EncodedPoint::from_bytes(&*bytes); - assert!(decode_result.is_err()); - } - } - } - - #[test] - fn decode_truncated_point() { - for bytes in &[&COMPRESSED_BYTES[..], &UNCOMPRESSED_BYTES[..]] { - for len in 0..bytes.len() { - let decode_result = EncodedPoint::from_bytes(&bytes[..len]); - assert!(decode_result.is_err()); - } - } - } - - #[test] - fn from_untagged_point() { - let untagged_bytes = hex!("11111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222"); - let uncompressed_point = - EncodedPoint::from_untagged_bytes(GenericArray::from_slice(&untagged_bytes[..])); - assert_eq!(uncompressed_point.as_bytes(), &UNCOMPRESSED_BYTES[..]); - } - - #[test] - fn from_affine_coordinates() { - let x = hex!("1111111111111111111111111111111111111111111111111111111111111111"); - let y = hex!("2222222222222222222222222222222222222222222222222222222222222222"); - - let uncompressed_point = EncodedPoint::from_affine_coordinates(&x.into(), &y.into(), false); - assert_eq!(uncompressed_point.as_bytes(), &UNCOMPRESSED_BYTES[..]); - - let compressed_point = EncodedPoint::from_affine_coordinates(&x.into(), &y.into(), true); - assert_eq!(compressed_point.as_bytes(), &COMPRESSED_BYTES[..]); - } - - #[test] - fn compress() { - let uncompressed_point = EncodedPoint::from_bytes(&UNCOMPRESSED_BYTES[..]).unwrap(); - let compressed_point = uncompressed_point.compress(); - assert_eq!(compressed_point.as_bytes(), &COMPRESSED_BYTES[..]); - } - - #[test] - fn conditional_select() { - let a = EncodedPoint::from_bytes(&COMPRESSED_BYTES[..]).unwrap(); - let b = EncodedPoint::from_bytes(&UNCOMPRESSED_BYTES[..]).unwrap(); - - let a_selected = EncodedPoint::conditional_select(&a, &b, 0.into()); - assert_eq!(a, a_selected); - - let b_selected = EncodedPoint::conditional_select(&a, &b, 1.into()); - assert_eq!(b, b_selected); - } - - #[test] - fn identity() { - let identity_point = EncodedPoint::identity(); - assert_eq!(identity_point.tag(), Tag::Identity); - assert_eq!(identity_point.len(), 1); - assert_eq!(identity_point.as_bytes(), &IDENTITY_BYTES[..]); - - // identity is default - assert_eq!(identity_point, EncodedPoint::default()); - } - - #[cfg(feature = "alloc")] - #[test] - fn to_bytes() { - let uncompressed_point = EncodedPoint::from_bytes(&UNCOMPRESSED_BYTES[..]).unwrap(); - assert_eq!(&*uncompressed_point.to_bytes(), &UNCOMPRESSED_BYTES[..]); - } -} diff --git a/elliptic-curve/src/sec1/ec_private_key.rs b/elliptic-curve/src/sec1/ec_private_key.rs new file mode 100644 index 000000000..093bf723d --- /dev/null +++ b/elliptic-curve/src/sec1/ec_private_key.rs @@ -0,0 +1,208 @@ +//! SEC1 elliptic curve private key support. +//! +//! Support for ASN.1 DER-encoded elliptic curve private keys as described in +//! SEC1: Elliptic Curve Cryptography (Version 2.0) Appendix C.4 (p.108): +//! +//! + +use core::{ + convert::{TryFrom, TryInto}, + fmt, +}; +use der::{ + asn1::{Any, BitString, ContextSpecific, ObjectIdentifier, OctetString}, + Choice, Encodable, Encoder, Length, Message, Tag, TagNumber, +}; + +/// `ECPrivateKey` version. +/// +/// From RFC5913 Section 3: +/// > version specifies the syntax version number of the elliptic curve +/// > private key structure. For this version of the document, it SHALL +/// > be set to ecPrivkeyVer1, which is of type INTEGER and whose value +/// > is one (1). +const VERSION: u8 = 1; + +/// Context-specific tag number for the elliptic curve parameters. +const EC_PARAMETERS_TAG: TagNumber = TagNumber::new(0); + +/// Context-specific tag number for the public key. +const PUBLIC_KEY_TAG: TagNumber = TagNumber::new(1); + +/// SEC1 elliptic curve private key. +/// +/// Described in [SEC1: Elliptic Curve Cryptography (Version 2.0)] +/// Appendix C.4 (p.108) and also [RFC5915 Section 3]: +/// +/// ```text +/// ECPrivateKey ::= SEQUENCE { +/// version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), +/// privateKey OCTET STRING, +/// parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, +/// publicKey [1] BIT STRING OPTIONAL +/// } +/// ``` +/// +/// This ASN.1 structure is used for PKCS#8 private keys. It can also be used +/// directly, with a PEM encoding that begins with the following: +/// +/// ```text +/// -----BEGIN EC PRIVATE KEY----- +/// ``` +/// +/// [SEC1: Elliptic Curve Cryptography (Version 2.0)]: https://www.secg.org/sec1-v2.pdf +/// [RFC5915 Section 3]: https://datatracker.ietf.org/doc/html/rfc5915#section-3 +#[derive(Clone)] +pub struct EcPrivateKey<'a> { + /// Private key data. + pub private_key: &'a [u8], + + /// Elliptic curve parameters. + pub parameters: Option, + + /// Public key data, optionally available if version is V2. + pub public_key: Option<&'a [u8]>, +} + +impl<'a> TryFrom> for EcPrivateKey<'a> { + type Error = der::Error; + + fn try_from(any: Any<'a>) -> der::Result> { + any.sequence(|decoder| { + if decoder.uint8()? != VERSION { + return Err(der::Tag::Integer.value_error()); + } + + let private_key = decoder.octet_string()?.as_bytes(); + + let parameters = decoder + .context_specific(EC_PARAMETERS_TAG)? + .map(TryInto::try_into) + .transpose()?; + + let public_key = decoder + .context_specific(PUBLIC_KEY_TAG)? + .map(|any| any.bit_string()) + .transpose()? + .map(|bs| bs.as_bytes()); + + Ok(EcPrivateKey { + private_key, + parameters, + public_key, + }) + }) + } +} + +impl<'a> Message<'a> for EcPrivateKey<'a> { + fn fields(&self, f: F) -> der::Result + where + F: FnOnce(&[&dyn Encodable]) -> der::Result, + { + f(&[ + &VERSION, + &OctetString::new(self.private_key)?, + &self.parameters.as_ref().map(|params| ContextSpecific { + tag_number: EC_PARAMETERS_TAG, + value: params.into(), + }), + &self + .public_key + .map(|pk| { + BitString::new(pk).map(|value| ContextSpecific { + tag_number: PUBLIC_KEY_TAG, + value: value.into(), + }) + }) + .transpose()?, + ]) + } +} + +impl<'a> fmt::Debug for EcPrivateKey<'a> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("EcPrivateKey") + .field("parameters", &self.parameters) + .field("public_key", &self.public_key) + .finish() // TODO: use `finish_non_exhaustive` when stable + } +} + +/// Elliptic curve parameters as described in +/// [RFC5480 Section 2.1.1](https://datatracker.ietf.org/doc/html/rfc5480#section-2.1.1): +/// +/// ```text +/// ECParameters ::= CHOICE { +/// namedCurve OBJECT IDENTIFIER +/// -- implicitCurve NULL +/// -- specifiedCurve SpecifiedECDomain +/// } +/// -- implicitCurve and specifiedCurve MUST NOT be used in PKIX. +/// -- Details for SpecifiedECDomain can be found in [X9.62]. +/// -- Any future additions to this CHOICE should be coordinated +/// -- with ANSI X9. +/// ``` +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum EcParameters { + /// Elliptic curve named by a particular OID. + /// + /// > namedCurve identifies all the required values for a particular + /// > set of elliptic curve domain parameters to be represented by an + /// > object identifier. + NamedCurve(ObjectIdentifier), +} + +impl EcParameters { + /// Obtain the `namedCurve` OID. + pub fn named_curve(self) -> Option { + match self { + Self::NamedCurve(oid) => Some(oid), + } + } +} + +impl<'a> From<&'a EcParameters> for Any<'a> { + fn from(params: &'a EcParameters) -> Any<'a> { + match params { + EcParameters::NamedCurve(oid) => oid.into(), + } + } +} + +impl From for EcParameters { + fn from(oid: ObjectIdentifier) -> EcParameters { + EcParameters::NamedCurve(oid) + } +} + +impl TryFrom> for EcParameters { + type Error = der::Error; + + fn try_from(any: Any<'_>) -> der::Result { + match any.tag() { + Tag::ObjectIdentifier => any.oid().map(Self::NamedCurve), + tag => Err(tag.unexpected_error(Some(Tag::ObjectIdentifier))), + } + } +} + +impl Choice<'_> for EcParameters { + fn can_decode(tag: Tag) -> bool { + tag == Tag::ObjectIdentifier + } +} + +impl Encodable for EcParameters { + fn encoded_len(&self) -> der::Result { + match self { + Self::NamedCurve(oid) => oid.encoded_len(), + } + } + + fn encode(&self, encoder: &mut Encoder<'_>) -> der::Result<()> { + match self { + Self::NamedCurve(oid) => encoder.oid(*oid), + } + } +} diff --git a/elliptic-curve/src/sec1/encoded_point.rs b/elliptic-curve/src/sec1/encoded_point.rs new file mode 100644 index 000000000..28a086ff1 --- /dev/null +++ b/elliptic-curve/src/sec1/encoded_point.rs @@ -0,0 +1,669 @@ +//! SEC1 encoded point support. +//! +//! Support for the `Elliptic-Curve-Point-to-Octet-String` encoding described +//! in SEC1: Elliptic Curve Cryptography (Version 2.0) section 2.3.3 (p.10): +//! +//! + +use super::{FromEncodedPoint, ToEncodedPoint}; +use crate::{bigint::Encoding as _, Error, FieldBytes, FieldSize, PrimeCurve, Result}; +use core::{ + fmt::{self, Debug}, + ops::Add, +}; +use generic_array::{typenum::U1, ArrayLength, GenericArray}; +use subtle::{Choice, ConditionallySelectable}; +use zeroize::Zeroize; + +#[cfg(feature = "alloc")] +use alloc::boxed::Box; + +#[cfg(feature = "arithmetic")] +use crate::{AffinePoint, DecompressPoint, ProjectiveArithmetic, SecretKey}; + +#[cfg(all(feature = "arithmetic"))] +use crate::group::{Curve as _, Group}; + +/// Size of a compressed point for the given elliptic curve when encoded +/// using the SEC1 `Elliptic-Curve-Point-to-Octet-String` algorithm +/// (including leading `0x02` or `0x03` tag byte). +pub type CompressedPointSize = as Add>::Output; + +/// Size of an uncompressed point for the given elliptic curve when encoded +/// using the SEC1 `Elliptic-Curve-Point-to-Octet-String` algorithm +/// (including leading `0x04` tag byte). +pub type UncompressedPointSize = as Add>::Output; + +/// Size of an untagged point for given elliptic curve. +pub type UntaggedPointSize = as Add>::Output; + +/// SEC1 encoded curve point. +/// +/// This type is an enum over the compressed and uncompressed encodings, +/// useful for cases where either encoding can be supported, or conversions +/// between the two forms. +#[derive(Clone, Default, Eq, PartialEq, PartialOrd, Ord)] +pub struct EncodedPoint +where + C: PrimeCurve, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + bytes: GenericArray>, +} + +#[allow(clippy::len_without_is_empty)] +impl EncodedPoint +where + C: PrimeCurve, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + /// Decode elliptic curve point (compressed or uncompressed) from the + /// `Elliptic-Curve-Point-to-Octet-String` encoding described in + /// SEC 1: Elliptic Curve Cryptography (Version 2.0) section + /// 2.3.3 (page 10). + /// + /// + pub fn from_bytes(input: impl AsRef<[u8]>) -> Result { + let input = input.as_ref(); + + // Validate tag + let tag = input.first().cloned().ok_or(Error).and_then(Tag::from_u8)?; + + // Validate length + let expected_len = tag.message_len(C::UInt::BYTE_SIZE); + + if input.len() != expected_len { + return Err(Error); + } + + let mut bytes = GenericArray::default(); + bytes[..expected_len].copy_from_slice(input); + Ok(Self { bytes }) + } + + /// Decode elliptic curve point from raw uncompressed coordinates, i.e. + /// encoded as the concatenated `x || y` coordinates with no leading SEC1 + /// tag byte (which would otherwise be `0x04` for an uncompressed point). + pub fn from_untagged_bytes(bytes: &GenericArray>) -> Self { + let (x, y) = bytes.split_at(C::UInt::BYTE_SIZE); + Self::from_affine_coordinates(x.into(), y.into(), false) + } + + /// Encode an elliptic curve point from big endian serialized coordinates + /// (with optional point compression) + pub fn from_affine_coordinates(x: &FieldBytes, y: &FieldBytes, compress: bool) -> Self { + let tag = if compress { + Tag::compress_y(y.as_slice()) + } else { + Tag::Uncompressed + }; + + let mut bytes = GenericArray::default(); + bytes[0] = tag.into(); + bytes[1..(C::UInt::BYTE_SIZE + 1)].copy_from_slice(x); + + if !compress { + bytes[(C::UInt::BYTE_SIZE + 1)..].copy_from_slice(y); + } + + Self { bytes } + } + + /// Compute [`EncodedPoint`] representing the public key for the provided + /// [`SecretKey`]. + /// + /// The `compress` flag requests point compression. + #[cfg(all(feature = "arithmetic"))] + #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] + pub fn from_secret_key(secret_key: &SecretKey, compress: bool) -> Self + where + C: PrimeCurve + ProjectiveArithmetic, + AffinePoint: ToEncodedPoint, + { + (C::ProjectivePoint::generator() * secret_key.to_nonzero_scalar().as_ref()) + .to_affine() + .to_encoded_point(compress) + } + + /// Return [`EncodedPoint`] representing the additive identity + /// (a.k.a. point at infinity) + pub fn identity() -> Self { + Self::default() + } + + /// Get the length of the encoded point in bytes + pub fn len(&self) -> usize { + self.tag().message_len(C::UInt::BYTE_SIZE) + } + + /// Get byte slice containing the serialized [`EncodedPoint`]. + pub fn as_bytes(&self) -> &[u8] { + &self.bytes[..self.len()] + } + + /// Get boxed byte slice containing the serialized [`EncodedPoint`] + #[cfg(feature = "alloc")] + #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] + pub fn to_bytes(&self) -> Box<[u8]> { + self.as_bytes().to_vec().into_boxed_slice() + } + + /// Serialize point as raw uncompressed coordinates without tag byte, i.e. + /// encoded as the concatenated `x || y` coordinates. + #[cfg(feature = "arithmetic")] + #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] + pub fn to_untagged_bytes(&self) -> Option>> + where + C: PrimeCurve + ProjectiveArithmetic, + AffinePoint: DecompressPoint + ToEncodedPoint, + { + self.decompress().map(|point| { + let mut bytes = GenericArray::>::default(); + bytes.copy_from_slice(&point.as_bytes()[1..]); + bytes + }) + } + + /// Is this [`EncodedPoint`] compact? + pub fn is_compact(&self) -> bool { + self.tag().is_compact() + } + + /// Is this [`EncodedPoint`] compressed? + pub fn is_compressed(&self) -> bool { + self.tag().is_compressed() + } + + /// Is this [`EncodedPoint`] the additive identity? (a.k.a. point at infinity) + pub fn is_identity(&self) -> bool { + self.tag().is_identity() + } + + /// Compress this [`EncodedPoint`], returning a new [`EncodedPoint`]. + pub fn compress(&self) -> Self { + match self.coordinates() { + Coordinates::Compressed { .. } + | Coordinates::Compact { .. } + | Coordinates::Identity => self.clone(), + Coordinates::Uncompressed { x, y } => Self::from_affine_coordinates(x, y, true), + } + } + + /// Decompress this [`EncodedPoint`], returning a new [`EncodedPoint`]. + #[cfg(feature = "arithmetic")] + #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] + pub fn decompress(&self) -> Option + where + C: PrimeCurve + ProjectiveArithmetic, + AffinePoint: DecompressPoint + ToEncodedPoint, + { + match self.coordinates() { + Coordinates::Compressed { x, y_is_odd } => { + AffinePoint::::decompress(x, Choice::from(y_is_odd as u8)) + .map(|s| s.to_encoded_point(false)) + .into() + } + Coordinates::Compact { .. } | Coordinates::Identity => None, + Coordinates::Uncompressed { .. } => Some(self.clone()), + } + } + + /// Encode an [`EncodedPoint`] from the desired type + pub fn encode(encodable: T, compress: bool) -> Self + where + T: ToEncodedPoint, + { + encodable.to_encoded_point(compress) + } + + /// Decode this [`EncodedPoint`] into the desired type + pub fn decode(&self) -> Result + where + T: FromEncodedPoint, + { + T::from_encoded_point(self).ok_or(Error) + } + + /// Get the SEC1 tag for this [`EncodedPoint`] + pub fn tag(&self) -> Tag { + // Tag is ensured valid by the constructor + Tag::from_u8(self.bytes[0]).expect("invalid tag") + } + + /// Get the [`Coordinates`] for this [`EncodedPoint`]. + #[inline] + pub fn coordinates(&self) -> Coordinates<'_, C> { + if self.is_identity() { + return Coordinates::Identity; + } + + let (x, y) = self.bytes[1..].split_at(C::UInt::BYTE_SIZE); + + if self.is_compressed() { + Coordinates::Compressed { + x: x.into(), + y_is_odd: self.tag() as u8 & 1 == 1, + } + } else if self.is_compact() { + Coordinates::Compact { x: x.into() } + } else { + Coordinates::Uncompressed { + x: x.into(), + y: y.into(), + } + } + } + + /// Get the x-coordinate for this [`EncodedPoint`]. + /// + /// Returns `None` if this point is the identity point. + pub fn x(&self) -> Option<&FieldBytes> { + match self.coordinates() { + Coordinates::Identity => None, + Coordinates::Compressed { x, .. } => Some(x), + Coordinates::Uncompressed { x, .. } => Some(x), + Coordinates::Compact { x } => Some(x), + } + } + + /// Get the y-coordinate for this [`EncodedPoint`]. + /// + /// Returns `None` if this point is compressed or the identity point. + pub fn y(&self) -> Option<&FieldBytes> { + match self.coordinates() { + Coordinates::Compressed { .. } | Coordinates::Identity => None, + Coordinates::Uncompressed { y, .. } => Some(y), + Coordinates::Compact { .. } => None, + } + } +} + +impl AsRef<[u8]> for EncodedPoint +where + C: PrimeCurve, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + #[inline] + fn as_ref(&self) -> &[u8] { + self.as_bytes() + } +} + +impl ConditionallySelectable for EncodedPoint +where + C: PrimeCurve, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, + as ArrayLength>::ArrayType: Copy, +{ + fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { + let mut bytes = GenericArray::default(); + + for (i, byte) in bytes.iter_mut().enumerate() { + *byte = u8::conditional_select(&a.bytes[i], &b.bytes[i], choice); + } + + Self { bytes } + } +} + +impl Copy for EncodedPoint +where + C: PrimeCurve, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, + as ArrayLength>::ArrayType: Copy, +{ +} + +impl Debug for EncodedPoint +where + C: PrimeCurve, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "EncodedPoint<{:?}>({:?})", C::default(), &self.bytes) + } +} + +impl Zeroize for EncodedPoint +where + C: PrimeCurve, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, +{ + fn zeroize(&mut self) { + self.bytes.zeroize(); + *self = Self::identity(); + } +} + +/// Enum representing the coordinates of either compressed or uncompressed +/// SEC1-encoded elliptic curve points. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum Coordinates<'a, C: PrimeCurve> { + /// Identity point (a.k.a. point at infinity) + Identity, + + /// Compact curve point + Compact { + /// x-coordinate + x: &'a FieldBytes, + }, + + /// Compressed curve point + Compressed { + /// x-coordinate + x: &'a FieldBytes, + + /// Is the y-coordinate odd? + y_is_odd: bool, + }, + + /// Uncompressed curve point + Uncompressed { + /// x-coordinate + x: &'a FieldBytes, + + /// y-coordinate + y: &'a FieldBytes, + }, +} + +impl<'a, C: PrimeCurve> Coordinates<'a, C> { + /// Get the tag octet needed to encode this set of [`Coordinates`] + pub fn tag(&self) -> Tag { + match self { + Coordinates::Compact { .. } => Tag::Compact, + Coordinates::Compressed { y_is_odd, .. } => { + if *y_is_odd { + Tag::CompressedOddY + } else { + Tag::CompressedEvenY + } + } + Coordinates::Identity => Tag::Identity, + Coordinates::Uncompressed { .. } => Tag::Uncompressed, + } + } +} + +/// Tag byte used by the `Elliptic-Curve-Point-to-Octet-String` encoding. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[repr(u8)] +pub enum Tag { + /// Identity point (`0x00`) + Identity = 0, + + /// Compressed point with even y-coordinate (`0x02`) + CompressedEvenY = 2, + + /// Compressed point with odd y-coordinate (`0x03`) + CompressedOddY = 3, + + /// Uncompressed point (`0x04`) + Uncompressed = 4, + + /// Compact point (`0x05`) + Compact = 5, +} + +impl Tag { + /// Parse a tag value from a byte + pub fn from_u8(byte: u8) -> Result { + match byte { + 0 => Ok(Tag::Identity), + 2 => Ok(Tag::CompressedEvenY), + 3 => Ok(Tag::CompressedOddY), + 4 => Ok(Tag::Uncompressed), + 5 => Ok(Tag::Compact), + _ => Err(Error), + } + } + + /// Is this point compact? + pub fn is_compact(self) -> bool { + matches!(self, Tag::Compact) + } + + /// Is this point compressed? + pub fn is_compressed(self) -> bool { + matches!(self, Tag::CompressedEvenY | Tag::CompressedOddY) + } + + /// Is this point the identity point? + pub fn is_identity(self) -> bool { + self == Tag::Identity + } + + /// Compute the expected total message length for a message prefixed + /// with this tag (including the tag byte), given the field element size + /// (in bytes) for a particular elliptic curve. + pub fn message_len(self, field_element_size: usize) -> usize { + 1 + match self { + Tag::Identity => 0, + Tag::CompressedEvenY | Tag::CompressedOddY => field_element_size, + Tag::Uncompressed => field_element_size * 2, + Tag::Compact => field_element_size, + } + } + + /// Compress the given y-coordinate, returning a `Tag::Compressed*` value + fn compress_y(y: &[u8]) -> Self { + // Is the y-coordinate odd in the SEC1 sense: `self mod 2 == 1`? + if y.as_ref().last().expect("empty y-coordinate") & 1 == 1 { + Tag::CompressedOddY + } else { + Tag::CompressedEvenY + } + } +} + +impl From for u8 { + fn from(tag: Tag) -> u8 { + tag as u8 + } +} + +#[cfg(all(test, feature = "dev"))] +mod tests { + use super::{Coordinates, Tag}; + use crate::dev::MockCurve; + use generic_array::GenericArray; + use hex_literal::hex; + use subtle::ConditionallySelectable; + + type EncodedPoint = super::EncodedPoint; + + /// Identity point + const IDENTITY_BYTES: [u8; 1] = [0]; + + /// Example uncompressed point + const UNCOMPRESSED_BYTES: [u8; 65] = hex!("0411111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222"); + + /// Example compressed point: `UNCOMPRESSED_BYTES` after point compression + const COMPRESSED_BYTES: [u8; 33] = + hex!("021111111111111111111111111111111111111111111111111111111111111111"); + + #[test] + fn decode_compressed_point() { + // Even y-coordinate + let compressed_even_y_bytes = + hex!("020100000000000000000000000000000000000000000000000000000000000000"); + + let compressed_even_y = EncodedPoint::from_bytes(&compressed_even_y_bytes[..]).unwrap(); + + assert!(compressed_even_y.is_compressed()); + assert_eq!(compressed_even_y.tag(), Tag::CompressedEvenY); + assert_eq!(compressed_even_y.len(), 33); + assert_eq!(compressed_even_y.as_bytes(), &compressed_even_y_bytes[..]); + + assert_eq!( + compressed_even_y.coordinates(), + Coordinates::Compressed { + x: &hex!("0100000000000000000000000000000000000000000000000000000000000000").into(), + y_is_odd: false + } + ); + + assert_eq!( + compressed_even_y.x().unwrap(), + &hex!("0100000000000000000000000000000000000000000000000000000000000000").into() + ); + assert_eq!(compressed_even_y.y(), None); + + // Odd y-coordinate + let compressed_odd_y_bytes = + hex!("030200000000000000000000000000000000000000000000000000000000000000"); + + let compressed_odd_y = EncodedPoint::from_bytes(&compressed_odd_y_bytes[..]).unwrap(); + + assert!(compressed_odd_y.is_compressed()); + assert_eq!(compressed_odd_y.tag(), Tag::CompressedOddY); + assert_eq!(compressed_odd_y.len(), 33); + assert_eq!(compressed_odd_y.as_bytes(), &compressed_odd_y_bytes[..]); + + assert_eq!( + compressed_odd_y.coordinates(), + Coordinates::Compressed { + x: &hex!("0200000000000000000000000000000000000000000000000000000000000000").into(), + y_is_odd: true + } + ); + + assert_eq!( + compressed_odd_y.x().unwrap(), + &hex!("0200000000000000000000000000000000000000000000000000000000000000").into() + ); + assert_eq!(compressed_odd_y.y(), None); + } + + #[test] + fn decode_uncompressed_point() { + let uncompressed_point = EncodedPoint::from_bytes(&UNCOMPRESSED_BYTES[..]).unwrap(); + + assert!(!uncompressed_point.is_compressed()); + assert_eq!(uncompressed_point.tag(), Tag::Uncompressed); + assert_eq!(uncompressed_point.len(), 65); + assert_eq!(uncompressed_point.as_bytes(), &UNCOMPRESSED_BYTES[..]); + + assert_eq!( + uncompressed_point.coordinates(), + Coordinates::Uncompressed { + x: &hex!("1111111111111111111111111111111111111111111111111111111111111111").into(), + y: &hex!("2222222222222222222222222222222222222222222222222222222222222222").into() + } + ); + + assert_eq!( + uncompressed_point.x().unwrap(), + &hex!("1111111111111111111111111111111111111111111111111111111111111111").into() + ); + assert_eq!( + uncompressed_point.y().unwrap(), + &hex!("2222222222222222222222222222222222222222222222222222222222222222").into() + ); + } + + #[test] + fn decode_identity() { + let identity_point = EncodedPoint::from_bytes(&IDENTITY_BYTES[..]).unwrap(); + assert!(identity_point.is_identity()); + assert_eq!(identity_point.tag(), Tag::Identity); + assert_eq!(identity_point.len(), 1); + assert_eq!(identity_point.as_bytes(), &IDENTITY_BYTES[..]); + assert_eq!(identity_point.coordinates(), Coordinates::Identity); + assert_eq!(identity_point.x(), None); + assert_eq!(identity_point.y(), None); + } + + #[test] + fn decode_invalid_tag() { + let mut compressed_bytes = COMPRESSED_BYTES.clone(); + let mut uncompressed_bytes = UNCOMPRESSED_BYTES.clone(); + + for bytes in &mut [&mut compressed_bytes[..], &mut uncompressed_bytes[..]] { + for tag in 0..=0xFF { + // valid tags + if tag == 2 || tag == 3 || tag == 4 || tag == 5 { + continue; + } + + (*bytes)[0] = tag; + let decode_result = EncodedPoint::from_bytes(&*bytes); + assert!(decode_result.is_err()); + } + } + } + + #[test] + fn decode_truncated_point() { + for bytes in &[&COMPRESSED_BYTES[..], &UNCOMPRESSED_BYTES[..]] { + for len in 0..bytes.len() { + let decode_result = EncodedPoint::from_bytes(&bytes[..len]); + assert!(decode_result.is_err()); + } + } + } + + #[test] + fn from_untagged_point() { + let untagged_bytes = hex!("11111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222"); + let uncompressed_point = + EncodedPoint::from_untagged_bytes(GenericArray::from_slice(&untagged_bytes[..])); + assert_eq!(uncompressed_point.as_bytes(), &UNCOMPRESSED_BYTES[..]); + } + + #[test] + fn from_affine_coordinates() { + let x = hex!("1111111111111111111111111111111111111111111111111111111111111111"); + let y = hex!("2222222222222222222222222222222222222222222222222222222222222222"); + + let uncompressed_point = EncodedPoint::from_affine_coordinates(&x.into(), &y.into(), false); + assert_eq!(uncompressed_point.as_bytes(), &UNCOMPRESSED_BYTES[..]); + + let compressed_point = EncodedPoint::from_affine_coordinates(&x.into(), &y.into(), true); + assert_eq!(compressed_point.as_bytes(), &COMPRESSED_BYTES[..]); + } + + #[test] + fn compress() { + let uncompressed_point = EncodedPoint::from_bytes(&UNCOMPRESSED_BYTES[..]).unwrap(); + let compressed_point = uncompressed_point.compress(); + assert_eq!(compressed_point.as_bytes(), &COMPRESSED_BYTES[..]); + } + + #[test] + fn conditional_select() { + let a = EncodedPoint::from_bytes(&COMPRESSED_BYTES[..]).unwrap(); + let b = EncodedPoint::from_bytes(&UNCOMPRESSED_BYTES[..]).unwrap(); + + let a_selected = EncodedPoint::conditional_select(&a, &b, 0.into()); + assert_eq!(a, a_selected); + + let b_selected = EncodedPoint::conditional_select(&a, &b, 1.into()); + assert_eq!(b, b_selected); + } + + #[test] + fn identity() { + let identity_point = EncodedPoint::identity(); + assert_eq!(identity_point.tag(), Tag::Identity); + assert_eq!(identity_point.len(), 1); + assert_eq!(identity_point.as_bytes(), &IDENTITY_BYTES[..]); + + // identity is default + assert_eq!(identity_point, EncodedPoint::default()); + } + + #[cfg(feature = "alloc")] + #[test] + fn to_bytes() { + let uncompressed_point = EncodedPoint::from_bytes(&UNCOMPRESSED_BYTES[..]).unwrap(); + assert_eq!(&*uncompressed_point.to_bytes(), &UNCOMPRESSED_BYTES[..]); + } +} diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 586c5000f..6155bb550 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -10,16 +10,33 @@ #[cfg(feature = "pkcs8")] mod pkcs8; -use crate::{Curve, Error, FieldBytes, Result, ScalarCore}; +use crate::{ + sec1::{self, UncompressedPointSize, UntaggedPointSize, ValidatePublicKey}, + Curve, Error, FieldBytes, PrimeCurve, Result, ScalarCore, +}; use core::{ - convert::TryFrom, + convert::{TryFrom, TryInto}, fmt::{self, Debug}, + ops::Add, }; use crypto_bigint::Encoding; +use der::Decodable; use generic_array::GenericArray; +use generic_array::{typenum::U1, ArrayLength}; use subtle::{Choice, ConstantTimeEq}; use zeroize::Zeroize; +#[cfg(all(feature = "alloc", feature = "arithmetic"))] +use { + crate::{ + sec1::{FromEncodedPoint, ToEncodedPoint}, + AffinePoint, + }, + alloc::vec::Vec, + der::Encodable, + zeroize::Zeroizing, +}; + #[cfg(feature = "arithmetic")] use crate::{ rand_core::{CryptoRng, RngCore}, @@ -27,26 +44,24 @@ use crate::{ }; #[cfg(feature = "jwk")] -use crate::{ - generic_array::{typenum::U1, ArrayLength}, - jwk::{JwkEcKey, JwkParameters}, - ops::Add, - sec1::{UncompressedPointSize, UntaggedPointSize, ValidatePublicKey}, -}; +use crate::jwk::{JwkEcKey, JwkParameters}; + +#[cfg(all(feature = "arithmetic", any(feature = "jwk", feature = "pem")))] +use alloc::string::String; #[cfg(all(feature = "arithmetic", feature = "jwk"))] -use { - crate::{ - sec1::{FromEncodedPoint, ToEncodedPoint}, - AffinePoint, PrimeCurve, - }, - alloc::string::{String, ToString}, - zeroize::Zeroizing, -}; +use alloc::string::ToString; + +#[cfg(feature = "pem")] +use pem_rfc7468 as pem; #[cfg(all(docsrs, feature = "pkcs8"))] use {crate::pkcs8::FromPrivateKey, core::str::FromStr}; +/// Type label for PEM-encoded SEC1 private keys. +#[cfg(feature = "pem")] +pub(crate) const SEC1_PEM_TYPE_LABEL: &str = "EC PRIVATE KEY"; + /// Elliptic curve secret keys. /// /// This type wraps a secret scalar value, helping to prevent accidental @@ -99,29 +114,6 @@ where Self { inner: scalar } } - /// Deserialize raw private scalar as a big endian integer. - pub fn from_be_bytes(bytes: &[u8]) -> Result { - if bytes.len() != C::UInt::BYTE_SIZE { - return Err(Error); - } - - let inner: ScalarCore = Option::from(ScalarCore::from_be_bytes( - GenericArray::clone_from_slice(bytes), - )) - .ok_or(Error)?; - - if inner.is_zero().into() { - return Err(Error); - } - - Ok(Self { inner }) - } - - /// Expose the byte serialization of the value this [`SecretKey`] wraps. - pub fn to_be_bytes(&self) -> FieldBytes { - self.inner.to_be_bytes() - } - /// Borrow the inner secret [`ScalarCore`] value. /// /// # ⚠️ Warning @@ -159,6 +151,113 @@ where PublicKey::from_secret_scalar(&self.to_nonzero_scalar()) } + /// Deserialize raw secret scalar as a big endian integer. + pub fn from_be_bytes(bytes: &[u8]) -> Result { + if bytes.len() != C::UInt::BYTE_SIZE { + return Err(Error); + } + + let inner: ScalarCore = Option::from(ScalarCore::from_be_bytes( + GenericArray::clone_from_slice(bytes), + )) + .ok_or(Error)?; + + if inner.is_zero().into() { + return Err(Error); + } + + Ok(Self { inner }) + } + + /// Serialize raw secret scalar as a big endian integer. + pub fn to_be_bytes(&self) -> FieldBytes { + self.inner.to_be_bytes() + } + + /// Deserialize secret key encoded in the SEC1 ASN.1 DER `ECPrivateKey` format. + pub fn from_sec1_der(der_bytes: &[u8]) -> Result + where + C: PrimeCurve + ValidatePublicKey, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, + { + sec1::EcPrivateKey::from_der(der_bytes) + .and_then(TryInto::try_into) + .map_err(|_| Error) + } + + /// Serialize secret key in the SEC1 ASN.1 DER `ECPrivateKey` format. + #[cfg(all(feature = "alloc", feature = "arithmetic"))] + pub fn to_sec1_der(&self) -> der::Result>> + where + C: PrimeCurve + ProjectiveArithmetic, + AffinePoint: FromEncodedPoint + ToEncodedPoint, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, + { + // TODO(tarcieri): wrap `secret_key_bytes` in `Zeroizing` + let mut private_key_bytes = self.to_be_bytes(); + let public_key_bytes = self.public_key().to_encoded_point(false); + + let ec_private_key = Zeroizing::new( + sec1::EcPrivateKey { + private_key: &private_key_bytes, + parameters: None, + public_key: Some(public_key_bytes.as_bytes()), + } + .to_vec()?, + ); + + // TODO(tarcieri): wrap `private_key_bytes` in `Zeroizing` + private_key_bytes.zeroize(); + + Ok(ec_private_key) + } + + /// Parse [`SecretKey`] from PEM-encoded SEC1 `ECPrivateKey` format. + /// + /// PEM-encoded SEC1 keys can be identified by the leading delimiter: + /// + /// ```text + /// -----BEGIN EC PRIVATE KEY----- + /// ``` + #[cfg(feature = "pem")] + #[cfg_attr(docsrs, doc(cfg(feature = "pem")))] + pub fn from_sec1_pem(s: &str) -> Result + where + C: PrimeCurve + ValidatePublicKey, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, + { + let (label, der_bytes) = pem::decode_vec(s.as_bytes()).map_err(|_| Error)?; + + if label != SEC1_PEM_TYPE_LABEL { + return Err(Error); + } + + Self::from_sec1_der(&*der_bytes).map_err(|_| Error) + } + + /// Serialize private key as self-zeroizing PEM-encoded SEC1 `ECPrivateKey` + /// with the given [`pem::LineEnding`]. + /// + /// Pass `Default::default()` to use the OS's native line endings. + #[cfg(feature = "pem")] + #[cfg_attr(docsrs, doc(cfg(feature = "pem")))] + pub fn to_pem(&self, line_ending: pem::LineEnding) -> Result> + where + C: PrimeCurve + ProjectiveArithmetic, + AffinePoint: FromEncodedPoint + ToEncodedPoint, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, + { + self.to_sec1_der() + .ok() + .and_then(|der| pem::encode_string(SEC1_PEM_TYPE_LABEL, line_ending, &der).ok()) + .map(Zeroizing::new) + .ok_or(Error) + } + /// Parse a [`JwkEcKey`] JSON Web Key (JWK) into a [`SecretKey`]. #[cfg(feature = "jwk")] #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] @@ -251,14 +350,29 @@ where } } -impl TryFrom<&[u8]> for SecretKey +impl TryFrom> for SecretKey where - C: Curve, + C: PrimeCurve + ValidatePublicKey, + UntaggedPointSize: Add + ArrayLength, + UncompressedPointSize: ArrayLength, { - type Error = Error; + type Error = der::Error; + + fn try_from(sec1_private_key: sec1::EcPrivateKey<'_>) -> der::Result { + let secret_key = Self::from_be_bytes(sec1_private_key.private_key) + .map_err(|_| der::Tag::Sequence.value_error())?; + + // TODO(tarcieri): validate `sec1_private_key.params`? + if let Some(pk_bytes) = sec1_private_key.public_key { + let pk = sec1::EncodedPoint::::from_bytes(pk_bytes) + .map_err(|_| der::Tag::BitString.value_error())?; + + if C::validate_public_key(&secret_key, &pk).is_err() { + return Err(der::Tag::BitString.value_error()); + } + } - fn try_from(slice: &[u8]) -> Result { - Self::from_be_bytes(slice) + Ok(secret_key) } } diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs index d530596f0..08d69198f 100644 --- a/elliptic-curve/src/secret_key/pkcs8.rs +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -1,47 +1,13 @@ //! PKCS#8 encoding/decoding support. -//! -//! This module implements the `ECPrivateKey` schema as described in -//! [RFC5915 Section 3](https://datatracker.ietf.org/doc/html/rfc5915#section-3): -//! -//! ```text -//! ECPrivateKey ::= SEQUENCE { -//! version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), -//! privateKey OCTET STRING, -//! parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, -//! publicKey [1] BIT STRING OPTIONAL -//! } -//! ``` -//! -//! It is presently only supported for use with PKCS#8, i.e. keys which begin -//! with the following: -//! -//! ```text -//! -----BEGIN PRIVATE KEY----- -//! ``` -//! -//! The following format is *NOT* presently supported: -//! -//! ```text -//! -----BEGIN EC PRIVATE KEY----- -//! ``` -//! -//! Supporting the above format (the "SECG" format as described in RFC5919) -//! would be fairly simple, as it's a PEM encoding of the aforementioned -//! ASN.1 data structure. Please open an issue if you are interested. -//! -//! That said, we recommend using PKCS#8 in new applications. use super::SecretKey; use crate::{ - sec1::{self, UncompressedPointSize, UntaggedPointSize, ValidatePublicKey}, - AlgorithmParameters, Curve, ALGORITHM_OID, + sec1::{EcPrivateKey, UncompressedPointSize, UntaggedPointSize, ValidatePublicKey}, + AlgorithmParameters, PrimeCurve, ALGORITHM_OID, }; -use core::ops::Add; +use core::{convert::TryFrom, ops::Add}; use generic_array::{typenum::U1, ArrayLength}; -use pkcs8::{ - der::{self, TagNumber}, - FromPrivateKey, -}; +use pkcs8::{der::Decodable, FromPrivateKey}; // Imports for the `ToPrivateKey` impl // TODO(tarcieri): use weak activation of `pkcs8/alloc` for gating `ToPrivateKey` impl @@ -51,34 +17,20 @@ use { sec1::{FromEncodedPoint, ToEncodedPoint}, AffinePoint, ProjectiveArithmetic, }, - core::convert::TryInto, - pkcs8::{ - der::{ - asn1::{BitString, ContextSpecific, OctetString}, - Encodable, - }, - ToPrivateKey, - }, - zeroize::{Zeroize, Zeroizing}, + pkcs8::ToPrivateKey, }; // Imports for actual PEM support #[cfg(feature = "pem")] use { - crate::{error::Error, PrimeCurve, Result}, + crate::{error::Error, Result}, core::str::FromStr, }; -/// Version -const VERSION: u8 = 1; - -/// Context-specific tag number for the public key. -const PUBLIC_KEY_TAG: TagNumber = TagNumber::new(1); - #[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))] impl FromPrivateKey for SecretKey where - C: Curve + AlgorithmParameters + ValidatePublicKey, + C: PrimeCurve + AlgorithmParameters + ValidatePublicKey, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { @@ -89,31 +41,8 @@ where .algorithm .assert_oids(ALGORITHM_OID, C::OID)?; - let mut decoder = der::Decoder::new(private_key_info.private_key); - - let result = decoder.sequence(|decoder| { - if decoder.uint8()? != VERSION { - return Err(der::Tag::Integer.value_error()); - } - - let secret_key = Self::from_be_bytes(decoder.octet_string()?.as_ref()) - .map_err(|_| der::Tag::Sequence.value_error())?; - - let public_key = decoder - .context_specific(PUBLIC_KEY_TAG)? - .ok_or_else(|| der::Tag::ContextSpecific(PUBLIC_KEY_TAG).value_error())? - .bit_string()?; - - if let Ok(pk) = sec1::EncodedPoint::::from_bytes(public_key.as_ref()) { - if C::validate_public_key(&secret_key, &pk).is_ok() { - return Ok(secret_key); - } - } - - Err(der::Tag::BitString.value_error()) - })?; - - Ok(decoder.finish(result)?) + let ec_private_key = EcPrivateKey::from_der(private_key_info.private_key)?; + Ok(Self::try_from(ec_private_key)?) } } @@ -131,28 +60,8 @@ where UncompressedPointSize: ArrayLength, { fn to_pkcs8_der(&self) -> pkcs8::Result { - // TODO(tarcieri): wrap `secret_key_bytes` in `Zeroizing` - let mut secret_key_bytes = self.to_be_bytes(); - let secret_key_field = OctetString::new(&secret_key_bytes)?; - let public_key_bytes = self.public_key().to_encoded_point(false); - let public_key_field = ContextSpecific { - tag_number: PUBLIC_KEY_TAG, - value: BitString::new(public_key_bytes.as_ref())?.into(), - }; - - let der_message_fields: &[&dyn Encodable] = - &[&VERSION, &secret_key_field, &public_key_field]; - - let encoded_len = der::message::encoded_len(der_message_fields)?.try_into()?; - let mut der_message = Zeroizing::new(vec![0u8; encoded_len]); - let mut encoder = der::Encoder::new(&mut der_message); - encoder.message(der_message_fields)?; - encoder.finish()?; - - // TODO(tarcieri): wrap `secret_key_bytes` in `Zeroizing` - secret_key_bytes.zeroize(); - - Ok(pkcs8::PrivateKeyInfo::new(C::algorithm_identifier(), &der_message).to_der()) + let ec_private_key = self.to_sec1_der()?; + Ok(pkcs8::PrivateKeyInfo::new(C::algorithm_identifier(), &ec_private_key).to_der()) } } From 5db7a31dcfb243387ab353694373cdc87f34910a Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 15 Sep 2021 17:58:17 -0600 Subject: [PATCH 0619/1461] elliptic-curve: (re)re-export `sec1::Tag` (#763) This was accidentally hidden during the refactoring in #762 --- elliptic-curve/src/sec1.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index c08ea7214..c5ca63742 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -6,7 +6,7 @@ mod ec_private_key; mod encoded_point; pub use self::encoded_point::{ - CompressedPointSize, Coordinates, EncodedPoint, UncompressedPointSize, UntaggedPointSize, + CompressedPointSize, Coordinates, EncodedPoint, Tag, UncompressedPointSize, UntaggedPointSize, }; pub(crate) use self::ec_private_key::EcPrivateKey; From fd041829071d2f0d0949575688eac31d78dd2c3e Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 16 Sep 2021 22:50:01 -0600 Subject: [PATCH 0620/1461] elliptic-curve: extract `EcPrivateKey` into the `sec1` crate (#765) The `sec1` crate is an extraction of the SEC1 ASN.1 DER types originally developed in the `elliptic-curve` crate: https://github.com/RustCrypto/formats/pull/37 The plan is to move more SEC1 functionality there to make it reusable. --- .github/workflows/elliptic-curve.yml | 5 +- Cargo.lock | 16 +- Cargo.toml | 4 + elliptic-curve/Cargo.toml | 5 +- elliptic-curve/src/error.rs | 7 + elliptic-curve/src/lib.rs | 2 +- elliptic-curve/src/sec1.rs | 3 - elliptic-curve/src/sec1/ec_private_key.rs | 208 ---------------------- elliptic-curve/src/secret_key.rs | 44 +++-- elliptic-curve/src/secret_key/pkcs8.rs | 6 +- 10 files changed, 63 insertions(+), 237 deletions(-) delete mode 100644 elliptic-curve/src/sec1/ec_private_key.rs diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index bfc530822..9fbd2fc33 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -44,7 +44,10 @@ jobs: - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features jwk - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features pem - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features pkcs8 - - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features ecdh,hazmat,jwk,pem + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features sec1 + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features pkcs8,sec1 + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features ecdh,hazmat,jwk,pem,sec1 + test: runs-on: ubuntu-latest strategy: diff --git a/Cargo.lock b/Cargo.lock index 5b29cd847..26a4bc288 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -118,8 +118,7 @@ dependencies = [ [[package]] name = "const-oid" version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdab415d6744056100f40250a66bc430c1a46f7a02e20bc11c94c79a0f0464df" +source = "git+https://github.com/rustcrypto/formats#46a02c5e43a213e20e07af1e6bc19512c6a5fd97" [[package]] name = "cpufeatures" @@ -189,8 +188,7 @@ dependencies = [ [[package]] name = "der" version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2adca118c71ecd9ae094d4b68257b3fdfcb711a612b9eec7b5a0d27a5a70a5b4" +source = "git+https://github.com/rustcrypto/formats#46a02c5e43a213e20e07af1e6bc19512c6a5fd97" dependencies = [ "const-oid", ] @@ -227,6 +225,7 @@ dependencies = [ "pem-rfc7468", "pkcs8", "rand_core", + "sec1", "serde", "serde_json", "subtle", @@ -394,6 +393,15 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +[[package]] +name = "sec1" +version = "0.0.0" +source = "git+https://github.com/rustcrypto/formats#46a02c5e43a213e20e07af1e6bc19512c6a5fd97" +dependencies = [ + "der", + "zeroize", +] + [[package]] name = "serde" version = "1.0.130" diff --git a/Cargo.toml b/Cargo.toml index ebf9e0985..d9fb216d7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,3 +12,7 @@ members = [ "signature/async", "universal-hash", ] + +[patch.crates-io] +der = { git = "https://github.com/rustcrypto/formats" } +sec1 = { git = "https://github.com/rustcrypto/formats" } diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index c9215f03a..44d7714f8 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -29,6 +29,7 @@ group = { version = "0.11", optional = true, default-features = false } hex-literal = { version = "0.3", optional = true } pem-rfc7468 = { version = "0.2", optional = true } pkcs8 = { version = "0.7", optional = true } +sec1 = { version = "0", optional = true } serde = { version = "1", optional = true, default-features = false } serde_json = { version = "1", optional = true, default-features = false, features = ["alloc"] } @@ -37,14 +38,14 @@ hex-literal = "0.3" [features] default = ["arithmetic"] -alloc = ["der/alloc", "zeroize/alloc"] # todo: activate `group/alloc` when weak feature activation is available +alloc = ["der/alloc", "sec1/alloc", "zeroize/alloc"] # todo: use weak activation for `group`/`sec1` alloc when available arithmetic = ["ff", "group"] bits = ["arithmetic", "ff/bits"] dev = ["arithmetic", "hex-literal", "pem"] ecdh = ["arithmetic"] hazmat = [] jwk = ["alloc", "base64ct/alloc", "serde", "serde_json", "zeroize/alloc"] -pem = ["alloc", "arithmetic", "pem-rfc7468/alloc", "pkcs8/pem"] +pem = ["alloc", "arithmetic", "pem-rfc7468/alloc", "pkcs8/pem", "sec1/alloc"] std = ["alloc", "rand_core/std"] [package.metadata.docs.rs] diff --git a/elliptic-curve/src/error.rs b/elliptic-curve/src/error.rs index bac007a0e..e579601f0 100644 --- a/elliptic-curve/src/error.rs +++ b/elliptic-curve/src/error.rs @@ -22,5 +22,12 @@ impl From for Error { } } +#[cfg(feature = "sec1")] +impl From for Error { + fn from(_: sec1::Error) -> Error { + Error + } +} + #[cfg(feature = "std")] impl std::error::Error for Error {} diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 518a68a55..4d6441c32 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -93,7 +93,7 @@ use core::fmt::Debug; use generic_array::GenericArray; /// Algorithm [`ObjectIdentifier`][`pkcs8::ObjectIdentifier`] for elliptic -/// curve public key cryptography. +/// curve public key cryptography (`id-ecPublicKey`). /// /// #[cfg(feature = "pkcs8")] diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index c5ca63742..81ec9cd3b 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -2,15 +2,12 @@ //! //! -mod ec_private_key; mod encoded_point; pub use self::encoded_point::{ CompressedPointSize, Coordinates, EncodedPoint, Tag, UncompressedPointSize, UntaggedPointSize, }; -pub(crate) use self::ec_private_key::EcPrivateKey; - use crate::{PrimeCurve, Result, SecretKey}; use core::ops::Add; use generic_array::{typenum::U1, ArrayLength}; diff --git a/elliptic-curve/src/sec1/ec_private_key.rs b/elliptic-curve/src/sec1/ec_private_key.rs deleted file mode 100644 index 093bf723d..000000000 --- a/elliptic-curve/src/sec1/ec_private_key.rs +++ /dev/null @@ -1,208 +0,0 @@ -//! SEC1 elliptic curve private key support. -//! -//! Support for ASN.1 DER-encoded elliptic curve private keys as described in -//! SEC1: Elliptic Curve Cryptography (Version 2.0) Appendix C.4 (p.108): -//! -//! - -use core::{ - convert::{TryFrom, TryInto}, - fmt, -}; -use der::{ - asn1::{Any, BitString, ContextSpecific, ObjectIdentifier, OctetString}, - Choice, Encodable, Encoder, Length, Message, Tag, TagNumber, -}; - -/// `ECPrivateKey` version. -/// -/// From RFC5913 Section 3: -/// > version specifies the syntax version number of the elliptic curve -/// > private key structure. For this version of the document, it SHALL -/// > be set to ecPrivkeyVer1, which is of type INTEGER and whose value -/// > is one (1). -const VERSION: u8 = 1; - -/// Context-specific tag number for the elliptic curve parameters. -const EC_PARAMETERS_TAG: TagNumber = TagNumber::new(0); - -/// Context-specific tag number for the public key. -const PUBLIC_KEY_TAG: TagNumber = TagNumber::new(1); - -/// SEC1 elliptic curve private key. -/// -/// Described in [SEC1: Elliptic Curve Cryptography (Version 2.0)] -/// Appendix C.4 (p.108) and also [RFC5915 Section 3]: -/// -/// ```text -/// ECPrivateKey ::= SEQUENCE { -/// version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), -/// privateKey OCTET STRING, -/// parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, -/// publicKey [1] BIT STRING OPTIONAL -/// } -/// ``` -/// -/// This ASN.1 structure is used for PKCS#8 private keys. It can also be used -/// directly, with a PEM encoding that begins with the following: -/// -/// ```text -/// -----BEGIN EC PRIVATE KEY----- -/// ``` -/// -/// [SEC1: Elliptic Curve Cryptography (Version 2.0)]: https://www.secg.org/sec1-v2.pdf -/// [RFC5915 Section 3]: https://datatracker.ietf.org/doc/html/rfc5915#section-3 -#[derive(Clone)] -pub struct EcPrivateKey<'a> { - /// Private key data. - pub private_key: &'a [u8], - - /// Elliptic curve parameters. - pub parameters: Option, - - /// Public key data, optionally available if version is V2. - pub public_key: Option<&'a [u8]>, -} - -impl<'a> TryFrom> for EcPrivateKey<'a> { - type Error = der::Error; - - fn try_from(any: Any<'a>) -> der::Result> { - any.sequence(|decoder| { - if decoder.uint8()? != VERSION { - return Err(der::Tag::Integer.value_error()); - } - - let private_key = decoder.octet_string()?.as_bytes(); - - let parameters = decoder - .context_specific(EC_PARAMETERS_TAG)? - .map(TryInto::try_into) - .transpose()?; - - let public_key = decoder - .context_specific(PUBLIC_KEY_TAG)? - .map(|any| any.bit_string()) - .transpose()? - .map(|bs| bs.as_bytes()); - - Ok(EcPrivateKey { - private_key, - parameters, - public_key, - }) - }) - } -} - -impl<'a> Message<'a> for EcPrivateKey<'a> { - fn fields(&self, f: F) -> der::Result - where - F: FnOnce(&[&dyn Encodable]) -> der::Result, - { - f(&[ - &VERSION, - &OctetString::new(self.private_key)?, - &self.parameters.as_ref().map(|params| ContextSpecific { - tag_number: EC_PARAMETERS_TAG, - value: params.into(), - }), - &self - .public_key - .map(|pk| { - BitString::new(pk).map(|value| ContextSpecific { - tag_number: PUBLIC_KEY_TAG, - value: value.into(), - }) - }) - .transpose()?, - ]) - } -} - -impl<'a> fmt::Debug for EcPrivateKey<'a> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("EcPrivateKey") - .field("parameters", &self.parameters) - .field("public_key", &self.public_key) - .finish() // TODO: use `finish_non_exhaustive` when stable - } -} - -/// Elliptic curve parameters as described in -/// [RFC5480 Section 2.1.1](https://datatracker.ietf.org/doc/html/rfc5480#section-2.1.1): -/// -/// ```text -/// ECParameters ::= CHOICE { -/// namedCurve OBJECT IDENTIFIER -/// -- implicitCurve NULL -/// -- specifiedCurve SpecifiedECDomain -/// } -/// -- implicitCurve and specifiedCurve MUST NOT be used in PKIX. -/// -- Details for SpecifiedECDomain can be found in [X9.62]. -/// -- Any future additions to this CHOICE should be coordinated -/// -- with ANSI X9. -/// ``` -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum EcParameters { - /// Elliptic curve named by a particular OID. - /// - /// > namedCurve identifies all the required values for a particular - /// > set of elliptic curve domain parameters to be represented by an - /// > object identifier. - NamedCurve(ObjectIdentifier), -} - -impl EcParameters { - /// Obtain the `namedCurve` OID. - pub fn named_curve(self) -> Option { - match self { - Self::NamedCurve(oid) => Some(oid), - } - } -} - -impl<'a> From<&'a EcParameters> for Any<'a> { - fn from(params: &'a EcParameters) -> Any<'a> { - match params { - EcParameters::NamedCurve(oid) => oid.into(), - } - } -} - -impl From for EcParameters { - fn from(oid: ObjectIdentifier) -> EcParameters { - EcParameters::NamedCurve(oid) - } -} - -impl TryFrom> for EcParameters { - type Error = der::Error; - - fn try_from(any: Any<'_>) -> der::Result { - match any.tag() { - Tag::ObjectIdentifier => any.oid().map(Self::NamedCurve), - tag => Err(tag.unexpected_error(Some(Tag::ObjectIdentifier))), - } - } -} - -impl Choice<'_> for EcParameters { - fn can_decode(tag: Tag) -> bool { - tag == Tag::ObjectIdentifier - } -} - -impl Encodable for EcParameters { - fn encoded_len(&self) -> der::Result { - match self { - Self::NamedCurve(oid) => oid.encoded_len(), - } - } - - fn encode(&self, encoder: &mut Encoder<'_>) -> der::Result<()> { - match self { - Self::NamedCurve(oid) => encoder.oid(*oid), - } - } -} diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 6155bb550..947f62fe9 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -7,22 +7,13 @@ //! When the `zeroize` feature of this crate is enabled, it also handles //! zeroing it out of memory securely on drop. -#[cfg(feature = "pkcs8")] +#[cfg(all(feature = "pkcs8", feature = "sec1"))] mod pkcs8; -use crate::{ - sec1::{self, UncompressedPointSize, UntaggedPointSize, ValidatePublicKey}, - Curve, Error, FieldBytes, PrimeCurve, Result, ScalarCore, -}; -use core::{ - convert::{TryFrom, TryInto}, - fmt::{self, Debug}, - ops::Add, -}; +use crate::{Curve, Error, FieldBytes, Result, ScalarCore}; +use core::fmt::{self, Debug}; use crypto_bigint::Encoding; -use der::Decodable; use generic_array::GenericArray; -use generic_array::{typenum::U1, ArrayLength}; use subtle::{Choice, ConstantTimeEq}; use zeroize::Zeroize; @@ -55,6 +46,19 @@ use alloc::string::ToString; #[cfg(feature = "pem")] use pem_rfc7468 as pem; +#[cfg(feature = "sec1")] +use { + crate::{ + sec1::{EncodedPoint, UncompressedPointSize, UntaggedPointSize, ValidatePublicKey}, + PrimeCurve, + }, + core::{ + convert::{TryFrom, TryInto}, + ops::Add, + }, + generic_array::{typenum::U1, ArrayLength}, +}; + #[cfg(all(docsrs, feature = "pkcs8"))] use {crate::pkcs8::FromPrivateKey, core::str::FromStr}; @@ -175,19 +179,25 @@ where } /// Deserialize secret key encoded in the SEC1 ASN.1 DER `ECPrivateKey` format. + #[cfg(all(feature = "sec1"))] + #[cfg_attr(docsrs, doc(cfg(feature = "sec1")))] pub fn from_sec1_der(der_bytes: &[u8]) -> Result where C: PrimeCurve + ValidatePublicKey, UntaggedPointSize: Add + ArrayLength, UncompressedPointSize: ArrayLength, { - sec1::EcPrivateKey::from_der(der_bytes) - .and_then(TryInto::try_into) + sec1::EcPrivateKey::try_from(der_bytes)? + .try_into() .map_err(|_| Error) } /// Serialize secret key in the SEC1 ASN.1 DER `ECPrivateKey` format. - #[cfg(all(feature = "alloc", feature = "arithmetic"))] + #[cfg(all(feature = "alloc", feature = "arithmetic", feature = "sec1"))] + #[cfg_attr( + docsrs, + doc(cfg(feature = "alloc", feature = "arithmetic", feature = "sec1")) + )] pub fn to_sec1_der(&self) -> der::Result>> where C: PrimeCurve + ProjectiveArithmetic, @@ -350,6 +360,8 @@ where } } +#[cfg(all(feature = "sec1"))] +#[cfg_attr(docsrs, doc(cfg(feature = "sec1")))] impl TryFrom> for SecretKey where C: PrimeCurve + ValidatePublicKey, @@ -364,7 +376,7 @@ where // TODO(tarcieri): validate `sec1_private_key.params`? if let Some(pk_bytes) = sec1_private_key.public_key { - let pk = sec1::EncodedPoint::::from_bytes(pk_bytes) + let pk = EncodedPoint::::from_bytes(pk_bytes) .map_err(|_| der::Tag::BitString.value_error())?; if C::validate_public_key(&secret_key, &pk).is_err() { diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs index 08d69198f..9a8d09539 100644 --- a/elliptic-curve/src/secret_key/pkcs8.rs +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -2,12 +2,14 @@ use super::SecretKey; use crate::{ - sec1::{EcPrivateKey, UncompressedPointSize, UntaggedPointSize, ValidatePublicKey}, + sec1::{UncompressedPointSize, UntaggedPointSize, ValidatePublicKey}, AlgorithmParameters, PrimeCurve, ALGORITHM_OID, }; use core::{convert::TryFrom, ops::Add}; +use der::Decodable; use generic_array::{typenum::U1, ArrayLength}; -use pkcs8::{der::Decodable, FromPrivateKey}; +use pkcs8::FromPrivateKey; +use sec1::EcPrivateKey; // Imports for the `ToPrivateKey` impl // TODO(tarcieri): use weak activation of `pkcs8/alloc` for gating `ToPrivateKey` impl From 259193dd05089f2626ac6a87460f21ac206a4d12 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 17 Sep 2021 08:04:29 -0600 Subject: [PATCH 0621/1461] signature: add LICENSE-APACHE and LICENSE-MIT (#767) Closes #766 --- signature/LICENSE-APACHE | 201 +++++++++++++++++++++++++++++++++++++++ signature/LICENSE-MIT | 25 +++++ 2 files changed, 226 insertions(+) create mode 100644 signature/LICENSE-APACHE create mode 100644 signature/LICENSE-MIT diff --git a/signature/LICENSE-APACHE b/signature/LICENSE-APACHE new file mode 100644 index 000000000..78173fa2e --- /dev/null +++ b/signature/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/signature/LICENSE-MIT b/signature/LICENSE-MIT new file mode 100644 index 000000000..fd43f17de --- /dev/null +++ b/signature/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2018-2021 RustCrypto Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. From 35321fb62406d26039343931d66fc8d4a831360b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Sep 2021 19:52:49 -0600 Subject: [PATCH 0622/1461] build(deps): bump pem-rfc7468 from 0.2.1 to 0.2.2 (#769) Bumps [pem-rfc7468](https://github.com/RustCrypto/formats) from 0.2.1 to 0.2.2. - [Release notes](https://github.com/RustCrypto/formats/releases) - [Commits](https://github.com/RustCrypto/formats/compare/pem-rfc7468/v0.2.1...pem-rfc7468/v0.2.2) --- updated-dependencies: - dependency-name: pem-rfc7468 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 26a4bc288..3d15e331c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -335,9 +335,9 @@ dependencies = [ [[package]] name = "pem-rfc7468" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ca8e0557253e074b4b42a32959384bca4fa69e40680032dba133baeed6cafd5" +checksum = "e71fb2d401a15271d52aade6d9410fb4ead603a86da5503f92e872e1df790265" dependencies = [ "base64ct", ] From 55a1af7a3ad1088dbfd26c4add473017a05088b5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Sep 2021 19:52:58 -0600 Subject: [PATCH 0623/1461] build(deps): bump crypto-bigint from 0.2.8 to 0.2.9 (#770) Bumps [crypto-bigint](https://github.com/RustCrypto/crypto-bigint) from 0.2.8 to 0.2.9. - [Release notes](https://github.com/RustCrypto/crypto-bigint/releases) - [Changelog](https://github.com/RustCrypto/crypto-bigint/blob/master/CHANGELOG.md) - [Commits](https://github.com/RustCrypto/crypto-bigint/compare/v0.2.8...v0.2.9) --- updated-dependencies: - dependency-name: crypto-bigint dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3d15e331c..a8d751281 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -145,9 +145,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43b0ca41e2a75a407a44812f110ecd40e1efacb8993f612746491e12d5b929fe" +checksum = "51e7ef8604ba15f1ea2cef61e17577e630ee39aef7f94305d138dbf1a216ada3" dependencies = [ "generic-array", "rand_core", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 44d7714f8..47b3c74d4 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -15,7 +15,7 @@ categories = ["cryptography", "no-std"] keywords = ["crypto", "ecc", "elliptic", "weierstrass"] [dependencies] -crypto-bigint = { version = "0.2.7", features = ["generic-array", "zeroize"] } +crypto-bigint = { version = "0.2.9", features = ["generic-array", "zeroize"] } der = { version = "0.4.3", default-features = false, features = ["oid"] } generic-array = { version = "0.14", default-features = false } rand_core = { version = "0.6", default-features = false } From 5251de66e4f9f74c6659b111cacfb78a70b85e4a Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 19 Sep 2021 12:52:38 -0600 Subject: [PATCH 0624/1461] elliptic-curve: use `sec1` crate's `EncodedPoint` (#771) The `EncodedPoint` type was extracted to the `sec1` crate in: https://github.com/RustCrypto/formats/pull/45 This switches the `elliptic-curve` to using the newly extracted implementation. This was a bit tricky/invasive as now `EncodedPoint` now only knows a size and not the rest of the details of the curve. APIs that were previously heavily leveraging `EncodedPoint` should probably switch to the `PublicKey` type instead unless they are specifically intending to work with SEC1-encoded points. --- .github/workflows/elliptic-curve.yml | 3 +- Cargo.lock | 7 +- elliptic-curve/src/arithmetic.rs | 2 + elliptic-curve/src/error.rs | 2 +- elliptic-curve/src/jwk.rs | 191 +++---- elliptic-curve/src/lib.rs | 2 + elliptic-curve/src/public_key.rs | 167 ++---- elliptic-curve/src/sec1.rs | 30 +- elliptic-curve/src/sec1/encoded_point.rs | 669 ----------------------- elliptic-curve/src/secret_key.rs | 37 +- elliptic-curve/src/secret_key/pkcs8.rs | 16 +- 11 files changed, 158 insertions(+), 968 deletions(-) delete mode 100644 elliptic-curve/src/sec1/encoded_point.rs diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index 9fbd2fc33..a13f67280 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -46,7 +46,8 @@ jobs: - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features pkcs8 - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features sec1 - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features pkcs8,sec1 - - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features ecdh,hazmat,jwk,pem,sec1 + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features pem,pkcs8,sec1 + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features ecdh,hazmat,jwk,pem,pkcs8,sec1 test: runs-on: ubuntu-latest diff --git a/Cargo.lock b/Cargo.lock index a8d751281..4724d08f8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -118,7 +118,7 @@ dependencies = [ [[package]] name = "const-oid" version = "0.6.1" -source = "git+https://github.com/rustcrypto/formats#46a02c5e43a213e20e07af1e6bc19512c6a5fd97" +source = "git+https://github.com/rustcrypto/formats#77564c368c60486dbbdfb6e8ab6b1ec9f79aba62" [[package]] name = "cpufeatures" @@ -188,7 +188,7 @@ dependencies = [ [[package]] name = "der" version = "0.4.3" -source = "git+https://github.com/rustcrypto/formats#46a02c5e43a213e20e07af1e6bc19512c6a5fd97" +source = "git+https://github.com/rustcrypto/formats#77564c368c60486dbbdfb6e8ab6b1ec9f79aba62" dependencies = [ "const-oid", ] @@ -396,9 +396,10 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "sec1" version = "0.0.0" -source = "git+https://github.com/rustcrypto/formats#46a02c5e43a213e20e07af1e6bc19512c6a5fd97" +source = "git+https://github.com/rustcrypto/formats#77564c368c60486dbbdfb6e8ab6b1ec9f79aba62" dependencies = [ "der", + "generic-array", "zeroize", ] diff --git a/elliptic-curve/src/arithmetic.rs b/elliptic-curve/src/arithmetic.rs index b43c3b8a2..341982c14 100644 --- a/elliptic-curve/src/arithmetic.rs +++ b/elliptic-curve/src/arithmetic.rs @@ -17,6 +17,8 @@ pub trait AffineArithmetic: Curve + ScalarArithmetic { + Debug + Default + DefaultIsZeroes + + Eq + + PartialEq + Sized + Send + Sync; diff --git a/elliptic-curve/src/error.rs b/elliptic-curve/src/error.rs index e579601f0..916295603 100644 --- a/elliptic-curve/src/error.rs +++ b/elliptic-curve/src/error.rs @@ -2,7 +2,7 @@ use core::fmt::{self, Display}; -/// Result type. +/// Result type with the `elliptic-curve` crate's [`Error`] type. pub type Result = core::result::Result; /// Elliptic curve errors. diff --git a/elliptic-curve/src/jwk.rs b/elliptic-curve/src/jwk.rs index 6d10e843f..ba4827cda 100644 --- a/elliptic-curve/src/jwk.rs +++ b/elliptic-curve/src/jwk.rs @@ -4,11 +4,9 @@ //! use crate::{ - sec1::{ - Coordinates, EncodedPoint, UncompressedPointSize, UntaggedPointSize, ValidatePublicKey, - }, + sec1::{Coordinates, EncodedPoint, ModulusSize, ValidatePublicKey}, secret_key::SecretKey, - Curve, Error, FieldBytes, PrimeCurve, + Curve, Error, FieldBytes, FieldSize, PrimeCurve, Result, }; use alloc::{ borrow::ToOwned, @@ -20,10 +18,8 @@ use core::{ convert::{TryFrom, TryInto}, fmt::{self, Debug}, marker::PhantomData, - ops::Add, str::{self, FromStr}, }; -use generic_array::{typenum::U1, ArrayLength}; use serde::{de, ser, Deserialize, Serialize}; use zeroize::Zeroize; @@ -116,24 +112,54 @@ impl JwkEcKey { /// Decode a JWK into a [`PublicKey`]. #[cfg(feature = "arithmetic")] #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] - pub fn to_public_key(&self) -> Result, Error> + pub fn to_public_key(&self) -> Result> where C: PrimeCurve + JwkParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + FieldSize: ModulusSize, { - self.try_into() + PublicKey::from_sec1_bytes(self.to_encoded_point::()?.as_bytes()) + } + + /// Create a JWK from a SEC1 [`EncodedPoint`]. + pub fn from_encoded_point(point: &EncodedPoint) -> Option + where + C: PrimeCurve + JwkParameters, + FieldSize: ModulusSize, + { + match point.coordinates() { + Coordinates::Uncompressed { x, y } => Some(JwkEcKey { + crv: C::CRV.to_owned(), + x: Base64Url::encode_string(x), + y: Base64Url::encode_string(y), + d: None, + }), + _ => None, + } + } + + /// Get the public key component of this JWK as a SEC1 [`EncodedPoint`]. + pub fn to_encoded_point(&self) -> Result> + where + C: PrimeCurve + JwkParameters, + FieldSize: ModulusSize, + { + if self.crv != C::CRV { + return Err(Error); + } + + let x = decode_base64url_fe::(&self.x)?; + let y = decode_base64url_fe::(&self.y)?; + Ok(EncodedPoint::::from_affine_coordinates(&x, &y, false)) } /// Decode a JWK into a [`SecretKey`]. #[cfg(feature = "arithmetic")] #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] - pub fn to_secret_key(&self) -> Result, Error> + pub fn to_secret_key(&self) -> Result> where C: PrimeCurve + JwkParameters + ValidatePublicKey, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + FieldSize: ModulusSize, { self.try_into() } @@ -142,7 +168,7 @@ impl JwkEcKey { impl FromStr for JwkEcKey { type Err = Error; - fn from_str(s: &str) -> Result { + fn from_str(s: &str) -> Result { serde_json::from_str(s).map_err(|_| Error) } } @@ -153,73 +179,16 @@ impl ToString for JwkEcKey { } } -#[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] -impl TryFrom for EncodedPoint -where - C: PrimeCurve + JwkParameters, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, -{ - type Error = Error; - - fn try_from(jwk: JwkEcKey) -> Result, Error> { - (&jwk).try_into() - } -} - -#[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] -impl TryFrom<&JwkEcKey> for EncodedPoint -where - C: PrimeCurve + JwkParameters, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, -{ - type Error = Error; - - fn try_from(jwk: &JwkEcKey) -> Result, Error> { - if jwk.crv != C::CRV { - return Err(Error); - } - - let x = decode_base64url_fe::(&jwk.x)?; - let y = decode_base64url_fe::(&jwk.y)?; - Ok(EncodedPoint::from_affine_coordinates(&x, &y, false)) - } -} - -#[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] -impl TryFrom> for JwkEcKey -where - C: PrimeCurve + JwkParameters, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, -{ - type Error = Error; - - fn try_from(point: EncodedPoint) -> Result { - (&point).try_into() - } -} - -#[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] -impl TryFrom<&EncodedPoint> for JwkEcKey +#[cfg(feature = "arithmetic")] +#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] +impl FromEncodedPoint for JwkEcKey where - C: PrimeCurve + JwkParameters, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + C: PrimeCurve + JwkParameters + ProjectiveArithmetic, + AffinePoint: FromEncodedPoint + ToEncodedPoint, + FieldSize: ModulusSize, { - type Error = Error; - - fn try_from(point: &EncodedPoint) -> Result { - match point.coordinates() { - Coordinates::Uncompressed { x, y } => Ok(JwkEcKey { - crv: C::CRV.to_owned(), - x: Base64Url::encode_string(x), - y: Base64Url::encode_string(y), - d: None, - }), - _ => Err(Error), - } + fn from_encoded_point(point: &EncodedPoint) -> Option { + Self::from_encoded_point::(point) } } @@ -227,12 +196,11 @@ where impl TryFrom for SecretKey where C: PrimeCurve + JwkParameters + ValidatePublicKey, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + FieldSize: ModulusSize, { type Error = Error; - fn try_from(jwk: JwkEcKey) -> Result, Error> { + fn try_from(jwk: JwkEcKey) -> Result> { (&jwk).try_into() } } @@ -241,14 +209,13 @@ where impl TryFrom<&JwkEcKey> for SecretKey where C: PrimeCurve + JwkParameters + ValidatePublicKey, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + FieldSize: ModulusSize, { type Error = Error; - fn try_from(jwk: &JwkEcKey) -> Result, Error> { + fn try_from(jwk: &JwkEcKey) -> Result> { if let Some(d_base64) = &jwk.d { - let pk = EncodedPoint::::try_from(jwk)?; + let pk = jwk.to_encoded_point::()?; let mut d_bytes = decode_base64url_fe::(d_base64)?; let result = SecretKey::from_be_bytes(&d_bytes); d_bytes.zeroize(); @@ -270,8 +237,7 @@ impl From> for JwkEcKey where C: PrimeCurve + JwkParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + FieldSize: ModulusSize, { fn from(sk: SecretKey) -> JwkEcKey { (&sk).into() @@ -285,8 +251,7 @@ impl From<&SecretKey> for JwkEcKey where C: PrimeCurve + JwkParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + FieldSize: ModulusSize, { fn from(sk: &SecretKey) -> JwkEcKey { let mut jwk = sk.public_key().to_jwk(); @@ -304,12 +269,11 @@ impl TryFrom for PublicKey where C: PrimeCurve + JwkParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + FieldSize: ModulusSize, { type Error = Error; - fn try_from(jwk: JwkEcKey) -> Result, Error> { + fn try_from(jwk: JwkEcKey) -> Result> { (&jwk).try_into() } } @@ -321,13 +285,12 @@ impl TryFrom<&JwkEcKey> for PublicKey where C: PrimeCurve + JwkParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + FieldSize: ModulusSize, { type Error = Error; - fn try_from(jwk: &JwkEcKey) -> Result, Error> { - EncodedPoint::::try_from(jwk).and_then(PublicKey::try_from) + fn try_from(jwk: &JwkEcKey) -> Result> { + PublicKey::from_sec1_bytes(jwk.to_encoded_point::()?.as_bytes()) } } @@ -338,8 +301,7 @@ impl From> for JwkEcKey where C: PrimeCurve + JwkParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + FieldSize: ModulusSize, { fn from(pk: PublicKey) -> JwkEcKey { (&pk).into() @@ -353,13 +315,10 @@ impl From<&PublicKey> for JwkEcKey where C: PrimeCurve + JwkParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + FieldSize: ModulusSize, { fn from(pk: &PublicKey) -> JwkEcKey { - pk.to_encoded_point(false) - .try_into() - .expect("JWK encoding error") + Self::from_encoded_point::(&pk.to_encoded_point(false)).expect("JWK encoding error") } } @@ -415,7 +374,7 @@ impl Zeroize for JwkEcKey { } impl<'de> Deserialize<'de> for JwkEcKey { - fn deserialize(deserializer: D) -> Result + fn deserialize(deserializer: D) -> core::result::Result where D: de::Deserializer<'de>, { @@ -438,7 +397,7 @@ impl<'de> Deserialize<'de> for JwkEcKey { fmt::Formatter::write_str(formatter, "field identifier") } - fn visit_u64(self, value: u64) -> Result + fn visit_u64(self, value: u64) -> core::result::Result where E: de::Error, { @@ -455,14 +414,14 @@ impl<'de> Deserialize<'de> for JwkEcKey { } } - fn visit_str(self, value: &str) -> Result + fn visit_str(self, value: &str) -> core::result::Result where E: de::Error, { self.visit_bytes(value.as_bytes()) } - fn visit_bytes(self, value: &[u8]) -> Result + fn visit_bytes(self, value: &[u8]) -> core::result::Result where E: de::Error, { @@ -482,7 +441,7 @@ impl<'de> Deserialize<'de> for JwkEcKey { impl<'de> Deserialize<'de> for Field { #[inline] - fn deserialize(__deserializer: D) -> Result + fn deserialize(__deserializer: D) -> core::result::Result where D: de::Deserializer<'de>, { @@ -503,7 +462,7 @@ impl<'de> Deserialize<'de> for JwkEcKey { } #[inline] - fn visit_seq(self, mut seq: A) -> Result + fn visit_seq(self, mut seq: A) -> core::result::Result where A: de::SeqAccess<'de>, { @@ -530,7 +489,7 @@ impl<'de> Deserialize<'de> for JwkEcKey { } #[inline] - fn visit_map(self, mut map: A) -> Result + fn visit_map(self, mut map: A) -> core::result::Result where A: de::MapAccess<'de>, { @@ -607,7 +566,7 @@ impl<'de> Deserialize<'de> for JwkEcKey { } impl Serialize for JwkEcKey { - fn serialize(&self, serializer: S) -> Result + fn serialize(&self, serializer: S) -> core::result::Result where S: ser::Serializer, { @@ -628,7 +587,7 @@ impl Serialize for JwkEcKey { } /// Decode a Base64url-encoded field element -fn decode_base64url_fe(s: &str) -> Result, Error> { +fn decode_base64url_fe(s: &str) -> Result> { let mut result = FieldBytes::::default(); Base64Url::decode(s, &mut result).map_err(|_| Error)?; Ok(result) @@ -724,7 +683,7 @@ mod tests { #[test] fn jwk_into_encoded_point() { let jwk = JwkEcKey::from_str(JWK_PUBLIC_KEY).unwrap(); - let point = EncodedPoint::::try_from(&jwk).unwrap(); + let point = jwk.to_encoded_point::().unwrap(); let (x, y) = match point.coordinates() { Coordinates::Uncompressed { x, y } => (x, y), other => panic!("unexpected coordinates: {:?}", other), @@ -738,8 +697,8 @@ mod tests { #[test] fn encoded_point_into_jwk() { let jwk = JwkEcKey::from_str(JWK_PUBLIC_KEY).unwrap(); - let point = EncodedPoint::::try_from(&jwk).unwrap(); - let jwk2 = JwkEcKey::try_from(point).unwrap(); + let point = jwk.to_encoded_point::().unwrap(); + let jwk2 = JwkEcKey::from_encoded_point::(&point).unwrap(); assert_eq!(jwk, jwk2); } } diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 4d6441c32..345ab5603 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -32,6 +32,8 @@ extern crate std; pub use rand_core; pub mod ops; + +#[cfg(feature = "sec1")] pub mod sec1; mod error; diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index 11ec37642..72e9f42a3 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -1,27 +1,15 @@ //! Elliptic curve public keys. use crate::{ - consts::U1, - point::PointCompression, - sec1::{ - EncodedPoint, FromEncodedPoint, ToEncodedPoint, UncompressedPointSize, UntaggedPointSize, - }, - AffinePoint, Curve, Error, NonZeroScalar, PrimeCurve, ProjectiveArithmetic, ProjectivePoint, - Result, -}; -use core::{ - cmp::Ordering, - convert::{TryFrom, TryInto}, - fmt::Debug, - ops::Add, + AffinePoint, Curve, Error, NonZeroScalar, ProjectiveArithmetic, ProjectivePoint, Result, }; -use generic_array::ArrayLength; +use core::fmt::Debug; use group::{Curve as _, Group}; #[cfg(feature = "jwk")] use crate::{JwkEcKey, JwkParameters}; -#[cfg(feature = "pkcs8")] +#[cfg(all(feature = "sec1", feature = "pkcs8"))] use { crate::{AlgorithmParameters, ALGORITHM_OID}, pkcs8::FromPublicKey, @@ -30,6 +18,15 @@ use { #[cfg(feature = "pem")] use {core::str::FromStr, pkcs8::ToPublicKey}; +#[cfg(feature = "sec1")] +use { + crate::{ + sec1::{EncodedPoint, FromEncodedPoint, ModulusSize, ToEncodedPoint}, + FieldSize, PrimeCurve, + }, + core::cmp::Ordering, +}; + #[cfg(any(feature = "jwk", feature = "pem"))] use alloc::string::{String, ToString}; @@ -60,7 +57,7 @@ use alloc::string::{String, ToString}; /// When the `pem` feature of this crate (or a specific RustCrypto elliptic /// curve crate) is enabled, a [`FromStr`] impl is also available. #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Eq, PartialEq)] pub struct PublicKey where C: Curve + ProjectiveArithmetic, @@ -96,16 +93,15 @@ where /// 2.3.3 (page 10). /// /// + #[cfg(feature = "sec1")] pub fn from_sec1_bytes(bytes: &[u8]) -> Result where - Self: TryFrom, Error = Error>, C: PrimeCurve, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + FieldSize: ModulusSize, + AffinePoint: FromEncodedPoint + ToEncodedPoint, { - EncodedPoint::from_bytes(bytes) - .map_err(|_| Error) - .and_then(TryInto::try_into) + let point = EncodedPoint::::from_bytes(bytes).map_err(|_| Error)?; + Self::from_encoded_point(&point).ok_or(Error) } /// Borrow the inner [`AffinePoint`] from this [`PublicKey`]. @@ -127,10 +123,9 @@ where where C: PrimeCurve + JwkParameters, AffinePoint: FromEncodedPoint + ToEncodedPoint, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + FieldSize: ModulusSize, { - jwk.try_into() + jwk.to_public_key::() } /// Parse a string containing a JSON Web Key (JWK) into a [`PublicKey`]. @@ -140,8 +135,7 @@ where where C: PrimeCurve + JwkParameters, AffinePoint: FromEncodedPoint + ToEncodedPoint, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + FieldSize: ModulusSize, { jwk.parse::().and_then(|jwk| Self::from_jwk(&jwk)) } @@ -153,8 +147,7 @@ where where C: PrimeCurve + JwkParameters, AffinePoint: FromEncodedPoint + ToEncodedPoint, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + FieldSize: ModulusSize, { self.into() } @@ -166,8 +159,7 @@ where where C: PrimeCurve + JwkParameters, AffinePoint: FromEncodedPoint + ToEncodedPoint, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + FieldSize: ModulusSize, { self.to_jwk().to_string() } @@ -184,64 +176,13 @@ where impl Copy for PublicKey where C: Curve + ProjectiveArithmetic {} -impl TryFrom> for PublicKey -where - C: PrimeCurve + ProjectiveArithmetic, - AffinePoint: FromEncodedPoint + ToEncodedPoint, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, -{ - type Error = Error; - - fn try_from(encoded_point: EncodedPoint) -> Result { - encoded_point.decode() - } -} - -impl TryFrom<&EncodedPoint> for PublicKey -where - C: PrimeCurve + ProjectiveArithmetic, - AffinePoint: FromEncodedPoint + ToEncodedPoint, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, -{ - type Error = Error; - - fn try_from(encoded_point: &EncodedPoint) -> Result { - encoded_point.decode() - } -} - -impl From> for EncodedPoint -where - C: PrimeCurve + ProjectiveArithmetic + PointCompression, - AffinePoint: FromEncodedPoint + ToEncodedPoint, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, -{ - fn from(public_key: PublicKey) -> EncodedPoint { - EncodedPoint::::from(&public_key) - } -} - -impl From<&PublicKey> for EncodedPoint -where - C: PrimeCurve + ProjectiveArithmetic + PointCompression, - AffinePoint: FromEncodedPoint + ToEncodedPoint, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, -{ - fn from(public_key: &PublicKey) -> EncodedPoint { - public_key.to_encoded_point(C::COMPRESS_POINTS) - } -} - +#[cfg(feature = "sec1")] +#[cfg_attr(docsrs, doc(cfg(feature = "sec1")))] impl FromEncodedPoint for PublicKey where C: PrimeCurve + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + FieldSize: ModulusSize, { /// Initialize [`PublicKey`] from an [`EncodedPoint`] fn from_encoded_point(encoded_point: &EncodedPoint) -> Option { @@ -250,12 +191,13 @@ where } } +#[cfg(feature = "sec1")] +#[cfg_attr(docsrs, doc(cfg(feature = "sec1")))] impl ToEncodedPoint for PublicKey where C: PrimeCurve + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + FieldSize: ModulusSize, { /// Serialize this [`PublicKey`] as a SEC1 [`EncodedPoint`], optionally applying /// point compression @@ -264,45 +206,26 @@ where } } -impl Eq for PublicKey -where - C: PrimeCurve + ProjectiveArithmetic, - AffinePoint: FromEncodedPoint + ToEncodedPoint, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, -{ -} - -impl PartialEq for PublicKey -where - C: PrimeCurve + ProjectiveArithmetic, - AffinePoint: FromEncodedPoint + ToEncodedPoint, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, -{ - fn eq(&self, other: &Self) -> bool { - self.cmp(other) == Ordering::Equal - } -} - +#[cfg(feature = "sec1")] +#[cfg_attr(docsrs, doc(cfg(feature = "sec1")))] impl PartialOrd for PublicKey where C: PrimeCurve + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + FieldSize: ModulusSize, { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } +#[cfg(feature = "sec1")] +#[cfg_attr(docsrs, doc(cfg(feature = "sec1")))] impl Ord for PublicKey where C: PrimeCurve + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + FieldSize: ModulusSize, { fn cmp(&self, other: &Self) -> Ordering { // TODO(tarcieri): more efficient implementation? @@ -312,14 +235,13 @@ where } } -#[cfg(feature = "pkcs8")] -#[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))] +#[cfg(all(feature = "pkcs8", feature = "sec1"))] +#[cfg_attr(docsrs, doc(cfg(all(feature = "pkcs8", feature = "sec1"))))] impl FromPublicKey for PublicKey where - Self: TryFrom, Error = Error>, C: PrimeCurve + AlgorithmParameters + ProjectiveArithmetic, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + AffinePoint: FromEncodedPoint + ToEncodedPoint, + FieldSize: ModulusSize, { fn from_spki(spki: pkcs8::SubjectPublicKeyInfo<'_>) -> pkcs8::Result { if spki.algorithm.oid != ALGORITHM_OID { @@ -346,8 +268,7 @@ impl ToPublicKey for PublicKey where C: PrimeCurve + AlgorithmParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + FieldSize: ModulusSize, { fn to_public_key_der(&self) -> pkcs8::Result { let public_key_bytes = self.to_encoded_point(false); @@ -364,10 +285,9 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "pem")))] impl FromStr for PublicKey where - Self: TryFrom, Error = Error>, C: PrimeCurve + AlgorithmParameters + ProjectiveArithmetic, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + AffinePoint: FromEncodedPoint + ToEncodedPoint, + FieldSize: ModulusSize, { type Err = Error; @@ -382,8 +302,7 @@ impl ToString for PublicKey where C: PrimeCurve + AlgorithmParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + FieldSize: ModulusSize, { fn to_string(&self) -> String { self.to_public_key_pem().expect("PEM encoding error") diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index 81ec9cd3b..a0abd5f0d 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -2,19 +2,16 @@ //! //! -mod encoded_point; +pub use sec1::point::{Coordinates, ModulusSize, Tag}; -pub use self::encoded_point::{ - CompressedPointSize, Coordinates, EncodedPoint, Tag, UncompressedPointSize, UntaggedPointSize, -}; - -use crate::{PrimeCurve, Result, SecretKey}; -use core::ops::Add; -use generic_array::{typenum::U1, ArrayLength}; +use crate::{FieldSize, PrimeCurve, Result, SecretKey}; #[cfg(feature = "arithmetic")] use crate::{AffinePoint, Error, ProjectiveArithmetic}; +/// Encoded elliptic curve point sized appropriately for a given curve. +pub type EncodedPoint = sec1::point::EncodedPoint>; + /// Trait for deserializing a value from a SEC1 encoded curve point. /// /// This is intended for use with the `AffinePoint` type for a given elliptic curve. @@ -22,15 +19,14 @@ pub trait FromEncodedPoint where Self: Sized, C: PrimeCurve, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + FieldSize: ModulusSize, { /// Deserialize the type this trait is impl'd on from an [`EncodedPoint`]. /// /// # Returns /// /// `None` if the [`EncodedPoint`] is invalid. - fn from_encoded_point(public_key: &EncodedPoint) -> Option; + fn from_encoded_point(point: &EncodedPoint) -> Option; } /// Trait for serializing a value to a SEC1 encoded curve point. @@ -39,8 +35,7 @@ where pub trait ToEncodedPoint where C: PrimeCurve, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + FieldSize: ModulusSize, { /// Serialize this value as a SEC1 [`EncodedPoint`], optionally applying /// point compression. @@ -53,8 +48,7 @@ where pub trait ToCompactEncodedPoint where C: PrimeCurve, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + FieldSize: ModulusSize, { /// Serialize this value as a SEC1 [`EncodedPoint`], optionally applying /// point compression. @@ -69,8 +63,7 @@ where pub trait ValidatePublicKey where Self: PrimeCurve, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + FieldSize: ModulusSize, { /// Validate that the given [`EncodedPoint`] is a valid public key for the /// provided secret value. @@ -95,8 +88,7 @@ impl ValidatePublicKey for C where C: PrimeCurve + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + FieldSize: ModulusSize, { fn validate_public_key(secret_key: &SecretKey, public_key: &EncodedPoint) -> Result<()> { let pk = secret_key diff --git a/elliptic-curve/src/sec1/encoded_point.rs b/elliptic-curve/src/sec1/encoded_point.rs deleted file mode 100644 index 28a086ff1..000000000 --- a/elliptic-curve/src/sec1/encoded_point.rs +++ /dev/null @@ -1,669 +0,0 @@ -//! SEC1 encoded point support. -//! -//! Support for the `Elliptic-Curve-Point-to-Octet-String` encoding described -//! in SEC1: Elliptic Curve Cryptography (Version 2.0) section 2.3.3 (p.10): -//! -//! - -use super::{FromEncodedPoint, ToEncodedPoint}; -use crate::{bigint::Encoding as _, Error, FieldBytes, FieldSize, PrimeCurve, Result}; -use core::{ - fmt::{self, Debug}, - ops::Add, -}; -use generic_array::{typenum::U1, ArrayLength, GenericArray}; -use subtle::{Choice, ConditionallySelectable}; -use zeroize::Zeroize; - -#[cfg(feature = "alloc")] -use alloc::boxed::Box; - -#[cfg(feature = "arithmetic")] -use crate::{AffinePoint, DecompressPoint, ProjectiveArithmetic, SecretKey}; - -#[cfg(all(feature = "arithmetic"))] -use crate::group::{Curve as _, Group}; - -/// Size of a compressed point for the given elliptic curve when encoded -/// using the SEC1 `Elliptic-Curve-Point-to-Octet-String` algorithm -/// (including leading `0x02` or `0x03` tag byte). -pub type CompressedPointSize = as Add>::Output; - -/// Size of an uncompressed point for the given elliptic curve when encoded -/// using the SEC1 `Elliptic-Curve-Point-to-Octet-String` algorithm -/// (including leading `0x04` tag byte). -pub type UncompressedPointSize = as Add>::Output; - -/// Size of an untagged point for given elliptic curve. -pub type UntaggedPointSize = as Add>::Output; - -/// SEC1 encoded curve point. -/// -/// This type is an enum over the compressed and uncompressed encodings, -/// useful for cases where either encoding can be supported, or conversions -/// between the two forms. -#[derive(Clone, Default, Eq, PartialEq, PartialOrd, Ord)] -pub struct EncodedPoint -where - C: PrimeCurve, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, -{ - bytes: GenericArray>, -} - -#[allow(clippy::len_without_is_empty)] -impl EncodedPoint -where - C: PrimeCurve, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, -{ - /// Decode elliptic curve point (compressed or uncompressed) from the - /// `Elliptic-Curve-Point-to-Octet-String` encoding described in - /// SEC 1: Elliptic Curve Cryptography (Version 2.0) section - /// 2.3.3 (page 10). - /// - /// - pub fn from_bytes(input: impl AsRef<[u8]>) -> Result { - let input = input.as_ref(); - - // Validate tag - let tag = input.first().cloned().ok_or(Error).and_then(Tag::from_u8)?; - - // Validate length - let expected_len = tag.message_len(C::UInt::BYTE_SIZE); - - if input.len() != expected_len { - return Err(Error); - } - - let mut bytes = GenericArray::default(); - bytes[..expected_len].copy_from_slice(input); - Ok(Self { bytes }) - } - - /// Decode elliptic curve point from raw uncompressed coordinates, i.e. - /// encoded as the concatenated `x || y` coordinates with no leading SEC1 - /// tag byte (which would otherwise be `0x04` for an uncompressed point). - pub fn from_untagged_bytes(bytes: &GenericArray>) -> Self { - let (x, y) = bytes.split_at(C::UInt::BYTE_SIZE); - Self::from_affine_coordinates(x.into(), y.into(), false) - } - - /// Encode an elliptic curve point from big endian serialized coordinates - /// (with optional point compression) - pub fn from_affine_coordinates(x: &FieldBytes, y: &FieldBytes, compress: bool) -> Self { - let tag = if compress { - Tag::compress_y(y.as_slice()) - } else { - Tag::Uncompressed - }; - - let mut bytes = GenericArray::default(); - bytes[0] = tag.into(); - bytes[1..(C::UInt::BYTE_SIZE + 1)].copy_from_slice(x); - - if !compress { - bytes[(C::UInt::BYTE_SIZE + 1)..].copy_from_slice(y); - } - - Self { bytes } - } - - /// Compute [`EncodedPoint`] representing the public key for the provided - /// [`SecretKey`]. - /// - /// The `compress` flag requests point compression. - #[cfg(all(feature = "arithmetic"))] - #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] - pub fn from_secret_key(secret_key: &SecretKey, compress: bool) -> Self - where - C: PrimeCurve + ProjectiveArithmetic, - AffinePoint: ToEncodedPoint, - { - (C::ProjectivePoint::generator() * secret_key.to_nonzero_scalar().as_ref()) - .to_affine() - .to_encoded_point(compress) - } - - /// Return [`EncodedPoint`] representing the additive identity - /// (a.k.a. point at infinity) - pub fn identity() -> Self { - Self::default() - } - - /// Get the length of the encoded point in bytes - pub fn len(&self) -> usize { - self.tag().message_len(C::UInt::BYTE_SIZE) - } - - /// Get byte slice containing the serialized [`EncodedPoint`]. - pub fn as_bytes(&self) -> &[u8] { - &self.bytes[..self.len()] - } - - /// Get boxed byte slice containing the serialized [`EncodedPoint`] - #[cfg(feature = "alloc")] - #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] - pub fn to_bytes(&self) -> Box<[u8]> { - self.as_bytes().to_vec().into_boxed_slice() - } - - /// Serialize point as raw uncompressed coordinates without tag byte, i.e. - /// encoded as the concatenated `x || y` coordinates. - #[cfg(feature = "arithmetic")] - #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] - pub fn to_untagged_bytes(&self) -> Option>> - where - C: PrimeCurve + ProjectiveArithmetic, - AffinePoint: DecompressPoint + ToEncodedPoint, - { - self.decompress().map(|point| { - let mut bytes = GenericArray::>::default(); - bytes.copy_from_slice(&point.as_bytes()[1..]); - bytes - }) - } - - /// Is this [`EncodedPoint`] compact? - pub fn is_compact(&self) -> bool { - self.tag().is_compact() - } - - /// Is this [`EncodedPoint`] compressed? - pub fn is_compressed(&self) -> bool { - self.tag().is_compressed() - } - - /// Is this [`EncodedPoint`] the additive identity? (a.k.a. point at infinity) - pub fn is_identity(&self) -> bool { - self.tag().is_identity() - } - - /// Compress this [`EncodedPoint`], returning a new [`EncodedPoint`]. - pub fn compress(&self) -> Self { - match self.coordinates() { - Coordinates::Compressed { .. } - | Coordinates::Compact { .. } - | Coordinates::Identity => self.clone(), - Coordinates::Uncompressed { x, y } => Self::from_affine_coordinates(x, y, true), - } - } - - /// Decompress this [`EncodedPoint`], returning a new [`EncodedPoint`]. - #[cfg(feature = "arithmetic")] - #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] - pub fn decompress(&self) -> Option - where - C: PrimeCurve + ProjectiveArithmetic, - AffinePoint: DecompressPoint + ToEncodedPoint, - { - match self.coordinates() { - Coordinates::Compressed { x, y_is_odd } => { - AffinePoint::::decompress(x, Choice::from(y_is_odd as u8)) - .map(|s| s.to_encoded_point(false)) - .into() - } - Coordinates::Compact { .. } | Coordinates::Identity => None, - Coordinates::Uncompressed { .. } => Some(self.clone()), - } - } - - /// Encode an [`EncodedPoint`] from the desired type - pub fn encode(encodable: T, compress: bool) -> Self - where - T: ToEncodedPoint, - { - encodable.to_encoded_point(compress) - } - - /// Decode this [`EncodedPoint`] into the desired type - pub fn decode(&self) -> Result - where - T: FromEncodedPoint, - { - T::from_encoded_point(self).ok_or(Error) - } - - /// Get the SEC1 tag for this [`EncodedPoint`] - pub fn tag(&self) -> Tag { - // Tag is ensured valid by the constructor - Tag::from_u8(self.bytes[0]).expect("invalid tag") - } - - /// Get the [`Coordinates`] for this [`EncodedPoint`]. - #[inline] - pub fn coordinates(&self) -> Coordinates<'_, C> { - if self.is_identity() { - return Coordinates::Identity; - } - - let (x, y) = self.bytes[1..].split_at(C::UInt::BYTE_SIZE); - - if self.is_compressed() { - Coordinates::Compressed { - x: x.into(), - y_is_odd: self.tag() as u8 & 1 == 1, - } - } else if self.is_compact() { - Coordinates::Compact { x: x.into() } - } else { - Coordinates::Uncompressed { - x: x.into(), - y: y.into(), - } - } - } - - /// Get the x-coordinate for this [`EncodedPoint`]. - /// - /// Returns `None` if this point is the identity point. - pub fn x(&self) -> Option<&FieldBytes> { - match self.coordinates() { - Coordinates::Identity => None, - Coordinates::Compressed { x, .. } => Some(x), - Coordinates::Uncompressed { x, .. } => Some(x), - Coordinates::Compact { x } => Some(x), - } - } - - /// Get the y-coordinate for this [`EncodedPoint`]. - /// - /// Returns `None` if this point is compressed or the identity point. - pub fn y(&self) -> Option<&FieldBytes> { - match self.coordinates() { - Coordinates::Compressed { .. } | Coordinates::Identity => None, - Coordinates::Uncompressed { y, .. } => Some(y), - Coordinates::Compact { .. } => None, - } - } -} - -impl AsRef<[u8]> for EncodedPoint -where - C: PrimeCurve, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, -{ - #[inline] - fn as_ref(&self) -> &[u8] { - self.as_bytes() - } -} - -impl ConditionallySelectable for EncodedPoint -where - C: PrimeCurve, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, - as ArrayLength>::ArrayType: Copy, -{ - fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { - let mut bytes = GenericArray::default(); - - for (i, byte) in bytes.iter_mut().enumerate() { - *byte = u8::conditional_select(&a.bytes[i], &b.bytes[i], choice); - } - - Self { bytes } - } -} - -impl Copy for EncodedPoint -where - C: PrimeCurve, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, - as ArrayLength>::ArrayType: Copy, -{ -} - -impl Debug for EncodedPoint -where - C: PrimeCurve, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "EncodedPoint<{:?}>({:?})", C::default(), &self.bytes) - } -} - -impl Zeroize for EncodedPoint -where - C: PrimeCurve, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, -{ - fn zeroize(&mut self) { - self.bytes.zeroize(); - *self = Self::identity(); - } -} - -/// Enum representing the coordinates of either compressed or uncompressed -/// SEC1-encoded elliptic curve points. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum Coordinates<'a, C: PrimeCurve> { - /// Identity point (a.k.a. point at infinity) - Identity, - - /// Compact curve point - Compact { - /// x-coordinate - x: &'a FieldBytes, - }, - - /// Compressed curve point - Compressed { - /// x-coordinate - x: &'a FieldBytes, - - /// Is the y-coordinate odd? - y_is_odd: bool, - }, - - /// Uncompressed curve point - Uncompressed { - /// x-coordinate - x: &'a FieldBytes, - - /// y-coordinate - y: &'a FieldBytes, - }, -} - -impl<'a, C: PrimeCurve> Coordinates<'a, C> { - /// Get the tag octet needed to encode this set of [`Coordinates`] - pub fn tag(&self) -> Tag { - match self { - Coordinates::Compact { .. } => Tag::Compact, - Coordinates::Compressed { y_is_odd, .. } => { - if *y_is_odd { - Tag::CompressedOddY - } else { - Tag::CompressedEvenY - } - } - Coordinates::Identity => Tag::Identity, - Coordinates::Uncompressed { .. } => Tag::Uncompressed, - } - } -} - -/// Tag byte used by the `Elliptic-Curve-Point-to-Octet-String` encoding. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -#[repr(u8)] -pub enum Tag { - /// Identity point (`0x00`) - Identity = 0, - - /// Compressed point with even y-coordinate (`0x02`) - CompressedEvenY = 2, - - /// Compressed point with odd y-coordinate (`0x03`) - CompressedOddY = 3, - - /// Uncompressed point (`0x04`) - Uncompressed = 4, - - /// Compact point (`0x05`) - Compact = 5, -} - -impl Tag { - /// Parse a tag value from a byte - pub fn from_u8(byte: u8) -> Result { - match byte { - 0 => Ok(Tag::Identity), - 2 => Ok(Tag::CompressedEvenY), - 3 => Ok(Tag::CompressedOddY), - 4 => Ok(Tag::Uncompressed), - 5 => Ok(Tag::Compact), - _ => Err(Error), - } - } - - /// Is this point compact? - pub fn is_compact(self) -> bool { - matches!(self, Tag::Compact) - } - - /// Is this point compressed? - pub fn is_compressed(self) -> bool { - matches!(self, Tag::CompressedEvenY | Tag::CompressedOddY) - } - - /// Is this point the identity point? - pub fn is_identity(self) -> bool { - self == Tag::Identity - } - - /// Compute the expected total message length for a message prefixed - /// with this tag (including the tag byte), given the field element size - /// (in bytes) for a particular elliptic curve. - pub fn message_len(self, field_element_size: usize) -> usize { - 1 + match self { - Tag::Identity => 0, - Tag::CompressedEvenY | Tag::CompressedOddY => field_element_size, - Tag::Uncompressed => field_element_size * 2, - Tag::Compact => field_element_size, - } - } - - /// Compress the given y-coordinate, returning a `Tag::Compressed*` value - fn compress_y(y: &[u8]) -> Self { - // Is the y-coordinate odd in the SEC1 sense: `self mod 2 == 1`? - if y.as_ref().last().expect("empty y-coordinate") & 1 == 1 { - Tag::CompressedOddY - } else { - Tag::CompressedEvenY - } - } -} - -impl From for u8 { - fn from(tag: Tag) -> u8 { - tag as u8 - } -} - -#[cfg(all(test, feature = "dev"))] -mod tests { - use super::{Coordinates, Tag}; - use crate::dev::MockCurve; - use generic_array::GenericArray; - use hex_literal::hex; - use subtle::ConditionallySelectable; - - type EncodedPoint = super::EncodedPoint; - - /// Identity point - const IDENTITY_BYTES: [u8; 1] = [0]; - - /// Example uncompressed point - const UNCOMPRESSED_BYTES: [u8; 65] = hex!("0411111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222"); - - /// Example compressed point: `UNCOMPRESSED_BYTES` after point compression - const COMPRESSED_BYTES: [u8; 33] = - hex!("021111111111111111111111111111111111111111111111111111111111111111"); - - #[test] - fn decode_compressed_point() { - // Even y-coordinate - let compressed_even_y_bytes = - hex!("020100000000000000000000000000000000000000000000000000000000000000"); - - let compressed_even_y = EncodedPoint::from_bytes(&compressed_even_y_bytes[..]).unwrap(); - - assert!(compressed_even_y.is_compressed()); - assert_eq!(compressed_even_y.tag(), Tag::CompressedEvenY); - assert_eq!(compressed_even_y.len(), 33); - assert_eq!(compressed_even_y.as_bytes(), &compressed_even_y_bytes[..]); - - assert_eq!( - compressed_even_y.coordinates(), - Coordinates::Compressed { - x: &hex!("0100000000000000000000000000000000000000000000000000000000000000").into(), - y_is_odd: false - } - ); - - assert_eq!( - compressed_even_y.x().unwrap(), - &hex!("0100000000000000000000000000000000000000000000000000000000000000").into() - ); - assert_eq!(compressed_even_y.y(), None); - - // Odd y-coordinate - let compressed_odd_y_bytes = - hex!("030200000000000000000000000000000000000000000000000000000000000000"); - - let compressed_odd_y = EncodedPoint::from_bytes(&compressed_odd_y_bytes[..]).unwrap(); - - assert!(compressed_odd_y.is_compressed()); - assert_eq!(compressed_odd_y.tag(), Tag::CompressedOddY); - assert_eq!(compressed_odd_y.len(), 33); - assert_eq!(compressed_odd_y.as_bytes(), &compressed_odd_y_bytes[..]); - - assert_eq!( - compressed_odd_y.coordinates(), - Coordinates::Compressed { - x: &hex!("0200000000000000000000000000000000000000000000000000000000000000").into(), - y_is_odd: true - } - ); - - assert_eq!( - compressed_odd_y.x().unwrap(), - &hex!("0200000000000000000000000000000000000000000000000000000000000000").into() - ); - assert_eq!(compressed_odd_y.y(), None); - } - - #[test] - fn decode_uncompressed_point() { - let uncompressed_point = EncodedPoint::from_bytes(&UNCOMPRESSED_BYTES[..]).unwrap(); - - assert!(!uncompressed_point.is_compressed()); - assert_eq!(uncompressed_point.tag(), Tag::Uncompressed); - assert_eq!(uncompressed_point.len(), 65); - assert_eq!(uncompressed_point.as_bytes(), &UNCOMPRESSED_BYTES[..]); - - assert_eq!( - uncompressed_point.coordinates(), - Coordinates::Uncompressed { - x: &hex!("1111111111111111111111111111111111111111111111111111111111111111").into(), - y: &hex!("2222222222222222222222222222222222222222222222222222222222222222").into() - } - ); - - assert_eq!( - uncompressed_point.x().unwrap(), - &hex!("1111111111111111111111111111111111111111111111111111111111111111").into() - ); - assert_eq!( - uncompressed_point.y().unwrap(), - &hex!("2222222222222222222222222222222222222222222222222222222222222222").into() - ); - } - - #[test] - fn decode_identity() { - let identity_point = EncodedPoint::from_bytes(&IDENTITY_BYTES[..]).unwrap(); - assert!(identity_point.is_identity()); - assert_eq!(identity_point.tag(), Tag::Identity); - assert_eq!(identity_point.len(), 1); - assert_eq!(identity_point.as_bytes(), &IDENTITY_BYTES[..]); - assert_eq!(identity_point.coordinates(), Coordinates::Identity); - assert_eq!(identity_point.x(), None); - assert_eq!(identity_point.y(), None); - } - - #[test] - fn decode_invalid_tag() { - let mut compressed_bytes = COMPRESSED_BYTES.clone(); - let mut uncompressed_bytes = UNCOMPRESSED_BYTES.clone(); - - for bytes in &mut [&mut compressed_bytes[..], &mut uncompressed_bytes[..]] { - for tag in 0..=0xFF { - // valid tags - if tag == 2 || tag == 3 || tag == 4 || tag == 5 { - continue; - } - - (*bytes)[0] = tag; - let decode_result = EncodedPoint::from_bytes(&*bytes); - assert!(decode_result.is_err()); - } - } - } - - #[test] - fn decode_truncated_point() { - for bytes in &[&COMPRESSED_BYTES[..], &UNCOMPRESSED_BYTES[..]] { - for len in 0..bytes.len() { - let decode_result = EncodedPoint::from_bytes(&bytes[..len]); - assert!(decode_result.is_err()); - } - } - } - - #[test] - fn from_untagged_point() { - let untagged_bytes = hex!("11111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222"); - let uncompressed_point = - EncodedPoint::from_untagged_bytes(GenericArray::from_slice(&untagged_bytes[..])); - assert_eq!(uncompressed_point.as_bytes(), &UNCOMPRESSED_BYTES[..]); - } - - #[test] - fn from_affine_coordinates() { - let x = hex!("1111111111111111111111111111111111111111111111111111111111111111"); - let y = hex!("2222222222222222222222222222222222222222222222222222222222222222"); - - let uncompressed_point = EncodedPoint::from_affine_coordinates(&x.into(), &y.into(), false); - assert_eq!(uncompressed_point.as_bytes(), &UNCOMPRESSED_BYTES[..]); - - let compressed_point = EncodedPoint::from_affine_coordinates(&x.into(), &y.into(), true); - assert_eq!(compressed_point.as_bytes(), &COMPRESSED_BYTES[..]); - } - - #[test] - fn compress() { - let uncompressed_point = EncodedPoint::from_bytes(&UNCOMPRESSED_BYTES[..]).unwrap(); - let compressed_point = uncompressed_point.compress(); - assert_eq!(compressed_point.as_bytes(), &COMPRESSED_BYTES[..]); - } - - #[test] - fn conditional_select() { - let a = EncodedPoint::from_bytes(&COMPRESSED_BYTES[..]).unwrap(); - let b = EncodedPoint::from_bytes(&UNCOMPRESSED_BYTES[..]).unwrap(); - - let a_selected = EncodedPoint::conditional_select(&a, &b, 0.into()); - assert_eq!(a, a_selected); - - let b_selected = EncodedPoint::conditional_select(&a, &b, 1.into()); - assert_eq!(b, b_selected); - } - - #[test] - fn identity() { - let identity_point = EncodedPoint::identity(); - assert_eq!(identity_point.tag(), Tag::Identity); - assert_eq!(identity_point.len(), 1); - assert_eq!(identity_point.as_bytes(), &IDENTITY_BYTES[..]); - - // identity is default - assert_eq!(identity_point, EncodedPoint::default()); - } - - #[cfg(feature = "alloc")] - #[test] - fn to_bytes() { - let uncompressed_point = EncodedPoint::from_bytes(&UNCOMPRESSED_BYTES[..]).unwrap(); - assert_eq!(&*uncompressed_point.to_bytes(), &UNCOMPRESSED_BYTES[..]); - } -} diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 947f62fe9..ae38c8d9d 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -49,14 +49,10 @@ use pem_rfc7468 as pem; #[cfg(feature = "sec1")] use { crate::{ - sec1::{EncodedPoint, UncompressedPointSize, UntaggedPointSize, ValidatePublicKey}, - PrimeCurve, + sec1::{EncodedPoint, ModulusSize, ValidatePublicKey}, + FieldSize, PrimeCurve, }, - core::{ - convert::{TryFrom, TryInto}, - ops::Add, - }, - generic_array::{typenum::U1, ArrayLength}, + core::convert::{TryFrom, TryInto}, }; #[cfg(all(docsrs, feature = "pkcs8"))] @@ -184,8 +180,7 @@ where pub fn from_sec1_der(der_bytes: &[u8]) -> Result where C: PrimeCurve + ValidatePublicKey, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + FieldSize: ModulusSize, { sec1::EcPrivateKey::try_from(der_bytes)? .try_into() @@ -202,8 +197,7 @@ where where C: PrimeCurve + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + FieldSize: ModulusSize, { // TODO(tarcieri): wrap `secret_key_bytes` in `Zeroizing` let mut private_key_bytes = self.to_be_bytes(); @@ -236,8 +230,7 @@ where pub fn from_sec1_pem(s: &str) -> Result where C: PrimeCurve + ValidatePublicKey, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + FieldSize: ModulusSize, { let (label, der_bytes) = pem::decode_vec(s.as_bytes()).map_err(|_| Error)?; @@ -258,8 +251,7 @@ where where C: PrimeCurve + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + FieldSize: ModulusSize, { self.to_sec1_der() .ok() @@ -274,8 +266,7 @@ where pub fn from_jwk(jwk: &JwkEcKey) -> Result where C: JwkParameters + ValidatePublicKey, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + FieldSize: ModulusSize, { Self::try_from(jwk) } @@ -286,8 +277,7 @@ where pub fn from_jwk_str(jwk: &str) -> Result where C: JwkParameters + ValidatePublicKey, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + FieldSize: ModulusSize, { jwk.parse::().and_then(|jwk| Self::from_jwk(&jwk)) } @@ -300,8 +290,7 @@ where where C: PrimeCurve + JwkParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + FieldSize: ModulusSize, { self.into() } @@ -314,8 +303,7 @@ where where C: PrimeCurve + JwkParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + FieldSize: ModulusSize, { Zeroizing::new(self.to_jwk().to_string()) } @@ -365,8 +353,7 @@ where impl TryFrom> for SecretKey where C: PrimeCurve + ValidatePublicKey, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + FieldSize: ModulusSize, { type Error = der::Error; diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs index 9a8d09539..24ecfbb14 100644 --- a/elliptic-curve/src/secret_key/pkcs8.rs +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -2,12 +2,11 @@ use super::SecretKey; use crate::{ - sec1::{UncompressedPointSize, UntaggedPointSize, ValidatePublicKey}, - AlgorithmParameters, PrimeCurve, ALGORITHM_OID, + sec1::{ModulusSize, ValidatePublicKey}, + AlgorithmParameters, FieldSize, PrimeCurve, ALGORITHM_OID, }; -use core::{convert::TryFrom, ops::Add}; +use core::convert::TryFrom; use der::Decodable; -use generic_array::{typenum::U1, ArrayLength}; use pkcs8::FromPrivateKey; use sec1::EcPrivateKey; @@ -33,8 +32,7 @@ use { impl FromPrivateKey for SecretKey where C: PrimeCurve + AlgorithmParameters + ValidatePublicKey, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + FieldSize: ModulusSize, { fn from_pkcs8_private_key_info( private_key_info: pkcs8::PrivateKeyInfo<'_>, @@ -58,8 +56,7 @@ impl ToPrivateKey for SecretKey where C: PrimeCurve + AlgorithmParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + FieldSize: ModulusSize, { fn to_pkcs8_der(&self) -> pkcs8::Result { let ec_private_key = self.to_sec1_der()?; @@ -72,8 +69,7 @@ where impl FromStr for SecretKey where C: PrimeCurve + AlgorithmParameters + ValidatePublicKey, - UntaggedPointSize: Add + ArrayLength, - UncompressedPointSize: ArrayLength, + FieldSize: ModulusSize, { type Err = Error; From 812b33adc7150a19f195b1f54a4b050e5d5f12c7 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 19 Sep 2021 13:10:57 -0600 Subject: [PATCH 0625/1461] elliptic-curve: enable `sec1` crate's `subtle` and `zeroize` features (#772) These are both hard dependencies of `elliptic-curve` anyway --- Cargo.lock | 1 + elliptic-curve/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 4724d08f8..cbed61c81 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -400,6 +400,7 @@ source = "git+https://github.com/rustcrypto/formats#77564c368c60486dbbdfb6e8ab6b dependencies = [ "der", "generic-array", + "subtle", "zeroize", ] diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 47b3c74d4..d2ea26323 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -29,7 +29,7 @@ group = { version = "0.11", optional = true, default-features = false } hex-literal = { version = "0.3", optional = true } pem-rfc7468 = { version = "0.2", optional = true } pkcs8 = { version = "0.7", optional = true } -sec1 = { version = "0", optional = true } +sec1 = { version = "0", optional = true, features = ["subtle", "zeroize"] } serde = { version = "1", optional = true, default-features = false } serde_json = { version = "1", optional = true, default-features = false, features = ["alloc"] } From 5a80783b616632150a677772e85f8bf14655c60b Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 20 Sep 2021 08:35:37 -0600 Subject: [PATCH 0626/1461] elliptic-curve: add `Reduce` trait (#768) Adds a trait for modular reduction, primarily intended for use cases like hashing to a field element. The trait is generic around a `UInt` to permit overlapping impls, allowing either "narrow" or "wide" reduction, selected by the size of the input. --- elliptic-curve/src/arithmetic.rs | 5 +++-- elliptic-curve/src/dev.rs | 7 +++++++ elliptic-curve/src/ops.rs | 19 +++++++++++++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/elliptic-curve/src/arithmetic.rs b/elliptic-curve/src/arithmetic.rs index 341982c14..2e4347d00 100644 --- a/elliptic-curve/src/arithmetic.rs +++ b/elliptic-curve/src/arithmetic.rs @@ -1,6 +1,6 @@ //! Elliptic curve arithmetic traits. -use crate::{Curve, FieldBytes, PrimeCurve, ScalarCore}; +use crate::{ops::Reduce, Curve, FieldBytes, PrimeCurve, ScalarCore}; use core::fmt::Debug; use subtle::{ConditionallySelectable, ConstantTimeEq}; use zeroize::DefaultIsZeroes; @@ -75,8 +75,9 @@ pub trait ScalarArithmetic: Curve { /// - [`Sync`] type Scalar: DefaultIsZeroes + From> - + Into + Into> + + Into + + Reduce + ff::Field + ff::PrimeField>; } diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index c390b4836..d975674db 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -4,6 +4,7 @@ use crate::{ bigint::U256, error::{Error, Result}, + ops::Reduce, rand_core::RngCore, sec1::{FromEncodedPoint, ToEncodedPoint}, subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}, @@ -310,6 +311,12 @@ impl Neg for Scalar { } } +impl Reduce for Scalar { + fn from_uint_reduced(_: U256) -> Self { + unimplemented!(); + } +} + impl From for Scalar { fn from(n: u64) -> Scalar { Self(n.into()) diff --git a/elliptic-curve/src/ops.rs b/elliptic-curve/src/ops.rs index fee8fda98..fb69b28fa 100644 --- a/elliptic-curve/src/ops.rs +++ b/elliptic-curve/src/ops.rs @@ -2,6 +2,7 @@ pub use core::ops::{Add, AddAssign, Mul, Neg, Sub, SubAssign}; +use crypto_bigint::{ArrayEncoding, ByteArray, Integer}; use subtle::CtOption; /// Perform an inversion on a field element (i.e. base field element or scalar) @@ -21,3 +22,21 @@ impl Invert for F { ff::Field::invert(self) } } + +/// Modular reduction. +pub trait Reduce: Sized { + /// Perform a modular reduction, returning a field element. + fn from_uint_reduced(n: UInt) -> Self; + + /// Interpret the given byte array as a big endian integer and perform a + /// modular reduction. + fn from_be_bytes_reduced(bytes: ByteArray) -> Self { + Self::from_uint_reduced(UInt::from_be_byte_array(bytes)) + } + + /// Interpret the given byte array as a big endian integer and perform a + /// modular reduction. + fn from_le_bytes_reduced(bytes: ByteArray) -> Self { + Self::from_uint_reduced(UInt::from_le_byte_array(bytes)) + } +} From 8a839b121ba9b6cb3b013140cfa3d8a4b708de86 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 20 Sep 2021 08:44:11 -0600 Subject: [PATCH 0627/1461] elliptic-curve: add back `From` for `EncodedPoint` impl (#773) This was removed in #771 but can still be supported --- elliptic-curve/src/public_key.rs | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index 72e9f42a3..f8552f780 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -22,7 +22,7 @@ use {core::str::FromStr, pkcs8::ToPublicKey}; use { crate::{ sec1::{EncodedPoint, FromEncodedPoint, ModulusSize, ToEncodedPoint}, - FieldSize, PrimeCurve, + FieldSize, PointCompression, PrimeCurve, }, core::cmp::Ordering, }; @@ -206,6 +206,32 @@ where } } +#[cfg(feature = "sec1")] +#[cfg_attr(docsrs, doc(cfg(feature = "sec1")))] +impl From> for EncodedPoint +where + C: PrimeCurve + ProjectiveArithmetic + PointCompression, + AffinePoint: FromEncodedPoint + ToEncodedPoint, + FieldSize: ModulusSize, +{ + fn from(public_key: PublicKey) -> EncodedPoint { + EncodedPoint::::from(&public_key) + } +} + +#[cfg(feature = "sec1")] +#[cfg_attr(docsrs, doc(cfg(feature = "sec1")))] +impl From<&PublicKey> for EncodedPoint +where + C: PrimeCurve + ProjectiveArithmetic + PointCompression, + AffinePoint: FromEncodedPoint + ToEncodedPoint, + FieldSize: ModulusSize, +{ + fn from(public_key: &PublicKey) -> EncodedPoint { + public_key.to_encoded_point(C::COMPRESS_POINTS) + } +} + #[cfg(feature = "sec1")] #[cfg_attr(docsrs, doc(cfg(feature = "sec1")))] impl PartialOrd for PublicKey From 301441b62b2563987ae8a76dc71c3d695feaf5e0 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 20 Sep 2021 09:18:57 -0600 Subject: [PATCH 0628/1461] elliptic-curve: remove narrow `Reduce` bound on `Scalar` (#774) Narrow reductions are not ideal and introduce much more bias than a wide reduction. If we are going to bound on a `Reduce` impl, it should at least include a wide reduction so we don't accidentally drive people to narrow reductions instead. While they are needed for ECDSA, narrow reductions should probably be discouraged in other non-legacy applications. --- elliptic-curve/src/arithmetic.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/elliptic-curve/src/arithmetic.rs b/elliptic-curve/src/arithmetic.rs index 2e4347d00..ece0fd029 100644 --- a/elliptic-curve/src/arithmetic.rs +++ b/elliptic-curve/src/arithmetic.rs @@ -1,6 +1,6 @@ //! Elliptic curve arithmetic traits. -use crate::{ops::Reduce, Curve, FieldBytes, PrimeCurve, ScalarCore}; +use crate::{Curve, FieldBytes, PrimeCurve, ScalarCore}; use core::fmt::Debug; use subtle::{ConditionallySelectable, ConstantTimeEq}; use zeroize::DefaultIsZeroes; @@ -77,7 +77,6 @@ pub trait ScalarArithmetic: Curve { + From> + Into> + Into - + Reduce + ff::Field + ff::PrimeField>; } From ec2ea209a6f9cb6e03ae1ab4e580c2ede0059d6d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 21 Sep 2021 16:53:20 -0600 Subject: [PATCH 0629/1461] Cargo.lock: bump dependencies (#778) --- Cargo.lock | 47 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cbed61c81..eed5105eb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -118,7 +118,7 @@ dependencies = [ [[package]] name = "const-oid" version = "0.6.1" -source = "git+https://github.com/rustcrypto/formats#77564c368c60486dbbdfb6e8ab6b1ec9f79aba62" +source = "git+https://github.com/rustcrypto/formats#85322893dc6038d91027599fcf6b19489acd1f7d" [[package]] name = "cpufeatures" @@ -145,9 +145,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51e7ef8604ba15f1ea2cef61e17577e630ee39aef7f94305d138dbf1a216ada3" +checksum = "d12477e115c0d570c12a2dfd859f80b55b60ddb5075df210d3af06d133a69f45" dependencies = [ "generic-array", "rand_core", @@ -188,7 +188,7 @@ dependencies = [ [[package]] name = "der" version = "0.4.3" -source = "git+https://github.com/rustcrypto/formats#77564c368c60486dbbdfb6e8ab6b1ec9f79aba62" +source = "git+https://github.com/rustcrypto/formats#85322893dc6038d91027599fcf6b19489acd1f7d" dependencies = [ "const-oid", ] @@ -292,11 +292,12 @@ dependencies = [ [[package]] name = "heapless" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50530280e9a947b192e3a30a9d7bcead527b22da30ff7cbd334233d820aaf82a" +checksum = "14db22a3fec113074342010bb85a75ba17789244649af8a3178594e0dc97c381" dependencies = [ "hash32", + "spin", "stable_deref_trait", ] @@ -314,9 +315,18 @@ checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" [[package]] name = "libc" -version = "0.2.101" +version = "0.2.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cb00336871be5ed2c8ed44b60ae9959dc5b9f08539422ed43f09e34ecaeba21" +checksum = "a2a5ac8f984bfcf3a823267e5fde638acc3325f6496633a5da6bb6eb2171e103" + +[[package]] +name = "lock_api" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109" +dependencies = [ + "scopeguard", +] [[package]] name = "opaque-debug" @@ -393,10 +403,16 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + [[package]] name = "sec1" version = "0.0.0" -source = "git+https://github.com/rustcrypto/formats#77564c368c60486dbbdfb6e8ab6b1ec9f79aba62" +source = "git+https://github.com/rustcrypto/formats#85322893dc6038d91027599fcf6b19489acd1f7d" dependencies = [ "der", "generic-array", @@ -455,6 +471,15 @@ dependencies = [ "synstructure", ] +[[package]] +name = "spin" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "511254be0c5bcf062b019a6c89c01a664aa359ded62f78aa72c6fc137c0590e5" +dependencies = [ + "lock_api", +] + [[package]] name = "spki" version = "0.4.1" @@ -548,6 +573,6 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "377db0846015f7ae377174787dd452e1c5f5a9050bc6f954911d01f116daa0cd" +checksum = "bf68b08513768deaa790264a7fac27a58cbf2705cfcdc9448362229217d7e970" From fcafb48f1fc9786a784644d6e4b8946d991510ae Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 22 Sep 2021 14:51:17 -0600 Subject: [PATCH 0630/1461] elliptic-curve: use `sec1` v0.1 crate release (#779) --- Cargo.lock | 11 +++++++---- Cargo.toml | 4 ---- elliptic-curve/Cargo.toml | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index eed5105eb..d08c26dbe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -118,7 +118,8 @@ dependencies = [ [[package]] name = "const-oid" version = "0.6.1" -source = "git+https://github.com/rustcrypto/formats#85322893dc6038d91027599fcf6b19489acd1f7d" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdab415d6744056100f40250a66bc430c1a46f7a02e20bc11c94c79a0f0464df" [[package]] name = "cpufeatures" @@ -188,7 +189,8 @@ dependencies = [ [[package]] name = "der" version = "0.4.3" -source = "git+https://github.com/rustcrypto/formats#85322893dc6038d91027599fcf6b19489acd1f7d" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2adca118c71ecd9ae094d4b68257b3fdfcb711a612b9eec7b5a0d27a5a70a5b4" dependencies = [ "const-oid", ] @@ -411,8 +413,9 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "sec1" -version = "0.0.0" -source = "git+https://github.com/rustcrypto/formats#85322893dc6038d91027599fcf6b19489acd1f7d" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "821f61b502d21d297a599436b55d03fff2340961a13bfd0a2c010380b8435823" dependencies = [ "der", "generic-array", diff --git a/Cargo.toml b/Cargo.toml index d9fb216d7..ebf9e0985 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,3 @@ members = [ "signature/async", "universal-hash", ] - -[patch.crates-io] -der = { git = "https://github.com/rustcrypto/formats" } -sec1 = { git = "https://github.com/rustcrypto/formats" } diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index d2ea26323..03d60bbc7 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -29,7 +29,7 @@ group = { version = "0.11", optional = true, default-features = false } hex-literal = { version = "0.3", optional = true } pem-rfc7468 = { version = "0.2", optional = true } pkcs8 = { version = "0.7", optional = true } -sec1 = { version = "0", optional = true, features = ["subtle", "zeroize"] } +sec1 = { version = "0.1", optional = true, features = ["subtle", "zeroize"] } serde = { version = "1", optional = true, default-features = false } serde_json = { version = "1", optional = true, default-features = false, features = ["alloc"] } From d485b10495b4c095c0e4f2114b4544bb917c7cd1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 22 Sep 2021 16:28:15 -0600 Subject: [PATCH 0631/1461] build(deps): bump heapless from 0.7.6 to 0.7.7 (#780) Bumps [heapless](https://github.com/japaric/heapless) from 0.7.6 to 0.7.7. - [Release notes](https://github.com/japaric/heapless/releases) - [Changelog](https://github.com/japaric/heapless/blob/master/CHANGELOG.md) - [Commits](https://github.com/japaric/heapless/compare/v0.7.6...v0.7.7) --- updated-dependencies: - dependency-name: heapless dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d08c26dbe..18481a6cf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -294,9 +294,9 @@ dependencies = [ [[package]] name = "heapless" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14db22a3fec113074342010bb85a75ba17789244649af8a3178594e0dc97c381" +checksum = "fe65ef062f1af5b1b189842b0bc45bd671c38e1d22c6aa22e6ada03d01026d53" dependencies = [ "hash32", "spin", From fea0010f3356186804b42e57a8cb3612b96dab9f Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 23 Sep 2021 12:45:28 -0600 Subject: [PATCH 0632/1461] elliptic-curve: impl `Reduce` for `dev::Scalar` (#781) This is needed for the RFC6979 tests in the `ecdsa` crate. --- elliptic-curve/src/dev.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index d975674db..f22d5c249 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -2,7 +2,7 @@ //! against concrete implementations of the traits in this crate. use crate::{ - bigint::U256, + bigint::{Encoding, Limb, U256}, error::{Error, Result}, ops::Reduce, rand_core::RngCore, @@ -312,8 +312,11 @@ impl Neg for Scalar { } impl Reduce for Scalar { - fn from_uint_reduced(_: U256) -> Self { - unimplemented!(); + fn from_uint_reduced(w: U256) -> Self { + let (r, underflow) = w.sbb(&MockCurve::ORDER, Limb::ZERO); + let underflow = Choice::from((underflow.0 >> (Limb::BIT_SIZE - 1)) as u8); + let reduced = U256::conditional_select(&w, &r, !underflow); + Self(ScalarCore::new(reduced).unwrap()) } } From 23cddf04946a5454e15396e1be6bc7d866f4617b Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 2 Oct 2021 12:12:20 -0600 Subject: [PATCH 0633/1461] elliptic-curve: make `FromEncodedPoint` return a `CtOption` (#782) Internally `k256`/`p256` return a `CtOption` for this method, then convert to an `Option`. It would be helpful when implementing other traits from the `group` crate, e.g. `GroupEncoding`, if this instead returned a `CtOption`. --- elliptic-curve/src/dev.rs | 23 ++++++++++------ elliptic-curve/src/jwk.rs | 41 ++++++++++------------------ elliptic-curve/src/public_key.rs | 47 ++++++++++++++++++-------------- elliptic-curve/src/sec1.rs | 19 ++++++------- 4 files changed, 63 insertions(+), 67 deletions(-) diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index f22d5c249..e8cd1a874 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -367,8 +367,13 @@ impl ConstantTimeEq for AffinePoint { } impl ConditionallySelectable for AffinePoint { - fn conditional_select(_a: &Self, _b: &Self, _choice: Choice) -> Self { - unimplemented!(); + fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { + // Not really constant time, but this is dev code + if choice.into() { + *b + } else { + *a + } } } @@ -381,12 +386,14 @@ impl Default for AffinePoint { impl DefaultIsZeroes for AffinePoint {} impl FromEncodedPoint for AffinePoint { - fn from_encoded_point(point: &EncodedPoint) -> Option { - if point.is_identity() { - Some(Self::Identity) + fn from_encoded_point(encoded_point: &EncodedPoint) -> CtOption { + let point = if encoded_point.is_identity() { + Self::Identity } else { - Some(Self::Other(*point)) - } + Self::Other(*encoded_point) + }; + + CtOption::new(point, Choice::from(1)) } } @@ -472,7 +479,7 @@ impl From for AffinePoint { } impl FromEncodedPoint for ProjectivePoint { - fn from_encoded_point(_point: &EncodedPoint) -> Option { + fn from_encoded_point(_point: &EncodedPoint) -> CtOption { unimplemented!(); } } diff --git a/elliptic-curve/src/jwk.rs b/elliptic-curve/src/jwk.rs index ba4827cda..f179c7483 100644 --- a/elliptic-curve/src/jwk.rs +++ b/elliptic-curve/src/jwk.rs @@ -6,7 +6,7 @@ use crate::{ sec1::{Coordinates, EncodedPoint, ModulusSize, ValidatePublicKey}, secret_key::SecretKey, - Curve, Error, FieldBytes, FieldSize, PrimeCurve, Result, + Curve, Error, FieldBytes, FieldSize, Result, }; use alloc::{ borrow::ToOwned, @@ -114,7 +114,7 @@ impl JwkEcKey { #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub fn to_public_key(&self) -> Result> where - C: PrimeCurve + JwkParameters + ProjectiveArithmetic, + C: Curve + JwkParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -124,7 +124,7 @@ impl JwkEcKey { /// Create a JWK from a SEC1 [`EncodedPoint`]. pub fn from_encoded_point(point: &EncodedPoint) -> Option where - C: PrimeCurve + JwkParameters, + C: Curve + JwkParameters, FieldSize: ModulusSize, { match point.coordinates() { @@ -141,7 +141,7 @@ impl JwkEcKey { /// Get the public key component of this JWK as a SEC1 [`EncodedPoint`]. pub fn to_encoded_point(&self) -> Result> where - C: PrimeCurve + JwkParameters, + C: Curve + JwkParameters, FieldSize: ModulusSize, { if self.crv != C::CRV { @@ -158,7 +158,7 @@ impl JwkEcKey { #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] pub fn to_secret_key(&self) -> Result> where - C: PrimeCurve + JwkParameters + ValidatePublicKey, + C: Curve + JwkParameters + ValidatePublicKey, FieldSize: ModulusSize, { self.try_into() @@ -179,23 +179,10 @@ impl ToString for JwkEcKey { } } -#[cfg(feature = "arithmetic")] -#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] -impl FromEncodedPoint for JwkEcKey -where - C: PrimeCurve + JwkParameters + ProjectiveArithmetic, - AffinePoint: FromEncodedPoint + ToEncodedPoint, - FieldSize: ModulusSize, -{ - fn from_encoded_point(point: &EncodedPoint) -> Option { - Self::from_encoded_point::(point) - } -} - #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] impl TryFrom for SecretKey where - C: PrimeCurve + JwkParameters + ValidatePublicKey, + C: Curve + JwkParameters + ValidatePublicKey, FieldSize: ModulusSize, { type Error = Error; @@ -208,7 +195,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] impl TryFrom<&JwkEcKey> for SecretKey where - C: PrimeCurve + JwkParameters + ValidatePublicKey, + C: Curve + JwkParameters + ValidatePublicKey, FieldSize: ModulusSize, { type Error = Error; @@ -235,7 +222,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] impl From> for JwkEcKey where - C: PrimeCurve + JwkParameters + ProjectiveArithmetic, + C: Curve + JwkParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -249,7 +236,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] impl From<&SecretKey> for JwkEcKey where - C: PrimeCurve + JwkParameters + ProjectiveArithmetic, + C: Curve + JwkParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -267,7 +254,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] impl TryFrom for PublicKey where - C: PrimeCurve + JwkParameters + ProjectiveArithmetic, + C: Curve + JwkParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -283,7 +270,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] impl TryFrom<&JwkEcKey> for PublicKey where - C: PrimeCurve + JwkParameters + ProjectiveArithmetic, + C: Curve + JwkParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -299,7 +286,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] impl From> for JwkEcKey where - C: PrimeCurve + JwkParameters + ProjectiveArithmetic, + C: Curve + JwkParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -313,7 +300,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] impl From<&PublicKey> for JwkEcKey where - C: PrimeCurve + JwkParameters + ProjectiveArithmetic, + C: Curve + JwkParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -587,7 +574,7 @@ impl Serialize for JwkEcKey { } /// Decode a Base64url-encoded field element -fn decode_base64url_fe(s: &str) -> Result> { +fn decode_base64url_fe(s: &str) -> Result> { let mut result = FieldBytes::::default(); Base64Url::decode(s, &mut result).map_err(|_| Error)?; Ok(result) diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index f8552f780..19104d0f5 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -22,9 +22,10 @@ use {core::str::FromStr, pkcs8::ToPublicKey}; use { crate::{ sec1::{EncodedPoint, FromEncodedPoint, ModulusSize, ToEncodedPoint}, - FieldSize, PointCompression, PrimeCurve, + FieldSize, PointCompression, }, core::cmp::Ordering, + subtle::CtOption, }; #[cfg(any(feature = "jwk", feature = "pem"))] @@ -96,12 +97,12 @@ where #[cfg(feature = "sec1")] pub fn from_sec1_bytes(bytes: &[u8]) -> Result where - C: PrimeCurve, + C: Curve, FieldSize: ModulusSize, AffinePoint: FromEncodedPoint + ToEncodedPoint, { let point = EncodedPoint::::from_bytes(bytes).map_err(|_| Error)?; - Self::from_encoded_point(&point).ok_or(Error) + Option::from(Self::from_encoded_point(&point)).ok_or(Error) } /// Borrow the inner [`AffinePoint`] from this [`PublicKey`]. @@ -121,7 +122,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] pub fn from_jwk(jwk: &JwkEcKey) -> Result where - C: PrimeCurve + JwkParameters, + C: Curve + JwkParameters, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -133,7 +134,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] pub fn from_jwk_str(jwk: &str) -> Result where - C: PrimeCurve + JwkParameters, + C: Curve + JwkParameters, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -145,7 +146,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] pub fn to_jwk(&self) -> JwkEcKey where - C: PrimeCurve + JwkParameters, + C: Curve + JwkParameters, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -157,7 +158,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] pub fn to_jwk_string(&self) -> String where - C: PrimeCurve + JwkParameters, + C: Curve + JwkParameters, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -180,14 +181,16 @@ impl Copy for PublicKey where C: Curve + ProjectiveArithmetic {} #[cfg_attr(docsrs, doc(cfg(feature = "sec1")))] impl FromEncodedPoint for PublicKey where - C: PrimeCurve + ProjectiveArithmetic, + C: Curve + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { /// Initialize [`PublicKey`] from an [`EncodedPoint`] - fn from_encoded_point(encoded_point: &EncodedPoint) -> Option { - AffinePoint::::from_encoded_point(encoded_point) - .and_then(|point| PublicKey::from_affine(point).ok()) + fn from_encoded_point(encoded_point: &EncodedPoint) -> CtOption { + AffinePoint::::from_encoded_point(encoded_point).and_then(|point| { + let is_identity = ProjectivePoint::::from(point).is_identity(); + CtOption::new(PublicKey { point }, !is_identity) + }) } } @@ -195,7 +198,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "sec1")))] impl ToEncodedPoint for PublicKey where - C: PrimeCurve + ProjectiveArithmetic, + C: Curve + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -210,7 +213,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "sec1")))] impl From> for EncodedPoint where - C: PrimeCurve + ProjectiveArithmetic + PointCompression, + C: Curve + ProjectiveArithmetic + PointCompression, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -223,7 +226,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "sec1")))] impl From<&PublicKey> for EncodedPoint where - C: PrimeCurve + ProjectiveArithmetic + PointCompression, + C: Curve + ProjectiveArithmetic + PointCompression, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -236,7 +239,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "sec1")))] impl PartialOrd for PublicKey where - C: PrimeCurve + ProjectiveArithmetic, + C: Curve + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -249,7 +252,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "sec1")))] impl Ord for PublicKey where - C: PrimeCurve + ProjectiveArithmetic, + C: Curve + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -265,7 +268,7 @@ where #[cfg_attr(docsrs, doc(cfg(all(feature = "pkcs8", feature = "sec1"))))] impl FromPublicKey for PublicKey where - C: PrimeCurve + AlgorithmParameters + ProjectiveArithmetic, + C: Curve + AlgorithmParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -292,7 +295,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "pem")))] impl ToPublicKey for PublicKey where - C: PrimeCurve + AlgorithmParameters + ProjectiveArithmetic, + C: Curve + AlgorithmParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -311,7 +314,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "pem")))] impl FromStr for PublicKey where - C: PrimeCurve + AlgorithmParameters + ProjectiveArithmetic, + C: Curve + AlgorithmParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -326,7 +329,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "pem")))] impl ToString for PublicKey where - C: PrimeCurve + AlgorithmParameters + ProjectiveArithmetic, + C: Curve + AlgorithmParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -345,6 +348,8 @@ mod tests { #[test] fn from_encoded_point_rejects_identity() { let identity = EncodedPoint::identity(); - assert_eq!(PublicKey::from_encoded_point(&identity), None); + assert!(bool::from( + PublicKey::from_encoded_point(&identity).is_none() + )); } } diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index a0abd5f0d..f548a7fea 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -4,7 +4,8 @@ pub use sec1::point::{Coordinates, ModulusSize, Tag}; -use crate::{FieldSize, PrimeCurve, Result, SecretKey}; +use crate::{Curve, FieldSize, Result, SecretKey}; +use subtle::CtOption; #[cfg(feature = "arithmetic")] use crate::{AffinePoint, Error, ProjectiveArithmetic}; @@ -18,15 +19,11 @@ pub type EncodedPoint = sec1::point::EncodedPoint>; pub trait FromEncodedPoint where Self: Sized, - C: PrimeCurve, + C: Curve, FieldSize: ModulusSize, { /// Deserialize the type this trait is impl'd on from an [`EncodedPoint`]. - /// - /// # Returns - /// - /// `None` if the [`EncodedPoint`] is invalid. - fn from_encoded_point(point: &EncodedPoint) -> Option; + fn from_encoded_point(point: &EncodedPoint) -> CtOption; } /// Trait for serializing a value to a SEC1 encoded curve point. @@ -34,7 +31,7 @@ where /// This is intended for use with the `AffinePoint` type for a given elliptic curve. pub trait ToEncodedPoint where - C: PrimeCurve, + C: Curve, FieldSize: ModulusSize, { /// Serialize this value as a SEC1 [`EncodedPoint`], optionally applying @@ -47,7 +44,7 @@ where /// This is intended for use with the `AffinePoint` type for a given elliptic curve. pub trait ToCompactEncodedPoint where - C: PrimeCurve, + C: Curve, FieldSize: ModulusSize, { /// Serialize this value as a SEC1 [`EncodedPoint`], optionally applying @@ -62,7 +59,7 @@ where /// a blanket default impl of this trait. pub trait ValidatePublicKey where - Self: PrimeCurve, + Self: Curve, FieldSize: ModulusSize, { /// Validate that the given [`EncodedPoint`] is a valid public key for the @@ -86,7 +83,7 @@ where #[cfg(all(feature = "arithmetic"))] impl ValidatePublicKey for C where - C: PrimeCurve + ProjectiveArithmetic, + C: Curve + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { From 148e5da89e85104fe172163093413785fea06c06 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 2 Oct 2021 12:19:45 -0600 Subject: [PATCH 0634/1461] elliptic-curve: remove `PrimeCurve` bounds on SEC1 points (#783) This is a needless restriction --- elliptic-curve/src/secret_key.rs | 16 ++++++++-------- elliptic-curve/src/secret_key/pkcs8.rs | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index ae38c8d9d..1d047a894 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -50,7 +50,7 @@ use pem_rfc7468 as pem; use { crate::{ sec1::{EncodedPoint, ModulusSize, ValidatePublicKey}, - FieldSize, PrimeCurve, + FieldSize, }, core::convert::{TryFrom, TryInto}, }; @@ -179,7 +179,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "sec1")))] pub fn from_sec1_der(der_bytes: &[u8]) -> Result where - C: PrimeCurve + ValidatePublicKey, + C: Curve + ValidatePublicKey, FieldSize: ModulusSize, { sec1::EcPrivateKey::try_from(der_bytes)? @@ -195,7 +195,7 @@ where )] pub fn to_sec1_der(&self) -> der::Result>> where - C: PrimeCurve + ProjectiveArithmetic, + C: Curve + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -229,7 +229,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "pem")))] pub fn from_sec1_pem(s: &str) -> Result where - C: PrimeCurve + ValidatePublicKey, + C: Curve + ValidatePublicKey, FieldSize: ModulusSize, { let (label, der_bytes) = pem::decode_vec(s.as_bytes()).map_err(|_| Error)?; @@ -249,7 +249,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "pem")))] pub fn to_pem(&self, line_ending: pem::LineEnding) -> Result> where - C: PrimeCurve + ProjectiveArithmetic, + C: Curve + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -288,7 +288,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] pub fn to_jwk(&self) -> JwkEcKey where - C: PrimeCurve + JwkParameters + ProjectiveArithmetic, + C: Curve + JwkParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -301,7 +301,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))] pub fn to_jwk_string(&self) -> Zeroizing where - C: PrimeCurve + JwkParameters + ProjectiveArithmetic, + C: Curve + JwkParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -352,7 +352,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "sec1")))] impl TryFrom> for SecretKey where - C: PrimeCurve + ValidatePublicKey, + C: Curve + ValidatePublicKey, FieldSize: ModulusSize, { type Error = der::Error; diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs index 24ecfbb14..84c034111 100644 --- a/elliptic-curve/src/secret_key/pkcs8.rs +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -3,7 +3,7 @@ use super::SecretKey; use crate::{ sec1::{ModulusSize, ValidatePublicKey}, - AlgorithmParameters, FieldSize, PrimeCurve, ALGORITHM_OID, + AlgorithmParameters, Curve, FieldSize, ALGORITHM_OID, }; use core::convert::TryFrom; use der::Decodable; @@ -31,7 +31,7 @@ use { #[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))] impl FromPrivateKey for SecretKey where - C: PrimeCurve + AlgorithmParameters + ValidatePublicKey, + C: Curve + AlgorithmParameters + ValidatePublicKey, FieldSize: ModulusSize, { fn from_pkcs8_private_key_info( @@ -54,7 +54,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "pem")))] impl ToPrivateKey for SecretKey where - C: PrimeCurve + AlgorithmParameters + ProjectiveArithmetic, + C: Curve + AlgorithmParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { @@ -68,7 +68,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "pem")))] impl FromStr for SecretKey where - C: PrimeCurve + AlgorithmParameters + ValidatePublicKey, + C: Curve + AlgorithmParameters + ValidatePublicKey, FieldSize: ModulusSize, { type Err = Error; From e2dd0759a7b85d186c15ca39fd3e6fa67313b0b7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Oct 2021 16:16:27 -0600 Subject: [PATCH 0635/1461] build(deps): bump der from 0.4.3 to 0.4.4 (#784) Bumps [der](https://github.com/RustCrypto/formats) from 0.4.3 to 0.4.4. - [Release notes](https://github.com/RustCrypto/formats/releases) - [Commits](https://github.com/RustCrypto/formats/compare/der/v0.4.3...der/v0.4.4) --- updated-dependencies: - dependency-name: der dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 18481a6cf..1208e365b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -188,9 +188,9 @@ dependencies = [ [[package]] name = "der" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2adca118c71ecd9ae094d4b68257b3fdfcb711a612b9eec7b5a0d27a5a70a5b4" +checksum = "28e98c534e9c8a0483aa01d6f6913bc063de254311bd267c9cf535e9b70e15b2" dependencies = [ "const-oid", ] diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 03d60bbc7..dbcdb27df 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -16,7 +16,7 @@ keywords = ["crypto", "ecc", "elliptic", "weierstrass"] [dependencies] crypto-bigint = { version = "0.2.9", features = ["generic-array", "zeroize"] } -der = { version = "0.4.3", default-features = false, features = ["oid"] } +der = { version = "0.4.4", default-features = false, features = ["oid"] } generic-array = { version = "0.14", default-features = false } rand_core = { version = "0.6", default-features = false } subtle = { version = ">=2, <2.5", default-features = false } From 97fe329f4d2f102075cd2cf5ad119f945af2ce1f Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 9 Oct 2021 10:48:01 -0600 Subject: [PATCH 0636/1461] elliptic-curve: fix `Zeroize` impl on `NonZeroScalar` (#785) The previous impl wrote `0`, which violates `NonZeroScalar`'s invariant that the inner scalar value must be non-zero. This commit changes the impl to write `1` instead. --- elliptic-curve/src/scalar/non_zero.rs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/elliptic-curve/src/scalar/non_zero.rs b/elliptic-curve/src/scalar/non_zero.rs index cdee0e2cb..ce8163edc 100644 --- a/elliptic-curve/src/scalar/non_zero.rs +++ b/elliptic-curve/src/scalar/non_zero.rs @@ -190,15 +190,21 @@ where C: Curve + ProjectiveArithmetic, { fn zeroize(&mut self) { + // Use zeroize's volatile writes to ensure value is cleared. self.scalar.zeroize(); + + // Write a 1 instead of a 0 to ensure this type's non-zero invariant + // is upheld. + self.scalar = Scalar::::one(); } } #[cfg(all(test, feature = "dev"))] mod tests { - use crate::dev::NonZeroScalar; - use ff::PrimeField; + use crate::dev::{NonZeroScalar, Scalar}; + use ff::{Field, PrimeField}; use hex_literal::hex; + use zeroize::Zeroize; #[test] fn round_trip() { @@ -206,4 +212,11 @@ mod tests { let scalar = NonZeroScalar::from_repr(bytes.into()).unwrap(); assert_eq!(&bytes, scalar.to_repr().as_slice()); } + + #[test] + fn zeroize() { + let mut scalar = NonZeroScalar::new(Scalar::from(42u64)).unwrap(); + scalar.zeroize(); + assert_eq!(*scalar, Scalar::one()); + } } From 28576f8807942cb5d606d8ed4bb7846cf80a5400 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 9 Oct 2021 13:12:31 -0600 Subject: [PATCH 0637/1461] elliptic-curve: use prerelease format parsers (#786) The `elliptic-curve` crate is presently a prerelease as well. This commit has it pull in the prerelease format parsers so we can properly integration test them for the elliptic curve use case. --- Cargo.lock | 46 +++++++++++++++++++++++---------------- Cargo.toml | 5 +++++ elliptic-curve/Cargo.toml | 6 ++--- 3 files changed, 35 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1208e365b..20829a72d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -37,6 +37,11 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a32fd6af2b5827bce66c29053ba0e7c42b9dcab01835835058558c10851a46b" +[[package]] +name = "base64ct" +version = "1.1.0" +source = "git+https://github.com/RustCrypto/formats.git#8df9765ec9ca6fa728c797051e780997052b0bb2" + [[package]] name = "bitvec" version = "0.22.3" @@ -118,8 +123,7 @@ dependencies = [ [[package]] name = "const-oid" version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdab415d6744056100f40250a66bc430c1a46f7a02e20bc11c94c79a0f0464df" +source = "git+https://github.com/RustCrypto/formats.git#8df9765ec9ca6fa728c797051e780997052b0bb2" [[package]] name = "cpufeatures" @@ -188,9 +192,8 @@ dependencies = [ [[package]] name = "der" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28e98c534e9c8a0483aa01d6f6913bc063de254311bd267c9cf535e9b70e15b2" +version = "0.5.0-pre" +source = "git+https://github.com/RustCrypto/formats.git#8df9765ec9ca6fa728c797051e780997052b0bb2" dependencies = [ "const-oid", ] @@ -217,14 +220,14 @@ dependencies = [ name = "elliptic-curve" version = "0.11.0-pre" dependencies = [ - "base64ct", + "base64ct 1.0.1", "crypto-bigint", "der", "ff", "generic-array", "group", "hex-literal", - "pem-rfc7468", + "pem-rfc7468 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "pkcs8", "rand_core", "sec1", @@ -340,7 +343,7 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" name = "password-hash" version = "0.3.2" dependencies = [ - "base64ct", + "base64ct 1.0.1", "rand_core", "subtle", ] @@ -351,17 +354,24 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e71fb2d401a15271d52aade6d9410fb4ead603a86da5503f92e872e1df790265" dependencies = [ - "base64ct", + "base64ct 1.0.1", +] + +[[package]] +name = "pem-rfc7468" +version = "0.2.2" +source = "git+https://github.com/RustCrypto/formats.git#8df9765ec9ca6fa728c797051e780997052b0bb2" +dependencies = [ + "base64ct 1.1.0", ] [[package]] name = "pkcs8" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee3ef9b64d26bad0536099c816c6734379e45bbd5f14798def6809e5cc350447" +version = "0.8.0-pre" +source = "git+https://github.com/RustCrypto/formats.git#8df9765ec9ca6fa728c797051e780997052b0bb2" dependencies = [ "der", - "pem-rfc7468", + "pem-rfc7468 0.2.2 (git+https://github.com/RustCrypto/formats.git)", "spki", "zeroize", ] @@ -413,9 +423,8 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "sec1" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "821f61b502d21d297a599436b55d03fff2340961a13bfd0a2c010380b8435823" +version = "0.2.0" +source = "git+https://github.com/RustCrypto/formats.git#8df9765ec9ca6fa728c797051e780997052b0bb2" dependencies = [ "der", "generic-array", @@ -485,9 +494,8 @@ dependencies = [ [[package]] name = "spki" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c01a0c15da1b0b0e1494112e7af814a678fec9bd157881b49beac661e9b6f32" +version = "0.5.0-pre" +source = "git+https://github.com/RustCrypto/formats.git#8df9765ec9ca6fa728c797051e780997052b0bb2" dependencies = [ "der", ] diff --git a/Cargo.toml b/Cargo.toml index ebf9e0985..8e3927f88 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,3 +12,8 @@ members = [ "signature/async", "universal-hash", ] + +[patch.crates-io] +der = { git = "https://github.com/RustCrypto/formats.git" } +pkcs8 = { git = "https://github.com/RustCrypto/formats.git" } +sec1 = { git = "https://github.com/RustCrypto/formats.git" } diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index dbcdb27df..3de8df704 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -16,7 +16,7 @@ keywords = ["crypto", "ecc", "elliptic", "weierstrass"] [dependencies] crypto-bigint = { version = "0.2.9", features = ["generic-array", "zeroize"] } -der = { version = "0.4.4", default-features = false, features = ["oid"] } +der = { version = "0.5.0-pre", default-features = false, features = ["oid"] } generic-array = { version = "0.14", default-features = false } rand_core = { version = "0.6", default-features = false } subtle = { version = ">=2, <2.5", default-features = false } @@ -28,8 +28,8 @@ ff = { version = "0.11", optional = true, default-features = false } group = { version = "0.11", optional = true, default-features = false } hex-literal = { version = "0.3", optional = true } pem-rfc7468 = { version = "0.2", optional = true } -pkcs8 = { version = "0.7", optional = true } -sec1 = { version = "0.1", optional = true, features = ["subtle", "zeroize"] } +pkcs8 = { version = "0.8.0-pre", optional = true } +sec1 = { version = "0.2.0-pre", optional = true, features = ["subtle", "zeroize"] } serde = { version = "1", optional = true, default-features = false } serde_json = { version = "1", optional = true, default-features = false, features = ["alloc"] } From 80ee951080a3544e6550a86923ed49258f8b91ce Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 14 Oct 2021 16:58:04 -0600 Subject: [PATCH 0638/1461] elliptic-curve: bump `der` to v0.5.0-pre.1; MSRV 1.55+ (#788) --- .github/workflows/crypto.yml | 4 +-- .github/workflows/elliptic-curve.yml | 4 +-- .github/workflows/workspace.yml | 2 +- Cargo.lock | 42 ++++++++++++++-------------- README.md | 3 +- crypto/README.md | 4 +-- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/README.md | 4 +-- elliptic-curve/src/lib.rs | 2 +- password-hash/src/traits.rs | 2 +- signature/src/signer.rs | 2 +- 11 files changed, 35 insertions(+), 36 deletions(-) diff --git a/.github/workflows/crypto.yml b/.github/workflows/crypto.yml index 57084f8b3..b66c8d7f1 100644 --- a/.github/workflows/crypto.yml +++ b/.github/workflows/crypto.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.52.0 # MSRV + - 1.55.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -43,7 +43,7 @@ jobs: strategy: matrix: rust: - - 1.52.0 # MSRV + - 1.55.0 # MSRV - stable steps: - uses: actions/checkout@v1 diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index a13f67280..f24504ddd 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.52.0 # MSRV + - 1.55.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -54,7 +54,7 @@ jobs: strategy: matrix: rust: - - 1.52.0 # MSRV + - 1.55.0 # MSRV - stable - nightly steps: diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index bf3bed285..32df8ea6f 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -16,7 +16,7 @@ jobs: - uses: actions/checkout@v1 - uses: actions-rs/toolchain@v1 with: - toolchain: 1.52.0 + toolchain: 1.55.0 components: clippy override: true profile: minimal diff --git a/Cargo.lock b/Cargo.lock index 20829a72d..4b9314dd2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -39,8 +39,8 @@ checksum = "8a32fd6af2b5827bce66c29053ba0e7c42b9dcab01835835058558c10851a46b" [[package]] name = "base64ct" -version = "1.1.0" -source = "git+https://github.com/RustCrypto/formats.git#8df9765ec9ca6fa728c797051e780997052b0bb2" +version = "1.1.1" +source = "git+https://github.com/RustCrypto/formats.git#98d7a2896d671169453f43ee57b43cee17b18b89" [[package]] name = "bitvec" @@ -122,8 +122,8 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.6.1" -source = "git+https://github.com/RustCrypto/formats.git#8df9765ec9ca6fa728c797051e780997052b0bb2" +version = "0.6.2" +source = "git+https://github.com/RustCrypto/formats.git#98d7a2896d671169453f43ee57b43cee17b18b89" [[package]] name = "cpufeatures" @@ -192,8 +192,8 @@ dependencies = [ [[package]] name = "der" -version = "0.5.0-pre" -source = "git+https://github.com/RustCrypto/formats.git#8df9765ec9ca6fa728c797051e780997052b0bb2" +version = "0.5.0-pre.1" +source = "git+https://github.com/RustCrypto/formats.git#98d7a2896d671169453f43ee57b43cee17b18b89" dependencies = [ "const-oid", ] @@ -320,9 +320,9 @@ checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" [[package]] name = "libc" -version = "0.2.102" +version = "0.2.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2a5ac8f984bfcf3a823267e5fde638acc3325f6496633a5da6bb6eb2171e103" +checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6" [[package]] name = "lock_api" @@ -360,15 +360,15 @@ dependencies = [ [[package]] name = "pem-rfc7468" version = "0.2.2" -source = "git+https://github.com/RustCrypto/formats.git#8df9765ec9ca6fa728c797051e780997052b0bb2" +source = "git+https://github.com/RustCrypto/formats.git#98d7a2896d671169453f43ee57b43cee17b18b89" dependencies = [ - "base64ct 1.1.0", + "base64ct 1.1.1", ] [[package]] name = "pkcs8" version = "0.8.0-pre" -source = "git+https://github.com/RustCrypto/formats.git#8df9765ec9ca6fa728c797051e780997052b0bb2" +source = "git+https://github.com/RustCrypto/formats.git#98d7a2896d671169453f43ee57b43cee17b18b89" dependencies = [ "der", "pem-rfc7468 0.2.2 (git+https://github.com/RustCrypto/formats.git)", @@ -378,18 +378,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.29" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d" +checksum = "edc3358ebc67bc8b7fa0c007f945b0b18226f78437d61bec735a9eb96b61ee70" dependencies = [ "unicode-xid", ] [[package]] name = "quote" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" dependencies = [ "proc-macro2", ] @@ -424,7 +424,7 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "sec1" version = "0.2.0" -source = "git+https://github.com/RustCrypto/formats.git#8df9765ec9ca6fa728c797051e780997052b0bb2" +source = "git+https://github.com/RustCrypto/formats.git#98d7a2896d671169453f43ee57b43cee17b18b89" dependencies = [ "der", "generic-array", @@ -495,7 +495,7 @@ dependencies = [ [[package]] name = "spki" version = "0.5.0-pre" -source = "git+https://github.com/RustCrypto/formats.git#8df9765ec9ca6fa728c797051e780997052b0bb2" +source = "git+https://github.com/RustCrypto/formats.git#98d7a2896d671169453f43ee57b43cee17b18b89" dependencies = [ "der", ] @@ -514,9 +514,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.76" +version = "1.0.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6f107db402c2c2055242dbf4d2af0e69197202e9faacbef9571bbe47f5a1b84" +checksum = "d010a1623fbd906d51d650a9916aaefc05ffa0e4053ff7fe601167f3e715d194" dependencies = [ "proc-macro2", "quote", @@ -525,9 +525,9 @@ dependencies = [ [[package]] name = "synstructure" -version = "0.12.5" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "474aaa926faa1603c40b7885a9eaea29b444d1cb2850cb7c0e37bb1a4182f4fa" +checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" dependencies = [ "proc-macro2", "quote", diff --git a/README.md b/README.md index 80a7411fd..ff4332a3b 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# RustCrypto: Traits ![Rust Version][rustc-image] [![Project Chat][chat-image]][chat-link] [![dependency status][deps-image]][deps-link] +# RustCrypto: Traits [![Project Chat][chat-image]][chat-link] [![dependency status][deps-image]][deps-link] Collection of traits which describe functionality of cryptographic primitives. @@ -46,7 +46,6 @@ dual licensed as above, without any additional terms or conditions. [//]: # (badges) -[rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/ [deps-image]: https://deps.rs/repo/github/RustCrypto/traits/status.svg diff --git a/crypto/README.md b/crypto/README.md index dcf008e79..fea6d8378 100644 --- a/crypto/README.md +++ b/crypto/README.md @@ -14,7 +14,7 @@ access compatible versions of all traits from the Rust Crypto project. ## Minimum Supported Rust Version -Rust **1.52** or higher. +Rust **1.55** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -46,7 +46,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/crypto/badge.svg [docs-link]: https://docs.rs/crypto/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.52+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.55+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260050-Traits [build-image]: https://github.com/RustCrypto/traits/workflows/crypto/badge.svg?branch=master&event=push diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 3de8df704..903019c94 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -16,7 +16,7 @@ keywords = ["crypto", "ecc", "elliptic", "weierstrass"] [dependencies] crypto-bigint = { version = "0.2.9", features = ["generic-array", "zeroize"] } -der = { version = "0.5.0-pre", default-features = false, features = ["oid"] } +der = { version = "=0.5.0-pre.1", default-features = false, features = ["oid"] } generic-array = { version = "0.14", default-features = false } rand_core = { version = "0.6", default-features = false } subtle = { version = ">=2, <2.5", default-features = false } diff --git a/elliptic-curve/README.md b/elliptic-curve/README.md index da1e44b60..e918f212e 100644 --- a/elliptic-curve/README.md +++ b/elliptic-curve/README.md @@ -15,7 +15,7 @@ and public/secret keys composed thereof. ## Minimum Supported Rust Version -Requires Rust **1.52** or higher. +Requires Rust **1.55** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -47,7 +47,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/elliptic-curve/badge.svg [docs-link]: https://docs.rs/elliptic-curve/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.52+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.55+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260040-elliptic-curves [build-image]: https://github.com/RustCrypto/elliptic-curves/workflows/elliptic-curve%20crate/badge.svg?branch=master&event=push diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 345ab5603..12ce2074e 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -4,7 +4,7 @@ //! //! ## Minimum Supported Rust Version //! -//! Rust **1.52** or higher. +//! Rust **1.55** or higher. //! //! Minimum supported Rust version can be changed in the future, but it will be //! done with a minor version bump. diff --git a/password-hash/src/traits.rs b/password-hash/src/traits.rs index 472cd2b95..96abccb6a 100644 --- a/password-hash/src/traits.rs +++ b/password-hash/src/traits.rs @@ -68,7 +68,7 @@ impl PasswordVerifier for T { password, Some(hash.algorithm), hash.version, - T::Params::try_from(&hash)?, + T::Params::try_from(hash)?, *salt, )?; diff --git a/signature/src/signer.rs b/signature/src/signer.rs index 8ec1099c3..c025711fe 100644 --- a/signature/src/signer.rs +++ b/signature/src/signer.rs @@ -47,7 +47,7 @@ where S: Signature, { fn try_sign(&mut self, msg: &[u8]) -> Result { - T::try_sign(&self, msg) + T::try_sign(self, msg) } } From d2639c11cbaa49db6186f99f1a0d90a44be146ad Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 17 Oct 2021 19:18:57 -0600 Subject: [PATCH 0639/1461] elliptic-curve: bump `pkcs8`; update encoding traits (#789) Updates `pkcs8` and related crates to use the new trait names after they were renamed in RustCrypto/formats#121. --- Cargo.lock | 27 +++++++++++++------------- elliptic-curve/src/public_key.rs | 26 ++++++++++++++----------- elliptic-curve/src/secret_key/pkcs8.rs | 14 ++++++------- elliptic-curve/tests/pkcs8.rs | 2 +- 4 files changed, 37 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4b9314dd2..534d385d1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -40,7 +40,7 @@ checksum = "8a32fd6af2b5827bce66c29053ba0e7c42b9dcab01835835058558c10851a46b" [[package]] name = "base64ct" version = "1.1.1" -source = "git+https://github.com/RustCrypto/formats.git#98d7a2896d671169453f43ee57b43cee17b18b89" +source = "git+https://github.com/RustCrypto/formats.git#3fb54bd27644e3f8bf8aeced336af77f4ed42813" [[package]] name = "bitvec" @@ -123,7 +123,7 @@ dependencies = [ [[package]] name = "const-oid" version = "0.6.2" -source = "git+https://github.com/RustCrypto/formats.git#98d7a2896d671169453f43ee57b43cee17b18b89" +source = "git+https://github.com/RustCrypto/formats.git#3fb54bd27644e3f8bf8aeced336af77f4ed42813" [[package]] name = "cpufeatures" @@ -150,9 +150,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d12477e115c0d570c12a2dfd859f80b55b60ddb5075df210d3af06d133a69f45" +checksum = "f83bd3bb4314701c568e340cd8cf78c975aa0ca79e03d3f6d1677d5b0c9c0c03" dependencies = [ "generic-array", "rand_core", @@ -193,9 +193,10 @@ dependencies = [ [[package]] name = "der" version = "0.5.0-pre.1" -source = "git+https://github.com/RustCrypto/formats.git#98d7a2896d671169453f43ee57b43cee17b18b89" +source = "git+https://github.com/RustCrypto/formats.git#3fb54bd27644e3f8bf8aeced336af77f4ed42813" dependencies = [ "const-oid", + "pem-rfc7468 0.2.2 (git+https://github.com/RustCrypto/formats.git)", ] [[package]] @@ -320,9 +321,9 @@ checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" [[package]] name = "libc" -version = "0.2.103" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6" +checksum = "7b2f96d100e1cf1929e7719b7edb3b90ab5298072638fccd77be9ce942ecdfce" [[package]] name = "lock_api" @@ -360,7 +361,7 @@ dependencies = [ [[package]] name = "pem-rfc7468" version = "0.2.2" -source = "git+https://github.com/RustCrypto/formats.git#98d7a2896d671169453f43ee57b43cee17b18b89" +source = "git+https://github.com/RustCrypto/formats.git#3fb54bd27644e3f8bf8aeced336af77f4ed42813" dependencies = [ "base64ct 1.1.1", ] @@ -368,10 +369,9 @@ dependencies = [ [[package]] name = "pkcs8" version = "0.8.0-pre" -source = "git+https://github.com/RustCrypto/formats.git#98d7a2896d671169453f43ee57b43cee17b18b89" +source = "git+https://github.com/RustCrypto/formats.git#3fb54bd27644e3f8bf8aeced336af77f4ed42813" dependencies = [ "der", - "pem-rfc7468 0.2.2 (git+https://github.com/RustCrypto/formats.git)", "spki", "zeroize", ] @@ -423,8 +423,8 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "sec1" -version = "0.2.0" -source = "git+https://github.com/RustCrypto/formats.git#98d7a2896d671169453f43ee57b43cee17b18b89" +version = "0.2.0-pre" +source = "git+https://github.com/RustCrypto/formats.git#3fb54bd27644e3f8bf8aeced336af77f4ed42813" dependencies = [ "der", "generic-array", @@ -495,8 +495,9 @@ dependencies = [ [[package]] name = "spki" version = "0.5.0-pre" -source = "git+https://github.com/RustCrypto/formats.git#98d7a2896d671169453f43ee57b43cee17b18b89" +source = "git+https://github.com/RustCrypto/formats.git#3fb54bd27644e3f8bf8aeced336af77f4ed42813" dependencies = [ + "base64ct 1.1.1", "der", ] diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index 19104d0f5..66813de6e 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -12,11 +12,14 @@ use crate::{JwkEcKey, JwkParameters}; #[cfg(all(feature = "sec1", feature = "pkcs8"))] use { crate::{AlgorithmParameters, ALGORITHM_OID}, - pkcs8::FromPublicKey, + pkcs8::DecodePublicKey, }; #[cfg(feature = "pem")] -use {core::str::FromStr, pkcs8::ToPublicKey}; +use { + core::{convert::TryInto, str::FromStr}, + pkcs8::EncodePublicKey, +}; #[cfg(feature = "sec1")] use { @@ -52,7 +55,7 @@ use alloc::string::{String, ToString}; /// To decode an elliptic curve public key from SPKI, enable the `pkcs8` /// feature of this crate (or the `pkcs8` feature of a specific RustCrypto /// elliptic curve crate) and use the -/// [`elliptic_curve::pkcs8::FromPublicKey`][`pkcs8::FromPublicKey`] +/// [`elliptic_curve::pkcs8::DecodePublicKey`][`pkcs8::DecodePublicKey`] /// trait to parse it. /// /// When the `pem` feature of this crate (or a specific RustCrypto elliptic @@ -266,13 +269,13 @@ where #[cfg(all(feature = "pkcs8", feature = "sec1"))] #[cfg_attr(docsrs, doc(cfg(all(feature = "pkcs8", feature = "sec1"))))] -impl FromPublicKey for PublicKey +impl DecodePublicKey for PublicKey where C: Curve + AlgorithmParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { - fn from_spki(spki: pkcs8::SubjectPublicKeyInfo<'_>) -> pkcs8::Result { + fn from_spki(spki: pkcs8::SubjectPublicKeyInfo<'_>) -> der::Result { if spki.algorithm.oid != ALGORITHM_OID { return Err(der::ErrorKind::UnknownOid { oid: spki.algorithm.oid, @@ -287,26 +290,26 @@ where } Self::from_sec1_bytes(spki.subject_public_key) - .map_err(|_| der::Tag::BitString.value_error().into()) + .map_err(|_| der::Tag::BitString.value_error()) } } #[cfg(feature = "pem")] #[cfg_attr(docsrs, doc(cfg(feature = "pem")))] -impl ToPublicKey for PublicKey +impl EncodePublicKey for PublicKey where C: Curve + AlgorithmParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { - fn to_public_key_der(&self) -> pkcs8::Result { + fn to_public_key_der(&self) -> der::Result { let public_key_bytes = self.to_encoded_point(false); - Ok(pkcs8::SubjectPublicKeyInfo { + pkcs8::SubjectPublicKeyInfo { algorithm: C::algorithm_identifier(), subject_public_key: public_key_bytes.as_ref(), } - .into()) + .try_into() } } @@ -334,7 +337,8 @@ where FieldSize: ModulusSize, { fn to_string(&self) -> String { - self.to_public_key_pem().expect("PEM encoding error") + self.to_public_key_pem(Default::default()) + .expect("PEM encoding error") } } diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs index 84c034111..d957dc3b3 100644 --- a/elliptic-curve/src/secret_key/pkcs8.rs +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -7,18 +7,18 @@ use crate::{ }; use core::convert::TryFrom; use der::Decodable; -use pkcs8::FromPrivateKey; +use pkcs8::DecodePrivateKey; use sec1::EcPrivateKey; -// Imports for the `ToPrivateKey` impl -// TODO(tarcieri): use weak activation of `pkcs8/alloc` for gating `ToPrivateKey` impl +// Imports for the `EncodePrivateKey` impl +// TODO(tarcieri): use weak activation of `pkcs8/alloc` for gating `EncodePrivateKey` impl #[cfg(all(feature = "arithmetic", feature = "pem"))] use { crate::{ sec1::{FromEncodedPoint, ToEncodedPoint}, AffinePoint, ProjectiveArithmetic, }, - pkcs8::ToPrivateKey, + pkcs8::EncodePrivateKey, }; // Imports for actual PEM support @@ -29,7 +29,7 @@ use { }; #[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))] -impl FromPrivateKey for SecretKey +impl DecodePrivateKey for SecretKey where C: Curve + AlgorithmParameters + ValidatePublicKey, FieldSize: ModulusSize, @@ -52,7 +52,7 @@ where #[cfg(all(feature = "arithmetic", feature = "pem"))] #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] #[cfg_attr(docsrs, doc(cfg(feature = "pem")))] -impl ToPrivateKey for SecretKey +impl EncodePrivateKey for SecretKey where C: Curve + AlgorithmParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, @@ -60,7 +60,7 @@ where { fn to_pkcs8_der(&self) -> pkcs8::Result { let ec_private_key = self.to_sec1_der()?; - Ok(pkcs8::PrivateKeyInfo::new(C::algorithm_identifier(), &ec_private_key).to_der()) + pkcs8::PrivateKeyInfo::new(C::algorithm_identifier(), &ec_private_key).to_der() } } diff --git a/elliptic-curve/tests/pkcs8.rs b/elliptic-curve/tests/pkcs8.rs index c43a323d6..647c20fea 100644 --- a/elliptic-curve/tests/pkcs8.rs +++ b/elliptic-curve/tests/pkcs8.rs @@ -7,7 +7,7 @@ use elliptic_curve::{ sec1::ToEncodedPoint, }; use hex_literal::hex; -use pkcs8::{FromPrivateKey, FromPublicKey, PrivateKeyDocument, ToPrivateKey}; +use pkcs8::{DecodePrivateKey, DecodePublicKey, EncodePrivateKey, PrivateKeyDocument}; /// DER-encoded PKCS#8 public key const PKCS8_PUBLIC_KEY_DER: &[u8; 91] = include_bytes!("examples/pkcs8-public-key.der"); From 4876cebd0c3b993c7959d8d011899f59354a6796 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 20 Oct 2021 17:30:40 -0600 Subject: [PATCH 0640/1461] signature: show error source in `Display` impl (#791) Previously the `Display` impl on `Error` didn't include source information if available. This change displays it if available. --- signature/src/error.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/signature/src/error.rs b/signature/src/error.rs index 31e58c801..06e22d527 100644 --- a/signature/src/error.rs +++ b/signature/src/error.rs @@ -78,7 +78,16 @@ impl Debug for Error { impl Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str("signature error") + f.write_str("signature error")?; + + #[cfg(feature = "std")] + { + if let Some(source) = &self.source { + write!(f, ": {}", source)?; + } + } + + Ok(()) } } From 19e250bfa1aac42e14ec826aa900f40b0d9cb083 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 20 Oct 2021 18:46:02 -0600 Subject: [PATCH 0641/1461] signature v1.4.0 (#793) --- Cargo.lock | 2 +- signature/CHANGELOG.md | 10 ++++++---- signature/Cargo.toml | 2 +- signature/src/lib.rs | 4 ++-- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 534d385d1..158b464e1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -464,7 +464,7 @@ dependencies = [ [[package]] name = "signature" -version = "1.3.1" +version = "1.4.0" dependencies = [ "digest 0.9.0", "hex-literal", diff --git a/signature/CHANGELOG.md b/signature/CHANGELOG.md index b21101d9e..6ee9cf4de 100644 --- a/signature/CHANGELOG.md +++ b/signature/CHANGELOG.md @@ -4,13 +4,15 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [Unreleased] +## 1.4.0 (2021-10-20) ### Added -- Re-export `rand_core`. Emit compilation error if unstable functionality -is enabled by bypassing the preview features. ([#683]) -- Defined the `SignerMut` trait +- Re-export `rand_core` when the `rand-preview` feature is enabled ([#683]) +- `SignerMut` trait ([#734]) +- Show error source in `Display` impl ([#791]) [#683]: https://github.com/RustCrypto/traits/pull/683 +[#734]: https://github.com/RustCrypto/traits/pull/734 +[#791]: https://github.com/RustCrypto/traits/pull/791 ## 1.3.1 (2021-06-29) ### Added diff --git a/signature/Cargo.toml b/signature/Cargo.toml index aa5363d8c..0d564a6f9 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "1.3.1" # Also update html_root_url in lib.rs when bumping this +version = "1.4.0" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/signature" diff --git a/signature/src/lib.rs b/signature/src/lib.rs index a65f31b58..ed8a9f5f2 100644 --- a/signature/src/lib.rs +++ b/signature/src/lib.rs @@ -160,7 +160,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/signature/1.3.1" + html_root_url = "https://docs.rs/signature/1.4.0" )] #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms, unused_qualifications)] @@ -193,7 +193,7 @@ pub use signature_derive::{Signer, Verifier}; #[cfg(feature = "digest-preview")] pub use digest; -#[cfg(feature = "rand_core")] +#[cfg(feature = "rand-preview")] #[cfg_attr(docsrs, doc(cfg(feature = "rand-preview")))] pub use rand_core; From aacc4a94f0c18c30645209b5d84355d2973ee6cf Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 21 Oct 2021 09:59:46 -0600 Subject: [PATCH 0642/1461] signature v1.3.2 (#794) I made a release which backported just the changes from #791 to the 1.3.x release series. --- signature/CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/signature/CHANGELOG.md b/signature/CHANGELOG.md index 6ee9cf4de..3890548c4 100644 --- a/signature/CHANGELOG.md +++ b/signature/CHANGELOG.md @@ -8,12 +8,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Re-export `rand_core` when the `rand-preview` feature is enabled ([#683]) - `SignerMut` trait ([#734]) + +### Fixed - Show error source in `Display` impl ([#791]) [#683]: https://github.com/RustCrypto/traits/pull/683 [#734]: https://github.com/RustCrypto/traits/pull/734 [#791]: https://github.com/RustCrypto/traits/pull/791 +## 1.3.2 (2021-10-21) +### Fixed +- Backport changes from [#791] to the 1.3.x series. + ## 1.3.1 (2021-06-29) ### Added - `Result` alias ([#676]) From b168e8c348ce358c6d9bfca66aa142b81d1380d2 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 21 Oct 2021 14:04:56 -0600 Subject: [PATCH 0643/1461] elliptic-curve: bump MSRV to 1.56 (#795) The RustCrypto/formats repo was bumped to Rust 2021 edition, and some of those crates (e.g. `der`, `sec1`) are hard dependencies for the `elliptic-curve` crate: https://github.com/RustCrypto/formats/pull/136 This is a corresponding Rust 2021 edition bump for the `elliptic-curve` crate, as well as the omnibus `crypto` crate whose MSRV is determined by the highest MSRV crate in this repo. --- .github/workflows/aead.yml | 5 +- .github/workflows/async-signature.yml | 3 +- .github/workflows/cipher.yml | 2 +- .github/workflows/crypto-common.yml | 5 +- .github/workflows/crypto-mac.yml | 5 +- .github/workflows/crypto.yml | 41 +++- .github/workflows/digest.yml | 5 +- .github/workflows/elliptic-curve.yml | 38 +++- .github/workflows/password-hash.yml | 2 +- .github/workflows/signature.yml | 6 +- .github/workflows/universal-hash.yml | 5 +- .github/workflows/workspace.yml | 13 +- Cargo.lock | 245 ++--------------------- Cargo.toml | 7 - crypto/Cargo.lock | 224 +++++++++++++++++++++ crypto/Cargo.toml | 13 +- crypto/README.md | 4 +- crypto/src/lib.rs | 2 +- elliptic-curve/Cargo.lock | 276 ++++++++++++++++++++++++++ elliptic-curve/Cargo.toml | 22 +- elliptic-curve/README.md | 4 +- elliptic-curve/src/lib.rs | 2 +- signature/Cargo.toml | 2 +- 23 files changed, 648 insertions(+), 283 deletions(-) create mode 100644 crypto/Cargo.lock create mode 100644 elliptic-curve/Cargo.lock diff --git a/.github/workflows/aead.yml b/.github/workflows/aead.yml index 4a1e675c8..d16b5b75d 100644 --- a/.github/workflows/aead.yml +++ b/.github/workflows/aead.yml @@ -58,6 +58,7 @@ jobs: toolchain: ${{ matrix.rust }} target: ${{ matrix.target }} override: true + - run: cargo check --all-features - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features heapless test: @@ -71,9 +72,9 @@ jobs: - uses: actions/checkout@v1 - uses: actions-rs/toolchain@v1 with: - profile: minimal toolchain: ${{ matrix.rust }} - - run: cargo check --all-features + override: true + profile: minimal - run: cargo test --release --no-default-features - run: cargo test --release - run: cargo test --release --features dev,rand_core,stream,std diff --git a/.github/workflows/async-signature.yml b/.github/workflows/async-signature.yml index edef51df8..940bb1fb5 100644 --- a/.github/workflows/async-signature.yml +++ b/.github/workflows/async-signature.yml @@ -28,8 +28,9 @@ jobs: - uses: actions/checkout@v1 - uses: actions-rs/toolchain@v1 with: - profile: minimal toolchain: ${{ matrix.rust }} + override: true + profile: minimal - run: cargo check --all-features - run: cargo test --release - run: cargo test --all-features --release diff --git a/.github/workflows/cipher.yml b/.github/workflows/cipher.yml index 2a4b449d3..d18dd4b64 100644 --- a/.github/workflows/cipher.yml +++ b/.github/workflows/cipher.yml @@ -31,10 +31,10 @@ jobs: - uses: actions/checkout@v1 - uses: actions-rs/toolchain@v1 with: - profile: minimal toolchain: ${{ matrix.rust }} target: ${{ matrix.target }} override: true + profile: minimal - run: cargo build --target ${{ matrix.target }} --release --no-default-features - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features rand_core diff --git a/.github/workflows/crypto-common.yml b/.github/workflows/crypto-common.yml index 84963aaae..287c49535 100644 --- a/.github/workflows/crypto-common.yml +++ b/.github/workflows/crypto-common.yml @@ -31,10 +31,10 @@ jobs: - uses: actions/checkout@v1 - uses: actions-rs/toolchain@v1 with: - profile: minimal toolchain: ${{ matrix.rust }} target: ${{ matrix.target }} override: true + profile: minimal - run: cargo build --no-default-features --release --target ${{ matrix.target }} test: runs-on: ubuntu-latest @@ -47,8 +47,9 @@ jobs: - uses: actions/checkout@v1 - uses: actions-rs/toolchain@v1 with: - profile: minimal toolchain: ${{ matrix.rust }} + override: true + profile: minimal - run: cargo check --all-features - run: cargo test - run: cargo test --features core-api diff --git a/.github/workflows/crypto-mac.yml b/.github/workflows/crypto-mac.yml index 15caa59ed..29186ab72 100644 --- a/.github/workflows/crypto-mac.yml +++ b/.github/workflows/crypto-mac.yml @@ -31,10 +31,10 @@ jobs: - uses: actions/checkout@v1 - uses: actions-rs/toolchain@v1 with: - profile: minimal toolchain: ${{ matrix.rust }} target: ${{ matrix.target }} override: true + profile: minimal - run: cargo build --target ${{ matrix.target }} --release --no-default-features - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features rand_core @@ -49,8 +49,9 @@ jobs: - uses: actions/checkout@v1 - uses: actions-rs/toolchain@v1 with: - profile: minimal toolchain: ${{ matrix.rust }} + override: true + profile: minimal - run: cargo check --all-features - run: cargo test - run: cargo test --features core-api diff --git a/.github/workflows/crypto.yml b/.github/workflows/crypto.yml index b66c8d7f1..f2d8a0b0b 100644 --- a/.github/workflows/crypto.yml +++ b/.github/workflows/crypto.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.55.0 # MSRV + - 1.56.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -31,10 +31,10 @@ jobs: - uses: actions/checkout@v1 - uses: actions-rs/toolchain@v1 with: - profile: minimal toolchain: ${{ matrix.rust }} target: ${{ matrix.target }} override: true + profile: minimal - run: cargo build --no-default-features --release --target ${{ matrix.target }} - run: cargo build --no-default-features --release --target ${{ matrix.target }} --features aead,cipher,mac,digest,elliptic-curve,signature,universal-hash @@ -43,15 +43,48 @@ jobs: strategy: matrix: rust: - - 1.55.0 # MSRV + - 1.56.0 # MSRV - stable steps: - uses: actions/checkout@v1 - uses: actions-rs/toolchain@v1 with: - profile: minimal toolchain: ${{ matrix.rust }} + override: true + profile: minimal - run: cargo check --all-features - run: cargo test --no-default-features --release - run: cargo test --release - run: cargo test --all-features --release + + clippy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + toolchain: 1.56.0 + components: clippy + override: true + profile: minimal + - run: cargo clippy --all --all-features -- -D warnings + + rustfmt: + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v1 + + - name: Install stable toolchain + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + components: rustfmt + override: true + profile: minimal + + - name: Run cargo fmt + uses: actions-rs/cargo@v1 + with: + command: fmt + args: --all -- --check diff --git a/.github/workflows/digest.yml b/.github/workflows/digest.yml index da00f2b12..a518cd23a 100644 --- a/.github/workflows/digest.yml +++ b/.github/workflows/digest.yml @@ -31,10 +31,10 @@ jobs: - uses: actions/checkout@v1 - uses: actions-rs/toolchain@v1 with: - profile: minimal toolchain: ${{ matrix.rust }} target: ${{ matrix.target }} override: true + profile: minimal - run: cargo build --no-default-features --release --target ${{ matrix.target }} test: runs-on: ubuntu-latest @@ -47,8 +47,9 @@ jobs: - uses: actions/checkout@v1 - uses: actions-rs/toolchain@v1 with: - profile: minimal toolchain: ${{ matrix.rust }} + override: true + profile: minimal - run: cargo check --all-features - run: cargo test --release - run: cargo test --features core-api --release diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index f24504ddd..621579ce6 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -22,13 +22,13 @@ jobs: strategy: matrix: rust: - - 1.55.0 # MSRV + - 1.56.0 # MSRV - stable target: - thumbv7em-none-eabi - wasm32-unknown-unknown steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: profile: minimal @@ -54,16 +54,44 @@ jobs: strategy: matrix: rust: - - 1.55.0 # MSRV + - 1.56.0 # MSRV - stable - nightly steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: - profile: minimal toolchain: ${{ matrix.rust }} + override: true + profile: minimal - run: cargo check --all-features - run: cargo test --no-default-features - run: cargo test - run: cargo test --all-features + + clippy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + toolchain: 1.56.0 + components: clippy + override: true + profile: minimal + - run: cargo clippy --all --all-features -- -D warnings + + rustfmt: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + toolchain: stable + components: rustfmt + override: true + profile: minimal + - uses: actions-rs/cargo@v1 + with: + command: fmt + args: --all -- --check diff --git a/.github/workflows/password-hash.yml b/.github/workflows/password-hash.yml index b5c09addb..1e780c073 100644 --- a/.github/workflows/password-hash.yml +++ b/.github/workflows/password-hash.yml @@ -51,8 +51,8 @@ jobs: - uses: actions-rs/toolchain@v1 with: toolchain: ${{ matrix.rust }} - profile: minimal override: true + profile: minimal - run: cargo check --all-features - run: cargo test --release --no-default-features - run: cargo test --release diff --git a/.github/workflows/signature.yml b/.github/workflows/signature.yml index b04544b7a..dc40bf54e 100644 --- a/.github/workflows/signature.yml +++ b/.github/workflows/signature.yml @@ -31,11 +31,12 @@ jobs: - uses: actions/checkout@v1 - uses: actions-rs/toolchain@v1 with: - profile: minimal toolchain: ${{ matrix.rust }} target: ${{ matrix.target }} override: true + profile: minimal - run: cargo build --no-default-features --release --target ${{ matrix.target }} + test: runs-on: ubuntu-latest strategy: @@ -47,8 +48,9 @@ jobs: - uses: actions/checkout@v1 - uses: actions-rs/toolchain@v1 with: - profile: minimal toolchain: ${{ matrix.rust }} + override: true + profile: minimal - run: cargo check --all-features - run: cargo test --no-default-features --release - run: cargo test --release diff --git a/.github/workflows/universal-hash.yml b/.github/workflows/universal-hash.yml index 118f29b04..50035c0e2 100644 --- a/.github/workflows/universal-hash.yml +++ b/.github/workflows/universal-hash.yml @@ -31,10 +31,10 @@ jobs: - uses: actions/checkout@v1 - uses: actions-rs/toolchain@v1 with: - profile: minimal toolchain: ${{ matrix.rust }} target: ${{ matrix.target }} override: true + profile: minimal - run: cargo build --no-default-features --release --target ${{ matrix.target }} test: runs-on: ubuntu-latest @@ -47,8 +47,9 @@ jobs: - uses: actions/checkout@v1 - uses: actions-rs/toolchain@v1 with: - profile: minimal toolchain: ${{ matrix.rust }} + override: true + profile: minimal - run: cargo check --all-features - run: cargo test --no-default-features --release - run: cargo test --release diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index 32df8ea6f..e2413ce35 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -16,7 +16,7 @@ jobs: - uses: actions/checkout@v1 - uses: actions-rs/toolchain@v1 with: - toolchain: 1.55.0 + toolchain: 1.56.0 components: clippy override: true profile: minimal @@ -25,19 +25,14 @@ jobs: rustfmt: runs-on: ubuntu-latest steps: - - name: Checkout sources - uses: actions/checkout@v1 - - - name: Install stable toolchain - uses: actions-rs/toolchain@v1 + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 with: toolchain: stable components: rustfmt override: true profile: minimal - - - name: Run cargo fmt - uses: actions-rs/cargo@v1 + - uses: actions-rs/cargo@v1 with: command: fmt args: --all -- --check diff --git a/Cargo.lock b/Cargo.lock index 158b464e1..e2867fdaf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,7 +1,5 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 - [[package]] name = "aead" version = "0.4.3" @@ -37,23 +35,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a32fd6af2b5827bce66c29053ba0e7c42b9dcab01835835058558c10851a46b" -[[package]] -name = "base64ct" -version = "1.1.1" -source = "git+https://github.com/RustCrypto/formats.git#3fb54bd27644e3f8bf8aeced336af77f4ed42813" - -[[package]] -name = "bitvec" -version = "0.22.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5237f00a8c86130a0cc317830e558b966dd7850d48a953d998c813f01a41b527" -dependencies = [ - "funty", - "radium", - "tap", - "wyz", -] - [[package]] name = "blobby" version = "0.3.0" @@ -100,15 +81,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "cipher" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" -dependencies = [ - "generic-array", -] - [[package]] name = "cipher" version = "0.4.0-pre" @@ -120,11 +92,6 @@ dependencies = [ "rand_core", ] -[[package]] -name = "const-oid" -version = "0.6.2" -source = "git+https://github.com/RustCrypto/formats.git#3fb54bd27644e3f8bf8aeced336af77f4ed42813" - [[package]] name = "cpufeatures" version = "0.2.1" @@ -134,32 +101,6 @@ dependencies = [ "libc", ] -[[package]] -name = "crypto" -version = "0.3.0" -dependencies = [ - "aead", - "cipher 0.3.0", - "crypto-mac 0.11.1", - "digest 0.9.0", - "elliptic-curve", - "password-hash", - "signature", - "universal-hash", -] - -[[package]] -name = "crypto-bigint" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f83bd3bb4314701c568e340cd8cf78c975aa0ca79e03d3f6d1677d5b0c9c0c03" -dependencies = [ - "generic-array", - "rand_core", - "subtle", - "zeroize", -] - [[package]] name = "crypto-common" version = "0.1.0-pre" @@ -168,37 +109,18 @@ dependencies = [ "generic-array", ] -[[package]] -name = "crypto-mac" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" -dependencies = [ - "generic-array", - "subtle", -] - [[package]] name = "crypto-mac" version = "0.12.0-pre" dependencies = [ "blobby", - "cipher 0.4.0-pre", + "cipher", "crypto-common", "generic-array", "rand_core", "subtle", ] -[[package]] -name = "der" -version = "0.5.0-pre.1" -source = "git+https://github.com/RustCrypto/formats.git#3fb54bd27644e3f8bf8aeced336af77f4ed42813" -dependencies = [ - "const-oid", - "pem-rfc7468 0.2.2 (git+https://github.com/RustCrypto/formats.git)", -] - [[package]] name = "digest" version = "0.9.0" @@ -217,44 +139,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "elliptic-curve" -version = "0.11.0-pre" -dependencies = [ - "base64ct 1.0.1", - "crypto-bigint", - "der", - "ff", - "generic-array", - "group", - "hex-literal", - "pem-rfc7468 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "pkcs8", - "rand_core", - "sec1", - "serde", - "serde_json", - "subtle", - "zeroize", -] - -[[package]] -name = "ff" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2958d04124b9f27f175eaeb9a9f383d026098aa837eadd8ba22c11f13a05b9e" -dependencies = [ - "bitvec", - "rand_core", - "subtle", -] - -[[package]] -name = "funty" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1847abb9cb65d566acd5942e94aea9c8f547ad02c98e1649326fc0e8910b8b1e" - [[package]] name = "generic-array" version = "0.14.4" @@ -276,17 +160,6 @@ dependencies = [ "wasi", ] -[[package]] -name = "group" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5ac374b108929de78460075f3dc439fa66df9d8fc77e8f12caa5165fcf0c89" -dependencies = [ - "ff", - "rand_core", - "subtle", -] - [[package]] name = "hash32" version = "0.2.1" @@ -309,15 +182,22 @@ dependencies = [ [[package]] name = "hex-literal" -version = "0.3.3" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21e4590e13640f19f249fe3e4eca5113bc4289f2497710378190e7f4bd96f45b" +checksum = "961de220ec9a91af2e1e5bd80d02109155695e516771762381ef8581317066e0" +dependencies = [ + "hex-literal-impl", + "proc-macro-hack", +] [[package]] -name = "itoa" -version = "0.4.8" +name = "hex-literal-impl" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" +checksum = "853f769599eb31de176303197b7ba4973299c38c7a7604a6bc88c3eef05b9b46" +dependencies = [ + "proc-macro-hack", +] [[package]] name = "libc" @@ -344,37 +224,16 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" name = "password-hash" version = "0.3.2" dependencies = [ - "base64ct 1.0.1", + "base64ct", "rand_core", "subtle", ] [[package]] -name = "pem-rfc7468" -version = "0.2.2" +name = "proc-macro-hack" +version = "0.5.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e71fb2d401a15271d52aade6d9410fb4ead603a86da5503f92e872e1df790265" -dependencies = [ - "base64ct 1.0.1", -] - -[[package]] -name = "pem-rfc7468" -version = "0.2.2" -source = "git+https://github.com/RustCrypto/formats.git#3fb54bd27644e3f8bf8aeced336af77f4ed42813" -dependencies = [ - "base64ct 1.1.1", -] - -[[package]] -name = "pkcs8" -version = "0.8.0-pre" -source = "git+https://github.com/RustCrypto/formats.git#3fb54bd27644e3f8bf8aeced336af77f4ed42813" -dependencies = [ - "der", - "spki", - "zeroize", -] +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" [[package]] name = "proc-macro2" @@ -394,12 +253,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "radium" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "643f8f41a8ebc4c5dc4515c82bb8abd397b527fc20fd681b7c011c2aee5d44fb" - [[package]] name = "rand_core" version = "0.6.3" @@ -409,46 +262,12 @@ dependencies = [ "getrandom", ] -[[package]] -name = "ryu" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" - [[package]] name = "scopeguard" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" -[[package]] -name = "sec1" -version = "0.2.0-pre" -source = "git+https://github.com/RustCrypto/formats.git#3fb54bd27644e3f8bf8aeced336af77f4ed42813" -dependencies = [ - "der", - "generic-array", - "subtle", - "zeroize", -] - -[[package]] -name = "serde" -version = "1.0.130" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" - -[[package]] -name = "serde_json" -version = "1.0.68" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f690853975602e1bfe1ccbf50504d67174e3bcf340f23b5ea9992e0587a52d8" -dependencies = [ - "itoa", - "ryu", - "serde", -] - [[package]] name = "sha2" version = "0.9.8" @@ -492,15 +311,6 @@ dependencies = [ "lock_api", ] -[[package]] -name = "spki" -version = "0.5.0-pre" -source = "git+https://github.com/RustCrypto/formats.git#3fb54bd27644e3f8bf8aeced336af77f4ed42813" -dependencies = [ - "base64ct 1.1.1", - "der", -] - [[package]] name = "stable_deref_trait" version = "1.2.0" @@ -536,12 +346,6 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "tap" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" - [[package]] name = "typenum" version = "1.14.0" @@ -573,18 +377,3 @@ name = "wasi" version = "0.10.2+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" - -[[package]] -name = "wyz" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "129e027ad65ce1453680623c3fb5163cbf7107bfe1aa32257e7d0e63f9ced188" -dependencies = [ - "tap", -] - -[[package]] -name = "zeroize" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf68b08513768deaa790264a7fac27a58cbf2705cfcdc9448362229217d7e970" diff --git a/Cargo.toml b/Cargo.toml index 8e3927f88..10ed45ce0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,16 +4,9 @@ members = [ "cipher", "crypto-common", "crypto-mac", - "crypto", "digest", - "elliptic-curve", "password-hash", "signature", "signature/async", "universal-hash", ] - -[patch.crates-io] -der = { git = "https://github.com/RustCrypto/formats.git" } -pkcs8 = { git = "https://github.com/RustCrypto/formats.git" } -sec1 = { git = "https://github.com/RustCrypto/formats.git" } diff --git a/crypto/Cargo.lock b/crypto/Cargo.lock new file mode 100644 index 000000000..112876aa5 --- /dev/null +++ b/crypto/Cargo.lock @@ -0,0 +1,224 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aead" +version = "0.4.3" +dependencies = [ + "generic-array", + "rand_core", +] + +[[package]] +name = "base64ct" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a32fd6af2b5827bce66c29053ba0e7c42b9dcab01835835058558c10851a46b" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cipher" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" +dependencies = [ + "generic-array", +] + +[[package]] +name = "const-oid" +version = "0.7.0-pre" +source = "git+https://github.com/RustCrypto/formats.git#4ec825666bcd552a873596743d9fead3bdc898e5" + +[[package]] +name = "crypto" +version = "0.4.0-pre" +dependencies = [ + "aead", + "cipher", + "crypto-mac", + "digest", + "elliptic-curve", + "password-hash", + "signature", + "universal-hash", +] + +[[package]] +name = "crypto-bigint" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83bd3bb4314701c568e340cd8cf78c975aa0ca79e03d3f6d1677d5b0c9c0c03" +dependencies = [ + "generic-array", + "rand_core", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-mac" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "der" +version = "0.5.0-pre.1" +source = "git+https://github.com/RustCrypto/formats.git#4ec825666bcd552a873596743d9fead3bdc898e5" +dependencies = [ + "const-oid", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "elliptic-curve" +version = "0.11.0-pre" +dependencies = [ + "crypto-bigint", + "der", + "ff", + "generic-array", + "group", + "rand_core", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "ff" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2958d04124b9f27f175eaeb9a9f383d026098aa837eadd8ba22c11f13a05b9e" +dependencies = [ + "rand_core", + "subtle", +] + +[[package]] +name = "generic-array" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "group" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5ac374b108929de78460075f3dc439fa66df9d8fc77e8f12caa5165fcf0c89" +dependencies = [ + "ff", + "rand_core", + "subtle", +] + +[[package]] +name = "libc" +version = "0.2.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b2f96d100e1cf1929e7719b7edb3b90ab5298072638fccd77be9ce942ecdfce" + +[[package]] +name = "password-hash" +version = "0.3.2" +dependencies = [ + "base64ct", + "rand_core", + "subtle", +] + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom", +] + +[[package]] +name = "sec1" +version = "0.2.0-pre" +source = "git+https://github.com/RustCrypto/formats.git#4ec825666bcd552a873596743d9fead3bdc898e5" +dependencies = [ + "der", + "generic-array", + "subtle", + "zeroize", +] + +[[package]] +name = "signature" +version = "1.4.0" + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "typenum" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" + +[[package]] +name = "universal-hash" +version = "0.4.1" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "version_check" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + +[[package]] +name = "zeroize" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf68b08513768deaa790264a7fac27a58cbf2705cfcdc9448362229217d7e970" diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 4f4138357..9d9fe398f 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "crypto" -version = "0.3.0" # Also update html_root_url in lib.rs when bumping this +version = "0.4.0-pre" # Also update html_root_url in lib.rs when bumping this description = """ Resources for building cryptosystems in Rust using the RustCrypto project's ecosystem. """ @@ -11,7 +11,12 @@ repository = "https://github.com/RustCrypto/traits" keywords = ["crypto", "encryption", "rustcrypto"] categories = ["cryptography", "no-std"] readme = "README.md" -edition = "2018" +edition = "2021" +rust-version = "1.56" + +# Hack to allow this crate to coexist with pre-2021 edition crates +[workspace] +members = ["."] [dependencies] aead = { version = "0.4", optional = true, path = "../aead" } @@ -37,3 +42,7 @@ std = [ [package.metadata.docs.rs] all-features = true + +[patch.crates-io] +der = { git = "https://github.com/RustCrypto/formats.git" } +sec1 = { git = "https://github.com/RustCrypto/formats.git" } diff --git a/crypto/README.md b/crypto/README.md index fea6d8378..870d5d0b2 100644 --- a/crypto/README.md +++ b/crypto/README.md @@ -14,7 +14,7 @@ access compatible versions of all traits from the Rust Crypto project. ## Minimum Supported Rust Version -Rust **1.55** or higher. +Rust **1.56** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -46,7 +46,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/crypto/badge.svg [docs-link]: https://docs.rs/crypto/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.55+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.56+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260050-Traits [build-image]: https://github.com/RustCrypto/traits/workflows/crypto/badge.svg?branch=master&event=push diff --git a/crypto/src/lib.rs b/crypto/src/lib.rs index 0dc4ea083..f26cee7de 100644 --- a/crypto/src/lib.rs +++ b/crypto/src/lib.rs @@ -39,7 +39,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/crypto/0.3.0" + html_root_url = "https://docs.rs/crypto/0.4.0-pre" )] #![forbid(unsafe_code)] #![warn(rust_2018_idioms)] diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock new file mode 100644 index 000000000..87a646cf5 --- /dev/null +++ b/elliptic-curve/Cargo.lock @@ -0,0 +1,276 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "base64ct" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6b4d9b1225d28d360ec6a231d65af1fd99a2a095154c8040689617290569c5c" + +[[package]] +name = "base64ct" +version = "1.2.0-pre" +source = "git+https://github.com/RustCrypto/formats.git#4ec825666bcd552a873596743d9fead3bdc898e5" + +[[package]] +name = "bitvec" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5237f00a8c86130a0cc317830e558b966dd7850d48a953d998c813f01a41b527" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "const-oid" +version = "0.7.0-pre" +source = "git+https://github.com/RustCrypto/formats.git#4ec825666bcd552a873596743d9fead3bdc898e5" + +[[package]] +name = "crypto-bigint" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83bd3bb4314701c568e340cd8cf78c975aa0ca79e03d3f6d1677d5b0c9c0c03" +dependencies = [ + "generic-array", + "rand_core", + "subtle", + "zeroize", +] + +[[package]] +name = "der" +version = "0.5.0-pre.1" +source = "git+https://github.com/RustCrypto/formats.git#4ec825666bcd552a873596743d9fead3bdc898e5" +dependencies = [ + "const-oid", + "pem-rfc7468 0.3.0-pre", +] + +[[package]] +name = "elliptic-curve" +version = "0.11.0-pre" +dependencies = [ + "base64ct 1.1.1", + "crypto-bigint", + "der", + "ff", + "generic-array", + "group", + "hex-literal", + "pem-rfc7468 0.2.3", + "pkcs8", + "rand_core", + "sec1", + "serde", + "serde_json", + "subtle", + "zeroize", +] + +[[package]] +name = "ff" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2958d04124b9f27f175eaeb9a9f383d026098aa837eadd8ba22c11f13a05b9e" +dependencies = [ + "bitvec", + "rand_core", + "subtle", +] + +[[package]] +name = "funty" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1847abb9cb65d566acd5942e94aea9c8f547ad02c98e1649326fc0e8910b8b1e" + +[[package]] +name = "generic-array" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "group" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5ac374b108929de78460075f3dc439fa66df9d8fc77e8f12caa5165fcf0c89" +dependencies = [ + "ff", + "rand_core", + "subtle", +] + +[[package]] +name = "hex-literal" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21e4590e13640f19f249fe3e4eca5113bc4289f2497710378190e7f4bd96f45b" + +[[package]] +name = "itoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" + +[[package]] +name = "libc" +version = "0.2.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b2f96d100e1cf1929e7719b7edb3b90ab5298072638fccd77be9ce942ecdfce" + +[[package]] +name = "pem-rfc7468" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f22eb0e3c593294a99e9ff4b24cf6b752d43f193aa4415fe5077c159996d497" +dependencies = [ + "base64ct 1.1.1", +] + +[[package]] +name = "pem-rfc7468" +version = "0.3.0-pre" +source = "git+https://github.com/RustCrypto/formats.git#4ec825666bcd552a873596743d9fead3bdc898e5" +dependencies = [ + "base64ct 1.2.0-pre", +] + +[[package]] +name = "pkcs8" +version = "0.8.0-pre" +source = "git+https://github.com/RustCrypto/formats.git#4ec825666bcd552a873596743d9fead3bdc898e5" +dependencies = [ + "der", + "spki", + "zeroize", +] + +[[package]] +name = "radium" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "643f8f41a8ebc4c5dc4515c82bb8abd397b527fc20fd681b7c011c2aee5d44fb" + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom", +] + +[[package]] +name = "ryu" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" + +[[package]] +name = "sec1" +version = "0.2.0-pre" +source = "git+https://github.com/RustCrypto/formats.git#4ec825666bcd552a873596743d9fead3bdc898e5" +dependencies = [ + "der", + "generic-array", + "subtle", + "zeroize", +] + +[[package]] +name = "serde" +version = "1.0.130" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" + +[[package]] +name = "serde_json" +version = "1.0.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f690853975602e1bfe1ccbf50504d67174e3bcf340f23b5ea9992e0587a52d8" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "spki" +version = "0.5.0-pre" +source = "git+https://github.com/RustCrypto/formats.git#4ec825666bcd552a873596743d9fead3bdc898e5" +dependencies = [ + "base64ct 1.2.0-pre", + "der", +] + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "typenum" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" + +[[package]] +name = "version_check" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + +[[package]] +name = "wyz" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "129e027ad65ce1453680623c3fb5163cbf7107bfe1aa32257e7d0e63f9ced188" +dependencies = [ + "tap", +] + +[[package]] +name = "zeroize" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf68b08513768deaa790264a7fac27a58cbf2705cfcdc9448362229217d7e970" diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 903019c94..ebec7844d 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -5,14 +5,19 @@ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. """ -version = "0.11.0-pre" # Also update html_root_url in lib.rs when bumping this -authors = ["RustCrypto Developers"] -license = "Apache-2.0 OR MIT" +version = "0.11.0-pre" # Also update html_root_url in lib.rs when bumping this +authors = ["RustCrypto Developers"] +license = "Apache-2.0 OR MIT" repository = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve" -readme = "README.md" -edition = "2018" +readme = "README.md" categories = ["cryptography", "no-std"] -keywords = ["crypto", "ecc", "elliptic", "weierstrass"] +keywords = ["crypto", "ecc", "elliptic", "weierstrass"] +edition = "2021" +rust-version = "1.56" + +# Hack to allow this crate to coexist with pre-2021 edition crates +[workspace] +members = ["."] [dependencies] crypto-bigint = { version = "0.2.9", features = ["generic-array", "zeroize"] } @@ -51,3 +56,8 @@ std = ["alloc", "rand_core/std"] [package.metadata.docs.rs] features = ["arithmetic", "ecdh", "jwk", "pem", "std"] rustdoc-args = ["--cfg", "docsrs"] + +[patch.crates-io] +der = { git = "https://github.com/RustCrypto/formats.git" } +pkcs8 = { git = "https://github.com/RustCrypto/formats.git" } +sec1 = { git = "https://github.com/RustCrypto/formats.git" } diff --git a/elliptic-curve/README.md b/elliptic-curve/README.md index e918f212e..97fd3be4e 100644 --- a/elliptic-curve/README.md +++ b/elliptic-curve/README.md @@ -15,7 +15,7 @@ and public/secret keys composed thereof. ## Minimum Supported Rust Version -Requires Rust **1.55** or higher. +Requires Rust **1.56** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -47,7 +47,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/elliptic-curve/badge.svg [docs-link]: https://docs.rs/elliptic-curve/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.55+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.56+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260040-elliptic-curves [build-image]: https://github.com/RustCrypto/elliptic-curves/workflows/elliptic-curve%20crate/badge.svg?branch=master&event=push diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 12ce2074e..4eadf78f7 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -4,7 +4,7 @@ //! //! ## Minimum Supported Rust Version //! -//! Rust **1.55** or higher. +//! Rust **1.56** or higher. //! //! Minimum supported Rust version can be changed in the future, but it will be //! done with a minor version bump. diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 0d564a6f9..53817708f 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -27,7 +27,7 @@ optional = true path = "derive" [dev-dependencies] -hex-literal = "0.3" +hex-literal = "0.2" sha2 = { version = "0.9", default-features = false } [features] From 655aea782cb0577ff09c8460522357c954887050 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 21 Oct 2021 15:27:40 -0600 Subject: [PATCH 0644/1461] elliptic-curve: re-export `ff` and `PrimeField` (#796) Provides more convenient access to these important traits. --- elliptic-curve/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 4eadf78f7..f23cd79b7 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -78,7 +78,7 @@ pub use { public_key::PublicKey, scalar::{non_zero::NonZeroScalar, Scalar}, }, - ff::Field, + ff::{self, Field, PrimeField}, group::{self, Group}, }; From 84bac176f1b456e17c60b70e923582ed6a332581 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 21 Oct 2021 15:36:54 -0600 Subject: [PATCH 0645/1461] elliptic-curve: remove `TryFrom`/`TryInto` imports (#797) Now that we've upgraded to Rust 2021 edition, these are now available via the prelude, making explicit imports redundant. --- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/dev.rs | 1 - elliptic-curve/src/jwk.rs | 1 - elliptic-curve/src/public_key.rs | 5 +---- elliptic-curve/src/scalar/non_zero.rs | 2 +- elliptic-curve/src/secret_key.rs | 9 +++------ elliptic-curve/src/secret_key/pkcs8.rs | 1 - 7 files changed, 6 insertions(+), 15 deletions(-) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index ebec7844d..d355f4900 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,11 +1,11 @@ [package] name = "elliptic-curve" +version = "0.11.0-pre" # Also update html_root_url in lib.rs when bumping this description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, and public/secret keys composed thereof. """ -version = "0.11.0-pre" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" repository = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve" diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index e8cd1a874..2f42bba01 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -13,7 +13,6 @@ use crate::{ ScalarArithmetic, }; use core::{ - convert::TryFrom, iter::Sum, ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign}, }; diff --git a/elliptic-curve/src/jwk.rs b/elliptic-curve/src/jwk.rs index f179c7483..ebeb6998a 100644 --- a/elliptic-curve/src/jwk.rs +++ b/elliptic-curve/src/jwk.rs @@ -15,7 +15,6 @@ use alloc::{ }; use base64ct::{Base64UrlUnpadded as Base64Url, Encoding}; use core::{ - convert::{TryFrom, TryInto}, fmt::{self, Debug}, marker::PhantomData, str::{self, FromStr}, diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index 66813de6e..f05d2dbd8 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -16,10 +16,7 @@ use { }; #[cfg(feature = "pem")] -use { - core::{convert::TryInto, str::FromStr}, - pkcs8::EncodePublicKey, -}; +use {core::str::FromStr, pkcs8::EncodePublicKey}; #[cfg(feature = "sec1")] use { diff --git a/elliptic-curve/src/scalar/non_zero.rs b/elliptic-curve/src/scalar/non_zero.rs index ce8163edc..e93ce6da9 100644 --- a/elliptic-curve/src/scalar/non_zero.rs +++ b/elliptic-curve/src/scalar/non_zero.rs @@ -7,7 +7,7 @@ use crate::{ rand_core::{CryptoRng, RngCore}, Curve, Error, FieldBytes, ProjectiveArithmetic, Result, Scalar, ScalarCore, SecretKey, }; -use core::{convert::TryFrom, ops::Deref}; +use core::ops::Deref; use ff::{Field, PrimeField}; use generic_array::GenericArray; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 1d047a894..7b3c3a0f4 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -47,12 +47,9 @@ use alloc::string::ToString; use pem_rfc7468 as pem; #[cfg(feature = "sec1")] -use { - crate::{ - sec1::{EncodedPoint, ModulusSize, ValidatePublicKey}, - FieldSize, - }, - core::convert::{TryFrom, TryInto}, +use crate::{ + sec1::{EncodedPoint, ModulusSize, ValidatePublicKey}, + FieldSize, }; #[cfg(all(docsrs, feature = "pkcs8"))] diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs index d957dc3b3..6151210f4 100644 --- a/elliptic-curve/src/secret_key/pkcs8.rs +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -5,7 +5,6 @@ use crate::{ sec1::{ModulusSize, ValidatePublicKey}, AlgorithmParameters, Curve, FieldSize, ALGORITHM_OID, }; -use core::convert::TryFrom; use der::Decodable; use pkcs8::DecodePrivateKey; use sec1::EcPrivateKey; From 38ade29f6e22eb768fcaef56775412485e6bcc9f Mon Sep 17 00:00:00 2001 From: Chris Palmer Date: Thu, 11 Nov 2021 07:06:28 -0800 Subject: [PATCH 0646/1461] Return early if `Ident` is too long (#800) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit At this point, we (can) know whether `too_long` is true, so don't iterate over all the `bytes`. (Both invalid chars and excessive length result in the same kind of error.) I don't think I see a constant-time/timing-independence concern — if a malicious input is too long, saying so immediately does not give the attacker any information about the `bytes` value. --- password-hash/src/ident.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/password-hash/src/ident.rs b/password-hash/src/ident.rs index 48f18c471..06926c0fa 100644 --- a/password-hash/src/ident.rs +++ b/password-hash/src/ident.rs @@ -126,16 +126,16 @@ impl<'a> TryFrom<&'a str> for Ident<'a> { let bytes = s.as_bytes(); let too_long = bytes.len() > Self::MAX_LENGTH; + if too_long { + return Err(Error::ParamNameInvalid); + } + for &c in bytes { if !is_char_valid(c) { return Err(Error::ParamNameInvalid); } } - if too_long { - return Err(Error::ParamNameInvalid); - } - Ok(Self::new(s)) } } From 9ba39263847fa787983ca34867dfeb294dcc6072 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 14 Nov 2021 12:27:11 -0700 Subject: [PATCH 0647/1461] elliptic-curve: bump `crypto-bigint` to v0.3.0-pre.1 (#803) --- elliptic-curve/Cargo.lock | 4 ++-- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/dev.rs | 2 +- elliptic-curve/src/scalar/core.rs | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index 87a646cf5..46999eff3 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -38,9 +38,9 @@ source = "git+https://github.com/RustCrypto/formats.git#4ec825666bcd552a87359674 [[package]] name = "crypto-bigint" -version = "0.2.11" +version = "0.3.0-pre.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f83bd3bb4314701c568e340cd8cf78c975aa0ca79e03d3f6d1677d5b0c9c0c03" +checksum = "d174cafe51590ef0e0a6e540b9ffc8b35a1ff47fb3adda3ab272bcc9f5bfc86c" dependencies = [ "generic-array", "rand_core", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index d355f4900..d9a0df0cf 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -20,7 +20,7 @@ rust-version = "1.56" members = ["."] [dependencies] -crypto-bigint = { version = "0.2.9", features = ["generic-array", "zeroize"] } +crypto-bigint = { version = "=0.3.0-pre.1", default-features = false, features = ["rand_core", "generic-array", "zeroize"] } der = { version = "=0.5.0-pre.1", default-features = false, features = ["oid"] } generic-array = { version = "0.14", default-features = false } rand_core = { version = "0.6", default-features = false } diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 2f42bba01..6b07cc399 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -2,7 +2,7 @@ //! against concrete implementations of the traits in this crate. use crate::{ - bigint::{Encoding, Limb, U256}, + bigint::{Limb, U256}, error::{Error, Result}, ops::Reduce, rand_core::RngCore, diff --git a/elliptic-curve/src/scalar/core.rs b/elliptic-curve/src/scalar/core.rs index db0593a90..8edb8df86 100644 --- a/elliptic-curve/src/scalar/core.rs +++ b/elliptic-curve/src/scalar/core.rs @@ -1,7 +1,7 @@ //! Generic scalar type with core functionality. use crate::{ - bigint::{AddMod, ArrayEncoding, Encoding, Integer, Limb, NegMod, RandomMod, SubMod}, + bigint::{prelude::*, Limb, NonZero}, rand_core::{CryptoRng, RngCore}, subtle::{ Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeGreater, ConstantTimeLess, @@ -55,7 +55,7 @@ where /// Generate a random [`ScalarCore`]. pub fn random(rng: impl CryptoRng + RngCore) -> Self { Self { - inner: C::UInt::random_mod(rng, &Self::MODULUS), + inner: C::UInt::random_mod(rng, &NonZero::new(Self::MODULUS).unwrap()), } } From b5ed205f9775bd26ac44f345c8af06ab5ea9831a Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 14 Nov 2021 13:18:53 -0700 Subject: [PATCH 0648/1461] password-hash: better `Debug`/`Display` impls for `SaltString` (#804) Adds impls of `Debug` and `Display` on `SaltString` similar to the ones on `Salt` (the reference type). Previously there was no `Display` impl at all. The `Debug` impl was previously derived, and therefore had confusing output due to the use of a fixed-sized internal buffer to support heapless platforms. Now they both print the string value, with the `Debug` impl wrapped in `SaltString(...)`. --- password-hash/src/salt.rs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/password-hash/src/salt.rs b/password-hash/src/salt.rs index bf5bf8137..cabd9c281 100644 --- a/password-hash/src/salt.rs +++ b/password-hash/src/salt.rs @@ -160,12 +160,12 @@ impl<'a> fmt::Display for Salt<'a> { impl<'a> fmt::Debug for Salt<'a> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "Salt({:?})", self.as_ref()) + write!(f, "Salt({:?})", self.as_str()) } } /// Owned stack-allocated equivalent of [`Salt`]. -#[derive(Clone, Debug, Eq)] +#[derive(Clone, Eq)] pub struct SaltString { /// Byte array containing an ASCiI-encoded string. bytes: [u8; Salt::MAX_LENGTH], @@ -258,6 +258,18 @@ impl<'a> From<&'a SaltString> for Salt<'a> { } } +impl fmt::Display for SaltString { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.as_str()) + } +} + +impl fmt::Debug for SaltString { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "SaltString({:?})", self.as_str()) + } +} + #[cfg(test)] mod tests { use super::{Error, Salt}; From 7fe7393bffa300b92da24b12f4eb4fe85e1dcff3 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 14 Nov 2021 13:52:33 -0700 Subject: [PATCH 0649/1461] elliptic-curve: bump RustCrypto/formats crates (#805) Updates `elliptic-curve` to the latest version of `pkcs8`/`spki` --- elliptic-curve/Cargo.lock | 44 ++++++++++++++++---------------- elliptic-curve/src/public_key.rs | 19 +++----------- 2 files changed, 26 insertions(+), 37 deletions(-) diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index 46999eff3..b2188ad1c 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -4,14 +4,14 @@ version = 3 [[package]] name = "base64ct" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6b4d9b1225d28d360ec6a231d65af1fd99a2a095154c8040689617290569c5c" +checksum = "392c772b012d685a640cdad68a5a21f4a45e696f85a2c2c907aab2fe49a91e19" [[package]] name = "base64ct" -version = "1.2.0-pre" -source = "git+https://github.com/RustCrypto/formats.git#4ec825666bcd552a873596743d9fead3bdc898e5" +version = "1.2.0" +source = "git+https://github.com/RustCrypto/formats.git#edb2c6a29ba96594f69759cbc331d669ef8e6a9d" [[package]] name = "bitvec" @@ -34,7 +34,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "const-oid" version = "0.7.0-pre" -source = "git+https://github.com/RustCrypto/formats.git#4ec825666bcd552a873596743d9fead3bdc898e5" +source = "git+https://github.com/RustCrypto/formats.git#edb2c6a29ba96594f69759cbc331d669ef8e6a9d" [[package]] name = "crypto-bigint" @@ -51,7 +51,7 @@ dependencies = [ [[package]] name = "der" version = "0.5.0-pre.1" -source = "git+https://github.com/RustCrypto/formats.git#4ec825666bcd552a873596743d9fead3bdc898e5" +source = "git+https://github.com/RustCrypto/formats.git#edb2c6a29ba96594f69759cbc331d669ef8e6a9d" dependencies = [ "const-oid", "pem-rfc7468 0.3.0-pre", @@ -61,7 +61,7 @@ dependencies = [ name = "elliptic-curve" version = "0.11.0-pre" dependencies = [ - "base64ct 1.1.1", + "base64ct 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "crypto-bigint", "der", "ff", @@ -129,9 +129,9 @@ dependencies = [ [[package]] name = "hex-literal" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21e4590e13640f19f249fe3e4eca5113bc4289f2497710378190e7f4bd96f45b" +checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" [[package]] name = "itoa" @@ -141,9 +141,9 @@ checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" [[package]] name = "libc" -version = "0.2.104" +version = "0.2.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b2f96d100e1cf1929e7719b7edb3b90ab5298072638fccd77be9ce942ecdfce" +checksum = "fbe5e23404da5b4f555ef85ebed98fb4083e55a00c317800bc2a50ede9f3d219" [[package]] name = "pem-rfc7468" @@ -151,21 +151,21 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f22eb0e3c593294a99e9ff4b24cf6b752d43f193aa4415fe5077c159996d497" dependencies = [ - "base64ct 1.1.1", + "base64ct 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "pem-rfc7468" version = "0.3.0-pre" -source = "git+https://github.com/RustCrypto/formats.git#4ec825666bcd552a873596743d9fead3bdc898e5" +source = "git+https://github.com/RustCrypto/formats.git#edb2c6a29ba96594f69759cbc331d669ef8e6a9d" dependencies = [ - "base64ct 1.2.0-pre", + "base64ct 1.2.0 (git+https://github.com/RustCrypto/formats.git)", ] [[package]] name = "pkcs8" version = "0.8.0-pre" -source = "git+https://github.com/RustCrypto/formats.git#4ec825666bcd552a873596743d9fead3bdc898e5" +source = "git+https://github.com/RustCrypto/formats.git#edb2c6a29ba96594f69759cbc331d669ef8e6a9d" dependencies = [ "der", "spki", @@ -196,7 +196,7 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "sec1" version = "0.2.0-pre" -source = "git+https://github.com/RustCrypto/formats.git#4ec825666bcd552a873596743d9fead3bdc898e5" +source = "git+https://github.com/RustCrypto/formats.git#edb2c6a29ba96594f69759cbc331d669ef8e6a9d" dependencies = [ "der", "generic-array", @@ -212,9 +212,9 @@ checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" [[package]] name = "serde_json" -version = "1.0.68" +version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f690853975602e1bfe1ccbf50504d67174e3bcf340f23b5ea9992e0587a52d8" +checksum = "e277c495ac6cd1a01a58d0a0c574568b4d1ddf14f59965c6a58b8d96400b54f3" dependencies = [ "itoa", "ryu", @@ -224,9 +224,9 @@ dependencies = [ [[package]] name = "spki" version = "0.5.0-pre" -source = "git+https://github.com/RustCrypto/formats.git#4ec825666bcd552a873596743d9fead3bdc898e5" +source = "git+https://github.com/RustCrypto/formats.git#edb2c6a29ba96594f69759cbc331d669ef8e6a9d" dependencies = [ - "base64ct 1.2.0-pre", + "base64ct 1.2.0 (git+https://github.com/RustCrypto/formats.git)", "der", ] @@ -271,6 +271,6 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.4.2" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf68b08513768deaa790264a7fac27a58cbf2705cfcdc9448362229217d7e970" +checksum = "d68d9dcec5f9b43a30d38c49f91dfedfaac384cb8f085faca366c26207dd1619" diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index f05d2dbd8..1fd0989a8 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -272,22 +272,11 @@ where AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { - fn from_spki(spki: pkcs8::SubjectPublicKeyInfo<'_>) -> der::Result { - if spki.algorithm.oid != ALGORITHM_OID { - return Err(der::ErrorKind::UnknownOid { - oid: spki.algorithm.oid, - } - .into()); - } - - let params_oid = spki.algorithm.parameters_oid()?; - - if params_oid != C::OID { - return Err(der::ErrorKind::UnknownOid { oid: params_oid }.into()); - } + fn from_spki(spki: pkcs8::SubjectPublicKeyInfo<'_>) -> pkcs8::spki::Result { + spki.algorithm.assert_oids(ALGORITHM_OID, C::OID)?; Self::from_sec1_bytes(spki.subject_public_key) - .map_err(|_| der::Tag::BitString.value_error()) + .map_err(|_| der::Tag::BitString.value_error().into()) } } @@ -299,7 +288,7 @@ where AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { - fn to_public_key_der(&self) -> der::Result { + fn to_public_key_der(&self) -> pkcs8::spki::Result { let public_key_bytes = self.to_encoded_point(false); pkcs8::SubjectPublicKeyInfo { From 03acdd168e01b0a38e41293ca82472c138ecdab3 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 14 Nov 2021 14:34:47 -0700 Subject: [PATCH 0650/1461] elliptic-curve: add Encoding bound on Curve::UInt (#806) It was removed upstream to allow the `Integer` trait to be blanket impl'd instead of using a macro. --- elliptic-curve/src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index f23cd79b7..063ddba91 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -113,10 +113,11 @@ pub const ALGORITHM_OID: pkcs8::ObjectIdentifier = /// curves (e.g. [`SecretKey`]). pub trait Curve: 'static + Copy + Clone + Debug + Default + Eq + Ord + Send + Sync { /// Integer type used to represent field elements of this elliptic curve. - // TODO(tarcieri): replace this with an e.g. `const Curve::MODULUS: uint`. + // TODO(tarcieri): replace this with an e.g. `const Curve::MODULUS: UInt`. // Requires rust-lang/rust#60551, i.e. `const_evaluatable_checked` type UInt: bigint::AddMod + bigint::ArrayEncoding + + bigint::Encoding + bigint::Integer + bigint::NegMod + bigint::Random From bf2898676d41b690d07a4628f7708d625b44d7b4 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 15 Nov 2021 13:33:11 -0700 Subject: [PATCH 0651/1461] elliptic-curve: bump `crypto-bigint` dependency to v0.3 (#807) --- elliptic-curve/Cargo.lock | 4 ++-- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index b2188ad1c..28523ffb3 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -38,9 +38,9 @@ source = "git+https://github.com/RustCrypto/formats.git#edb2c6a29ba96594f69759cb [[package]] name = "crypto-bigint" -version = "0.3.0-pre.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d174cafe51590ef0e0a6e540b9ffc8b35a1ff47fb3adda3ab272bcc9f5bfc86c" +checksum = "476ecdba12db8402a1664482de8c37fff7dc96241258bd0de1f0d70e760a45fd" dependencies = [ "generic-array", "rand_core", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index d9a0df0cf..b9107530c 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -20,7 +20,7 @@ rust-version = "1.56" members = ["."] [dependencies] -crypto-bigint = { version = "=0.3.0-pre.1", default-features = false, features = ["rand_core", "generic-array", "zeroize"] } +crypto-bigint = { version = "0.3", default-features = false, features = ["rand_core", "generic-array", "zeroize"] } der = { version = "=0.5.0-pre.1", default-features = false, features = ["oid"] } generic-array = { version = "0.14", default-features = false } rand_core = { version = "0.6", default-features = false } From 0d6f582e941ce60d5876288664e3fccfc29cbe8d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 16 Nov 2021 10:42:44 -0700 Subject: [PATCH 0652/1461] elliptic-curve: use `sec1` crate for `pkcs8` support (#809) The `sec1` crate provides a blanket impl of traits like `DecodeEcPrivateKey` and `EncodeEcPrivateKey` for types which impl the `pkcs8` traits. This commit leverages them. --- elliptic-curve/Cargo.lock | 26 +++++++++++++------------- elliptic-curve/Cargo.toml | 12 ++++++------ elliptic-curve/src/dev.rs | 1 + elliptic-curve/src/error.rs | 3 +++ elliptic-curve/src/lib.rs | 2 +- elliptic-curve/src/public_key.rs | 23 +++++++++++++++++------ elliptic-curve/src/secret_key/pkcs8.rs | 18 +++++++++++++----- elliptic-curve/tests/pkcs8.rs | 2 +- 8 files changed, 55 insertions(+), 32 deletions(-) diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index 28523ffb3..bf6763d11 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -11,7 +11,7 @@ checksum = "392c772b012d685a640cdad68a5a21f4a45e696f85a2c2c907aab2fe49a91e19" [[package]] name = "base64ct" version = "1.2.0" -source = "git+https://github.com/RustCrypto/formats.git#edb2c6a29ba96594f69759cbc331d669ef8e6a9d" +source = "git+https://github.com/RustCrypto/formats.git#43d3ca3f8bca8d7f0a779489885d21a77b0f64a5" [[package]] name = "bitvec" @@ -33,8 +33,8 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "const-oid" -version = "0.7.0-pre" -source = "git+https://github.com/RustCrypto/formats.git#edb2c6a29ba96594f69759cbc331d669ef8e6a9d" +version = "0.7.0" +source = "git+https://github.com/RustCrypto/formats.git#43d3ca3f8bca8d7f0a779489885d21a77b0f64a5" [[package]] name = "crypto-bigint" @@ -50,11 +50,11 @@ dependencies = [ [[package]] name = "der" -version = "0.5.0-pre.1" -source = "git+https://github.com/RustCrypto/formats.git#edb2c6a29ba96594f69759cbc331d669ef8e6a9d" +version = "0.5.0" +source = "git+https://github.com/RustCrypto/formats.git#43d3ca3f8bca8d7f0a779489885d21a77b0f64a5" dependencies = [ "const-oid", - "pem-rfc7468 0.3.0-pre", + "pem-rfc7468 0.3.0", ] [[package]] @@ -69,7 +69,6 @@ dependencies = [ "group", "hex-literal", "pem-rfc7468 0.2.3", - "pkcs8", "rand_core", "sec1", "serde", @@ -156,8 +155,8 @@ dependencies = [ [[package]] name = "pem-rfc7468" -version = "0.3.0-pre" -source = "git+https://github.com/RustCrypto/formats.git#edb2c6a29ba96594f69759cbc331d669ef8e6a9d" +version = "0.3.0" +source = "git+https://github.com/RustCrypto/formats.git#43d3ca3f8bca8d7f0a779489885d21a77b0f64a5" dependencies = [ "base64ct 1.2.0 (git+https://github.com/RustCrypto/formats.git)", ] @@ -165,7 +164,7 @@ dependencies = [ [[package]] name = "pkcs8" version = "0.8.0-pre" -source = "git+https://github.com/RustCrypto/formats.git#edb2c6a29ba96594f69759cbc331d669ef8e6a9d" +source = "git+https://github.com/RustCrypto/formats.git#43d3ca3f8bca8d7f0a779489885d21a77b0f64a5" dependencies = [ "der", "spki", @@ -196,10 +195,11 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "sec1" version = "0.2.0-pre" -source = "git+https://github.com/RustCrypto/formats.git#edb2c6a29ba96594f69759cbc331d669ef8e6a9d" +source = "git+https://github.com/RustCrypto/formats.git#43d3ca3f8bca8d7f0a779489885d21a77b0f64a5" dependencies = [ "der", "generic-array", + "pkcs8", "subtle", "zeroize", ] @@ -223,8 +223,8 @@ dependencies = [ [[package]] name = "spki" -version = "0.5.0-pre" -source = "git+https://github.com/RustCrypto/formats.git#edb2c6a29ba96594f69759cbc331d669ef8e6a9d" +version = "0.5.0" +source = "git+https://github.com/RustCrypto/formats.git#43d3ca3f8bca8d7f0a779489885d21a77b0f64a5" dependencies = [ "base64ct 1.2.0 (git+https://github.com/RustCrypto/formats.git)", "der", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index b9107530c..202997777 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -21,11 +21,11 @@ members = ["."] [dependencies] crypto-bigint = { version = "0.3", default-features = false, features = ["rand_core", "generic-array", "zeroize"] } -der = { version = "=0.5.0-pre.1", default-features = false, features = ["oid"] } +der = { version = "0.5", default-features = false, features = ["oid"] } generic-array = { version = "0.14", default-features = false } rand_core = { version = "0.6", default-features = false } subtle = { version = ">=2, <2.5", default-features = false } -zeroize = { version = ">=1, <1.5", default-features = false } +zeroize = { version = "1", default-features = false } # optional dependencies base64ct = { version = "1", optional = true, default-features = false } @@ -33,8 +33,7 @@ ff = { version = "0.11", optional = true, default-features = false } group = { version = "0.11", optional = true, default-features = false } hex-literal = { version = "0.3", optional = true } pem-rfc7468 = { version = "0.2", optional = true } -pkcs8 = { version = "0.8.0-pre", optional = true } -sec1 = { version = "0.2.0-pre", optional = true, features = ["subtle", "zeroize"] } +sec1 = { version = "=0.2.0-pre", optional = true, features = ["subtle", "zeroize"] } serde = { version = "1", optional = true, default-features = false } serde_json = { version = "1", optional = true, default-features = false, features = ["alloc"] } @@ -46,11 +45,12 @@ default = ["arithmetic"] alloc = ["der/alloc", "sec1/alloc", "zeroize/alloc"] # todo: use weak activation for `group`/`sec1` alloc when available arithmetic = ["ff", "group"] bits = ["arithmetic", "ff/bits"] -dev = ["arithmetic", "hex-literal", "pem"] +dev = ["arithmetic", "hex-literal", "pem", "pkcs8"] ecdh = ["arithmetic"] hazmat = [] jwk = ["alloc", "base64ct/alloc", "serde", "serde_json", "zeroize/alloc"] -pem = ["alloc", "arithmetic", "pem-rfc7468/alloc", "pkcs8/pem", "sec1/alloc"] +pem = ["alloc", "arithmetic", "pem-rfc7468/alloc", "pkcs8", "sec1/pem"] +pkcs8 = ["sec1/pkcs8"] std = ["alloc", "rand_core/std"] [package.metadata.docs.rs] diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 6b07cc399..dd44501a8 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -5,6 +5,7 @@ use crate::{ bigint::{Limb, U256}, error::{Error, Result}, ops::Reduce, + pkcs8, rand_core::RngCore, sec1::{FromEncodedPoint, ToEncodedPoint}, subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}, diff --git a/elliptic-curve/src/error.rs b/elliptic-curve/src/error.rs index 916295603..945955ffc 100644 --- a/elliptic-curve/src/error.rs +++ b/elliptic-curve/src/error.rs @@ -2,6 +2,9 @@ use core::fmt::{self, Display}; +#[cfg(feature = "pkcs8")] +use crate::pkcs8; + /// Result type with the `elliptic-curve` crate's [`Error`] type. pub type Result = core::result::Result; diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 063ddba91..bb8346685 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -89,7 +89,7 @@ pub use crate::scalar::ScalarBits; pub use crate::jwk::{JwkEcKey, JwkParameters}; #[cfg(feature = "pkcs8")] -pub use pkcs8; +pub use ::sec1::pkcs8; use core::fmt::Debug; use generic_array::GenericArray; diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index 1fd0989a8..59382c0f9 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -10,9 +10,9 @@ use group::{Curve as _, Group}; use crate::{JwkEcKey, JwkParameters}; #[cfg(all(feature = "sec1", feature = "pkcs8"))] -use { - crate::{AlgorithmParameters, ALGORITHM_OID}, - pkcs8::DecodePublicKey, +use crate::{ + pkcs8::{self, DecodePublicKey}, + AlgorithmParameters, ALGORITHM_OID, }; #[cfg(feature = "pem")] @@ -266,20 +266,31 @@ where #[cfg(all(feature = "pkcs8", feature = "sec1"))] #[cfg_attr(docsrs, doc(cfg(all(feature = "pkcs8", feature = "sec1"))))] -impl DecodePublicKey for PublicKey +impl TryFrom> for PublicKey where C: Curve + AlgorithmParameters + ProjectiveArithmetic, AffinePoint: FromEncodedPoint + ToEncodedPoint, FieldSize: ModulusSize, { - fn from_spki(spki: pkcs8::SubjectPublicKeyInfo<'_>) -> pkcs8::spki::Result { - spki.algorithm.assert_oids(ALGORITHM_OID, C::OID)?; + type Error = pkcs8::spki::Error; + fn try_from(spki: pkcs8::SubjectPublicKeyInfo<'_>) -> pkcs8::spki::Result { + spki.algorithm.assert_oids(ALGORITHM_OID, C::OID)?; Self::from_sec1_bytes(spki.subject_public_key) .map_err(|_| der::Tag::BitString.value_error().into()) } } +#[cfg(all(feature = "pkcs8", feature = "sec1"))] +#[cfg_attr(docsrs, doc(cfg(all(feature = "pkcs8", feature = "sec1"))))] +impl DecodePublicKey for PublicKey +where + C: Curve + AlgorithmParameters + ProjectiveArithmetic, + AffinePoint: FromEncodedPoint + ToEncodedPoint, + FieldSize: ModulusSize, +{ +} + #[cfg(feature = "pem")] #[cfg_attr(docsrs, doc(cfg(feature = "pem")))] impl EncodePublicKey for PublicKey diff --git a/elliptic-curve/src/secret_key/pkcs8.rs b/elliptic-curve/src/secret_key/pkcs8.rs index 6151210f4..2786b61bd 100644 --- a/elliptic-curve/src/secret_key/pkcs8.rs +++ b/elliptic-curve/src/secret_key/pkcs8.rs @@ -2,11 +2,11 @@ use super::SecretKey; use crate::{ + pkcs8::{self, DecodePrivateKey}, sec1::{ModulusSize, ValidatePublicKey}, AlgorithmParameters, Curve, FieldSize, ALGORITHM_OID, }; use der::Decodable; -use pkcs8::DecodePrivateKey; use sec1::EcPrivateKey; // Imports for the `EncodePrivateKey` impl @@ -28,14 +28,14 @@ use { }; #[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))] -impl DecodePrivateKey for SecretKey +impl TryFrom> for SecretKey where C: Curve + AlgorithmParameters + ValidatePublicKey, FieldSize: ModulusSize, { - fn from_pkcs8_private_key_info( - private_key_info: pkcs8::PrivateKeyInfo<'_>, - ) -> pkcs8::Result { + type Error = pkcs8::Error; + + fn try_from(private_key_info: pkcs8::PrivateKeyInfo<'_>) -> pkcs8::Result { private_key_info .algorithm .assert_oids(ALGORITHM_OID, C::OID)?; @@ -45,6 +45,14 @@ where } } +#[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))] +impl DecodePrivateKey for SecretKey +where + C: Curve + AlgorithmParameters + ValidatePublicKey, + FieldSize: ModulusSize, +{ +} + // TODO(tarcieri): use weak activation of `pkcs8/alloc` for this when possible // It doesn't strictly depend on `pkcs8/pem` but we can't easily activate `pkcs8/alloc` // without adding a separate crate feature just for this functionality. diff --git a/elliptic-curve/tests/pkcs8.rs b/elliptic-curve/tests/pkcs8.rs index 647c20fea..c88b416a9 100644 --- a/elliptic-curve/tests/pkcs8.rs +++ b/elliptic-curve/tests/pkcs8.rs @@ -4,10 +4,10 @@ use elliptic_curve::{ dev::{PublicKey, SecretKey}, + pkcs8::{DecodePrivateKey, DecodePublicKey, EncodePrivateKey, PrivateKeyDocument}, sec1::ToEncodedPoint, }; use hex_literal::hex; -use pkcs8::{DecodePrivateKey, DecodePublicKey, EncodePrivateKey, PrivateKeyDocument}; /// DER-encoded PKCS#8 public key const PKCS8_PUBLIC_KEY_DER: &[u8; 91] = include_bytes!("examples/pkcs8-public-key.der"); From 3502b5b35966e690eaf504e8e60542d7b7a22eff Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 17 Nov 2021 08:01:49 -0700 Subject: [PATCH 0653/1461] elliptic-curve: bump `spki` to v0.5 release (#810) This removes all of the git-based dependencies on `RustCrypto/formats` --- elliptic-curve/Cargo.lock | 39 ++++++++++++++++++++------------------- elliptic-curve/Cargo.toml | 9 ++------- 2 files changed, 22 insertions(+), 26 deletions(-) diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index bf6763d11..952831623 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -8,11 +8,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "392c772b012d685a640cdad68a5a21f4a45e696f85a2c2c907aab2fe49a91e19" -[[package]] -name = "base64ct" -version = "1.2.0" -source = "git+https://github.com/RustCrypto/formats.git#43d3ca3f8bca8d7f0a779489885d21a77b0f64a5" - [[package]] name = "bitvec" version = "0.22.3" @@ -34,7 +29,8 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "const-oid" version = "0.7.0" -source = "git+https://github.com/RustCrypto/formats.git#43d3ca3f8bca8d7f0a779489885d21a77b0f64a5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d355758f44afa81c21e66e1301d47cbffbbcde4b405cbe46b8b19f213abf9f60" [[package]] name = "crypto-bigint" @@ -50,8 +46,9 @@ dependencies = [ [[package]] name = "der" -version = "0.5.0" -source = "git+https://github.com/RustCrypto/formats.git#43d3ca3f8bca8d7f0a779489885d21a77b0f64a5" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" dependencies = [ "const-oid", "pem-rfc7468 0.3.0", @@ -61,7 +58,7 @@ dependencies = [ name = "elliptic-curve" version = "0.11.0-pre" dependencies = [ - "base64ct 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "base64ct", "crypto-bigint", "der", "ff", @@ -150,21 +147,23 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f22eb0e3c593294a99e9ff4b24cf6b752d43f193aa4415fe5077c159996d497" dependencies = [ - "base64ct 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "base64ct", ] [[package]] name = "pem-rfc7468" version = "0.3.0" -source = "git+https://github.com/RustCrypto/formats.git#43d3ca3f8bca8d7f0a779489885d21a77b0f64a5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af1254538022fc9aaf1db9f36f315f7a622dc4d46bedc42f8f8220ee23f932ee" dependencies = [ - "base64ct 1.2.0 (git+https://github.com/RustCrypto/formats.git)", + "base64ct", ] [[package]] name = "pkcs8" -version = "0.8.0-pre" -source = "git+https://github.com/RustCrypto/formats.git#43d3ca3f8bca8d7f0a779489885d21a77b0f64a5" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" dependencies = [ "der", "spki", @@ -194,8 +193,9 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "sec1" -version = "0.2.0-pre" -source = "git+https://github.com/RustCrypto/formats.git#43d3ca3f8bca8d7f0a779489885d21a77b0f64a5" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2503adcd8c83e7081b3f9a3173f328f4d6cd50e116aaa324389b46f2d771d595" dependencies = [ "der", "generic-array", @@ -223,10 +223,11 @@ dependencies = [ [[package]] name = "spki" -version = "0.5.0" -source = "git+https://github.com/RustCrypto/formats.git#43d3ca3f8bca8d7f0a779489885d21a77b0f64a5" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707c346225adc965b02243d87a3951bb6f8cbd039947cd99430ee2b2fdad09a3" dependencies = [ - "base64ct 1.2.0 (git+https://github.com/RustCrypto/formats.git)", + "base64ct", "der", ] diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 202997777..bb5eac321 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -24,7 +24,7 @@ crypto-bigint = { version = "0.3", default-features = false, features = ["rand_c der = { version = "0.5", default-features = false, features = ["oid"] } generic-array = { version = "0.14", default-features = false } rand_core = { version = "0.6", default-features = false } -subtle = { version = ">=2, <2.5", default-features = false } +subtle = { version = "2", default-features = false } zeroize = { version = "1", default-features = false } # optional dependencies @@ -33,7 +33,7 @@ ff = { version = "0.11", optional = true, default-features = false } group = { version = "0.11", optional = true, default-features = false } hex-literal = { version = "0.3", optional = true } pem-rfc7468 = { version = "0.2", optional = true } -sec1 = { version = "=0.2.0-pre", optional = true, features = ["subtle", "zeroize"] } +sec1 = { version = "0.2", optional = true, features = ["subtle", "zeroize"] } serde = { version = "1", optional = true, default-features = false } serde_json = { version = "1", optional = true, default-features = false, features = ["alloc"] } @@ -56,8 +56,3 @@ std = ["alloc", "rand_core/std"] [package.metadata.docs.rs] features = ["arithmetic", "ecdh", "jwk", "pem", "std"] rustdoc-args = ["--cfg", "docsrs"] - -[patch.crates-io] -der = { git = "https://github.com/RustCrypto/formats.git" } -pkcs8 = { git = "https://github.com/RustCrypto/formats.git" } -sec1 = { git = "https://github.com/RustCrypto/formats.git" } From 31436a2eaf8bd3fb5292e11e9a0b1f93056a7817 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 17 Nov 2021 09:13:13 -0700 Subject: [PATCH 0654/1461] Cargo.lock(s): update dependencies (#811) This is mainly to pick up the new releases of `pem-rfc7468` and `spki` which now have relaxed `base64ct` requirements: https://github.com/RustCrypto/formats/pull/239 This should correct the build failures seen on `master`: https://github.com/RustCrypto/traits/runs/4239715372?check_suite_focus=true --- Cargo.lock | 18 ++++++++------ crypto/Cargo.lock | 51 +++++++++++++++++++++++++++++---------- elliptic-curve/Cargo.lock | 10 ++++---- 3 files changed, 53 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e2867fdaf..fe92941cb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,7 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "aead" version = "0.4.3" @@ -171,9 +173,9 @@ dependencies = [ [[package]] name = "heapless" -version = "0.7.7" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe65ef062f1af5b1b189842b0bc45bd671c38e1d22c6aa22e6ada03d01026d53" +checksum = "9c1ad878e07405df82b695089e63d278244344f80e764074d0bdfe99b89460f3" dependencies = [ "hash32", "spin", @@ -201,9 +203,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.104" +version = "0.2.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b2f96d100e1cf1929e7719b7edb3b90ab5298072638fccd77be9ce942ecdfce" +checksum = "fbe5e23404da5b4f555ef85ebed98fb4083e55a00c317800bc2a50ede9f3d219" [[package]] name = "lock_api" @@ -237,9 +239,9 @@ checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" [[package]] name = "proc-macro2" -version = "1.0.30" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edc3358ebc67bc8b7fa0c007f945b0b18226f78437d61bec735a9eb96b61ee70" +checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43" dependencies = [ "unicode-xid", ] @@ -325,9 +327,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.80" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d010a1623fbd906d51d650a9916aaefc05ffa0e4053ff7fe601167f3e715d194" +checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966" dependencies = [ "proc-macro2", "quote", diff --git a/crypto/Cargo.lock b/crypto/Cargo.lock index 112876aa5..8d0f1e283 100644 --- a/crypto/Cargo.lock +++ b/crypto/Cargo.lock @@ -16,6 +16,11 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a32fd6af2b5827bce66c29053ba0e7c42b9dcab01835835058558c10851a46b" +[[package]] +name = "base64ct" +version = "1.2.0" +source = "git+https://github.com/RustCrypto/formats.git#271163d6c48d930190cc434c155574b1281385cf" + [[package]] name = "cfg-if" version = "1.0.0" @@ -33,8 +38,8 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.7.0-pre" -source = "git+https://github.com/RustCrypto/formats.git#4ec825666bcd552a873596743d9fead3bdc898e5" +version = "0.7.0" +source = "git+https://github.com/RustCrypto/formats.git#271163d6c48d930190cc434c155574b1281385cf" [[package]] name = "crypto" @@ -52,9 +57,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.2.11" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f83bd3bb4314701c568e340cd8cf78c975aa0ca79e03d3f6d1677d5b0c9c0c03" +checksum = "476ecdba12db8402a1664482de8c37fff7dc96241258bd0de1f0d70e760a45fd" dependencies = [ "generic-array", "rand_core", @@ -74,8 +79,8 @@ dependencies = [ [[package]] name = "der" -version = "0.5.0-pre.1" -source = "git+https://github.com/RustCrypto/formats.git#4ec825666bcd552a873596743d9fead3bdc898e5" +version = "0.5.1" +source = "git+https://github.com/RustCrypto/formats.git#271163d6c48d930190cc434c155574b1281385cf" dependencies = [ "const-oid", ] @@ -148,19 +153,29 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.104" +version = "0.2.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b2f96d100e1cf1929e7719b7edb3b90ab5298072638fccd77be9ce942ecdfce" +checksum = "fbe5e23404da5b4f555ef85ebed98fb4083e55a00c317800bc2a50ede9f3d219" [[package]] name = "password-hash" version = "0.3.2" dependencies = [ - "base64ct", + "base64ct 1.0.1", "rand_core", "subtle", ] +[[package]] +name = "pkcs8" +version = "0.8.0" +source = "git+https://github.com/RustCrypto/formats.git#271163d6c48d930190cc434c155574b1281385cf" +dependencies = [ + "der", + "spki", + "zeroize", +] + [[package]] name = "rand_core" version = "0.6.3" @@ -172,11 +187,12 @@ dependencies = [ [[package]] name = "sec1" -version = "0.2.0-pre" -source = "git+https://github.com/RustCrypto/formats.git#4ec825666bcd552a873596743d9fead3bdc898e5" +version = "0.2.0" +source = "git+https://github.com/RustCrypto/formats.git#271163d6c48d930190cc434c155574b1281385cf" dependencies = [ "der", "generic-array", + "pkcs8", "subtle", "zeroize", ] @@ -185,6 +201,15 @@ dependencies = [ name = "signature" version = "1.4.0" +[[package]] +name = "spki" +version = "0.5.2" +source = "git+https://github.com/RustCrypto/formats.git#271163d6c48d930190cc434c155574b1281385cf" +dependencies = [ + "base64ct 1.2.0", + "der", +] + [[package]] name = "subtle" version = "2.4.1" @@ -219,6 +244,6 @@ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] name = "zeroize" -version = "1.4.2" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf68b08513768deaa790264a7fac27a58cbf2705cfcdc9448362229217d7e970" +checksum = "d68d9dcec5f9b43a30d38c49f91dfedfaac384cb8f085faca366c26207dd1619" diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index 952831623..19e31bd1b 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -51,7 +51,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" dependencies = [ "const-oid", - "pem-rfc7468 0.3.0", + "pem-rfc7468 0.3.1", ] [[package]] @@ -152,9 +152,9 @@ dependencies = [ [[package]] name = "pem-rfc7468" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af1254538022fc9aaf1db9f36f315f7a622dc4d46bedc42f8f8220ee23f932ee" +checksum = "01de5d978f34aa4b2296576379fcc416034702fd94117c56ffd8a1a767cefb30" dependencies = [ "base64ct", ] @@ -223,9 +223,9 @@ dependencies = [ [[package]] name = "spki" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707c346225adc965b02243d87a3951bb6f8cbd039947cd99430ee2b2fdad09a3" +checksum = "c8a277a21925310de1d31bb6b021da3550b00e9127096ef84ee38f44609925c4" dependencies = [ "base64ct", "der", From 7309422341ec6cd46039a46b3809ed7f2e79cdb9 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 17 Nov 2021 10:44:58 -0700 Subject: [PATCH 0655/1461] elliptic-curve: use `ScalarArithmetic` as `NonZeroScalar` bounds (#812) Previously they were `ProjectiveArithmetic`, ostensibly because the `ScalarArithmetic` trait didn't exist at the time. --- elliptic-curve/src/scalar/non_zero.rs | 35 +++++++++++++-------------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/elliptic-curve/src/scalar/non_zero.rs b/elliptic-curve/src/scalar/non_zero.rs index e93ce6da9..c3edf4fc2 100644 --- a/elliptic-curve/src/scalar/non_zero.rs +++ b/elliptic-curve/src/scalar/non_zero.rs @@ -1,11 +1,10 @@ //! Non-zero scalar type. -// TODO(tarcieri): change bounds to `ScalarArithmetic` instead of `ProjectiveArithmetic` use crate::{ bigint::Encoding as _, ops::Invert, rand_core::{CryptoRng, RngCore}, - Curve, Error, FieldBytes, ProjectiveArithmetic, Result, Scalar, ScalarCore, SecretKey, + Curve, Error, FieldBytes, Result, Scalar, ScalarArithmetic, ScalarCore, SecretKey, }; use core::ops::Deref; use ff::{Field, PrimeField}; @@ -25,14 +24,14 @@ use zeroize::Zeroize; #[derive(Clone)] pub struct NonZeroScalar where - C: Curve + ProjectiveArithmetic, + C: Curve + ScalarArithmetic, { scalar: Scalar, } impl NonZeroScalar where - C: Curve + ProjectiveArithmetic, + C: Curve + ScalarArithmetic, { /// Generate a random `NonZeroScalar`. pub fn random(mut rng: impl CryptoRng + RngCore) -> Self { @@ -59,7 +58,7 @@ where impl AsRef> for NonZeroScalar where - C: Curve + ProjectiveArithmetic, + C: Curve + ScalarArithmetic, { fn as_ref(&self) -> &Scalar { &self.scalar @@ -68,7 +67,7 @@ where impl ConditionallySelectable for NonZeroScalar where - C: Curve + ProjectiveArithmetic, + C: Curve + ScalarArithmetic, { fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { Self { @@ -79,18 +78,18 @@ where impl ConstantTimeEq for NonZeroScalar where - C: Curve + ProjectiveArithmetic, + C: Curve + ScalarArithmetic, { fn ct_eq(&self, other: &Self) -> Choice { self.scalar.ct_eq(&other.scalar) } } -impl Copy for NonZeroScalar where C: Curve + ProjectiveArithmetic {} +impl Copy for NonZeroScalar where C: Curve + ScalarArithmetic {} impl Deref for NonZeroScalar where - C: Curve + ProjectiveArithmetic, + C: Curve + ScalarArithmetic, { type Target = Scalar; @@ -101,7 +100,7 @@ where impl From> for FieldBytes where - C: Curve + ProjectiveArithmetic, + C: Curve + ScalarArithmetic, { fn from(scalar: NonZeroScalar) -> FieldBytes { Self::from(&scalar) @@ -110,7 +109,7 @@ where impl From<&NonZeroScalar> for FieldBytes where - C: Curve + ProjectiveArithmetic, + C: Curve + ScalarArithmetic, { fn from(scalar: &NonZeroScalar) -> FieldBytes { scalar.to_repr() @@ -119,7 +118,7 @@ where impl From> for ScalarCore where - C: Curve + ProjectiveArithmetic, + C: Curve + ScalarArithmetic, { fn from(scalar: NonZeroScalar) -> ScalarCore { ScalarCore::from_be_bytes(scalar.to_repr()).unwrap() @@ -128,7 +127,7 @@ where impl From<&NonZeroScalar> for ScalarCore where - C: Curve + ProjectiveArithmetic, + C: Curve + ScalarArithmetic, { fn from(scalar: &NonZeroScalar) -> ScalarCore { ScalarCore::from_be_bytes(scalar.to_repr()).unwrap() @@ -137,7 +136,7 @@ where impl From> for NonZeroScalar where - C: Curve + ProjectiveArithmetic, + C: Curve + ScalarArithmetic, { fn from(sk: SecretKey) -> NonZeroScalar { Self::from(&sk) @@ -146,7 +145,7 @@ where impl From<&SecretKey> for NonZeroScalar where - C: Curve + ProjectiveArithmetic, + C: Curve + ScalarArithmetic, { fn from(sk: &SecretKey) -> NonZeroScalar { let scalar = sk.as_scalar_core().to_scalar(); @@ -157,7 +156,7 @@ where impl Invert for NonZeroScalar where - C: Curve + ProjectiveArithmetic, + C: Curve + ScalarArithmetic, { type Output = Scalar; @@ -169,7 +168,7 @@ where impl TryFrom<&[u8]> for NonZeroScalar where - C: Curve + ProjectiveArithmetic, + C: Curve + ScalarArithmetic, { type Error = Error; @@ -187,7 +186,7 @@ where impl Zeroize for NonZeroScalar where - C: Curve + ProjectiveArithmetic, + C: Curve + ScalarArithmetic, { fn zeroize(&mut self) { // Use zeroize's volatile writes to ensure value is cleared. From 5c7394c420b6c536a5babf02f4d985650de49b34 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 17 Nov 2021 11:11:50 -0700 Subject: [PATCH 0656/1461] elliptic-curve: include README.md in rustdoc + expand docs (#813) Uses the new `doc = include_str!("...")` attribute to include README.md in the rustdoc documentation. Additionally fills out the toplevel rustdoc with a bit more information about how the crate is intended to be used. --- elliptic-curve/src/dev.rs | 6 ++++-- elliptic-curve/src/lib.rs | 33 +++++++++++++++++++++++++------- elliptic-curve/src/secret_key.rs | 6 +++--- 3 files changed, 33 insertions(+), 12 deletions(-) diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index dd44501a8..73642b9d2 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -1,5 +1,7 @@ -//! Development-related functionality: helpers and types for writing tests -//! against concrete implementations of the traits in this crate. +//! Development-related functionality. +//! +//! Helpers and types for writing tests against concrete implementations of +//! the traits in this crate. use crate::{ bigint::{Limb, U256}, diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index bb8346685..7396080ae 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -1,13 +1,32 @@ -//! General purpose Elliptic Curve Cryptography (ECC) support, including types -//! and traits for representing various elliptic curve forms, scalars, points, -//! and public/secret keys composed thereof. +#![doc = include_str!("../README.md")] + +//! ## Usage +//! +//! This crate provides traits for describing elliptic curves, along with +//! types which are generic over elliptic curves which can be used as the +//! basis of curve-agnostic code. +//! +//! It's intended to be used with the following concrete elliptic curve +//! implementations from the [`RustCrypto/elliptic-curves`] project: //! -//! ## Minimum Supported Rust Version +//! - [`bp256`]: brainpoolP256r1 and brainpoolP256t1 +//! - [`bp384`]: brainpoolP384r1 and brainpoolP384t1 +//! - [`k256`]: secp256k1 a.k.a. K-256 +//! - [`p256`]: NIST P-256 a.k.a secp256r1, prime256v1 +//! - [`p384`]: NIST P-384 a.k.a. secp384r1 //! -//! Rust **1.56** or higher. +//! The [`ecdsa`] crate provides a generic implementation of the +//! Elliptic Curve Digital Signature Algorithm which can be used with any of +//! the above crates, either via an external ECDSA implementation, or +//! using native curve arithmetic where applicable. //! -//! Minimum supported Rust version can be changed in the future, but it will be -//! done with a minor version bump. +//! [`RustCrypto/elliptic-curves`]: https://github.com/RustCrypto/elliptic-curves +//! [`bp256`]: https://github.com/RustCrypto/elliptic-curves/tree/master/bp256 +//! [`bp384`]: https://github.com/RustCrypto/elliptic-curves/tree/master/bp384 +//! [`k256`]: https://github.com/RustCrypto/elliptic-curves/tree/master/k256 +//! [`p256`]: https://github.com/RustCrypto/elliptic-curves/tree/master/p256 +//! [`p384`]: https://github.com/RustCrypto/elliptic-curves/tree/master/p384 +//! [`ecdsa`]: https://github.com/RustCrypto/signatures/tree/master/ecdsa #![no_std] #![cfg_attr(docsrs, feature(doc_cfg))] diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 7b3c3a0f4..8dc3f07e2 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -53,7 +53,7 @@ use crate::{ }; #[cfg(all(docsrs, feature = "pkcs8"))] -use {crate::pkcs8::FromPrivateKey, core::str::FromStr}; +use {crate::pkcs8::DecodePrivateKey, core::str::FromStr}; /// Type label for PEM-encoded SEC1 private keys. #[cfg(feature = "pem")] @@ -79,7 +79,7 @@ pub(crate) const SEC1_PEM_TYPE_LABEL: &str = "EC PRIVATE KEY"; /// To decode an elliptic curve private key from PKCS#8, enable the `pkcs8` /// feature of this crate (or the `pkcs8` feature of a specific RustCrypto /// elliptic curve crate) and use the -/// [`elliptic_curve::pkcs8::FromPrivateKey`][`FromPrivateKey`] +/// [`elliptic_curve::pkcs8::DecodePrivateKey`][`DecodePrivateKey`] /// trait to parse it. /// /// When the `pem` feature of this crate (or a specific RustCrypto elliptic @@ -188,7 +188,7 @@ where #[cfg(all(feature = "alloc", feature = "arithmetic", feature = "sec1"))] #[cfg_attr( docsrs, - doc(cfg(feature = "alloc", feature = "arithmetic", feature = "sec1")) + doc(cfg(all(feature = "alloc", feature = "arithmetic", feature = "sec1"))) )] pub fn to_sec1_der(&self) -> der::Result>> where From 0b265023ae709a2cf482eebe65d6b4d53824c0e2 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 17 Nov 2021 14:02:53 -0700 Subject: [PATCH 0657/1461] elliptic-curve: add `scalar::IsHigh` trait (#814) Adds a trait for determining if a given scalar is larger than the order divided by 2. This is useful for "normalization" use cases such as low-S normalized ECDSA signatures, where a scalar is conditionally negated if "high". --- elliptic-curve/Cargo.lock | 8 ++++---- elliptic-curve/src/arithmetic.rs | 3 ++- elliptic-curve/src/dev.rs | 8 +++++++- elliptic-curve/src/lib.rs | 2 +- elliptic-curve/src/scalar.rs | 13 +++++++++++++ elliptic-curve/src/scalar/core.rs | 12 +++++++++++- 6 files changed, 38 insertions(+), 8 deletions(-) diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index 19e31bd1b..5ffaab435 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -34,9 +34,9 @@ checksum = "d355758f44afa81c21e66e1301d47cbffbbcde4b405cbe46b8b19f213abf9f60" [[package]] name = "crypto-bigint" -version = "0.3.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "476ecdba12db8402a1664482de8c37fff7dc96241258bd0de1f0d70e760a45fd" +checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21" dependencies = [ "generic-array", "rand_core", @@ -212,9 +212,9 @@ checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" [[package]] name = "serde_json" -version = "1.0.70" +version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e277c495ac6cd1a01a58d0a0c574568b4d1ddf14f59965c6a58b8d96400b54f3" +checksum = "063bf466a64011ac24040a49009724ee60a57da1b437617ceb32e53ad61bfb19" dependencies = [ "itoa", "ryu", diff --git a/elliptic-curve/src/arithmetic.rs b/elliptic-curve/src/arithmetic.rs index ece0fd029..40980f969 100644 --- a/elliptic-curve/src/arithmetic.rs +++ b/elliptic-curve/src/arithmetic.rs @@ -1,6 +1,6 @@ //! Elliptic curve arithmetic traits. -use crate::{Curve, FieldBytes, PrimeCurve, ScalarCore}; +use crate::{Curve, FieldBytes, IsHigh, PrimeCurve, ScalarCore}; use core::fmt::Debug; use subtle::{ConditionallySelectable, ConstantTimeEq}; use zeroize::DefaultIsZeroes; @@ -77,6 +77,7 @@ pub trait ScalarArithmetic: Curve { + From> + Into> + Into + + IsHigh + ff::Field + ff::PrimeField>; } diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 73642b9d2..3984e81cb 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -12,7 +12,7 @@ use crate::{ sec1::{FromEncodedPoint, ToEncodedPoint}, subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}, zeroize::DefaultIsZeroes, - AffineArithmetic, AlgorithmParameters, Curve, PrimeCurve, ProjectiveArithmetic, + AffineArithmetic, AlgorithmParameters, Curve, IsHigh, PrimeCurve, ProjectiveArithmetic, ScalarArithmetic, }; use core::{ @@ -346,6 +346,12 @@ impl From<&Scalar> for FieldBytes { } } +impl IsHigh for Scalar { + fn is_high(&self) -> Choice { + self.0.is_high() + } +} + /// Example affine point type #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum AffinePoint { diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 7396080ae..6cef2e348 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -79,7 +79,7 @@ mod jwk; pub use crate::{ error::{Error, Result}, point::{DecompactPoint, DecompressPoint, PointCompaction, PointCompression}, - scalar::core::ScalarCore, + scalar::{core::ScalarCore, IsHigh}, secret_key::SecretKey, }; pub use crypto_bigint as bigint; diff --git a/elliptic-curve/src/scalar.rs b/elliptic-curve/src/scalar.rs index 8e04ee497..e8a5be8b1 100644 --- a/elliptic-curve/src/scalar.rs +++ b/elliptic-curve/src/scalar.rs @@ -1,5 +1,7 @@ //! Scalar types. +use subtle::Choice; + pub(crate) mod core; #[cfg(feature = "arithmetic")] @@ -17,3 +19,14 @@ pub type Scalar = ::Scalar; #[cfg(feature = "bits")] #[cfg_attr(docsrs, doc(cfg(feature = "bits")))] pub type ScalarBits = ff::FieldBits< as ff::PrimeFieldBits>::ReprBits>; + +/// Is this scalar greater than n / 2? +/// +/// # Returns +/// +/// - For scalars 0 through n / 2: `Choice::from(0)` +/// - For scalars (n / 2) + 1 through n - 1: `Choice::from(1)` +pub trait IsHigh { + /// Is this scalar greater than or equal to n / 2? + fn is_high(&self) -> Choice; +} diff --git a/elliptic-curve/src/scalar/core.rs b/elliptic-curve/src/scalar/core.rs index 8edb8df86..6b6533c71 100644 --- a/elliptic-curve/src/scalar/core.rs +++ b/elliptic-curve/src/scalar/core.rs @@ -7,7 +7,7 @@ use crate::{ Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeGreater, ConstantTimeLess, CtOption, }, - Curve, Error, FieldBytes, Result, + Curve, Error, FieldBytes, IsHigh, Result, }; use core::{ cmp::Ordering, @@ -337,3 +337,13 @@ where -*self } } + +impl IsHigh for ScalarCore +where + C: Curve, +{ + fn is_high(&self) -> Choice { + let n_2 = C::ORDER >> 1; + self.inner.ct_gt(&n_2) + } +} From dc787822dbda6897d327917ed73cadec3f320c99 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 17 Nov 2021 14:13:44 -0700 Subject: [PATCH 0658/1461] elliptic-curve: impl `IsHigh` for `NonZeroScalar` (#815) Add support for determining if a given non-zero scalar is in the upper or lower half of the order. --- crypto/Cargo.lock | 4 ++-- elliptic-curve/src/scalar/non_zero.rs | 11 ++++++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/crypto/Cargo.lock b/crypto/Cargo.lock index 8d0f1e283..262b494fe 100644 --- a/crypto/Cargo.lock +++ b/crypto/Cargo.lock @@ -57,9 +57,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.3.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "476ecdba12db8402a1664482de8c37fff7dc96241258bd0de1f0d70e760a45fd" +checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21" dependencies = [ "generic-array", "rand_core", diff --git a/elliptic-curve/src/scalar/non_zero.rs b/elliptic-curve/src/scalar/non_zero.rs index c3edf4fc2..8a1749676 100644 --- a/elliptic-curve/src/scalar/non_zero.rs +++ b/elliptic-curve/src/scalar/non_zero.rs @@ -4,7 +4,7 @@ use crate::{ bigint::Encoding as _, ops::Invert, rand_core::{CryptoRng, RngCore}, - Curve, Error, FieldBytes, Result, Scalar, ScalarArithmetic, ScalarCore, SecretKey, + Curve, Error, FieldBytes, IsHigh, Result, Scalar, ScalarArithmetic, ScalarCore, SecretKey, }; use core::ops::Deref; use ff::{Field, PrimeField}; @@ -166,6 +166,15 @@ where } } +impl IsHigh for NonZeroScalar +where + C: Curve + ScalarArithmetic, +{ + fn is_high(&self) -> Choice { + self.scalar.is_high() + } +} + impl TryFrom<&[u8]> for NonZeroScalar where C: Curve + ScalarArithmetic, From f484ed6326282dc834451ae5a51cda4e60f275bf Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 17 Nov 2021 14:22:56 -0700 Subject: [PATCH 0659/1461] elliptic-curve: impl `Neg` for `NonZeroScalar` (#816) --- elliptic-curve/src/scalar/non_zero.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/elliptic-curve/src/scalar/non_zero.rs b/elliptic-curve/src/scalar/non_zero.rs index 8a1749676..818f5d101 100644 --- a/elliptic-curve/src/scalar/non_zero.rs +++ b/elliptic-curve/src/scalar/non_zero.rs @@ -6,7 +6,7 @@ use crate::{ rand_core::{CryptoRng, RngCore}, Curve, Error, FieldBytes, IsHigh, Result, Scalar, ScalarArithmetic, ScalarCore, SecretKey, }; -use core::ops::Deref; +use core::ops::{Deref, Neg}; use ff::{Field, PrimeField}; use generic_array::GenericArray; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; @@ -175,6 +175,19 @@ where } } +impl Neg for NonZeroScalar +where + C: Curve + ScalarArithmetic, +{ + type Output = NonZeroScalar; + + fn neg(self) -> NonZeroScalar { + let scalar = -self.scalar; + debug_assert!(!bool::from(scalar.is_zero())); + NonZeroScalar { scalar } + } +} + impl TryFrom<&[u8]> for NonZeroScalar where C: Curve + ScalarArithmetic, From 7d813023da0ce6e418e4f7bf3b0dda9914a891cb Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 17 Nov 2021 16:59:01 -0700 Subject: [PATCH 0660/1461] elliptic-curve: add `AffineXCoordinate` trait (#817) Protocols like ECDH and ECDSA rely on x-coordinate access. We've tried various ways of trying to keep affine coordinate access out of the public API, but it complicates generic implementations of these protocols. Most recently RustCrypto/signatures#395 attempted to add a trait which encapsulated ECDSA signing, but a similar (or expaned version of the same) trait is needed for verification. All of these problems go away, and can be expressed with simple trait bounds, if there is some way to access the x-coordinate of an `AffinePoint` as serialized `FieldBytes`. This commit adds such a trait: `AffineXCoordinate`, which is a mandatory bound of `AffineArithmetic::AffinePoint`. --- elliptic-curve/src/arithmetic.rs | 3 ++- elliptic-curve/src/dev.rs | 10 ++++++++-- elliptic-curve/src/ecdh.rs | 23 +++++++++++++++-------- elliptic-curve/src/lib.rs | 4 +++- elliptic-curve/src/point.rs | 26 ++++++++++++++++---------- 5 files changed, 44 insertions(+), 22 deletions(-) diff --git a/elliptic-curve/src/arithmetic.rs b/elliptic-curve/src/arithmetic.rs index 40980f969..b69c1a408 100644 --- a/elliptic-curve/src/arithmetic.rs +++ b/elliptic-curve/src/arithmetic.rs @@ -1,6 +1,6 @@ //! Elliptic curve arithmetic traits. -use crate::{Curve, FieldBytes, IsHigh, PrimeCurve, ScalarCore}; +use crate::{AffineXCoordinate, Curve, FieldBytes, IsHigh, PrimeCurve, ScalarCore}; use core::fmt::Debug; use subtle::{ConditionallySelectable, ConstantTimeEq}; use zeroize::DefaultIsZeroes; @@ -10,6 +10,7 @@ use zeroize::DefaultIsZeroes; pub trait AffineArithmetic: Curve + ScalarArithmetic { /// Elliptic curve point in affine coordinates. type AffinePoint: 'static + + AffineXCoordinate + Copy + Clone + ConditionallySelectable diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 3984e81cb..1da6c6316 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -12,8 +12,8 @@ use crate::{ sec1::{FromEncodedPoint, ToEncodedPoint}, subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}, zeroize::DefaultIsZeroes, - AffineArithmetic, AlgorithmParameters, Curve, IsHigh, PrimeCurve, ProjectiveArithmetic, - ScalarArithmetic, + AffineArithmetic, AffineXCoordinate, AlgorithmParameters, Curve, IsHigh, PrimeCurve, + ProjectiveArithmetic, ScalarArithmetic, }; use core::{ iter::Sum, @@ -368,6 +368,12 @@ pub enum AffinePoint { Other(EncodedPoint), } +impl AffineXCoordinate for AffinePoint { + fn x(&self) -> FieldBytes { + unimplemented!(); + } +} + impl ConstantTimeEq for AffinePoint { fn ct_eq(&self, _other: &Self) -> Choice { unimplemented!(); diff --git a/elliptic-curve/src/ecdh.rs b/elliptic-curve/src/ecdh.rs index 5af896e78..90aff47f6 100644 --- a/elliptic-curve/src/ecdh.rs +++ b/elliptic-curve/src/ecdh.rs @@ -27,7 +27,8 @@ //! [SIGMA]: https://webee.technion.ac.il/~hugo/sigma-pdf.pdf use crate::{ - AffinePoint, Curve, FieldBytes, NonZeroScalar, ProjectiveArithmetic, ProjectivePoint, PublicKey, + AffineArithmetic, AffinePoint, AffineXCoordinate, Curve, FieldBytes, NonZeroScalar, + ProjectiveArithmetic, ProjectivePoint, PublicKey, }; use core::borrow::Borrow; use group::Curve as _; @@ -60,13 +61,10 @@ pub fn diffie_hellman( ) -> SharedSecret where C: Curve + ProjectiveArithmetic, - SharedSecret: for<'a> From<&'a AffinePoint>, { let public_point = ProjectivePoint::::from(*public_key.borrow()); - let mut secret_point = (public_point * secret_key.borrow().as_ref()).to_affine(); - let shared_secret = SharedSecret::from(&secret_point); - secret_point.zeroize(); - shared_secret + let secret_point = (public_point * secret_key.borrow().as_ref()).to_affine(); + SharedSecret::new(secret_point) } /// Ephemeral Diffie-Hellman Secret. @@ -100,7 +98,6 @@ where impl EphemeralSecret where C: Curve + ProjectiveArithmetic, - SharedSecret: for<'a> From<&'a AffinePoint>, { /// Generate a cryptographically random [`EphemeralSecret`]. pub fn random(rng: impl CryptoRng + RngCore) -> Self { @@ -126,7 +123,6 @@ where impl From<&EphemeralSecret> for PublicKey where C: Curve + ProjectiveArithmetic, - SharedSecret: for<'a> From<&'a AffinePoint>, { fn from(ephemeral_secret: &EphemeralSecret) -> Self { ephemeral_secret.public_key() @@ -172,6 +168,17 @@ pub struct SharedSecret { } impl SharedSecret { + /// Create a new [`SharedSecret`] from an [`AffinePoint`] for this curve. + #[inline] + fn new(point: AffinePoint) -> Self + where + C: AffineArithmetic, + { + Self { + secret_bytes: point.x(), + } + } + /// Shared secret value, serialized as bytes. /// /// As noted in the comments for this struct, this value is non-uniform and diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 6cef2e348..02ba070a7 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -78,7 +78,9 @@ mod jwk; pub use crate::{ error::{Error, Result}, - point::{DecompactPoint, DecompressPoint, PointCompaction, PointCompression}, + point::{ + AffineXCoordinate, DecompactPoint, DecompressPoint, PointCompaction, PointCompression, + }, scalar::{core::ScalarCore, IsHigh}, secret_key::SecretKey, }; diff --git a/elliptic-curve/src/point.rs b/elliptic-curve/src/point.rs index 4ff58aeee..825db3fd1 100644 --- a/elliptic-curve/src/point.rs +++ b/elliptic-curve/src/point.rs @@ -3,16 +3,10 @@ use crate::{Curve, FieldBytes}; use subtle::{Choice, CtOption}; -/// Point compression settings. -pub trait PointCompression { - /// Should point compression be applied by default? - const COMPRESS_POINTS: bool; -} - -/// Point compaction settings. -pub trait PointCompaction { - /// Should point compaction be applied by default? - const COMPACT_POINTS: bool; +/// Obtain the affine x-coordinate of an elliptic curve point. +pub trait AffineXCoordinate { + /// Get the affine x-coordinate as a serialized field element. + fn x(&self) -> FieldBytes; } /// Attempt to decompress an elliptic curve point from its x-coordinate and @@ -27,3 +21,15 @@ pub trait DecompactPoint: Sized { /// Attempt to decompact an elliptic curve point fn decompact(x: &FieldBytes) -> CtOption; } + +/// Point compression settings. +pub trait PointCompression { + /// Should point compression be applied by default? + const COMPRESS_POINTS: bool; +} + +/// Point compaction settings. +pub trait PointCompaction { + /// Should point compaction be applied by default? + const COMPACT_POINTS: bool; +} From 88d5ea3ad633d13c9ac3b064c084f645830d7713 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 18 Nov 2021 18:18:03 -0700 Subject: [PATCH 0661/1461] elliptic-curve: `serde` support for scalar and `PublicKey` types (#818) Adds support for serializing/deserializing the following types using serde: - `ScalarCore` - `NonZeroScalar` - `PublicKey` While this crate had `serde` support previously, it was entirely limited to the JWK implementation. This commit expands it to support more types, and provides the underpinnings for better leveraging `serde` in all of the dependent crates. --- .github/workflows/elliptic-curve.yml | 4 +- elliptic-curve/Cargo.lock | 4 +- elliptic-curve/src/hex.rs | 127 ++++++++++++++++++++++++++ elliptic-curve/src/lib.rs | 4 + elliptic-curve/src/public_key.rs | 42 +++++++++ elliptic-curve/src/scalar/core.rs | 109 +++++++++++++++++++++- elliptic-curve/src/scalar/non_zero.rs | 47 +++++++++- 7 files changed, 332 insertions(+), 5 deletions(-) create mode 100644 elliptic-curve/src/hex.rs diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index 621579ce6..2448a6627 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -36,6 +36,7 @@ jobs: target: ${{ matrix.target }} override: true - run: cargo build --target ${{ matrix.target }} --release --no-default-features + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features arithmetic - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features bits - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features dev @@ -45,9 +46,10 @@ jobs: - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features pem - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features pkcs8 - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features sec1 + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features serde - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features pkcs8,sec1 - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features pem,pkcs8,sec1 - - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features ecdh,hazmat,jwk,pem,pkcs8,sec1 + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,ecdh,hazmat,jwk,pem,pkcs8,sec1,serde test: runs-on: ubuntu-latest diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index 5ffaab435..ebeec275a 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -193,9 +193,9 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "sec1" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2503adcd8c83e7081b3f9a3173f328f4d6cd50e116aaa324389b46f2d771d595" +checksum = "08da66b8b0965a5555b6bd6639e68ccba85e1e2506f5fbb089e93f8a04e1a2d1" dependencies = [ "der", "generic-array", diff --git a/elliptic-curve/src/hex.rs b/elliptic-curve/src/hex.rs new file mode 100644 index 000000000..4c0f37fd1 --- /dev/null +++ b/elliptic-curve/src/hex.rs @@ -0,0 +1,127 @@ +//! Hexadecimal encoding helpers + +use crate::{Error, Result}; +use core::{fmt, str}; + +/// Write the provided slice to the formatter as lower case hexadecimal +#[inline] +pub(crate) fn write_lower(slice: &[u8], formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + for byte in slice { + write!(formatter, "{:02x}", byte)?; + } + Ok(()) +} + +/// Write the provided slice to the formatter as upper case hexadecimal +#[inline] +pub(crate) fn write_upper(slice: &[u8], formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + for byte in slice { + write!(formatter, "{:02X}", byte)?; + } + Ok(()) +} + +/// Decode the provided hexadecimal string into the provided buffer. +/// +/// Accepts either lower case or upper case hexadecimal, but not mixed. +// TODO(tarcieri): constant-time hex decoder? +pub(crate) fn decode(hex: &str, out: &mut [u8]) -> Result<()> { + if hex.as_bytes().len() != out.len() * 2 { + return Err(Error); + } + + let mut upper_case = None; + + // Ensure all characters are valid and case is not mixed + for &byte in hex.as_bytes() { + match byte { + b'0'..=b'9' => (), + b'a'..=b'z' => match upper_case { + Some(true) => return Err(Error), + Some(false) => (), + None => upper_case = Some(false), + }, + b'A'..=b'Z' => match upper_case { + Some(true) => (), + Some(false) => return Err(Error), + None => upper_case = Some(true), + }, + _ => return Err(Error), + } + } + + for (digit, byte) in hex.as_bytes().chunks_exact(2).zip(out.iter_mut()) { + *byte = str::from_utf8(digit) + .ok() + .and_then(|s| u8::from_str_radix(s, 16).ok()) + .ok_or(Error)?; + } + + Ok(()) +} + +#[cfg(all(test, feature = "std"))] +mod tests { + use core::fmt; + use hex_literal::hex; + + const EXAMPLE_DATA: &[u8] = &hex!("0123456789ABCDEF"); + const EXAMPLE_HEX_LOWER: &str = "0123456789abcdef"; + const EXAMPLE_HEX_UPPER: &str = "0123456789ABCDEF"; + + struct Wrapper<'a>(&'a [u8]); + + impl fmt::LowerHex for Wrapper<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + super::write_lower(self.0, f) + } + } + + impl fmt::UpperHex for Wrapper<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + super::write_upper(self.0, f) + } + } + + #[test] + fn decode_lower() { + let mut buf = [0u8; 8]; + super::decode(EXAMPLE_HEX_LOWER, &mut buf).unwrap(); + assert_eq!(buf, EXAMPLE_DATA); + } + + #[test] + fn decode_upper() { + let mut buf = [0u8; 8]; + super::decode(EXAMPLE_HEX_LOWER, &mut buf).unwrap(); + assert_eq!(buf, EXAMPLE_DATA); + } + + #[test] + fn decode_rejects_mixed_case() { + let mut buf = [0u8; 8]; + assert!(super::decode("0123456789abcDEF", &mut buf).is_err()); + } + + #[test] + fn decode_rejects_too_short() { + let mut buf = [0u8; 9]; + assert!(super::decode(EXAMPLE_HEX_LOWER, &mut buf).is_err()); + } + + #[test] + fn decode_rejects_too_long() { + let mut buf = [0u8; 7]; + assert!(super::decode(EXAMPLE_HEX_LOWER, &mut buf).is_err()); + } + + #[test] + fn encode_lower() { + assert_eq!(format!("{:x}", Wrapper(EXAMPLE_DATA)), EXAMPLE_HEX_LOWER); + } + + #[test] + fn encode_upper() { + assert_eq!(format!("{:X}", Wrapper(EXAMPLE_DATA)), EXAMPLE_HEX_UPPER); + } +} diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 02ba070a7..4fd6ce390 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -56,6 +56,7 @@ pub mod ops; pub mod sec1; mod error; +mod hex; mod point; mod scalar; mod secret_key; @@ -112,6 +113,9 @@ pub use crate::jwk::{JwkEcKey, JwkParameters}; #[cfg(feature = "pkcs8")] pub use ::sec1::pkcs8; +#[cfg(feature = "serde")] +pub use serde; + use core::fmt::Debug; use generic_array::GenericArray; diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index 59382c0f9..4ff04aae7 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -31,6 +31,10 @@ use { #[cfg(any(feature = "jwk", feature = "pem"))] use alloc::string::{String, ToString}; +#[cfg(all(feature = "pem", feature = "serde"))] +#[cfg_attr(docsrs, doc(all(feature = "pem", feature = "serde")))] +use serde::{de, ser, Deserialize, Serialize}; + /// Elliptic curve public keys. /// /// This is a wrapper type for [`AffinePoint`] which ensures an inner @@ -339,6 +343,44 @@ where } } +#[cfg(all(feature = "pem", feature = "serde"))] +#[cfg_attr(docsrs, doc(all(feature = "pem", feature = "serde")))] +impl Serialize for PublicKey +where + C: Curve + AlgorithmParameters + ProjectiveArithmetic, + AffinePoint: FromEncodedPoint + ToEncodedPoint, + FieldSize: ModulusSize, +{ + fn serialize(&self, serializer: S) -> core::result::Result + where + S: ser::Serializer, + { + self.to_public_key_der() + .map_err(ser::Error::custom)? + .as_ref() + .serialize(serializer) + } +} + +#[cfg(all(feature = "pem", feature = "serde"))] +#[cfg_attr(docsrs, doc(all(feature = "pem", feature = "serde")))] +impl<'de, C> Deserialize<'de> for PublicKey +where + C: Curve + AlgorithmParameters + ProjectiveArithmetic, + AffinePoint: FromEncodedPoint + ToEncodedPoint, + FieldSize: ModulusSize, +{ + fn deserialize(deserializer: D) -> core::result::Result + where + D: de::Deserializer<'de>, + { + use de::Error; + + <&[u8]>::deserialize(deserializer) + .and_then(|bytes| Self::from_public_key_der(bytes).map_err(D::Error::custom)) + } +} + #[cfg(all(feature = "dev", test))] mod tests { use crate::{dev::MockCurve, sec1::FromEncodedPoint}; diff --git a/elliptic-curve/src/scalar/core.rs b/elliptic-curve/src/scalar/core.rs index 6b6533c71..5d0bf9e92 100644 --- a/elliptic-curve/src/scalar/core.rs +++ b/elliptic-curve/src/scalar/core.rs @@ -2,6 +2,7 @@ use crate::{ bigint::{prelude::*, Limb, NonZero}, + hex, rand_core::{CryptoRng, RngCore}, subtle::{ Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeGreater, ConstantTimeLess, @@ -11,7 +12,9 @@ use crate::{ }; use core::{ cmp::Ordering, + fmt, ops::{Add, AddAssign, Neg, Sub, SubAssign}, + str, }; use generic_array::GenericArray; use zeroize::DefaultIsZeroes; @@ -22,6 +25,9 @@ use { group::ff::PrimeField, }; +#[cfg(feature = "serde")] +use serde::{de, ser, Deserialize, Serialize}; + /// Generic scalar type with core functionality. /// /// This type provides a baseline level of scalar arithmetic functionality @@ -123,7 +129,7 @@ where } /// Encode [`ScalarCore`] as little endian bytes. - pub fn to_bytes_le(self) -> FieldBytes { + pub fn to_le_bytes(self) -> FieldBytes { self.inner.to_le_byte_array() } } @@ -347,3 +353,104 @@ where self.inner.ct_gt(&n_2) } } + +impl fmt::Display for ScalarCore +where + C: Curve, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{:X}", self) + } +} + +impl fmt::LowerHex for ScalarCore +where + C: Curve, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + hex::write_lower(&self.to_be_bytes(), f) + } +} + +impl fmt::UpperHex for ScalarCore +where + C: Curve, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + hex::write_upper(&self.to_be_bytes(), f) + } +} + +impl str::FromStr for ScalarCore +where + C: Curve, +{ + type Err = Error; + + fn from_str(hex: &str) -> Result { + let mut bytes = FieldBytes::::default(); + hex::decode(hex, &mut bytes)?; + Option::from(Self::from_be_bytes(bytes)).ok_or(Error) + } +} + +#[cfg(feature = "serde")] +#[cfg_attr(docsrs, doc(cfg(feature = "serde")))] +impl Serialize for ScalarCore +where + C: Curve, +{ + #[cfg(not(feature = "alloc"))] + fn serialize(&self, serializer: S) -> core::result::Result + where + S: ser::Serializer, + { + self.to_be_bytes().as_slice().serialize(serializer) + } + + #[cfg(feature = "alloc")] + fn serialize(&self, serializer: S) -> core::result::Result + where + S: ser::Serializer, + { + use alloc::string::ToString; + if serializer.is_human_readable() { + self.to_string().serialize(serializer) + } else { + self.to_be_bytes().as_slice().serialize(serializer) + } + } +} + +#[cfg(feature = "serde")] +#[cfg_attr(docsrs, doc(cfg(feature = "serde")))] +impl<'de, C> Deserialize<'de> for ScalarCore +where + C: Curve, +{ + #[cfg(not(feature = "alloc"))] + fn deserialize(deserializer: D) -> core::result::Result + where + D: de::Deserializer<'de>, + { + use de::Error; + <&[u8]>::deserialize(deserializer) + .and_then(|slice| Self::from_be_slice(slice).map_err(D::Error::custom)) + } + + #[cfg(feature = "alloc")] + fn deserialize(deserializer: D) -> core::result::Result + where + D: de::Deserializer<'de>, + { + use de::Error; + if deserializer.is_human_readable() { + <&str>::deserialize(deserializer)? + .parse() + .map_err(D::Error::custom) + } else { + <&[u8]>::deserialize(deserializer) + .and_then(|slice| Self::from_be_slice(slice).map_err(D::Error::custom)) + } + } +} diff --git a/elliptic-curve/src/scalar/non_zero.rs b/elliptic-curve/src/scalar/non_zero.rs index 818f5d101..498e6ac1c 100644 --- a/elliptic-curve/src/scalar/non_zero.rs +++ b/elliptic-curve/src/scalar/non_zero.rs @@ -2,11 +2,16 @@ use crate::{ bigint::Encoding as _, + hex, ops::Invert, rand_core::{CryptoRng, RngCore}, Curve, Error, FieldBytes, IsHigh, Result, Scalar, ScalarArithmetic, ScalarCore, SecretKey, }; -use core::ops::{Deref, Neg}; +use core::{ + fmt, + ops::{Deref, Neg}, + str, +}; use ff::{Field, PrimeField}; use generic_array::GenericArray; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; @@ -220,6 +225,46 @@ where } } +impl fmt::Display for NonZeroScalar +where + C: Curve + ScalarArithmetic, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{:X}", self) + } +} + +impl fmt::LowerHex for NonZeroScalar +where + C: Curve + ScalarArithmetic, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + hex::write_lower(&self.to_repr(), f) + } +} + +impl fmt::UpperHex for NonZeroScalar +where + C: Curve + ScalarArithmetic, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + hex::write_upper(&self.to_repr(), f) + } +} + +impl str::FromStr for NonZeroScalar +where + C: Curve + ScalarArithmetic, +{ + type Err = Error; + + fn from_str(hex: &str) -> Result { + let mut bytes = FieldBytes::::default(); + hex::decode(hex, &mut bytes)?; + Option::from(Self::from_repr(bytes)).ok_or(Error) + } +} + #[cfg(all(test, feature = "dev"))] mod tests { use crate::dev::{NonZeroScalar, Scalar}; From bd1f7122d668a866037886462c380bdc89b5f412 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 19 Nov 2021 09:59:03 -0700 Subject: [PATCH 0662/1461] elliptic-curve: fix `doc(cfg(...))` attributes (#820) --- elliptic-curve/src/public_key.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index 4ff04aae7..8875ec987 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -32,7 +32,7 @@ use { use alloc::string::{String, ToString}; #[cfg(all(feature = "pem", feature = "serde"))] -#[cfg_attr(docsrs, doc(all(feature = "pem", feature = "serde")))] +#[cfg_attr(docsrs, doc(cfg(all(feature = "pem", feature = "serde"))))] use serde::{de, ser, Deserialize, Serialize}; /// Elliptic curve public keys. @@ -344,7 +344,7 @@ where } #[cfg(all(feature = "pem", feature = "serde"))] -#[cfg_attr(docsrs, doc(all(feature = "pem", feature = "serde")))] +#[cfg_attr(docsrs, doc(cfg(all(feature = "pem", feature = "serde"))))] impl Serialize for PublicKey where C: Curve + AlgorithmParameters + ProjectiveArithmetic, @@ -363,7 +363,7 @@ where } #[cfg(all(feature = "pem", feature = "serde"))] -#[cfg_attr(docsrs, doc(all(feature = "pem", feature = "serde")))] +#[cfg_attr(docsrs, doc(cfg(all(feature = "pem", feature = "serde"))))] impl<'de, C> Deserialize<'de> for PublicKey where C: Curve + AlgorithmParameters + ProjectiveArithmetic, From 2b92d8602640d2ae1093672b8aa50833ef61c9a4 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 20 Nov 2021 07:48:37 -0700 Subject: [PATCH 0663/1461] elliptic-curve v0.11.0 (#821) --- crypto/Cargo.lock | 28 ++++++++++---------- crypto/Cargo.toml | 6 +---- elliptic-curve/CHANGELOG.md | 52 ++++++++++++++++++++++++++++++++++++- elliptic-curve/Cargo.lock | 2 +- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 2 +- 6 files changed, 69 insertions(+), 23 deletions(-) diff --git a/crypto/Cargo.lock b/crypto/Cargo.lock index 262b494fe..0a42ba1f7 100644 --- a/crypto/Cargo.lock +++ b/crypto/Cargo.lock @@ -16,11 +16,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a32fd6af2b5827bce66c29053ba0e7c42b9dcab01835835058558c10851a46b" -[[package]] -name = "base64ct" -version = "1.2.0" -source = "git+https://github.com/RustCrypto/formats.git#271163d6c48d930190cc434c155574b1281385cf" - [[package]] name = "cfg-if" version = "1.0.0" @@ -39,7 +34,8 @@ dependencies = [ [[package]] name = "const-oid" version = "0.7.0" -source = "git+https://github.com/RustCrypto/formats.git#271163d6c48d930190cc434c155574b1281385cf" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d355758f44afa81c21e66e1301d47cbffbbcde4b405cbe46b8b19f213abf9f60" [[package]] name = "crypto" @@ -80,7 +76,8 @@ dependencies = [ [[package]] name = "der" version = "0.5.1" -source = "git+https://github.com/RustCrypto/formats.git#271163d6c48d930190cc434c155574b1281385cf" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" dependencies = [ "const-oid", ] @@ -96,7 +93,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.11.0-pre" +version = "0.11.0" dependencies = [ "crypto-bigint", "der", @@ -161,7 +158,7 @@ checksum = "fbe5e23404da5b4f555ef85ebed98fb4083e55a00c317800bc2a50ede9f3d219" name = "password-hash" version = "0.3.2" dependencies = [ - "base64ct 1.0.1", + "base64ct", "rand_core", "subtle", ] @@ -169,7 +166,8 @@ dependencies = [ [[package]] name = "pkcs8" version = "0.8.0" -source = "git+https://github.com/RustCrypto/formats.git#271163d6c48d930190cc434c155574b1281385cf" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" dependencies = [ "der", "spki", @@ -187,8 +185,9 @@ dependencies = [ [[package]] name = "sec1" -version = "0.2.0" -source = "git+https://github.com/RustCrypto/formats.git#271163d6c48d930190cc434c155574b1281385cf" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08da66b8b0965a5555b6bd6639e68ccba85e1e2506f5fbb089e93f8a04e1a2d1" dependencies = [ "der", "generic-array", @@ -204,9 +203,10 @@ version = "1.4.0" [[package]] name = "spki" version = "0.5.2" -source = "git+https://github.com/RustCrypto/formats.git#271163d6c48d930190cc434c155574b1281385cf" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8a277a21925310de1d31bb6b021da3550b00e9127096ef84ee38f44609925c4" dependencies = [ - "base64ct 1.2.0", + "base64ct", "der", ] diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 9d9fe398f..9336c4b4e 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -22,7 +22,7 @@ members = ["."] aead = { version = "0.4", optional = true, path = "../aead" } cipher = { version = "0.3", optional = true } digest = { version = "0.9", optional = true } -elliptic-curve = { version = "=0.11.0-pre", optional = true, path = "../elliptic-curve" } +elliptic-curve = { version = "0.11", optional = true, path = "../elliptic-curve" } mac = { version = "0.11", package = "crypto-mac", optional = true } password-hash = { version = "0.3", optional = true, path = "../password-hash" } signature = { version = "1.3.0", optional = true, default-features = false, path = "../signature" } @@ -42,7 +42,3 @@ std = [ [package.metadata.docs.rs] all-features = true - -[patch.crates-io] -der = { git = "https://github.com/RustCrypto/formats.git" } -sec1 = { git = "https://github.com/RustCrypto/formats.git" } diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index a7e520862..9c11c3270 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,56 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.11.0 (2021-11-19) +### Added +- `ScalarCore` type ([#732]) +- `PrimeCurveArithmetic` trait ([#739]) +- SEC1 private key support ([#762]) +- `Reduce` trait ([#768]) +- Re-export `ff` and `PrimeField` ([#796]) +- `Encoding` bound on `Curve::UInt` ([#806]) +- `scalar::IsHigh` trait ([#814], [#815]) +- `Neg` impl for `NonZeroScalar` ([#816]) +- `AffineXCoordinate` trait ([#817]) +- `serde` support for scalar and `PublicKey` types ([#818]) + +### Changed +- Bump `ff` + `group` to v0.11 ([#730]) +- Make `SecretKey::to_jwk_string` self-zeroizing ([#742]) +- Use `sec1` crate's `EncodedPoint` ([#771]) +- Make `FromEncodedPoint` return a `CtOption` ([#782]) +- Rust 2021 edition upgrade; MSRV to 1.56 ([#795]) +- Bump `crypto-bigint` dependency to v0.3 ([#807]) +- Use `sec1` crate for `pkcs8` support ([#809]) +- Bump `spki` dependency to v0.5 release ([#810]) +- `NonZeroScalar` is now bounded on `ScalarArithmetic` instead of + `ProjectiveArithmetic` ([#812]) + +### Fixed +- `Zeroize` impl on `NonZeroScalar` ([#785]) + +[#730]: https://github.com/RustCrypto/traits/pull/730 +[#732]: https://github.com/RustCrypto/traits/pull/732 +[#739]: https://github.com/RustCrypto/traits/pull/739 +[#742]: https://github.com/RustCrypto/traits/pull/742 +[#762]: https://github.com/RustCrypto/traits/pull/762 +[#768]: https://github.com/RustCrypto/traits/pull/768 +[#771]: https://github.com/RustCrypto/traits/pull/771 +[#782]: https://github.com/RustCrypto/traits/pull/782 +[#785]: https://github.com/RustCrypto/traits/pull/785 +[#795]: https://github.com/RustCrypto/traits/pull/795 +[#796]: https://github.com/RustCrypto/traits/pull/796 +[#806]: https://github.com/RustCrypto/traits/pull/806 +[#807]: https://github.com/RustCrypto/traits/pull/807 +[#809]: https://github.com/RustCrypto/traits/pull/809 +[#810]: https://github.com/RustCrypto/traits/pull/810 +[#812]: https://github.com/RustCrypto/traits/pull/812 +[#814]: https://github.com/RustCrypto/traits/pull/814 +[#815]: https://github.com/RustCrypto/traits/pull/815 +[#816]: https://github.com/RustCrypto/traits/pull/816 +[#817]: https://github.com/RustCrypto/traits/pull/817 +[#818]: https://github.com/RustCrypto/traits/pull/818 + ## 0.10.6 (2021-08-23) ### Changed - Bump `crypto-bigint` dependency to v0.2.4 ([#710]) @@ -12,7 +62,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## 0.10.5 (2021-07-20) ### Changed -- Pin `zeroize` dependency to v1.4 and `subtle` to v2.4 ([#349]) +- Pin `zeroize` dependency to v1.4 and `subtle` to v2.4 ([#689]) [#689]: https://github.com/RustCrypto/traits/pull/689 diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index ebeec275a..e4651b20f 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -56,7 +56,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.11.0-pre" +version = "0.11.0" dependencies = [ "base64ct", "crypto-bigint", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index bb5eac321..1cd966a9d 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.11.0-pre" # Also update html_root_url in lib.rs when bumping this +version = "0.11.0" # Also update html_root_url in lib.rs when bumping this description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 4fd6ce390..09bd922e5 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -35,7 +35,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.11.0-pre" + html_root_url = "https://docs.rs/elliptic-curve/0.11.0" )] #[cfg(feature = "alloc")] From ba5ae8e49792e341913461fda512a46953c5cce8 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 21 Nov 2021 11:19:09 -0700 Subject: [PATCH 0664/1461] elliptic-curve: add `NonZeroScalar::from_unit` (#822) Adds a `NonZeroScalar` constructor that accepts a `C::UInt` as a parameter, returning a `CtOption` if the `UInt` represents a valid non-zero element of the scalar field. --- elliptic-curve/src/scalar/non_zero.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/elliptic-curve/src/scalar/non_zero.rs b/elliptic-curve/src/scalar/non_zero.rs index 498e6ac1c..5e54f942d 100644 --- a/elliptic-curve/src/scalar/non_zero.rs +++ b/elliptic-curve/src/scalar/non_zero.rs @@ -59,6 +59,11 @@ where pub fn from_repr(repr: FieldBytes) -> CtOption { Scalar::::from_repr(repr).and_then(Self::new) } + + /// Create a [`NonZeroScalar`] from a [`UInt`]. + pub fn from_uint(uint: C::UInt) -> CtOption { + ScalarCore::new(uint).and_then(|scalar| Self::new(scalar.into())) + } } impl AsRef> for NonZeroScalar From b7148ceb3a38cddbca05a09e98f9b700fb7941d9 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 21 Nov 2021 11:26:18 -0700 Subject: [PATCH 0665/1461] elliptic-curve v0.11.1 (#823) --- crypto/Cargo.lock | 2 +- elliptic-curve/CHANGELOG.md | 6 ++++++ elliptic-curve/Cargo.lock | 2 +- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 2 +- 5 files changed, 10 insertions(+), 4 deletions(-) diff --git a/crypto/Cargo.lock b/crypto/Cargo.lock index 0a42ba1f7..d1fac9ced 100644 --- a/crypto/Cargo.lock +++ b/crypto/Cargo.lock @@ -93,7 +93,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.11.0" +version = "0.11.1" dependencies = [ "crypto-bigint", "der", diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index 9c11c3270..0a98a435d 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.11.1 (2021-11-21) +### Added +- `NonZeroScalar::from_uint` ([#822]) + +[#822]: https://github.com/RustCrypto/traits/pull/822 + ## 0.11.0 (2021-11-19) ### Added - `ScalarCore` type ([#732]) diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index e4651b20f..3e57f3e94 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -56,7 +56,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.11.0" +version = "0.11.1" dependencies = [ "base64ct", "crypto-bigint", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 1cd966a9d..203b6fcdb 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.11.0" # Also update html_root_url in lib.rs when bumping this +version = "0.11.1" # Also update html_root_url in lib.rs when bumping this description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 09bd922e5..87750873e 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -35,7 +35,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.11.0" + html_root_url = "https://docs.rs/elliptic-curve/0.11.1" )] #[cfg(feature = "alloc")] From 6701636a6f7ad1d62c507d31563862f5093f03fe Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 3 Dec 2021 09:16:14 -0700 Subject: [PATCH 0666/1461] elliptic-curve: bump `pem-rfc7468` dependency to v0.3 (#825) --- elliptic-curve/Cargo.lock | 13 ++----------- elliptic-curve/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index 3e57f3e94..7008f4009 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -51,7 +51,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" dependencies = [ "const-oid", - "pem-rfc7468 0.3.1", + "pem-rfc7468", ] [[package]] @@ -65,7 +65,7 @@ dependencies = [ "generic-array", "group", "hex-literal", - "pem-rfc7468 0.2.3", + "pem-rfc7468", "rand_core", "sec1", "serde", @@ -141,15 +141,6 @@ version = "0.2.107" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbe5e23404da5b4f555ef85ebed98fb4083e55a00c317800bc2a50ede9f3d219" -[[package]] -name = "pem-rfc7468" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f22eb0e3c593294a99e9ff4b24cf6b752d43f193aa4415fe5077c159996d497" -dependencies = [ - "base64ct", -] - [[package]] name = "pem-rfc7468" version = "0.3.1" diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 203b6fcdb..99c14d490 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -32,7 +32,7 @@ base64ct = { version = "1", optional = true, default-features = false } ff = { version = "0.11", optional = true, default-features = false } group = { version = "0.11", optional = true, default-features = false } hex-literal = { version = "0.3", optional = true } -pem-rfc7468 = { version = "0.2", optional = true } +pem-rfc7468 = { version = "0.3", optional = true } sec1 = { version = "0.2", optional = true, features = ["subtle", "zeroize"] } serde = { version = "1", optional = true, default-features = false } serde_json = { version = "1", optional = true, default-features = false, features = ["alloc"] } From afe0b794f51c2a7d4641f3e4c42c247ed596c474 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 3 Dec 2021 09:41:05 -0700 Subject: [PATCH 0667/1461] elliptic-curve v0.11.2 (#826) --- elliptic-curve/CHANGELOG.md | 10 ++++++++-- elliptic-curve/Cargo.lock | 2 +- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 2 +- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index 0a98a435d..379ea79a6 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,13 +4,19 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 0.11.1 (2021-11-21) +## 0.11.2 (2021-12-03) +### Changed +- Bump `pem-rfc7468` dependency to v0.3 ([#825]) + +[#825]: https://github.com/RustCrypto/traits/pull/825 + +## 0.11.1 (2021-11-21) [YANKED] ### Added - `NonZeroScalar::from_uint` ([#822]) [#822]: https://github.com/RustCrypto/traits/pull/822 -## 0.11.0 (2021-11-19) +## 0.11.0 (2021-11-19) [YANKED] ### Added - `ScalarCore` type ([#732]) - `PrimeCurveArithmetic` trait ([#739]) diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index 7008f4009..9755dde9e 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -56,7 +56,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.11.1" +version = "0.11.2" dependencies = [ "base64ct", "crypto-bigint", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 99c14d490..b156ca329 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.11.1" # Also update html_root_url in lib.rs when bumping this +version = "0.11.2" # Also update html_root_url in lib.rs when bumping this description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 87750873e..16dab13f3 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -35,7 +35,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.11.1" + html_root_url = "https://docs.rs/elliptic-curve/0.11.2" )] #[cfg(feature = "alloc")] From f6ac4b06f45e97014ece847a4ce91fda817543f1 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 3 Dec 2021 12:53:51 -0700 Subject: [PATCH 0668/1461] elliptic-curve: add `ReduceNonZero` trait (#827) Adds a trait similar to `Reduce`, but where the output of the reduction is ensured to be non-zero. Also impls `Reduce` and `ReduceNonZero` for `NonZeroScalar`. This means that end users need only concern themselves with `Reduce` as they can use `NonZeroScalar::::from_uint_reduced` instead of the more cumbersome `Scalar::::from_uint_reduced_non_zero`. Related: RustCrypto/elliptic-curves#432 --- elliptic-curve/src/ops.rs | 10 ++++++++++ elliptic-curve/src/scalar/non_zero.rs | 28 ++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/elliptic-curve/src/ops.rs b/elliptic-curve/src/ops.rs index fb69b28fa..f4449a723 100644 --- a/elliptic-curve/src/ops.rs +++ b/elliptic-curve/src/ops.rs @@ -40,3 +40,13 @@ pub trait Reduce: Sized { Self::from_uint_reduced(UInt::from_le_byte_array(bytes)) } } + +/// Modular reduction to a non-zero output. +/// +/// This trait is primarily intended for use by curve implementations. +/// +/// End users can use the `Reduce` impl on `NonZeroScalar` instead. +pub trait ReduceNonZero: Sized { + /// Perform a modular reduction, returning a field element. + fn from_uint_reduced_non_zero(n: UInt) -> Self; +} diff --git a/elliptic-curve/src/scalar/non_zero.rs b/elliptic-curve/src/scalar/non_zero.rs index 5e54f942d..2692ea08e 100644 --- a/elliptic-curve/src/scalar/non_zero.rs +++ b/elliptic-curve/src/scalar/non_zero.rs @@ -3,7 +3,7 @@ use crate::{ bigint::Encoding as _, hex, - ops::Invert, + ops::{Invert, Reduce, ReduceNonZero}, rand_core::{CryptoRng, RngCore}, Curve, Error, FieldBytes, IsHigh, Result, Scalar, ScalarArithmetic, ScalarCore, SecretKey, }; @@ -12,6 +12,7 @@ use core::{ ops::{Deref, Neg}, str, }; +use crypto_bigint::{ArrayEncoding, Integer}; use ff::{Field, PrimeField}; use generic_array::GenericArray; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; @@ -198,6 +199,31 @@ where } } +/// Note: implementation is the same as `ReduceNonZero` +impl Reduce for NonZeroScalar +where + C: Curve + ScalarArithmetic, + I: Integer + ArrayEncoding, + Scalar: ReduceNonZero, +{ + fn from_uint_reduced(n: I) -> Self { + Self::from_uint_reduced_non_zero(n) + } +} + +impl ReduceNonZero for NonZeroScalar +where + C: Curve + ScalarArithmetic, + I: Integer + ArrayEncoding, + Scalar: ReduceNonZero, +{ + fn from_uint_reduced_non_zero(n: I) -> Self { + let scalar = Scalar::::from_uint_reduced_non_zero(n); + debug_assert!(!bool::from(scalar.is_zero())); + Self::new(scalar).unwrap() + } +} + impl TryFrom<&[u8]> for NonZeroScalar where C: Curve + ScalarArithmetic, From a01885d8d568c3711b9e214bb54d63e56455dda9 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 3 Dec 2021 13:22:15 -0700 Subject: [PATCH 0669/1461] elliptic-curve: `non_zero` => `nonzero` (#828) In #827, a `ReduceNonZero` trait was added whose method name uses an underscored `*_non_zero`. However, there's already one bit of precedent in the public API: - `SecretKey::to_nonzero_scalar` Since this is already a stable API and providing precedent, for consistency this commit changes all of the unstable/unreleased APIs and internal module naming to use `nonzero` instead of `non_zero`, as this is a non-breaking change. --- elliptic-curve/src/lib.rs | 2 +- elliptic-curve/src/ops.rs | 2 +- elliptic-curve/src/scalar.rs | 2 +- elliptic-curve/src/scalar/{non_zero.rs => nonzero.rs} | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) rename elliptic-curve/src/scalar/{non_zero.rs => nonzero.rs} (97%) diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 16dab13f3..2da9aeb0f 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -98,7 +98,7 @@ pub use { AffineArithmetic, PrimeCurveArithmetic, ProjectiveArithmetic, ScalarArithmetic, }, public_key::PublicKey, - scalar::{non_zero::NonZeroScalar, Scalar}, + scalar::{nonzero::NonZeroScalar, Scalar}, }, ff::{self, Field, PrimeField}, group::{self, Group}, diff --git a/elliptic-curve/src/ops.rs b/elliptic-curve/src/ops.rs index f4449a723..35581647f 100644 --- a/elliptic-curve/src/ops.rs +++ b/elliptic-curve/src/ops.rs @@ -48,5 +48,5 @@ pub trait Reduce: Sized { /// End users can use the `Reduce` impl on `NonZeroScalar` instead. pub trait ReduceNonZero: Sized { /// Perform a modular reduction, returning a field element. - fn from_uint_reduced_non_zero(n: UInt) -> Self; + fn from_uint_reduced_nonzero(n: UInt) -> Self; } diff --git a/elliptic-curve/src/scalar.rs b/elliptic-curve/src/scalar.rs index e8a5be8b1..72d796847 100644 --- a/elliptic-curve/src/scalar.rs +++ b/elliptic-curve/src/scalar.rs @@ -5,7 +5,7 @@ use subtle::Choice; pub(crate) mod core; #[cfg(feature = "arithmetic")] -pub(crate) mod non_zero; +pub(crate) mod nonzero; #[cfg(feature = "arithmetic")] use crate::ScalarArithmetic; diff --git a/elliptic-curve/src/scalar/non_zero.rs b/elliptic-curve/src/scalar/nonzero.rs similarity index 97% rename from elliptic-curve/src/scalar/non_zero.rs rename to elliptic-curve/src/scalar/nonzero.rs index 2692ea08e..eac39aa9b 100644 --- a/elliptic-curve/src/scalar/non_zero.rs +++ b/elliptic-curve/src/scalar/nonzero.rs @@ -207,7 +207,7 @@ where Scalar: ReduceNonZero, { fn from_uint_reduced(n: I) -> Self { - Self::from_uint_reduced_non_zero(n) + Self::from_uint_reduced_nonzero(n) } } @@ -217,8 +217,8 @@ where I: Integer + ArrayEncoding, Scalar: ReduceNonZero, { - fn from_uint_reduced_non_zero(n: I) -> Self { - let scalar = Scalar::::from_uint_reduced_non_zero(n); + fn from_uint_reduced_nonzero(n: I) -> Self { + let scalar = Scalar::::from_uint_reduced_nonzero(n); debug_assert!(!bool::from(scalar.is_zero())); Self::new(scalar).unwrap() } From a1b0efe8f76a9685eb4e34d828f077890911c5ba Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 3 Dec 2021 13:42:16 -0700 Subject: [PATCH 0670/1461] elliptic-curve v0.11.3 (#829) --- elliptic-curve/CHANGELOG.md | 6 ++++++ elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index 379ea79a6..838d73b0c 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.11.3 (2021-12-03) +### Added +- `ReduceNonZero` trait ([#827]) + +[#827]: https://github.com/RustCrypto/traits/pull/827 + ## 0.11.2 (2021-12-03) ### Changed - Bump `pem-rfc7468` dependency to v0.3 ([#825]) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index b156ca329..8a4d81fc1 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.11.2" # Also update html_root_url in lib.rs when bumping this +version = "0.11.3" # Also update html_root_url in lib.rs when bumping this description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 2da9aeb0f..cbc049764 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -35,7 +35,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.11.2" + html_root_url = "https://docs.rs/elliptic-curve/0.11.3" )] #[cfg(feature = "alloc")] From 559eb9e349884ff53db032db9bff7044b9d73dad Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 3 Dec 2021 17:40:25 -0700 Subject: [PATCH 0671/1461] elliptic-curve: serde documentation (#831) Document serde serializations provided by this crate --- elliptic-curve/Cargo.lock | 2 +- elliptic-curve/src/point.rs | 11 ++++++++--- elliptic-curve/src/public_key.rs | 10 ++++++++++ elliptic-curve/src/scalar/core.rs | 8 ++++++++ elliptic-curve/src/scalar/nonzero.rs | 2 +- 5 files changed, 28 insertions(+), 5 deletions(-) diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index 9755dde9e..8df140834 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -56,7 +56,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.11.2" +version = "0.11.3" dependencies = [ "base64ct", "crypto-bigint", diff --git a/elliptic-curve/src/point.rs b/elliptic-curve/src/point.rs index 825db3fd1..7257be66c 100644 --- a/elliptic-curve/src/point.rs +++ b/elliptic-curve/src/point.rs @@ -9,14 +9,19 @@ pub trait AffineXCoordinate { fn x(&self) -> FieldBytes; } -/// Attempt to decompress an elliptic curve point from its x-coordinate and -/// a boolean flag indicating whether or not the y-coordinate is odd. +/// Decompress an elliptic curve point. +/// +/// Point decompression recovers an original curve point from its x-coordinate +/// and a boolean flag indicating whether or not the y-coordinate is odd. pub trait DecompressPoint: Sized { /// Attempt to decompress an elliptic curve point. fn decompress(x: &FieldBytes, y_is_odd: Choice) -> CtOption; } -/// Attempt to decompact an elliptic curve point from an x-coordinate. +/// Decompact an elliptic curve point from an x-coordinate. +/// +/// Decompaction relies on properties of specially-generated keys but provides +/// a more compact representation than standard point compression. pub trait DecompactPoint: Sized { /// Attempt to decompact an elliptic curve point fn decompact(x: &FieldBytes) -> CtOption; diff --git a/elliptic-curve/src/public_key.rs b/elliptic-curve/src/public_key.rs index 8875ec987..edc6e6aa6 100644 --- a/elliptic-curve/src/public_key.rs +++ b/elliptic-curve/src/public_key.rs @@ -61,6 +61,16 @@ use serde::{de, ser, Deserialize, Serialize}; /// /// When the `pem` feature of this crate (or a specific RustCrypto elliptic /// curve crate) is enabled, a [`FromStr`] impl is also available. +/// +/// # `serde` support +/// +/// When the optional `serde` feature of this create is enabled, [`Serialize`] +/// and [`Deserialize`] impls are provided for this type. +/// +/// The serialization is binary-oriented and supports ASN.1 DER +/// Subject Public Key Info (SPKI) as the encoding format. +/// +/// For a more text-friendly encoding of public keys, use [`JwkEcKey`] instead. #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] #[derive(Clone, Debug, Eq, PartialEq)] pub struct PublicKey diff --git a/elliptic-curve/src/scalar/core.rs b/elliptic-curve/src/scalar/core.rs index 5d0bf9e92..40d36083d 100644 --- a/elliptic-curve/src/scalar/core.rs +++ b/elliptic-curve/src/scalar/core.rs @@ -33,6 +33,14 @@ use serde::{de, ser, Deserialize, Serialize}; /// This type provides a baseline level of scalar arithmetic functionality /// which is always available for all curves, regardless of if they implement /// any arithmetic traits. +/// +/// # `serde` support +/// +/// When the optional `serde` feature of this create is enabled, [`Serialize`] +/// and [`Deserialize`] impls are provided for this type. +/// +/// The serialization is a fixed-width big endian encoding. When used with +/// textual formats, the binary data is encoded as hexadecimal. // TODO(tarcieri): make this a fully generic `Scalar` type and use it for `ScalarArithmetic` #[derive(Copy, Clone, Debug, Default)] #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] diff --git a/elliptic-curve/src/scalar/nonzero.rs b/elliptic-curve/src/scalar/nonzero.rs index eac39aa9b..3ed35358c 100644 --- a/elliptic-curve/src/scalar/nonzero.rs +++ b/elliptic-curve/src/scalar/nonzero.rs @@ -61,7 +61,7 @@ where Scalar::::from_repr(repr).and_then(Self::new) } - /// Create a [`NonZeroScalar`] from a [`UInt`]. + /// Create a [`NonZeroScalar`] from a `C::UInt`. pub fn from_uint(uint: C::UInt) -> CtOption { ScalarCore::new(uint).and_then(|scalar| Self::new(scalar.into())) } From 012e39ec2cde06d87611d4b5aede3b3b296cfedb Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 4 Dec 2021 09:57:25 -0700 Subject: [PATCH 0672/1461] elliptic-curve: add `LinearCombination` trait (#832) Adds a trait for computing `x * k + y * l`. This allows curve implementations to provide optimized arithmetic when available (e.g. Shamir's Trick) --- elliptic-curve/src/ops.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/elliptic-curve/src/ops.rs b/elliptic-curve/src/ops.rs index 35581647f..b49e1b335 100644 --- a/elliptic-curve/src/ops.rs +++ b/elliptic-curve/src/ops.rs @@ -5,6 +5,9 @@ pub use core::ops::{Add, AddAssign, Mul, Neg, Sub, SubAssign}; use crypto_bigint::{ArrayEncoding, ByteArray, Integer}; use subtle::CtOption; +#[cfg(feature = "arithmetic")] +use crate::ProjectiveArithmetic; + /// Perform an inversion on a field element (i.e. base field element or scalar) pub trait Invert { /// Field element type @@ -23,6 +26,26 @@ impl Invert for F { } } +/// Linear combination. +/// +/// This trait enables crates to provide an optimized implementation of +/// linear combinations (e.g. Shamir's Trick), or otherwise provides a default +/// non-optimized implementation. +// TODO(tarcieri): replace this with a trait from the `group` crate? (see zkcrypto/group#25) +#[cfg(feature = "arithmetic")] +#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] +pub trait LinearCombination: ProjectiveArithmetic { + /// Calculates `x * k + y * l`. + fn lincomb( + x: &Self::ProjectivePoint, + k: &Self::Scalar, + y: &Self::ProjectivePoint, + l: &Self::Scalar, + ) -> Self::ProjectivePoint { + (*x * k) + (*y * l) + } +} + /// Modular reduction. pub trait Reduce: Sized { /// Perform a modular reduction, returning a field element. From af0c9e7a69ea1b074561a548782a7a3639e30b3d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 4 Dec 2021 10:05:35 -0700 Subject: [PATCH 0673/1461] elliptic-curve v0.11.4 (#833) --- elliptic-curve/CHANGELOG.md | 6 ++++++ elliptic-curve/Cargo.lock | 2 +- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 13 ++++++++++++- 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index 838d73b0c..c8c25fbb4 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.11.4 (2021-12-04) +### Added +- `LinearCombination` trait ([#832]) + +[#832]: https://github.com/RustCrypto/traits/pull/832 + ## 0.11.3 (2021-12-03) ### Added - `ReduceNonZero` trait ([#827]) diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index 8df140834..ebfe40f19 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -56,7 +56,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.11.3" +version = "0.11.4" dependencies = [ "base64ct", "crypto-bigint", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 8a4d81fc1..dfb1268c4 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.11.3" # Also update html_root_url in lib.rs when bumping this +version = "0.11.4" # Also update html_root_url in lib.rs when bumping this description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index cbc049764..7cc49a263 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -20,6 +20,17 @@ //! the above crates, either via an external ECDSA implementation, or //! using native curve arithmetic where applicable. //! +//! ## `serde` support +//! +//! When the `serde` feature of this crate is enabled, `Serialize` and +//! `Deserialize` impls are provided for the following types: +//! +//! - [`JwkEcKey`] +//! - [`PublicKey`] +//! - [`ScalarCore`] +//! +//! Please see type-specific documentation for more information. +//! //! [`RustCrypto/elliptic-curves`]: https://github.com/RustCrypto/elliptic-curves //! [`bp256`]: https://github.com/RustCrypto/elliptic-curves/tree/master/bp256 //! [`bp384`]: https://github.com/RustCrypto/elliptic-curves/tree/master/bp384 @@ -35,7 +46,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.11.3" + html_root_url = "https://docs.rs/elliptic-curve/0.11.4" )] #[cfg(feature = "alloc")] From ad3fa7356c6b8870810e924d028f31149254697d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 4 Dec 2021 10:33:47 -0700 Subject: [PATCH 0674/1461] elliptic-curve: fix `ecdh` docs (#834) There's an example marked `ignore` for the `diffie_hellman` function which is no longer valid. This commit fixes it. --- elliptic-curve/src/ecdh.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elliptic-curve/src/ecdh.rs b/elliptic-curve/src/ecdh.rs index 90aff47f6..8b5960236 100644 --- a/elliptic-curve/src/ecdh.rs +++ b/elliptic-curve/src/ecdh.rs @@ -51,7 +51,7 @@ use zeroize::Zeroize; /// /// ```ignore /// let shared_secret = elliptic_curve::ecdh::diffie_hellman( -/// secret_key.secret_scalar(), +/// secret_key.to_nonzero_scalar(), /// public_key.as_affine() /// ); /// ``` From e10f28775673563e9f0ade9c549dd30f5649fedc Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 4 Dec 2021 11:23:30 -0700 Subject: [PATCH 0675/1461] elliptic-curve: revised `LinearCombination` trait (#835) Changes `LinearCombination` to be impl'd on the `ProjectivePoint` type for a given curve, rather than the curve ZST. This better fits the trait-based structure used by the `group` crate, and also makes sense as `ProjectivePoint` is the return type, so it's almost certain to be in scope (as opposed to importing a curve ZST to do the operation) This is technically a breaking change as the `LinearCombination` trait was just released an hour ago in v0.11.4, but given that it's unlikely anyone is using it yet, so it can probably be safely yanked and the updated version included in a new release. --- elliptic-curve/src/arithmetic.rs | 5 ++++- elliptic-curve/src/dev.rs | 4 +++- elliptic-curve/src/ops.rs | 11 +++-------- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/elliptic-curve/src/arithmetic.rs b/elliptic-curve/src/arithmetic.rs index b69c1a408..fa445f1bc 100644 --- a/elliptic-curve/src/arithmetic.rs +++ b/elliptic-curve/src/arithmetic.rs @@ -1,6 +1,8 @@ //! Elliptic curve arithmetic traits. -use crate::{AffineXCoordinate, Curve, FieldBytes, IsHigh, PrimeCurve, ScalarCore}; +use crate::{ + ops::LinearCombination, AffineXCoordinate, Curve, FieldBytes, IsHigh, PrimeCurve, ScalarCore, +}; use core::fmt::Debug; use subtle::{ConditionallySelectable, ConstantTimeEq}; use zeroize::DefaultIsZeroes; @@ -54,6 +56,7 @@ pub trait ProjectiveArithmetic: Curve + AffineArithmetic { + DefaultIsZeroes + From + Into + + LinearCombination + group::Curve + group::Group; } diff --git a/elliptic-curve/src/dev.rs b/elliptic-curve/src/dev.rs index 1da6c6316..5b9ca3781 100644 --- a/elliptic-curve/src/dev.rs +++ b/elliptic-curve/src/dev.rs @@ -6,7 +6,7 @@ use crate::{ bigint::{Limb, U256}, error::{Error, Result}, - ops::Reduce, + ops::{LinearCombination, Reduce}, pkcs8, rand_core::RngCore, sec1::{FromEncodedPoint, ToEncodedPoint}, @@ -541,6 +541,8 @@ impl group::Curve for ProjectivePoint { } } +impl LinearCombination for ProjectivePoint {} + impl Add for ProjectivePoint { type Output = ProjectivePoint; diff --git a/elliptic-curve/src/ops.rs b/elliptic-curve/src/ops.rs index b49e1b335..b5ab2dd8f 100644 --- a/elliptic-curve/src/ops.rs +++ b/elliptic-curve/src/ops.rs @@ -6,7 +6,7 @@ use crypto_bigint::{ArrayEncoding, ByteArray, Integer}; use subtle::CtOption; #[cfg(feature = "arithmetic")] -use crate::ProjectiveArithmetic; +use group::Group; /// Perform an inversion on a field element (i.e. base field element or scalar) pub trait Invert { @@ -34,14 +34,9 @@ impl Invert for F { // TODO(tarcieri): replace this with a trait from the `group` crate? (see zkcrypto/group#25) #[cfg(feature = "arithmetic")] #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] -pub trait LinearCombination: ProjectiveArithmetic { +pub trait LinearCombination: Group { /// Calculates `x * k + y * l`. - fn lincomb( - x: &Self::ProjectivePoint, - k: &Self::Scalar, - y: &Self::ProjectivePoint, - l: &Self::Scalar, - ) -> Self::ProjectivePoint { + fn lincomb(x: &Self, k: &Self::Scalar, y: &Self, l: &Self::Scalar) -> Self { (*x * k) + (*y * l) } } From 39d118201090e567d7d41099910d5601f1d1e7e8 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 4 Dec 2021 11:33:12 -0700 Subject: [PATCH 0676/1461] elliptic-curve v0.11.5 (#836) --- elliptic-curve/CHANGELOG.md | 12 +++++++++--- elliptic-curve/Cargo.lock | 2 +- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 2 +- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index c8c25fbb4..3ebab41bc 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,19 +4,25 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 0.11.4 (2021-12-04) +## 0.11.5 (2021-12-05) +### Changed +- Revised `LinearCombination` trait ([#835]) + +[#835]: https://github.com/RustCrypto/traits/pull/835 + +## 0.11.4 (2021-12-04) [YANKED] ### Added - `LinearCombination` trait ([#832]) [#832]: https://github.com/RustCrypto/traits/pull/832 -## 0.11.3 (2021-12-03) +## 0.11.3 (2021-12-03) [YANKED] ### Added - `ReduceNonZero` trait ([#827]) [#827]: https://github.com/RustCrypto/traits/pull/827 -## 0.11.2 (2021-12-03) +## 0.11.2 (2021-12-03) [YANKED] ### Changed - Bump `pem-rfc7468` dependency to v0.3 ([#825]) diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index ebfe40f19..9106d9042 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -56,7 +56,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.11.4" +version = "0.11.5" dependencies = [ "base64ct", "crypto-bigint", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index dfb1268c4..dabbdc532 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.11.4" # Also update html_root_url in lib.rs when bumping this +version = "0.11.5" # Also update html_root_url in lib.rs when bumping this description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 7cc49a263..3b2d3b534 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -46,7 +46,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.11.4" + html_root_url = "https://docs.rs/elliptic-curve/0.11.5" )] #[cfg(feature = "alloc")] From 56de6873faeedbcb3a20092d5c499d3fff88fb29 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Tue, 7 Dec 2021 19:10:52 +0000 Subject: [PATCH 0677/1461] digest v0.10 and crypto-common v0.1 (#819) --- .github/workflows/crypto-common.yml | 3 +- .github/workflows/crypto-mac.yml | 60 ------ .github/workflows/digest.yml | 14 +- Cargo.lock | 49 ++--- Cargo.toml | 1 - README.md | 69 +++---- cipher/Cargo.toml | 6 +- crypto-common/CHANGELOG.md | 9 + crypto-common/Cargo.toml | 6 +- crypto-common/src/core_api.rs | 132 ------------- crypto-common/src/lib.rs | 278 ++++++++++++++++++++++++---- crypto-mac/CHANGELOG.md | 104 ----------- crypto-mac/Cargo.toml | 30 --- crypto-mac/LICENSE-APACHE | 201 -------------------- crypto-mac/LICENSE-MIT | 25 --- crypto-mac/README.md | 59 ------ crypto-mac/src/core_api.rs | 2 - crypto-mac/src/dev.rs | 148 --------------- crypto-mac/src/lib.rs | 123 ------------ digest/CHANGELOG.md | 10 +- digest/Cargo.toml | 11 +- digest/src/core_api.rs | 123 +++++++----- digest/src/core_api/ct_variable.rs | 118 +++++++++--- digest/src/core_api/rt_variable.rs | 112 ++++++++--- digest/src/core_api/wrapper.rs | 275 +++++++++++++++++++++++++++ digest/src/core_api/xof_reader.rs | 39 +++- digest/src/dev.rs | 258 +++++--------------------- digest/src/dev/fixed.rs | 65 +++++++ digest/src/dev/mac.rs | 159 ++++++++++++++++ digest/src/dev/rng.rs | 38 ++++ digest/src/dev/variable.rs | 82 ++++++++ digest/src/dev/xof.rs | 51 +++++ digest/src/digest.rs | 149 +++++++++++++-- digest/src/dyn_digest.rs | 124 ------------- digest/src/lib.rs | 171 ++++++++++++----- digest/src/mac.rs | 221 ++++++++++++++++++++++ 36 files changed, 1806 insertions(+), 1519 deletions(-) delete mode 100644 .github/workflows/crypto-mac.yml create mode 100644 crypto-common/CHANGELOG.md delete mode 100644 crypto-common/src/core_api.rs delete mode 100644 crypto-mac/CHANGELOG.md delete mode 100644 crypto-mac/Cargo.toml delete mode 100644 crypto-mac/LICENSE-APACHE delete mode 100644 crypto-mac/LICENSE-MIT delete mode 100644 crypto-mac/README.md delete mode 100644 crypto-mac/src/core_api.rs delete mode 100644 crypto-mac/src/dev.rs delete mode 100644 crypto-mac/src/lib.rs create mode 100644 digest/src/core_api/wrapper.rs create mode 100644 digest/src/dev/fixed.rs create mode 100644 digest/src/dev/mac.rs create mode 100644 digest/src/dev/rng.rs create mode 100644 digest/src/dev/variable.rs create mode 100644 digest/src/dev/xof.rs delete mode 100644 digest/src/dyn_digest.rs create mode 100644 digest/src/mac.rs diff --git a/.github/workflows/crypto-common.yml b/.github/workflows/crypto-common.yml index 287c49535..1155de5c3 100644 --- a/.github/workflows/crypto-common.yml +++ b/.github/workflows/crypto-common.yml @@ -35,7 +35,7 @@ jobs: target: ${{ matrix.target }} override: true profile: minimal - - run: cargo build --no-default-features --release --target ${{ matrix.target }} + - run: cargo build --target ${{ matrix.target }} test: runs-on: ubuntu-latest strategy: @@ -52,6 +52,5 @@ jobs: profile: minimal - run: cargo check --all-features - run: cargo test - - run: cargo test --features core-api - run: cargo test --features std - run: cargo test --all-features diff --git a/.github/workflows/crypto-mac.yml b/.github/workflows/crypto-mac.yml deleted file mode 100644 index 29186ab72..000000000 --- a/.github/workflows/crypto-mac.yml +++ /dev/null @@ -1,60 +0,0 @@ -name: crypto-mac - -on: - pull_request: - paths: - - "crypto-mac/**" - - "Cargo.*" - push: - branches: master - -defaults: - run: - working-directory: crypto-mac - -env: - CARGO_INCREMENTAL: 0 - RUSTFLAGS: "-Dwarnings" - -jobs: - build: - runs-on: ubuntu-latest - strategy: - matrix: - rust: - - 1.41.0 # MSRV - - stable - target: - - thumbv7em-none-eabi - - wasm32-unknown-unknown - steps: - - uses: actions/checkout@v1 - - uses: actions-rs/toolchain@v1 - with: - toolchain: ${{ matrix.rust }} - target: ${{ matrix.target }} - override: true - profile: minimal - - run: cargo build --target ${{ matrix.target }} --release --no-default-features - - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features rand_core - - test: - runs-on: ubuntu-latest - strategy: - matrix: - rust: - - 1.41.0 # MSRV - - stable - steps: - - uses: actions/checkout@v1 - - uses: actions-rs/toolchain@v1 - with: - toolchain: ${{ matrix.rust }} - override: true - profile: minimal - - run: cargo check --all-features - - run: cargo test - - run: cargo test --features core-api - - run: cargo test --features dev - - run: cargo test --features std - - run: cargo test --all-features diff --git a/.github/workflows/digest.yml b/.github/workflows/digest.yml index a518cd23a..18b7a1bdd 100644 --- a/.github/workflows/digest.yml +++ b/.github/workflows/digest.yml @@ -35,7 +35,7 @@ jobs: target: ${{ matrix.target }} override: true profile: minimal - - run: cargo build --no-default-features --release --target ${{ matrix.target }} + - run: cargo build --target ${{ matrix.target }} test: runs-on: ubuntu-latest strategy: @@ -51,9 +51,9 @@ jobs: override: true profile: minimal - run: cargo check --all-features - - run: cargo test --release - - run: cargo test --features core-api --release - - run: cargo test --features dev --release - - run: cargo test --features alloc --release - - run: cargo test --features std --release - - run: cargo test --all-features --release + - run: cargo test --no-default-features + - run: cargo test + - run: cargo test --features dev + - run: cargo test --features alloc + - run: cargo test --features std + - run: cargo test --all-features diff --git a/Cargo.lock b/Cargo.lock index fe92941cb..cf9a6902d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -39,9 +39,9 @@ checksum = "8a32fd6af2b5827bce66c29053ba0e7c42b9dcab01835835058558c10851a46b" [[package]] name = "blobby" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc52553543ecb104069b0ff9e0fcc5c739ad16202935528a112d974e8f1a4ee8" +checksum = "847495c209977a90e8aad588b959d0ca9f5dc228096d29a6bd3defd53f35eaec" [[package]] name = "block-buffer" @@ -54,19 +54,9 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.10.0-pre.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4b13c429c0b48d55a541108e23c7795eb821ee65b50c2f719f4f7fc5a022dcf" -dependencies = [ - "block-padding", - "generic-array", -] - -[[package]] -name = "block-padding" -version = "0.3.0-pre" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3992d179d1dd2fa87869057217d43cf88ad31d4e44738d159a5a6caafdf63ae6" +checksum = "f1d36a02058e76b040de25a4464ba1c80935655595b661505c8b39b664828b95" dependencies = [ "generic-array", ] @@ -88,7 +78,6 @@ name = "cipher" version = "0.4.0-pre" dependencies = [ "blobby", - "block-buffer 0.10.0-pre.4", "crypto-common", "generic-array", "rand_core", @@ -105,22 +94,10 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.1.0-pre" -dependencies = [ - "block-buffer 0.10.0-pre.4", - "generic-array", -] - -[[package]] -name = "crypto-mac" -version = "0.12.0-pre" +version = "0.1.0" dependencies = [ - "blobby", - "cipher", - "crypto-common", "generic-array", "rand_core", - "subtle", ] [[package]] @@ -134,11 +111,13 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.0-pre.3" +version = "0.10.0" dependencies = [ "blobby", + "block-buffer 0.10.0", "crypto-common", "generic-array", + "subtle", ] [[package]] @@ -203,9 +182,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.107" +version = "0.2.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbe5e23404da5b4f555ef85ebed98fb4083e55a00c317800bc2a50ede9f3d219" +checksum = "f98a04dce437184842841303488f70d0188c5f51437d2a834dc097eafa909a01" [[package]] name = "lock_api" @@ -239,9 +218,9 @@ checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" [[package]] name = "proc-macro2" -version = "1.0.32" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43" +checksum = "fb37d2df5df740e582f28f8560cf425f52bb267d872fe58358eadb554909f07a" dependencies = [ "unicode-xid", ] @@ -327,9 +306,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.81" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966" +checksum = "8daf5dd0bb60cbd4137b1b587d2fc0ae729bc07cf01cd70b36a1ed5ade3b9d59" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 10ed45ce0..c0e881aa2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,6 @@ members = [ "aead", "cipher", "crypto-common", - "crypto-mac", "digest", "password-hash", "signature", diff --git a/README.md b/README.md index ff4332a3b..05f79cd19 100644 --- a/README.md +++ b/README.md @@ -1,33 +1,32 @@ -# RustCrypto: Traits [![Project Chat][chat-image]][chat-link] [![dependency status][deps-image]][deps-link] +# RustCrypto: Traits + +[![Project Chat][chat-image]][chat-link] [![dependency status][deps-image]][deps-link] ![Apache2/MIT licensed][license-image] Collection of traits which describe functionality of cryptographic primitives. ## Crates -| Crate name | Algorithm | Crates.io | Docs | Build Status | -|---------------------|-------------------------------|-----------|-------|--------------| -| [`aead`] | [Authenticated encryption] | [![crates.io](https://img.shields.io/crates/v/aead.svg)](https://crates.io/crates/aead) | [![Documentation](https://docs.rs/aead/badge.svg)](https://docs.rs/aead) | ![build](https://github.com/RustCrypto/traits/workflows/aead/badge.svg?branch=master&event=push) | -| [`async‑signature`] | [Digital signature] | [![crates.io](https://img.shields.io/crates/v/async-signature.svg)](https://crates.io/crates/async-signature) | [![Documentation](https://docs.rs/async-signature/badge.svg)](https://docs.rs/async-signature) | ![build](https://github.com/RustCrypto/traits/workflows/async-signature/badge.svg?branch=master&event=push) | -| [`cipher`] | [Block] and [stream cipher] | [![crates.io](https://img.shields.io/crates/v/cipher.svg)](https://crates.io/crates/cipher) | [![Documentation](https://docs.rs/cipher/badge.svg)](https://docs.rs/cipher) | ![build](https://github.com/RustCrypto/traits/workflows/cipher/badge.svg?branch=master&event=push) | -| [`crypto‑mac`] | [Message authentication code] | [![crates.io](https://img.shields.io/crates/v/crypto-mac.svg)](https://crates.io/crates/crypto-mac) | [![Documentation](https://docs.rs/crypto-mac/badge.svg)](https://docs.rs/crypto-mac) | ![build](https://github.com/RustCrypto/traits/workflows/crypto-mac/badge.svg?branch=master&event=push) | -| [`digest`] | [Cryptographic hash function] | [![crates.io](https://img.shields.io/crates/v/digest.svg)](https://crates.io/crates/digest) | [![Documentation](https://docs.rs/digest/badge.svg)](https://docs.rs/digest) | ![build](https://github.com/RustCrypto/traits/workflows/digest/badge.svg?branch=master&event=push) | -| [`elliptic‑curve`] | [Elliptic curve cryptography] | [![crates.io](https://img.shields.io/crates/v/elliptic-curve.svg)](https://crates.io/crates/elliptic-curve) | [![Documentation](https://docs.rs/elliptic-curve/badge.svg)](https://docs.rs/elliptic-curve) | ![build](https://github.com/RustCrypto/traits/workflows/elliptic-curve/badge.svg?branch=master&event=push) | -| [`password-hash`] | [Password hashing] | [![crates.io](https://img.shields.io/crates/v/password-hash.svg)](https://crates.io/crates/password-hash) | [![Documentation](https://docs.rs/password-hash/badge.svg)](https://docs.rs/password-hash) | ![build](https://github.com/RustCrypto/traits/workflows/password-hash/badge.svg?branch=master&event=push) | -| [`signature`] | [Digital signature] | [![crates.io](https://img.shields.io/crates/v/signature.svg)](https://crates.io/crates/signature) | [![Documentation](https://docs.rs/signature/badge.svg)](https://docs.rs/signature) | ![build](https://github.com/RustCrypto/traits/workflows/signature/badge.svg?branch=master&event=push) | -| [`universal‑hash`] | [Universal hash function] | [![crates.io](https://img.shields.io/crates/v/universal-hash.svg)](https://crates.io/crates/universal-hash) | [![Documentation](https://docs.rs/universal-hash/badge.svg)](https://docs.rs/universal-hash) | ![build](https://github.com/RustCrypto/traits/workflows/universal-hash/badge.svg?branch=master&event=push) | - -### Additional crates +| Name | Algorithm | Crates.io | Docs | MSRV | +|---------------------|-----------|:---------:|:-----:|:----:| +| [`aead`] | [Authenticated encryption] | [![crates.io](https://img.shields.io/crates/v/aead.svg)](https://crates.io/crates/aead) | [![Documentation](https://docs.rs/aead/badge.svg)](https://docs.rs/aead) | ![MSRV 1.41][msrv-1.41] | +| [`async‑signature`] | [Digital signature] | [![crates.io](https://img.shields.io/crates/v/async-signature.svg)](https://crates.io/crates/async-signature) | [![Documentation](https://docs.rs/async-signature/badge.svg)](https://docs.rs/async-signature) | ![MSRV 1.41][msrv-1.41] | +| [`cipher`] | [Block] and [stream cipher] | [![crates.io](https://img.shields.io/crates/v/cipher.svg)](https://crates.io/crates/cipher) | [![Documentation](https://docs.rs/cipher/badge.svg)](https://docs.rs/cipher) | ![MSRV 1.41][msrv-1.41] | +| [`crypto‑common`] | Common cryptographic traits | [![crates.io](https://img.shields.io/crates/v/crypto-common.svg)](https://crates.io/crates/crypto-common) | [![Documentation](https://docs.rs/crypto-common/badge.svg)](https://docs.rs/crypto-common) | ![MSRV 1.41][msrv-1.41] | +| [`digest`] | [Cryptographic hash function] | [![crates.io](https://img.shields.io/crates/v/digest.svg)](https://crates.io/crates/digest) | [![Documentation](https://docs.rs/digest/badge.svg)](https://docs.rs/digest) | ![MSRV 1.41][msrv-1.41] | +| [`elliptic‑curve`] | [Elliptic curve cryptography] | [![crates.io](https://img.shields.io/crates/v/elliptic-curve.svg)](https://crates.io/crates/elliptic-curve) | [![Documentation](https://docs.rs/elliptic-curve/badge.svg)](https://docs.rs/elliptic-curve) | ![MSRV 1.56][msrv-1.56] | +| [`password-hash`] | [Password hashing] | [![crates.io](https://img.shields.io/crates/v/password-hash.svg)](https://crates.io/crates/password-hash) | [![Documentation](https://docs.rs/password-hash/badge.svg)](https://docs.rs/password-hash) | ![MSRV 1.47][msrv-1.47] | +| [`signature`] | [Digital signature] | [![crates.io](https://img.shields.io/crates/v/signature.svg)](https://crates.io/crates/signature) | [![Documentation](https://docs.rs/signature/badge.svg)](https://docs.rs/signature) | ![MSRV 1.41][msrv-1.41] | +| [`universal‑hash`] | [Universal hash function] | [![crates.io](https://img.shields.io/crates/v/universal-hash.svg)](https://crates.io/crates/universal-hash) | [![Documentation](https://docs.rs/universal-hash/badge.svg)](https://docs.rs/universal-hash) | ![MSRV 1.41][msrv-1.41] | -| Crate name | Description | Crates.io | Docs | Build Status | -|------------|-------------------------|-----------|-------|--------------| -| [`crypto`] | Facade for trait crates | [![crates.io](https://img.shields.io/crates/v/crypto.svg)](https://crates.io/crates/crypto) | [![Documentation](https://docs.rs/crypto/badge.svg)](https://docs.rs/crypto) | ![build](https://github.com/RustCrypto/traits/workflows/crypto/badge.svg?branch=master&event=push) +### Additional Crates -### Minimum Supported Rust Version +| Crate name | Description | Crates.io | Docs | MSRV | +|------------|-------------------------|:---------:|:-----:|:----:| +| [`crypto`] | Facade for trait crates | [![crates.io](https://img.shields.io/crates/v/crypto.svg)](https://crates.io/crates/crypto) | [![Documentation](https://docs.rs/crypto/badge.svg)](https://docs.rs/crypto) | ![MSRV 1.56][msrv-1.56] | -All crates in this repository support **Rust 1.41** or higher unless otherwise noted. +### Minimum Supported Rust Version (MSRV) Policy -In future minimally supported version of Rust can be changed, but it will be done -with the minor version bump. +MSRV bumps are considered breaking changes and will be performed only with minor version bump. ## License @@ -40,29 +39,31 @@ at your option. ### Contribution -Unless you explicitly state otherwise, any contribution intentionally submitted -for inclusion in the work by you, as defined in the Apache-2.0 license, shall be -dual licensed as above, without any additional terms or conditions. +Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. [//]: # (badges) [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/ +[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg [deps-image]: https://deps.rs/repo/github/RustCrypto/traits/status.svg [deps-link]: https://deps.rs/repo/github/RustCrypto/traits +[msrv-1.41]: https://img.shields.io/badge/rustc-1.41.0+-blue.svg +[msrv-1.47]: https://img.shields.io/badge/rustc-1.47.0+-blue.svg +[msrv-1.56]: https://img.shields.io/badge/rustc-1.56.0+-blue.svg [//]: # (crates) -[`aead`]: https://github.com/RustCrypto/traits/tree/master/aead -[`async‑signature`]: https://github.com/RustCrypto/traits/tree/master/signature/async -[`cipher`]: https://github.com/RustCrypto/traits/tree/master/cipher -[`crypto‑mac`]: https://github.com/RustCrypto/traits/tree/master/crypto-mac -[`crypto`]: https://github.com/RustCrypto/traits/tree/master/crypto -[`digest`]: https://github.com/RustCrypto/traits/tree/master/digest -[`elliptic‑curve`]: https://github.com/RustCrypto/traits/tree/master/elliptic-curve -[`password-hash`]: https://github.com/RustCrypto/traits/tree/master/password-hash -[`signature`]: https://github.com/RustCrypto/traits/tree/master/signature -[`universal‑hash`]: https://github.com/RustCrypto/traits/tree/master/universal-hash +[`aead`]: ./aead +[`async‑signature`]: ./signature/async +[`cipher`]: ./cipher +[`crypto‑common`]: ./crypto-common +[`crypto`]: ./crypto +[`digest`]: ./digest +[`elliptic‑curve`]: ./elliptic-curve +[`password-hash`]: ./password-hash +[`signature`]: ./signature +[`universal‑hash`]: ./universal-hash [//]: # (algorithms) diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index 017e3c028..49a2b4c4e 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -13,17 +13,13 @@ categories = ["cryptography", "no-std"] [dependencies] generic-array = "0.14" -crypto-common = { version = "=0.1.0-pre", path = "../crypto-common" } +crypto-common = { version = "0.1", path = "../crypto-common" } -# optional dependencies -block-buffer = { version = "=0.10.0-pre.4", features = ["block-padding"], optional = true } blobby = { version = "0.3", optional = true } rand_core = { version = "0.6", optional = true } [features] -default = ["mode_wrapper"] std = ["crypto-common/std", "rand_core/std"] -mode_wrapper = ["block-buffer"] dev = ["blobby"] [package.metadata.docs.rs] diff --git a/crypto-common/CHANGELOG.md b/crypto-common/CHANGELOG.md new file mode 100644 index 000000000..822c0bec4 --- /dev/null +++ b/crypto-common/CHANGELOG.md @@ -0,0 +1,9 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## 0.1.0 (2021-12-07) +- Initial release diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index 3fa429be3..b38f4bb9d 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crypto-common" description = "Common cryptographic traits" -version = "0.1.0-pre" +version = "0.1.0" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" @@ -13,9 +13,7 @@ categories = ["cryptography", "no-std"] [dependencies] generic-array = "0.14" -block-buffer = { version = "0.10.0-pre.2", optional = true } +rand_core = { version = "0.6", optional = true } [features] -block-padding = ["block-buffer/block-padding"] -core-api = ["block-buffer"] std = [] diff --git a/crypto-common/src/core_api.rs b/crypto-common/src/core_api.rs deleted file mode 100644 index 7def7a076..000000000 --- a/crypto-common/src/core_api.rs +++ /dev/null @@ -1,132 +0,0 @@ -//! Low-level core API traits. -use super::{FixedOutput, FixedOutputReset, Reset, Update}; -use block_buffer::DigestBuffer; -use core::fmt; -use generic_array::{ArrayLength, GenericArray}; - -/// Trait for types which consume data in blocks. -#[cfg(feature = "core-api")] -#[cfg_attr(docsrs, doc(cfg(feature = "core-api")))] -pub trait UpdateCore { - /// Block size in bytes. - type BlockSize: ArrayLength; - /// Block buffer type over which value operates. - type Buffer: DigestBuffer; - - /// Update state using the provided data blocks. - fn update_blocks(&mut self, blocks: &[GenericArray]); -} - -/// Core trait for hash functions with fixed output size. -#[cfg(feature = "core-api")] -#[cfg_attr(docsrs, doc(cfg(feature = "core-api")))] -pub trait FixedOutputCore: UpdateCore { - /// Size of result in bytes. - type OutputSize: ArrayLength; - - /// Finalize state using remaining data stored in the provided block buffer, - /// write result into provided array using and leave value in a dirty state. - fn finalize_fixed_core( - &mut self, - buffer: &mut Self::Buffer, - out: &mut GenericArray, - ); -} - -/// Trait which stores algorithm name constant, used in `Debug` implementations. -pub trait AlgorithmName { - /// Write algorithm name into `f`. - fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result; -} - -/// Wrapper around [`UpdateCore`] implementations. -/// -/// It handles data buffering and implements the slice-based traits. -#[derive(Clone, Default)] -pub struct CoreWrapper { - core: T, - buffer: T::Buffer, -} - -impl CoreWrapper { - /// Create new wrapper from `core`. - #[inline] - pub fn from_core(core: T) -> Self { - let buffer = Default::default(); - Self { core, buffer } - } - - /// Decompose wrapper into inner parts. - #[inline] - pub fn decompose(self) -> (T, T::Buffer) { - let Self { core, buffer } = self; - (core, buffer) - } -} - -impl CoreWrapper { - /// Apply function to core and buffer, return its result, - /// and reset core and buffer. - pub fn apply_reset(&mut self, mut f: impl FnMut(&mut T, &mut T::Buffer) -> V) -> V { - let Self { core, buffer } = self; - let res = f(core, buffer); - core.reset(); - buffer.reset(); - res - } -} - -impl fmt::Debug for CoreWrapper { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - T::write_alg_name(f)?; - f.write_str(" { .. }") - } -} - -impl Reset for CoreWrapper { - #[inline] - fn reset(&mut self) { - self.core.reset(); - self.buffer.reset(); - } -} - -impl Update for CoreWrapper { - #[inline] - fn update(&mut self, input: &[u8]) { - let Self { core, buffer } = self; - buffer.digest_blocks(input, |blocks| core.update_blocks(blocks)); - } -} - -impl FixedOutput for CoreWrapper { - type OutputSize = D::OutputSize; - - #[inline] - fn finalize_into(mut self, out: &mut GenericArray) { - let Self { core, buffer } = &mut self; - core.finalize_fixed_core(buffer, out); - } -} - -impl FixedOutputReset for CoreWrapper { - #[inline] - fn finalize_into_reset(&mut self, out: &mut GenericArray) { - self.apply_reset(|core, buffer| core.finalize_fixed_core(buffer, out)); - } -} - -#[cfg(feature = "std")] -#[cfg_attr(docsrs, doc(cfg(feature = "std")))] -impl std::io::Write for CoreWrapper { - #[inline] - fn write(&mut self, buf: &[u8]) -> std::io::Result { - Update::update(self, buf); - Ok(buf.len()) - } - - #[inline] - fn flush(&mut self) -> std::io::Result<()> { - Ok(()) - } -} diff --git a/crypto-common/src/lib.rs b/crypto-common/src/lib.rs index 5869bc677..a11626d37 100644 --- a/crypto-common/src/lib.rs +++ b/crypto-common/src/lib.rs @@ -12,56 +12,262 @@ #[cfg(feature = "std")] extern crate std; -use generic_array::{ArrayLength, GenericArray}; +use core::fmt; +use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; +#[cfg(feature = "rand_core")] +use rand_core::{CryptoRng, RngCore}; -#[cfg(feature = "core-api")] -#[cfg_attr(docsrs, doc(cfg(feature = "core-api")))] -pub use block_buffer; +/// Block on which [`BlockSizeUser`] implementors operate. +pub type Block = GenericArray::BlockSize>; +/// Output array of [`OutputSizeUser`] implementors. +pub type Output = GenericArray::OutputSize>; +/// Key used by [`KeySizeUser`] implementors. +pub type Key = GenericArray::KeySize>; +/// Initialization vector (nonce) used by [`IvSizeUser`] implementors. +pub type Iv = GenericArray::IvSize>; -#[cfg(feature = "core-api")] -#[cfg_attr(docsrs, doc(cfg(feature = "core-api")))] -pub mod core_api; +/// Types which process data in blocks. +pub trait BlockSizeUser { + /// Size of the block in bytes. + type BlockSize: ArrayLength + 'static; +} -/// Trait for types which consume data. -pub trait Update { - /// Update state using the provided data. - fn update(&mut self, data: &[u8]); +impl BlockSizeUser for &T { + type BlockSize = T::BlockSize; } -/// Trait for types which return fixed-sized result after finalization. -pub trait FixedOutput: Sized { - /// Size of result in bytes. - type OutputSize: ArrayLength; +impl BlockSizeUser for &mut T { + type BlockSize = T::BlockSize; +} - /// Consume value and write result into provided array. - fn finalize_into(self, out: &mut GenericArray); +/// Types which return data with the given size. +pub trait OutputSizeUser { + /// Size of the output in bytes. + type OutputSize: ArrayLength + 'static; +} + +/// Types which use key for initialization. +/// +/// Generally it's used indirectly via [`KeyInit`] or [`KeyIvInit`]. +pub trait KeySizeUser { + /// Key size in bytes. + type KeySize: ArrayLength + 'static; +} + +/// Types which use initialization vector (nonce) for initialization. +/// +/// Generally it's used indirectly via [`KeyIvInit`] or [`InnerIvInit`]. +pub trait IvSizeUser { + /// Initialization vector size in bytes. + type IvSize: ArrayLength + 'static; +} + +/// Types which use another type for initialization. +/// +/// Generally it's used indirectly via [`InnerInit`] or [`InnerIvInit`]. +pub trait InnerUser { + /// Inner type. + type Inner; +} - /// Retrieve result and consume the hasher instance. +/// Resettable types. +pub trait Reset { + /// Reset state to its initial value. + fn reset(&mut self); +} + +/// Trait which stores algorithm name constant, used in `Debug` implementations. +pub trait AlgorithmName { + /// Write algorithm name into `f`. + fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result; +} + +/// Types which can be initialized from key. +pub trait KeyInit: KeySizeUser + Sized { + /// Create new value from fixed size key. + fn new(key: &Key) -> Self; + + /// Create new value from variable size key. + fn new_from_slice(key: &[u8]) -> Result { + if key.len() != Self::KeySize::to_usize() { + Err(InvalidLength) + } else { + Ok(Self::new(Key::::from_slice(key))) + } + } + + /// Generate random key using the provided [`CryptoRng`]. + #[cfg(feature = "rand_core")] + #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] #[inline] - fn finalize_fixed(self) -> GenericArray { - let mut out = Default::default(); - self.finalize_into(&mut out); - out + fn generate_key(mut rng: impl CryptoRng + RngCore) -> Key { + let mut key = Key::::default(); + rng.fill_bytes(&mut key); + key } } -/// Trait for types which return fixed-sized result after finalization and reset -/// values into its initial state. -pub trait FixedOutputReset: FixedOutput + Reset { - /// Write result into provided array and reset value to its initial state. - fn finalize_into_reset(&mut self, out: &mut GenericArray); +/// Types which can be initialized from key and initialization vector (nonce). +pub trait KeyIvInit: KeySizeUser + IvSizeUser + Sized { + /// Create new value from fixed length key and nonce. + fn new(key: &Key, iv: &Iv) -> Self; + + /// Create new value from variable length key and nonce. + #[inline] + fn new_from_slices(key: &[u8], iv: &[u8]) -> Result { + let key_len = Self::KeySize::USIZE; + let iv_len = Self::IvSize::USIZE; + if key.len() != key_len || iv.len() != iv_len { + Err(InvalidLength) + } else { + Ok(Self::new( + Key::::from_slice(key), + Iv::::from_slice(iv), + )) + } + } + + /// Generate random key using the provided [`CryptoRng`]. + #[cfg(feature = "rand_core")] + #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] + #[inline] + fn generate_key(mut rng: impl CryptoRng + RngCore) -> Key { + let mut key = Key::::default(); + rng.fill_bytes(&mut key); + key + } + + /// Generate random IV using the provided [`CryptoRng`]. + #[cfg(feature = "rand_core")] + #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] + #[inline] + fn generate_iv(mut rng: impl CryptoRng + RngCore) -> Iv { + let mut iv = Iv::::default(); + rng.fill_bytes(&mut iv); + iv + } - /// Retrieve result and reset the hasher instance. + /// Generate random key and nonce using the provided [`CryptoRng`]. + #[cfg(feature = "rand_core")] + #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] #[inline] - fn finalize_fixed_reset(&mut self) -> GenericArray { - let mut out = Default::default(); - self.finalize_into_reset(&mut out); - out + fn generate_key_iv(mut rng: impl CryptoRng + RngCore) -> (Key, Iv) { + (Self::generate_key(&mut rng), Self::generate_iv(&mut rng)) } } -/// Trait for resetting values to initial state. -pub trait Reset { - /// Reset value to its initial state. - fn reset(&mut self); +/// Types which can be initialized from another type (usually block ciphers). +/// +/// Usually used for initializing types from block ciphers. +pub trait InnerInit: InnerUser + Sized { + /// Initialize value from the `inner`. + fn inner_init(inner: Self::Inner) -> Self; } + +/// Types which can be initialized from another type and additional initialization +/// vector/nonce. +/// +/// Usually used for initializing types from block ciphers. +pub trait InnerIvInit: InnerUser + IvSizeUser + Sized { + /// Initialize value using `inner` and `iv` array. + fn inner_iv_init(inner: Self::Inner, iv: &Iv) -> Self; + + /// Initialize value using `inner` and `iv` slice. + fn inner_iv_slice_init(inner: Self::Inner, iv: &[u8]) -> Result { + if iv.len() != Self::IvSize::to_usize() { + Err(InvalidLength) + } else { + Ok(Self::inner_iv_init(inner, Iv::::from_slice(iv))) + } + } + + /// Generate random IV using the provided [`CryptoRng`]. + #[cfg(feature = "rand_core")] + #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] + #[inline] + fn generate_iv(mut rng: impl CryptoRng + RngCore) -> Iv { + let mut iv = Iv::::default(); + rng.fill_bytes(&mut iv); + iv + } +} + +impl KeySizeUser for T +where + T: InnerUser, + T::Inner: KeySizeUser, +{ + type KeySize = ::KeySize; +} + +impl KeyIvInit for T +where + T: InnerIvInit, + T::Inner: KeyInit, +{ + #[inline] + fn new(key: &Key, iv: &Iv) -> Self { + Self::inner_iv_init(T::Inner::new(key), iv) + } + + #[inline] + fn new_from_slices(key: &[u8], iv: &[u8]) -> Result { + T::Inner::new_from_slice(key).and_then(|i| T::inner_iv_slice_init(i, iv)) + } +} + +impl KeyInit for T +where + T: InnerInit, + T::Inner: KeyInit, +{ + #[inline] + fn new(key: &Key) -> Self { + Self::inner_init(T::Inner::new(key)) + } + + #[inline] + fn new_from_slice(key: &[u8]) -> Result { + T::Inner::new_from_slice(key) + .map_err(|_| InvalidLength) + .map(Self::inner_init) + } +} + +// Unfortunately this blanket impl is impossible without mutually +// exclusive traits, see: https://github.com/rust-lang/rfcs/issues/1053 +// or at the very least without: https://github.com/rust-lang/rust/issues/20400 +/* +impl KeyIvInit for T +where + T: InnerInit, + T::Inner: KeyIvInit, +{ + #[inline] + fn new(key: &Key, iv: &Iv) -> Self { + Self::inner_init(T::Inner::new(key, iv)) + } + + #[inline] + fn new_from_slices(key: &[u8], iv: &[u8]) -> Result { + T::Inner::new_from_slice(key) + .map_err(|_| InvalidLength) + .map(Self::inner_init) + } +} +*/ + +/// The error type returned when key and/or IV used in the [`KeyInit`], +/// [`KeyIvInit`], and [`InnerIvInit`] slice-based methods had +/// an invalid length. +#[derive(Copy, Clone, Eq, PartialEq, Debug)] +pub struct InvalidLength; + +impl fmt::Display for InvalidLength { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + f.write_str("Invalid Length") + } +} + +#[cfg(feature = "std")] +impl std::error::Error for InvalidLength {} diff --git a/crypto-mac/CHANGELOG.md b/crypto-mac/CHANGELOG.md deleted file mode 100644 index 7488081b1..000000000 --- a/crypto-mac/CHANGELOG.md +++ /dev/null @@ -1,104 +0,0 @@ -# Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## [Unreleased] -### Added -- Re-export `rand_core` ([#683]) - -[#683]: https://github.com/RustCrypto/traits/pull/683 - -## 0.11.1 (2021-07-20) -### Changed -- Pin `subtle` dependency to v2.4 ([#691]) - -[#691]: https://github.com/RustCrypto/traits/pull/691 - -## 0.11.0 (2021-04-28) -### Added -- `generate_key` method to `New*` trait ([#513]) - -### Changed -- Renamed `new_var` to `new_from_slice` ([#442]) -- Bump `cipher` dependency to v0.3 ([#621]) - -[#442]: https://github.com/RustCrypto/traits/pull/442 -[#513]: https://github.com/RustCrypto/traits/pull/513 -[#621]: https://github.com/RustCrypto/traits/pull/621 - -## 0.10.1 (2021-07-20) -### Changed -- Pin `subtle` dependency to v2.4 ([#690]) - -[#690]: https://github.com/RustCrypto/traits/pull/690 - -## 0.10.0 (2020-10-15) -### Changed -- Replace `block-cipher` crate with new `cipher` crate ([#337], [#338]) - -[#338]: https://github.com/RustCrypto/traits/pull/338 -[#337]: https://github.com/RustCrypto/traits/pull/337 - -## 0.9.1 (2020-08-12) -### Added -- Re-export the `block-cipher` crate ([#257]) - -[#257]: https://github.com/RustCrypto/traits/pull/257 - -## 0.9.0 (2020-08-10) -### Added -- `FromBlockCipher` trait and blanket implementation of the `NewMac` trait -for it ([#217]) - -### Changed -- Updated test vectors storage to `blobby v0.3` ([#217]) - -### Removed -- `impl_write!` macro ([#217]) - -[#217]: https://github.com/RustCrypto/traits/pull/217 - -## 0.8.0 (2020-06-04) -### Added -- `impl_write!` macro ([#134]) - -### Changed -- Bump `generic-array` dependency to v0.14 ([#144]) -- Split `Mac` initialization into `NewMac` trait ([#133]) -- Rename `MacResult` => `Output`, `code` => `into_bytes` ([#114]) -- Rename `Input::input` to `Update::update` ([#111]) -- Update to 2018 edition ([#108]) -- Bump `subtle` dependency from v1.0 to v2.0 ([#33]) - -[#144]: https://github.com/RustCrypto/traits/pull/95 -[#134]: https://github.com/RustCrypto/traits/pull/134 -[#133]: https://github.com/RustCrypto/traits/pull/133 -[#114]: https://github.com/RustCrypto/traits/pull/114 -[#111]: https://github.com/RustCrypto/traits/pull/111 -[#108]: https://github.com/RustCrypto/traits/pull/108 -[#33]: https://github.com/RustCrypto/traits/pull/33 - -## 0.7.0 (2018-10-01) - -## 0.6.2 (2018-06-21) - -## 0.6.1 (2018-06-20) - -## 0.6.0 (2017-11-26) - -## 0.5.2 (2017-11-20) - -## 0.5.1 (2017-11-15) - -## 0.5.0 (2017-11-14) - -## 0.4.0 (2017-06-12) - -## 0.3.0 (2017-05-14) - -## 0.2.0 (2017-05-14) - -## 0.1.0 (2016-10-14) diff --git a/crypto-mac/Cargo.toml b/crypto-mac/Cargo.toml deleted file mode 100644 index 725f75fa4..000000000 --- a/crypto-mac/Cargo.toml +++ /dev/null @@ -1,30 +0,0 @@ -[package] -name = "crypto-mac" -description = "Trait for Message Authentication Code (MAC) algorithms" -version = "0.12.0-pre" # Also update html_root_url in lib.rs when bumping this -authors = ["RustCrypto Developers"] -license = "MIT OR Apache-2.0" -readme = "README.md" -edition = "2018" -documentation = "https://docs.rs/crypto-mac" -repository = "https://github.com/RustCrypto/traits" -keywords = ["crypto", "mac"] -categories = ["cryptography", "no-std"] - -[dependencies] -generic-array = "0.14" -crypto-common = { version = "=0.1.0-pre", path = "../crypto-common" } -cipher = { version = "=0.4.0-pre", path = "../cipher" } -subtle = { version = "=2.4", default-features = false } - -blobby = { version = "0.3", optional = true } -rand_core = { version = "0.6", optional = true } - -[features] -dev = ["blobby"] -core-api = ["crypto-common/core-api"] -std = ["crypto-common/std", "rand_core/std"] - -[package.metadata.docs.rs] -all-features = true -rustdoc-args = ["--cfg", "docsrs"] diff --git a/crypto-mac/LICENSE-APACHE b/crypto-mac/LICENSE-APACHE deleted file mode 100644 index 78173fa2e..000000000 --- a/crypto-mac/LICENSE-APACHE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - -Copyright [yyyy] [name of copyright owner] - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/crypto-mac/LICENSE-MIT b/crypto-mac/LICENSE-MIT deleted file mode 100644 index 8dcb85b30..000000000 --- a/crypto-mac/LICENSE-MIT +++ /dev/null @@ -1,25 +0,0 @@ -Copyright (c) 2017 Artyom Pavlov - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without -limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/crypto-mac/README.md b/crypto-mac/README.md deleted file mode 100644 index 889d6c244..000000000 --- a/crypto-mac/README.md +++ /dev/null @@ -1,59 +0,0 @@ -# RustCrypto: Message Authentication Code Traits - -[![crate][crate-image]][crate-link] -[![Docs][docs-image]][docs-link] -![Apache2/MIT licensed][license-image] -![Rust Version][rustc-image] -[![Project Chat][chat-image]][chat-link] -[![Build Status][build-image]][build-link] - -Traits for [Message Authentication Code] (MAC) algorithms. - -See [RustCrypto/MACs] for implementations which use this trait. - -[Documentation][docs-link] - -## Minimum Supported Rust Version - -Rust **1.41** or higher. - -Minimum supported Rust version can be changed in the future, but it will be -done with a minor version bump. - -## SemVer Policy - -- All on-by-default features of this library are covered by SemVer -- MSRV is considered exempt from SemVer as noted above - -## License - -Licensed under either of: - - * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) - * [MIT license](http://opensource.org/licenses/MIT) - -at your option. - -### Contribution - -Unless you explicitly state otherwise, any contribution intentionally submitted -for inclusion in the work by you, as defined in the Apache-2.0 license, shall be -dual licensed as above, without any additional terms or conditions. - -[//]: # (badges) - -[crate-image]: https://img.shields.io/crates/v/crypto-mac.svg -[crate-link]: https://crates.io/crates/crypto-mac -[docs-image]: https://docs.rs/crypto-mac/badge.svg -[docs-link]: https://docs.rs/crypto-mac/ -[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg -[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg -[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260044-MACs -[build-image]: https://github.com/RustCrypto/traits/workflows/crypto-mac/badge.svg?branch=master&event=push -[build-link]: https://github.com/RustCrypto/traits/actions?query=workflow%3Acrypto-mac - -[//]: # (general links) - -[Message Authentication Code]: https://en.wikipedia.org/wiki/Message_authentication_code -[RustCrypto/MACs]: https://github.com/RustCrypto/MACs diff --git a/crypto-mac/src/core_api.rs b/crypto-mac/src/core_api.rs deleted file mode 100644 index 7f7e6a6ec..000000000 --- a/crypto-mac/src/core_api.rs +++ /dev/null @@ -1,2 +0,0 @@ -//! Low-level core API traits. -pub use crypto_common::core_api::{AlgorithmName, CoreWrapper, FixedOutputCore, UpdateCore}; diff --git a/crypto-mac/src/dev.rs b/crypto-mac/src/dev.rs deleted file mode 100644 index 1c397e631..000000000 --- a/crypto-mac/src/dev.rs +++ /dev/null @@ -1,148 +0,0 @@ -//! Development-related functionality - -pub use blobby; - -/// Define test -#[macro_export] -#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] -macro_rules! new_test { - ($name:ident, $test_name:expr, $mac:ty) => { - #[test] - fn $name() { - use crypto_mac::dev::blobby::Blob3Iterator; - use crypto_mac::{Mac, NewMac}; - - fn run_test(key: &[u8], input: &[u8], tag: &[u8]) -> Option<&'static str> { - let mut mac = <$mac as NewMac>::new_from_slice(key).unwrap(); - mac.update(input); - let result = mac.finalize_reset(); - if &result.into_bytes()[..] != tag { - return Some("whole message"); - } - // test if reset worked correctly - mac.update(input); - if mac.verify(&tag).is_err() { - return Some("after reset"); - } - - let mut mac = <$mac as NewMac>::new_from_slice(key).unwrap(); - // test reading byte by byte - for i in 0..input.len() { - mac.update(&input[i..i + 1]); - } - if let Err(_) = mac.verify(tag) { - return Some("message byte-by-byte"); - } - None - } - - let data = include_bytes!(concat!("data/", $test_name, ".blb")); - - for (i, row) in Blob3Iterator::new(data).unwrap().enumerate() { - let [key, input, tag] = row.unwrap(); - if let Some(desc) = run_test(key, input, tag) { - panic!( - "\n\ - Failed test №{}: {}\n\ - key:\t{:?}\n\ - input:\t{:?}\n\ - tag:\t{:?}\n", - i, desc, key, input, tag, - ); - } - } - } - }; -} - -/// Define test that allows for truncated tag. -#[macro_export] -#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] -macro_rules! new_trunc_test { - ($name:ident, $test_name:expr, $mac:ty) => { - #[test] - fn $name() { - use crypto_mac::dev::blobby::Blob3Iterator; - use crypto_mac::generic_array::typenum::Unsigned; - use crypto_mac::{Mac, NewMac}; - - fn run_test(key: &[u8], input: &[u8], tag: &[u8]) -> Option<&'static str> { - let mut mac = <$mac as NewMac>::new_from_slice(key).unwrap(); - mac.update(input); - let result = mac.finalize_reset(); - let mut len = <$mac as Mac>::OutputSize::to_usize(); - if tag.len() < len { - len = tag.len(); - } - if &result.into_bytes()[..len] != tag { - return Some("whole message"); - } - // test if reset worked correctly - mac.update(input); - let result = mac.finalize(); - if &result.into_bytes()[..len] != tag { - return Some("after reset"); - } - - let mut mac = <$mac as NewMac>::new_from_slice(key).unwrap(); - // test reading byte by byte - for i in 0..input.len() { - mac.update(&input[i..i + 1]); - } - let result = mac.finalize(); - if &result.into_bytes()[..len] != tag { - return Some("message byte-by-byte"); - } - None - } - - let data = include_bytes!(concat!("data/", $test_name, ".blb")); - - for (i, row) in Blob3Iterator::new(data).unwrap().enumerate() { - let [key, input, tag] = row.unwrap(); - if let Some(desc) = run_test(key, input, tag) { - panic!( - "\n\ - Failed test №{}: {}\n\ - key:\t{:?}\n\ - input:\t{:?}\n\ - tag:\t{:?}\n", - i, desc, key, input, tag, - ); - } - } - } - }; -} - -/// Define benchmark -#[macro_export] -#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] -macro_rules! bench { - ($name:ident, $engine:path, $bs:expr) => { - #[bench] - fn $name(b: &mut Bencher) { - let key = Default::default(); - let mut mac = <$engine>::new(&key); - let data = [0; $bs]; - - b.iter(|| { - mac.update(&data); - }); - - b.bytes = $bs; - } - }; - - ($engine:path) => { - extern crate test; - - use crypto_mac::{Mac, NewMac}; - use test::Bencher; - - $crate::bench!(bench1_10, $engine, 10); - $crate::bench!(bench2_100, $engine, 100); - $crate::bench!(bench3_1000, $engine, 1000); - $crate::bench!(bench3_10000, $engine, 10000); - }; -} diff --git a/crypto-mac/src/lib.rs b/crypto-mac/src/lib.rs deleted file mode 100644 index e5e2f2ba7..000000000 --- a/crypto-mac/src/lib.rs +++ /dev/null @@ -1,123 +0,0 @@ -//! This crate provides trait for Message Authentication Code (MAC) algorithms. - -#![no_std] -#![cfg_attr(docsrs, feature(doc_cfg))] -#![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/crypto-mac/0.12.0-pre" -)] -#![forbid(unsafe_code)] -#![warn(missing_docs, rust_2018_idioms)] - -#[cfg(feature = "std")] -extern crate std; - -#[cfg(feature = "rand_core")] -#[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] -pub use rand_core; - -#[cfg(feature = "cipher")] -pub use cipher; -#[cfg(feature = "cipher")] -use cipher::{BlockCipher, NewBlockCipher}; - -#[cfg(feature = "dev")] -#[cfg_attr(docsrs, doc(cfg(feature = "dev")))] -pub mod dev; - -#[cfg(feature = "core-api")] -#[cfg_attr(docsrs, doc(cfg(feature = "core-api")))] -pub mod core_api; - -pub use cipher::{errors::InvalidLength, FromKey}; -pub use crypto_common::{FixedOutput, FixedOutputReset, Reset, Update}; -pub use generic_array::{self, typenum::consts}; - -use core::fmt; -use generic_array::GenericArray; -use subtle::{Choice, ConstantTimeEq}; - -/// Key for an algorithm that implements [`FromKey`]. -pub type Key = GenericArray::KeySize>; - -/// Convinience super-trait covering functionality of Message Authentication algorithms. -pub trait Mac: FromKey + Update + FixedOutput { - /// Obtain the result of a [`Mac`] computation as a [`Output`] and consume - /// [`Mac`] instance. - fn finalize(self) -> Output { - Output::new(self.finalize_fixed()) - } - - /// Obtain the result of a [`Mac`] computation as a [`Output`] and reset - /// [`Mac`] instance. - fn finalize_reset(&mut self) -> Output - where - Self: FixedOutputReset, - { - Output::new(self.finalize_fixed_reset()) - } - - /// Check if tag/code value is correct for the processed input. - fn verify(self, tag: &[u8]) -> Result<(), MacError> { - let choice = self.finalize().bytes.ct_eq(tag); - - if choice.unwrap_u8() == 1 { - Ok(()) - } else { - Err(MacError) - } - } -} - -impl Mac for T {} - -/// [`Output`] is a thin wrapper around bytes array which provides a safe `Eq` -/// implementation that runs in a fixed time. -#[derive(Clone)] -pub struct Output { - bytes: GenericArray, -} - -impl Output { - /// Create a new MAC [`Output`]. - pub fn new(bytes: GenericArray) -> Output { - Output { bytes } - } - - /// Get the MAC tag/code value as a byte array. - /// - /// Be very careful using this method, since incorrect use of the tag value - /// may permit timing attacks which defeat the security provided by the - /// [`Mac`] trait. - pub fn into_bytes(self) -> GenericArray { - self.bytes - } -} - -impl ConstantTimeEq for Output { - fn ct_eq(&self, other: &Self) -> Choice { - self.bytes.ct_eq(&other.bytes) - } -} - -impl PartialEq for Output { - fn eq(&self, x: &Output) -> bool { - self.ct_eq(x).unwrap_u8() == 1 - } -} - -impl Eq for Output {} - -/// Error type for signaling failed MAC verification -#[derive(Default, Debug, Copy, Clone, Eq, PartialEq)] -pub struct MacError; - -impl fmt::Display for MacError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str("failed MAC verification") - } -} - -#[cfg(feature = "std")] -impl std::error::Error for MacError {} diff --git a/digest/CHANGELOG.md b/digest/CHANGELOG.md index 0b8547c6f..60dfb44d6 100644 --- a/digest/CHANGELOG.md +++ b/digest/CHANGELOG.md @@ -5,13 +5,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 0.10.0 (2021-01-18) -### Breaking changes +## 0.10.0 (2021-12-07) +### Changed - Dirty traits are removed and instead block-level traits are introduced. -Variable output traits are removed as well in favor of fixed output tratis, -implementors of variable output hashes are expected to be generic over -output size. ([#380]) +Variable output traits reworked and now support both run and compile time selection of output size. ([#380], [#819]) +- The `crypto-mac` traits are reworked and merged in. ([#819]) +[#819]: https://github.com/RustCrypto/traits/pull/819 [#380]: https://github.com/RustCrypto/traits/pull/380 ## 0.9.0 (2020-06-09) diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 61852b9d9..f7359bb2a 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "digest" description = "Traits for cryptographic hash functions" -version = "0.10.0-pre.3" +version = "0.10.0" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" @@ -13,16 +13,19 @@ categories = ["cryptography", "no-std"] [dependencies] generic-array = "0.14" -crypto-common = { version = "=0.1.0-pre", path = "../crypto-common" } +crypto-common = { version = "0.1", path = "../crypto-common" } +block-buffer = { version = "0.10", optional = true } +subtle = { version = "=2.4", default-features = false, optional = true } blobby = { version = "0.3", optional = true } [features] +default = ["core-api"] +core-api = ["block-buffer"] # Enable Core API traits +mac = ["subtle"] # Enable MAC traits alloc = [] std = ["alloc", "crypto-common/std"] dev = ["blobby"] -core-api = ["crypto-common/core-api"] -block-padding = ["crypto-common/block-padding"] [package.metadata.docs.rs] all-features = true diff --git a/digest/src/core_api.rs b/digest/src/core_api.rs index 63e573d33..6783e1985 100644 --- a/digest/src/core_api.rs +++ b/digest/src/core_api.rs @@ -1,80 +1,117 @@ -//! Low-level core API traits. +//! Low-level traits operating on blocks and wrappers around them. //! //! Usage of traits in this module in user code is discouraged. Instead use //! core algorithm wrapped by the wrapper types, which implement the //! higher-level traits. use crate::InvalidOutputSize; -use crate::{ExtendableOutput, Reset}; -use generic_array::{ArrayLength, GenericArray}; +use generic_array::typenum::{IsLess, Le, NonZero, U256}; -pub use crypto_common::core_api::{AlgorithmName, CoreWrapper, FixedOutputCore, UpdateCore}; +pub use crypto_common::{AlgorithmName, Block, BlockSizeUser, OutputSizeUser, Reset}; + +use block_buffer::{BlockBuffer, BufferKind}; +use crypto_common::Output; mod ct_variable; mod rt_variable; +mod wrapper; mod xof_reader; pub use ct_variable::CtVariableCoreWrapper; pub use rt_variable::RtVariableCoreWrapper; +pub use wrapper::{CoreProxy, CoreWrapper}; pub use xof_reader::XofReaderCoreWrapper; +/// Buffer type used by type which implements [`BufferKindUser`]. +pub type Buffer = + BlockBuffer<::BlockSize, ::BufferKind>; + +/// Types which consume data in blocks. +pub trait UpdateCore: BlockSizeUser { + /// Update state using the provided data blocks. + fn update_blocks(&mut self, blocks: &[Block]); +} + +/// Types which use [`BlockBuffer`] functionality. +pub trait BufferKindUser: BlockSizeUser { + /// Block buffer kind over which type operates. + type BufferKind: BufferKind; +} + +/// Core trait for hash functions with fixed output size. +pub trait FixedOutputCore: UpdateCore + BufferKindUser + OutputSizeUser +where + Self::BlockSize: IsLess, + Le: NonZero, +{ + /// Finalize state using remaining data stored in the provided block buffer, + /// write result into provided array and leave `self` in a dirty state. + fn finalize_fixed_core(&mut self, buffer: &mut Buffer, out: &mut Output); +} + /// Core trait for hash functions with extendable (XOF) output size. -pub trait ExtendableOutputCore: UpdateCore { +pub trait ExtendableOutputCore: UpdateCore + BufferKindUser +where + Self::BlockSize: IsLess, + Le: NonZero, +{ /// XOF reader core state. type ReaderCore: XofReaderCore; /// Retrieve XOF reader using remaining data stored in the block buffer /// and leave hasher in a dirty state. - fn finalize_xof_core(&mut self, buffer: &mut Self::Buffer) -> Self::ReaderCore; + fn finalize_xof_core(&mut self, buffer: &mut Buffer) -> Self::ReaderCore; } /// Core reader trait for extendable-output function (XOF) result. -pub trait XofReaderCore { - /// Block size in bytes. - type BlockSize: ArrayLength; - +pub trait XofReaderCore: BlockSizeUser { /// Read next XOF block. - fn read_block(&mut self) -> GenericArray; + fn read_block(&mut self) -> Block; } /// Core trait for hash functions with variable output size. -pub trait VariableOutputCore: UpdateCore + Sized { - /// Maximum output size. - type MaxOutputSize: ArrayLength; +/// +/// Maximum output size is equal to [`OutputSizeUser::OutputSize`]. +/// Users are expected to truncate result returned by the +/// [`finalize_variable_core`] to `output_size` passed to the [`new`] method +/// during construction. Truncation side is defined by the [`TRUNC_SIDE`] +/// associated constant. +/// +/// [`finalize_variable_core`]: VariableOutputCore::finalize_variable_core +/// [`new`]: VariableOutputCore::new +/// [`TRUNC_SIDE`]: VariableOutputCore::TRUNC_SIDE +pub trait VariableOutputCore: UpdateCore + OutputSizeUser + BufferKindUser + Sized +where + Self::BlockSize: IsLess, + Le: NonZero, +{ + /// Side which should be used in a truncated result. + const TRUNC_SIDE: TruncSide; /// Initialize hasher state for given output size. /// - /// Returns [`InvalidOutputSize`] if `output_size` is equal to zero or - /// bigger than `Self::MaxOutputSize`. + /// Returns [`InvalidOutputSize`] if `output_size` is not valid for + /// the algorithm, e.g. if it's bigger than the [`OutputSize`] + /// associated type. + /// + /// [`OutputSize`]: OutputSizeUser::OutputSize fn new(output_size: usize) -> Result; - /// Finalize hasher and return result of lenght `output_size` via closure `f`. + /// Finalize hasher and write full hashing result into the `out` buffer. /// - /// `output_size` must be equal to `output_size` used during construction. - fn finalize_variable_core( - &mut self, - buffer: &mut Self::Buffer, - output_size: usize, - f: impl FnOnce(&[u8]), - ); + /// The result must be truncated to `output_size` used during hasher + /// construction. Truncation side is defined by the [`TRUNC_SIDE`] + /// associated constant. + /// + /// [`TRUNC_SIDE`]: VariableOutputCore::TRUNC_SIDE + fn finalize_variable_core(&mut self, buffer: &mut Buffer, out: &mut Output); } -impl ExtendableOutput for CoreWrapper { - type Reader = XofReaderCoreWrapper; - - #[inline] - fn finalize_xof(self) -> Self::Reader { - let (mut core, mut buffer) = self.decompose(); - let core = core.finalize_xof_core(&mut buffer); - let buffer = Default::default(); - Self::Reader { core, buffer } - } - - #[inline] - fn finalize_xof_reset(&mut self) -> Self::Reader { - self.apply_reset(|core, buffer| { - let core = core.finalize_xof_core(buffer); - let buffer = Default::default(); - Self::Reader { core, buffer } - }) - } +/// Type which used for defining truncation side in the [`VariableOutputCore`] +/// trait. +#[derive(Copy, Clone, Debug)] +pub enum TruncSide { + /// Truncate left side, i.e. `&out[..n]`. + Left, + /// Truncate right side, i.e. `&out[m..]`. + Right, } diff --git a/digest/src/core_api/ct_variable.rs b/digest/src/core_api/ct_variable.rs index 11474326f..c69544912 100644 --- a/digest/src/core_api/ct_variable.rs +++ b/digest/src/core_api/ct_variable.rs @@ -1,7 +1,14 @@ -use super::{AlgorithmName, FixedOutputCore, Reset, UpdateCore, VariableOutputCore}; +use super::{ + AlgorithmName, Buffer, BufferKindUser, FixedOutputCore, Reset, TruncSide, UpdateCore, + VariableOutputCore, +}; +use crate::HashMarker; +#[cfg(feature = "mac")] +use crate::MacMarker; use core::{fmt, marker::PhantomData}; +use crypto_common::{Block, BlockSizeUser, OutputSizeUser}; use generic_array::{ - typenum::{IsLessOrEqual, LeEq, NonZero}, + typenum::{IsLess, IsLessOrEqual, Le, LeEq, NonZero, U256}, ArrayLength, GenericArray, }; @@ -11,58 +18,121 @@ use generic_array::{ pub struct CtVariableCoreWrapper where T: VariableOutputCore, - OutSize: ArrayLength + IsLessOrEqual, - LeEq: NonZero, + OutSize: ArrayLength + IsLessOrEqual, + LeEq: NonZero, + T::BlockSize: IsLess, + Le: NonZero, { inner: T, _out: PhantomData, } -impl UpdateCore for CtVariableCoreWrapper +impl HashMarker for CtVariableCoreWrapper +where + T: VariableOutputCore + HashMarker, + OutSize: ArrayLength + IsLessOrEqual, + LeEq: NonZero, + T::BlockSize: IsLess, + Le: NonZero, +{ +} + +#[cfg(feature = "mac")] +impl MacMarker for CtVariableCoreWrapper +where + T: VariableOutputCore + MacMarker, + OutSize: ArrayLength + IsLessOrEqual, + LeEq: NonZero, + T::BlockSize: IsLess, + Le: NonZero, +{ +} + +impl BlockSizeUser for CtVariableCoreWrapper where T: VariableOutputCore, - OutSize: ArrayLength + IsLessOrEqual, - LeEq: NonZero, + OutSize: ArrayLength + IsLessOrEqual, + LeEq: NonZero, + T::BlockSize: IsLess, + Le: NonZero, { type BlockSize = T::BlockSize; - type Buffer = T::Buffer; +} +impl UpdateCore for CtVariableCoreWrapper +where + T: VariableOutputCore, + OutSize: ArrayLength + IsLessOrEqual, + LeEq: NonZero, + T::BlockSize: IsLess, + Le: NonZero, +{ #[inline] - fn update_blocks(&mut self, blocks: &[GenericArray]) { + fn update_blocks(&mut self, blocks: &[Block]) { self.inner.update_blocks(blocks); } } -impl FixedOutputCore for CtVariableCoreWrapper +impl OutputSizeUser for CtVariableCoreWrapper where T: VariableOutputCore, - OutSize: ArrayLength + IsLessOrEqual, - LeEq: NonZero, + OutSize: ArrayLength + IsLessOrEqual + 'static, + LeEq: NonZero, + T::BlockSize: IsLess, + Le: NonZero, { type OutputSize = OutSize; +} +impl BufferKindUser for CtVariableCoreWrapper +where + T: VariableOutputCore, + OutSize: ArrayLength + IsLessOrEqual, + LeEq: NonZero, + T::BlockSize: IsLess, + Le: NonZero, +{ + type BufferKind = T::BufferKind; +} + +impl FixedOutputCore for CtVariableCoreWrapper +where + T: VariableOutputCore, + OutSize: ArrayLength + IsLessOrEqual + 'static, + LeEq: NonZero, + T::BlockSize: IsLess, + Le: NonZero, +{ #[inline] fn finalize_fixed_core( &mut self, - buffer: &mut Self::Buffer, + buffer: &mut Buffer, out: &mut GenericArray, ) { - self.inner - .finalize_variable_core(buffer, out.len(), |r| out.copy_from_slice(r)); + let mut full_res = Default::default(); + self.inner.finalize_variable_core(buffer, &mut full_res); + let n = out.len(); + let m = full_res.len() - n; + match T::TRUNC_SIDE { + TruncSide::Left => out.copy_from_slice(&full_res[..n]), + TruncSide::Right => out.copy_from_slice(&full_res[m..]), + } } } impl Default for CtVariableCoreWrapper where T: VariableOutputCore, - OutSize: ArrayLength + IsLessOrEqual, - LeEq: NonZero, + OutSize: ArrayLength + IsLessOrEqual, + LeEq: NonZero, + T::BlockSize: IsLess, + Le: NonZero, { #[inline] fn default() -> Self { Self { inner: T::new(OutSize::USIZE).unwrap(), - _out: Default::default(), + _out: PhantomData, } } } @@ -70,8 +140,10 @@ where impl Reset for CtVariableCoreWrapper where T: VariableOutputCore, - OutSize: ArrayLength + IsLessOrEqual, - LeEq: NonZero, + OutSize: ArrayLength + IsLessOrEqual, + LeEq: NonZero, + T::BlockSize: IsLess, + Le: NonZero, { #[inline] fn reset(&mut self) { @@ -82,8 +154,10 @@ where impl AlgorithmName for CtVariableCoreWrapper where T: VariableOutputCore + AlgorithmName, - OutSize: ArrayLength + IsLessOrEqual, - LeEq: NonZero, + OutSize: ArrayLength + IsLessOrEqual, + LeEq: NonZero, + T::BlockSize: IsLess, + Le: NonZero, { fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { T::write_alg_name(f)?; diff --git a/digest/src/core_api/rt_variable.rs b/digest/src/core_api/rt_variable.rs index c9af06ae3..0c2233fe0 100644 --- a/digest/src/core_api/rt_variable.rs +++ b/digest/src/core_api/rt_variable.rs @@ -1,8 +1,11 @@ -use super::{AlgorithmName, UpdateCore, VariableOutputCore}; -use crate::{InvalidOutputSize, Reset, Update, VariableOutput}; +use super::{AlgorithmName, TruncSide, UpdateCore, VariableOutputCore}; +#[cfg(feature = "mac")] +use crate::MacMarker; +use crate::{HashMarker, InvalidBufferSize}; +use crate::{InvalidOutputSize, Reset, Update, VariableOutput, VariableOutputReset}; +use block_buffer::BlockBuffer; use core::fmt; -use crypto_common::block_buffer::DigestBuffer; -use generic_array::typenum::Unsigned; +use generic_array::typenum::{IsLess, Le, NonZero, Unsigned, U256}; /// Wrapper around [`VariableOutputCore`] which selects output size /// at run time. @@ -10,32 +13,78 @@ use generic_array::typenum::Unsigned; pub struct RtVariableCoreWrapper where T: VariableOutputCore + UpdateCore, + T::BlockSize: IsLess, + Le: NonZero, { core: T, - buffer: T::Buffer, + buffer: BlockBuffer, output_size: usize, } +impl RtVariableCoreWrapper +where + T: VariableOutputCore, + T::BlockSize: IsLess, + Le: NonZero, +{ + #[inline] + fn finalize_dirty(&mut self, out: &mut [u8]) -> Result<(), InvalidBufferSize> { + let Self { + core, + buffer, + output_size, + } = self; + if out.len() != *output_size || out.len() > Self::MAX_OUTPUT_SIZE { + return Err(InvalidBufferSize); + } + let mut full_res = Default::default(); + core.finalize_variable_core(buffer, &mut full_res); + let n = out.len(); + let m = full_res.len() - n; + match T::TRUNC_SIDE { + TruncSide::Left => out.copy_from_slice(&full_res[..n]), + TruncSide::Right => out.copy_from_slice(&full_res[m..]), + } + Ok(()) + } +} + +impl HashMarker for RtVariableCoreWrapper +where + T: VariableOutputCore + HashMarker, + T::BlockSize: IsLess, + Le: NonZero, +{ +} + +#[cfg(feature = "mac")] +#[cfg_attr(docsrs, doc(cfg(feature = "mac")))] +impl MacMarker for RtVariableCoreWrapper +where + T: VariableOutputCore + MacMarker, + T::BlockSize: IsLess, + Le: NonZero, +{ +} + impl Reset for RtVariableCoreWrapper where - T: VariableOutputCore + UpdateCore, + T: VariableOutputCore + UpdateCore + Reset, + T::BlockSize: IsLess, + Le: NonZero, { #[inline] fn reset(&mut self) { - // For correct implementations `new` should always return `Ok` - // since wrapper can be only created with valid `output_size` - if let Ok(v) = T::new(self.output_size) { - self.core = v; - } else { - debug_assert!(false); - } self.buffer.reset(); + self.core.reset(); } } impl Update for RtVariableCoreWrapper where T: VariableOutputCore + UpdateCore, + T::BlockSize: IsLess, + Le: NonZero, { #[inline] fn update(&mut self, input: &[u8]) { @@ -47,8 +96,10 @@ where impl VariableOutput for RtVariableCoreWrapper where T: VariableOutputCore + UpdateCore, + T::BlockSize: IsLess, + Le: NonZero, { - const MAX_OUTPUT_SIZE: usize = T::MaxOutputSize::USIZE; + const MAX_OUTPUT_SIZE: usize = T::OutputSize::USIZE; fn new(output_size: usize) -> Result { let buffer = Default::default(); @@ -63,29 +114,30 @@ where self.output_size } - fn finalize_variable(mut self, f: impl FnOnce(&[u8])) { - let Self { - core, - buffer, - output_size, - } = &mut self; - core.finalize_variable_core(buffer, *output_size, f); + fn finalize_variable(mut self, out: &mut [u8]) -> Result<(), InvalidBufferSize> { + self.finalize_dirty(out) } +} - fn finalize_variable_reset(&mut self, f: impl FnOnce(&[u8])) { - let Self { - core, - buffer, - output_size, - } = self; - core.finalize_variable_core(buffer, *output_size, f); - self.reset() +impl VariableOutputReset for RtVariableCoreWrapper +where + T: VariableOutputCore + UpdateCore + Reset, + T::BlockSize: IsLess, + Le: NonZero, +{ + fn finalize_variable_reset(&mut self, out: &mut [u8]) -> Result<(), InvalidBufferSize> { + self.finalize_dirty(out)?; + self.core.reset(); + self.buffer.reset(); + Ok(()) } } impl fmt::Debug for RtVariableCoreWrapper where T: VariableOutputCore + UpdateCore + AlgorithmName, + T::BlockSize: IsLess, + Le: NonZero, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { T::write_alg_name(f)?; @@ -98,6 +150,8 @@ where impl std::io::Write for RtVariableCoreWrapper where T: VariableOutputCore + UpdateCore, + T::BlockSize: IsLess, + Le: NonZero, { #[inline] fn write(&mut self, buf: &[u8]) -> std::io::Result { diff --git a/digest/src/core_api/wrapper.rs b/digest/src/core_api/wrapper.rs new file mode 100644 index 000000000..f600642c2 --- /dev/null +++ b/digest/src/core_api/wrapper.rs @@ -0,0 +1,275 @@ +use super::{ + AlgorithmName, Buffer, BufferKindUser, ExtendableOutputCore, FixedOutputCore, OutputSizeUser, + Reset, UpdateCore, XofReaderCoreWrapper, +}; +use crate::{ + ExtendableOutput, ExtendableOutputReset, FixedOutput, FixedOutputReset, HashMarker, Update, +}; +use block_buffer::BlockBuffer; +use core::fmt; +use crypto_common::{BlockSizeUser, InvalidLength, Key, KeyInit, KeySizeUser, Output}; +use generic_array::typenum::{IsLess, Le, NonZero, U256}; + +#[cfg(feature = "mac")] +use crate::MacMarker; + +/// Wrapper around [`BufferKindUser`]. +/// +/// It handles data buffering and implements the slice-based traits. +#[derive(Clone, Default)] +pub struct CoreWrapper +where + T: BufferKindUser, + T::BlockSize: IsLess, + Le: NonZero, +{ + core: T, + buffer: BlockBuffer, +} + +impl HashMarker for CoreWrapper +where + T: BufferKindUser + HashMarker, + T::BlockSize: IsLess, + Le: NonZero, +{ +} + +#[cfg(feature = "mac")] +#[cfg_attr(docsrs, doc(cfg(feature = "mac")))] +impl MacMarker for CoreWrapper +where + T: BufferKindUser + MacMarker, + T::BlockSize: IsLess, + Le: NonZero, +{ +} + +// this blanket impl is needed for HMAC +impl BlockSizeUser for CoreWrapper +where + T: BufferKindUser + HashMarker, + T::BlockSize: IsLess, + Le: NonZero, +{ + type BlockSize = T::BlockSize; +} + +impl CoreWrapper +where + T: BufferKindUser, + T::BlockSize: IsLess, + Le: NonZero, +{ + /// Create new wrapper from `core`. + #[inline] + pub fn from_core(core: T) -> Self { + let buffer = Default::default(); + Self { core, buffer } + } + + /// Decompose wrapper into inner parts. + #[inline] + pub fn decompose(self) -> (T, Buffer) { + let Self { core, buffer } = self; + (core, buffer) + } +} + +impl KeySizeUser for CoreWrapper +where + T: BufferKindUser + KeySizeUser, + T::BlockSize: IsLess, + Le: NonZero, +{ + type KeySize = T::KeySize; +} + +impl KeyInit for CoreWrapper +where + T: BufferKindUser + KeyInit, + T::BlockSize: IsLess, + Le: NonZero, +{ + #[inline] + fn new(key: &Key) -> Self { + Self { + core: T::new(key), + buffer: Default::default(), + } + } + + #[inline] + fn new_from_slice(key: &[u8]) -> Result { + Ok(Self { + core: T::new_from_slice(key)?, + buffer: Default::default(), + }) + } +} + +impl fmt::Debug for CoreWrapper +where + T: BufferKindUser + AlgorithmName, + T::BlockSize: IsLess, + Le: NonZero, +{ + #[inline] + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + T::write_alg_name(f)?; + f.write_str(" { .. }") + } +} + +impl Reset for CoreWrapper +where + T: BufferKindUser + Reset, + T::BlockSize: IsLess, + Le: NonZero, +{ + #[inline] + fn reset(&mut self) { + self.core.reset(); + self.buffer.reset(); + } +} + +impl Update for CoreWrapper +where + T: BufferKindUser + UpdateCore, + T::BlockSize: IsLess, + Le: NonZero, +{ + #[inline] + fn update(&mut self, input: &[u8]) { + let Self { core, buffer } = self; + buffer.digest_blocks(input, |blocks| core.update_blocks(blocks)); + } +} + +impl OutputSizeUser for CoreWrapper +where + T: BufferKindUser + OutputSizeUser, + T::BlockSize: IsLess, + Le: NonZero, +{ + type OutputSize = T::OutputSize; +} + +impl FixedOutput for CoreWrapper +where + T: FixedOutputCore, + T::BlockSize: IsLess, + Le: NonZero, +{ + #[inline] + fn finalize_into(mut self, out: &mut Output) { + let Self { core, buffer } = &mut self; + core.finalize_fixed_core(buffer, out); + } +} + +impl FixedOutputReset for CoreWrapper +where + T: FixedOutputCore + Reset, + T::BlockSize: IsLess, + Le: NonZero, +{ + #[inline] + fn finalize_into_reset(&mut self, out: &mut Output) { + let Self { core, buffer } = self; + core.finalize_fixed_core(buffer, out); + core.reset(); + buffer.reset(); + } +} + +impl ExtendableOutput for CoreWrapper +where + T: ExtendableOutputCore, + T::BlockSize: IsLess, + Le: NonZero, + ::BlockSize: IsLess, + Le<::BlockSize, U256>: NonZero, +{ + type Reader = XofReaderCoreWrapper; + + #[inline] + fn finalize_xof(self) -> Self::Reader { + let (mut core, mut buffer) = self.decompose(); + let core = core.finalize_xof_core(&mut buffer); + let buffer = Default::default(); + Self::Reader { core, buffer } + } +} + +impl ExtendableOutputReset for CoreWrapper +where + T: ExtendableOutputCore + Reset, + T::BlockSize: IsLess, + Le: NonZero, + ::BlockSize: IsLess, + Le<::BlockSize, U256>: NonZero, +{ + #[inline] + fn finalize_xof_reset(&mut self) -> Self::Reader { + let Self { core, buffer } = self; + let reader_core = core.finalize_xof_core(buffer); + core.reset(); + buffer.reset(); + let buffer = Default::default(); + Self::Reader { + core: reader_core, + buffer, + } + } +} + +#[cfg(feature = "std")] +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] +impl std::io::Write for CoreWrapper +where + T: BufferKindUser + UpdateCore, + T::BlockSize: IsLess, + Le: NonZero, +{ + #[inline] + fn write(&mut self, buf: &[u8]) -> std::io::Result { + Update::update(self, buf); + Ok(buf.len()) + } + + #[inline] + fn flush(&mut self) -> std::io::Result<()> { + Ok(()) + } +} + +/// A proxy trait to a core type implemented by [`CoreWrapper`] +// TODO: replace with an inherent associated type on stabilization: +// https://github.com/rust-lang/rust/issues/8995 +pub trait CoreProxy: sealed::Sealed { + /// Type wrapped by [`CoreWrapper`]. + type Core; +} + +mod sealed { + pub trait Sealed {} +} + +impl sealed::Sealed for CoreWrapper +where + T: BufferKindUser, + T::BlockSize: IsLess, + Le: NonZero, +{ +} + +impl CoreProxy for CoreWrapper +where + T: BufferKindUser, + T::BlockSize: IsLess, + Le: NonZero, +{ + type Core = T; +} diff --git a/digest/src/core_api/xof_reader.rs b/digest/src/core_api/xof_reader.rs index 5d7b83520..5b41479b0 100644 --- a/digest/src/core_api/xof_reader.rs +++ b/digest/src/core_api/xof_reader.rs @@ -1,35 +1,60 @@ use super::{AlgorithmName, XofReaderCore}; use crate::XofReader; +use block_buffer::EagerBuffer; use core::fmt; -use crypto_common::block_buffer::BlockBuffer; +use generic_array::typenum::{IsLess, Le, NonZero, U256}; /// Wrapper around [`XofReaderCore`] implementations. /// /// It handles data buffering and implements the mid-level traits. #[derive(Clone, Default)] -pub struct XofReaderCoreWrapper { +pub struct XofReaderCoreWrapper +where + T: XofReaderCore, + T::BlockSize: IsLess, + Le: NonZero, +{ pub(super) core: T, - pub(super) buffer: BlockBuffer, + pub(super) buffer: EagerBuffer, } -impl fmt::Debug for XofReaderCoreWrapper { +impl fmt::Debug for XofReaderCoreWrapper +where + T: XofReaderCore + AlgorithmName, + T::BlockSize: IsLess, + Le: NonZero, +{ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { T::write_alg_name(f)?; f.write_str(" { .. }") } } -impl XofReader for XofReaderCoreWrapper { +impl XofReader for XofReaderCoreWrapper +where + T: XofReaderCore, + T::BlockSize: IsLess, + Le: NonZero, +{ #[inline] fn read(&mut self, buffer: &mut [u8]) { let Self { core, buffer: buf } = self; - buf.set_data(buffer, || core.read_block()); + buf.set_data(buffer, |blocks| { + for block in blocks { + *block = core.read_block(); + } + }); } } #[cfg(feature = "std")] #[cfg_attr(docsrs, doc(cfg(feature = "std")))] -impl std::io::Read for XofReaderCoreWrapper { +impl std::io::Read for XofReaderCoreWrapper +where + T: XofReaderCore, + T::BlockSize: IsLess, + Le: NonZero, +{ #[inline] fn read(&mut self, buf: &mut [u8]) -> std::io::Result { XofReader::read(self, buf); diff --git a/digest/src/dev.rs b/digest/src/dev.rs index 926ebbd53..2b68bdd4d 100644 --- a/digest/src/dev.rs +++ b/digest/src/dev.rs @@ -2,14 +2,22 @@ pub use blobby; -use super::{ExtendableOutput, Reset, Update, VariableOutput, XofReader}; -use core::fmt::Debug; - -/// Define test +mod fixed; +mod mac; +mod rng; +mod variable; +mod xof; + +pub use fixed::*; +pub use mac::*; +pub use variable::*; +pub use xof::*; + +/// Define hash function test #[macro_export] #[cfg_attr(docsrs, doc(cfg(feature = "dev")))] macro_rules! new_test { - ($name:ident, $test_name:expr, $hasher:ty, $test_func:ident) => { + ($name:ident, $test_name:expr, $hasher:ty, $test_func:ident $(,)?) => { #[test] fn $name() { use digest::dev::blobby::Blob2Iterator; @@ -31,216 +39,40 @@ macro_rules! new_test { }; } -/// Module to separate Digest from other traits -mod foo { - use super::super::{Digest, Reset}; - use core::fmt::Debug; - - /// Digest test - pub fn digest_test(input: &[u8], output: &[u8]) -> Option<&'static str> - where - D: Digest + Reset + Debug + Clone, - { - let mut hasher = D::new(); - // Test that it works when accepting the message all at once - hasher.update(input); - let mut hasher2 = hasher.clone(); - if hasher.finalize().as_slice() != output { - return Some("whole message"); - } - - // Test if reset works correctly - hasher2.reset(); - hasher2.update(input); - if hasher2.finalize().as_slice() != output { - return Some("whole message after reset"); - } - - // Test that it works when accepting the message in pieces - let mut hasher = D::new(); - let len = input.len(); - let mut left = len; - while left > 0 { - let take = (left + 1) / 2; - hasher.update(&input[len - left..take + len - left]); - left -= take; - } - if hasher.finalize().as_slice() != output { - return Some("message in pieces"); - } - - // Test processing byte-by-byte - let mut hasher = D::new(); - for chunk in input.chunks(1) { - hasher.update(chunk) - } - if hasher.finalize().as_slice() != output { - return Some("message byte-by-byte"); - } - None - } - - /// Compute digest of one million `a` bytes - pub fn one_million_a(expected: &[u8]) - where - D: Digest + Debug + Clone, - { - let mut sh = D::new(); - for _ in 0..50_000 { - sh.update(&[b'a'; 10]); - } - sh.update(&[b'a'; 500_000][..]); - let out = sh.finalize(); - assert_eq!(out[..], expected[..]); - } -} - -pub use self::foo::{digest_test, one_million_a}; - -/// XOF test -pub fn xof_test(input: &[u8], output: &[u8]) -> Option<&'static str> -where - D: Update + ExtendableOutput + Default + Debug + Reset + Clone, -{ - let mut hasher = D::default(); - let mut buf = [0u8; 1024]; - // Test that it works when accepting the message all at once - hasher.update(input); - - let mut hasher2 = hasher.clone(); - { - let out = &mut buf[..output.len()]; - hasher.finalize_xof().read(out); - - if out != output { - return Some("whole message"); - } - } - - // Test if hasher resets correctly - hasher2.reset(); - hasher2.update(input); - - { - let out = &mut buf[..output.len()]; - hasher2.finalize_xof().read(out); - - if out != output { - return Some("whole message after reset"); - } - } - - // Test if hasher accepts message in pieces correctly - let mut hasher = D::default(); - let len = input.len(); - let mut left = len; - while left > 0 { - let take = (left + 1) / 2; - hasher.update(&input[len - left..take + len - left]); - left -= take; - } - - { - let out = &mut buf[..output.len()]; - hasher.finalize_xof().read(out); - if out != output { - return Some("message in pieces"); - } - } - - // Test reading from reader byte by byte - let mut hasher = D::default(); - hasher.update(input); - - let mut reader = hasher.finalize_xof(); - let out = &mut buf[..output.len()]; - for chunk in out.chunks_mut(1) { - reader.read(chunk); - } - - if out != output { - return Some("message in pieces"); - } - None -} - -/// Variable-output digest test -pub fn variable_test(input: &[u8], output: &[u8]) -> Option<&'static str> -where - D: Update + VariableOutput + Reset + Debug + Clone, -{ - let mut hasher = D::new(output.len()).unwrap(); - let mut buf = [0u8; 128]; - let buf = &mut buf[..output.len()]; - // Test that it works when accepting the message all at once - hasher.update(input); - let mut hasher2 = hasher.clone(); - hasher.finalize_variable(|res| buf.copy_from_slice(res)); - if buf != output { - return Some("whole message"); - } - - // Test if reset works correctly - hasher2.reset(); - hasher2.update(input); - hasher2.finalize_variable(|res| buf.copy_from_slice(res)); - if buf != output { - return Some("whole message after reset"); - } - - // Test that it works when accepting the message in pieces - let mut hasher = D::new(output.len()).unwrap(); - let len = input.len(); - let mut left = len; - while left > 0 { - let take = (left + 1) / 2; - hasher.update(&input[len - left..take + len - left]); - left -= take; - } - hasher.finalize_variable(|res| buf.copy_from_slice(res)); - if buf != output { - return Some("message in pieces"); - } - - // Test processing byte-by-byte - let mut hasher = D::new(output.len()).unwrap(); - for chunk in input.chunks(1) { - hasher.update(chunk) - } - hasher.finalize_variable(|res| buf.copy_from_slice(res)); - if buf != output { - return Some("message byte-by-byte"); - } - None -} - -/// Define benchmark +/// Define [`Update`][crate::Update] impl benchmark #[macro_export] #[cfg_attr(docsrs, doc(cfg(feature = "dev")))] -macro_rules! bench { - ($name:ident, $engine:path, $bs:expr) => { - #[bench] - fn $name(b: &mut Bencher) { - let mut d = <$engine>::default(); - let data = [0; $bs]; - - b.iter(|| { - d.update(&data[..]); - }); - - b.bytes = $bs; - } +macro_rules! bench_update { + ( + $init:expr; + $($name:ident $bs:expr;)* + ) => { + $( + #[bench] + fn $name(b: &mut Bencher) { + let mut d = $init; + let data = [0; $bs]; + + b.iter(|| { + digest::Update::update(&mut d, &data[..]); + }); + + b.bytes = $bs; + } + )* }; +} - ($engine:path) => { - extern crate test; - - use digest::Digest; - use test::Bencher; - - $crate::bench!(bench1_10, $engine, 10); - $crate::bench!(bench2_100, $engine, 100); - $crate::bench!(bench3_1000, $engine, 1000); - $crate::bench!(bench4_10000, $engine, 10000); - }; +/// Feed ~1 MiB of pseudorandom data to an updatable state. +pub fn feed_rand_16mib(d: &mut D) { + let buf = &mut [0u8; 1024]; + let mut rng = rng::RNG; + let n = 16 * (1 << 20) / buf.len(); + for _ in 0..n { + rng.fill(buf); + d.update(buf); + // additional byte, so size of feeded data + // will not be multiple of block size + d.update(&[42]); + } } diff --git a/digest/src/dev/fixed.rs b/digest/src/dev/fixed.rs new file mode 100644 index 000000000..24f380112 --- /dev/null +++ b/digest/src/dev/fixed.rs @@ -0,0 +1,65 @@ +use crate::{Digest, FixedOutput, FixedOutputReset, HashMarker, Update}; +use core::fmt::Debug; + +/// Fixed-output resettable digest test via the `Digest` trait +pub fn fixed_reset_test(input: &[u8], output: &[u8]) -> Option<&'static str> +where + D: FixedOutputReset + Debug + Clone + Default + Update + HashMarker, +{ + let mut hasher = D::new(); + // Test that it works when accepting the message all at once + hasher.update(input); + let mut hasher2 = hasher.clone(); + if hasher.finalize()[..] != output[..] { + return Some("whole message"); + } + + // Test if reset works correctly + hasher2.reset(); + hasher2.update(input); + if hasher2.finalize_reset()[..] != output[..] { + return Some("whole message after reset"); + } + + // Test that it works when accepting the message in chunks + for n in 1..core::cmp::min(17, input.len()) { + let mut hasher = D::new(); + for chunk in input.chunks(n) { + hasher.update(chunk); + hasher2.update(chunk); + } + if hasher.finalize()[..] != output[..] { + return Some("message in chunks"); + } + if hasher2.finalize_reset()[..] != output[..] { + return Some("message in chunks"); + } + } + + None +} + +/// Variable-output resettable digest test +pub fn fixed_test(input: &[u8], output: &[u8]) -> Option<&'static str> +where + D: FixedOutput + Default + Debug + Clone, +{ + let mut hasher = D::default(); + // Test that it works when accepting the message all at once + hasher.update(input); + if hasher.finalize_fixed()[..] != output[..] { + return Some("whole message"); + } + + // Test that it works when accepting the message in chunks + for n in 1..core::cmp::min(17, input.len()) { + let mut hasher = D::default(); + for chunk in input.chunks(n) { + hasher.update(chunk); + } + if hasher.finalize_fixed()[..] != output[..] { + return Some("message in chunks"); + } + } + None +} diff --git a/digest/src/dev/mac.rs b/digest/src/dev/mac.rs new file mode 100644 index 000000000..0d4a37dfc --- /dev/null +++ b/digest/src/dev/mac.rs @@ -0,0 +1,159 @@ +/// Define MAC test +#[macro_export] +#[cfg(feature = "mac")] +#[cfg_attr(docsrs, doc(cfg(all(feature = "dev", feature = "mac"))))] +macro_rules! new_mac_test { + ($name:ident, $test_name:expr, $mac:ty $(,)?) => { + digest::new_mac_test!($name, $test_name, $mac, ""); + }; + ($name:ident, $test_name:expr, $mac:ty, trunc_left $(,)?) => { + digest::new_mac_test!($name, $test_name, $mac, "left"); + }; + ($name:ident, $test_name:expr, $mac:ty, trunc_right $(,)?) => { + digest::new_mac_test!($name, $test_name, $mac, "right"); + }; + ($name:ident, $test_name:expr, $mac:ty, $trunc:expr $(,)?) => { + #[test] + fn $name() { + use core::cmp::min; + use digest::dev::blobby::Blob3Iterator; + use digest::Mac; + + fn run_test(key: &[u8], input: &[u8], tag: &[u8]) -> Option<&'static str> { + let mac0 = <$mac as Mac>::new_from_slice(key).unwrap(); + + let mut mac = mac0.clone(); + mac.update(input); + let result = mac.finalize().into_bytes(); + let n = tag.len(); + let result_bytes = match $trunc { + "left" => &result[..n], + "right" => &result[result.len() - n..], + _ => &result[..], + }; + if result_bytes != tag { + return Some("whole message"); + } + + // test reading different chunk sizes + for chunk_size in 1..min(64, input.len()) { + let mut mac = mac0.clone(); + for chunk in input.chunks(chunk_size) { + mac.update(chunk); + } + let res = match $trunc { + "left" => mac.verify_truncated_left(tag), + "right" => mac.verify_truncated_right(tag), + _ => mac.verify_slice(tag), + }; + if res.is_err() { + return Some("chunked message"); + } + } + + None + } + + let data = include_bytes!(concat!("data/", $test_name, ".blb")); + + for (i, row) in Blob3Iterator::new(data).unwrap().enumerate() { + let [key, input, tag] = row.unwrap(); + if let Some(desc) = run_test(key, input, tag) { + panic!( + "\n\ + Failed test №{}: {}\n\ + key:\t{:?}\n\ + input:\t{:?}\n\ + tag:\t{:?}\n", + i, desc, key, input, tag, + ); + } + } + } + }; +} + +/// Define resettable MAC test +#[macro_export] +#[cfg(feature = "mac")] +#[cfg_attr(docsrs, doc(cfg(all(feature = "dev", feature = "mac"))))] +macro_rules! new_resettable_mac_test { + ($name:ident, $test_name:expr, $mac:ty $(,)?) => { + digest::new_resettable_mac_test!($name, $test_name, $mac, ""); + }; + ($name:ident, $test_name:expr, $mac:ty, trunc_left $(,)?) => { + digest::new_resettable_mac_test!($name, $test_name, $mac, "left"); + }; + ($name:ident, $test_name:expr, $mac:ty, trunc_right $(,)?) => { + digest::new_resettable_mac_test!($name, $test_name, $mac, "right"); + }; + ($name:ident, $test_name:expr, $mac:ty, $trunc:expr $(,)?) => { + #[test] + fn $name() { + use core::cmp::min; + use digest::dev::blobby::Blob3Iterator; + use digest::Mac; + + fn run_test(key: &[u8], input: &[u8], tag: &[u8]) -> Option<&'static str> { + let mac0 = <$mac as Mac>::new_from_slice(key).unwrap(); + + let mut mac = mac0.clone(); + mac.update(input); + let result = mac.finalize_reset().into_bytes(); + let n = tag.len(); + let result_bytes = match $trunc { + "left" => &result[..n], + "right" => &result[result.len() - n..], + _ => &result[..], + }; + if result_bytes != tag { + return Some("whole message"); + } + + // test if reset worked correctly + mac.update(input); + let res = match $trunc { + "left" => mac.verify_truncated_left(tag), + "right" => mac.verify_truncated_right(tag), + _ => mac.verify_slice(tag), + }; + if res.is_err() { + return Some("after reset"); + } + + // test reading different chunk sizes + for chunk_size in 1..min(64, input.len()) { + let mut mac = mac0.clone(); + for chunk in input.chunks(chunk_size) { + mac.update(chunk); + } + let res = match $trunc { + "left" => mac.verify_truncated_left(tag), + "right" => mac.verify_truncated_right(tag), + _ => mac.verify_slice(tag), + }; + if res.is_err() { + return Some("chunked message"); + } + } + None + } + + let data = include_bytes!(concat!("data/", $test_name, ".blb")); + + for (i, row) in Blob3Iterator::new(data).unwrap().enumerate() { + let [key, input, tag] = row.unwrap(); + if let Some(desc) = run_test(key, input, tag) { + panic!( + "\n\ + Failed test №{}: {}\n\ + key:\t{:?}\n\ + input:\t{:?}\n\ + tag:\t{:?}\n", + i, desc, key, input, tag, + ); + } + } + } + }; +} diff --git a/digest/src/dev/rng.rs b/digest/src/dev/rng.rs new file mode 100644 index 000000000..8b233aafb --- /dev/null +++ b/digest/src/dev/rng.rs @@ -0,0 +1,38 @@ +//! Xorshift RNG used for tests. Based on the `rand_xorshift` crate. +use core::num::Wrapping; + +/// Initial RNG state used in tests. +// choosen by fair dice roll. guaranteed to be random. +pub(crate) const RNG: XorShiftRng = XorShiftRng { + x: Wrapping(0x0787_3B4A), + y: Wrapping(0xFAAB_8FFE), + z: Wrapping(0x1745_980F), + w: Wrapping(0xB0AD_B4F3), +}; + +/// Xorshift RNG instance/ +pub(crate) struct XorShiftRng { + x: Wrapping, + y: Wrapping, + z: Wrapping, + w: Wrapping, +} + +impl XorShiftRng { + pub(crate) fn fill(&mut self, buf: &mut [u8; 1024]) { + for chunk in buf.chunks_exact_mut(4) { + chunk.copy_from_slice(&self.next_u32().to_le_bytes()); + } + } + + fn next_u32(&mut self) -> u32 { + let x = self.x; + let t = x ^ (x << 11); + self.x = self.y; + self.y = self.z; + self.z = self.w; + let w = self.w; + self.w = w ^ (w >> 19) ^ (t ^ (t >> 8)); + self.w.0 + } +} diff --git a/digest/src/dev/variable.rs b/digest/src/dev/variable.rs new file mode 100644 index 000000000..ed8ff8828 --- /dev/null +++ b/digest/src/dev/variable.rs @@ -0,0 +1,82 @@ +use crate::{VariableOutput, VariableOutputReset}; +use core::fmt::Debug; + +/// Variable-output resettable digest test +pub fn variable_reset_test(input: &[u8], output: &[u8]) -> Option<&'static str> +where + D: VariableOutputReset + Debug + Clone, +{ + let mut hasher = D::new(output.len()).unwrap(); + let mut buf = [0u8; 128]; + let buf = &mut buf[..output.len()]; + // Test that it works when accepting the message all at once + hasher.update(input); + let mut hasher2 = hasher.clone(); + hasher.finalize_variable(buf).unwrap(); + if buf != output { + return Some("whole message"); + } + buf.iter_mut().for_each(|b| *b = 0); + + // Test if reset works correctly + hasher2.reset(); + hasher2.update(input); + hasher2.finalize_variable_reset(buf).unwrap(); + if buf != output { + return Some("whole message after reset"); + } + buf.iter_mut().for_each(|b| *b = 0); + + // Test that it works when accepting the message in chunks + for n in 1..core::cmp::min(17, input.len()) { + let mut hasher = D::new(output.len()).unwrap(); + for chunk in input.chunks(n) { + hasher.update(chunk); + hasher2.update(chunk); + } + hasher.finalize_variable(buf).unwrap(); + if buf != output { + return Some("message in chunks"); + } + buf.iter_mut().for_each(|b| *b = 0); + + hasher2.finalize_variable_reset(buf).unwrap(); + if buf != output { + return Some("message in chunks"); + } + buf.iter_mut().for_each(|b| *b = 0); + } + + None +} + +/// Variable-output resettable digest test +pub fn variable_test(input: &[u8], output: &[u8]) -> Option<&'static str> +where + D: VariableOutput + Debug + Clone, +{ + let mut hasher = D::new(output.len()).unwrap(); + let mut buf = [0u8; 128]; + let buf = &mut buf[..output.len()]; + // Test that it works when accepting the message all at once + hasher.update(input); + hasher.finalize_variable(buf).unwrap(); + if buf != output { + return Some("whole message"); + } + buf.iter_mut().for_each(|b| *b = 0); + + // Test that it works when accepting the message in chunks + for n in 1..core::cmp::min(17, input.len()) { + let mut hasher = D::new(output.len()).unwrap(); + for chunk in input.chunks(n) { + hasher.update(chunk); + } + hasher.finalize_variable(buf).unwrap(); + if buf != output { + return Some("message in chunks"); + } + buf.iter_mut().for_each(|b| *b = 0); + } + None +} diff --git a/digest/src/dev/xof.rs b/digest/src/dev/xof.rs new file mode 100644 index 000000000..9e5d07a09 --- /dev/null +++ b/digest/src/dev/xof.rs @@ -0,0 +1,51 @@ +use crate::ExtendableOutputReset; +use core::fmt::Debug; + +/// Resettable XOF test +pub fn xof_reset_test(input: &[u8], output: &[u8]) -> Option<&'static str> +where + D: ExtendableOutputReset + Default + Debug + Clone, +{ + let mut hasher = D::default(); + let mut buf = [0u8; 1024]; + let buf = &mut buf[..output.len()]; + // Test that it works when accepting the message all at once + hasher.update(input); + let mut hasher2 = hasher.clone(); + hasher.finalize_xof_into(buf); + if buf != output { + return Some("whole message"); + } + buf.iter_mut().for_each(|b| *b = 0); + + // Test if reset works correctly + hasher2.reset(); + hasher2.update(input); + hasher2.finalize_xof_reset_into(buf); + if buf != output { + return Some("whole message after reset"); + } + buf.iter_mut().for_each(|b| *b = 0); + + // Test that it works when accepting the message in chunks + for n in 1..core::cmp::min(17, input.len()) { + let mut hasher = D::default(); + for chunk in input.chunks(n) { + hasher.update(chunk); + hasher2.update(chunk); + } + hasher.finalize_xof_into(buf); + if buf != output { + return Some("message in chunks"); + } + buf.iter_mut().for_each(|b| *b = 0); + + hasher2.finalize_xof_reset_into(buf); + if buf != output { + return Some("message in chunks"); + } + buf.iter_mut().for_each(|b| *b = 0); + } + + None +} diff --git a/digest/src/digest.rs b/digest/src/digest.rs index 7c277c9a6..0e974b329 100644 --- a/digest/src/digest.rs +++ b/digest/src/digest.rs @@ -1,17 +1,19 @@ -use super::{FixedOutput, FixedOutputReset, Update}; +use super::{FixedOutput, FixedOutputReset, InvalidBufferSize, Reset, Update}; +use crypto_common::{Output, OutputSizeUser}; use generic_array::typenum::Unsigned; -use generic_array::{ArrayLength, GenericArray}; -/// The `Digest` trait specifies an interface common for digest functions. -/// -/// It's a convenience wrapper around [`Update`], [`FixedOutput`], -/// [`Reset`][`crate::Reset`], [`Clone`], and [`Default`] traits. -/// -/// It also provides additional convenience methods. -pub trait Digest { - /// Output size for `Digest` - type OutputSize: ArrayLength; +#[cfg(feature = "alloc")] +use alloc::boxed::Box; + +/// Marker trait for cryptographic hash functions. +pub trait HashMarker {} +/// Convinience wrapper trait covering functionality of cryptographic hash +/// functions with fixed output size. +/// +/// This trait wraps [`Update`], [`FixedOutput`], [`Default`], and +/// [`HashMarker`] traits and provides additional convenience methods. +pub trait Digest: OutputSizeUser { /// Create new hasher instance fn new() -> Self; @@ -37,6 +39,11 @@ pub trait Digest { where Self: FixedOutputReset; + /// Reset hasher instance to its initial state. + fn reset(&mut self) + where + Self: Reset; + /// Get output size of the hasher fn output_size() -> usize; @@ -44,9 +51,7 @@ pub trait Digest { fn digest(data: impl AsRef<[u8]>) -> Output; } -impl Digest for D { - type OutputSize = ::OutputSize; - +impl Digest for D { #[inline] fn new() -> Self { Self::default() @@ -89,6 +94,14 @@ impl Digest for D { FixedOutputReset::finalize_into_reset(self, out); } + #[inline] + fn reset(&mut self) + where + Self: Reset, + { + Reset::reset(self) + } + #[inline] fn output_size() -> usize { Self::OutputSize::to_usize() @@ -102,5 +115,109 @@ impl Digest for D { } } -/// Fixed of fixed-sized hash-function used by [`Digest`] methods. -pub type Output = GenericArray::OutputSize>; +/// Modification of the [`Digest`] trait suitable for trait objects. +pub trait DynDigest { + /// Digest input data. + /// + /// This method can be called repeatedly for use with streaming messages. + fn update(&mut self, data: &[u8]); + + /// Retrieve result and reset hasher instance + #[cfg(feature = "alloc")] + #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] + fn finalize_reset(&mut self) -> Box<[u8]> { + let mut result = vec![0; self.output_size()]; + self.finalize_into_reset(&mut result).unwrap(); + result.into_boxed_slice() + } + + /// Retrieve result and consume boxed hasher instance + #[cfg(feature = "alloc")] + #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] + #[allow(clippy::boxed_local)] + fn finalize(mut self: Box) -> Box<[u8]> { + let mut result = vec![0; self.output_size()]; + self.finalize_into_reset(&mut result).unwrap(); + result.into_boxed_slice() + } + + /// Write result into provided array and consume the hasher instance. + /// + /// Returns error if buffer length is not equal to `output_size`. + fn finalize_into(self, buf: &mut [u8]) -> Result<(), InvalidBufferSize>; + + /// Write result into provided array and reset the hasher instance. + /// + /// Returns error if buffer length is not equal to `output_size`. + fn finalize_into_reset(&mut self, out: &mut [u8]) -> Result<(), InvalidBufferSize>; + + /// Reset hasher instance to its initial state. + fn reset(&mut self); + + /// Get output size of the hasher + fn output_size(&self) -> usize; + + /// Clone hasher state into a boxed trait object + #[cfg(feature = "alloc")] + #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] + fn box_clone(&self) -> Box; +} + +impl DynDigest for D { + fn update(&mut self, data: &[u8]) { + Update::update(self, data); + } + + #[cfg(feature = "alloc")] + fn finalize_reset(&mut self) -> Box<[u8]> { + FixedOutputReset::finalize_fixed_reset(self) + .to_vec() + .into_boxed_slice() + } + + #[cfg(feature = "alloc")] + fn finalize(self: Box) -> Box<[u8]> { + FixedOutput::finalize_fixed(*self) + .to_vec() + .into_boxed_slice() + } + + fn finalize_into(self, buf: &mut [u8]) -> Result<(), InvalidBufferSize> { + if buf.len() == self.output_size() { + FixedOutput::finalize_into(self, Output::::from_mut_slice(buf)); + Ok(()) + } else { + Err(InvalidBufferSize) + } + } + + fn finalize_into_reset(&mut self, buf: &mut [u8]) -> Result<(), InvalidBufferSize> { + if buf.len() == self.output_size() { + FixedOutputReset::finalize_into_reset(self, Output::::from_mut_slice(buf)); + Ok(()) + } else { + Err(InvalidBufferSize) + } + } + + fn reset(&mut self) { + Reset::reset(self); + } + + fn output_size(&self) -> usize { + ::OutputSize::to_usize() + } + + #[cfg(feature = "alloc")] + fn box_clone(&self) -> Box { + Box::new(self.clone()) + } +} + +#[cfg(feature = "alloc")] +#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] +impl Clone for Box { + fn clone(&self) -> Self { + self.box_clone() + } +} diff --git a/digest/src/dyn_digest.rs b/digest/src/dyn_digest.rs deleted file mode 100644 index ecafe7945..000000000 --- a/digest/src/dyn_digest.rs +++ /dev/null @@ -1,124 +0,0 @@ -use super::{FixedOutput, FixedOutputReset, Reset, Update}; -use core::fmt; -use generic_array::{typenum::Unsigned, GenericArray}; - -#[cfg(feature = "alloc")] -use alloc::boxed::Box; - -/// The `DynDigest` trait is a modification of `Digest` trait suitable -/// for trait objects. -pub trait DynDigest { - /// Digest input data. - /// - /// This method can be called repeatedly for use with streaming messages. - fn update(&mut self, data: &[u8]); - - /// Retrieve result and reset hasher instance - #[cfg(feature = "alloc")] - #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] - fn finalize_reset(&mut self) -> Box<[u8]> { - let mut result = vec![0; self.output_size()]; - self.finalize_into_reset(&mut result).unwrap(); - result.into_boxed_slice() - } - - /// Retrieve result and consume boxed hasher instance - #[cfg(feature = "alloc")] - #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] - #[allow(clippy::boxed_local)] - fn finalize(mut self: Box) -> Box<[u8]> { - let mut result = vec![0; self.output_size()]; - self.finalize_into_reset(&mut result).unwrap(); - result.into_boxed_slice() - } - - /// Write result into provided array and consume the hasher instance. - /// - /// Returns error if buffer length is not equal to `output_size`. - fn finalize_into(self, buf: &mut [u8]) -> Result<(), InvalidBufferLength>; - - /// Write result into provided array and reset the hasher instance. - /// - /// Returns error if buffer length is not equal to `output_size`. - fn finalize_into_reset(&mut self, out: &mut [u8]) -> Result<(), InvalidBufferLength>; - - /// Reset hasher instance to its initial state. - fn reset(&mut self); - - /// Get output size of the hasher - fn output_size(&self) -> usize; - - /// Clone hasher state into a boxed trait object - #[cfg(feature = "alloc")] - #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] - fn box_clone(&self) -> Box; -} - -impl DynDigest for D { - fn update(&mut self, data: &[u8]) { - Update::update(self, data); - } - - #[cfg(feature = "alloc")] - fn finalize_reset(&mut self) -> Box<[u8]> { - self.finalize_fixed_reset().to_vec().into_boxed_slice() - } - - #[cfg(feature = "alloc")] - fn finalize(self: Box) -> Box<[u8]> { - self.finalize_fixed().to_vec().into_boxed_slice() - } - - fn finalize_into(self, buf: &mut [u8]) -> Result<(), InvalidBufferLength> { - if buf.len() == self.output_size() { - self.finalize_into(GenericArray::from_mut_slice(buf)); - Ok(()) - } else { - Err(InvalidBufferLength) - } - } - - fn finalize_into_reset(&mut self, buf: &mut [u8]) -> Result<(), InvalidBufferLength> { - if buf.len() == self.output_size() { - self.finalize_into_reset(GenericArray::from_mut_slice(buf)); - Ok(()) - } else { - Err(InvalidBufferLength) - } - } - - fn reset(&mut self) { - Reset::reset(self); - } - - fn output_size(&self) -> usize { - ::OutputSize::to_usize() - } - - #[cfg(feature = "alloc")] - fn box_clone(&self) -> Box { - Box::new(self.clone()) - } -} - -#[cfg(feature = "alloc")] -#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] -impl Clone for Box { - fn clone(&self) -> Self { - self.box_clone() - } -} - -/// Buffer length is not equal to the hash output size. -#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] -#[derive(Default, Debug, Copy, Clone, Eq, PartialEq)] -pub struct InvalidBufferLength; - -impl fmt::Display for InvalidBufferLength { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str("invalid buffer length") - } -} - -#[cfg(feature = "std")] -impl std::error::Error for InvalidBufferLength {} diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 2991ded68..3938c54c8 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -1,27 +1,27 @@ //! This crate provides traits which describe functionality of cryptographic hash -//! functions. +//! functions and Message Authentication algorithms. //! -//! Traits in this repository are organized into high-level convenience traits, -//! mid-level traits which expose more fine-grained functionality, and -//! low-level traits intended to only be used by algorithm implementations: +//! Traits in this repository are organized into the following levels: //! -//! - **High-level convenience traits**: [`Digest`], [`DynDigest`]. They are wrappers -//! around lower-level traits for most common hash-function use-cases. -//! - **Mid-level traits**: [`Update`], [`FixedOutput`], [`ExtendableOutput`], [`Reset`]. -//! These traits atomically describe available functionality of hash function -//! implementations. +//! - **High-level convenience traits**: [`Digest`], [`DynDigest`], [`Mac`]. +//! Wrappers around lower-level traits for most common use-cases. Users should +//! usually prefer using these traits. +//! - **Mid-level traits**: [`Update`], [`FixedOutput`], [`FixedOutputReset`], +//! [`ExtendableOutput`], [`ExtendableOutputReset`], [`XofReader`], +//! [`VariableOutput`], [`VariableOutput`], [`Reset`], [`KeyInit`], and +//! [`InnerInit`]. These traits atomically describe available functionality +//! of an algorithm. +//! - **Marker traits**: [`HashMarker`], [`MacMarker`]. Used to distinguish +//! different algorithm classes. //! - **Low-level traits** defined in the [`core_api`] module. These traits //! operate at a block-level and do not contain any built-in buffering. -//! They are intended to be implemented by low-level algorithm providers only -//! and simplify the amount of work implementers need to do and therefore -//! usually shouldn't be used in application-level code. +//! They are intended to be implemented by low-level algorithm providers only. +//! Usually they should not be used in application-level code. //! //! Additionally hash functions implement traits from the standard library: //! [`Default`], [`Clone`], [`Write`][std::io::Write]. The latter is //! feature-gated behind `std` feature, which is usually enabled by default //! by hash implementation crates. -//! -//! The [`Digest`] trait is the most commonly used trait. #![no_std] #![cfg_attr(docsrs, feature(doc_cfg))] @@ -50,20 +50,60 @@ pub mod dev; #[cfg_attr(docsrs, doc(cfg(feature = "core-api")))] pub mod core_api; mod digest; -mod dyn_digest; +#[cfg(feature = "mac")] +mod mac; -pub use crate::digest::{Digest, Output}; -use core::fmt; #[cfg(feature = "core-api")] #[cfg_attr(docsrs, doc(cfg(feature = "core-api")))] -pub use crypto_common::block_buffer; -pub use dyn_digest::{DynDigest, InvalidBufferLength}; -pub use generic_array::{self, typenum::consts, GenericArray}; +pub use block_buffer; +pub use crypto_common; + +pub use crate::digest::{Digest, DynDigest, HashMarker}; +#[cfg(feature = "mac")] +pub use crypto_common::{InnerInit, InvalidLength, Key, KeyInit}; +pub use crypto_common::{Output, OutputSizeUser, Reset}; +pub use generic_array::{self, typenum::consts}; +#[cfg(feature = "mac")] +pub use mac::{CtOutput, Mac, MacError, MacMarker}; + +use core::fmt; + +/// Types which consume data with byte granularity. +pub trait Update { + /// Update state using the provided data. + fn update(&mut self, data: &[u8]); +} + +/// Trait for hash functions with fixed-size output. +pub trait FixedOutput: Update + OutputSizeUser + Sized { + /// Consume value and write result into provided array. + fn finalize_into(self, out: &mut Output); + + /// Retrieve result and consume the hasher instance. + #[inline] + fn finalize_fixed(self) -> Output { + let mut out = Default::default(); + self.finalize_into(&mut out); + out + } +} + +/// Trait for hash functions with fixed-size output able to reset themselves. +pub trait FixedOutputReset: FixedOutput + Reset { + /// Write result into provided array and reset the hasher state. + fn finalize_into_reset(&mut self, out: &mut Output); -pub use crypto_common::{FixedOutput, FixedOutputReset, Reset, Update}; + /// Retrieve result and reset the hasher state. + #[inline] + fn finalize_fixed_reset(&mut self) -> Output { + let mut out = Default::default(); + self.finalize_into_reset(&mut out); + out + } +} -/// Trait for describing readers which are used to extract extendable output -/// from XOF (extendable-output function) result. +/// Trait for reader types which are used to extract extendable output +/// from a XOF (extendable-output function) result. pub trait XofReader { /// Read output into the `buffer`. Can be called an unlimited number of times. fn read(&mut self, buffer: &mut [u8]); @@ -83,19 +123,24 @@ pub trait XofReader { } } -/// Trait which describes extendable-output functions (XOF). -pub trait ExtendableOutput: Sized + Update + Default + Reset { +/// Trait for hash functions with extendable-output (XOF). +pub trait ExtendableOutput: Sized + Update { /// Reader type Reader: XofReader; /// Retrieve XOF reader and consume hasher instance. fn finalize_xof(self) -> Self::Reader; - /// Retrieve XOF reader and reset hasher instance state. - fn finalize_xof_reset(&mut self) -> Self::Reader; + /// Finalize XOF and write result into `out`. + fn finalize_xof_into(self, out: &mut [u8]) { + self.finalize_xof().read(out); + } - /// Compute hash of `data` and write it to `output`. - fn digest_xof(input: impl AsRef<[u8]>, output: &mut [u8]) { + /// Compute hash of `data` and write it into `output`. + fn digest_xof(input: impl AsRef<[u8]>, output: &mut [u8]) + where + Self: Default, + { let mut hasher = Self::default(); hasher.update(input.as_ref()); hasher.finalize_xof().read(output); @@ -113,9 +158,20 @@ pub trait ExtendableOutput: Sized + Update + Default + Reset { self.finalize_xof().read(&mut buf); buf } +} + +/// Trait for hash functions with extendable-output (XOF) able to reset themselves. +pub trait ExtendableOutputReset: ExtendableOutput + Reset { + /// Retrieve XOF reader and reset hasher instance state. + fn finalize_xof_reset(&mut self) -> Self::Reader; + + /// Finalize XOF, write result into `out`, and reset the hasher state. + fn finalize_xof_reset_into(&mut self, out: &mut [u8]) { + self.finalize_xof_reset().read(out); + } /// Retrieve result into a boxed slice of the specified size and reset - /// the hasher's state. + /// the hasher state. /// /// `Box<[u8]>` is used instead of `Vec` to save stack space, since /// they have size of 2 and 3 words respectively. @@ -128,8 +184,8 @@ pub trait ExtendableOutput: Sized + Update + Default + Reset { } } -/// Trait for variable output size hash functions. -pub trait VariableOutput: Sized + Update + Reset { +/// Trait for hash functions with variable-size output. +pub trait VariableOutput: Sized + Update { /// Maximum size of output hash. const MAX_OUTPUT_SIZE: usize; @@ -142,17 +198,11 @@ pub trait VariableOutput: Sized + Update + Reset { /// Get output size of the hasher instance provided to the `new` method fn output_size(&self) -> usize; - /// Retrieve result via closure and consume hasher. - /// - /// Closure is guaranteed to be called, length of the buffer passed to it - /// will be equal to `output_size`. - fn finalize_variable(self, f: impl FnOnce(&[u8])); - - /// Retrieve result via closure and reset the hasher state. + /// Write result into the output buffer. /// - /// Closure is guaranteed to be called, length of the buffer passed to it - /// will be equal to `output_size`. - fn finalize_variable_reset(&mut self, f: impl FnOnce(&[u8])); + /// Returns `Err(InvalidOutputSize)` if `out` size is not equal to + /// `self.output_size()`. + fn finalize_variable(self, out: &mut [u8]) -> Result<(), InvalidBufferSize>; /// Compute hash of `data` and write it to `output`. /// @@ -165,8 +215,9 @@ pub trait VariableOutput: Sized + Update + Reset { ) -> Result<(), InvalidOutputSize> { let mut hasher = Self::new(output.len())?; hasher.update(input.as_ref()); - hasher.finalize_variable(|out| output.copy_from_slice(out)); - Ok(()) + hasher + .finalize_variable(output) + .map_err(|_| InvalidOutputSize) } /// Retrieve result into a boxed slice and consume hasher. @@ -178,11 +229,21 @@ pub trait VariableOutput: Sized + Update + Reset { fn finalize_boxed(self) -> Box<[u8]> { let n = self.output_size(); let mut buf = vec![0u8; n].into_boxed_slice(); - self.finalize_variable(|res| buf.copy_from_slice(res)); + self.finalize_variable(&mut buf) + .expect("buf length is equal to output_size"); buf } +} - /// Retrieve result into a boxed slice and reset hasher state. +/// Trait for hash functions with variable-size output able to reset themselves. +pub trait VariableOutputReset: VariableOutput + Reset { + /// Write result into the output buffer and reset the hasher state. + /// + /// Returns `Err(InvalidOutputSize)` if `out` size is not equal to + /// `self.output_size()`. + fn finalize_variable_reset(&mut self, out: &mut [u8]) -> Result<(), InvalidBufferSize>; + + /// Retrieve result into a boxed slice and reset the hasher state. /// /// `Box<[u8]>` is used instead of `Vec` to save stack space, since /// they have size of 2 and 3 words respectively. @@ -191,12 +252,13 @@ pub trait VariableOutput: Sized + Update + Reset { fn finalize_boxed_reset(&mut self) -> Box<[u8]> { let n = self.output_size(); let mut buf = vec![0u8; n].into_boxed_slice(); - self.finalize_variable_reset(|res| buf.copy_from_slice(res)); + self.finalize_variable_reset(&mut buf) + .expect("buf length is equal to output_size"); buf } } -/// The error type for variable hasher initialization. +/// The error type used in variable hash traits. #[derive(Clone, Copy, Debug, Default)] pub struct InvalidOutputSize; @@ -209,3 +271,16 @@ impl fmt::Display for InvalidOutputSize { #[cfg(feature = "std")] #[cfg_attr(docsrs, doc(cfg(feature = "std")))] impl std::error::Error for InvalidOutputSize {} + +/// Buffer length is not equal to hash output size. +#[derive(Default, Debug, Copy, Clone, Eq, PartialEq)] +pub struct InvalidBufferSize; + +impl fmt::Display for InvalidBufferSize { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("invalid buffer length") + } +} + +#[cfg(feature = "std")] +impl std::error::Error for InvalidBufferSize {} diff --git a/digest/src/mac.rs b/digest/src/mac.rs new file mode 100644 index 000000000..efebe1dcb --- /dev/null +++ b/digest/src/mac.rs @@ -0,0 +1,221 @@ +use crate::{FixedOutput, FixedOutputReset, Update}; +use crypto_common::{InvalidLength, Key, KeyInit, KeySizeUser, Output, OutputSizeUser, Reset}; + +use core::fmt; +use generic_array::typenum::Unsigned; +use subtle::{Choice, ConstantTimeEq}; + +/// Marker trait for Message Authentication algorithms. +#[cfg_attr(docsrs, doc(cfg(feature = "mac")))] +pub trait MacMarker {} + +/// Convinience wrapper trait covering functionality of Message Authentication algorithms. +/// +/// This trait wraps [`KeyInit`], [`Update`], [`FixedOutput`], and [`MacMarker`] +/// traits and provides additional convenience methods. +#[cfg_attr(docsrs, doc(cfg(feature = "mac")))] +pub trait Mac: KeySizeUser + OutputSizeUser + Sized { + /// Create new value from fixed size key. + fn new(key: &Key) -> Self; + + /// Create new value from variable size key. + fn new_from_slice(key: &[u8]) -> Result; + + /// Update state using the provided data. + fn update(&mut self, data: &[u8]); + + /// Obtain the result of a [`Mac`] computation as a [`CtOutput`] and consume + /// [`Mac`] instance. + fn finalize(self) -> CtOutput; + + /// Obtain the result of a [`Mac`] computation as a [`CtOutput`] and reset + /// [`Mac`] instance. + fn finalize_reset(&mut self) -> CtOutput + where + Self: FixedOutputReset; + + /// Reset MAC instance to its initial state. + fn reset(&mut self) + where + Self: Reset; + + /// Check if tag/code value is correct for the processed input. + fn verify(self, tag: &Output) -> Result<(), MacError>; + + /// Check truncated tag correctness using all bytes + /// of calculated tag. + /// + /// Returns `Error` if `tag` is not valid or not equal in length + /// to MAC's output. + fn verify_slice(self, tag: &[u8]) -> Result<(), MacError>; + + /// Check truncated tag correctness using left side bytes + /// (i.e. `tag[..n]`) of calculated tag. + /// + /// Returns `Error` if `tag` is not valid or empty. + fn verify_truncated_left(self, tag: &[u8]) -> Result<(), MacError>; + + /// Check truncated tag correctness using right side bytes + /// (i.e. `tag[n..]`) of calculated tag. + /// + /// Returns `Error` if `tag` is not valid or empty. + fn verify_truncated_right(self, tag: &[u8]) -> Result<(), MacError>; +} + +impl Mac for T { + #[inline(always)] + fn new(key: &Key) -> Self { + KeyInit::new(key) + } + + #[inline(always)] + fn new_from_slice(key: &[u8]) -> Result { + KeyInit::new_from_slice(key) + } + + #[inline] + fn update(&mut self, data: &[u8]) { + Update::update(self, data); + } + + #[inline] + fn finalize(self) -> CtOutput { + CtOutput::new(self.finalize_fixed()) + } + + #[inline(always)] + fn finalize_reset(&mut self) -> CtOutput + where + Self: FixedOutputReset, + { + CtOutput::new(self.finalize_fixed_reset()) + } + + #[inline] + fn reset(&mut self) + where + Self: Reset, + { + Reset::reset(self) + } + + #[inline] + fn verify(self, tag: &Output) -> Result<(), MacError> { + if self.finalize() == tag.into() { + Ok(()) + } else { + Err(MacError) + } + } + + #[inline] + fn verify_slice(self, tag: &[u8]) -> Result<(), MacError> { + let n = tag.len(); + if n != Self::OutputSize::USIZE { + return Err(MacError); + } + let choice = self.finalize_fixed().ct_eq(tag); + if choice.unwrap_u8() == 1 { + Ok(()) + } else { + Err(MacError) + } + } + + fn verify_truncated_left(self, tag: &[u8]) -> Result<(), MacError> { + let n = tag.len(); + if n == 0 || n > Self::OutputSize::USIZE { + return Err(MacError); + } + let choice = self.finalize_fixed()[..n].ct_eq(tag); + + if choice.unwrap_u8() == 1 { + Ok(()) + } else { + Err(MacError) + } + } + + fn verify_truncated_right(self, tag: &[u8]) -> Result<(), MacError> { + let n = tag.len(); + if n == 0 || n > Self::OutputSize::USIZE { + return Err(MacError); + } + let m = Self::OutputSize::USIZE - n; + let choice = self.finalize_fixed()[m..].ct_eq(tag); + + if choice.unwrap_u8() == 1 { + Ok(()) + } else { + Err(MacError) + } + } +} + +/// Fixed size output value which provides a safe [`Eq`] implementation that +/// runs in constant time. +/// +/// It is useful for implementing Message Authentication Codes (MACs). +#[derive(Clone)] +#[cfg_attr(docsrs, doc(cfg(feature = "subtle")))] +pub struct CtOutput { + bytes: Output, +} + +impl CtOutput { + /// Create a new [`CtOutput`] value. + #[inline(always)] + pub fn new(bytes: Output) -> Self { + Self { bytes } + } + + /// Get the inner [`Output`] array this type wraps. + #[inline(always)] + pub fn into_bytes(self) -> Output { + self.bytes + } +} + +impl From> for CtOutput { + #[inline(always)] + fn from(bytes: Output) -> Self { + Self { bytes } + } +} + +impl<'a, T: OutputSizeUser> From<&'a Output> for CtOutput { + #[inline(always)] + fn from(bytes: &'a Output) -> Self { + bytes.clone().into() + } +} + +impl ConstantTimeEq for CtOutput { + #[inline(always)] + fn ct_eq(&self, other: &Self) -> Choice { + self.bytes.ct_eq(&other.bytes) + } +} + +impl PartialEq for CtOutput { + #[inline(always)] + fn eq(&self, x: &CtOutput) -> bool { + self.ct_eq(x).unwrap_u8() == 1 + } +} + +impl Eq for CtOutput {} + +/// Error type for when the [`Output`] of a [`Mac`] +/// is not equal to the expected value. +#[derive(Default, Debug, Copy, Clone, Eq, PartialEq)] +pub struct MacError; + +impl fmt::Display for MacError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("MAC tag mismatch") + } +} + +#[cfg(feature = "std")] +impl std::error::Error for MacError {} From ef0f3e32e256b67d7bfc8f5b7d0429cb8e7634e0 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Wed, 8 Dec 2021 18:19:13 +0000 Subject: [PATCH 0678/1461] Fix doc cfg for CtOutput and MacError (#842) --- digest/src/mac.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/digest/src/mac.rs b/digest/src/mac.rs index efebe1dcb..fdddb8322 100644 --- a/digest/src/mac.rs +++ b/digest/src/mac.rs @@ -157,7 +157,7 @@ impl Mac for T { /// /// It is useful for implementing Message Authentication Codes (MACs). #[derive(Clone)] -#[cfg_attr(docsrs, doc(cfg(feature = "subtle")))] +#[cfg_attr(docsrs, doc(cfg(feature = "mac")))] pub struct CtOutput { bytes: Output, } @@ -209,6 +209,7 @@ impl Eq for CtOutput {} /// Error type for when the [`Output`] of a [`Mac`] /// is not equal to the expected value. #[derive(Default, Debug, Copy, Clone, Eq, PartialEq)] +#[cfg_attr(docsrs, doc(cfg(feature = "mac")))] pub struct MacError; impl fmt::Display for MacError { From f7cd3abd05d60b9d2dde0e158eaa2e3e14bf9c0c Mon Sep 17 00:00:00 2001 From: Popog <761307+Popog@users.noreply.github.com> Date: Sat, 11 Dec 2021 08:23:40 -0800 Subject: [PATCH 0679/1461] Fix typo (#844) --- cipher/src/stream.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cipher/src/stream.rs b/cipher/src/stream.rs index e33dd15a1..0e7d88ede 100644 --- a/cipher/src/stream.rs +++ b/cipher/src/stream.rs @@ -57,7 +57,7 @@ pub trait StreamCipherSeek { /// Seek to the given position /// /// # Panics - /// If provided position value is bigger than keystream leangth + /// If provided position value is bigger than keystream length fn seek(&mut self, pos: T) { self.try_seek(pos).unwrap() } From ffd8fe72bd9de1e054c21b4e968139b552b7776e Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Tue, 14 Dec 2021 05:45:58 +0000 Subject: [PATCH 0680/1461] Add Update::chain and Digest::new_with_prefix (#846) --- digest/CHANGELOG.md | 10 ++++++++++ digest/src/digest.rs | 15 ++++++++++++++- digest/src/lib.rs | 9 +++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/digest/CHANGELOG.md b/digest/CHANGELOG.md index 60dfb44d6..5229f8fc4 100644 --- a/digest/CHANGELOG.md +++ b/digest/CHANGELOG.md @@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.10.1 (2021-12-14) +### Added +- `Update::chain` and `Digest::new_with_prefix` methods. ([#846]) + +### Fixed +- Doc cfg attribute for CtOutput and MacError. ([#842]) + +[#842]: https://github.com/RustCrypto/traits/pull/842 +[#846]: https://github.com/RustCrypto/traits/pull/846 + ## 0.10.0 (2021-12-07) ### Changed - Dirty traits are removed and instead block-level traits are introduced. diff --git a/digest/src/digest.rs b/digest/src/digest.rs index 0e974b329..1ede72eb1 100644 --- a/digest/src/digest.rs +++ b/digest/src/digest.rs @@ -14,9 +14,12 @@ pub trait HashMarker {} /// This trait wraps [`Update`], [`FixedOutput`], [`Default`], and /// [`HashMarker`] traits and provides additional convenience methods. pub trait Digest: OutputSizeUser { - /// Create new hasher instance + /// Create new hasher instance. fn new() -> Self; + /// Create new hasher instance which has processed the provided data. + fn new_with_prefix(data: impl AsRef<[u8]>) -> Self; + /// Process data, updating the internal state. fn update(&mut self, data: impl AsRef<[u8]>); @@ -57,6 +60,16 @@ impl Digest for D { Self::default() } + #[inline] + fn new_with_prefix(data: impl AsRef<[u8]>) -> Self + where + Self: Default + Sized, + { + let mut h = Self::default(); + h.update(data.as_ref()); + h + } + #[inline] fn update(&mut self, data: impl AsRef<[u8]>) { Update::update(self, data.as_ref()); diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 3938c54c8..8d2498f3f 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -72,6 +72,15 @@ use core::fmt; pub trait Update { /// Update state using the provided data. fn update(&mut self, data: &[u8]); + + /// Digest input data in a chained manner. + fn chain(mut self, data: impl AsRef<[u8]>) -> Self + where + Self: Sized, + { + self.update(data.as_ref()); + self + } } /// Trait for hash functions with fixed-size output. From 03f83b8a7e2cc744e53f133195189e888fd30920 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Tue, 14 Dec 2021 08:18:25 +0000 Subject: [PATCH 0681/1461] rand_core fixes for digest and crypto-common (#847) --- Cargo.lock | 4 ++-- crypto-common/CHANGELOG.md | 6 ++++++ crypto-common/Cargo.toml | 6 +++++- crypto-common/src/lib.rs | 8 ++++++-- digest/CHANGELOG.md | 3 +++ digest/Cargo.toml | 5 +++-- digest/src/lib.rs | 8 ++++++-- digest/src/mac.rs | 14 ++++++++++++++ 8 files changed, 45 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cf9a6902d..cd72be07e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -94,7 +94,7 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.1.0" +version = "0.1.1" dependencies = [ "generic-array", "rand_core", @@ -111,7 +111,7 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.0" +version = "0.10.1" dependencies = [ "blobby", "block-buffer 0.10.0", diff --git a/crypto-common/CHANGELOG.md b/crypto-common/CHANGELOG.md index 822c0bec4..b5cf73540 100644 --- a/crypto-common/CHANGELOG.md +++ b/crypto-common/CHANGELOG.md @@ -5,5 +5,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.1.1 (2021-12-14) +### Added +- `rand_core` re-export and proper exposure of key/IV generation methods on docs.rs ([#847]) + +[#847]: https://github.com/RustCrypto/traits/pull/847 + ## 0.1.0 (2021-12-07) - Initial release diff --git a/crypto-common/Cargo.toml b/crypto-common/Cargo.toml index b38f4bb9d..1b629b109 100644 --- a/crypto-common/Cargo.toml +++ b/crypto-common/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crypto-common" description = "Common cryptographic traits" -version = "0.1.0" +version = "0.1.1" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" @@ -17,3 +17,7 @@ rand_core = { version = "0.6", optional = true } [features] std = [] + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] diff --git a/crypto-common/src/lib.rs b/crypto-common/src/lib.rs index a11626d37..f1e1570bc 100644 --- a/crypto-common/src/lib.rs +++ b/crypto-common/src/lib.rs @@ -3,8 +3,9 @@ #![no_std] #![cfg_attr(docsrs, feature(doc_cfg))] #![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", + html_root_url = "https://docs.rs/crypto-common/0.1.1" )] #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] @@ -12,6 +13,9 @@ #[cfg(feature = "std")] extern crate std; +#[cfg(feature = "rand_core")] +pub use rand_core; + use core::fmt; use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; #[cfg(feature = "rand_core")] diff --git a/digest/CHANGELOG.md b/digest/CHANGELOG.md index 5229f8fc4..f72a9825c 100644 --- a/digest/CHANGELOG.md +++ b/digest/CHANGELOG.md @@ -8,12 +8,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## 0.10.1 (2021-12-14) ### Added - `Update::chain` and `Digest::new_with_prefix` methods. ([#846]) +- `Mac::generate_key` method. ([#847]) ### Fixed - Doc cfg attribute for CtOutput and MacError. ([#842]) +- Expose `KeyInit::generate_key` method in docs. ([#847]) [#842]: https://github.com/RustCrypto/traits/pull/842 [#846]: https://github.com/RustCrypto/traits/pull/846 +[#847]: https://github.com/RustCrypto/traits/pull/847 ## 0.10.0 (2021-12-07) ### Changed diff --git a/digest/Cargo.toml b/digest/Cargo.toml index f7359bb2a..9ec439e41 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "digest" description = "Traits for cryptographic hash functions" -version = "0.10.0" +version = "0.10.1" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" @@ -13,7 +13,7 @@ categories = ["cryptography", "no-std"] [dependencies] generic-array = "0.14" -crypto-common = { version = "0.1", path = "../crypto-common" } +crypto-common = { version = "0.1.1", path = "../crypto-common" } block-buffer = { version = "0.10", optional = true } subtle = { version = "=2.4", default-features = false, optional = true } @@ -23,6 +23,7 @@ blobby = { version = "0.3", optional = true } default = ["core-api"] core-api = ["block-buffer"] # Enable Core API traits mac = ["subtle"] # Enable MAC traits +rand_core = ["crypto-common/rand_core"] # Enable random key generation methods alloc = [] std = ["alloc", "crypto-common/std"] dev = ["blobby"] diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 8d2498f3f..7aa346e39 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -27,8 +27,9 @@ #![cfg_attr(docsrs, feature(doc_cfg))] #![forbid(unsafe_code)] #![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg" + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", + html_root_url = "https://docs.rs/digest/0.10.1" )] #![warn(missing_docs, rust_2018_idioms)] @@ -39,6 +40,9 @@ extern crate alloc; #[cfg(feature = "std")] extern crate std; +#[cfg(feature = "rand_core")] +pub use crypto_common::rand_core; + #[cfg(feature = "alloc")] use alloc::boxed::Box; diff --git a/digest/src/mac.rs b/digest/src/mac.rs index fdddb8322..672ce93e3 100644 --- a/digest/src/mac.rs +++ b/digest/src/mac.rs @@ -1,6 +1,8 @@ use crate::{FixedOutput, FixedOutputReset, Update}; use crypto_common::{InvalidLength, Key, KeyInit, KeySizeUser, Output, OutputSizeUser, Reset}; +#[cfg(feature = "rand_core")] +use crate::rand_core::{CryptoRng, RngCore}; use core::fmt; use generic_array::typenum::Unsigned; use subtle::{Choice, ConstantTimeEq}; @@ -18,6 +20,11 @@ pub trait Mac: KeySizeUser + OutputSizeUser + Sized { /// Create new value from fixed size key. fn new(key: &Key) -> Self; + /// Generate random key using the provided [`CryptoRng`]. + #[cfg(feature = "rand_core")] + #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] + fn generate_key(rng: impl CryptoRng + RngCore) -> Key; + /// Create new value from variable size key. fn new_from_slice(key: &[u8]) -> Result; @@ -150,6 +157,13 @@ impl Mac for T { Err(MacError) } } + + #[cfg(feature = "rand_core")] + #[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))] + #[inline] + fn generate_key(rng: impl CryptoRng + RngCore) -> Key { + ::generate_key(rng) + } } /// Fixed size output value which provides a safe [`Eq`] implementation that From f97307afb8632897187102a0e8346309080cd545 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 14 Dec 2021 11:35:02 -0700 Subject: [PATCH 0682/1461] signature: bump `digest` dependency to v0.10 (#850) --- Cargo.lock | 54 ++++++------- crypto/Cargo.lock | 28 ++++++- crypto/Cargo.toml | 4 +- signature/Cargo.toml | 22 ++---- signature/async/Cargo.toml | 4 +- signature/derive/Cargo.toml | 2 +- signature/derive/src/lib.rs | 8 +- signature/tests/signature_derive.rs | 118 ++++++++++++++-------------- 8 files changed, 122 insertions(+), 118 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cd72be07e..72e9e2e0f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,7 +14,7 @@ dependencies = [ [[package]] name = "async-signature" -version = "0.0.1" +version = "0.1.0-pre" dependencies = [ "async-trait", "signature", @@ -43,15 +43,6 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "847495c209977a90e8aad588b959d0ca9f5dc228096d29a6bd3defd53f35eaec" -[[package]] -name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "generic-array", -] - [[package]] name = "block-buffer" version = "0.10.0" @@ -78,7 +69,7 @@ name = "cipher" version = "0.4.0-pre" dependencies = [ "blobby", - "crypto-common", + "crypto-common 0.1.1", "generic-array", "rand_core", ] @@ -101,10 +92,10 @@ dependencies = [ ] [[package]] -name = "digest" -version = "0.9.0" +name = "crypto-common" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +checksum = "683d6b536309245c849479fba3da410962a43ed8e51c26b729208ec0ac2798d0" dependencies = [ "generic-array", ] @@ -114,12 +105,23 @@ name = "digest" version = "0.10.1" dependencies = [ "blobby", - "block-buffer 0.10.0", - "crypto-common", + "block-buffer", + "crypto-common 0.1.1", "generic-array", "subtle", ] +[[package]] +name = "digest" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b697d66081d42af4fba142d56918a3cb21dc8eb63372c6b85d14f44fb9c5979b" +dependencies = [ + "block-buffer", + "crypto-common 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "generic-array", +] + [[package]] name = "generic-array" version = "0.14.4" @@ -195,12 +197,6 @@ dependencies = [ "scopeguard", ] -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - [[package]] name = "password-hash" version = "0.3.2" @@ -251,22 +247,20 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "sha2" -version = "0.9.8" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b69f9a4c9740d74c5baa3fd2e547f9525fa8088a8a958e0ca2409a514e33f5fa" +checksum = "900d964dd36bb15bcf2f2b35694c072feab74969a54f2bbeec7a2d725d2bdcb6" dependencies = [ - "block-buffer 0.9.0", "cfg-if", "cpufeatures", - "digest 0.9.0", - "opaque-debug", + "digest 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "signature" -version = "1.4.0" +version = "1.5.0-pre" dependencies = [ - "digest 0.9.0", + "digest 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal", "rand_core", "sha2", @@ -275,7 +269,7 @@ dependencies = [ [[package]] name = "signature_derive" -version = "1.0.0-pre.3" +version = "1.0.0-pre.4" dependencies = [ "proc-macro2", "quote", diff --git a/crypto/Cargo.lock b/crypto/Cargo.lock index d1fac9ced..5a1d3489f 100644 --- a/crypto/Cargo.lock +++ b/crypto/Cargo.lock @@ -16,6 +16,15 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a32fd6af2b5827bce66c29053ba0e7c42b9dcab01835835058558c10851a46b" +[[package]] +name = "block-buffer" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1d36a02058e76b040de25a4464ba1c80935655595b661505c8b39b664828b95" +dependencies = [ + "generic-array", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -63,6 +72,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "crypto-common" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d6b536309245c849479fba3da410962a43ed8e51c26b729208ec0ac2798d0" +dependencies = [ + "generic-array", +] + [[package]] name = "crypto-mac" version = "0.11.1" @@ -84,16 +102,18 @@ dependencies = [ [[package]] name = "digest" -version = "0.9.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +checksum = "b697d66081d42af4fba142d56918a3cb21dc8eb63372c6b85d14f44fb9c5979b" dependencies = [ + "block-buffer", + "crypto-common", "generic-array", ] [[package]] name = "elliptic-curve" -version = "0.11.1" +version = "0.11.5" dependencies = [ "crypto-bigint", "der", @@ -198,7 +218,7 @@ dependencies = [ [[package]] name = "signature" -version = "1.4.0" +version = "1.5.0-pre" [[package]] name = "spki" diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 9336c4b4e..e85e9abc9 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -21,11 +21,11 @@ members = ["."] [dependencies] aead = { version = "0.4", optional = true, path = "../aead" } cipher = { version = "0.3", optional = true } -digest = { version = "0.9", optional = true } +digest = { version = "0.10", optional = true } elliptic-curve = { version = "0.11", optional = true, path = "../elliptic-curve" } mac = { version = "0.11", package = "crypto-mac", optional = true } password-hash = { version = "0.3", optional = true, path = "../password-hash" } -signature = { version = "1.3.0", optional = true, default-features = false, path = "../signature" } +signature = { version = "=1.5.0-pre", optional = true, default-features = false, path = "../signature" } universal-hash = { version = "0.4", optional = true, path = "../universal-hash" } [features] diff --git a/signature/Cargo.toml b/signature/Cargo.toml index 53817708f..a2fe57c26 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "1.4.0" # Also update html_root_url in lib.rs when bumping this +version = "1.5.0-pre" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/signature" @@ -11,24 +11,14 @@ edition = "2018" keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"] categories = ["cryptography", "no-std"] -[dependencies.digest] -version = "0.9" -optional = true -default-features = false - -[dependencies.rand_core] -version = "0.6" -optional = true -default-features = false - -[dependencies.signature_derive] -version = "= 1.0.0-pre.3" -optional = true -path = "derive" +[dependencies] +digest = { version = "0.10.1", optional = true, default-features = false } +rand_core = { version = "0.6", optional = true, default-features = false } +signature_derive = { version = "=1.0.0-pre.4", optional = true, path = "derive" } [dev-dependencies] hex-literal = "0.2" -sha2 = { version = "0.9", default-features = false } +sha2 = { version = "0.10", default-features = false } [features] default = ["std"] diff --git a/signature/async/Cargo.toml b/signature/async/Cargo.toml index b5206b47a..054ae91c1 100644 --- a/signature/async/Cargo.toml +++ b/signature/async/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "async-signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "0.0.1" # Also update html_root_url in lib.rs when bumping this +version = "0.1.0-pre" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/async-signature" @@ -13,7 +13,7 @@ categories = ["cryptography", "no-std"] [dependencies] async-trait = "0.1" -signature = { version = "1.3.0", path = ".." } +signature = { version = "=1.5.0-pre", path = ".." } [features] digest = ["signature/digest-preview"] diff --git a/signature/derive/Cargo.toml b/signature/derive/Cargo.toml index f5487cbf3..0aa15c9d6 100644 --- a/signature/derive/Cargo.toml +++ b/signature/derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "signature_derive" -version = "1.0.0-pre.3" +version = "1.0.0-pre.4" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" description = "Custom derive support for the 'signature' crate" diff --git a/signature/derive/src/lib.rs b/signature/derive/src/lib.rs index be067427c..fc937f77e 100644 --- a/signature/derive/src/lib.rs +++ b/signature/derive/src/lib.rs @@ -24,7 +24,7 @@ fn derive_signer(mut s: synstructure::Structure) -> TokenStream { Self: signature::DigestSigner { fn try_sign(&self, msg: &[u8]) -> Result { - self.try_sign_digest(S::Digest::new().chain(msg)) + self.try_sign_digest(S::Digest::new_with_prefix(msg)) } } }) @@ -61,7 +61,7 @@ fn derive_verifier(mut s: synstructure::Structure) -> TokenStream { Self: signature::DigestVerifier { fn verify(&self, msg: &[u8], signature: &S) -> Result<(), signature::Error> { - self.verify_digest(S::Digest::new().chain(msg), signature) + self.verify_digest(S::Digest::new_with_prefix(msg), signature) } } }) @@ -110,7 +110,7 @@ mod tests { Self: signature::DigestSigner { fn try_sign(&self, msg: &[u8]) -> Result { - self.try_sign_digest(S::Digest::new().chain(msg)) + self.try_sign_digest(S::Digest::new_with_prefix(msg)) } } }; @@ -136,7 +136,7 @@ mod tests { Self: signature::DigestVerifier { fn verify(&self, msg: &[u8], signature: &S) -> Result<(), signature::Error> { - self.verify_digest(S::Digest::new().chain(msg), signature) + self.verify_digest(S::Digest::new_with_prefix(msg), signature) } } }; diff --git a/signature/tests/signature_derive.rs b/signature/tests/signature_derive.rs index 272718a66..bda95d6f9 100644 --- a/signature/tests/signature_derive.rs +++ b/signature/tests/signature_derive.rs @@ -1,76 +1,76 @@ -/// "Tests" for code generated by `signature_derive` -#[cfg(all(test, feature = "derive-preview"))] -mod tests { - use digest::{generic_array::GenericArray, Digest}; - use hex_literal::hex; - use sha2::Sha256; - use signature::{ - DigestSigner, DigestVerifier, Error, PrehashSignature, Signature, Signer, Verifier, - }; +//! Tests for code generated by `signature_derive` - /// Test vector to compute SHA-256 digest of - const INPUT_STRING: &[u8] = b"abc"; +#![cfg(all(test, feature = "derive-preview"))] - /// Expected SHA-256 digest for the input string - const INPUT_STRING_DIGEST: [u8; 32] = - hex!("ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad"); +use digest::{generic_array::GenericArray, Digest, OutputSizeUser}; +use hex_literal::hex; +use sha2::Sha256; +use signature::{ + DigestSigner, DigestVerifier, Error, PrehashSignature, Signature, Signer, Verifier, +}; - /// Dummy signature which just contains a digest output - #[derive(Debug)] - struct DummySignature(GenericArray::OutputSize>); +/// Test vector to compute SHA-256 digest of +const INPUT_STRING: &[u8] = b"abc"; - impl Signature for DummySignature { - fn from_bytes(bytes: &[u8]) -> Result { - Ok(DummySignature(GenericArray::clone_from_slice( - bytes.as_ref(), - ))) - } - } +/// Expected SHA-256 digest for the input string +const INPUT_STRING_DIGEST: [u8; 32] = + hex!("ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad"); + +/// Dummy signature which just contains a digest output +#[derive(Debug)] +struct DummySignature(GenericArray::OutputSize>); - impl AsRef<[u8]> for DummySignature { - fn as_ref(&self) -> &[u8] { - self.0.as_ref() - } +impl Signature for DummySignature { + fn from_bytes(bytes: &[u8]) -> Result { + Ok(DummySignature(GenericArray::clone_from_slice( + bytes.as_ref(), + ))) } +} - impl PrehashSignature for DummySignature { - type Digest = Sha256; +impl AsRef<[u8]> for DummySignature { + fn as_ref(&self) -> &[u8] { + self.0.as_ref() } +} + +impl PrehashSignature for DummySignature { + type Digest = Sha256; +} - /// Dummy signer which just returns the message digest as a `DummySignature` - #[derive(Signer, Default)] - struct DummySigner {} +/// Dummy signer which just returns the message digest as a `DummySignature` +#[derive(Signer, Default)] +struct DummySigner {} - impl DigestSigner for DummySigner { - fn try_sign_digest(&self, digest: Sha256) -> Result { - DummySignature::from_bytes(&digest.finalize()) - } +impl DigestSigner for DummySigner { + fn try_sign_digest(&self, digest: Sha256) -> Result { + DummySignature::from_bytes(&digest.finalize()) } +} - /// Dummy verifier which ensures the `DummySignature` digest matches the - /// expected value. - /// - /// Panics (via `assert_eq!`) if the value is not what is expected. - #[derive(Verifier, Default)] - struct DummyVerifier {} +/// Dummy verifier which ensures the `DummySignature` digest matches the +/// expected value. +/// +/// Panics (via `assert_eq!`) if the value is not what is expected. +#[derive(Verifier, Default)] +struct DummyVerifier {} - impl DigestVerifier for DummyVerifier { - fn verify_digest(&self, digest: Sha256, signature: &DummySignature) -> Result<(), Error> { - let actual_digest = digest.finalize(); - assert_eq!(signature.as_ref(), actual_digest.as_slice()); - Ok(()) - } +impl DigestVerifier for DummyVerifier { + fn verify_digest(&self, digest: Sha256, signature: &DummySignature) -> Result<(), Error> { + let actual_digest = digest.finalize(); + assert_eq!(signature.as_ref(), actual_digest.as_slice()); + Ok(()) } +} - #[test] - fn derived_signer_impl() { - let sig: DummySignature = DummySigner::default().sign(INPUT_STRING); - assert_eq!(sig.as_ref(), INPUT_STRING_DIGEST.as_ref()) - } +#[test] +fn derived_signer_impl() { + let sig: DummySignature = DummySigner::default().sign(INPUT_STRING); + assert_eq!(sig.as_ref(), INPUT_STRING_DIGEST.as_ref()) +} - #[test] - fn derived_verifier_impl() { - let sig: DummySignature = DummySigner::default().sign(INPUT_STRING); - assert!(DummyVerifier::default().verify(INPUT_STRING, &sig).is_ok()); - } +#[test] +fn derived_verifier_impl() { + let sig: DummySignature = DummySigner::default().sign(INPUT_STRING); + assert!(DummyVerifier::default().verify(INPUT_STRING, &sig).is_ok()); } From c235c0c0d828202f63cb3f263e310e45dda9901d Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 20 Dec 2021 14:53:38 -0700 Subject: [PATCH 0683/1461] elliptic-curve: type conversions chart (#852) Adds a chart which illustrates the various conversions possible between the various types defined by this crate to the toplevel rustdoc. --- elliptic-curve/src/lib.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 3b2d3b534..3e5974f31 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -20,6 +20,13 @@ //! the above crates, either via an external ECDSA implementation, or //! using native curve arithmetic where applicable. //! +//! ## Type conversions +//! +//! The following chart illustrates the various conversions possible between +//! the various types defined by this crate. +//! +//! ![Type Conversion Map](https://raw.githubusercontent.com/RustCrypto/media/master/img/elliptic-curve/type-transforms.svg) +//! //! ## `serde` support //! //! When the `serde` feature of this crate is enabled, `Serialize` and From b611df39d9c315566a1d1284a6d91d70af1eef33 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 20 Dec 2021 15:10:33 -0700 Subject: [PATCH 0684/1461] elliptic-curve v0.11.6 (#853) --- crypto/Cargo.lock | 2 +- elliptic-curve/CHANGELOG.md | 6 ++++++ elliptic-curve/Cargo.lock | 2 +- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 19 +++++++++---------- 5 files changed, 18 insertions(+), 13 deletions(-) diff --git a/crypto/Cargo.lock b/crypto/Cargo.lock index 5a1d3489f..7f86ea218 100644 --- a/crypto/Cargo.lock +++ b/crypto/Cargo.lock @@ -113,7 +113,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.11.5" +version = "0.11.6" dependencies = [ "crypto-bigint", "der", diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index 3ebab41bc..005721465 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.11.6 (2021-12-20) +### Added +- Type conversions chart ([#852]) + +[#852]: https://github.com/RustCrypto/traits/pull/852 + ## 0.11.5 (2021-12-05) ### Changed - Revised `LinearCombination` trait ([#835]) diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index 9106d9042..9352ce4cd 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -56,7 +56,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.11.5" +version = "0.11.6" dependencies = [ "base64ct", "crypto-bigint", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index dabbdc532..bcda30783 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.11.5" # Also update html_root_url in lib.rs when bumping this +version = "0.11.6" # Also update html_root_url in lib.rs when bumping this description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 3e5974f31..3e4083244 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -1,3 +1,12 @@ +#![no_std] +#![cfg_attr(docsrs, feature(doc_cfg))] +#![forbid(unsafe_code, clippy::unwrap_used)] +#![warn(missing_docs, rust_2018_idioms, unused_qualifications)] +#![doc( + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", + html_root_url = "https://docs.rs/elliptic-curve/0.11.6" +)] #![doc = include_str!("../README.md")] //! ## Usage @@ -46,16 +55,6 @@ //! [`p384`]: https://github.com/RustCrypto/elliptic-curves/tree/master/p384 //! [`ecdsa`]: https://github.com/RustCrypto/signatures/tree/master/ecdsa -#![no_std] -#![cfg_attr(docsrs, feature(doc_cfg))] -#![forbid(unsafe_code, clippy::unwrap_used)] -#![warn(missing_docs, rust_2018_idioms, unused_qualifications)] -#![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.11.5" -)] - #[cfg(feature = "alloc")] #[allow(unused_imports)] #[macro_use] From dcbce6a19db9003b2b7faaaad651e8b10a5ddf24 Mon Sep 17 00:00:00 2001 From: Michael Lodder Date: Wed, 22 Dec 2021 13:32:42 -0700 Subject: [PATCH 0685/1461] feat: add osswu trait (#854) Signed-off-by: Michael Lodder --- elliptic-curve/Cargo.toml | 1 + elliptic-curve/src/lib.rs | 5 +++ elliptic-curve/src/osswu.rs | 84 +++++++++++++++++++++++++++++++++++++ 3 files changed, 90 insertions(+) create mode 100644 elliptic-curve/src/osswu.rs diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index bcda30783..848b3e5d0 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -49,6 +49,7 @@ dev = ["arithmetic", "hex-literal", "pem", "pkcs8"] ecdh = ["arithmetic"] hazmat = [] jwk = ["alloc", "base64ct/alloc", "serde", "serde_json", "zeroize/alloc"] +osswu = ["ff"] pem = ["alloc", "arithmetic", "pem-rfc7468/alloc", "pkcs8", "sec1/pem"] pkcs8 = ["sec1/pkcs8"] std = ["alloc", "rand_core/std"] diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 3e4083244..2131cae74 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -94,6 +94,11 @@ pub mod ecdh; #[cfg(feature = "jwk")] mod jwk; +/// Optimized simplified Shallue-van de Woestijne-Ulas methods +#[cfg(feature = "osswu")] +#[cfg_attr(docsrs, doc(cfg(feature = "osswu")))] +pub mod osswu; + pub use crate::{ error::{Error, Result}, point::{ diff --git a/elliptic-curve/src/osswu.rs b/elliptic-curve/src/osswu.rs new file mode 100644 index 000000000..ae8637512 --- /dev/null +++ b/elliptic-curve/src/osswu.rs @@ -0,0 +1,84 @@ +use ff::Field; +use subtle::Choice; + +/// The Optimized Simplified Shallue-van de Woestijne-Ulas parameters +pub struct OsswuMapParams +where + F: Field, +{ + /// The first constant term + pub c1: [u64; 4], + /// The second constant term + pub c2: F, + /// The ISO A variable or Curve A variable + pub map_a: F, + /// The ISO A variable or Curve A variable + pub map_b: F, + /// The Z parameter + pub z: F, +} + +/// Trait for determining the parity of the field +pub trait Sgn0 { + /// Return the parity of the field + /// 1 == negative + /// 0 == non-negative + fn sgn0(&self) -> Choice; +} + +/// The optimized simplified Shallue-van de Woestijne-Ulas method +/// for mapping elliptic curve scalars to affine points. +pub trait OsswuMap: Field + Sgn0 { + /// The OSSWU parameters for mapping the field to affine points. + /// For Weierstrass curves having A==0 or B==0, the parameters + /// should be for isogeny where A≠0 and B≠0. + const PARAMS: OsswuMapParams; + + /// Convert this field element into an affine point on the ellliptic curve + /// returning (X, Y). For Weierstrass curves having A==0 or B==0 + /// the result is a point on an isogeny. + fn osswu(&self) -> (Self, Self) { + let tv1 = self.square(); // u^2 + let tv3 = Self::PARAMS.z * tv1; // Z * u^2 + let mut tv2 = tv3.square(); // tv3^2 + let mut xd = tv2 + tv3; // tv3^2 + tv3 + let x1n = Self::PARAMS.map_b * (xd + Self::one()); // B * (xd + 1) + let a_neg = -Self::PARAMS.map_a; + xd *= a_neg; // -A * xd + + let tv = Self::PARAMS.z * Self::PARAMS.map_a; + xd.conditional_assign(&tv, xd.is_zero()); + + tv2 = xd.square(); //xd^2 + let gxd = tv2 * xd; // xd^3 + tv2 *= Self::PARAMS.map_a; // A * tv2 + + let mut gx1 = x1n * (tv2 + x1n.square()); //x1n *(tv2 + x1n^2) + tv2 = gxd * Self::PARAMS.map_b; // B * gxd + gx1 += tv2; // gx1 + tv2 + + let mut tv4 = gxd.square(); // gxd^2 + tv2 = gx1 * gxd; // gx1 * gxd + tv4 *= tv2; + + let y1 = tv4.pow_vartime(&Self::PARAMS.c1) * tv2; // tv4^C1 * tv2 + let x2n = tv3 * x1n; // tv3 * x1n + + let y2 = y1 * Self::PARAMS.c2 * tv1 * self; // y1 * c2 * tv1 * u + + tv2 = y1.square() * gxd; //y1^2 * gxd + + let e2 = tv2.ct_eq(&gx1); + + // if e2 , x = x1, else x = x2 + let mut x = Self::conditional_select(&x2n, &x1n, e2); + // xn / xd + x *= xd.invert().unwrap(); + + // if e2, y = y1, else y = y2 + let mut y = Self::conditional_select(&y2, &y1, e2); + + y.conditional_assign(&-y, self.sgn0() ^ y.sgn0()); + (x, y) + } +} From e6990462e3edbc91f2fb9fcd5174c833d13b9cbe Mon Sep 17 00:00:00 2001 From: Michael Rosenberg Date: Fri, 31 Dec 2021 09:30:28 -0500 Subject: [PATCH 0686/1461] KEM Traits (#845) --- .github/workflows/kem.yml | 84 +++++ kem/CHANGELOG.md | 9 + kem/Cargo.lock | 700 ++++++++++++++++++++++++++++++++++++++ kem/Cargo.toml | 41 +++ kem/LICENSE-APACHE | 13 + kem/LICENSE-MIT | 25 ++ kem/README.md | 62 ++++ kem/src/errors.rs | 17 + kem/src/kem.rs | 55 +++ kem/src/lib.rs | 19 ++ kem/tests/hpke.rs | 145 ++++++++ kem/tests/saber.rs | 72 ++++ kem/tests/x3dh.rs | 141 ++++++++ 13 files changed, 1383 insertions(+) create mode 100644 .github/workflows/kem.yml create mode 100644 kem/CHANGELOG.md create mode 100644 kem/Cargo.lock create mode 100644 kem/Cargo.toml create mode 100644 kem/LICENSE-APACHE create mode 100644 kem/LICENSE-MIT create mode 100644 kem/README.md create mode 100644 kem/src/errors.rs create mode 100644 kem/src/kem.rs create mode 100644 kem/src/lib.rs create mode 100644 kem/tests/hpke.rs create mode 100644 kem/tests/saber.rs create mode 100644 kem/tests/x3dh.rs diff --git a/.github/workflows/kem.yml b/.github/workflows/kem.yml new file mode 100644 index 000000000..2ee3c00af --- /dev/null +++ b/.github/workflows/kem.yml @@ -0,0 +1,84 @@ +name: kem + +on: + pull_request: + paths: + - "kem/**" + - "Cargo.*" + push: + branches: master + +defaults: + run: + working-directory: kem + +env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + rust: + - 1.56.0 # MSRV + - stable + target: + - thumbv7em-none-eabi + - wasm32-unknown-unknown + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ matrix.rust }} + target: ${{ matrix.target }} + override: true + profile: minimal + - run: cargo build --no-default-features --release --target ${{ matrix.target }} + + test: + runs-on: ubuntu-latest + strategy: + matrix: + rust: + - 1.56.0 # MSRV + - stable + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ matrix.rust }} + override: true + profile: minimal + - run: cargo check --all-features + - run: cargo test --no-default-features --release + - run: cargo test --release + - run: cargo test --all-features --release + + clippy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + toolchain: 1.56.0 + components: clippy + override: true + profile: minimal + - run: cargo clippy --all --all-features -- -D warnings + + rustfmt: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + toolchain: stable + components: rustfmt + override: true + profile: minimal + - uses: actions-rs/cargo@v1 + with: + command: fmt + args: --all -- --check diff --git a/kem/CHANGELOG.md b/kem/CHANGELOG.md new file mode 100644 index 000000000..ba69d0b88 --- /dev/null +++ b/kem/CHANGELOG.md @@ -0,0 +1,9 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## 0.0.1 (2021-12-13) + +- Initial commit diff --git a/kem/Cargo.lock b/kem/Cargo.lock new file mode 100644 index 000000000..a23a8f240 --- /dev/null +++ b/kem/Cargo.lock @@ -0,0 +1,700 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aead" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" +dependencies = [ + "generic-array", +] + +[[package]] +name = "aes" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", + "opaque-debug", +] + +[[package]] +name = "aes-gcm" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df5f85a83a7d8b0442b6aa7b504b8212c1733da07b98aae43d4bc21b2cb3cdf6" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "ghash", + "subtle", +] + +[[package]] +name = "base64ct" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "874f8444adcb4952a8bc51305c8be95c8ec8237bb0d2e78d2e039f771f8828a0" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "cc" +version = "1.0.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" +dependencies = [ + "jobserver", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chacha20" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01b72a433d0cf2aef113ba70f62634c56fddb0f244e6377185c56a7cadbd8f91" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", + "zeroize", +] + +[[package]] +name = "chacha20poly1305" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b84ed6d1d5f7aa9bdde921a5090e0ca4d934d250ea3b402a5fab3a994e28a2a" +dependencies = [ + "aead", + "chacha20", + "cipher", + "poly1305", + "zeroize", +] + +[[package]] +name = "cipher" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" +dependencies = [ + "generic-array", +] + +[[package]] +name = "const-oid" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d6f2aa4d0537bcc1c74df8755072bd31c1ef1a3a1b85a68e8404a8c353b7b8b" + +[[package]] +name = "cpufeatures" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-bigint" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83bd3bb4314701c568e340cd8cf78c975aa0ca79e03d3f6d1677d5b0c9c0c03" +dependencies = [ + "generic-array", + "rand_core 0.6.3", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-mac" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "ctr" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea" +dependencies = [ + "cipher", +] + +[[package]] +name = "curve25519-dalek" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +dependencies = [ + "byteorder", + "digest", + "rand_core 0.5.1", + "subtle", + "zeroize", +] + +[[package]] +name = "der" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79b71cca7d95d7681a4b3b9cdf63c8dbc3730d0584c2c74e31416d64a90493f4" +dependencies = [ + "const-oid", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "ecdsa" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43ee23aa5b4f68c7a092b5c3beb25f50c406adc75e2363634f242f28ab255372" +dependencies = [ + "der", + "elliptic-curve", + "hmac", + "signature", +] + +[[package]] +name = "elliptic-curve" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "beca177dcb8eb540133e7680baff45e7cc4d93bf22002676cec549f82343721b" +dependencies = [ + "crypto-bigint", + "ff", + "generic-array", + "group", + "pkcs8", + "rand_core 0.6.3", + "subtle", + "zeroize", +] + +[[package]] +name = "ff" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0f40b2dcd8bc322217a5f6559ae5f9e9d1de202a2ecee2e9eafcbece7562a4f" +dependencies = [ + "rand_core 0.6.3", + "subtle", +] + +[[package]] +name = "generic-array" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "ghash" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1583cc1656d7839fd3732b80cf4f38850336cdb9b8ded1cd399ca62958de3c99" +dependencies = [ + "opaque-debug", + "polyval", +] + +[[package]] +name = "glob" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" + +[[package]] +name = "group" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c363a5301b8f153d80747126a04b3c82073b9fe3130571a9d170cacdeaf7912" +dependencies = [ + "ff", + "rand_core 0.6.3", + "subtle", +] + +[[package]] +name = "hkdf" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01706d578d5c281058480e673ae4086a9f4710d8df1ad80a5b03e39ece5f886b" +dependencies = [ + "digest", + "hmac", +] + +[[package]] +name = "hmac" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" +dependencies = [ + "crypto-mac", + "digest", +] + +[[package]] +name = "hpke" +version = "0.8.0" +source = "git+https://github.com/rozbb/rust-hpke?rev=3c795445f38317d6a0868259caf3e87916548356#3c795445f38317d6a0868259caf3e87916548356" +dependencies = [ + "aead", + "aes-gcm", + "byteorder", + "chacha20poly1305", + "digest", + "generic-array", + "hkdf", + "paste", + "rand_core 0.6.3", + "sha2", + "subtle", + "x25519-dalek", + "zeroize", +] + +[[package]] +name = "jobserver" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa" +dependencies = [ + "libc", +] + +[[package]] +name = "kem" +version = "0.1.0" +dependencies = [ + "generic-array", + "hpke", + "p256", + "pqcrypto", + "pqcrypto-traits", + "rand", + "rand_core 0.6.3", + "x3dh-ke", +] + +[[package]] +name = "libc" +version = "0.2.112" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "p256" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d053368e1bae4c8a672953397bd1bd7183dde1c72b0b7612a15719173148d186" +dependencies = [ + "ecdsa", + "elliptic-curve", + "sha2", +] + +[[package]] +name = "paste" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0744126afe1a6dd7f394cb50a716dbe086cb06e255e53d8d0185d82828358fb5" + +[[package]] +name = "pem-rfc7468" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f22eb0e3c593294a99e9ff4b24cf6b752d43f193aa4415fe5077c159996d497" +dependencies = [ + "base64ct", +] + +[[package]] +name = "pkcs8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee3ef9b64d26bad0536099c816c6734379e45bbd5f14798def6809e5cc350447" +dependencies = [ + "der", + "pem-rfc7468", + "spki", + "zeroize", +] + +[[package]] +name = "poly1305" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "048aeb476be11a4b6ca432ca569e375810de9294ae78f4774e78ea98a9246ede" +dependencies = [ + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "polyval" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8419d2b623c7c0896ff2d5d96e2cb4ede590fed28fcc34934f4c33c036e620a1" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" + +[[package]] +name = "pqcrypto" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9da39bd0587bff4189521766c34f3203263926f7527906578a96d22a81a700d5" +dependencies = [ + "pqcrypto-saber", + "pqcrypto-traits", +] + +[[package]] +name = "pqcrypto-internals" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64b13e34e3758451a74aee45db434cc258b7794225bcbef3274b981545058645" +dependencies = [ + "cc", + "getrandom", + "libc", +] + +[[package]] +name = "pqcrypto-saber" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57ba16b59d256e2cae57bcdbd013f73b32496ebc66db3db6ccb79a10f0d4b275" +dependencies = [ + "cc", + "glob", + "libc", + "pqcrypto-internals", + "pqcrypto-traits", +] + +[[package]] +name = "pqcrypto-traits" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97e91cb6af081c6daad5fa705f8adb0634c027662052cb3174bdf2957bf07e25" + +[[package]] +name = "proc-macro2" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47aa80447ce4daf1717500037052af176af5d38cc3e571d9ec1c7353fc10c87d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" +dependencies = [ + "libc", + "rand_chacha", + "rand_core 0.6.3", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.3", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" +dependencies = [ + "rand_core 0.6.3", +] + +[[package]] +name = "serde" +version = "1.0.132" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9875c23cf305cd1fd7eb77234cbb705f21ea6a72c637a5c6db5fe4b8e7f008" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_bytes" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16ae07dd2f88a366f15bd0632ba725227018c69a1c8550a927324f8eb8368bb9" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.132" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc0db5cb2556c0e558887d9bbdcf6ac4471e83ff66cf696e5419024d1606276" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sha2" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b69f9a4c9740d74c5baa3fd2e547f9525fa8088a8a958e0ca2409a514e33f5fa" +dependencies = [ + "block-buffer", + "cfg-if", + "cpufeatures", + "digest", + "opaque-debug", +] + +[[package]] +name = "signature" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2807892cfa58e081aa1f1111391c7a0649d4fa127a4ffbe34bcbfb35a1171a4" +dependencies = [ + "digest", + "rand_core 0.6.3", +] + +[[package]] +name = "spki" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c01a0c15da1b0b0e1494112e7af814a678fec9bd157881b49beac661e9b6f32" +dependencies = [ + "der", +] + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "syn" +version = "1.0.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecb2e6da8ee5eb9a61068762a32fa9619cc591ceb055b3687f4cd4051ec2e06b" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "synstructure" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "unicode-xid", +] + +[[package]] +name = "typenum" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "universal-hash" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + +[[package]] +name = "x25519-dalek" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2392b6b94a576b4e2bf3c5b2757d63f10ada8020a2e4d08ac849ebcf6ea8e077" +dependencies = [ + "curve25519-dalek", + "rand_core 0.5.1", + "zeroize", +] + +[[package]] +name = "x3dh-ke" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ee8f59e7095cfd040618f328897c4b07925933de33b517949a64bc97b9fcde3" +dependencies = [ + "base64ct", + "bincode", + "const-oid", + "getrandom", + "hkdf", + "p256", + "rand_core 0.6.3", + "serde", + "serde_bytes", + "sha2", +] + +[[package]] +name = "zeroize" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65f1a51723ec88c66d5d1fe80c841f17f63587d6691901d66be9bec6c3b51f73" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] diff --git a/kem/Cargo.toml b/kem/Cargo.toml new file mode 100644 index 000000000..0d3c3d6af --- /dev/null +++ b/kem/Cargo.toml @@ -0,0 +1,41 @@ +[package] +name = "kem" +description = "Traits for key encapsulation mechanisms" +version = "0.1.0" +authors = ["RustCrypto Developers"] +license = "Apache-2.0 OR MIT" +documentation = "https://docs.rs/kem" +repository = "https://github.com/RustCrypto/traits/tree/master/kem" +readme = "README.md" +edition = "2021" +keywords = ["crypto"] +categories = ["cryptography", "no-std"] + +# Hack to allow this crate to coexist with pre-2021 edition crates +[workspace] +members = ["."] + +[dependencies] +rand_core = "0.6" +generic-array = "0.14" + +[dev-dependencies] +rand = { version = "0.8", features = [ "getrandom" ] } +x3dh-ke = "0.1" +p256 = { version = "0.9", features = [ "ecdsa" ] } +pqcrypto = { version = "0.14", default-features = false, features = [ "pqcrypto-saber" ] } +pqcrypto-traits = "0.3" + +[dev-dependencies.hpke] +git = "https://github.com/rozbb/rust-hpke" +rev = "3c795445f38317d6a0868259caf3e87916548356" +default-features = false +features = [ "x25519" ] + +[features] +default = [] +std = [] + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] diff --git a/kem/LICENSE-APACHE b/kem/LICENSE-APACHE new file mode 100644 index 000000000..7a88b44dc --- /dev/null +++ b/kem/LICENSE-APACHE @@ -0,0 +1,13 @@ +Copyright 2021 RustCrypto Developers + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/kem/LICENSE-MIT b/kem/LICENSE-MIT new file mode 100644 index 000000000..fd43f17de --- /dev/null +++ b/kem/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2018-2021 RustCrypto Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/kem/README.md b/kem/README.md new file mode 100644 index 000000000..9c4a8c876 --- /dev/null +++ b/kem/README.md @@ -0,0 +1,62 @@ +# RustCrypto: Key Encapsulation Mechanisms + +[![crate][crate-image]][crate-link] +[![Docs][docs-image]][docs-link] +![Apache2/MIT licensed][license-image] +![Rust Version][rustc-image] +[![Project Chat][chat-image]][chat-link] +[![Build Status][build-image]][build-link] + +This crate provides a common set of traits for [key encapsulation mechanisms][1]—algorithms for non-interactively establishing secrets between peers. This is intended to be implemented by libraries which produce or contain implementations of key encapsulation mechanisms, and used by libraries which want to produce or consume encapsulated secrets while generically supporting any compatible backend. + +The crate exposes four traits, `Encapsulator`, `Decapsulator`, `AuthEncapsulator`, and `AuthDecapsulator`. These traits represent the ability to initiate a key exchange and complete a key exchange, in the case where the sender is authenticated to the receiver and in the case where the sender is not. + +[Documentation][docs-link] + +## Minimum Supported Rust Version + +Rust **1.56** or higher. + +Minimum supported Rust version can be changed in the future, but it will be +done with a minor version bump. + +## SemVer Policy + +- All on-by-default features of this library are covered by SemVer +- MSRV is considered exempt from SemVer as noted above +- The off-by-default features `derive-preview` and `digest-preview` are + unstable "preview" features which are also considered exempt from SemVer. + Breaking changes to these features will, like MSRV, be done with a minor + version bump. + +## License + +Licensed under either of + + * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) + * [MIT license](http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall be +dual licensed as above, without any additional terms or conditions. + +[//]: # (badges) + +[crate-image]: https://img.shields.io/crates/v/kem.svg +[crate-link]: https://crates.io/crates/kem +[docs-image]: https://docs.rs/kem/badge.svg +[docs-link]: https://docs.rs/kem/ +[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg +[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg +[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260048-signatures +[build-image]: https://github.com/RustCrypto/traits/workflows/kem/badge.svg?branch=master&event=push +[build-link]: https://github.com/RustCrypto/traits/actions?query=workflow%3Akem + +[//]: # (general links) + +[1]: https://en.wikipedia.org/wiki/Key_encapsulation diff --git a/kem/src/errors.rs b/kem/src/errors.rs new file mode 100644 index 000000000..1cef35add --- /dev/null +++ b/kem/src/errors.rs @@ -0,0 +1,17 @@ +//! KEM error types + +use core::fmt::{Debug, Display}; + +/// Represents KEM errors. This is intentionally opaque to avoid leaking information about private +/// keys through side channels. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct Error; + +impl Display for Error { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "error encapsulating or decapsulating") + } +} + +#[cfg(feature = "std")] +impl std::error::Error for Error {} diff --git a/kem/src/kem.rs b/kem/src/kem.rs new file mode 100644 index 000000000..193eaadf3 --- /dev/null +++ b/kem/src/kem.rs @@ -0,0 +1,55 @@ +//! KEM Traits + +use crate::errors::Error; +use core::fmt::Debug; +use generic_array::{ArrayLength, GenericArray}; + +use rand_core::{CryptoRng, RngCore}; + +/// Trait impl'd by concrete types that represent an encapsulated key. This is intended to be, in +/// essence, a bag of bytes. +pub trait EncappedKey: AsRef<[u8]> + Debug + Sized { + /// The size of the shared secret that this KEM produces + type NSecret: ArrayLength; + + /// Represents the identity key of an encapsulator. This is used in authenticated + /// decapsulation. + type SenderPublicKey; + + /// The public key of a decapsulator. This is used in encapsulation. + type RecipientPublicKey; +} + +/// Represents the functionality of a key encapsulator. For unauthenticated encapsulation, `Self` +/// can be an empty struct. For authenticated encapsulation, `Self` is a private key. +pub trait Encapsulator { + /// Attempt to encapsulate a fresh shared secret with the given recipient. The resulting shared + /// secret is bound to the identity encoded in `Self` (i.e., authenticated wrt `Self`). If + /// `Self` is empty, then this is equivalent to unauthenticated encapsulation. Returns the + /// shared secret and encapsulated key on success, or an error if something went wrong. + fn try_encap( + &self, + csprng: &mut R, + recip_pubkey: &EK::RecipientPublicKey, + ) -> Result<(EK, GenericArray), Error>; +} + +/// Represents the functionality of a key decapsulator, where `Self` is a cryptographic key +pub trait Decapsulator { + /// Attempt to decapsulate the given encapsulated key. Returns the shared secret on success, or + /// an error if something went wrong. + fn try_decap(&self, encapped_key: &EK) -> Result, Error>; +} + +/// Represents the functionality of a authenticated-key decapsulator, where `Self` is a +/// cryptographic key +pub trait AuthDecapsulator { + /// Attempt to decapsulate the given encapsulated key. The resulting shared secret is bound to + /// the provided sender identity, thus providing authenticity. Returns the shared secret + /// success, or an error if something went wrong. + fn try_auth_decap( + &self, + encapped_key: &EK, + sender_pubkey: &EK::SenderPublicKey, + ) -> Result, Error>; +} diff --git a/kem/src/lib.rs b/kem/src/lib.rs new file mode 100644 index 000000000..8ba35a1ed --- /dev/null +++ b/kem/src/lib.rs @@ -0,0 +1,19 @@ +#![doc = include_str!("../README.md")] +#![no_std] +#![cfg_attr(docsrs, feature(doc_cfg))] +#![doc( + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", + html_root_url = "https://docs.rs/kem" +)] +#![forbid(unsafe_code)] +#![warn(missing_docs, unused_qualifications)] + +#[cfg(feature = "std")] +extern crate std; + +mod errors; +mod kem; + +pub use crate::{errors::*, kem::*}; +pub use generic_array; diff --git a/kem/tests/hpke.rs b/kem/tests/hpke.rs new file mode 100644 index 000000000..e287038ec --- /dev/null +++ b/kem/tests/hpke.rs @@ -0,0 +1,145 @@ +use generic_array::GenericArray; +use hpke::{ + kem::{Kem as KemTrait, X25519HkdfSha256}, + Deserializable as HpkeDeserializable, Serializable as HpkeSerializable, +}; +use kem::{AuthDecapsulator, Decapsulator, EncappedKey, Encapsulator, Error}; +use rand::rngs::OsRng; +use rand_core::{CryptoRng, RngCore}; + +// Define the pubkey type. This has no trait bounds required by the library +#[derive(Clone)] +struct X25519PublicKey(::PublicKey); + +// Define the encapsulated key type and impl the necessary traits. Since authenticated and +// unauthenticated DHKEMs have the same encapped key type, this will support both types of +// algorithms. In practice, one should use types to distinguish between the two. But this is just +// test code, so whatever. +#[derive(Debug)] +struct X25519EncappedKey( + // It's just an array of bytes + GenericArray::EncappedKey as HpkeSerializable>::OutputSize>, +); +impl EncappedKey for X25519EncappedKey { + type NSecret = ::NSecret; + // In HPKE the only recipient public key is the identity key + type RecipientPublicKey = X25519PublicKey; + // The sender's pubkey is the identity too + type SenderPublicKey = X25519PublicKey; +} +impl AsRef<[u8]> for X25519EncappedKey { + fn as_ref(&self) -> &[u8] { + &self.0 + } +} + +// Define some convenience types +type X25519PrivateKey = ::PrivateKey; +type SharedSecret = GenericArray::NSecret>; + +// Define an authenticated encapsulator. To authenticate, we need a full sender keypair. +struct X25519AuthEncap(X25519PrivateKey, X25519PublicKey); +impl Encapsulator for X25519AuthEncap { + fn try_encap( + &self, + csprng: &mut R, + recip_pubkey: &X25519PublicKey, + ) -> Result<(X25519EncappedKey, SharedSecret), Error> { + ::encap(&recip_pubkey.0, Some((&self.0, &(self.1).0)), csprng) + .map(|(ss, ek)| (X25519EncappedKey(ek.to_bytes()), ss.0)) + .map_err(|_| Error) + } +} + +// Define an unauthenticated encapsulator. This doesn't need any state at all. +struct X25519Encap; +impl Encapsulator for X25519Encap { + fn try_encap( + &self, + csprng: &mut R, + recip_pubkey: &X25519PublicKey, + ) -> Result<(X25519EncappedKey, SharedSecret), Error> { + ::encap(&recip_pubkey.0, None, csprng) + .map(|(ss, ek)| (X25519EncappedKey(ek.to_bytes()), ss.0)) + .map_err(|_| Error) + } +} + +// Define an decapsulator. Since authenticated and unauthenticated encapped keys are represented by +// the same type (which, outside of testing, should not be the case), this can do both auth'd and +// unauth'd decapsulation. +impl Decapsulator for X25519PrivateKey { + fn try_decap(&self, encapped_key: &X25519EncappedKey) -> Result { + // First parse the encapped key, since it's just bytes right now + let deserialized_encapped_key = + <::EncappedKey as HpkeDeserializable>::from_bytes( + &encapped_key.0, + ) + .map_err(|_| Error)?; + + // Now decapsulate + ::decap(self, None, &deserialized_encapped_key) + .map(|ss| ss.0) + .map_err(|_| Error) + } +} +impl AuthDecapsulator for X25519PrivateKey { + fn try_auth_decap( + &self, + encapped_key: &X25519EncappedKey, + sender_pubkey: &X25519PublicKey, + ) -> Result { + // First parse the encapped key, since it's just bytes right now + let deserialized_encapped_key = + <::EncappedKey as HpkeDeserializable>::from_bytes( + &encapped_key.0, + ) + .map_err(|_| Error)?; + + // Now decapsulate + ::decap( + self, + Some(&sender_pubkey.0), + &deserialized_encapped_key, + ) + .map(|ss| ss.0) + .map_err(|_| Error) + } +} + +// A simple wrapper around the keypair generation function +fn gen_keypair(csprng: &mut R) -> (X25519PrivateKey, X25519PublicKey) { + let (sk, pk) = X25519HkdfSha256::gen_keypair(csprng); + let wrapped_pk = X25519PublicKey(pk); + + (sk, wrapped_pk) +} + +#[test] +fn test_hpke() { + let mut rng = OsRng; + + // Make a sender and recipient keypair + let (sk_sender, pk_sender) = gen_keypair(&mut rng); + let (sk_recip, pk_recip) = gen_keypair(&mut rng); + + // Try an unauthed encap first. Check that the derived shared secrets are equal + let encapper = X25519Encap; + let (ek, ss1) = encapper.try_encap(&mut rng, &pk_recip).unwrap(); + let ss2 = sk_recip.try_decap(&ek).unwrap(); + assert_eq!(ss1, ss2); + + // Now do an authenticated encap + let encapper = X25519AuthEncap(sk_sender, pk_sender.clone()); + let (ek, ss1) = encapper.try_encap(&mut rng, &pk_recip).unwrap(); + let ss2 = sk_recip.try_auth_decap(&ek, &pk_sender).unwrap(); + assert_eq!(ss1, ss2); + + // Now do an invalid authenticated encap, where the sender uses the wrong private key. This + // should produce unequal shared secrets. + let (rand_sk, _) = gen_keypair(&mut rng); + let encapper = X25519AuthEncap(rand_sk, pk_sender.clone()); + let (ek, ss1) = encapper.try_encap(&mut rng, &pk_recip).unwrap(); + let ss2 = sk_recip.try_auth_decap(&ek, &pk_sender).unwrap(); + assert_ne!(ss1, ss2); +} diff --git a/kem/tests/saber.rs b/kem/tests/saber.rs new file mode 100644 index 000000000..b4229e912 --- /dev/null +++ b/kem/tests/saber.rs @@ -0,0 +1,72 @@ +use generic_array::{typenum::U32, GenericArray}; +use kem::{Decapsulator, EncappedKey, Encapsulator, Error}; +use pqcrypto::kem::firesaber::{ + decapsulate, encapsulate, keypair, Ciphertext, PublicKey, SecretKey, +}; +use pqcrypto_traits::kem::{Ciphertext as CiphertextTrait, SharedSecret as SharedSecretTrait}; +use rand::rngs::OsRng; +use rand_core::{CryptoRng, RngCore}; + +// Define the pubkey type. This has no trait bounds required by the library +type SaberPublicKey = PublicKey; + +// The encapped key type is called "Ciphertext" in Rust's pqcrypto. Impl the necessary traits. +struct SaberEncappedKey(Ciphertext); +impl EncappedKey for SaberEncappedKey { + type NSecret = U32; + // In HPKE the only recipient public key is the identity key + type RecipientPublicKey = SaberPublicKey; + // The sender's pubkey is the identity too + type SenderPublicKey = SaberPrivateKey; +} +impl AsRef<[u8]> for SaberEncappedKey { + fn as_ref(&self) -> &[u8] { + self.0.as_bytes() + } +} +impl core::fmt::Debug for SaberEncappedKey { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{:x?}", self.as_ref()) + } +} + +// Define some convenience types +type SaberSharedSecret = GenericArray::NSecret>; +type SaberPrivateKey = SecretKey; + +// Define an unauthenticated encapsulator. It holds nothing at all +struct SaberEncapper; +impl Encapsulator for SaberEncapper { + fn try_encap( + &self, + _csprng: &mut R, + recip_pubkey: &SaberPublicKey, + ) -> Result<(SaberEncappedKey, SaberSharedSecret), Error> { + let (ss, ek) = encapsulate(recip_pubkey); + let ss_bytes = SaberSharedSecret::clone_from_slice(ss.as_bytes()); + + Ok((SaberEncappedKey(ek), ss_bytes)) + } +} + +// Define a decapsulator +impl Decapsulator for SaberPrivateKey { + fn try_decap(&self, encapped_key: &SaberEncappedKey) -> Result { + let ss = decapsulate(&encapped_key.0, self); + Ok(SaberSharedSecret::clone_from_slice(ss.as_bytes())) + } +} + +#[test] +fn test_saber() { + let mut rng = OsRng; + + // Make a recipient keypair + let (pk_recip, sk_recip) = keypair(); + + // Do an unauthed encap. Check that the derived shared secrets are equal + let encapper = SaberEncapper; + let (ek, ss1) = encapper.try_encap(&mut rng, &pk_recip).unwrap(); + let ss2 = sk_recip.try_decap(&ek).unwrap(); + assert_eq!(ss1, ss2); +} diff --git a/kem/tests/x3dh.rs b/kem/tests/x3dh.rs new file mode 100644 index 000000000..23af60c29 --- /dev/null +++ b/kem/tests/x3dh.rs @@ -0,0 +1,141 @@ +use generic_array::{typenum::U32, GenericArray}; +use kem::{AuthDecapsulator, EncappedKey, Encapsulator, Error}; +use p256::ecdsa::Signature; +use rand::rngs::OsRng; +use rand_core::{CryptoRng, RngCore}; +use x3dh_ke::{x3dh_a, x3dh_b, EphemeralKey, IdentityKey, Key, OneTimePreKey, SignedPreKey}; + +// The size of an encapped key +const P256_POINT_SIZE: usize = 231; + +// Define the sender pubkey type. This is an identity key; +type X3DhSenderPublicKey = IdentityKey; +// Define the recipient privkey type. This is a bundle of 3 privkeys of different lifespans +struct X3DhPrivkeyBundle { + ik: IdentityKey, + spk: SignedPreKey, + sig: Signature, + opk: OneTimePreKey, +} +impl X3DhPrivkeyBundle { + fn gen() -> X3DhPrivkeyBundle { + let ik = IdentityKey::default(); + let spk = SignedPreKey::default(); + let sig = ik.sign(&spk.pk_to_bytes()); + let opk = OneTimePreKey::default(); + X3DhPrivkeyBundle { ik, spk, sig, opk } + } + fn as_pubkeys(&self) -> X3DhPubkeyBundle { + X3DhPubkeyBundle { + ik: self.ik.strip(), + spk: self.spk.strip(), + opk: self.opk.strip(), + sig: self.sig, + } + } +} +// The pubkeys keys associated with a privkey bundle. In x3dh-ke, all the keys serve as both +// pubkeys and privkeys. This seems dangerous but hey this isn't prod. +type X3DhPubkeyBundle = X3DhPrivkeyBundle; + +// The encapped key is just the byte repr of an ephemeral key. Impl the appropriate traits +#[derive(Debug)] +struct X3DhEncappedKey([u8; P256_POINT_SIZE]); +impl EncappedKey for X3DhEncappedKey { + type NSecret = U32; + type SenderPublicKey = X3DhSenderPublicKey; + type RecipientPublicKey = X3DhPubkeyBundle; +} +impl AsRef<[u8]> for X3DhEncappedKey { + fn as_ref(&self) -> &[u8] { + &self.0 + } +} + +// The private key of an authenticated sender is just their identity key. Again, this is the same +// type as the pubkey. +type X3DhSenderPrivateKey = IdentityKey; +type SharedSecret = GenericArray::NSecret>; + +// Define an authenticated encapsulator. To authenticate, we need a full sender keypair. +impl Encapsulator for X3DhSenderPrivateKey { + fn try_encap( + &self, + _csprng: &mut R, + recip_pubkey: &X3DhPubkeyBundle, + ) -> Result<(X3DhEncappedKey, SharedSecret), Error> { + // Make a new ephemeral key. This will be the encapped key + let ek = EphemeralKey::default(); + // Deconstruct the recipient's pubkey bundle + let X3DhPubkeyBundle { ik, spk, sig, opk } = recip_pubkey; + + // Do the X3DH operation to get the shared secret + let shared_secret = x3dh_a(sig, self, spk, &ek, ik, opk) + .map(|ss| SharedSecret::clone_from_slice(&ss)) + .map_err(|e| { + println!("err {:?}", e); + Error + })?; + // Serialize the ephemeral key + let encapped_key = { + let mut buf = [0u8; P256_POINT_SIZE]; + buf.copy_from_slice(&ek.to_bytes()); + X3DhEncappedKey(buf) + }; + + Ok((encapped_key, shared_secret)) + } +} + +// Define an decapsulator. Since authenticated and unauthenticated encapped keys are represented by +// the same type (which, outside of testing, should not be the case), this can do both auth'd and +// unauth'd decapsulation. +impl AuthDecapsulator for X3DhPrivkeyBundle { + fn try_auth_decap( + &self, + encapped_key: &X3DhEncappedKey, + sender_pubkey: &X3DhSenderPublicKey, + ) -> Result { + // First parse the encapped key, since it's just bytes right now + let deserialized_ek = EphemeralKey::from_bytes(&encapped_key.0).map_err(|_| Error)?; + // Deconstruct our private keys bundle + let X3DhPubkeyBundle { + ik, + spk, + sig: _, + opk, + } = self; + + // Now decapsulate + let buf = x3dh_b(sender_pubkey, spk, &deserialized_ek, ik, opk); + Ok(SharedSecret::clone_from_slice(&buf)) + } +} + +#[test] +fn test_x3dh() { + let mut rng = OsRng; + + // We use _a and _b suffixes to denote whether a key belongs to Alice or Bob. Alice is the + // sender in this case. + let sk_ident_a = X3DhSenderPrivateKey::default(); + let pk_ident_a = sk_ident_a.strip(); + let sk_bundle_b = X3DhPrivkeyBundle::gen(); + let pk_bundle_b = sk_bundle_b.as_pubkeys(); + + // Now do an authenticated encap + let (encapped_key, ss1) = sk_ident_a.try_encap(&mut rng, &pk_bundle_b).unwrap(); + let ss2 = sk_bundle_b + .try_auth_decap(&encapped_key, &pk_ident_a) + .unwrap(); + assert_eq!(ss1, ss2); + + // Now do an invalid authenticated encap, where the sender uses the wrong private key. This + // should produce unequal shared secrets. + let sk_ident_rando = X3DhSenderPrivateKey::default(); + let (encapped_key, ss1) = sk_ident_rando.try_encap(&mut rng, &pk_bundle_b).unwrap(); + let ss2 = sk_bundle_b + .try_auth_decap(&encapped_key, &pk_ident_a) + .unwrap(); + assert_ne!(ss1, ss2); +} From a84630d6088bf59d23dd3911c3e0bed05f22356f Mon Sep 17 00:00:00 2001 From: Alexander Wagner Date: Mon, 3 Jan 2022 15:52:37 +0100 Subject: [PATCH 0687/1461] digest: Fix typo in docs (#858) --- digest/src/lib.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 7aa346e39..b896bb910 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -8,9 +8,8 @@ //! usually prefer using these traits. //! - **Mid-level traits**: [`Update`], [`FixedOutput`], [`FixedOutputReset`], //! [`ExtendableOutput`], [`ExtendableOutputReset`], [`XofReader`], -//! [`VariableOutput`], [`VariableOutput`], [`Reset`], [`KeyInit`], and -//! [`InnerInit`]. These traits atomically describe available functionality -//! of an algorithm. +//! [`VariableOutput`], [`Reset`], [`KeyInit`], and [`InnerInit`]. These +//! traits atomically describe available functionality of an algorithm. //! - **Marker traits**: [`HashMarker`], [`MacMarker`]. Used to distinguish //! different algorithm classes. //! - **Low-level traits** defined in the [`core_api`] module. These traits From 726537b9389120e2f8ca86b60e572f6583d32c91 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 3 Jan 2022 09:04:28 -0700 Subject: [PATCH 0688/1461] kem: minor fixups (#859) - Bump `version` down to 0.0.0 as it hasn't been released - Add `rust-version` to Cargo.toml - Fix MSRV badge in README.md --- kem/Cargo.lock | 2 +- kem/Cargo.toml | 3 ++- kem/README.md | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/kem/Cargo.lock b/kem/Cargo.lock index a23a8f240..cac1ac80b 100644 --- a/kem/Cargo.lock +++ b/kem/Cargo.lock @@ -330,7 +330,7 @@ dependencies = [ [[package]] name = "kem" -version = "0.1.0" +version = "0.0.0" dependencies = [ "generic-array", "hpke", diff --git a/kem/Cargo.toml b/kem/Cargo.toml index 0d3c3d6af..4611f6a4c 100644 --- a/kem/Cargo.toml +++ b/kem/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "kem" description = "Traits for key encapsulation mechanisms" -version = "0.1.0" +version = "0.0.0" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/kem" @@ -10,6 +10,7 @@ readme = "README.md" edition = "2021" keywords = ["crypto"] categories = ["cryptography", "no-std"] +rust-version = "1.56" # Hack to allow this crate to coexist with pre-2021 edition crates [workspace] diff --git a/kem/README.md b/kem/README.md index 9c4a8c876..db87bb2dd 100644 --- a/kem/README.md +++ b/kem/README.md @@ -51,7 +51,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/kem/badge.svg [docs-link]: https://docs.rs/kem/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.41+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.56+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260048-signatures [build-image]: https://github.com/RustCrypto/traits/workflows/kem/badge.svg?branch=master&event=push From 4df5d995c9dbb3e76910c1eeae1fac50efa9b2e4 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 3 Jan 2022 09:13:19 -0700 Subject: [PATCH 0689/1461] kem v0.1.0 (#860) --- kem/CHANGELOG.md | 5 ++--- kem/Cargo.lock | 2 +- kem/Cargo.toml | 2 +- kem/LICENSE-MIT | 2 +- kem/README.md | 5 +++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/kem/CHANGELOG.md b/kem/CHANGELOG.md index ba69d0b88..07beeed89 100644 --- a/kem/CHANGELOG.md +++ b/kem/CHANGELOG.md @@ -4,6 +4,5 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 0.0.1 (2021-12-13) - -- Initial commit +## 0.1.0 (2022-01-03) +- Initial release diff --git a/kem/Cargo.lock b/kem/Cargo.lock index cac1ac80b..a23a8f240 100644 --- a/kem/Cargo.lock +++ b/kem/Cargo.lock @@ -330,7 +330,7 @@ dependencies = [ [[package]] name = "kem" -version = "0.0.0" +version = "0.1.0" dependencies = [ "generic-array", "hpke", diff --git a/kem/Cargo.toml b/kem/Cargo.toml index 4611f6a4c..50d87a483 100644 --- a/kem/Cargo.toml +++ b/kem/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "kem" description = "Traits for key encapsulation mechanisms" -version = "0.0.0" +version = "0.1.0" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/kem" diff --git a/kem/LICENSE-MIT b/kem/LICENSE-MIT index fd43f17de..a2b36f25c 100644 --- a/kem/LICENSE-MIT +++ b/kem/LICENSE-MIT @@ -1,4 +1,4 @@ -Copyright (c) 2018-2021 RustCrypto Developers +Copyright (c) 2021-2022 RustCrypto Developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated diff --git a/kem/README.md b/kem/README.md index db87bb2dd..b989278a7 100644 --- a/kem/README.md +++ b/kem/README.md @@ -1,4 +1,4 @@ -# RustCrypto: Key Encapsulation Mechanisms +# [RustCrypto]: Key Encapsulation Mechanisms (KEMs) [![crate][crate-image]][crate-link] [![Docs][docs-image]][docs-link] @@ -57,6 +57,7 @@ dual licensed as above, without any additional terms or conditions. [build-image]: https://github.com/RustCrypto/traits/workflows/kem/badge.svg?branch=master&event=push [build-link]: https://github.com/RustCrypto/traits/actions?query=workflow%3Akem -[//]: # (general links) +[//]: # (links) +[RustCrypto]: https://github.com/RustCrypto [1]: https://en.wikipedia.org/wiki/Key_encapsulation From 65c2cb7db611b4934f97b60496c618ca553125da Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 3 Jan 2022 09:18:49 -0700 Subject: [PATCH 0690/1461] README.md: add `kem` crate (#861) --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 05f79cd19..a52c945da 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ Collection of traits which describe functionality of cryptographic primitives. | [`crypto‑common`] | Common cryptographic traits | [![crates.io](https://img.shields.io/crates/v/crypto-common.svg)](https://crates.io/crates/crypto-common) | [![Documentation](https://docs.rs/crypto-common/badge.svg)](https://docs.rs/crypto-common) | ![MSRV 1.41][msrv-1.41] | | [`digest`] | [Cryptographic hash function] | [![crates.io](https://img.shields.io/crates/v/digest.svg)](https://crates.io/crates/digest) | [![Documentation](https://docs.rs/digest/badge.svg)](https://docs.rs/digest) | ![MSRV 1.41][msrv-1.41] | | [`elliptic‑curve`] | [Elliptic curve cryptography] | [![crates.io](https://img.shields.io/crates/v/elliptic-curve.svg)](https://crates.io/crates/elliptic-curve) | [![Documentation](https://docs.rs/elliptic-curve/badge.svg)](https://docs.rs/elliptic-curve) | ![MSRV 1.56][msrv-1.56] | +| [`kem`] | [Key encapsulation mechanism] | [![crates.io](https://img.shields.io/crates/v/kem.svg)](https://crates.io/crates/kem) | [![Documentation](https://docs.rs/kem/badge.svg)](https://docs.rs/kem) | ![MSRV 1.56][msrv-1.56] | | [`password-hash`] | [Password hashing] | [![crates.io](https://img.shields.io/crates/v/password-hash.svg)](https://crates.io/crates/password-hash) | [![Documentation](https://docs.rs/password-hash/badge.svg)](https://docs.rs/password-hash) | ![MSRV 1.47][msrv-1.47] | | [`signature`] | [Digital signature] | [![crates.io](https://img.shields.io/crates/v/signature.svg)](https://crates.io/crates/signature) | [![Documentation](https://docs.rs/signature/badge.svg)](https://docs.rs/signature) | ![MSRV 1.41][msrv-1.41] | | [`universal‑hash`] | [Universal hash function] | [![crates.io](https://img.shields.io/crates/v/universal-hash.svg)](https://crates.io/crates/universal-hash) | [![Documentation](https://docs.rs/universal-hash/badge.svg)](https://docs.rs/universal-hash) | ![MSRV 1.41][msrv-1.41] | @@ -61,6 +62,7 @@ Unless you explicitly state otherwise, any contribution intentionally submitted [`crypto`]: ./crypto [`digest`]: ./digest [`elliptic‑curve`]: ./elliptic-curve +[`kem`]: ./kem [`password-hash`]: ./password-hash [`signature`]: ./signature [`universal‑hash`]: ./universal-hash @@ -73,6 +75,7 @@ Unless you explicitly state otherwise, any contribution intentionally submitted [Cryptographic hash function]: https://en.wikipedia.org/wiki/Cryptographic_hash_function [Digital signature]: https://en.wikipedia.org/wiki/Digital_signature [Elliptic curve cryptography]: https://en.wikipedia.org/wiki/Elliptic-curve_cryptography +[Key encapsulation mechanism]: https://en.wikipedia.org/wiki/Key_encapsulation [Password hashing]: https://en.wikipedia.org/wiki/Cryptographic_hash_function#Password_verification [Stream cipher]: https://en.wikipedia.org/wiki/Stream_cipher [Universal hash function]: https://en.wikipedia.org/wiki/Universal_hashing From 432a96491c4c6ea70fe9a79ad8ba437d189f0483 Mon Sep 17 00:00:00 2001 From: Michael Lodder Date: Mon, 3 Jan 2022 09:20:26 -0700 Subject: [PATCH 0691/1461] feat: add hash to field (#855) Signed-off-by: Michael Lodder --- elliptic-curve/Cargo.lock | 42 ++++++----- elliptic-curve/Cargo.toml | 2 + elliptic-curve/src/hash2field.rs | 33 +++++++++ elliptic-curve/src/hash2field/expand_msg.rs | 5 ++ .../src/hash2field/expand_msg_xmd.rs | 72 +++++++++++++++++++ .../src/hash2field/expand_msg_xof.rs | 27 +++++++ elliptic-curve/src/lib.rs | 6 ++ 7 files changed, 171 insertions(+), 16 deletions(-) create mode 100644 elliptic-curve/src/hash2field.rs create mode 100644 elliptic-curve/src/hash2field/expand_msg.rs create mode 100644 elliptic-curve/src/hash2field/expand_msg_xmd.rs create mode 100644 elliptic-curve/src/hash2field/expand_msg_xof.rs diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index 9352ce4cd..812bece07 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "base64ct" -version = "1.2.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "392c772b012d685a640cdad68a5a21f4a45e696f85a2c2c907aab2fe49a91e19" +checksum = "a30f9c631ae8b97868a2e841015b72f2c99b05e3f03a14d543b843816a0a5b4d" [[package]] name = "bitvec" @@ -28,9 +28,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "const-oid" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d355758f44afa81c21e66e1301d47cbffbbcde4b405cbe46b8b19f213abf9f60" +checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" [[package]] name = "crypto-bigint" @@ -54,6 +54,15 @@ dependencies = [ "pem-rfc7468", ] +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + [[package]] name = "elliptic-curve" version = "0.11.6" @@ -61,6 +70,7 @@ dependencies = [ "base64ct", "crypto-bigint", "der", + "digest", "ff", "generic-array", "group", @@ -131,15 +141,15 @@ checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" [[package]] name = "itoa" -version = "0.4.8" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" +checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" [[package]] name = "libc" -version = "0.2.107" +version = "0.2.112" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbe5e23404da5b4f555ef85ebed98fb4083e55a00c317800bc2a50ede9f3d219" +checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" [[package]] name = "pem-rfc7468" @@ -178,9 +188,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.5" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" [[package]] name = "sec1" @@ -197,15 +207,15 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.130" +version = "1.0.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" +checksum = "8b9875c23cf305cd1fd7eb77234cbb705f21ea6a72c637a5c6db5fe4b8e7f008" [[package]] name = "serde_json" -version = "1.0.71" +version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "063bf466a64011ac24040a49009724ee60a57da1b437617ceb32e53ad61bfb19" +checksum = "bcbd0344bc6533bc7ec56df11d42fb70f1b912351c0825ccb7211b59d8af7cf5" dependencies = [ "itoa", "ryu", @@ -214,9 +224,9 @@ dependencies = [ [[package]] name = "spki" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8a277a21925310de1d31bb6b021da3550b00e9127096ef84ee38f44609925c4" +checksum = "964d3a6f8b7ef6d6d20887f4c30c4848f4ffa05f600c87277d30a5b4fe32cb4b" dependencies = [ "base64ct", "der", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 848b3e5d0..242ce3452 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -29,6 +29,7 @@ zeroize = { version = "1", default-features = false } # optional dependencies base64ct = { version = "1", optional = true, default-features = false } +digest = { version = "0.9", optional = true, default-features = false } ff = { version = "0.11", optional = true, default-features = false } group = { version = "0.11", optional = true, default-features = false } hex-literal = { version = "0.3", optional = true } @@ -47,6 +48,7 @@ arithmetic = ["ff", "group"] bits = ["arithmetic", "ff/bits"] dev = ["arithmetic", "hex-literal", "pem", "pkcs8"] ecdh = ["arithmetic"] +hashing = ["digest"] hazmat = [] jwk = ["alloc", "base64ct/alloc", "serde", "serde_json", "zeroize/alloc"] osswu = ["ff"] diff --git a/elliptic-curve/src/hash2field.rs b/elliptic-curve/src/hash2field.rs new file mode 100644 index 000000000..a68a06edc --- /dev/null +++ b/elliptic-curve/src/hash2field.rs @@ -0,0 +1,33 @@ +mod expand_msg; +mod expand_msg_xmd; +mod expand_msg_xof; + +use core::convert::TryFrom; +pub use expand_msg::*; +pub use expand_msg_xmd::*; +pub use expand_msg_xof::*; + +/// The trait for helping to convert to a scalar +pub trait FromOkm: Sized { + /// Convert a byte sequence into a scalar + fn from_okm(data: &[u8; L]) -> Self; +} + +/// Convert an arbitrary byte sequence according to +/// +pub fn hash_to_field( + data: &[u8], + domain: &[u8], +) -> [T; COUNT] +where + E: ExpandMsg, + T: FromOkm + Default + Copy, +{ + let random_bytes = E::expand_message(data, domain); + let mut out = [T::default(); COUNT]; + for i in 0..COUNT { + let u = <[u8; L]>::try_from(&random_bytes[(L * i)..L * (i + 1)]).expect("not enough bytes"); + out[i] = T::from_okm(&u); + } + out +} diff --git a/elliptic-curve/src/hash2field/expand_msg.rs b/elliptic-curve/src/hash2field/expand_msg.rs new file mode 100644 index 000000000..ba08f98f7 --- /dev/null +++ b/elliptic-curve/src/hash2field/expand_msg.rs @@ -0,0 +1,5 @@ +/// Trait for types implementing expand_message interface for hash_to_field +pub trait ExpandMsg { + /// Expands `msg` to the required number of bytes in `buf` + fn expand_message(msg: &[u8], dst: &[u8]) -> [u8; OUT]; +} diff --git a/elliptic-curve/src/hash2field/expand_msg_xmd.rs b/elliptic-curve/src/hash2field/expand_msg_xmd.rs new file mode 100644 index 000000000..e99f8b6e0 --- /dev/null +++ b/elliptic-curve/src/hash2field/expand_msg_xmd.rs @@ -0,0 +1,72 @@ +use super::ExpandMsg; +use core::marker::PhantomData; +use digest::{ + generic_array::{typenum::Unsigned, GenericArray}, + BlockInput, Digest, +}; +use subtle::{Choice, ConditionallySelectable}; + +/// Placeholder type for implementing expand_message_xmd based on a hash function +#[derive(Debug)] +pub struct ExpandMsgXmd { + phantom: PhantomData, +} + +/// ExpandMsgXmd implements expand_message_xmd for the ExpandMsg trait +impl ExpandMsg for ExpandMsgXmd +where + HashT: Digest + BlockInput, +{ + fn expand_message(msg: &[u8], dst: &[u8]) -> [u8; LEN_IN_BYTES] { + let b_in_bytes = HashT::OutputSize::to_usize(); + let ell = (LEN_IN_BYTES + b_in_bytes - 1) / b_in_bytes; + if ell > 255 { + panic!("ell was too big in expand_message_xmd"); + } + let b_0 = HashT::new() + .chain(GenericArray::::default()) + .chain(msg) + .chain([(LEN_IN_BYTES >> 8) as u8, LEN_IN_BYTES as u8, 0u8]) + .chain(dst) + .chain([dst.len() as u8]) + .finalize(); + + let mut b_vals = HashT::new() + .chain(&b_0[..]) + .chain([1u8]) + .chain(dst) + .chain([dst.len() as u8]) + .finalize(); + + let mut buf = [0u8; LEN_IN_BYTES]; + let mut offset = 0; + + for i in 1..ell { + // b_0 XOR b_(idx - 1) + let mut tmp = GenericArray::::default(); + b_0.iter() + .zip(&b_vals[..]) + .enumerate() + .for_each(|(j, (b0val, bi1val))| tmp[j] = b0val ^ bi1val); + for b in b_vals { + buf[offset % LEN_IN_BYTES].conditional_assign( + &b, + Choice::from(if offset < LEN_IN_BYTES { 1 } else { 0 }), + ); + offset += 1; + } + b_vals = HashT::new() + .chain(tmp) + .chain([(i + 1) as u8]) + .chain(dst) + .chain([dst.len() as u8]) + .finalize(); + } + for b in b_vals { + buf[offset % LEN_IN_BYTES] + .conditional_assign(&b, Choice::from(if offset < LEN_IN_BYTES { 1 } else { 0 })); + offset += 1; + } + buf + } +} diff --git a/elliptic-curve/src/hash2field/expand_msg_xof.rs b/elliptic-curve/src/hash2field/expand_msg_xof.rs new file mode 100644 index 000000000..0ec1df024 --- /dev/null +++ b/elliptic-curve/src/hash2field/expand_msg_xof.rs @@ -0,0 +1,27 @@ +use super::ExpandMsg; +use core::marker::PhantomData; +use digest::{ExtendableOutput, Update, XofReader}; + +/// Placeholder type for implementing expand_message_xof based on an extendable output function +#[derive(Debug)] +pub struct ExpandMsgXof { + phantom: PhantomData, +} + +/// ExpandMsgXof implements expand_message_xof for the ExpandMsg trait +impl ExpandMsg for ExpandMsgXof +where + HashT: Default + ExtendableOutput + Update, +{ + fn expand_message(msg: &[u8], dst: &[u8]) -> [u8; LEN_IN_BYTES] { + let mut buf = [0u8; LEN_IN_BYTES]; + let mut r = HashT::default() + .chain(msg) + .chain([(LEN_IN_BYTES >> 8) as u8, LEN_IN_BYTES as u8]) + .chain(dst) + .chain([dst.len() as u8]) + .finalize_xof(); + r.read(&mut buf); + buf + } +} diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 2131cae74..211bf3ee5 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -99,6 +99,12 @@ mod jwk; #[cfg_attr(docsrs, doc(cfg(feature = "osswu")))] pub mod osswu; +/// Traits for computing hash to field as described in +/// +#[cfg(feature = "hashing")] +#[cfg_attr(docsrs, doc(cfg(feature = "hashing")))] +pub mod hash2field; + pub use crate::{ error::{Error, Result}, point::{ From 43b46ac39b32b4b07c7c5bf14651e9fa120110b7 Mon Sep 17 00:00:00 2001 From: Bogdan Opanchuk Date: Mon, 3 Jan 2022 08:21:07 -0800 Subject: [PATCH 0692/1461] Add impl Mul for NonZeroScalar * NonZeroScalar (#857) --- elliptic-curve/src/scalar/nonzero.rs | 32 +++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/elliptic-curve/src/scalar/nonzero.rs b/elliptic-curve/src/scalar/nonzero.rs index 3ed35358c..8aabd3709 100644 --- a/elliptic-curve/src/scalar/nonzero.rs +++ b/elliptic-curve/src/scalar/nonzero.rs @@ -9,7 +9,7 @@ use crate::{ }; use core::{ fmt, - ops::{Deref, Neg}, + ops::{Deref, Mul, Neg}, str, }; use crypto_bigint::{ArrayEncoding, Integer}; @@ -199,6 +199,36 @@ where } } +impl Mul> for NonZeroScalar +where + C: Curve + ScalarArithmetic, +{ + type Output = Self; + + fn mul(self, other: Self) -> Self { + // Assumes that the multiplication is modulo a prime, + // so the product of two non-zero scalars is also non-zero. + let scalar = self.scalar * other.scalar; + debug_assert!(!bool::from(scalar.is_zero())); + NonZeroScalar { scalar } + } +} + +impl Mul<&NonZeroScalar> for NonZeroScalar +where + C: Curve + ScalarArithmetic, +{ + type Output = Self; + + fn mul(self, other: &Self) -> Self { + // Assumes that the multiplication is modulo a prime, + // so the product of two non-zero scalars is also non-zero. + let scalar = self.scalar * other.scalar; + debug_assert!(!bool::from(scalar.is_zero())); + NonZeroScalar { scalar } + } +} + /// Note: implementation is the same as `ReduceNonZero` impl Reduce for NonZeroScalar where From 1e1ab1da05e2d7480e2aca46c4a381173a968476 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 3 Jan 2022 09:48:10 -0700 Subject: [PATCH 0693/1461] elliptic-curve: fixups for `Mul` impls for `NonZeroScalar` (#862) - Uses a `PrimeCurve` bound to ensure curve is prime order - Composes the owned and borrowed impls of `Mul`, implementing the former in terms of the latter --- elliptic-curve/src/scalar/nonzero.rs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/elliptic-curve/src/scalar/nonzero.rs b/elliptic-curve/src/scalar/nonzero.rs index 8aabd3709..0f38d7cfa 100644 --- a/elliptic-curve/src/scalar/nonzero.rs +++ b/elliptic-curve/src/scalar/nonzero.rs @@ -5,7 +5,8 @@ use crate::{ hex, ops::{Invert, Reduce, ReduceNonZero}, rand_core::{CryptoRng, RngCore}, - Curve, Error, FieldBytes, IsHigh, Result, Scalar, ScalarArithmetic, ScalarCore, SecretKey, + Curve, Error, FieldBytes, IsHigh, PrimeCurve, Result, Scalar, ScalarArithmetic, ScalarCore, + SecretKey, }; use core::{ fmt, @@ -201,28 +202,25 @@ where impl Mul> for NonZeroScalar where - C: Curve + ScalarArithmetic, + C: PrimeCurve + ScalarArithmetic, { type Output = Self; + #[inline] fn mul(self, other: Self) -> Self { - // Assumes that the multiplication is modulo a prime, - // so the product of two non-zero scalars is also non-zero. - let scalar = self.scalar * other.scalar; - debug_assert!(!bool::from(scalar.is_zero())); - NonZeroScalar { scalar } + Self::mul(self, &other) } } impl Mul<&NonZeroScalar> for NonZeroScalar where - C: Curve + ScalarArithmetic, + C: PrimeCurve + ScalarArithmetic, { type Output = Self; fn mul(self, other: &Self) -> Self { - // Assumes that the multiplication is modulo a prime, - // so the product of two non-zero scalars is also non-zero. + // Multiplication is modulo a prime, so the product of two non-zero + // scalars is also non-zero. let scalar = self.scalar * other.scalar; debug_assert!(!bool::from(scalar.is_zero())); NonZeroScalar { scalar } From 0de6d560bfffa11ff6586f9368bff000bb62038a Mon Sep 17 00:00:00 2001 From: Michael Lodder Date: Mon, 3 Jan 2022 11:22:20 -0700 Subject: [PATCH 0694/1461] gate behind hashing => digest (#863) Signed-off-by: Michael Lodder --- elliptic-curve/Cargo.toml | 1 - elliptic-curve/src/lib.rs | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 242ce3452..3249ec1f2 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -48,7 +48,6 @@ arithmetic = ["ff", "group"] bits = ["arithmetic", "ff/bits"] dev = ["arithmetic", "hex-literal", "pem", "pkcs8"] ecdh = ["arithmetic"] -hashing = ["digest"] hazmat = [] jwk = ["alloc", "base64ct/alloc", "serde", "serde_json", "zeroize/alloc"] osswu = ["ff"] diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 211bf3ee5..d6b637f0b 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -101,8 +101,8 @@ pub mod osswu; /// Traits for computing hash to field as described in /// -#[cfg(feature = "hashing")] -#[cfg_attr(docsrs, doc(cfg(feature = "hashing")))] +#[cfg(feature = "digest")] +#[cfg_attr(docsrs, doc(cfg(feature = "digest")))] pub mod hash2field; pub use crate::{ From 96b2eb05f10523a9b6acf03aaf7bac4bccccdb8e Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 4 Jan 2022 22:26:45 -0700 Subject: [PATCH 0695/1461] signature-derive v1.0.0-pre.4 (#866) --- signature/derive/CHANGELOG.md | 10 +- signature/derive/LICENSE-APACHE | 201 ++++++++++++++++++++++++++++++++ signature/derive/LICENSE-MIT | 25 ++++ signature/derive/src/lib.rs | 1 - 4 files changed, 234 insertions(+), 3 deletions(-) create mode 100644 signature/derive/LICENSE-APACHE create mode 100644 signature/derive/LICENSE-MIT diff --git a/signature/derive/CHANGELOG.md b/signature/derive/CHANGELOG.md index 711385824..b7f29fa97 100644 --- a/signature/derive/CHANGELOG.md +++ b/signature/derive/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 1.0.0-pre.4 (2022-01-04) +### Changed +- Support for new `digest` v0.10 API ([#850]) + +[#850]: https://github.com/RustCrypto/traits/pull/850 + ## 1.0.0-pre.3 (2021-01-06) ### Fixed - rustdoc links ([#458]) @@ -18,7 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## 1.0.0-pre.1 (2020-03-08) ### Added -- Initial Changelog for `signature_derive` -- Rustdoc ([#79]) +- Initial changelog for `signature_derive` +- rustdoc ([#79]) [#79]: https://github.com/RustCrypto/traits/pull/79 diff --git a/signature/derive/LICENSE-APACHE b/signature/derive/LICENSE-APACHE new file mode 100644 index 000000000..78173fa2e --- /dev/null +++ b/signature/derive/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/signature/derive/LICENSE-MIT b/signature/derive/LICENSE-MIT new file mode 100644 index 000000000..d874d2e01 --- /dev/null +++ b/signature/derive/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2019-2022 RustCrypto Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/signature/derive/src/lib.rs b/signature/derive/src/lib.rs index fc937f77e..a6c6e7234 100644 --- a/signature/derive/src/lib.rs +++ b/signature/derive/src/lib.rs @@ -4,7 +4,6 @@ //! types that impl `DigestSigner` or `DigestVerifier` respectively. #![crate_type = "proc-macro"] -#![recursion_limit = "128"] #![deny(warnings, unused_import_braces, unused_qualifications)] #![forbid(unsafe_code)] From fc0e7b8fffdd98e71bae4649f4b2b4e6c7c07cd8 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 4 Jan 2022 22:40:58 -0700 Subject: [PATCH 0696/1461] signature v1.5.0 (#867) --- Cargo.lock | 2 +- crypto/Cargo.lock | 2 +- crypto/Cargo.toml | 2 +- signature/CHANGELOG.md | 8 ++++++++ signature/Cargo.toml | 2 +- signature/async/Cargo.toml | 2 +- signature/src/lib.rs | 2 +- 7 files changed, 14 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 72e9e2e0f..e4946cf81 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -258,7 +258,7 @@ dependencies = [ [[package]] name = "signature" -version = "1.5.0-pre" +version = "1.5.0" dependencies = [ "digest 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal", diff --git a/crypto/Cargo.lock b/crypto/Cargo.lock index 7f86ea218..8fbb78819 100644 --- a/crypto/Cargo.lock +++ b/crypto/Cargo.lock @@ -218,7 +218,7 @@ dependencies = [ [[package]] name = "signature" -version = "1.5.0-pre" +version = "1.5.0" [[package]] name = "spki" diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index e85e9abc9..71be1bd64 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -25,7 +25,7 @@ digest = { version = "0.10", optional = true } elliptic-curve = { version = "0.11", optional = true, path = "../elliptic-curve" } mac = { version = "0.11", package = "crypto-mac", optional = true } password-hash = { version = "0.3", optional = true, path = "../password-hash" } -signature = { version = "=1.5.0-pre", optional = true, default-features = false, path = "../signature" } +signature = { version = "1.5", optional = true, default-features = false, path = "../signature" } universal-hash = { version = "0.4", optional = true, path = "../universal-hash" } [features] diff --git a/signature/CHANGELOG.md b/signature/CHANGELOG.md index 3890548c4..bec83106f 100644 --- a/signature/CHANGELOG.md +++ b/signature/CHANGELOG.md @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 1.5.0 (2022-01-04) +### Changed +- Bump `digest` dependency to v0.10 ([#850]) +- Bump `signature-derive` dependency to v1.0.0-pre.4 ([#866]) + +[#850]: https://github.com/RustCrypto/traits/pull/850 +[#866]: https://github.com/RustCrypto/traits/pull/866 + ## 1.4.0 (2021-10-20) ### Added - Re-export `rand_core` when the `rand-preview` feature is enabled ([#683]) diff --git a/signature/Cargo.toml b/signature/Cargo.toml index a2fe57c26..d59349135 100644 --- a/signature/Cargo.toml +++ b/signature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "1.5.0-pre" # Also update html_root_url in lib.rs when bumping this +version = "1.5.0" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/signature" diff --git a/signature/async/Cargo.toml b/signature/async/Cargo.toml index 054ae91c1..adbfea90d 100644 --- a/signature/async/Cargo.toml +++ b/signature/async/Cargo.toml @@ -13,7 +13,7 @@ categories = ["cryptography", "no-std"] [dependencies] async-trait = "0.1" -signature = { version = "=1.5.0-pre", path = ".." } +signature = { version = "1.5", path = ".." } [features] digest = ["signature/digest-preview"] diff --git a/signature/src/lib.rs b/signature/src/lib.rs index ed8a9f5f2..432aa8d6d 100644 --- a/signature/src/lib.rs +++ b/signature/src/lib.rs @@ -160,7 +160,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/signature/1.4.0" + html_root_url = "https://docs.rs/signature/1.5.0" )] #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms, unused_qualifications)] From a42440f8db2dc0dd55c4e63b51f150ee77a010bd Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 4 Jan 2022 22:53:12 -0700 Subject: [PATCH 0697/1461] async-signature v0.1.0 (#868) --- Cargo.lock | 2 +- signature/LICENSE-MIT | 2 +- signature/async/CHANGELOG.md | 7 ++ signature/async/Cargo.toml | 2 +- signature/async/LICENSE-APACHE | 201 +++++++++++++++++++++++++++++++++ signature/async/LICENSE-MIT | 25 ++++ signature/async/src/lib.rs | 2 +- 7 files changed, 237 insertions(+), 4 deletions(-) create mode 100644 signature/async/LICENSE-APACHE create mode 100644 signature/async/LICENSE-MIT diff --git a/Cargo.lock b/Cargo.lock index e4946cf81..5df889976 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,7 +14,7 @@ dependencies = [ [[package]] name = "async-signature" -version = "0.1.0-pre" +version = "0.1.0" dependencies = [ "async-trait", "signature", diff --git a/signature/LICENSE-MIT b/signature/LICENSE-MIT index fd43f17de..81a3d57ac 100644 --- a/signature/LICENSE-MIT +++ b/signature/LICENSE-MIT @@ -1,4 +1,4 @@ -Copyright (c) 2018-2021 RustCrypto Developers +Copyright (c) 2018-2022 RustCrypto Developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated diff --git a/signature/async/CHANGELOG.md b/signature/async/CHANGELOG.md index 2815fcdc5..3e9762a85 100644 --- a/signature/async/CHANGELOG.md +++ b/signature/async/CHANGELOG.md @@ -4,5 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.1.0 (2022-01-04) +### Changed +- Bump `signature` crate dependency to v1.5 ([#850], [#867]) + +[#850]: https://github.com/RustCrypto/traits/pull/850 +[#867]: https://github.com/RustCrypto/traits/pull/867 + ## 0.0.1 (2020-10-06) - Initial release diff --git a/signature/async/Cargo.toml b/signature/async/Cargo.toml index adbfea90d..a3fc81480 100644 --- a/signature/async/Cargo.toml +++ b/signature/async/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "async-signature" description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)" -version = "0.1.0-pre" # Also update html_root_url in lib.rs when bumping this +version = "0.1.0" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" documentation = "https://docs.rs/async-signature" diff --git a/signature/async/LICENSE-APACHE b/signature/async/LICENSE-APACHE new file mode 100644 index 000000000..78173fa2e --- /dev/null +++ b/signature/async/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/signature/async/LICENSE-MIT b/signature/async/LICENSE-MIT new file mode 100644 index 000000000..d4ce06527 --- /dev/null +++ b/signature/async/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2020-2022 RustCrypto Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/signature/async/src/lib.rs b/signature/async/src/lib.rs index a3f23b7f2..02a0f6609 100644 --- a/signature/async/src/lib.rs +++ b/signature/async/src/lib.rs @@ -21,7 +21,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/async-signature/0.0.1" + html_root_url = "https://docs.rs/async-signature/0.1.0" )] #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms, unused_qualifications)] From a6f22ef746377877bd015b708e9dbc251c6c4718 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 5 Jan 2022 17:46:06 -0700 Subject: [PATCH 0698/1461] elliptic-curve: add `Reduce::from_*e_digest_reduced` (#869) Adds `digest` feature-gated methods to the `Reduce` trait for reducing the output of a hash function as either a big endian or little endian integer. --- .github/workflows/elliptic-curve.yml | 3 ++- elliptic-curve/src/ops.rs | 37 ++++++++++++++++++++++++---- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index 2448a6627..6ea0096df 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -40,6 +40,7 @@ jobs: - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features arithmetic - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features bits - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features dev + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features digest - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features ecdh - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features hazmat - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features jwk @@ -49,7 +50,7 @@ jobs: - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features serde - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features pkcs8,sec1 - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features pem,pkcs8,sec1 - - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,ecdh,hazmat,jwk,pem,pkcs8,sec1,serde + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,digest,ecdh,hazmat,jwk,pem,pkcs8,sec1,serde test: runs-on: ubuntu-latest diff --git a/elliptic-curve/src/ops.rs b/elliptic-curve/src/ops.rs index b5ab2dd8f..d8038d931 100644 --- a/elliptic-curve/src/ops.rs +++ b/elliptic-curve/src/ops.rs @@ -8,6 +8,9 @@ use subtle::CtOption; #[cfg(feature = "arithmetic")] use group::Group; +#[cfg(feature = "digest")] +use digest::{BlockInput, Digest, FixedOutput, Reset, Update}; + /// Perform an inversion on a field element (i.e. base field element or scalar) pub trait Invert { /// Field element type @@ -46,24 +49,48 @@ pub trait Reduce: Sized { /// Perform a modular reduction, returning a field element. fn from_uint_reduced(n: UInt) -> Self; - /// Interpret the given byte array as a big endian integer and perform a - /// modular reduction. + /// Interpret the given byte array as a big endian integer and perform + /// a modular reduction. fn from_be_bytes_reduced(bytes: ByteArray) -> Self { Self::from_uint_reduced(UInt::from_be_byte_array(bytes)) } - /// Interpret the given byte array as a big endian integer and perform a + /// Interpret the given byte array as a little endian integer and perform a /// modular reduction. fn from_le_bytes_reduced(bytes: ByteArray) -> Self { Self::from_uint_reduced(UInt::from_le_byte_array(bytes)) } + + /// Interpret a digest as a big endian integer and perform a modular + /// reduction. + #[cfg(feature = "digest")] + #[cfg_attr(docsrs, doc(cfg(feature = "digest")))] + fn from_be_digest_reduced(digest: D) -> Self + where + D: FixedOutput + BlockInput + Clone + Default + Reset + Update, + { + Self::from_be_bytes_reduced(digest.finalize()) + } + + /// Interpret a digest as a little endian integer and perform a modular + /// reduction. + #[cfg(feature = "digest")] + #[cfg_attr(docsrs, doc(cfg(feature = "digest")))] + fn from_le_digest_reduced(digest: D) -> Self + where + D: FixedOutput + BlockInput + Clone + Default + Reset + Update, + { + Self::from_le_bytes_reduced(digest.finalize()) + } } /// Modular reduction to a non-zero output. /// -/// This trait is primarily intended for use by curve implementations. +/// This trait is primarily intended for use by curve implementations such +/// as the `k256` and `p256` crates. /// -/// End users can use the `Reduce` impl on `NonZeroScalar` instead. +/// End users should use the [`Reduce`] impl on +/// [`NonZeroScalar`][`crate::NonZeroScalar`] instead. pub trait ReduceNonZero: Sized { /// Perform a modular reduction, returning a field element. fn from_uint_reduced_nonzero(n: UInt) -> Self; From 4ea973c7c0aedb76a1b5b7537380a3403c5dc37e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 6 Jan 2022 15:09:47 -0700 Subject: [PATCH 0699/1461] build(deps): bump sha2 from 0.10.0 to 0.10.1 (#870) Bumps [sha2](https://github.com/RustCrypto/hashes) from 0.10.0 to 0.10.1. - [Release notes](https://github.com/RustCrypto/hashes/releases) - [Commits](https://github.com/RustCrypto/hashes/compare/sha2-v0.10.0...sha2-v0.10.1) --- updated-dependencies: - dependency-name: sha2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5df889976..2efc3e668 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -247,9 +247,9 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "sha2" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900d964dd36bb15bcf2f2b35694c072feab74969a54f2bbeec7a2d725d2bdcb6" +checksum = "99c3bd8169c58782adad9290a9af5939994036b76187f7b4f0e6de91dbbfc0ec" dependencies = [ "cfg-if", "cpufeatures", From 4b5c1e4ee7b1eec5c58d4cab6462efda9c365131 Mon Sep 17 00:00:00 2001 From: Michael Lodder Date: Thu, 6 Jan 2022 20:41:38 -0700 Subject: [PATCH 0700/1461] elliptic-curve: add traits for group digest (#865) --- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/hash2curve.rs | 14 ++ elliptic-curve/src/hash2curve/group_digest.rs | 69 ++++++++++ elliptic-curve/src/hash2curve/isogeny.rs | 53 ++++++++ elliptic-curve/src/hash2curve/map2curve.rs | 12 ++ elliptic-curve/src/{ => hash2curve}/osswu.rs | 3 +- elliptic-curve/src/hash2field.rs | 30 ++--- elliptic-curve/src/hash2field/expand_msg.rs | 75 ++++++++++- .../src/hash2field/expand_msg_xmd.rs | 123 +++++++++++------- .../src/hash2field/expand_msg_xof.rs | 36 ++--- elliptic-curve/src/lib.rs | 17 ++- 11 files changed, 343 insertions(+), 91 deletions(-) create mode 100644 elliptic-curve/src/hash2curve.rs create mode 100644 elliptic-curve/src/hash2curve/group_digest.rs create mode 100644 elliptic-curve/src/hash2curve/isogeny.rs create mode 100644 elliptic-curve/src/hash2curve/map2curve.rs rename elliptic-curve/src/{ => hash2curve}/osswu.rs (97%) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 3249ec1f2..0f48d46ab 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -47,10 +47,10 @@ alloc = ["der/alloc", "sec1/alloc", "zeroize/alloc"] # todo: use weak activation arithmetic = ["ff", "group"] bits = ["arithmetic", "ff/bits"] dev = ["arithmetic", "hex-literal", "pem", "pkcs8"] +hash2curve = ["digest", "ff", "group"] ecdh = ["arithmetic"] hazmat = [] jwk = ["alloc", "base64ct/alloc", "serde", "serde_json", "zeroize/alloc"] -osswu = ["ff"] pem = ["alloc", "arithmetic", "pem-rfc7468/alloc", "pkcs8", "sec1/pem"] pkcs8 = ["sec1/pkcs8"] std = ["alloc", "rand_core/std"] diff --git a/elliptic-curve/src/hash2curve.rs b/elliptic-curve/src/hash2curve.rs new file mode 100644 index 000000000..5b81eca8f --- /dev/null +++ b/elliptic-curve/src/hash2curve.rs @@ -0,0 +1,14 @@ +/// Traits for handling hash to curve +mod group_digest; +/// Traits for mapping an isogeny to another curve +/// +mod isogeny; +/// Traits for mapping field elements to points on the curve +mod map2curve; +/// Optimized simplified Shallue-van de Woestijne-Ulas methods +mod osswu; + +pub use group_digest::*; +pub use isogeny::*; +pub use map2curve::*; +pub use osswu::*; diff --git a/elliptic-curve/src/hash2curve/group_digest.rs b/elliptic-curve/src/hash2curve/group_digest.rs new file mode 100644 index 000000000..736f7c935 --- /dev/null +++ b/elliptic-curve/src/hash2curve/group_digest.rs @@ -0,0 +1,69 @@ +use super::MapToCurve; +use crate::hash2field::{hash_to_field, ExpandMsg, FromOkm}; +use group::cofactor::CofactorGroup; + +/// Adds hashing arbitrary byte sequences to a valid group element +pub trait GroupDigest { + /// The field element representation for a group value with multiple elements + type FieldElement: FromOkm + Default + Copy; + /// The resulting group element + type Output: CofactorGroup + + MapToCurve; + + /// Computes the hash to curve routine according to + /// + /// which says + /// Uniform encoding from byte strings to points in G. + /// That is, the distribution of its output is statistically close + /// to uniform in G. + /// This function is suitable for most applications requiring a random + /// oracle returning points in G assuming a cryptographically secure + /// hash function is used. + /// + /// Examples + /// + /// Using a fixed size hash function + /// + /// ```ignore + /// let pt = ProjectivePoint::hash_from_bytes::>(b"test data", b"CURVE_XMD:SHA-256_SSWU_RO_"); + /// ``` + /// + /// Using an extendable output function + /// + /// ```ignore + /// let pt = ProjectivePoint::hash_from_bytes::>(b"test data", b"CURVE_XOF:SHAKE-256_SSWU_RO_"); + /// ``` + /// + fn hash_from_bytes(msg: &[u8], dst: &'static [u8]) -> Self::Output { + let mut u = [Self::FieldElement::default(), Self::FieldElement::default()]; + hash_to_field::(msg, dst, &mut u); + let q0 = Self::Output::map_to_curve(u[0]); + let q1 = Self::Output::map_to_curve(u[1]); + // Ideally we could add and then clear cofactor once + // thus saving a call but the field elements may not + // add properly due to the underlying implementation + // which could result in an incorrect subgroup. + // This is caused curve coefficients being different than + // what is usually implemented. + // FieldElement expects the `a` and `b` to be the original values + // isogenies are different with curves like k256 and bls12-381. + // This problem doesn't manifest for curves with no isogeny like p256. + // For k256 and p256 clear_cofactor doesn't do anything anyway so it will be a no-op. + q0.clear_cofactor() + q1.clear_cofactor() + } + + /// Computes the encode to curve routine according to + /// + /// which says + /// Nonuniform encoding from byte strings to + /// points in G. That is, the distribution of its output is not + /// uniformly random in G: the set of possible outputs of + /// encode_to_curve is only a fraction of the points in G, and some + /// points in this set are more likely to be output than others. + fn encode_from_bytes(msg: &[u8], dst: &'static [u8]) -> Self::Output { + let mut u = [Self::FieldElement::default()]; + hash_to_field::(msg, dst, &mut u); + let q0 = Self::Output::map_to_curve(u[0]); + q0.clear_cofactor() + } +} diff --git a/elliptic-curve/src/hash2curve/isogeny.rs b/elliptic-curve/src/hash2curve/isogeny.rs new file mode 100644 index 000000000..abf1da27c --- /dev/null +++ b/elliptic-curve/src/hash2curve/isogeny.rs @@ -0,0 +1,53 @@ +use core::ops::{AddAssign, Mul}; +use ff::Field; +use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; + +/// The coefficients for mapping from one isogenous curve to another +pub struct IsogenyCoefficients> { + /// The coefficients for the x numerator + pub xnum: &'static [F], + /// The coefficients for the x denominator + pub xden: &'static [F], + /// The coefficients for the y numerator + pub ynum: &'static [F], + /// The coefficients for the x denominator + pub yden: &'static [F], +} + +/// The Isogeny methods to map to another curve +pub trait Isogeny: Field + AddAssign + Mul { + /// The maximum number of coefficients + type Degree: ArrayLength; + /// The isogeny coefficients + const COEFFICIENTS: IsogenyCoefficients; + + /// Map from the isogeny points to the main curve + fn isogeny(x: Self, y: Self) -> (Self, Self) { + let mut xs = GenericArray::::default(); + xs[0] = Self::one(); + xs[1] = x; + xs[2] = x.square(); + for i in 3..Self::Degree::to_usize() { + xs[i] = xs[i - 1] * x; + } + let x_num = Self::compute_iso(&xs, Self::COEFFICIENTS.xnum); + let x_den = Self::compute_iso(&xs, Self::COEFFICIENTS.xden) + .invert() + .unwrap(); + let y_num = Self::compute_iso(&xs, Self::COEFFICIENTS.ynum) * y; + let y_den = Self::compute_iso(&xs, Self::COEFFICIENTS.yden) + .invert() + .unwrap(); + + (x_num * x_den, y_num * y_den) + } + + /// Compute the ISO transform + fn compute_iso(xxs: &[Self], k: &[Self]) -> Self { + let mut xx = Self::zero(); + for (xi, ki) in xxs.iter().zip(k.iter()) { + xx += *xi * ki; + } + xx + } +} diff --git a/elliptic-curve/src/hash2curve/map2curve.rs b/elliptic-curve/src/hash2curve/map2curve.rs new file mode 100644 index 000000000..90310166e --- /dev/null +++ b/elliptic-curve/src/hash2curve/map2curve.rs @@ -0,0 +1,12 @@ +/// Trait for converting field elements into a point +/// via a mapping method like Simplified Shallue-van de Woestijne-Ulas +/// or Elligator +pub trait MapToCurve { + /// The input values representing x and y + type FieldElement; + /// The output point + type Output; + + /// Map a field element into a point + fn map_to_curve(u: Self::FieldElement) -> Self::Output; +} diff --git a/elliptic-curve/src/osswu.rs b/elliptic-curve/src/hash2curve/osswu.rs similarity index 97% rename from elliptic-curve/src/osswu.rs rename to elliptic-curve/src/hash2curve/osswu.rs index ae8637512..e10652142 100644 --- a/elliptic-curve/src/osswu.rs +++ b/elliptic-curve/src/hash2curve/osswu.rs @@ -43,8 +43,7 @@ pub trait OsswuMap: Field + Sgn0 { let mut tv2 = tv3.square(); // tv3^2 let mut xd = tv2 + tv3; // tv3^2 + tv3 let x1n = Self::PARAMS.map_b * (xd + Self::one()); // B * (xd + 1) - let a_neg = -Self::PARAMS.map_a; - xd *= a_neg; // -A * xd + xd *= -Self::PARAMS.map_a; // -A * xd let tv = Self::PARAMS.z * Self::PARAMS.map_a; xd.conditional_assign(&tv, xd.is_zero()); diff --git a/elliptic-curve/src/hash2field.rs b/elliptic-curve/src/hash2field.rs index a68a06edc..bdf30b9a5 100644 --- a/elliptic-curve/src/hash2field.rs +++ b/elliptic-curve/src/hash2field.rs @@ -2,32 +2,32 @@ mod expand_msg; mod expand_msg_xmd; mod expand_msg_xof; -use core::convert::TryFrom; pub use expand_msg::*; pub use expand_msg_xmd::*; pub use expand_msg_xof::*; +use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; /// The trait for helping to convert to a scalar -pub trait FromOkm: Sized { +pub trait FromOkm { + /// The number of bytes needed to convert to a scalar + type Length: ArrayLength; + /// Convert a byte sequence into a scalar - fn from_okm(data: &[u8; L]) -> Self; + fn from_okm(data: &GenericArray) -> Self; } /// Convert an arbitrary byte sequence according to /// -pub fn hash_to_field( - data: &[u8], - domain: &[u8], -) -> [T; COUNT] +pub fn hash_to_field(data: &[u8], domain: &'static [u8], out: &mut [T]) where - E: ExpandMsg, - T: FromOkm + Default + Copy, + E: ExpandMsg, + T: FromOkm + Default, { - let random_bytes = E::expand_message(data, domain); - let mut out = [T::default(); COUNT]; - for i in 0..COUNT { - let u = <[u8; L]>::try_from(&random_bytes[(L * i)..L * (i + 1)]).expect("not enough bytes"); - out[i] = T::from_okm(&u); + let len_in_bytes = T::Length::to_usize() * out.len(); + let mut tmp = GenericArray::::Length>::default(); + let mut expander = E::expand_message(data, domain, len_in_bytes); + for o in out.iter_mut() { + expander.fill_bytes(&mut tmp); + *o = T::from_okm(&tmp); } - out } diff --git a/elliptic-curve/src/hash2field/expand_msg.rs b/elliptic-curve/src/hash2field/expand_msg.rs index ba08f98f7..9adfab766 100644 --- a/elliptic-curve/src/hash2field/expand_msg.rs +++ b/elliptic-curve/src/hash2field/expand_msg.rs @@ -1,5 +1,74 @@ +use digest::{Digest, ExtendableOutputDirty, Update, XofReader}; +use generic_array::{ArrayLength, GenericArray}; + +/// Salt when the DST is too long +const OVERSIZE_DST_SALT: &[u8] = b"H2C-OVERSIZE-DST-"; +/// Maximum domain separation tag length +const MAX_DST_LEN: usize = 255; + /// Trait for types implementing expand_message interface for hash_to_field -pub trait ExpandMsg { - /// Expands `msg` to the required number of bytes in `buf` - fn expand_message(msg: &[u8], dst: &[u8]) -> [u8; OUT]; +pub trait ExpandMsg { + /// Expands `msg` to the required number of bytes + /// Returns an expander that can be used to call `read` until enough + /// bytes have been consumed + fn expand_message(msg: &[u8], dst: &'static [u8], len_in_bytes: usize) -> Self; + + /// Fill the array with the expanded bytes + fn fill_bytes(&mut self, okm: &mut [u8]); +} + +/// The domain separation tag +/// +/// Implements [section 5.4.3 of `draft-irtf-cfrg-hash-to-curve-13`][dst]. +/// +/// [dst]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-13#section-5.4.3 +pub(crate) enum Domain> { + /// > 255 + Hashed(GenericArray), + /// <= 255 + Array(&'static [u8]), +} + +impl> Domain { + pub fn xof(dst: &'static [u8]) -> Self + where + X: Default + ExtendableOutputDirty + Update, + { + if dst.len() > MAX_DST_LEN { + let mut data = GenericArray::::default(); + X::default() + .chain(OVERSIZE_DST_SALT) + .chain(dst) + .finalize_xof_dirty() + .read(&mut data); + Self::Hashed(data) + } else { + Self::Array(dst) + } + } + + pub fn xmd(dst: &'static [u8]) -> Self + where + X: Digest, + { + if dst.len() > MAX_DST_LEN { + Self::Hashed(X::new().chain(OVERSIZE_DST_SALT).chain(dst).finalize()) + } else { + Self::Array(dst) + } + } + + pub fn data(&self) -> &[u8] { + match self { + Self::Hashed(d) => &d[..], + Self::Array(d) => *d, + } + } + + pub fn len(&self) -> usize { + match self { + Self::Hashed(_) => L::to_usize(), + Self::Array(d) => d.len(), + } + } } diff --git a/elliptic-curve/src/hash2field/expand_msg_xmd.rs b/elliptic-curve/src/hash2field/expand_msg_xmd.rs index e99f8b6e0..be599fcea 100644 --- a/elliptic-curve/src/hash2field/expand_msg_xmd.rs +++ b/elliptic-curve/src/hash2field/expand_msg_xmd.rs @@ -1,72 +1,103 @@ -use super::ExpandMsg; -use core::marker::PhantomData; +use super::{Domain, ExpandMsg}; use digest::{ - generic_array::{typenum::Unsigned, GenericArray}, + generic_array::{ + typenum::{IsLess, IsLessOrEqual, Unsigned, U256}, + GenericArray, + }, BlockInput, Digest, }; -use subtle::{Choice, ConditionallySelectable}; /// Placeholder type for implementing expand_message_xmd based on a hash function -#[derive(Debug)] -pub struct ExpandMsgXmd { - phantom: PhantomData, +pub struct ExpandMsgXmd +where + HashT: Digest + BlockInput, + HashT::OutputSize: IsLess, + HashT::OutputSize: IsLessOrEqual, +{ + b_0: GenericArray, + b_vals: GenericArray, + domain: Domain, + index: usize, + offset: usize, + ell: usize, +} + +impl ExpandMsgXmd +where + HashT: Digest + BlockInput, + HashT::OutputSize: IsLess, + HashT::OutputSize: IsLessOrEqual, +{ + fn next(&mut self) -> bool { + if self.index < self.ell { + self.index += 1; + self.offset = 0; + // b_0 XOR b_(idx - 1) + let mut tmp = GenericArray::::default(); + self.b_0 + .iter() + .zip(&self.b_vals[..]) + .enumerate() + .for_each(|(j, (b0val, bi1val))| tmp[j] = b0val ^ bi1val); + self.b_vals = HashT::new() + .chain(tmp) + .chain([self.index as u8]) + .chain(self.domain.data()) + .chain([self.domain.len() as u8]) + .finalize(); + true + } else { + false + } + } } /// ExpandMsgXmd implements expand_message_xmd for the ExpandMsg trait -impl ExpandMsg for ExpandMsgXmd +impl ExpandMsg for ExpandMsgXmd where HashT: Digest + BlockInput, + HashT::OutputSize: IsLess, + HashT::OutputSize: IsLessOrEqual, { - fn expand_message(msg: &[u8], dst: &[u8]) -> [u8; LEN_IN_BYTES] { + fn expand_message(msg: &[u8], dst: &'static [u8], len_in_bytes: usize) -> Self { let b_in_bytes = HashT::OutputSize::to_usize(); - let ell = (LEN_IN_BYTES + b_in_bytes - 1) / b_in_bytes; - if ell > 255 { - panic!("ell was too big in expand_message_xmd"); - } + let ell = (len_in_bytes + b_in_bytes - 1) / b_in_bytes; + // if ell > 255 { + // panic!("ell was too big in expand_message_xmd"); + // } + let domain = Domain::xmd::(dst); let b_0 = HashT::new() .chain(GenericArray::::default()) .chain(msg) - .chain([(LEN_IN_BYTES >> 8) as u8, LEN_IN_BYTES as u8, 0u8]) - .chain(dst) - .chain([dst.len() as u8]) + .chain([(len_in_bytes >> 8) as u8, len_in_bytes as u8, 0u8]) + .chain(domain.data()) + .chain([domain.len() as u8]) .finalize(); - let mut b_vals = HashT::new() + let b_vals = HashT::new() .chain(&b_0[..]) .chain([1u8]) - .chain(dst) - .chain([dst.len() as u8]) + .chain(domain.data()) + .chain([domain.len() as u8]) .finalize(); - let mut buf = [0u8; LEN_IN_BYTES]; - let mut offset = 0; + Self { + b_0, + b_vals, + domain, + index: 1, + offset: 0, + ell, + } + } - for i in 1..ell { - // b_0 XOR b_(idx - 1) - let mut tmp = GenericArray::::default(); - b_0.iter() - .zip(&b_vals[..]) - .enumerate() - .for_each(|(j, (b0val, bi1val))| tmp[j] = b0val ^ bi1val); - for b in b_vals { - buf[offset % LEN_IN_BYTES].conditional_assign( - &b, - Choice::from(if offset < LEN_IN_BYTES { 1 } else { 0 }), - ); - offset += 1; + fn fill_bytes(&mut self, okm: &mut [u8]) { + for b in okm { + if self.offset == self.b_vals.len() && !self.next() { + return; } - b_vals = HashT::new() - .chain(tmp) - .chain([(i + 1) as u8]) - .chain(dst) - .chain([dst.len() as u8]) - .finalize(); - } - for b in b_vals { - buf[offset % LEN_IN_BYTES] - .conditional_assign(&b, Choice::from(if offset < LEN_IN_BYTES { 1 } else { 0 })); - offset += 1; + *b = self.b_vals[self.offset]; + self.offset += 1; } - buf } } diff --git a/elliptic-curve/src/hash2field/expand_msg_xof.rs b/elliptic-curve/src/hash2field/expand_msg_xof.rs index 0ec1df024..371482ae4 100644 --- a/elliptic-curve/src/hash2field/expand_msg_xof.rs +++ b/elliptic-curve/src/hash2field/expand_msg_xof.rs @@ -1,27 +1,33 @@ use super::ExpandMsg; -use core::marker::PhantomData; -use digest::{ExtendableOutput, Update, XofReader}; +use crate::hash2field::Domain; +use digest::{ExtendableOutput, ExtendableOutputDirty, Update, XofReader}; +use generic_array::typenum::U32; /// Placeholder type for implementing expand_message_xof based on an extendable output function -#[derive(Debug)] -pub struct ExpandMsgXof { - phantom: PhantomData, +pub struct ExpandMsgXof +where + HashT: Default + ExtendableOutput + ExtendableOutputDirty + Update, +{ + reader: ::Reader, } /// ExpandMsgXof implements expand_message_xof for the ExpandMsg trait -impl ExpandMsg for ExpandMsgXof +impl ExpandMsg for ExpandMsgXof where - HashT: Default + ExtendableOutput + Update, + HashT: Default + ExtendableOutput + ExtendableOutputDirty + Update, { - fn expand_message(msg: &[u8], dst: &[u8]) -> [u8; LEN_IN_BYTES] { - let mut buf = [0u8; LEN_IN_BYTES]; - let mut r = HashT::default() + fn expand_message(msg: &[u8], dst: &'static [u8], len_in_bytes: usize) -> Self { + let domain = Domain::::xof::(dst); + let reader = HashT::default() .chain(msg) - .chain([(LEN_IN_BYTES >> 8) as u8, LEN_IN_BYTES as u8]) - .chain(dst) - .chain([dst.len() as u8]) + .chain([(len_in_bytes >> 8) as u8, len_in_bytes as u8]) + .chain(domain.data()) + .chain([domain.len() as u8]) .finalize_xof(); - r.read(&mut buf); - buf + Self { reader } + } + + fn fill_bytes(&mut self, okm: &mut [u8]) { + self.reader.read(okm); } } diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index d6b637f0b..b67121f20 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -94,17 +94,16 @@ pub mod ecdh; #[cfg(feature = "jwk")] mod jwk; -/// Optimized simplified Shallue-van de Woestijne-Ulas methods -#[cfg(feature = "osswu")] -#[cfg_attr(docsrs, doc(cfg(feature = "osswu")))] -pub mod osswu; - -/// Traits for computing hash to field as described in -/// -#[cfg(feature = "digest")] -#[cfg_attr(docsrs, doc(cfg(feature = "digest")))] +/// Traits for hashing to field elements +#[cfg(feature = "hash2curve")] +#[cfg_attr(docsrs, doc(cfg(feature = "hash2curve")))] pub mod hash2field; +/// Traits for hashing byte sequences to curve points +#[cfg(feature = "hash2curve")] +#[cfg_attr(docsrs, doc(cfg(feature = "hash2curve")))] +pub mod hash2curve; + pub use crate::{ error::{Error, Result}, point::{ From 7f1b5f516eed312a5268d5f8da077f5093d8b227 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 7 Jan 2022 08:46:02 -0700 Subject: [PATCH 0701/1461] elliptic-curve: make `ExpandMsg` fallible (#871) As noted on #865 there are some potential overflow problems constructing the messages used for expansion, particularly around input lengths. This commit changes `ExpandMsg::expand_message`, and all of its transitive callers, to be fallible in order to handle these cases. --- elliptic-curve/src/hash2curve/group_digest.rs | 17 ++++++++------ elliptic-curve/src/hash2field.rs | 7 ++++-- elliptic-curve/src/hash2field/expand_msg.rs | 5 +++-- .../src/hash2field/expand_msg_xmd.rs | 22 ++++++++++++------- .../src/hash2field/expand_msg_xof.rs | 6 ++--- 5 files changed, 35 insertions(+), 22 deletions(-) diff --git a/elliptic-curve/src/hash2curve/group_digest.rs b/elliptic-curve/src/hash2curve/group_digest.rs index 736f7c935..f0a0dc17d 100644 --- a/elliptic-curve/src/hash2curve/group_digest.rs +++ b/elliptic-curve/src/hash2curve/group_digest.rs @@ -1,5 +1,8 @@ use super::MapToCurve; -use crate::hash2field::{hash_to_field, ExpandMsg, FromOkm}; +use crate::{ + hash2field::{hash_to_field, ExpandMsg, FromOkm}, + Result, +}; use group::cofactor::CofactorGroup; /// Adds hashing arbitrary byte sequences to a valid group element @@ -34,9 +37,9 @@ pub trait GroupDigest { /// let pt = ProjectivePoint::hash_from_bytes::>(b"test data", b"CURVE_XOF:SHAKE-256_SSWU_RO_"); /// ``` /// - fn hash_from_bytes(msg: &[u8], dst: &'static [u8]) -> Self::Output { + fn hash_from_bytes(msg: &[u8], dst: &'static [u8]) -> Result { let mut u = [Self::FieldElement::default(), Self::FieldElement::default()]; - hash_to_field::(msg, dst, &mut u); + hash_to_field::(msg, dst, &mut u)?; let q0 = Self::Output::map_to_curve(u[0]); let q1 = Self::Output::map_to_curve(u[1]); // Ideally we could add and then clear cofactor once @@ -49,7 +52,7 @@ pub trait GroupDigest { // isogenies are different with curves like k256 and bls12-381. // This problem doesn't manifest for curves with no isogeny like p256. // For k256 and p256 clear_cofactor doesn't do anything anyway so it will be a no-op. - q0.clear_cofactor() + q1.clear_cofactor() + Ok(q0.clear_cofactor() + q1.clear_cofactor()) } /// Computes the encode to curve routine according to @@ -60,10 +63,10 @@ pub trait GroupDigest { /// uniformly random in G: the set of possible outputs of /// encode_to_curve is only a fraction of the points in G, and some /// points in this set are more likely to be output than others. - fn encode_from_bytes(msg: &[u8], dst: &'static [u8]) -> Self::Output { + fn encode_from_bytes(msg: &[u8], dst: &'static [u8]) -> Result { let mut u = [Self::FieldElement::default()]; - hash_to_field::(msg, dst, &mut u); + hash_to_field::(msg, dst, &mut u)?; let q0 = Self::Output::map_to_curve(u[0]); - q0.clear_cofactor() + Ok(q0.clear_cofactor()) } } diff --git a/elliptic-curve/src/hash2field.rs b/elliptic-curve/src/hash2field.rs index bdf30b9a5..8d0c08808 100644 --- a/elliptic-curve/src/hash2field.rs +++ b/elliptic-curve/src/hash2field.rs @@ -5,6 +5,8 @@ mod expand_msg_xof; pub use expand_msg::*; pub use expand_msg_xmd::*; pub use expand_msg_xof::*; + +use crate::Result; use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; /// The trait for helping to convert to a scalar @@ -18,16 +20,17 @@ pub trait FromOkm { /// Convert an arbitrary byte sequence according to /// -pub fn hash_to_field(data: &[u8], domain: &'static [u8], out: &mut [T]) +pub fn hash_to_field(data: &[u8], domain: &'static [u8], out: &mut [T]) -> Result<()> where E: ExpandMsg, T: FromOkm + Default, { let len_in_bytes = T::Length::to_usize() * out.len(); let mut tmp = GenericArray::::Length>::default(); - let mut expander = E::expand_message(data, domain, len_in_bytes); + let mut expander = E::expand_message(data, domain, len_in_bytes)?; for o in out.iter_mut() { expander.fill_bytes(&mut tmp); *o = T::from_okm(&tmp); } + Ok(()) } diff --git a/elliptic-curve/src/hash2field/expand_msg.rs b/elliptic-curve/src/hash2field/expand_msg.rs index 9adfab766..4c80a7245 100644 --- a/elliptic-curve/src/hash2field/expand_msg.rs +++ b/elliptic-curve/src/hash2field/expand_msg.rs @@ -1,3 +1,4 @@ +use crate::Result; use digest::{Digest, ExtendableOutputDirty, Update, XofReader}; use generic_array::{ArrayLength, GenericArray}; @@ -7,11 +8,11 @@ const OVERSIZE_DST_SALT: &[u8] = b"H2C-OVERSIZE-DST-"; const MAX_DST_LEN: usize = 255; /// Trait for types implementing expand_message interface for hash_to_field -pub trait ExpandMsg { +pub trait ExpandMsg: Sized { /// Expands `msg` to the required number of bytes /// Returns an expander that can be used to call `read` until enough /// bytes have been consumed - fn expand_message(msg: &[u8], dst: &'static [u8], len_in_bytes: usize) -> Self; + fn expand_message(msg: &[u8], dst: &'static [u8], len_in_bytes: usize) -> Result; /// Fill the array with the expanded bytes fn fill_bytes(&mut self, okm: &mut [u8]); diff --git a/elliptic-curve/src/hash2field/expand_msg_xmd.rs b/elliptic-curve/src/hash2field/expand_msg_xmd.rs index be599fcea..1a688c9f0 100644 --- a/elliptic-curve/src/hash2field/expand_msg_xmd.rs +++ b/elliptic-curve/src/hash2field/expand_msg_xmd.rs @@ -1,4 +1,5 @@ use super::{Domain, ExpandMsg}; +use crate::{Error, Result}; use digest::{ generic_array::{ typenum::{IsLess, IsLessOrEqual, Unsigned, U256}, @@ -56,15 +57,20 @@ where impl ExpandMsg for ExpandMsgXmd where HashT: Digest + BlockInput, - HashT::OutputSize: IsLess, - HashT::OutputSize: IsLessOrEqual, + HashT::OutputSize: IsLess + IsLessOrEqual, { - fn expand_message(msg: &[u8], dst: &'static [u8], len_in_bytes: usize) -> Self { + fn expand_message(msg: &[u8], dst: &'static [u8], len_in_bytes: usize) -> Result { + if len_in_bytes > 0xFFFF { + return Err(Error); + } + let b_in_bytes = HashT::OutputSize::to_usize(); let ell = (len_in_bytes + b_in_bytes - 1) / b_in_bytes; - // if ell > 255 { - // panic!("ell was too big in expand_message_xmd"); - // } + + if ell > 255 { + return Err(Error); + } + let domain = Domain::xmd::(dst); let b_0 = HashT::new() .chain(GenericArray::::default()) @@ -81,14 +87,14 @@ where .chain([domain.len() as u8]) .finalize(); - Self { + Ok(Self { b_0, b_vals, domain, index: 1, offset: 0, ell, - } + }) } fn fill_bytes(&mut self, okm: &mut [u8]) { diff --git a/elliptic-curve/src/hash2field/expand_msg_xof.rs b/elliptic-curve/src/hash2field/expand_msg_xof.rs index 371482ae4..94035470f 100644 --- a/elliptic-curve/src/hash2field/expand_msg_xof.rs +++ b/elliptic-curve/src/hash2field/expand_msg_xof.rs @@ -1,5 +1,5 @@ use super::ExpandMsg; -use crate::hash2field::Domain; +use crate::{hash2field::Domain, Result}; use digest::{ExtendableOutput, ExtendableOutputDirty, Update, XofReader}; use generic_array::typenum::U32; @@ -16,7 +16,7 @@ impl ExpandMsg for ExpandMsgXof where HashT: Default + ExtendableOutput + ExtendableOutputDirty + Update, { - fn expand_message(msg: &[u8], dst: &'static [u8], len_in_bytes: usize) -> Self { + fn expand_message(msg: &[u8], dst: &'static [u8], len_in_bytes: usize) -> Result { let domain = Domain::::xof::(dst); let reader = HashT::default() .chain(msg) @@ -24,7 +24,7 @@ where .chain(domain.data()) .chain([domain.len() as u8]) .finalize_xof(); - Self { reader } + Ok(Self { reader }) } fn fill_bytes(&mut self, okm: &mut [u8]) { From 67960c2cd0fd8e38f81b18bac695e85cae7a4727 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Fri, 7 Jan 2022 23:20:37 +0100 Subject: [PATCH 0702/1461] `ExpandMsg` improvements (#874) Follow-up for #400 Prevent overflows and add zero check. --- .github/workflows/elliptic-curve.yml | 3 +- elliptic-curve/Cargo.lock | 64 ++++ elliptic-curve/Cargo.toml | 2 + elliptic-curve/src/hash2curve/group_digest.rs | 11 +- elliptic-curve/src/hash2curve/map2curve.rs | 4 +- elliptic-curve/src/hash2field/expand_msg.rs | 31 +- .../src/hash2field/expand_msg_xmd.rs | 333 +++++++++++++++++- .../src/hash2field/expand_msg_xof.rs | 303 +++++++++++++++- 8 files changed, 713 insertions(+), 38 deletions(-) diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index 6ea0096df..370a7a466 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -43,6 +43,7 @@ jobs: - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features digest - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features ecdh - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features hazmat + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features hash2curve - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features jwk - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features pem - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features pkcs8 @@ -50,7 +51,7 @@ jobs: - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features serde - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features pkcs8,sec1 - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features pem,pkcs8,sec1 - - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,digest,ecdh,hazmat,jwk,pem,pkcs8,sec1,serde + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,digest,ecdh,hazmat,hash2curve,jwk,pem,pkcs8,sec1,serde test: runs-on: ubuntu-latest diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index 812bece07..2dc485a80 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -20,6 +20,22 @@ dependencies = [ "wyz", ] +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "block-padding", + "generic-array", +] + +[[package]] +name = "block-padding" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" + [[package]] name = "cfg-if" version = "1.0.0" @@ -32,6 +48,15 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" +[[package]] +name = "cpufeatures" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" +dependencies = [ + "libc", +] + [[package]] name = "crypto-bigint" version = "0.3.2" @@ -80,6 +105,8 @@ dependencies = [ "sec1", "serde", "serde_json", + "sha2", + "sha3", "subtle", "zeroize", ] @@ -145,12 +172,24 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" +[[package]] +name = "keccak" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" + [[package]] name = "libc" version = "0.2.112" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + [[package]] name = "pem-rfc7468" version = "0.3.1" @@ -222,6 +261,31 @@ dependencies = [ "serde", ] +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer", + "cfg-if", + "cpufeatures", + "digest", + "opaque-debug", +] + +[[package]] +name = "sha3" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" +dependencies = [ + "block-buffer", + "digest", + "keccak", + "opaque-debug", +] + [[package]] name = "spki" version = "0.5.3" diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 0f48d46ab..9e476cda1 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -40,6 +40,8 @@ serde_json = { version = "1", optional = true, default-features = false, feature [dev-dependencies] hex-literal = "0.3" +sha2 = "0.9" +sha3 = "0.9" [features] default = ["arithmetic"] diff --git a/elliptic-curve/src/hash2curve/group_digest.rs b/elliptic-curve/src/hash2curve/group_digest.rs index f0a0dc17d..837a76684 100644 --- a/elliptic-curve/src/hash2curve/group_digest.rs +++ b/elliptic-curve/src/hash2curve/group_digest.rs @@ -8,10 +8,9 @@ use group::cofactor::CofactorGroup; /// Adds hashing arbitrary byte sequences to a valid group element pub trait GroupDigest { /// The field element representation for a group value with multiple elements - type FieldElement: FromOkm + Default + Copy; + type FieldElement: FromOkm + MapToCurve + Default + Copy; /// The resulting group element - type Output: CofactorGroup - + MapToCurve; + type Output: CofactorGroup; /// Computes the hash to curve routine according to /// @@ -40,8 +39,8 @@ pub trait GroupDigest { fn hash_from_bytes(msg: &[u8], dst: &'static [u8]) -> Result { let mut u = [Self::FieldElement::default(), Self::FieldElement::default()]; hash_to_field::(msg, dst, &mut u)?; - let q0 = Self::Output::map_to_curve(u[0]); - let q1 = Self::Output::map_to_curve(u[1]); + let q0 = u[0].map_to_curve(); + let q1 = u[1].map_to_curve(); // Ideally we could add and then clear cofactor once // thus saving a call but the field elements may not // add properly due to the underlying implementation @@ -66,7 +65,7 @@ pub trait GroupDigest { fn encode_from_bytes(msg: &[u8], dst: &'static [u8]) -> Result { let mut u = [Self::FieldElement::default()]; hash_to_field::(msg, dst, &mut u)?; - let q0 = Self::Output::map_to_curve(u[0]); + let q0 = u[0].map_to_curve(); Ok(q0.clear_cofactor()) } } diff --git a/elliptic-curve/src/hash2curve/map2curve.rs b/elliptic-curve/src/hash2curve/map2curve.rs index 90310166e..0708a2cd8 100644 --- a/elliptic-curve/src/hash2curve/map2curve.rs +++ b/elliptic-curve/src/hash2curve/map2curve.rs @@ -2,11 +2,9 @@ /// via a mapping method like Simplified Shallue-van de Woestijne-Ulas /// or Elligator pub trait MapToCurve { - /// The input values representing x and y - type FieldElement; /// The output point type Output; /// Map a field element into a point - fn map_to_curve(u: Self::FieldElement) -> Self::Output; + fn map_to_curve(&self) -> Self::Output; } diff --git a/elliptic-curve/src/hash2field/expand_msg.rs b/elliptic-curve/src/hash2field/expand_msg.rs index 4c80a7245..49537f150 100644 --- a/elliptic-curve/src/hash2field/expand_msg.rs +++ b/elliptic-curve/src/hash2field/expand_msg.rs @@ -1,5 +1,6 @@ use crate::Result; -use digest::{Digest, ExtendableOutputDirty, Update, XofReader}; +use digest::{Digest, ExtendableOutput, Update, XofReader}; +use generic_array::typenum::{IsLess, U256}; use generic_array::{ArrayLength, GenericArray}; /// Salt when the DST is too long @@ -23,24 +24,30 @@ pub trait ExpandMsg: Sized { /// Implements [section 5.4.3 of `draft-irtf-cfrg-hash-to-curve-13`][dst]. /// /// [dst]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-13#section-5.4.3 -pub(crate) enum Domain> { +pub(crate) enum Domain +where + L: ArrayLength + IsLess, +{ /// > 255 Hashed(GenericArray), /// <= 255 Array(&'static [u8]), } -impl> Domain { +impl Domain +where + L: ArrayLength + IsLess, +{ pub fn xof(dst: &'static [u8]) -> Self where - X: Default + ExtendableOutputDirty + Update, + X: Default + ExtendableOutput + Update, { if dst.len() > MAX_DST_LEN { let mut data = GenericArray::::default(); X::default() .chain(OVERSIZE_DST_SALT) .chain(dst) - .finalize_xof_dirty() + .finalize_xof() .read(&mut data); Self::Hashed(data) } else { @@ -66,10 +73,18 @@ impl> Domain { } } - pub fn len(&self) -> usize { + pub fn len(&self) -> u8 { match self { - Self::Hashed(_) => L::to_usize(), - Self::Array(d) => d.len(), + // Can't overflow because it's enforced on a type level. + Self::Hashed(_) => L::to_u8(), + // Can't overflow because it's checked on creation. + Self::Array(d) => u8::try_from(d.len()).expect("length overflow"), } } + + #[cfg(test)] + pub fn assert(&self, bytes: &[u8]) { + assert_eq!(self.data(), &bytes[..bytes.len() - 1]); + assert_eq!(self.len(), bytes[bytes.len() - 1]); + } } diff --git a/elliptic-curve/src/hash2field/expand_msg_xmd.rs b/elliptic-curve/src/hash2field/expand_msg_xmd.rs index 1a688c9f0..2e0a8fd17 100644 --- a/elliptic-curve/src/hash2field/expand_msg_xmd.rs +++ b/elliptic-curve/src/hash2field/expand_msg_xmd.rs @@ -18,9 +18,9 @@ where b_0: GenericArray, b_vals: GenericArray, domain: Domain, - index: usize, + index: u8, offset: usize, - ell: usize, + ell: u8, } impl ExpandMsgXmd @@ -42,9 +42,9 @@ where .for_each(|(j, (b0val, bi1val))| tmp[j] = b0val ^ bi1val); self.b_vals = HashT::new() .chain(tmp) - .chain([self.index as u8]) + .chain([self.index]) .chain(self.domain.data()) - .chain([self.domain.len() as u8]) + .chain([self.domain.len()]) .finalize(); true } else { @@ -57,34 +57,39 @@ where impl ExpandMsg for ExpandMsgXmd where HashT: Digest + BlockInput, - HashT::OutputSize: IsLess + IsLessOrEqual, + // If `len_in_bytes` is bigger then 256, length of the `DST` will depend on + // the output size of the hash, which is still not allowed to be bigger then 256: + // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-13.html#section-5.4.1-6 + HashT::OutputSize: IsLess, + // Constraint set by `expand_message_xmd`: + // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-13.html#section-5.4.1-4 + HashT::OutputSize: IsLessOrEqual, { fn expand_message(msg: &[u8], dst: &'static [u8], len_in_bytes: usize) -> Result { - if len_in_bytes > 0xFFFF { + if len_in_bytes == 0 { return Err(Error); } - let b_in_bytes = HashT::OutputSize::to_usize(); - let ell = (len_in_bytes + b_in_bytes - 1) / b_in_bytes; + let len_in_bytes_u16 = u16::try_from(len_in_bytes).map_err(|_| Error)?; - if ell > 255 { - return Err(Error); - } + let b_in_bytes = HashT::OutputSize::to_usize(); + let ell = u8::try_from((len_in_bytes + b_in_bytes - 1) / b_in_bytes).map_err(|_| Error)?; let domain = Domain::xmd::(dst); let b_0 = HashT::new() .chain(GenericArray::::default()) .chain(msg) - .chain([(len_in_bytes >> 8) as u8, len_in_bytes as u8, 0u8]) + .chain(len_in_bytes_u16.to_be_bytes()) + .chain([0]) .chain(domain.data()) - .chain([domain.len() as u8]) + .chain([domain.len()]) .finalize(); let b_vals = HashT::new() .chain(&b_0[..]) .chain([1u8]) .chain(domain.data()) - .chain([domain.len() as u8]) + .chain([domain.len()]) .finalize(); Ok(Self { @@ -107,3 +112,303 @@ where } } } + +#[cfg(test)] +mod test { + use super::*; + use core::mem; + use generic_array::{ + typenum::{U128, U32}, + ArrayLength, + }; + use hex_literal::hex; + use sha2::Sha256; + + fn assert_message( + msg: &[u8], + domain: &Domain, + len_in_bytes: u16, + bytes: &[u8], + ) where + HashT: Digest + BlockInput, + HashT::OutputSize: IsLess, + { + let block = HashT::BlockSize::to_usize(); + assert_eq!( + GenericArray::::default().as_slice(), + &bytes[..block] + ); + + let msg_len = block + msg.len(); + assert_eq!(msg, &bytes[block..msg_len]); + + let l = msg_len + mem::size_of::(); + assert_eq!(len_in_bytes.to_be_bytes(), &bytes[msg_len..l]); + + let pad = l + mem::size_of::(); + assert_eq!([0], &bytes[l..pad]); + + let dst = pad + domain.data().len(); + assert_eq!(domain.data(), &bytes[pad..dst]); + + let dst_len = dst + mem::size_of::(); + assert_eq!([domain.len()], &bytes[dst..dst_len]); + + assert_eq!(dst_len, bytes.len()); + } + + struct TestVector { + msg: &'static [u8], + msg_prime: &'static [u8], + uniform_bytes: &'static [u8], + } + + impl TestVector { + fn assert>( + &self, + dst: &'static [u8], + domain: &Domain, + ) -> Result<()> + where + HashT: Digest + BlockInput, + HashT::OutputSize: IsLess + IsLessOrEqual, + { + assert_message::(self.msg, domain, L::to_u16(), self.msg_prime); + + let mut expander = + as ExpandMsg>::expand_message(self.msg, dst, L::to_usize())?; + + let mut uniform_bytes = GenericArray::::default(); + expander.fill_bytes(&mut uniform_bytes); + + assert_eq!(uniform_bytes.as_slice(), self.uniform_bytes); + Ok(()) + } + } + + #[test] + fn expand_message_xmd_sha_256() -> Result<()> { + const DST: &[u8] = b"QUUX-V01-CS02-with-expander-SHA256-128"; + const DST_PRIME: &[u8] = + &hex!("515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826"); + + let dst_prime = Domain::xmd::(DST); + dst_prime.assert(DST_PRIME); + + const TEST_VECTORS_32: &[TestVector] = &[ + TestVector { + msg: b"", + msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826"), + uniform_bytes: &hex!("68a985b87eb6b46952128911f2a4412bbc302a9d759667f87f7a21d803f07235"), + }, + TestVector { + msg: b"abc", + msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000616263002000515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826"), + uniform_bytes: &hex!("d8ccab23b5985ccea865c6c97b6e5b8350e794e603b4b97902f53a8a0d605615"), + }, + TestVector { + msg: b"abcdef0123456789", + msg_prime: &hex!("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000061626364656630313233343536373839002000515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826"), + uniform_bytes: &hex!("eff31487c770a893cfb36f912fbfcbff40d5661771ca4b2cb4eafe524333f5c1"), + }, + TestVector { + msg: b"q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", + msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000713132385f7171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171002000515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826"), + uniform_bytes: &hex!("b23a1d2b4d97b2ef7785562a7e8bac7eed54ed6e97e29aa51bfe3f12ddad1ff9"), + }, + TestVector { + msg: b"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000613531325f6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161002000515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826"), + uniform_bytes: &hex!("4623227bcc01293b8c130bf771da8c298dede7383243dc0993d2d94823958c4c"), + }, + ]; + + for test_vector in TEST_VECTORS_32 { + test_vector.assert::(DST, &dst_prime)?; + } + + const TEST_VECTORS_128: &[TestVector] = &[ + TestVector { + msg: b"", + msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826"), + uniform_bytes: &hex!("af84c27ccfd45d41914fdff5df25293e221afc53d8ad2ac06d5e3e29485dadbee0d121587713a3e0dd4d5e69e93eb7cd4f5df4cd103e188cf60cb02edc3edf18eda8576c412b18ffb658e3dd6ec849469b979d444cf7b26911a08e63cf31f9dcc541708d3491184472c2c29bb749d4286b004ceb5ee6b9a7fa5b646c993f0ced"), + }, TestVector { + msg: b"abc", + msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000616263008000515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826"), + uniform_bytes: &hex!("abba86a6129e366fc877aab32fc4ffc70120d8996c88aee2fe4b32d6c7b6437a647e6c3163d40b76a73cf6a5674ef1d890f95b664ee0afa5359a5c4e07985635bbecbac65d747d3d2da7ec2b8221b17b0ca9dc8a1ac1c07ea6a1e60583e2cb00058e77b7b72a298425cd1b941ad4ec65e8afc50303a22c0f99b0509b4c895f40"), + }, TestVector { + msg: b"abcdef0123456789", + msg_prime: &hex!("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000061626364656630313233343536373839008000515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826"), + uniform_bytes: &hex!("ef904a29bffc4cf9ee82832451c946ac3c8f8058ae97d8d629831a74c6572bd9ebd0df635cd1f208e2038e760c4994984ce73f0d55ea9f22af83ba4734569d4bc95e18350f740c07eef653cbb9f87910d833751825f0ebefa1abe5420bb52be14cf489b37fe1a72f7de2d10be453b2c9d9eb20c7e3f6edc5a60629178d9478df"), + }, TestVector { + msg: b"q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", + msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000713132385f7171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171008000515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826"), + uniform_bytes: &hex!("80be107d0884f0d881bb460322f0443d38bd222db8bd0b0a5312a6fedb49c1bbd88fd75d8b9a09486c60123dfa1d73c1cc3169761b17476d3c6b7cbbd727acd0e2c942f4dd96ae3da5de368d26b32286e32de7e5a8cb2949f866a0b80c58116b29fa7fabb3ea7d520ee603e0c25bcaf0b9a5e92ec6a1fe4e0391d1cdbce8c68a"), + }, TestVector { + msg: b"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000613531325f6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161008000515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826"), + uniform_bytes: &hex!("546aff5444b5b79aa6148bd81728704c32decb73a3ba76e9e75885cad9def1d06d6792f8a7d12794e90efed817d96920d728896a4510864370c207f99bd4a608ea121700ef01ed879745ee3e4ceef777eda6d9e5e38b90c86ea6fb0b36504ba4a45d22e86f6db5dd43d98a294bebb9125d5b794e9d2a81181066eb954966a487"), + }, + ]; + + for test_vector in TEST_VECTORS_128 { + test_vector.assert::(DST, &dst_prime)?; + } + + Ok(()) + } + + #[test] + fn expand_message_xmd_sha_256_long() -> Result<()> { + const DST: &[u8] = b"QUUX-V01-CS02-with-expander-SHA256-128-long-DST-1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"; + const DST_PRIME: &[u8] = + &hex!("412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620"); + + let dst_prime = Domain::xmd::(DST); + dst_prime.assert(DST_PRIME); + + const TEST_VECTORS_32: &[TestVector] = &[ + TestVector { + msg: b"", + msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620"), + uniform_bytes: &hex!("e8dc0c8b686b7ef2074086fbdd2f30e3f8bfbd3bdf177f73f04b97ce618a3ed3"), + }, + TestVector { + msg: b"abc", + msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000616263002000412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620"), + uniform_bytes: &hex!("52dbf4f36cf560fca57dedec2ad924ee9c266341d8f3d6afe5171733b16bbb12"), + }, + TestVector { + msg: b"abcdef0123456789", + msg_prime: &hex!("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000061626364656630313233343536373839002000412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620"), + uniform_bytes: &hex!("35387dcf22618f3728e6c686490f8b431f76550b0b2c61cbc1ce7001536f4521"), + }, + TestVector { + msg: b"q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", + msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000713132385f7171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171002000412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620"), + uniform_bytes: &hex!("01b637612bb18e840028be900a833a74414140dde0c4754c198532c3a0ba42bc"), + }, + TestVector { + msg: b"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000613531325f6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161002000412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620"), + uniform_bytes: &hex!("20cce7033cabc5460743180be6fa8aac5a103f56d481cf369a8accc0c374431b"), + }, + ]; + + for test_vector in TEST_VECTORS_32 { + test_vector.assert::(DST, &dst_prime)?; + } + + const TEST_VECTORS_128: &[TestVector] = &[ + TestVector { + msg: b"", + msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620"), + uniform_bytes: &hex!("14604d85432c68b757e485c8894db3117992fc57e0e136f71ad987f789a0abc287c47876978e2388a02af86b1e8d1342e5ce4f7aaa07a87321e691f6fba7e0072eecc1218aebb89fb14a0662322d5edbd873f0eb35260145cd4e64f748c5dfe60567e126604bcab1a3ee2dc0778102ae8a5cfd1429ebc0fa6bf1a53c36f55dfc"), + }, + TestVector { + msg: b"abc", + msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000616263008000412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620"), + uniform_bytes: &hex!("1a30a5e36fbdb87077552b9d18b9f0aee16e80181d5b951d0471d55b66684914aef87dbb3626eaabf5ded8cd0686567e503853e5c84c259ba0efc37f71c839da2129fe81afdaec7fbdc0ccd4c794727a17c0d20ff0ea55e1389d6982d1241cb8d165762dbc39fb0cee4474d2cbbd468a835ae5b2f20e4f959f56ab24cd6fe267"), + }, + TestVector { + msg: b"abcdef0123456789", + msg_prime: &hex!("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000061626364656630313233343536373839008000412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620"), + uniform_bytes: &hex!("d2ecef3635d2397f34a9f86438d772db19ffe9924e28a1caf6f1c8f15603d4028f40891044e5c7e39ebb9b31339979ff33a4249206f67d4a1e7c765410bcd249ad78d407e303675918f20f26ce6d7027ed3774512ef5b00d816e51bfcc96c3539601fa48ef1c07e494bdc37054ba96ecb9dbd666417e3de289d4f424f502a982"), + }, + TestVector { + msg: b"q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", + msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000713132385f7171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171008000412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620"), + uniform_bytes: &hex!("ed6e8c036df90111410431431a232d41a32c86e296c05d426e5f44e75b9a50d335b2412bc6c91e0a6dc131de09c43110d9180d0a70f0d6289cb4e43b05f7ee5e9b3f42a1fad0f31bac6a625b3b5c50e3a83316783b649e5ecc9d3b1d9471cb5024b7ccf40d41d1751a04ca0356548bc6e703fca02ab521b505e8e45600508d32"), + }, + TestVector { + msg: b"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000613531325f6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161008000412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620"), + uniform_bytes: &hex!("78b53f2413f3c688f07732c10e5ced29a17c6a16f717179ffbe38d92d6c9ec296502eb9889af83a1928cd162e845b0d3c5424e83280fed3d10cffb2f8431f14e7a23f4c68819d40617589e4c41169d0b56e0e3535be1fd71fbb08bb70c5b5ffed953d6c14bf7618b35fc1f4c4b30538236b4b08c9fbf90462447a8ada60be495"), + }, + ]; + + for test_vector in TEST_VECTORS_128 { + test_vector.assert::(DST, &dst_prime)?; + } + + Ok(()) + } + + #[test] + fn expand_message_xmd_sha_512() -> Result<()> { + use sha2::Sha512; + + const DST: &[u8] = b"QUUX-V01-CS02-with-expander-SHA512-256"; + const DST_PRIME: &[u8] = + &hex!("515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626"); + + let dst_prime = Domain::xmd::(DST); + dst_prime.assert(DST_PRIME); + + const TEST_VECTORS_32: &[TestVector] = &[ + TestVector { + msg: b"", + msg_prime: &hex!("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626"), + uniform_bytes: &hex!("6b9a7312411d92f921c6f68ca0b6380730a1a4d982c507211a90964c394179ba"), + }, + TestVector { + msg: b"abc", + msg_prime: &hex!("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000616263002000515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626"), + uniform_bytes: &hex!("0da749f12fbe5483eb066a5f595055679b976e93abe9be6f0f6318bce7aca8dc"), + }, + TestVector { + msg: b"abcdef0123456789", + msg_prime: &hex!("000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000061626364656630313233343536373839002000515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626"), + uniform_bytes: &hex!("087e45a86e2939ee8b91100af1583c4938e0f5fc6c9db4b107b83346bc967f58"), + }, + TestVector { + msg: b"q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", + msg_prime: &hex!("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000713132385f7171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171002000515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626"), + uniform_bytes: &hex!("7336234ee9983902440f6bc35b348352013becd88938d2afec44311caf8356b3"), + }, + TestVector { + msg: b"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + msg_prime: &hex!("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000613531325f6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161002000515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626"), + uniform_bytes: &hex!("57b5f7e766d5be68a6bfe1768e3c2b7f1228b3e4b3134956dd73a59b954c66f4"), + }, + ]; + + for test_vector in TEST_VECTORS_32 { + test_vector.assert::(DST, &dst_prime)?; + } + + const TEST_VECTORS_128: &[TestVector] = &[ + TestVector { + msg: b"", + msg_prime: &hex!("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626"), + uniform_bytes: &hex!("41b037d1734a5f8df225dd8c7de38f851efdb45c372887be655212d07251b921b052b62eaed99b46f72f2ef4cc96bfaf254ebbbec091e1a3b9e4fb5e5b619d2e0c5414800a1d882b62bb5cd1778f098b8eb6cb399d5d9d18f5d5842cf5d13d7eb00a7cff859b605da678b318bd0e65ebff70bec88c753b159a805d2c89c55961"), + }, + TestVector { + msg: b"abc", + msg_prime: &hex!("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000616263008000515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626"), + uniform_bytes: &hex!("7f1dddd13c08b543f2e2037b14cefb255b44c83cc397c1786d975653e36a6b11bdd7732d8b38adb4a0edc26a0cef4bb45217135456e58fbca1703cd6032cb1347ee720b87972d63fbf232587043ed2901bce7f22610c0419751c065922b488431851041310ad659e4b23520e1772ab29dcdeb2002222a363f0c2b1c972b3efe1"), + }, + TestVector { + msg: b"abcdef0123456789", + msg_prime: &hex!("000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000061626364656630313233343536373839008000515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626"), + uniform_bytes: &hex!("3f721f208e6199fe903545abc26c837ce59ac6fa45733f1baaf0222f8b7acb0424814fcb5eecf6c1d38f06e9d0a6ccfbf85ae612ab8735dfdf9ce84c372a77c8f9e1c1e952c3a61b7567dd0693016af51d2745822663d0c2367e3f4f0bed827feecc2aaf98c949b5ed0d35c3f1023d64ad1407924288d366ea159f46287e61ac"), + }, + TestVector { + msg: b"q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", + msg_prime: &hex!("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000713132385f7171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171008000515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626"), + uniform_bytes: &hex!("b799b045a58c8d2b4334cf54b78260b45eec544f9f2fb5bd12fb603eaee70db7317bf807c406e26373922b7b8920fa29142703dd52bdf280084fb7ef69da78afdf80b3586395b433dc66cde048a258e476a561e9deba7060af40adf30c64249ca7ddea79806ee5beb9a1422949471d267b21bc88e688e4014087a0b592b695ed"), + }, + TestVector { + msg: b"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + msg_prime: &hex!("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000613531325f6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161008000515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626"), + uniform_bytes: &hex!("05b0bfef265dcee87654372777b7c44177e2ae4c13a27f103340d9cd11c86cb2426ffcad5bd964080c2aee97f03be1ca18e30a1f14e27bc11ebbd650f305269cc9fb1db08bf90bfc79b42a952b46daf810359e7bc36452684784a64952c343c52e5124cd1f71d474d5197fefc571a92929c9084ffe1112cf5eea5192ebff330b"), + }, + ]; + + for test_vector in TEST_VECTORS_128 { + test_vector.assert::(DST, &dst_prime)?; + } + + Ok(()) + } +} diff --git a/elliptic-curve/src/hash2field/expand_msg_xof.rs b/elliptic-curve/src/hash2field/expand_msg_xof.rs index 94035470f..a48aaa8bb 100644 --- a/elliptic-curve/src/hash2field/expand_msg_xof.rs +++ b/elliptic-curve/src/hash2field/expand_msg_xof.rs @@ -1,12 +1,12 @@ use super::ExpandMsg; -use crate::{hash2field::Domain, Result}; -use digest::{ExtendableOutput, ExtendableOutputDirty, Update, XofReader}; +use crate::{hash2field::Domain, Error, Result}; +use digest::{ExtendableOutput, Update, XofReader}; use generic_array::typenum::U32; /// Placeholder type for implementing expand_message_xof based on an extendable output function pub struct ExpandMsgXof where - HashT: Default + ExtendableOutput + ExtendableOutputDirty + Update, + HashT: Default + ExtendableOutput + Update, { reader: ::Reader, } @@ -14,15 +14,21 @@ where /// ExpandMsgXof implements expand_message_xof for the ExpandMsg trait impl ExpandMsg for ExpandMsgXof where - HashT: Default + ExtendableOutput + ExtendableOutputDirty + Update, + HashT: Default + ExtendableOutput + Update, { fn expand_message(msg: &[u8], dst: &'static [u8], len_in_bytes: usize) -> Result { + if len_in_bytes == 0 { + return Err(Error); + } + + let len_in_bytes = u16::try_from(len_in_bytes).map_err(|_| Error)?; + let domain = Domain::::xof::(dst); let reader = HashT::default() .chain(msg) - .chain([(len_in_bytes >> 8) as u8, len_in_bytes as u8]) + .chain(len_in_bytes.to_be_bytes()) .chain(domain.data()) - .chain([domain.len() as u8]) + .chain([domain.len()]) .finalize_xof(); Ok(Self { reader }) } @@ -31,3 +37,288 @@ where self.reader.read(okm); } } +#[cfg(test)] +mod test { + use super::*; + use core::mem; + use generic_array::{ + typenum::{U128, U32}, + ArrayLength, GenericArray, + }; + use hex_literal::hex; + use sha3::Shake128; + + fn assert_message(msg: &[u8], domain: &Domain, len_in_bytes: u16, bytes: &[u8]) { + let msg_len = msg.len(); + assert_eq!(msg, &bytes[..msg_len]); + + let len_in_bytes_len = msg_len + mem::size_of::(); + assert_eq!( + len_in_bytes.to_be_bytes(), + &bytes[msg_len..len_in_bytes_len] + ); + + let dst = len_in_bytes_len + domain.data().len(); + assert_eq!(domain.data(), &bytes[len_in_bytes_len..dst]); + + let dst_len = dst + mem::size_of::(); + assert_eq!([domain.len()], &bytes[dst..dst_len]); + + assert_eq!(dst_len, bytes.len()); + } + + struct TestVector { + msg: &'static [u8], + msg_prime: &'static [u8], + uniform_bytes: &'static [u8], + } + + impl TestVector { + fn assert(&self, dst: &'static [u8], domain: &Domain) -> Result<()> + where + HashT: Default + ExtendableOutput + Update, + L: ArrayLength, + { + assert_message::(self.msg, domain, L::to_u16(), self.msg_prime); + + let mut expander = + as ExpandMsg>::expand_message(self.msg, dst, L::to_usize())?; + + let mut uniform_bytes = GenericArray::::default(); + expander.fill_bytes(&mut uniform_bytes); + + assert_eq!(uniform_bytes.as_slice(), self.uniform_bytes); + Ok(()) + } + } + + #[test] + fn expand_message_xof_shake_128() -> Result<()> { + const DST: &[u8] = b"QUUX-V01-CS02-with-expander-SHAKE128"; + const DST_PRIME: &[u8] = + &hex!("515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824"); + + let dst_prime = Domain::::xof::(DST); + dst_prime.assert(DST_PRIME); + + const TEST_VECTORS_32: &[TestVector] = &[ + TestVector { + msg: b"", + msg_prime: &hex!("0020515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824"), + uniform_bytes: &hex!("86518c9cd86581486e9485aa74ab35ba150d1c75c88e26b7043e44e2acd735a2"), + }, + TestVector { + msg: b"abc", + msg_prime: &hex!("6162630020515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824"), + uniform_bytes: &hex!("8696af52a4d862417c0763556073f47bc9b9ba43c99b505305cb1ec04a9ab468"), + }, + TestVector { + msg: b"abcdef0123456789", + msg_prime: &hex!("616263646566303132333435363738390020515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824"), + uniform_bytes: &hex!("912c58deac4821c3509dbefa094df54b34b8f5d01a191d1d3108a2c89077acca"), + }, + TestVector { + msg: b"q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", + msg_prime: &hex!("713132385f71717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171710020515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824"), + uniform_bytes: &hex!("1adbcc448aef2a0cebc71dac9f756b22e51839d348e031e63b33ebb50faeaf3f"), + }, + TestVector { + msg: b"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + msg_prime: &hex!("613531325f61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161610020515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824"), + uniform_bytes: &hex!("df3447cc5f3e9a77da10f819218ddf31342c310778e0e4ef72bbaecee786a4fe"), + }, + ]; + + for test_vector in TEST_VECTORS_32 { + test_vector.assert::(DST, &dst_prime)?; + } + + const TEST_VECTORS_128: &[TestVector] = &[ + TestVector { + msg: b"", + msg_prime: &hex!("0080515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824"), + uniform_bytes: &hex!("7314ff1a155a2fb99a0171dc71b89ab6e3b2b7d59e38e64419b8b6294d03ffee42491f11370261f436220ef787f8f76f5b26bdcd850071920ce023f3ac46847744f4612b8714db8f5db83205b2e625d95afd7d7b4d3094d3bdde815f52850bb41ead9822e08f22cf41d615a303b0d9dde73263c049a7b9898208003a739a2e57"), + }, + TestVector { + msg: b"abc", + msg_prime: &hex!("6162630080515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824"), + uniform_bytes: &hex!("c952f0c8e529ca8824acc6a4cab0e782fc3648c563ddb00da7399f2ae35654f4860ec671db2356ba7baa55a34a9d7f79197b60ddae6e64768a37d699a78323496db3878c8d64d909d0f8a7de4927dcab0d3dbbc26cb20a49eceb0530b431cdf47bc8c0fa3e0d88f53b318b6739fbed7d7634974f1b5c386d6230c76260d5337a"), + }, + TestVector { + msg: b"abcdef0123456789", + msg_prime: &hex!("616263646566303132333435363738390080515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824"), + uniform_bytes: &hex!("19b65ee7afec6ac06a144f2d6134f08eeec185f1a890fe34e68f0e377b7d0312883c048d9b8a1d6ecc3b541cb4987c26f45e0c82691ea299b5e6889bbfe589153016d8131717ba26f07c3c14ffbef1f3eff9752e5b6183f43871a78219a75e7000fbac6a7072e2b83c790a3a5aecd9d14be79f9fd4fb180960a3772e08680495"), + }, + TestVector { + msg: b"q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", + msg_prime: &hex!("713132385f71717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171710080515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824"), + uniform_bytes: &hex!("ca1b56861482b16eae0f4a26212112362fcc2d76dcc80c93c4182ed66c5113fe41733ed68be2942a3487394317f3379856f4822a611735e50528a60e7ade8ec8c71670fec6661e2c59a09ed36386513221688b35dc47e3c3111ee8c67ff49579089d661caa29db1ef10eb6eace575bf3dc9806e7c4016bd50f3c0e2a6481ee6d"), + }, + TestVector { + msg: b"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + msg_prime: &hex!("613531325f61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161610080515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824"), + uniform_bytes: &hex!("9d763a5ce58f65c91531b4100c7266d479a5d9777ba761693d052acd37d149e7ac91c796a10b919cd74a591a1e38719fb91b7203e2af31eac3bff7ead2c195af7d88b8bc0a8adf3d1e90ab9bed6ddc2b7f655dd86c730bdeaea884e73741097142c92f0e3fc1811b699ba593c7fbd81da288a29d423df831652e3a01a9374999"), + }, + ]; + + for test_vector in TEST_VECTORS_128 { + test_vector.assert::(DST, &dst_prime)?; + } + + Ok(()) + } + + #[test] + fn expand_message_xof_shake_128_long() -> Result<()> { + const DST: &[u8] = b"QUUX-V01-CS02-with-expander-SHAKE128-long-DST-111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"; + const DST_PRIME: &[u8] = + &hex!("acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20"); + + let dst_prime = Domain::::xof::(DST); + dst_prime.assert(DST_PRIME); + + const TEST_VECTORS_32: &[TestVector] = &[ + TestVector { + msg: b"", + msg_prime: &hex!("0020acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20"), + uniform_bytes: &hex!("827c6216330a122352312bccc0c8d6e7a146c5257a776dbd9ad9d75cd880fc53"), + }, + TestVector { + msg: b"abc", + msg_prime: &hex!("6162630020acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20"), + uniform_bytes: &hex!("690c8d82c7213b4282c6cb41c00e31ea1d3e2005f93ad19bbf6da40f15790c5c"), + }, + TestVector { + msg: b"abcdef0123456789", + msg_prime: &hex!("616263646566303132333435363738390020acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20"), + uniform_bytes: &hex!("979e3a15064afbbcf99f62cc09fa9c85028afcf3f825eb0711894dcfc2f57057"), + }, + TestVector { + msg: b"q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", + msg_prime: &hex!("713132385f71717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171710020acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20"), + uniform_bytes: &hex!("c5a9220962d9edc212c063f4f65b609755a1ed96e62f9db5d1fd6adb5a8dc52b"), + }, + TestVector { + msg: b"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + msg_prime: &hex!("613531325f61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161610020acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20"), + uniform_bytes: &hex!("f7b96a5901af5d78ce1d071d9c383cac66a1dfadb508300ec6aeaea0d62d5d62"), + }, + ]; + + for test_vector in TEST_VECTORS_32 { + test_vector.assert::(DST, &dst_prime)?; + } + + const TEST_VECTORS_128: &[TestVector] = &[ + TestVector { + msg: b"", + msg_prime: &hex!("0080acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20"), + uniform_bytes: &hex!("3890dbab00a2830be398524b71c2713bbef5f4884ac2e6f070b092effdb19208c7df943dc5dcbaee3094a78c267ef276632ee2c8ea0c05363c94b6348500fae4208345dd3475fe0c834c2beac7fa7bc181692fb728c0a53d809fc8111495222ce0f38468b11becb15b32060218e285c57a60162c2c8bb5b6bded13973cd41819"), + }, + TestVector { + msg: b"abc", + msg_prime: &hex!("6162630080acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20"), + uniform_bytes: &hex!("41b7ffa7a301b5c1441495ebb9774e2a53dbbf4e54b9a1af6a20fd41eafd69ef7b9418599c5545b1ee422f363642b01d4a53449313f68da3e49dddb9cd25b97465170537d45dcbdf92391b5bdff344db4bd06311a05bca7dcd360b6caec849c299133e5c9194f4e15e3e23cfaab4003fab776f6ac0bfae9144c6e2e1c62e7d57"), + }, + TestVector { + msg: b"abcdef0123456789", + msg_prime: &hex!("616263646566303132333435363738390080acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20"), + uniform_bytes: &hex!("55317e4a21318472cd2290c3082957e1242241d9e0d04f47026f03401643131401071f01aa03038b2783e795bdfa8a3541c194ad5de7cb9c225133e24af6c86e748deb52e560569bd54ef4dac03465111a3a44b0ea490fb36777ff8ea9f1a8a3e8e0de3cf0880b4b2f8dd37d3a85a8b82375aee4fa0e909f9763319b55778e71"), + }, + TestVector { + msg: b"q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", + msg_prime: &hex!("713132385f71717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171710080acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20"), + uniform_bytes: &hex!("19fdd2639f082e31c77717ac9bb032a22ff0958382b2dbb39020cdc78f0da43305414806abf9a561cb2d0067eb2f7bc544482f75623438ed4b4e39dd9e6e2909dd858bd8f1d57cd0fce2d3150d90aa67b4498bdf2df98c0100dd1a173436ba5d0df6be1defb0b2ce55ccd2f4fc05eb7cb2c019c35d5398b85adc676da4238bc7"), + }, + TestVector { + msg: b"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + msg_prime: &hex!("613531325f61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161610080acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20"), + uniform_bytes: &hex!("945373f0b3431a103333ba6a0a34f1efab2702efde41754c4cb1d5216d5b0a92a67458d968562bde7fa6310a83f53dda1383680a276a283438d58ceebfa7ab7ba72499d4a3eddc860595f63c93b1c5e823ea41fc490d938398a26db28f61857698553e93f0574eb8c5017bfed6249491f9976aaa8d23d9485339cc85ca329308"), + }, + ]; + + for test_vector in TEST_VECTORS_128 { + test_vector.assert::(DST, &dst_prime)?; + } + + Ok(()) + } + + #[test] + fn expand_message_xof_shake_256() -> Result<()> { + use sha3::Shake256; + + const DST: &[u8] = b"QUUX-V01-CS02-with-expander-SHAKE256"; + const DST_PRIME: &[u8] = + &hex!("515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624"); + + let dst_prime = Domain::::xof::(DST); + dst_prime.assert(DST_PRIME); + + const TEST_VECTORS_32: &[TestVector] = &[ + TestVector { + msg: b"", + msg_prime: &hex!("0020515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624"), + uniform_bytes: &hex!("2ffc05c48ed32b95d72e807f6eab9f7530dd1c2f013914c8fed38c5ccc15ad76"), + }, + TestVector { + msg: b"abc", + msg_prime: &hex!("6162630020515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624"), + uniform_bytes: &hex!("b39e493867e2767216792abce1f2676c197c0692aed061560ead251821808e07"), + }, + TestVector { + msg: b"abcdef0123456789", + msg_prime: &hex!("616263646566303132333435363738390020515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624"), + uniform_bytes: &hex!("245389cf44a13f0e70af8665fe5337ec2dcd138890bb7901c4ad9cfceb054b65"), + }, + TestVector { + msg: b"q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", + msg_prime: &hex!("713132385f71717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171710020515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624"), + uniform_bytes: &hex!("719b3911821e6428a5ed9b8e600f2866bcf23c8f0515e52d6c6c019a03f16f0e"), + }, + TestVector { + msg: b"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + msg_prime: &hex!("613531325f61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161610020515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624"), + uniform_bytes: &hex!("9181ead5220b1963f1b5951f35547a5ea86a820562287d6ca4723633d17ccbbc"), + }, + ]; + + for test_vector in TEST_VECTORS_32 { + test_vector.assert::(DST, &dst_prime)?; + } + + const TEST_VECTORS_128: &[TestVector] = &[ + TestVector { + msg: b"", + msg_prime: &hex!("0080515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624"), + uniform_bytes: &hex!("7a1361d2d7d82d79e035b8880c5a3c86c5afa719478c007d96e6c88737a3f631dd74a2c88df79a4cb5e5d9f7504957c70d669ec6bfedc31e01e2bacc4ff3fdf9b6a00b17cc18d9d72ace7d6b81c2e481b4f73f34f9a7505dccbe8f5485f3d20c5409b0310093d5d6492dea4e18aa6979c23c8ea5de01582e9689612afbb353df"), + }, + TestVector { + msg: b"abc", + msg_prime: &hex!("6162630080515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624"), + uniform_bytes: &hex!("a54303e6b172909783353ab05ef08dd435a558c3197db0c132134649708e0b9b4e34fb99b92a9e9e28fc1f1d8860d85897a8e021e6382f3eea10577f968ff6df6c45fe624ce65ca25932f679a42a404bc3681efe03fcd45ef73bb3a8f79ba784f80f55ea8a3c367408f30381299617f50c8cf8fbb21d0f1e1d70b0131a7b6fbe"), + }, + TestVector { + msg: b"abcdef0123456789", + msg_prime: &hex!("616263646566303132333435363738390080515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624"), + uniform_bytes: &hex!("e42e4d9538a189316e3154b821c1bafb390f78b2f010ea404e6ac063deb8c0852fcd412e098e231e43427bd2be1330bb47b4039ad57b30ae1fc94e34993b162ff4d695e42d59d9777ea18d3848d9d336c25d2acb93adcad009bcfb9cde12286df267ada283063de0bb1505565b2eb6c90e31c48798ecdc71a71756a9110ff373"), + }, + TestVector { + msg: b"q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", + msg_prime: &hex!("713132385f71717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171710080515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624"), + uniform_bytes: &hex!("4ac054dda0a38a65d0ecf7afd3c2812300027c8789655e47aecf1ecc1a2426b17444c7482c99e5907afd9c25b991990490bb9c686f43e79b4471a23a703d4b02f23c669737a886a7ec28bddb92c3a98de63ebf878aa363a501a60055c048bea11840c4717beae7eee28c3cfa42857b3d130188571943a7bd747de831bd6444e0"), + }, + TestVector { + msg: b"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + msg_prime: &hex!("613531325f61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161610080515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624"), + uniform_bytes: &hex!("09afc76d51c2cccbc129c2315df66c2be7295a231203b8ab2dd7f95c2772c68e500bc72e20c602abc9964663b7a03a389be128c56971ce81001a0b875e7fd17822db9d69792ddf6a23a151bf470079c518279aef3e75611f8f828994a9988f4a8a256ddb8bae161e658d5a2a09bcfe839c6396dc06ee5c8ff3c22d3b1f9deb7e"), + }, + ]; + + for test_vector in TEST_VECTORS_128 { + test_vector.assert::(DST, &dst_prime)?; + } + + Ok(()) + } +} From 20132e8495eed9506aa6af2291205a87213af57a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Jan 2022 15:35:16 -0700 Subject: [PATCH 0703/1461] build(deps): bump generic-array from 0.14.4 to 0.14.5 (#864) Bumps [generic-array](https://github.com/fizyk20/generic-array) from 0.14.4 to 0.14.5. - [Release notes](https://github.com/fizyk20/generic-array/releases) - [Changelog](https://github.com/fizyk20/generic-array/blob/master/CHANGELOG.md) - [Commits](https://github.com/fizyk20/generic-array/commits) --- updated-dependencies: - dependency-name: generic-array dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2efc3e668..5820faa28 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -124,9 +124,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.4" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" dependencies = [ "typenum", "version_check", From cabb47bf5ebefed1c0f1499f165a740da9cbf70c Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 7 Jan 2022 16:01:19 -0700 Subject: [PATCH 0704/1461] elliptic-curve: refactor `hash2curve::expand_msg*` module structure (#875) The `hash2curve` module has three submodules which start with the `expand_msg` prefix: - `expand_msg` - `expand_msg_xmd` - `expand_msg_xof` This commit refactors them into a structure I think its more idiomatic, placing `xmd` and `xof` into submodules: - `expand_msg` - `xmd` - `xof` Accessing them is effecitvely the same: - `expand_msg_xmd` => `expand_msg::xmd` - `expand_msg_xof` => `expand_msg::xof` I'd cite this as precedent (which is similar, but not quite exactly the same thing): https://github.com/rust-lang/rfcs/blob/master/text/0356-no-module-prefixes.md Additionally adds `#[doc(hidden)]` to `hash2field` module --- elliptic-curve/src/hash2field.rs | 6 +----- elliptic-curve/src/hash2field/expand_msg.rs | 3 +++ .../src/hash2field/{expand_msg_xmd.rs => expand_msg/xmd.rs} | 0 .../src/hash2field/{expand_msg_xof.rs => expand_msg/xof.rs} | 0 elliptic-curve/src/lib.rs | 2 +- 5 files changed, 5 insertions(+), 6 deletions(-) rename elliptic-curve/src/hash2field/{expand_msg_xmd.rs => expand_msg/xmd.rs} (100%) rename elliptic-curve/src/hash2field/{expand_msg_xof.rs => expand_msg/xof.rs} (100%) diff --git a/elliptic-curve/src/hash2field.rs b/elliptic-curve/src/hash2field.rs index 8d0c08808..953855cbc 100644 --- a/elliptic-curve/src/hash2field.rs +++ b/elliptic-curve/src/hash2field.rs @@ -1,10 +1,6 @@ mod expand_msg; -mod expand_msg_xmd; -mod expand_msg_xof; -pub use expand_msg::*; -pub use expand_msg_xmd::*; -pub use expand_msg_xof::*; +pub use expand_msg::{xmd::*, xof::*, *}; use crate::Result; use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; diff --git a/elliptic-curve/src/hash2field/expand_msg.rs b/elliptic-curve/src/hash2field/expand_msg.rs index 49537f150..7ab938369 100644 --- a/elliptic-curve/src/hash2field/expand_msg.rs +++ b/elliptic-curve/src/hash2field/expand_msg.rs @@ -1,3 +1,6 @@ +pub(super) mod xmd; +pub(super) mod xof; + use crate::Result; use digest::{Digest, ExtendableOutput, Update, XofReader}; use generic_array::typenum::{IsLess, U256}; diff --git a/elliptic-curve/src/hash2field/expand_msg_xmd.rs b/elliptic-curve/src/hash2field/expand_msg/xmd.rs similarity index 100% rename from elliptic-curve/src/hash2field/expand_msg_xmd.rs rename to elliptic-curve/src/hash2field/expand_msg/xmd.rs diff --git a/elliptic-curve/src/hash2field/expand_msg_xof.rs b/elliptic-curve/src/hash2field/expand_msg/xof.rs similarity index 100% rename from elliptic-curve/src/hash2field/expand_msg_xof.rs rename to elliptic-curve/src/hash2field/expand_msg/xof.rs diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index b67121f20..e266f6fca 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -96,7 +96,7 @@ mod jwk; /// Traits for hashing to field elements #[cfg(feature = "hash2curve")] -#[cfg_attr(docsrs, doc(cfg(feature = "hash2curve")))] +#[doc(hidden)] pub mod hash2field; /// Traits for hashing byte sequences to curve points From c8b73e556e060d53d500d662d6ecaa7f2c261b39 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 7 Jan 2022 17:29:24 -0700 Subject: [PATCH 0705/1461] elliptic-curve: hash2curve rustdoc improvements (#877) - Moves doc comments on `mod ` into toplevel module comments. These have the same effect, but also self-document the module you are looking at, and are more amenable to rich top-of-module documentation. - Breaks apart the rustdoc "headline" from the rest of the comments for better formatting on the HTML rendering. - Uses backticks and [`TypeName`] syntax to linkify type names where appropriate. --- elliptic-curve/src/hash2curve.rs | 9 ++-- elliptic-curve/src/hash2curve/group_digest.rs | 44 ++++++++++--------- elliptic-curve/src/hash2curve/isogeny.rs | 6 ++- elliptic-curve/src/hash2curve/map2curve.rs | 2 + elliptic-curve/src/hash2curve/osswu.rs | 6 ++- elliptic-curve/src/hash2field.rs | 13 ++++-- elliptic-curve/src/hash2field/expand_msg.rs | 7 ++- .../src/hash2field/expand_msg/xmd.rs | 4 +- .../src/hash2field/expand_msg/xof.rs | 6 ++- elliptic-curve/src/lib.rs | 2 - 10 files changed, 61 insertions(+), 38 deletions(-) diff --git a/elliptic-curve/src/hash2curve.rs b/elliptic-curve/src/hash2curve.rs index 5b81eca8f..1ac1d35fe 100644 --- a/elliptic-curve/src/hash2curve.rs +++ b/elliptic-curve/src/hash2curve.rs @@ -1,11 +1,10 @@ -/// Traits for handling hash to curve +//! Traits for hashing byte sequences to curve points. +//! +//! + mod group_digest; -/// Traits for mapping an isogeny to another curve -/// mod isogeny; -/// Traits for mapping field elements to points on the curve mod map2curve; -/// Optimized simplified Shallue-van de Woestijne-Ulas methods mod osswu; pub use group_digest::*; diff --git a/elliptic-curve/src/hash2curve/group_digest.rs b/elliptic-curve/src/hash2curve/group_digest.rs index 837a76684..4fac9c53c 100644 --- a/elliptic-curve/src/hash2curve/group_digest.rs +++ b/elliptic-curve/src/hash2curve/group_digest.rs @@ -1,3 +1,5 @@ +//! Traits for handling hash to curve. + use super::MapToCurve; use crate::{ hash2field::{hash_to_field, ExpandMsg, FromOkm}, @@ -12,25 +14,26 @@ pub trait GroupDigest { /// The resulting group element type Output: CofactorGroup; - /// Computes the hash to curve routine according to - /// - /// which says - /// Uniform encoding from byte strings to points in G. - /// That is, the distribution of its output is statistically close - /// to uniform in G. - /// This function is suitable for most applications requiring a random - /// oracle returning points in G assuming a cryptographically secure - /// hash function is used. + /// Computes the hash to curve routine. + /// + /// From : + /// + /// > Uniform encoding from byte strings to points in G. + /// > That is, the distribution of its output is statistically close + /// > to uniform in G. + /// > This function is suitable for most applications requiring a random + /// > oracle returning points in G assuming a cryptographically secure + /// > hash function is used. /// - /// Examples + /// # Examples /// - /// Using a fixed size hash function + /// ## Using a fixed size hash function /// /// ```ignore /// let pt = ProjectivePoint::hash_from_bytes::>(b"test data", b"CURVE_XMD:SHA-256_SSWU_RO_"); /// ``` /// - /// Using an extendable output function + /// ## Using an extendable output function /// /// ```ignore /// let pt = ProjectivePoint::hash_from_bytes::>(b"test data", b"CURVE_XOF:SHAKE-256_SSWU_RO_"); @@ -54,14 +57,15 @@ pub trait GroupDigest { Ok(q0.clear_cofactor() + q1.clear_cofactor()) } - /// Computes the encode to curve routine according to - /// - /// which says - /// Nonuniform encoding from byte strings to - /// points in G. That is, the distribution of its output is not - /// uniformly random in G: the set of possible outputs of - /// encode_to_curve is only a fraction of the points in G, and some - /// points in this set are more likely to be output than others. + /// Computes the encode to curve routine. + /// + /// From : + /// + /// > Nonuniform encoding from byte strings to + /// > points in G. That is, the distribution of its output is not + /// > uniformly random in G: the set of possible outputs of + /// > encode_to_curve is only a fraction of the points in G, and some + /// > points in this set are more likely to be output than others. fn encode_from_bytes(msg: &[u8], dst: &'static [u8]) -> Result { let mut u = [Self::FieldElement::default()]; hash_to_field::(msg, dst, &mut u)?; diff --git a/elliptic-curve/src/hash2curve/isogeny.rs b/elliptic-curve/src/hash2curve/isogeny.rs index abf1da27c..fc197246a 100644 --- a/elliptic-curve/src/hash2curve/isogeny.rs +++ b/elliptic-curve/src/hash2curve/isogeny.rs @@ -1,3 +1,7 @@ +//! Traits for mapping an isogeny to another curve +//! +//! + use core::ops::{AddAssign, Mul}; use ff::Field; use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; @@ -14,7 +18,7 @@ pub struct IsogenyCoefficients> { pub yden: &'static [F], } -/// The Isogeny methods to map to another curve +/// The [`Isogeny`] methods to map to another curve. pub trait Isogeny: Field + AddAssign + Mul { /// The maximum number of coefficients type Degree: ArrayLength; diff --git a/elliptic-curve/src/hash2curve/map2curve.rs b/elliptic-curve/src/hash2curve/map2curve.rs index 0708a2cd8..6092e57ba 100644 --- a/elliptic-curve/src/hash2curve/map2curve.rs +++ b/elliptic-curve/src/hash2curve/map2curve.rs @@ -1,3 +1,5 @@ +//! Traits for mapping field elements to points on the curve. + /// Trait for converting field elements into a point /// via a mapping method like Simplified Shallue-van de Woestijne-Ulas /// or Elligator diff --git a/elliptic-curve/src/hash2curve/osswu.rs b/elliptic-curve/src/hash2curve/osswu.rs index e10652142..f803863b1 100644 --- a/elliptic-curve/src/hash2curve/osswu.rs +++ b/elliptic-curve/src/hash2curve/osswu.rs @@ -1,3 +1,7 @@ +//! Optimized simplified Shallue-van de Woestijne-Ulas methods. +//! +//! + use ff::Field; use subtle::Choice; @@ -34,7 +38,7 @@ pub trait OsswuMap: Field + Sgn0 { /// should be for isogeny where A≠0 and B≠0. const PARAMS: OsswuMapParams; - /// Convert this field element into an affine point on the ellliptic curve + /// Convert this field element into an affine point on the elliptic curve /// returning (X, Y). For Weierstrass curves having A==0 or B==0 /// the result is a point on an isogeny. fn osswu(&self) -> (Self, Self) { diff --git a/elliptic-curve/src/hash2field.rs b/elliptic-curve/src/hash2field.rs index 953855cbc..94faa958c 100644 --- a/elliptic-curve/src/hash2field.rs +++ b/elliptic-curve/src/hash2field.rs @@ -1,3 +1,7 @@ +//! Traits for hashing to field elements. +//! +//! + mod expand_msg; pub use expand_msg::{xmd::*, xof::*, *}; @@ -5,16 +9,17 @@ pub use expand_msg::{xmd::*, xof::*, *}; use crate::Result; use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; -/// The trait for helping to convert to a scalar +/// The trait for helping to convert to a field element. pub trait FromOkm { - /// The number of bytes needed to convert to a scalar + /// The number of bytes needed to convert to a field element. type Length: ArrayLength; - /// Convert a byte sequence into a scalar + /// Convert a byte sequence into a field element. fn from_okm(data: &GenericArray) -> Self; } -/// Convert an arbitrary byte sequence according to +/// Convert an arbitrary byte sequence into a field element. +/// /// pub fn hash_to_field(data: &[u8], domain: &'static [u8], out: &mut [T]) -> Result<()> where diff --git a/elliptic-curve/src/hash2field/expand_msg.rs b/elliptic-curve/src/hash2field/expand_msg.rs index 7ab938369..90e81e1f6 100644 --- a/elliptic-curve/src/hash2field/expand_msg.rs +++ b/elliptic-curve/src/hash2field/expand_msg.rs @@ -1,3 +1,5 @@ +//! `expand_message` interface `for hash_to_field`. + pub(super) mod xmd; pub(super) mod xof; @@ -11,9 +13,10 @@ const OVERSIZE_DST_SALT: &[u8] = b"H2C-OVERSIZE-DST-"; /// Maximum domain separation tag length const MAX_DST_LEN: usize = 255; -/// Trait for types implementing expand_message interface for hash_to_field +/// Trait for types implementing expand_message interface for `hash_to_field`. pub trait ExpandMsg: Sized { - /// Expands `msg` to the required number of bytes + /// Expands `msg` to the required number of bytes. + /// /// Returns an expander that can be used to call `read` until enough /// bytes have been consumed fn expand_message(msg: &[u8], dst: &'static [u8], len_in_bytes: usize) -> Result; diff --git a/elliptic-curve/src/hash2field/expand_msg/xmd.rs b/elliptic-curve/src/hash2field/expand_msg/xmd.rs index 2e0a8fd17..a1e96d969 100644 --- a/elliptic-curve/src/hash2field/expand_msg/xmd.rs +++ b/elliptic-curve/src/hash2field/expand_msg/xmd.rs @@ -1,3 +1,5 @@ +//! `expand_message_xmd` based on a hash function. + use super::{Domain, ExpandMsg}; use crate::{Error, Result}; use digest::{ @@ -8,7 +10,7 @@ use digest::{ BlockInput, Digest, }; -/// Placeholder type for implementing expand_message_xmd based on a hash function +/// Placeholder type for implementing `expand_message_xmd` based on a hash function pub struct ExpandMsgXmd where HashT: Digest + BlockInput, diff --git a/elliptic-curve/src/hash2field/expand_msg/xof.rs b/elliptic-curve/src/hash2field/expand_msg/xof.rs index a48aaa8bb..f30cb370e 100644 --- a/elliptic-curve/src/hash2field/expand_msg/xof.rs +++ b/elliptic-curve/src/hash2field/expand_msg/xof.rs @@ -1,9 +1,11 @@ +//! `expand_message_xof` for the `ExpandMsg` trait + use super::ExpandMsg; use crate::{hash2field::Domain, Error, Result}; use digest::{ExtendableOutput, Update, XofReader}; use generic_array::typenum::U32; -/// Placeholder type for implementing expand_message_xof based on an extendable output function +/// Placeholder type for implementing `expand_message_xof` based on an extendable output function pub struct ExpandMsgXof where HashT: Default + ExtendableOutput + Update, @@ -11,7 +13,7 @@ where reader: ::Reader, } -/// ExpandMsgXof implements expand_message_xof for the ExpandMsg trait +/// ExpandMsgXof implements `expand_message_xof` for the [`ExpandMsg`] trait impl ExpandMsg for ExpandMsgXof where HashT: Default + ExtendableOutput + Update, diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index e266f6fca..0212e77c4 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -94,12 +94,10 @@ pub mod ecdh; #[cfg(feature = "jwk")] mod jwk; -/// Traits for hashing to field elements #[cfg(feature = "hash2curve")] #[doc(hidden)] pub mod hash2field; -/// Traits for hashing byte sequences to curve points #[cfg(feature = "hash2curve")] #[cfg_attr(docsrs, doc(cfg(feature = "hash2curve")))] pub mod hash2curve; From e844f78cccb89c9e9250f687eaa4746d1830b365 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Tue, 11 Jan 2022 14:03:17 +0100 Subject: [PATCH 0706/1461] Improve API for hash2curve functions (#876) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Allow methods to accept multiple `data`/`msg`s by using `&[&[u8]]`, á la `Hkdf::expand_multi_info()` - Implement `hash_to_scalar`, got an implementation for P-256 already working with test vectors. - Remove `'static` requirement for `dst`. The goal here is to make this usable for voprf. VOPRF sometimes builds complex `msg`s that are impossible to concat without allocation, this is why the multi-message API was necessary. I would even prefer just to take an `Iterator`. The `'static` requirement doesn't work for VOPRF because it needs to build the `dst` from multiple parts that are party derived from associated types from traits, this can't be used in const to build a `&'static [u8]` in Rust right now. --- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/hash2curve/group_digest.rs | 63 +++++++-- elliptic-curve/src/hash2field.rs | 14 +- elliptic-curve/src/hash2field/expand_msg.rs | 24 +++- .../src/hash2field/expand_msg/xmd.rs | 131 +++++++++++------- .../src/hash2field/expand_msg/xof.rs | 44 ++++-- 6 files changed, 201 insertions(+), 77 deletions(-) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 9e476cda1..30528f54b 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -49,7 +49,7 @@ alloc = ["der/alloc", "sec1/alloc", "zeroize/alloc"] # todo: use weak activation arithmetic = ["ff", "group"] bits = ["arithmetic", "ff/bits"] dev = ["arithmetic", "hex-literal", "pem", "pkcs8"] -hash2curve = ["digest", "ff", "group"] +hash2curve = ["arithmetic", "digest"] ecdh = ["arithmetic"] hazmat = [] jwk = ["alloc", "base64ct/alloc", "serde", "serde_json", "zeroize/alloc"] diff --git a/elliptic-curve/src/hash2curve/group_digest.rs b/elliptic-curve/src/hash2curve/group_digest.rs index 4fac9c53c..644d149a7 100644 --- a/elliptic-curve/src/hash2curve/group_digest.rs +++ b/elliptic-curve/src/hash2curve/group_digest.rs @@ -3,12 +3,12 @@ use super::MapToCurve; use crate::{ hash2field::{hash_to_field, ExpandMsg, FromOkm}, - Result, + ProjectiveArithmetic, Result, }; use group::cofactor::CofactorGroup; /// Adds hashing arbitrary byte sequences to a valid group element -pub trait GroupDigest { +pub trait GroupDigest: ProjectiveArithmetic { /// The field element representation for a group value with multiple elements type FieldElement: FromOkm + MapToCurve + Default + Copy; /// The resulting group element @@ -30,18 +30,30 @@ pub trait GroupDigest { /// ## Using a fixed size hash function /// /// ```ignore - /// let pt = ProjectivePoint::hash_from_bytes::>(b"test data", b"CURVE_XMD:SHA-256_SSWU_RO_"); + /// let pt = ProjectivePoint::hash_from_bytes::>(b"test data", b"CURVE_XMD:SHA-256_SSWU_RO_"); /// ``` /// /// ## Using an extendable output function /// /// ```ignore - /// let pt = ProjectivePoint::hash_from_bytes::>(b"test data", b"CURVE_XOF:SHAKE-256_SSWU_RO_"); + /// let pt = ProjectivePoint::hash_from_bytes::>(b"test data", b"CURVE_XOF:SHAKE-256_SSWU_RO_"); /// ``` /// - fn hash_from_bytes(msg: &[u8], dst: &'static [u8]) -> Result { + /// # Errors + /// See implementors of [`ExpandMsg`] for errors: + /// - [`ExpandMsgXmd`] + /// - [`ExpandMsgXof`] + /// + /// `len_in_bytes = T::Length * 2` + /// + /// [`ExpandMsgXmd`]: crate::hash2field::ExpandMsgXmd + /// [`ExpandMsgXof`]: crate::hash2field::ExpandMsgXof + fn hash_from_bytes<'a, X: ExpandMsg<'a>>( + msgs: &[&[u8]], + dst: &'a [u8], + ) -> Result { let mut u = [Self::FieldElement::default(), Self::FieldElement::default()]; - hash_to_field::(msg, dst, &mut u)?; + hash_to_field::(msgs, dst, &mut u)?; let q0 = u[0].map_to_curve(); let q1 = u[1].map_to_curve(); // Ideally we could add and then clear cofactor once @@ -66,10 +78,45 @@ pub trait GroupDigest { /// > uniformly random in G: the set of possible outputs of /// > encode_to_curve is only a fraction of the points in G, and some /// > points in this set are more likely to be output than others. - fn encode_from_bytes(msg: &[u8], dst: &'static [u8]) -> Result { + /// + /// # Errors + /// See implementors of [`ExpandMsg`] for errors: + /// - [`ExpandMsgXmd`] + /// - [`ExpandMsgXof`] + /// + /// `len_in_bytes = T::Length` + /// + /// [`ExpandMsgXmd`]: crate::hash2field::ExpandMsgXmd + /// [`ExpandMsgXof`]: crate::hash2field::ExpandMsgXof + fn encode_from_bytes<'a, X: ExpandMsg<'a>>( + msgs: &[&[u8]], + dst: &'a [u8], + ) -> Result { let mut u = [Self::FieldElement::default()]; - hash_to_field::(msg, dst, &mut u)?; + hash_to_field::(msgs, dst, &mut u)?; let q0 = u[0].map_to_curve(); Ok(q0.clear_cofactor()) } + + /// Computes the hash to field routine according to + /// + /// and returns a scalar. + /// + /// # Errors + /// See implementors of [`ExpandMsg`] for errors: + /// - [`ExpandMsgXmd`] + /// - [`ExpandMsgXof`] + /// + /// `len_in_bytes = T::Length` + /// + /// [`ExpandMsgXmd`]: crate::hash2field::ExpandMsgXmd + /// [`ExpandMsgXof`]: crate::hash2field::ExpandMsgXof + fn hash_to_scalar<'a, X: ExpandMsg<'a>>(msgs: &[&[u8]], dst: &'a [u8]) -> Result + where + Self::Scalar: FromOkm, + { + let mut u = [Self::Scalar::default()]; + hash_to_field::(msgs, dst, &mut u)?; + Ok(u[0]) + } } diff --git a/elliptic-curve/src/hash2field.rs b/elliptic-curve/src/hash2field.rs index 94faa958c..369e96cf5 100644 --- a/elliptic-curve/src/hash2field.rs +++ b/elliptic-curve/src/hash2field.rs @@ -21,9 +21,19 @@ pub trait FromOkm { /// Convert an arbitrary byte sequence into a field element. /// /// -pub fn hash_to_field(data: &[u8], domain: &'static [u8], out: &mut [T]) -> Result<()> +/// +/// # Errors +/// See implementors of [`ExpandMsg`] for errors: +/// - [`ExpandMsgXmd`] +/// - [`ExpandMsgXof`] +/// +/// `len_in_bytes = T::Length * out.len()` +/// +/// [`ExpandMsgXmd`]: crate::hash2field::ExpandMsgXmd +/// [`ExpandMsgXof`]: crate::hash2field::ExpandMsgXof +pub fn hash_to_field<'a, E, T>(data: &[&[u8]], domain: &'a [u8], out: &mut [T]) -> Result<()> where - E: ExpandMsg, + E: ExpandMsg<'a>, T: FromOkm + Default, { let len_in_bytes = T::Length::to_usize() * out.len(); diff --git a/elliptic-curve/src/hash2field/expand_msg.rs b/elliptic-curve/src/hash2field/expand_msg.rs index 90e81e1f6..fda9fcc83 100644 --- a/elliptic-curve/src/hash2field/expand_msg.rs +++ b/elliptic-curve/src/hash2field/expand_msg.rs @@ -14,13 +14,23 @@ const OVERSIZE_DST_SALT: &[u8] = b"H2C-OVERSIZE-DST-"; const MAX_DST_LEN: usize = 255; /// Trait for types implementing expand_message interface for `hash_to_field`. -pub trait ExpandMsg: Sized { +/// +/// # Errors +/// See implementors of [`ExpandMsg`] for errors. +pub trait ExpandMsg<'a> { + /// Type holding data for the [`Expander`]. + type Expander: Expander + Sized; + /// Expands `msg` to the required number of bytes. /// /// Returns an expander that can be used to call `read` until enough /// bytes have been consumed - fn expand_message(msg: &[u8], dst: &'static [u8], len_in_bytes: usize) -> Result; + fn expand_message(msgs: &[&[u8]], dst: &'a [u8], len_in_bytes: usize) + -> Result; +} +/// Expander that, call `read` until enough bytes have been consumed. +pub trait Expander { /// Fill the array with the expanded bytes fn fill_bytes(&mut self, okm: &mut [u8]); } @@ -30,21 +40,21 @@ pub trait ExpandMsg: Sized { /// Implements [section 5.4.3 of `draft-irtf-cfrg-hash-to-curve-13`][dst]. /// /// [dst]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-13#section-5.4.3 -pub(crate) enum Domain +pub(crate) enum Domain<'a, L> where L: ArrayLength + IsLess, { /// > 255 Hashed(GenericArray), /// <= 255 - Array(&'static [u8]), + Array(&'a [u8]), } -impl Domain +impl<'a, L> Domain<'a, L> where L: ArrayLength + IsLess, { - pub fn xof(dst: &'static [u8]) -> Self + pub fn xof(dst: &'a [u8]) -> Self where X: Default + ExtendableOutput + Update, { @@ -61,7 +71,7 @@ where } } - pub fn xmd(dst: &'static [u8]) -> Self + pub fn xmd(dst: &'a [u8]) -> Self where X: Digest, { diff --git a/elliptic-curve/src/hash2field/expand_msg/xmd.rs b/elliptic-curve/src/hash2field/expand_msg/xmd.rs index a1e96d969..8e05e715b 100644 --- a/elliptic-curve/src/hash2field/expand_msg/xmd.rs +++ b/elliptic-curve/src/hash2field/expand_msg/xmd.rs @@ -1,6 +1,8 @@ //! `expand_message_xmd` based on a hash function. -use super::{Domain, ExpandMsg}; +use core::marker::PhantomData; + +use super::{Domain, ExpandMsg, Expander}; use crate::{Error, Result}; use digest::{ generic_array::{ @@ -11,52 +13,19 @@ use digest::{ }; /// Placeholder type for implementing `expand_message_xmd` based on a hash function -pub struct ExpandMsgXmd +/// +/// # Errors +/// - `len_in_bytes == 0` +/// - `len_in_bytes > u16::MAX` +/// - `len_in_bytes > 255 * HashT::OutputSize` +pub struct ExpandMsgXmd(PhantomData) where HashT: Digest + BlockInput, HashT::OutputSize: IsLess, - HashT::OutputSize: IsLessOrEqual, -{ - b_0: GenericArray, - b_vals: GenericArray, - domain: Domain, - index: u8, - offset: usize, - ell: u8, -} - -impl ExpandMsgXmd -where - HashT: Digest + BlockInput, - HashT::OutputSize: IsLess, - HashT::OutputSize: IsLessOrEqual, -{ - fn next(&mut self) -> bool { - if self.index < self.ell { - self.index += 1; - self.offset = 0; - // b_0 XOR b_(idx - 1) - let mut tmp = GenericArray::::default(); - self.b_0 - .iter() - .zip(&self.b_vals[..]) - .enumerate() - .for_each(|(j, (b0val, bi1val))| tmp[j] = b0val ^ bi1val); - self.b_vals = HashT::new() - .chain(tmp) - .chain([self.index]) - .chain(self.domain.data()) - .chain([self.domain.len()]) - .finalize(); - true - } else { - false - } - } -} + HashT::OutputSize: IsLessOrEqual; /// ExpandMsgXmd implements expand_message_xmd for the ExpandMsg trait -impl ExpandMsg for ExpandMsgXmd +impl<'a, HashT> ExpandMsg<'a> for ExpandMsgXmd where HashT: Digest + BlockInput, // If `len_in_bytes` is bigger then 256, length of the `DST` will depend on @@ -67,7 +36,13 @@ where // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-13.html#section-5.4.1-4 HashT::OutputSize: IsLessOrEqual, { - fn expand_message(msg: &[u8], dst: &'static [u8], len_in_bytes: usize) -> Result { + type Expander = ExpanderXmd<'a, HashT>; + + fn expand_message( + msgs: &[&[u8]], + dst: &'a [u8], + len_in_bytes: usize, + ) -> Result { if len_in_bytes == 0 { return Err(Error); } @@ -78,9 +53,13 @@ where let ell = u8::try_from((len_in_bytes + b_in_bytes - 1) / b_in_bytes).map_err(|_| Error)?; let domain = Domain::xmd::(dst); - let b_0 = HashT::new() - .chain(GenericArray::::default()) - .chain(msg) + let mut b_0 = HashT::new().chain(GenericArray::::default()); + + for msg in msgs { + b_0 = b_0.chain(msg); + } + + let b_0 = b_0 .chain(len_in_bytes_u16.to_be_bytes()) .chain([0]) .chain(domain.data()) @@ -94,7 +73,7 @@ where .chain([domain.len()]) .finalize(); - Ok(Self { + Ok(ExpanderXmd { b_0, b_vals, domain, @@ -103,7 +82,59 @@ where ell, }) } +} +/// [`Expander`] type for [`ExpandMsgXmd`]. +pub struct ExpanderXmd<'a, HashT> +where + HashT: Digest + BlockInput, + HashT::OutputSize: IsLess, + HashT::OutputSize: IsLessOrEqual, +{ + b_0: GenericArray, + b_vals: GenericArray, + domain: Domain<'a, HashT::OutputSize>, + index: u8, + offset: usize, + ell: u8, +} + +impl<'a, HashT> ExpanderXmd<'a, HashT> +where + HashT: Digest + BlockInput, + HashT::OutputSize: IsLess, + HashT::OutputSize: IsLessOrEqual, +{ + fn next(&mut self) -> bool { + if self.index < self.ell { + self.index += 1; + self.offset = 0; + // b_0 XOR b_(idx - 1) + let mut tmp = GenericArray::::default(); + self.b_0 + .iter() + .zip(&self.b_vals[..]) + .enumerate() + .for_each(|(j, (b0val, bi1val))| tmp[j] = b0val ^ bi1val); + self.b_vals = HashT::new() + .chain(tmp) + .chain([self.index]) + .chain(self.domain.data()) + .chain([self.domain.len()]) + .finalize(); + true + } else { + false + } + } +} + +impl<'a, HashT> Expander for ExpanderXmd<'a, HashT> +where + HashT: Digest + BlockInput, + HashT::OutputSize: IsLess, + HashT::OutputSize: IsLessOrEqual, +{ fn fill_bytes(&mut self, okm: &mut [u8]) { for b in okm { if self.offset == self.b_vals.len() && !self.next() { @@ -128,7 +159,7 @@ mod test { fn assert_message( msg: &[u8], - domain: &Domain, + domain: &Domain<'_, HashT::OutputSize>, len_in_bytes: u16, bytes: &[u8], ) where @@ -169,7 +200,7 @@ mod test { fn assert>( &self, dst: &'static [u8], - domain: &Domain, + domain: &Domain<'_, HashT::OutputSize>, ) -> Result<()> where HashT: Digest + BlockInput, @@ -178,7 +209,7 @@ mod test { assert_message::(self.msg, domain, L::to_u16(), self.msg_prime); let mut expander = - as ExpandMsg>::expand_message(self.msg, dst, L::to_usize())?; + ExpandMsgXmd::::expand_message(&[self.msg], dst, L::to_usize())?; let mut uniform_bytes = GenericArray::::default(); expander.fill_bytes(&mut uniform_bytes); diff --git a/elliptic-curve/src/hash2field/expand_msg/xof.rs b/elliptic-curve/src/hash2field/expand_msg/xof.rs index f30cb370e..d7ca714cf 100644 --- a/elliptic-curve/src/hash2field/expand_msg/xof.rs +++ b/elliptic-curve/src/hash2field/expand_msg/xof.rs @@ -1,11 +1,15 @@ //! `expand_message_xof` for the `ExpandMsg` trait -use super::ExpandMsg; -use crate::{hash2field::Domain, Error, Result}; +use super::{Domain, ExpandMsg, Expander}; +use crate::{Error, Result}; use digest::{ExtendableOutput, Update, XofReader}; use generic_array::typenum::U32; /// Placeholder type for implementing `expand_message_xof` based on an extendable output function +/// +/// # Errors +/// - `len_in_bytes == 0` +/// - `len_in_bytes > u16::MAX` pub struct ExpandMsgXof where HashT: Default + ExtendableOutput + Update, @@ -14,11 +18,17 @@ where } /// ExpandMsgXof implements `expand_message_xof` for the [`ExpandMsg`] trait -impl ExpandMsg for ExpandMsgXof +impl<'a, HashT> ExpandMsg<'a> for ExpandMsgXof where HashT: Default + ExtendableOutput + Update, { - fn expand_message(msg: &[u8], dst: &'static [u8], len_in_bytes: usize) -> Result { + type Expander = Self; + + fn expand_message( + msgs: &[&[u8]], + dst: &'a [u8], + len_in_bytes: usize, + ) -> Result { if len_in_bytes == 0 { return Err(Error); } @@ -26,19 +36,30 @@ where let len_in_bytes = u16::try_from(len_in_bytes).map_err(|_| Error)?; let domain = Domain::::xof::(dst); - let reader = HashT::default() - .chain(msg) + let mut reader = HashT::default(); + + for msg in msgs { + reader = reader.chain(msg); + } + + let reader = reader .chain(len_in_bytes.to_be_bytes()) .chain(domain.data()) .chain([domain.len()]) .finalize_xof(); Ok(Self { reader }) } +} +impl Expander for ExpandMsgXof +where + HashT: Default + ExtendableOutput + Update, +{ fn fill_bytes(&mut self, okm: &mut [u8]) { self.reader.read(okm); } } + #[cfg(test)] mod test { use super::*; @@ -50,7 +71,12 @@ mod test { use hex_literal::hex; use sha3::Shake128; - fn assert_message(msg: &[u8], domain: &Domain, len_in_bytes: u16, bytes: &[u8]) { + fn assert_message( + msg: &[u8], + domain: &Domain<'_, U32>, + len_in_bytes: u16, + bytes: &[u8], + ) { let msg_len = msg.len(); assert_eq!(msg, &bytes[..msg_len]); @@ -76,7 +102,7 @@ mod test { } impl TestVector { - fn assert(&self, dst: &'static [u8], domain: &Domain) -> Result<()> + fn assert(&self, dst: &'static [u8], domain: &Domain<'_, U32>) -> Result<()> where HashT: Default + ExtendableOutput + Update, L: ArrayLength, @@ -84,7 +110,7 @@ mod test { assert_message::(self.msg, domain, L::to_u16(), self.msg_prime); let mut expander = - as ExpandMsg>::expand_message(self.msg, dst, L::to_usize())?; + ExpandMsgXof::::expand_message(&[self.msg], dst, L::to_usize())?; let mut uniform_bytes = GenericArray::::default(); expander.fill_bytes(&mut uniform_bytes); From d7e21f847f8faf8629e21de14b17a8b45fc94d64 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Thu, 13 Jan 2022 15:37:54 +0100 Subject: [PATCH 0707/1461] Introduce `VoprfParameters` trait (#878) --- .github/workflows/elliptic-curve.yml | 3 ++- elliptic-curve/Cargo.toml | 1 + elliptic-curve/src/lib.rs | 17 +++++++++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index 370a7a466..338812ccf 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -49,9 +49,10 @@ jobs: - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features pkcs8 - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features sec1 - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features serde + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features voprf - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features pkcs8,sec1 - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features pem,pkcs8,sec1 - - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,digest,ecdh,hazmat,hash2curve,jwk,pem,pkcs8,sec1,serde + - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features alloc,digest,ecdh,hazmat,hash2curve,jwk,pem,pkcs8,sec1,serde,voprf test: runs-on: ubuntu-latest diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 30528f54b..8602a6f44 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -56,6 +56,7 @@ jwk = ["alloc", "base64ct/alloc", "serde", "serde_json", "zeroize/alloc"] pem = ["alloc", "arithmetic", "pem-rfc7468/alloc", "pkcs8", "sec1/pem"] pkcs8 = ["sec1/pkcs8"] std = ["alloc", "rand_core/std"] +voprf = ["digest"] [package.metadata.docs.rs] features = ["arithmetic", "ecdh", "jwk", "pem", "std"] diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 0212e77c4..7730cafa0 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -223,3 +223,20 @@ pub trait AlgorithmParameters: Curve { } } } + +/// Elliptic curve parameters used by VOPRF. +#[cfg(feature = "voprf")] +#[cfg_attr(docsrs, doc(cfg(feature = "voprf")))] +pub trait VoprfParameters: Curve { + /// The `ID` parameter which identifies a particular elliptic curve + /// as defined in [section 4 of `draft-irtf-cfrg-voprf-08`][voprf]. + /// + /// [voprf]: https://www.ietf.org/archive/id/draft-irtf-cfrg-voprf-08.html#section-4 + const ID: u16; + + /// The `Hash` parameter which assigns a particular hash function to this + /// ciphersuite as defined in [section 4 of `draft-irtf-cfrg-voprf-08`][voprf]. + /// + /// [voprf]: https://www.ietf.org/archive/id/draft-irtf-cfrg-voprf-08.html#section-4 + type Hash: digest::Digest; +} From e484b4db9647d8a9fbe3c14dbbbb70ccc22f3d3e Mon Sep 17 00:00:00 2001 From: daxpedda Date: Fri, 14 Jan 2022 19:19:58 +0100 Subject: [PATCH 0708/1461] Fix `GroupDigest` docs (#881) --- elliptic-curve/src/hash2curve/group_digest.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/elliptic-curve/src/hash2curve/group_digest.rs b/elliptic-curve/src/hash2curve/group_digest.rs index 644d149a7..be42553d0 100644 --- a/elliptic-curve/src/hash2curve/group_digest.rs +++ b/elliptic-curve/src/hash2curve/group_digest.rs @@ -44,7 +44,7 @@ pub trait GroupDigest: ProjectiveArithmetic { /// - [`ExpandMsgXmd`] /// - [`ExpandMsgXof`] /// - /// `len_in_bytes = T::Length * 2` + /// `len_in_bytes = ::Length * 2` /// /// [`ExpandMsgXmd`]: crate::hash2field::ExpandMsgXmd /// [`ExpandMsgXof`]: crate::hash2field::ExpandMsgXof @@ -84,7 +84,7 @@ pub trait GroupDigest: ProjectiveArithmetic { /// - [`ExpandMsgXmd`] /// - [`ExpandMsgXof`] /// - /// `len_in_bytes = T::Length` + /// `len_in_bytes = ::Length` /// /// [`ExpandMsgXmd`]: crate::hash2field::ExpandMsgXmd /// [`ExpandMsgXof`]: crate::hash2field::ExpandMsgXof @@ -107,7 +107,7 @@ pub trait GroupDigest: ProjectiveArithmetic { /// - [`ExpandMsgXmd`] /// - [`ExpandMsgXof`] /// - /// `len_in_bytes = T::Length` + /// `len_in_bytes = ::Length` /// /// [`ExpandMsgXmd`]: crate::hash2field::ExpandMsgXmd /// [`ExpandMsgXof`]: crate::hash2field::ExpandMsgXof From 7fa3088552cf0c76b1d57c13462d619cf9139b2b Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 14 Jan 2022 11:41:08 -0700 Subject: [PATCH 0709/1461] elliptic-curve v0.11.7 (#882) --- elliptic-curve/CHANGELOG.md | 19 +++++++++++++++++++ elliptic-curve/Cargo.lock | 2 +- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 2 +- 4 files changed, 22 insertions(+), 3 deletions(-) diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index 005721465..90680adde 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,25 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.11.7 (2021-01-14) +### Added +- Initial hash-to-field support ([#854], [#855], [#871], [#874]) +- Initial hash-to-curve support ([#865], [#876]) +- Impl `Mul` for `NonZeroScalar` * `NonZeroScalar` ([#857], [#862]) +- `Reduce::from_*e_digest_reduced` ([#869]) +- `VoprfParameters` trait ([#878]) + +[#854]: https://github.com/RustCrypto/traits/pull/854 +[#855]: https://github.com/RustCrypto/traits/pull/855 +[#857]: https://github.com/RustCrypto/traits/pull/857 +[#862]: https://github.com/RustCrypto/traits/pull/862 +[#865]: https://github.com/RustCrypto/traits/pull/865 +[#869]: https://github.com/RustCrypto/traits/pull/869 +[#871]: https://github.com/RustCrypto/traits/pull/871 +[#874]: https://github.com/RustCrypto/traits/pull/874 +[#876]: https://github.com/RustCrypto/traits/pull/876 +[#878]: https://github.com/RustCrypto/traits/pull/878 + ## 0.11.6 (2021-12-20) ### Added - Type conversions chart ([#852]) diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index 2dc485a80..b40da8672 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -90,7 +90,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.11.6" +version = "0.11.7" dependencies = [ "base64ct", "crypto-bigint", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 8602a6f44..b48fd9d4a 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.11.6" # Also update html_root_url in lib.rs when bumping this +version = "0.11.7" # Also update html_root_url in lib.rs when bumping this description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 7730cafa0..5e97c2fb4 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -5,7 +5,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.11.6" + html_root_url = "https://docs.rs/elliptic-curve/0.11.7" )] #![doc = include_str!("../README.md")] From e5b99207535ed36964ddfc454d1ea46fb1425a07 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Fri, 14 Jan 2022 21:56:27 +0100 Subject: [PATCH 0710/1461] Implement `ZeroizeOnDrop` on appropriate items (#884) --- elliptic-curve/Cargo.lock | 4 ++-- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/ecdh.rs | 6 +++++- elliptic-curve/src/jwk.rs | 4 +++- elliptic-curve/src/secret_key.rs | 4 +++- 5 files changed, 14 insertions(+), 6 deletions(-) diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index b40da8672..77fa77521 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -337,6 +337,6 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d68d9dcec5f9b43a30d38c49f91dfedfaac384cb8f085faca366c26207dd1619" +checksum = "cc222aec311c323c717f56060324f32b82da1ce1dd81d9a09aa6a9030bfe08db" diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index b48fd9d4a..594c98c33 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -25,7 +25,7 @@ der = { version = "0.5", default-features = false, features = ["oid"] } generic-array = { version = "0.14", default-features = false } rand_core = { version = "0.6", default-features = false } subtle = { version = "2", default-features = false } -zeroize = { version = "1", default-features = false } +zeroize = { version = "1.5", default-features = false } # optional dependencies base64ct = { version = "1", optional = true, default-features = false } diff --git a/elliptic-curve/src/ecdh.rs b/elliptic-curve/src/ecdh.rs index 8b5960236..40307ea44 100644 --- a/elliptic-curve/src/ecdh.rs +++ b/elliptic-curve/src/ecdh.rs @@ -33,7 +33,7 @@ use crate::{ use core::borrow::Borrow; use group::Curve as _; use rand_core::{CryptoRng, RngCore}; -use zeroize::Zeroize; +use zeroize::{Zeroize, ZeroizeOnDrop}; /// Low-level Elliptic Curve Diffie-Hellman (ECDH) function. /// @@ -138,6 +138,8 @@ where } } +impl ZeroizeOnDrop for EphemeralSecret where C: Curve + ProjectiveArithmetic {} + impl Drop for EphemeralSecret where C: Curve + ProjectiveArithmetic, @@ -208,6 +210,8 @@ impl Zeroize for SharedSecret { } } +impl ZeroizeOnDrop for SharedSecret {} + impl Drop for SharedSecret { fn drop(&mut self) { self.zeroize(); diff --git a/elliptic-curve/src/jwk.rs b/elliptic-curve/src/jwk.rs index ebeb6998a..85dbfe2cd 100644 --- a/elliptic-curve/src/jwk.rs +++ b/elliptic-curve/src/jwk.rs @@ -20,7 +20,7 @@ use core::{ str::{self, FromStr}, }; use serde::{de, ser, Deserialize, Serialize}; -use zeroize::Zeroize; +use zeroize::{Zeroize, ZeroizeOnDrop}; #[cfg(feature = "arithmetic")] use crate::{ @@ -345,6 +345,8 @@ impl PartialEq for JwkEcKey { impl Eq for JwkEcKey {} +impl ZeroizeOnDrop for JwkEcKey {} + impl Drop for JwkEcKey { fn drop(&mut self) { self.zeroize(); diff --git a/elliptic-curve/src/secret_key.rs b/elliptic-curve/src/secret_key.rs index 8dc3f07e2..1f90ea1c7 100644 --- a/elliptic-curve/src/secret_key.rs +++ b/elliptic-curve/src/secret_key.rs @@ -15,7 +15,7 @@ use core::fmt::{self, Debug}; use crypto_bigint::Encoding; use generic_array::GenericArray; use subtle::{Choice, ConstantTimeEq}; -use zeroize::Zeroize; +use zeroize::{Zeroize, ZeroizeOnDrop}; #[cfg(all(feature = "alloc", feature = "arithmetic"))] use { @@ -325,6 +325,8 @@ where } } +impl ZeroizeOnDrop for SecretKey where C: Curve {} + impl Drop for SecretKey where C: Curve, From bbc18e2038c044f09b6cf1ae3c821741d4c446c4 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 15 Jan 2022 07:14:16 -0700 Subject: [PATCH 0711/1461] elliptic-curve: use the `base16ct` crate (#886) Uses the new `base16ct` crate for hex decoding. The encoder is still implemented in a non-constant-time manner. The functionality to encode to a `fmt::Formatter` needs to be upstreamed into the `base16ct` crate. --- elliptic-curve/Cargo.lock | 7 ++++++ elliptic-curve/Cargo.toml | 1 + elliptic-curve/src/error.rs | 6 +++++ elliptic-curve/src/hex.rs | 44 +++++-------------------------------- 4 files changed, 19 insertions(+), 39 deletions(-) diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index 77fa77521..620cd4316 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -2,6 +2,12 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "base16ct" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ecf0f8400afa4e4e3654e950d5717c0c626ffbaf218d80cccd86abd609529ed" + [[package]] name = "base64ct" version = "1.3.1" @@ -92,6 +98,7 @@ dependencies = [ name = "elliptic-curve" version = "0.11.7" dependencies = [ + "base16ct", "base64ct", "crypto-bigint", "der", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 594c98c33..97269e55f 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -20,6 +20,7 @@ rust-version = "1.56" members = ["."] [dependencies] +base16ct = "0.1" crypto-bigint = { version = "0.3", default-features = false, features = ["rand_core", "generic-array", "zeroize"] } der = { version = "0.5", default-features = false, features = ["oid"] } generic-array = { version = "0.14", default-features = false } diff --git a/elliptic-curve/src/error.rs b/elliptic-curve/src/error.rs index 945955ffc..53f5b1773 100644 --- a/elliptic-curve/src/error.rs +++ b/elliptic-curve/src/error.rs @@ -18,6 +18,12 @@ impl Display for Error { } } +impl From for Error { + fn from(_: base16ct::Error) -> Error { + Error + } +} + #[cfg(feature = "pkcs8")] impl From for Error { fn from(_: pkcs8::Error) -> Error { diff --git a/elliptic-curve/src/hex.rs b/elliptic-curve/src/hex.rs index 4c0f37fd1..dbf8a8338 100644 --- a/elliptic-curve/src/hex.rs +++ b/elliptic-curve/src/hex.rs @@ -23,41 +23,13 @@ pub(crate) fn write_upper(slice: &[u8], formatter: &mut fmt::Formatter<'_>) -> f /// Decode the provided hexadecimal string into the provided buffer. /// -/// Accepts either lower case or upper case hexadecimal, but not mixed. -// TODO(tarcieri): constant-time hex decoder? +/// Accepts either lower case or upper case hexadecimal. pub(crate) fn decode(hex: &str, out: &mut [u8]) -> Result<()> { - if hex.as_bytes().len() != out.len() * 2 { - return Err(Error); + if base16ct::mixed::decode(hex, out)?.len() == out.len() { + Ok(()) + } else { + Err(Error) } - - let mut upper_case = None; - - // Ensure all characters are valid and case is not mixed - for &byte in hex.as_bytes() { - match byte { - b'0'..=b'9' => (), - b'a'..=b'z' => match upper_case { - Some(true) => return Err(Error), - Some(false) => (), - None => upper_case = Some(false), - }, - b'A'..=b'Z' => match upper_case { - Some(true) => (), - Some(false) => return Err(Error), - None => upper_case = Some(true), - }, - _ => return Err(Error), - } - } - - for (digit, byte) in hex.as_bytes().chunks_exact(2).zip(out.iter_mut()) { - *byte = str::from_utf8(digit) - .ok() - .and_then(|s| u8::from_str_radix(s, 16).ok()) - .ok_or(Error)?; - } - - Ok(()) } #[cfg(all(test, feature = "std"))] @@ -97,12 +69,6 @@ mod tests { assert_eq!(buf, EXAMPLE_DATA); } - #[test] - fn decode_rejects_mixed_case() { - let mut buf = [0u8; 8]; - assert!(super::decode("0123456789abcDEF", &mut buf).is_err()); - } - #[test] fn decode_rejects_too_short() { let mut buf = [0u8; 9]; From 77ec628f0f8ab3276efd6a8418f66d2ac4a58140 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 15 Jan 2022 08:51:34 -0700 Subject: [PATCH 0712/1461] elliptic-curve: use `base16ct::HexDisplay` (#887) Uses a constant time-ish implementation of a hexadecimal display formatter to replace what was previously in the `hex` module. --- elliptic-curve/Cargo.lock | 4 +-- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/hex.rs | 46 +--------------------------- elliptic-curve/src/scalar/core.rs | 5 +-- elliptic-curve/src/scalar/nonzero.rs | 5 +-- 5 files changed, 10 insertions(+), 52 deletions(-) diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index 620cd4316..a28aad7ea 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "base16ct" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ecf0f8400afa4e4e3654e950d5717c0c626ffbaf218d80cccd86abd609529ed" +checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" [[package]] name = "base64ct" diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 97269e55f..f8ed0ee2a 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -20,7 +20,7 @@ rust-version = "1.56" members = ["."] [dependencies] -base16ct = "0.1" +base16ct = "0.1.1" crypto-bigint = { version = "0.3", default-features = false, features = ["rand_core", "generic-array", "zeroize"] } der = { version = "0.5", default-features = false, features = ["oid"] } generic-array = { version = "0.14", default-features = false } diff --git a/elliptic-curve/src/hex.rs b/elliptic-curve/src/hex.rs index dbf8a8338..2d782ab74 100644 --- a/elliptic-curve/src/hex.rs +++ b/elliptic-curve/src/hex.rs @@ -1,25 +1,7 @@ //! Hexadecimal encoding helpers use crate::{Error, Result}; -use core::{fmt, str}; - -/// Write the provided slice to the formatter as lower case hexadecimal -#[inline] -pub(crate) fn write_lower(slice: &[u8], formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - for byte in slice { - write!(formatter, "{:02x}", byte)?; - } - Ok(()) -} - -/// Write the provided slice to the formatter as upper case hexadecimal -#[inline] -pub(crate) fn write_upper(slice: &[u8], formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - for byte in slice { - write!(formatter, "{:02X}", byte)?; - } - Ok(()) -} +use core::str; /// Decode the provided hexadecimal string into the provided buffer. /// @@ -34,26 +16,10 @@ pub(crate) fn decode(hex: &str, out: &mut [u8]) -> Result<()> { #[cfg(all(test, feature = "std"))] mod tests { - use core::fmt; use hex_literal::hex; const EXAMPLE_DATA: &[u8] = &hex!("0123456789ABCDEF"); const EXAMPLE_HEX_LOWER: &str = "0123456789abcdef"; - const EXAMPLE_HEX_UPPER: &str = "0123456789ABCDEF"; - - struct Wrapper<'a>(&'a [u8]); - - impl fmt::LowerHex for Wrapper<'_> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - super::write_lower(self.0, f) - } - } - - impl fmt::UpperHex for Wrapper<'_> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - super::write_upper(self.0, f) - } - } #[test] fn decode_lower() { @@ -80,14 +46,4 @@ mod tests { let mut buf = [0u8; 7]; assert!(super::decode(EXAMPLE_HEX_LOWER, &mut buf).is_err()); } - - #[test] - fn encode_lower() { - assert_eq!(format!("{:x}", Wrapper(EXAMPLE_DATA)), EXAMPLE_HEX_LOWER); - } - - #[test] - fn encode_upper() { - assert_eq!(format!("{:X}", Wrapper(EXAMPLE_DATA)), EXAMPLE_HEX_UPPER); - } } diff --git a/elliptic-curve/src/scalar/core.rs b/elliptic-curve/src/scalar/core.rs index 40d36083d..c76bb1cd2 100644 --- a/elliptic-curve/src/scalar/core.rs +++ b/elliptic-curve/src/scalar/core.rs @@ -10,6 +10,7 @@ use crate::{ }, Curve, Error, FieldBytes, IsHigh, Result, }; +use base16ct::HexDisplay; use core::{ cmp::Ordering, fmt, @@ -376,7 +377,7 @@ where C: Curve, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - hex::write_lower(&self.to_be_bytes(), f) + write!(f, "{:x}", HexDisplay(&self.to_be_bytes())) } } @@ -385,7 +386,7 @@ where C: Curve, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - hex::write_upper(&self.to_be_bytes(), f) + write!(f, "{:X}", HexDisplay(&self.to_be_bytes())) } } diff --git a/elliptic-curve/src/scalar/nonzero.rs b/elliptic-curve/src/scalar/nonzero.rs index 0f38d7cfa..c1766be52 100644 --- a/elliptic-curve/src/scalar/nonzero.rs +++ b/elliptic-curve/src/scalar/nonzero.rs @@ -8,6 +8,7 @@ use crate::{ Curve, Error, FieldBytes, IsHigh, PrimeCurve, Result, Scalar, ScalarArithmetic, ScalarCore, SecretKey, }; +use base16ct::HexDisplay; use core::{ fmt, ops::{Deref, Mul, Neg}, @@ -298,7 +299,7 @@ where C: Curve + ScalarArithmetic, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - hex::write_lower(&self.to_repr(), f) + write!(f, "{:x}", HexDisplay(&self.to_repr())) } } @@ -307,7 +308,7 @@ where C: Curve + ScalarArithmetic, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - hex::write_upper(&self.to_repr(), f) + write!(f, "{:}", HexDisplay(&self.to_repr())) } } From 6aa3eb26dc7d843b4df8a8841f04602cb109457f Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 15 Jan 2022 13:11:29 -0700 Subject: [PATCH 0713/1461] elliptic-curve: replace `hex` module with `base16ct` (#888) Completely replaces the previous `hex` module with the `base16ct` crate --- elliptic-curve/src/hex.rs | 49 ---------------------------- elliptic-curve/src/lib.rs | 1 - elliptic-curve/src/scalar/core.rs | 3 +- elliptic-curve/src/scalar/nonzero.rs | 9 +++-- 4 files changed, 7 insertions(+), 55 deletions(-) delete mode 100644 elliptic-curve/src/hex.rs diff --git a/elliptic-curve/src/hex.rs b/elliptic-curve/src/hex.rs deleted file mode 100644 index 2d782ab74..000000000 --- a/elliptic-curve/src/hex.rs +++ /dev/null @@ -1,49 +0,0 @@ -//! Hexadecimal encoding helpers - -use crate::{Error, Result}; -use core::str; - -/// Decode the provided hexadecimal string into the provided buffer. -/// -/// Accepts either lower case or upper case hexadecimal. -pub(crate) fn decode(hex: &str, out: &mut [u8]) -> Result<()> { - if base16ct::mixed::decode(hex, out)?.len() == out.len() { - Ok(()) - } else { - Err(Error) - } -} - -#[cfg(all(test, feature = "std"))] -mod tests { - use hex_literal::hex; - - const EXAMPLE_DATA: &[u8] = &hex!("0123456789ABCDEF"); - const EXAMPLE_HEX_LOWER: &str = "0123456789abcdef"; - - #[test] - fn decode_lower() { - let mut buf = [0u8; 8]; - super::decode(EXAMPLE_HEX_LOWER, &mut buf).unwrap(); - assert_eq!(buf, EXAMPLE_DATA); - } - - #[test] - fn decode_upper() { - let mut buf = [0u8; 8]; - super::decode(EXAMPLE_HEX_LOWER, &mut buf).unwrap(); - assert_eq!(buf, EXAMPLE_DATA); - } - - #[test] - fn decode_rejects_too_short() { - let mut buf = [0u8; 9]; - assert!(super::decode(EXAMPLE_HEX_LOWER, &mut buf).is_err()); - } - - #[test] - fn decode_rejects_too_long() { - let mut buf = [0u8; 7]; - assert!(super::decode(EXAMPLE_HEX_LOWER, &mut buf).is_err()); - } -} diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 5e97c2fb4..5eae839b6 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -73,7 +73,6 @@ pub mod ops; pub mod sec1; mod error; -mod hex; mod point; mod scalar; mod secret_key; diff --git a/elliptic-curve/src/scalar/core.rs b/elliptic-curve/src/scalar/core.rs index c76bb1cd2..ff806f0aa 100644 --- a/elliptic-curve/src/scalar/core.rs +++ b/elliptic-curve/src/scalar/core.rs @@ -2,7 +2,6 @@ use crate::{ bigint::{prelude::*, Limb, NonZero}, - hex, rand_core::{CryptoRng, RngCore}, subtle::{ Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeGreater, ConstantTimeLess, @@ -398,7 +397,7 @@ where fn from_str(hex: &str) -> Result { let mut bytes = FieldBytes::::default(); - hex::decode(hex, &mut bytes)?; + base16ct::lower::decode(hex, &mut bytes)?; Option::from(Self::from_be_bytes(bytes)).ok_or(Error) } } diff --git a/elliptic-curve/src/scalar/nonzero.rs b/elliptic-curve/src/scalar/nonzero.rs index c1766be52..224c26603 100644 --- a/elliptic-curve/src/scalar/nonzero.rs +++ b/elliptic-curve/src/scalar/nonzero.rs @@ -2,7 +2,6 @@ use crate::{ bigint::Encoding as _, - hex, ops::{Invert, Reduce, ReduceNonZero}, rand_core::{CryptoRng, RngCore}, Curve, Error, FieldBytes, IsHigh, PrimeCurve, Result, Scalar, ScalarArithmetic, ScalarCore, @@ -320,8 +319,12 @@ where fn from_str(hex: &str) -> Result { let mut bytes = FieldBytes::::default(); - hex::decode(hex, &mut bytes)?; - Option::from(Self::from_repr(bytes)).ok_or(Error) + + if base16ct::mixed::decode(hex, &mut bytes)?.len() == bytes.len() { + Option::from(Self::from_repr(bytes)).ok_or(Error) + } else { + Err(Error) + } } } From e6eef1d3097188c48b586354618505ef4b7a5245 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 15 Jan 2022 13:18:38 -0700 Subject: [PATCH 0714/1461] elliptic-curve v0.11.8 (#889) --- crypto/Cargo.lock | 13 ++++++++++--- elliptic-curve/CHANGELOG.md | 12 ++++++++++++ elliptic-curve/Cargo.lock | 2 +- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 2 +- 5 files changed, 25 insertions(+), 6 deletions(-) diff --git a/crypto/Cargo.lock b/crypto/Cargo.lock index 8fbb78819..6af7bd59c 100644 --- a/crypto/Cargo.lock +++ b/crypto/Cargo.lock @@ -10,6 +10,12 @@ dependencies = [ "rand_core", ] +[[package]] +name = "base16ct" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" + [[package]] name = "base64ct" version = "1.0.1" @@ -113,8 +119,9 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.11.6" +version = "0.11.8" dependencies = [ + "base16ct", "crypto-bigint", "der", "ff", @@ -264,6 +271,6 @@ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] name = "zeroize" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d68d9dcec5f9b43a30d38c49f91dfedfaac384cb8f085faca366c26207dd1619" +checksum = "cc222aec311c323c717f56060324f32b82da1ce1dd81d9a09aa6a9030bfe08db" diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index 90680adde..1ad55275b 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.11.8 (2021-01-15) +### Added +- Impl `ZeroizeOnDrop` on appropriate items ([#884]) + +### Changed +- Use the `base16ct` crate for hex serialization ([#886], [#887], [#888]) + +[#884]: https://github.com/RustCrypto/traits/pull/884 +[#886]: https://github.com/RustCrypto/traits/pull/886 +[#887]: https://github.com/RustCrypto/traits/pull/887 +[#888]: https://github.com/RustCrypto/traits/pull/888 + ## 0.11.7 (2021-01-14) ### Added - Initial hash-to-field support ([#854], [#855], [#871], [#874]) diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index a28aad7ea..04bf8690d 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -96,7 +96,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.11.7" +version = "0.11.8" dependencies = [ "base16ct", "base64ct", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index f8ed0ee2a..18f8f5c4a 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.11.7" # Also update html_root_url in lib.rs when bumping this +version = "0.11.8" # Also update html_root_url in lib.rs when bumping this description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 5eae839b6..516f92708 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -5,7 +5,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.11.7" + html_root_url = "https://docs.rs/elliptic-curve/0.11.8" )] #![doc = include_str!("../README.md")] From d3e544885f0f8c6bd07658470d6f5f6fd0a95b57 Mon Sep 17 00:00:00 2001 From: Daiki Mizukami Date: Sat, 15 Jan 2022 23:14:29 +0000 Subject: [PATCH 0715/1461] digest: bump `generic-array` dependency to v0.14.4 (#885) `generic-array` v0.14.4 uses `typenum` v1.12.0, which makes `Unsigned` imply `Default`, which, in turn, is required for `CoreWrapper` to to implement `Digest`. --- digest/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 9ec439e41..037216dda 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -12,7 +12,7 @@ keywords = ["digest", "crypto", "hash"] categories = ["cryptography", "no-std"] [dependencies] -generic-array = "0.14" +generic-array = "0.14.4" crypto-common = { version = "0.1.1", path = "../crypto-common" } block-buffer = { version = "0.10", optional = true } From ff14dadb2a252940ecc579928fc88b5fba03e601 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 17 Jan 2022 08:59:51 -0700 Subject: [PATCH 0716/1461] elliptic-curve: activate `bits`, `hash2curve`, `voprf` on docs.rs (#891) Expands the list of features that appear in rustdoc documentation published to https://docs.rs/elliptic-curve/ to include all of the newly added features which shipped in v0.11.8. We'll need to publish a v0.11.9 in order for this to render. --- elliptic-curve/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 18f8f5c4a..662d485be 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -60,5 +60,5 @@ std = ["alloc", "rand_core/std"] voprf = ["digest"] [package.metadata.docs.rs] -features = ["arithmetic", "ecdh", "jwk", "pem", "std"] +features = ["bits", "ecdh", "hash2curve", "jwk", "pem", "std", "voprf"] rustdoc-args = ["--cfg", "docsrs"] From 999dab2c12b19252d5c6c80744e211cf170705c1 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 17 Jan 2022 09:06:38 -0700 Subject: [PATCH 0717/1461] elliptic-curve v0.11.9 (#892) --- crypto/Cargo.lock | 2 +- elliptic-curve/CHANGELOG.md | 10 ++++++++-- elliptic-curve/Cargo.lock | 2 +- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/LICENSE-MIT | 2 +- elliptic-curve/src/lib.rs | 2 +- 6 files changed, 13 insertions(+), 7 deletions(-) diff --git a/crypto/Cargo.lock b/crypto/Cargo.lock index 6af7bd59c..905a71d3e 100644 --- a/crypto/Cargo.lock +++ b/crypto/Cargo.lock @@ -119,7 +119,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.11.8" +version = "0.11.9" dependencies = [ "base16ct", "crypto-bigint", diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index 1ad55275b..6cc45ff7f 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,7 +4,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 0.11.8 (2021-01-15) +## 0.11.9 (2022-01-17) +### Changed +- Activate `bits`, `hash2curve`, and `voprf` features on docs.rs ([#891]) + +[#891]: https://github.com/RustCrypto/traits/pull/891 + +## 0.11.8 (2022-01-15) ### Added - Impl `ZeroizeOnDrop` on appropriate items ([#884]) @@ -16,7 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [#887]: https://github.com/RustCrypto/traits/pull/887 [#888]: https://github.com/RustCrypto/traits/pull/888 -## 0.11.7 (2021-01-14) +## 0.11.7 (2022-01-14) ### Added - Initial hash-to-field support ([#854], [#855], [#871], [#874]) - Initial hash-to-curve support ([#865], [#876]) diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index 04bf8690d..76ee28dd4 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -96,7 +96,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.11.8" +version = "0.11.9" dependencies = [ "base16ct", "base64ct", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 662d485be..cef05f580 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.11.8" # Also update html_root_url in lib.rs when bumping this +version = "0.11.9" # Also update html_root_url in lib.rs when bumping this description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, diff --git a/elliptic-curve/LICENSE-MIT b/elliptic-curve/LICENSE-MIT index f39f9ff82..d4ce06527 100644 --- a/elliptic-curve/LICENSE-MIT +++ b/elliptic-curve/LICENSE-MIT @@ -1,4 +1,4 @@ -Copyright (c) 2020 RustCrypto Developers +Copyright (c) 2020-2022 RustCrypto Developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 516f92708..32474e263 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -5,7 +5,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.11.8" + html_root_url = "https://docs.rs/elliptic-curve/0.11.9" )] #![doc = include_str!("../README.md")] From 981af7794590ea25f0e7d5796ccde7a8a3734de2 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Mon, 17 Jan 2022 22:31:11 +0100 Subject: [PATCH 0718/1461] Update to digest 0.10 (#883) --- elliptic-curve/Cargo.lock | 44 +++++++------- elliptic-curve/Cargo.toml | 6 +- elliptic-curve/src/hash2field/expand_msg.rs | 7 ++- .../src/hash2field/expand_msg/xmd.rs | 57 ++++++++++--------- elliptic-curve/src/ops.rs | 6 +- 5 files changed, 60 insertions(+), 60 deletions(-) diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index 76ee28dd4..b3896be8b 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -28,20 +28,13 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +checksum = "f1d36a02058e76b040de25a4464ba1c80935655595b661505c8b39b664828b95" dependencies = [ - "block-padding", "generic-array", ] -[[package]] -name = "block-padding" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" - [[package]] name = "cfg-if" version = "1.0.0" @@ -75,6 +68,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "crypto-common" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d6b536309245c849479fba3da410962a43ed8e51c26b729208ec0ac2798d0" +dependencies = [ + "generic-array", +] + [[package]] name = "der" version = "0.5.1" @@ -87,10 +89,12 @@ dependencies = [ [[package]] name = "digest" -version = "0.9.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +checksum = "b697d66081d42af4fba142d56918a3cb21dc8eb63372c6b85d14f44fb9c5979b" dependencies = [ + "block-buffer", + "crypto-common", "generic-array", ] @@ -191,12 +195,6 @@ version = "0.2.112" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - [[package]] name = "pem-rfc7468" version = "0.3.1" @@ -270,27 +268,23 @@ dependencies = [ [[package]] name = "sha2" -version = "0.9.9" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +checksum = "99c3bd8169c58782adad9290a9af5939994036b76187f7b4f0e6de91dbbfc0ec" dependencies = [ - "block-buffer", "cfg-if", "cpufeatures", "digest", - "opaque-debug", ] [[package]] name = "sha3" -version = "0.9.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" +checksum = "31f935e31cf406e8c0e96c2815a5516181b7004ae8c5f296293221e9b1e356bd" dependencies = [ - "block-buffer", "digest", "keccak", - "opaque-debug", ] [[package]] diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index cef05f580..4a19f40f3 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -30,7 +30,7 @@ zeroize = { version = "1.5", default-features = false } # optional dependencies base64ct = { version = "1", optional = true, default-features = false } -digest = { version = "0.9", optional = true, default-features = false } +digest = { version = "0.10", optional = true } ff = { version = "0.11", optional = true, default-features = false } group = { version = "0.11", optional = true, default-features = false } hex-literal = { version = "0.3", optional = true } @@ -41,8 +41,8 @@ serde_json = { version = "1", optional = true, default-features = false, feature [dev-dependencies] hex-literal = "0.3" -sha2 = "0.9" -sha3 = "0.9" +sha2 = "0.10" +sha3 = "0.10" [features] default = ["arithmetic"] diff --git a/elliptic-curve/src/hash2field/expand_msg.rs b/elliptic-curve/src/hash2field/expand_msg.rs index fda9fcc83..6fd88dfdc 100644 --- a/elliptic-curve/src/hash2field/expand_msg.rs +++ b/elliptic-curve/src/hash2field/expand_msg.rs @@ -76,7 +76,12 @@ where X: Digest, { if dst.len() > MAX_DST_LEN { - Self::Hashed(X::new().chain(OVERSIZE_DST_SALT).chain(dst).finalize()) + Self::Hashed({ + let mut hash = X::new(); + hash.update(OVERSIZE_DST_SALT); + hash.update(dst); + hash.finalize() + }) } else { Self::Array(dst) } diff --git a/elliptic-curve/src/hash2field/expand_msg/xmd.rs b/elliptic-curve/src/hash2field/expand_msg/xmd.rs index 8e05e715b..5132f3b3a 100644 --- a/elliptic-curve/src/hash2field/expand_msg/xmd.rs +++ b/elliptic-curve/src/hash2field/expand_msg/xmd.rs @@ -5,11 +5,12 @@ use core::marker::PhantomData; use super::{Domain, ExpandMsg, Expander}; use crate::{Error, Result}; use digest::{ + core_api::BlockSizeUser, generic_array::{ typenum::{IsLess, IsLessOrEqual, Unsigned, U256}, GenericArray, }, - BlockInput, Digest, + Digest, }; /// Placeholder type for implementing `expand_message_xmd` based on a hash function @@ -20,14 +21,14 @@ use digest::{ /// - `len_in_bytes > 255 * HashT::OutputSize` pub struct ExpandMsgXmd(PhantomData) where - HashT: Digest + BlockInput, + HashT: Digest + BlockSizeUser, HashT::OutputSize: IsLess, HashT::OutputSize: IsLessOrEqual; /// ExpandMsgXmd implements expand_message_xmd for the ExpandMsg trait impl<'a, HashT> ExpandMsg<'a> for ExpandMsgXmd where - HashT: Digest + BlockInput, + HashT: Digest + BlockSizeUser, // If `len_in_bytes` is bigger then 256, length of the `DST` will depend on // the output size of the hash, which is still not allowed to be bigger then 256: // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-13.html#section-5.4.1-6 @@ -53,25 +54,25 @@ where let ell = u8::try_from((len_in_bytes + b_in_bytes - 1) / b_in_bytes).map_err(|_| Error)?; let domain = Domain::xmd::(dst); - let mut b_0 = HashT::new().chain(GenericArray::::default()); + let mut b_0 = HashT::new(); + b_0.update(GenericArray::::default()); for msg in msgs { - b_0 = b_0.chain(msg); + b_0.update(msg); } - let b_0 = b_0 - .chain(len_in_bytes_u16.to_be_bytes()) - .chain([0]) - .chain(domain.data()) - .chain([domain.len()]) - .finalize(); + b_0.update(len_in_bytes_u16.to_be_bytes()); + b_0.update([0]); + b_0.update(domain.data()); + b_0.update([domain.len()]); + let b_0 = b_0.finalize(); - let b_vals = HashT::new() - .chain(&b_0[..]) - .chain([1u8]) - .chain(domain.data()) - .chain([domain.len()]) - .finalize(); + let mut b_vals = HashT::new(); + b_vals.update(&b_0[..]); + b_vals.update([1u8]); + b_vals.update(domain.data()); + b_vals.update([domain.len()]); + let b_vals = b_vals.finalize(); Ok(ExpanderXmd { b_0, @@ -87,7 +88,7 @@ where /// [`Expander`] type for [`ExpandMsgXmd`]. pub struct ExpanderXmd<'a, HashT> where - HashT: Digest + BlockInput, + HashT: Digest + BlockSizeUser, HashT::OutputSize: IsLess, HashT::OutputSize: IsLessOrEqual, { @@ -101,7 +102,7 @@ where impl<'a, HashT> ExpanderXmd<'a, HashT> where - HashT: Digest + BlockInput, + HashT: Digest + BlockSizeUser, HashT::OutputSize: IsLess, HashT::OutputSize: IsLessOrEqual, { @@ -116,12 +117,12 @@ where .zip(&self.b_vals[..]) .enumerate() .for_each(|(j, (b0val, bi1val))| tmp[j] = b0val ^ bi1val); - self.b_vals = HashT::new() - .chain(tmp) - .chain([self.index]) - .chain(self.domain.data()) - .chain([self.domain.len()]) - .finalize(); + let mut b_vals = HashT::new(); + b_vals.update(tmp); + b_vals.update([self.index]); + b_vals.update(self.domain.data()); + b_vals.update([self.domain.len()]); + self.b_vals = b_vals.finalize(); true } else { false @@ -131,7 +132,7 @@ where impl<'a, HashT> Expander for ExpanderXmd<'a, HashT> where - HashT: Digest + BlockInput, + HashT: Digest + BlockSizeUser, HashT::OutputSize: IsLess, HashT::OutputSize: IsLessOrEqual, { @@ -163,7 +164,7 @@ mod test { len_in_bytes: u16, bytes: &[u8], ) where - HashT: Digest + BlockInput, + HashT: Digest + BlockSizeUser, HashT::OutputSize: IsLess, { let block = HashT::BlockSize::to_usize(); @@ -203,7 +204,7 @@ mod test { domain: &Domain<'_, HashT::OutputSize>, ) -> Result<()> where - HashT: Digest + BlockInput, + HashT: Digest + BlockSizeUser, HashT::OutputSize: IsLess + IsLessOrEqual, { assert_message::(self.msg, domain, L::to_u16(), self.msg_prime); diff --git a/elliptic-curve/src/ops.rs b/elliptic-curve/src/ops.rs index d8038d931..d6a215490 100644 --- a/elliptic-curve/src/ops.rs +++ b/elliptic-curve/src/ops.rs @@ -9,7 +9,7 @@ use subtle::CtOption; use group::Group; #[cfg(feature = "digest")] -use digest::{BlockInput, Digest, FixedOutput, Reset, Update}; +use digest::{core_api::BlockSizeUser, Digest, FixedOutput, Reset}; /// Perform an inversion on a field element (i.e. base field element or scalar) pub trait Invert { @@ -67,7 +67,7 @@ pub trait Reduce: Sized { #[cfg_attr(docsrs, doc(cfg(feature = "digest")))] fn from_be_digest_reduced(digest: D) -> Self where - D: FixedOutput + BlockInput + Clone + Default + Reset + Update, + D: FixedOutput + BlockSizeUser + Clone + Digest + Reset, { Self::from_be_bytes_reduced(digest.finalize()) } @@ -78,7 +78,7 @@ pub trait Reduce: Sized { #[cfg_attr(docsrs, doc(cfg(feature = "digest")))] fn from_le_digest_reduced(digest: D) -> Self where - D: FixedOutput + BlockInput + Clone + Default + Reset + Update, + D: FixedOutput + BlockSizeUser + Clone + Digest + Reset, { Self::from_le_bytes_reduced(digest.finalize()) } From dc47a5abc2d05a5f05366d3b4dc1f677570a4db8 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 17 Jan 2022 14:37:49 -0700 Subject: [PATCH 0719/1461] elliptic-curve: bump version to 0.12 prerelease (#893) Switching over to making breaking changes again now that #883 is merged. There are a number of other pent up breaking changes that have been desired which we can now start working on. --- crypto/Cargo.lock | 2 +- crypto/Cargo.toml | 2 +- elliptic-curve/Cargo.lock | 2 +- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/crypto/Cargo.lock b/crypto/Cargo.lock index 905a71d3e..296df354c 100644 --- a/crypto/Cargo.lock +++ b/crypto/Cargo.lock @@ -119,7 +119,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.11.9" +version = "0.12.0-pre" dependencies = [ "base16ct", "crypto-bigint", diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 71be1bd64..266a0fbb1 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -22,7 +22,7 @@ members = ["."] aead = { version = "0.4", optional = true, path = "../aead" } cipher = { version = "0.3", optional = true } digest = { version = "0.10", optional = true } -elliptic-curve = { version = "0.11", optional = true, path = "../elliptic-curve" } +elliptic-curve = { version = "0.12.0-pre", optional = true, path = "../elliptic-curve" } mac = { version = "0.11", package = "crypto-mac", optional = true } password-hash = { version = "0.3", optional = true, path = "../password-hash" } signature = { version = "1.5", optional = true, default-features = false, path = "../signature" } diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index b3896be8b..defe91c47 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -100,7 +100,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.11.9" +version = "0.12.0-pre" dependencies = [ "base16ct", "base64ct", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 4a19f40f3..14695fd39 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.11.9" # Also update html_root_url in lib.rs when bumping this +version = "0.12.0-pre" # Also update html_root_url in lib.rs when bumping this description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 32474e263..27a738536 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -5,7 +5,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.11.9" + html_root_url = "https://docs.rs/elliptic-curve/0.12.0-pre" )] #![doc = include_str!("../README.md")] From bb3d0de358006a476533720fae6fcadffcbe12cf Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 17 Jan 2022 14:48:26 -0700 Subject: [PATCH 0720/1461] elliptic-curve: make `NonZeroScalar::invert` infallible (#894) Because `NonZeroScalar` means we'll never divide by 0, it's possible to make the implementation infallible. To accomplish this, `CtOption` is removed from the `Invert` trait's signature, and used as the result type for scalars that are potentially zero as part of the blanket impl of `Invert`. Fixes RustCrypto/elliptic-curves#499 --- elliptic-curve/src/ops.rs | 7 +++---- elliptic-curve/src/scalar/nonzero.rs | 10 ++++++---- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/elliptic-curve/src/ops.rs b/elliptic-curve/src/ops.rs index d6a215490..64a0eb3c6 100644 --- a/elliptic-curve/src/ops.rs +++ b/elliptic-curve/src/ops.rs @@ -3,10 +3,9 @@ pub use core::ops::{Add, AddAssign, Mul, Neg, Sub, SubAssign}; use crypto_bigint::{ArrayEncoding, ByteArray, Integer}; -use subtle::CtOption; #[cfg(feature = "arithmetic")] -use group::Group; +use {group::Group, subtle::CtOption}; #[cfg(feature = "digest")] use digest::{core_api::BlockSizeUser, Digest, FixedOutput, Reset}; @@ -17,12 +16,12 @@ pub trait Invert { type Output; /// Invert a field element. - fn invert(&self) -> CtOption; + fn invert(&self) -> Self::Output; } #[cfg(feature = "arithmetic")] impl Invert for F { - type Output = F; + type Output = CtOption; fn invert(&self) -> CtOption { ff::Field::invert(self) diff --git a/elliptic-curve/src/scalar/nonzero.rs b/elliptic-curve/src/scalar/nonzero.rs index 224c26603..7450537a9 100644 --- a/elliptic-curve/src/scalar/nonzero.rs +++ b/elliptic-curve/src/scalar/nonzero.rs @@ -170,11 +170,13 @@ impl Invert for NonZeroScalar where C: Curve + ScalarArithmetic, { - type Output = Scalar; + type Output = Self; - /// Perform a scalar inversion - fn invert(&self) -> CtOption { - ff::Field::invert(&self.scalar) + fn invert(&self) -> Self { + Self { + // This will always succeed since `scalar` will never be 0 + scalar: ff::Field::invert(&self.scalar).unwrap(), + } } } From e8f838ab6fe91324ee246b909b296ea122f509ce Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 17 Jan 2022 14:54:34 -0700 Subject: [PATCH 0721/1461] elliptic-curve: make `ToCompactEncodedPoint` return `CtOption` (#895) This is more consistent with the `ToEncodedPoint` trait. --- elliptic-curve/src/sec1.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elliptic-curve/src/sec1.rs b/elliptic-curve/src/sec1.rs index f548a7fea..fd6d2c156 100644 --- a/elliptic-curve/src/sec1.rs +++ b/elliptic-curve/src/sec1.rs @@ -49,7 +49,7 @@ where { /// Serialize this value as a SEC1 [`EncodedPoint`], optionally applying /// point compression. - fn to_compact_encoded_point(&self) -> Option>; + fn to_compact_encoded_point(&self) -> CtOption>; } /// Validate that the given [`EncodedPoint`] represents the encoded public key From f24a530129481b9a8b55c25a36550bd6dd19f079 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 17 Jan 2022 18:17:54 -0700 Subject: [PATCH 0722/1461] password-hash: leverage `const_panic`; MSRV 1.57 (#896) Leverages the newly stabilized support for panicking in const contexts to replace the hack `const_assert!` macro. After this, it will also be trivial to bump to the 2021 edition. --- .github/workflows/crypto.yml | 6 +++--- .github/workflows/password-hash.yml | 4 ++-- .github/workflows/workspace.yml | 2 +- Cargo.lock | 2 +- crypto/Cargo.lock | 2 +- crypto/Cargo.toml | 4 ++-- crypto/README.md | 4 ++-- crypto/src/lib.rs | 18 +++++++++--------- password-hash/Cargo.toml | 2 +- password-hash/README.md | 4 ++-- password-hash/src/ident.rs | 15 +++------------ password-hash/src/lib.rs | 2 +- 12 files changed, 28 insertions(+), 37 deletions(-) diff --git a/.github/workflows/crypto.yml b/.github/workflows/crypto.yml index f2d8a0b0b..c93bb5095 100644 --- a/.github/workflows/crypto.yml +++ b/.github/workflows/crypto.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.57.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -43,7 +43,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.57.0 # MSRV - stable steps: - uses: actions/checkout@v1 @@ -63,7 +63,7 @@ jobs: - uses: actions/checkout@v1 - uses: actions-rs/toolchain@v1 with: - toolchain: 1.56.0 + toolchain: 1.57.0 components: clippy override: true profile: minimal diff --git a/.github/workflows/password-hash.yml b/.github/workflows/password-hash.yml index 1e780c073..eb68d8f78 100644 --- a/.github/workflows/password-hash.yml +++ b/.github/workflows/password-hash.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.47.0 # MSRV + - 1.57.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -44,7 +44,7 @@ jobs: strategy: matrix: rust: - - 1.47.0 # MSRV + - 1.57.0 # MSRV - stable steps: - uses: actions/checkout@v1 diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index e2413ce35..c5b9498e2 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -16,7 +16,7 @@ jobs: - uses: actions/checkout@v1 - uses: actions-rs/toolchain@v1 with: - toolchain: 1.56.0 + toolchain: 1.57.0 components: clippy override: true profile: minimal diff --git a/Cargo.lock b/Cargo.lock index 5820faa28..c8da2e442 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -199,7 +199,7 @@ dependencies = [ [[package]] name = "password-hash" -version = "0.3.2" +version = "0.4.0-pre" dependencies = [ "base64ct", "rand_core", diff --git a/crypto/Cargo.lock b/crypto/Cargo.lock index 296df354c..cf9bc9780 100644 --- a/crypto/Cargo.lock +++ b/crypto/Cargo.lock @@ -183,7 +183,7 @@ checksum = "fbe5e23404da5b4f555ef85ebed98fb4083e55a00c317800bc2a50ede9f3d219" [[package]] name = "password-hash" -version = "0.3.2" +version = "0.4.0-pre" dependencies = [ "base64ct", "rand_core", diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index 266a0fbb1..7ef2d9d27 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -12,7 +12,7 @@ keywords = ["crypto", "encryption", "rustcrypto"] categories = ["cryptography", "no-std"] readme = "README.md" edition = "2021" -rust-version = "1.56" +rust-version = "1.57" # Hack to allow this crate to coexist with pre-2021 edition crates [workspace] @@ -24,7 +24,7 @@ cipher = { version = "0.3", optional = true } digest = { version = "0.10", optional = true } elliptic-curve = { version = "0.12.0-pre", optional = true, path = "../elliptic-curve" } mac = { version = "0.11", package = "crypto-mac", optional = true } -password-hash = { version = "0.3", optional = true, path = "../password-hash" } +password-hash = { version = "=0.4.0-pre", optional = true, path = "../password-hash" } signature = { version = "1.5", optional = true, default-features = false, path = "../signature" } universal-hash = { version = "0.4", optional = true, path = "../universal-hash" } diff --git a/crypto/README.md b/crypto/README.md index 870d5d0b2..3ed0ced44 100644 --- a/crypto/README.md +++ b/crypto/README.md @@ -14,7 +14,7 @@ access compatible versions of all traits from the Rust Crypto project. ## Minimum Supported Rust Version -Rust **1.56** or higher. +Rust **1.57** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -46,7 +46,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/crypto/badge.svg [docs-link]: https://docs.rs/crypto/ [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.57+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260050-Traits [build-image]: https://github.com/RustCrypto/traits/workflows/crypto/badge.svg?branch=master&event=push diff --git a/crypto/src/lib.rs b/crypto/src/lib.rs index f26cee7de..e5730641e 100644 --- a/crypto/src/lib.rs +++ b/crypto/src/lib.rs @@ -1,3 +1,12 @@ +#![no_std] +#![doc( + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", + html_root_url = "https://docs.rs/crypto/0.4.0-pre" +)] +#![forbid(unsafe_code)] +#![warn(rust_2018_idioms)] + //! Facade crate for [RustCrypto Traits][1], providing a single place to //! access compatible versions of all traits from the Rust Crypto project. //! @@ -35,15 +44,6 @@ //! [1]: https://github.com/RustCrypto/traits //! [2]: https://github.com/RustCrypto -#![no_std] -#![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/crypto/0.4.0-pre" -)] -#![forbid(unsafe_code)] -#![warn(rust_2018_idioms)] - #[cfg(feature = "aead")] pub use aead; diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index dd74c22b7..bb4c70a76 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -5,7 +5,7 @@ Traits which describe the functionality of password hashing algorithms, as well as a `no_std`-friendly implementation of the PHC string format (a well-defined subset of the Modular Crypt Format a.k.a. MCF) """ -version = "0.3.2" # Also update html_root_url in lib.rs when bumping this +version = "0.4.0-pre" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/password-hash/README.md b/password-hash/README.md index 7f025a280..e873f2a1c 100644 --- a/password-hash/README.md +++ b/password-hash/README.md @@ -20,7 +20,7 @@ these traits. ## Minimum Supported Rust Version -Rust **1.47** or higher. +Rust **1.57** or higher. Minimum supported Rust version may be changed in the future, but it will be accompanied by a minor version bump. @@ -52,7 +52,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/password-hash/badge.svg [docs-link]: https://docs.rs/password-hash/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.47+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.57+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260046-password-hashes [build-image]: https://github.com/RustCrypto/traits/workflows/password-hash/badge.svg?branch=master&event=push diff --git a/password-hash/src/ident.rs b/password-hash/src/ident.rs index 06926c0fa..a97b0ae06 100644 --- a/password-hash/src/ident.rs +++ b/password-hash/src/ident.rs @@ -60,23 +60,14 @@ impl<'a> Ident<'a> { pub const fn new(s: &'a str) -> Self { let input = s.as_bytes(); - /// Constant panicking assertion. - // TODO(tarcieri): use const panic when stable. - // See: https://github.com/rust-lang/rust/issues/51999 - macro_rules! const_assert { - ($bool:expr, $msg:expr) => { - [$msg][!$bool as usize] - }; - } - - const_assert!(!input.is_empty(), "PHC ident string can't be empty"); - const_assert!(input.len() <= Self::MAX_LENGTH, "PHC ident string too long"); + assert!(!input.is_empty(), "PHC ident string can't be empty"); + assert!(input.len() <= Self::MAX_LENGTH, "PHC ident string too long"); macro_rules! validate_chars { ($($pos:expr),+) => { $( if $pos < input.len() { - const_assert!( + assert!( is_char_valid(input[$pos]), "invalid character in PHC string ident" ); diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index 317b7fe65..4d8360f03 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -39,7 +39,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/password-hash/0.3.2" + html_root_url = "https://docs.rs/password-hash/0.4.0-pre" )] #![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms, unused_lifetimes)] From 1ecd0930bfc84e41be0de57d38934b6a7306c5a5 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 17 Jan 2022 18:39:36 -0700 Subject: [PATCH 0723/1461] password-hash: Rust 2021 edition upgrade (#897) Upgrades the edition to 2021: deduplicating documentation between README.md and lib.rs and removing explicit `TryFrom`/`TryInto` imports. --- Cargo.lock | 15 ------- Cargo.toml | 1 - elliptic-curve/src/lib.rs | 6 +-- password-hash/Cargo.lock | 62 ++++++++++++++++++++++++++++ password-hash/Cargo.toml | 7 +++- password-hash/README.md | 25 ++++++++--- password-hash/src/ident.rs | 3 +- password-hash/src/lib.rs | 50 ++++++---------------- password-hash/src/output.rs | 2 +- password-hash/src/params.rs | 3 +- password-hash/src/salt.rs | 5 +-- password-hash/src/traits.rs | 5 +-- password-hash/src/value.rs | 3 +- password-hash/tests/hashing.rs | 1 - password-hash/tests/password_hash.rs | 1 - 15 files changed, 108 insertions(+), 81 deletions(-) create mode 100644 password-hash/Cargo.lock diff --git a/Cargo.lock b/Cargo.lock index c8da2e442..96ff03900 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -31,12 +31,6 @@ dependencies = [ "syn", ] -[[package]] -name = "base64ct" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a32fd6af2b5827bce66c29053ba0e7c42b9dcab01835835058558c10851a46b" - [[package]] name = "blobby" version = "0.3.1" @@ -197,15 +191,6 @@ dependencies = [ "scopeguard", ] -[[package]] -name = "password-hash" -version = "0.4.0-pre" -dependencies = [ - "base64ct", - "rand_core", - "subtle", -] - [[package]] name = "proc-macro-hack" version = "0.5.19" diff --git a/Cargo.toml b/Cargo.toml index c0e881aa2..8484c3c8e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,6 @@ members = [ "cipher", "crypto-common", "digest", - "password-hash", "signature", "signature/async", "universal-hash", diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 27a738536..0cc7dc54c 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -1,13 +1,13 @@ #![no_std] #![cfg_attr(docsrs, feature(doc_cfg))] -#![forbid(unsafe_code, clippy::unwrap_used)] -#![warn(missing_docs, rust_2018_idioms, unused_qualifications)] +#![doc = include_str!("../README.md")] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_root_url = "https://docs.rs/elliptic-curve/0.12.0-pre" )] -#![doc = include_str!("../README.md")] +#![forbid(unsafe_code, clippy::unwrap_used)] +#![warn(missing_docs, rust_2018_idioms, unused_qualifications)] //! ## Usage //! diff --git a/password-hash/Cargo.lock b/password-hash/Cargo.lock new file mode 100644 index 000000000..a10c756bb --- /dev/null +++ b/password-hash/Cargo.lock @@ -0,0 +1,62 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "base64ct" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a32fd6af2b5827bce66c29053ba0e7c42b9dcab01835835058558c10851a46b" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "getrandom" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "libc" +version = "0.2.112" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" + +[[package]] +name = "password-hash" +version = "0.4.0-pre" +dependencies = [ + "base64ct", + "rand_core", + "subtle", +] + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom", +] + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index bb4c70a76..a3260ca5c 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -9,11 +9,16 @@ version = "0.4.0-pre" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" -edition = "2018" documentation = "https://docs.rs/password-hash" repository = "https://github.com/RustCrypto/traits/tree/master/password-hash" categories = ["cryptography", "no-std"] keywords = ["crypt", "mcf", "password", "pbkdf", "phc"] +edition = "2021" +rust-version = "1.57" + +# Hack to allow this crate to coexist with pre-2021 edition crates +[workspace] +members = ["."] [dependencies] base64ct = ">=1, <1.1.0" diff --git a/password-hash/README.md b/password-hash/README.md index e873f2a1c..05ba77239 100644 --- a/password-hash/README.md +++ b/password-hash/README.md @@ -9,14 +9,23 @@ Traits which describe the functionality of [password hashing algorithms]. -Includes a `no_std`-friendly implementation of the [PHC string format] -(a well-defined subset of the Modular Crypt Format a.k.a. MCF) which -uses the traits this crate defines. +[Documentation][docs-link] + +## About + +Provides a `no_std`-friendly implementation of the +[Password Hashing Competition (PHC) string format specification][PHC] +(a well-defined subset of the [Modular Crypt Format a.k.a. MCF][MCF]) which +works in conjunction with the traits this crate defines. + +## Supported Crates See [RustCrypto/password-hashes] for algorithm implementations which use -these traits. +this crate for interoperability: -[Documentation][docs-link] +- [`argon2`] - Argon2 memory hard key derivation function +- [`pbkdf2`] - Password-Based Key Derivation Function v2 +- [`scrypt`] - scrypt key derivation function ## Minimum Supported Rust Version @@ -61,5 +70,9 @@ dual licensed as above, without any additional terms or conditions. [//]: # (general links) [password hashing algorithms]: https://en.wikipedia.org/wiki/Cryptographic_hash_function#Password_verification -[PHC string format]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md +[PHC]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md +[MCF]: https://passlib.readthedocs.io/en/stable/modular_crypt_format.html [RustCrypto/password-hashes]: https://github.com/RustCrypto/password-hashes +[`argon2`]: https://docs.rs/argon2 +[`pbkdf2`]: https://docs.rs/pbkdf2 +[`scrypt`]: https://docs.rs/scrypt diff --git a/password-hash/src/ident.rs b/password-hash/src/ident.rs index a97b0ae06..8283385ce 100644 --- a/password-hash/src/ident.rs +++ b/password-hash/src/ident.rs @@ -17,7 +17,7 @@ //! [1]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md use crate::{Error, Result}; -use core::{convert::TryFrom, fmt, ops::Deref, str}; +use core::{fmt, ops::Deref, str}; /// Algorithm or parameter identifier. /// @@ -151,7 +151,6 @@ const fn is_char_valid(c: u8) -> bool { #[cfg(test)] mod tests { use super::{Error, Ident}; - use core::convert::TryFrom; // Invalid ident examples const INVALID_EMPTY: &str = ""; diff --git a/password-hash/src/lib.rs b/password-hash/src/lib.rs index 4d8360f03..c59fa2b1f 100644 --- a/password-hash/src/lib.rs +++ b/password-hash/src/lib.rs @@ -1,19 +1,14 @@ -//! This crate defines a set of traits which describe the functionality of -//! [password hashing algorithms]. -//! -//! Provides a `no_std`-friendly implementation of the -//! [Password Hashing Competition (PHC) string format specification][PHC] -//! (a well-defined subset of the [Modular Crypt Format a.k.a. MCF][MCF]) which -//! works in conjunction with the traits this crate defines. -//! -//! # Supported Crates -//! -//! See [RustCrypto/password-hashes] for algorithm implementations which use -//! this crate for interoperability: -//! -//! - [`argon2`] - Argon2 memory hard key derivation function -//! - [`pbkdf2`] - Password-Based Key Derivation Function v2 -//! - [`scrypt`] - scrypt key derivation function +#![no_std] +#![cfg_attr(docsrs, feature(doc_cfg))] +#![doc = include_str!("../README.md")] +#![doc( + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", + html_root_url = "https://docs.rs/password-hash/0.4.0-pre" +)] +#![forbid(unsafe_code)] +#![warn(missing_docs, rust_2018_idioms, unused_lifetimes)] + //! //! # Usage //! @@ -25,24 +20,6 @@ //! ``` //! //! For more information, please see the documentation for [`PasswordHash`]. -//! -//! [password hashing algorithms]: https://en.wikipedia.org/wiki/Cryptographic_hash_function#Password_verification -//! [PHC]: https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md -//! [MCF]: https://passlib.readthedocs.io/en/stable/modular_crypt_format.html -//! [RustCrypto/password-hashes]: https://github.com/RustCrypto/password-hashes -//! [`argon2`]: https://docs.rs/argon2 -//! [`pbkdf2`]: https://docs.rs/pbkdf2 -//! [`scrypt`]: https://docs.rs/scrypt - -#![no_std] -#![cfg_attr(docsrs, feature(doc_cfg))] -#![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/password-hash/0.4.0-pre" -)] -#![forbid(unsafe_code)] -#![warn(missing_docs, rust_2018_idioms, unused_lifetimes)] #[cfg(feature = "alloc")] extern crate alloc; @@ -74,10 +51,7 @@ pub use crate::{ value::{Decimal, Value}, }; -use core::{ - convert::{TryFrom, TryInto}, - fmt::{self, Debug}, -}; +use core::fmt::{self, Debug}; #[cfg(feature = "alloc")] use alloc::{ diff --git a/password-hash/src/output.rs b/password-hash/src/output.rs index 786e6ae62..c2560ce12 100644 --- a/password-hash/src/output.rs +++ b/password-hash/src/output.rs @@ -1,7 +1,7 @@ //! Outputs from password hashing functions. use crate::{Encoding, Error, Result}; -use core::{cmp::PartialEq, convert::TryFrom, fmt, str::FromStr}; +use core::{cmp::PartialEq, fmt, str::FromStr}; use subtle::{Choice, ConstantTimeEq}; /// Output from password hashing functions, i.e. the "hash" or "digest" diff --git a/password-hash/src/params.rs b/password-hash/src/params.rs index 5dc3c996c..913a55f49 100644 --- a/password-hash/src/params.rs +++ b/password-hash/src/params.rs @@ -6,7 +6,6 @@ use crate::{ Encoding, Error, Ident, Result, }; use core::{ - convert::{TryFrom, TryInto}, fmt::{self, Debug, Write}, iter::FromIterator, str::{self, FromStr}, @@ -325,7 +324,7 @@ mod tests { #[cfg(feature = "alloc")] use alloc::string::ToString; - use core::{convert::TryFrom, str::FromStr}; + use core::str::FromStr; #[test] fn add() { diff --git a/password-hash/src/salt.rs b/password-hash/src/salt.rs index cabd9c281..b5f09f84d 100644 --- a/password-hash/src/salt.rs +++ b/password-hash/src/salt.rs @@ -1,10 +1,7 @@ //! Salt string support. use crate::{Encoding, Error, Result, Value}; -use core::{ - convert::{TryFrom, TryInto}, - fmt, str, -}; +use core::{fmt, str}; use crate::errors::InvalidValue; #[cfg(feature = "rand_core")] diff --git a/password-hash/src/traits.rs b/password-hash/src/traits.rs index 96abccb6a..61e04adda 100644 --- a/password-hash/src/traits.rs +++ b/password-hash/src/traits.rs @@ -1,10 +1,7 @@ //! Trait definitions. use crate::{Decimal, Error, Ident, ParamsString, PasswordHash, Result, Salt}; -use core::{ - convert::{TryFrom, TryInto}, - fmt::Debug, -}; +use core::fmt::Debug; /// Trait for password hashing functions. pub trait PasswordHasher { diff --git a/password-hash/src/value.rs b/password-hash/src/value.rs index 5a453c0f8..acce35cc9 100644 --- a/password-hash/src/value.rs +++ b/password-hash/src/value.rs @@ -15,7 +15,7 @@ use crate::errors::InvalidValue; use crate::{Encoding, Error, Result}; -use core::{convert::TryFrom, fmt, str}; +use core::{fmt, str}; /// Type used to represent decimal (i.e. integer) values. pub type Decimal = u32; @@ -209,7 +209,6 @@ fn is_char_valid(c: char) -> bool { #[cfg(test)] mod tests { use super::{Error, InvalidValue, Value}; - use core::convert::TryFrom; // Invalid value examples const INVALID_CHAR: &str = "x;y"; diff --git a/password-hash/tests/hashing.rs b/password-hash/tests/hashing.rs index 496b4cd00..b88bff86a 100644 --- a/password-hash/tests/hashing.rs +++ b/password-hash/tests/hashing.rs @@ -3,7 +3,6 @@ pub use password_hash::{ Decimal, Error, Ident, Output, ParamsString, PasswordHash, PasswordHasher, Result, Salt, }; -use std::convert::{TryFrom, TryInto}; const ALG: Ident = Ident::new("example"); diff --git a/password-hash/tests/password_hash.rs b/password-hash/tests/password_hash.rs index 107136063..30e4357ed 100644 --- a/password-hash/tests/password_hash.rs +++ b/password-hash/tests/password_hash.rs @@ -4,7 +4,6 @@ //! of the string encoding, and ensures password hashes round trip under each //! of the conditions. -use core::convert::{TryFrom, TryInto}; use password_hash::{Ident, ParamsString, PasswordHash, Salt}; const EXAMPLE_ALGORITHM: Ident = Ident::new("argon2d"); From f899a15cb2cd293d69d1b6502e7cc537d3da480d Mon Sep 17 00:00:00 2001 From: daxpedda Date: Tue, 18 Jan 2022 14:41:08 +0100 Subject: [PATCH 0724/1461] Handle empty `dst` (#899) --- elliptic-curve/src/hash2field/expand_msg.rs | 24 +++++++++++-------- .../src/hash2field/expand_msg/xmd.rs | 9 +++---- .../src/hash2field/expand_msg/xof.rs | 9 +++---- 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/elliptic-curve/src/hash2field/expand_msg.rs b/elliptic-curve/src/hash2field/expand_msg.rs index 6fd88dfdc..dfb3bab9c 100644 --- a/elliptic-curve/src/hash2field/expand_msg.rs +++ b/elliptic-curve/src/hash2field/expand_msg.rs @@ -3,7 +3,7 @@ pub(super) mod xmd; pub(super) mod xof; -use crate::Result; +use crate::{Error, Result}; use digest::{Digest, ExtendableOutput, Update, XofReader}; use generic_array::typenum::{IsLess, U256}; use generic_array::{ArrayLength, GenericArray}; @@ -54,36 +54,40 @@ impl<'a, L> Domain<'a, L> where L: ArrayLength + IsLess, { - pub fn xof(dst: &'a [u8]) -> Self + pub fn xof(dst: &'a [u8]) -> Result where X: Default + ExtendableOutput + Update, { - if dst.len() > MAX_DST_LEN { + if dst.is_empty() { + Err(Error) + } else if dst.len() > MAX_DST_LEN { let mut data = GenericArray::::default(); X::default() .chain(OVERSIZE_DST_SALT) .chain(dst) .finalize_xof() .read(&mut data); - Self::Hashed(data) + Ok(Self::Hashed(data)) } else { - Self::Array(dst) + Ok(Self::Array(dst)) } } - pub fn xmd(dst: &'a [u8]) -> Self + pub fn xmd(dst: &'a [u8]) -> Result where X: Digest, { - if dst.len() > MAX_DST_LEN { - Self::Hashed({ + if dst.is_empty() { + Err(Error) + } else if dst.len() > MAX_DST_LEN { + Ok(Self::Hashed({ let mut hash = X::new(); hash.update(OVERSIZE_DST_SALT); hash.update(dst); hash.finalize() - }) + })) } else { - Self::Array(dst) + Ok(Self::Array(dst)) } } diff --git a/elliptic-curve/src/hash2field/expand_msg/xmd.rs b/elliptic-curve/src/hash2field/expand_msg/xmd.rs index 5132f3b3a..876b012f5 100644 --- a/elliptic-curve/src/hash2field/expand_msg/xmd.rs +++ b/elliptic-curve/src/hash2field/expand_msg/xmd.rs @@ -16,6 +16,7 @@ use digest::{ /// Placeholder type for implementing `expand_message_xmd` based on a hash function /// /// # Errors +/// - `dst.is_empty()` /// - `len_in_bytes == 0` /// - `len_in_bytes > u16::MAX` /// - `len_in_bytes > 255 * HashT::OutputSize` @@ -53,7 +54,7 @@ where let b_in_bytes = HashT::OutputSize::to_usize(); let ell = u8::try_from((len_in_bytes + b_in_bytes - 1) / b_in_bytes).map_err(|_| Error)?; - let domain = Domain::xmd::(dst); + let domain = Domain::xmd::(dst)?; let mut b_0 = HashT::new(); b_0.update(GenericArray::::default()); @@ -226,7 +227,7 @@ mod test { const DST_PRIME: &[u8] = &hex!("515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826"); - let dst_prime = Domain::xmd::(DST); + let dst_prime = Domain::xmd::(DST)?; dst_prime.assert(DST_PRIME); const TEST_VECTORS_32: &[TestVector] = &[ @@ -298,7 +299,7 @@ mod test { const DST_PRIME: &[u8] = &hex!("412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620"); - let dst_prime = Domain::xmd::(DST); + let dst_prime = Domain::xmd::(DST)?; dst_prime.assert(DST_PRIME); const TEST_VECTORS_32: &[TestVector] = &[ @@ -376,7 +377,7 @@ mod test { const DST_PRIME: &[u8] = &hex!("515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626"); - let dst_prime = Domain::xmd::(DST); + let dst_prime = Domain::xmd::(DST)?; dst_prime.assert(DST_PRIME); const TEST_VECTORS_32: &[TestVector] = &[ diff --git a/elliptic-curve/src/hash2field/expand_msg/xof.rs b/elliptic-curve/src/hash2field/expand_msg/xof.rs index d7ca714cf..107ac5e06 100644 --- a/elliptic-curve/src/hash2field/expand_msg/xof.rs +++ b/elliptic-curve/src/hash2field/expand_msg/xof.rs @@ -8,6 +8,7 @@ use generic_array::typenum::U32; /// Placeholder type for implementing `expand_message_xof` based on an extendable output function /// /// # Errors +/// - `dst.is_empty()` /// - `len_in_bytes == 0` /// - `len_in_bytes > u16::MAX` pub struct ExpandMsgXof @@ -35,7 +36,7 @@ where let len_in_bytes = u16::try_from(len_in_bytes).map_err(|_| Error)?; - let domain = Domain::::xof::(dst); + let domain = Domain::::xof::(dst)?; let mut reader = HashT::default(); for msg in msgs { @@ -126,7 +127,7 @@ mod test { const DST_PRIME: &[u8] = &hex!("515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824"); - let dst_prime = Domain::::xof::(DST); + let dst_prime = Domain::::xof::(DST)?; dst_prime.assert(DST_PRIME); const TEST_VECTORS_32: &[TestVector] = &[ @@ -202,7 +203,7 @@ mod test { const DST_PRIME: &[u8] = &hex!("acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20"); - let dst_prime = Domain::::xof::(DST); + let dst_prime = Domain::::xof::(DST)?; dst_prime.assert(DST_PRIME); const TEST_VECTORS_32: &[TestVector] = &[ @@ -280,7 +281,7 @@ mod test { const DST_PRIME: &[u8] = &hex!("515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624"); - let dst_prime = Domain::::xof::(DST); + let dst_prime = Domain::::xof::(DST)?; dst_prime.assert(DST_PRIME); const TEST_VECTORS_32: &[TestVector] = &[ From 8744c46c7488edda4b297b3506bf2fefbb82b931 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 18 Jan 2022 08:33:30 -0700 Subject: [PATCH 0725/1461] elliptic-curve: bump `crypto-bigint` to v0.4.0-pre.0 (#900) --- .github/workflows/elliptic-curve.yml | 6 +++--- elliptic-curve/Cargo.lock | 4 ++-- elliptic-curve/Cargo.toml | 4 ++-- elliptic-curve/README.md | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/elliptic-curve.yml b/.github/workflows/elliptic-curve.yml index 338812ccf..7accaf507 100644 --- a/.github/workflows/elliptic-curve.yml +++ b/.github/workflows/elliptic-curve.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.57.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -59,7 +59,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.57.0 # MSRV - stable - nightly steps: @@ -80,7 +80,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: - toolchain: 1.56.0 + toolchain: 1.57.0 components: clippy override: true profile: minimal diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index defe91c47..1375bfaef 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -58,9 +58,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.3.2" +version = "0.4.0-pre.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21" +checksum = "6a9df9647255ed398be26379810e02ed1d58263570b3bcd243ee2481f79c88b1" dependencies = [ "generic-array", "rand_core", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 14695fd39..56902dc0e 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -13,7 +13,7 @@ readme = "README.md" categories = ["cryptography", "no-std"] keywords = ["crypto", "ecc", "elliptic", "weierstrass"] edition = "2021" -rust-version = "1.56" +rust-version = "1.57" # Hack to allow this crate to coexist with pre-2021 edition crates [workspace] @@ -21,7 +21,7 @@ members = ["."] [dependencies] base16ct = "0.1.1" -crypto-bigint = { version = "0.3", default-features = false, features = ["rand_core", "generic-array", "zeroize"] } +crypto-bigint = { version = "=0.4.0-pre.0", default-features = false, features = ["rand_core", "generic-array", "zeroize"] } der = { version = "0.5", default-features = false, features = ["oid"] } generic-array = { version = "0.14", default-features = false } rand_core = { version = "0.6", default-features = false } diff --git a/elliptic-curve/README.md b/elliptic-curve/README.md index 97fd3be4e..0fa524d34 100644 --- a/elliptic-curve/README.md +++ b/elliptic-curve/README.md @@ -15,7 +15,7 @@ and public/secret keys composed thereof. ## Minimum Supported Rust Version -Requires Rust **1.56** or higher. +Requires Rust **1.57** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -47,7 +47,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/elliptic-curve/badge.svg [docs-link]: https://docs.rs/elliptic-curve/ [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.57+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260040-elliptic-curves [build-image]: https://github.com/RustCrypto/elliptic-curves/workflows/elliptic-curve%20crate/badge.svg?branch=master&event=push From 15d2c1945f1f4600138d2bbabd9b26245b8c12b8 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 18 Jan 2022 08:50:11 -0700 Subject: [PATCH 0726/1461] elliptic-curve v0.12.0-pre.0 (#902) --- elliptic-curve/Cargo.lock | 2 +- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index 1375bfaef..6f1b4d291 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -100,7 +100,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.12.0-pre" +version = "0.12.0-pre.0" dependencies = [ "base16ct", "base64ct", diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 56902dc0e..9fd5b94cd 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.12.0-pre" # Also update html_root_url in lib.rs when bumping this +version = "0.12.0-pre.0" # Also update html_root_url in lib.rs when bumping this description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 0cc7dc54c..4627e2fd2 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -4,7 +4,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.12.0-pre" + html_root_url = "https://docs.rs/elliptic-curve/0.12.0-pre.0" )] #![forbid(unsafe_code, clippy::unwrap_used)] #![warn(missing_docs, rust_2018_idioms, unused_qualifications)] From 27536e0b298a39bd13290529aa209dbd7e995a42 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Tue, 18 Jan 2022 17:28:58 +0100 Subject: [PATCH 0727/1461] elliptic-curve: move `hash2field` into `hash2curve` module (#903) --- elliptic-curve/src/hash2curve.rs | 2 ++ elliptic-curve/src/hash2curve/group_digest.rs | 7 ++----- elliptic-curve/src/{ => hash2curve}/hash2field.rs | 1 + .../src/{ => hash2curve}/hash2field/expand_msg.rs | 0 .../src/{ => hash2curve}/hash2field/expand_msg/xmd.rs | 0 .../src/{ => hash2curve}/hash2field/expand_msg/xof.rs | 0 elliptic-curve/src/lib.rs | 4 ---- 7 files changed, 5 insertions(+), 9 deletions(-) rename elliptic-curve/src/{ => hash2curve}/hash2field.rs (98%) rename elliptic-curve/src/{ => hash2curve}/hash2field/expand_msg.rs (100%) rename elliptic-curve/src/{ => hash2curve}/hash2field/expand_msg/xmd.rs (100%) rename elliptic-curve/src/{ => hash2curve}/hash2field/expand_msg/xof.rs (100%) diff --git a/elliptic-curve/src/hash2curve.rs b/elliptic-curve/src/hash2curve.rs index 1ac1d35fe..3df394f79 100644 --- a/elliptic-curve/src/hash2curve.rs +++ b/elliptic-curve/src/hash2curve.rs @@ -3,11 +3,13 @@ //! mod group_digest; +mod hash2field; mod isogeny; mod map2curve; mod osswu; pub use group_digest::*; +pub use hash2field::*; pub use isogeny::*; pub use map2curve::*; pub use osswu::*; diff --git a/elliptic-curve/src/hash2curve/group_digest.rs b/elliptic-curve/src/hash2curve/group_digest.rs index be42553d0..ba287906d 100644 --- a/elliptic-curve/src/hash2curve/group_digest.rs +++ b/elliptic-curve/src/hash2curve/group_digest.rs @@ -1,10 +1,7 @@ //! Traits for handling hash to curve. -use super::MapToCurve; -use crate::{ - hash2field::{hash_to_field, ExpandMsg, FromOkm}, - ProjectiveArithmetic, Result, -}; +use super::{hash_to_field, ExpandMsg, FromOkm, MapToCurve}; +use crate::{ProjectiveArithmetic, Result}; use group::cofactor::CofactorGroup; /// Adds hashing arbitrary byte sequences to a valid group element diff --git a/elliptic-curve/src/hash2field.rs b/elliptic-curve/src/hash2curve/hash2field.rs similarity index 98% rename from elliptic-curve/src/hash2field.rs rename to elliptic-curve/src/hash2curve/hash2field.rs index 369e96cf5..6cd0723aa 100644 --- a/elliptic-curve/src/hash2field.rs +++ b/elliptic-curve/src/hash2curve/hash2field.rs @@ -31,6 +31,7 @@ pub trait FromOkm { /// /// [`ExpandMsgXmd`]: crate::hash2field::ExpandMsgXmd /// [`ExpandMsgXof`]: crate::hash2field::ExpandMsgXof +#[doc(hidden)] pub fn hash_to_field<'a, E, T>(data: &[&[u8]], domain: &'a [u8], out: &mut [T]) -> Result<()> where E: ExpandMsg<'a>, diff --git a/elliptic-curve/src/hash2field/expand_msg.rs b/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs similarity index 100% rename from elliptic-curve/src/hash2field/expand_msg.rs rename to elliptic-curve/src/hash2curve/hash2field/expand_msg.rs diff --git a/elliptic-curve/src/hash2field/expand_msg/xmd.rs b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs similarity index 100% rename from elliptic-curve/src/hash2field/expand_msg/xmd.rs rename to elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs diff --git a/elliptic-curve/src/hash2field/expand_msg/xof.rs b/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs similarity index 100% rename from elliptic-curve/src/hash2field/expand_msg/xof.rs rename to elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index 4627e2fd2..c145446a2 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -93,10 +93,6 @@ pub mod ecdh; #[cfg(feature = "jwk")] mod jwk; -#[cfg(feature = "hash2curve")] -#[doc(hidden)] -pub mod hash2field; - #[cfg(feature = "hash2curve")] #[cfg_attr(docsrs, doc(cfg(feature = "hash2curve")))] pub mod hash2curve; From 03cbd28d1f6d97fcc35beecdc7af92c307c557cc Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 18 Jan 2022 18:36:36 -0700 Subject: [PATCH 0728/1461] elliptic-curve: simplify `Reduce::from_*_digest_reduce` bounds (#904) Several of the previous bounds are unnecessary for the actual operation performed, which is just `finalize_fixed`. This commit removes the unneeded bounds. --- elliptic-curve/src/ops.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/elliptic-curve/src/ops.rs b/elliptic-curve/src/ops.rs index 64a0eb3c6..580c5aefc 100644 --- a/elliptic-curve/src/ops.rs +++ b/elliptic-curve/src/ops.rs @@ -8,7 +8,7 @@ use crypto_bigint::{ArrayEncoding, ByteArray, Integer}; use {group::Group, subtle::CtOption}; #[cfg(feature = "digest")] -use digest::{core_api::BlockSizeUser, Digest, FixedOutput, Reset}; +use digest::FixedOutput; /// Perform an inversion on a field element (i.e. base field element or scalar) pub trait Invert { @@ -66,9 +66,9 @@ pub trait Reduce: Sized { #[cfg_attr(docsrs, doc(cfg(feature = "digest")))] fn from_be_digest_reduced(digest: D) -> Self where - D: FixedOutput + BlockSizeUser + Clone + Digest + Reset, + D: FixedOutput, { - Self::from_be_bytes_reduced(digest.finalize()) + Self::from_be_bytes_reduced(digest.finalize_fixed()) } /// Interpret a digest as a little endian integer and perform a modular @@ -77,9 +77,9 @@ pub trait Reduce: Sized { #[cfg_attr(docsrs, doc(cfg(feature = "digest")))] fn from_le_digest_reduced(digest: D) -> Self where - D: FixedOutput + BlockSizeUser + Clone + Digest + Reset, + D: FixedOutput, { - Self::from_le_bytes_reduced(digest.finalize()) + Self::from_le_bytes_reduced(digest.finalize_fixed()) } } From c4c3df126674141c4c09c106d4be2a2ec1476fbd Mon Sep 17 00:00:00 2001 From: daxpedda Date: Wed, 19 Jan 2022 14:16:59 +0100 Subject: [PATCH 0729/1461] Add missing jobs to excluded workspace crates (#905) --- .github/dependabot.yml | 20 +++++ .github/workflows/security-audit.yml | 76 ++++++++++++++++++- .github/workflows/workspace.yml | 106 ++++++++++++++++++++++++--- 3 files changed, 187 insertions(+), 15 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 5cde1657c..ce2b35da8 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,3 +5,23 @@ updates: schedule: interval: daily open-pull-requests-limit: 10 +- package-ecosystem: cargo + directory: "/crypto" + schedule: + interval: daily + open-pull-requests-limit: 10 +- package-ecosystem: cargo + directory: "/elliptic-curve" + schedule: + interval: daily + open-pull-requests-limit: 10 +- package-ecosystem: cargo + directory: "/kem" + schedule: + interval: daily + open-pull-requests-limit: 10 +- package-ecosystem: cargo + directory: "/password-hash" + schedule: + interval: daily + open-pull-requests-limit: 10 diff --git a/.github/workflows/security-audit.yml b/.github/workflows/security-audit.yml index 0d82d54ba..b1091a4c2 100644 --- a/.github/workflows/security-audit.yml +++ b/.github/workflows/security-audit.yml @@ -1,16 +1,16 @@ name: Security Audit on: pull_request: - paths: Cargo.lock + paths: '**/Cargo.lock' push: branches: master - paths: Cargo.lock + paths: '**/Cargo.lock' schedule: - cron: "0 0 * * *" jobs: - security_audit: - name: Security Audit + security_audit_workspace: + name: Security Audit Workspace runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 @@ -22,3 +22,71 @@ jobs: - uses: actions-rs/audit-check@v1 with: token: ${{ secrets.GITHUB_TOKEN }} + + security_audit_crypto: + name: Security Audit crypto + runs-on: ubuntu-latest + defaults: + run: + working-directory: crypto + steps: + - uses: actions/checkout@v1 + - name: Cache cargo bin + uses: actions/cache@v1 + with: + path: ~/.cargo/bin + key: ${{ runner.os }}-cargo-audit-v0.12.0 + - uses: actions-rs/audit-check@v1 + with: + token: ${{ secrets.GITHUB_TOKEN }} + + security_audit_elliptic-curve: + name: Security Audit elliptic-curve + runs-on: ubuntu-latest + defaults: + run: + working-directory: elliptic-curve + steps: + - uses: actions/checkout@v1 + - name: Cache cargo bin + uses: actions/cache@v1 + with: + path: ~/.cargo/bin + key: ${{ runner.os }}-cargo-audit-v0.12.0 + - uses: actions-rs/audit-check@v1 + with: + token: ${{ secrets.GITHUB_TOKEN }} + + security_audit_kem: + name: Security Audit kem + runs-on: ubuntu-latest + defaults: + run: + working-directory: kem + steps: + - uses: actions/checkout@v1 + - name: Cache cargo bin + uses: actions/cache@v1 + with: + path: ~/.cargo/bin + key: ${{ runner.os }}-cargo-audit-v0.12.0 + - uses: actions-rs/audit-check@v1 + with: + token: ${{ secrets.GITHUB_TOKEN }} + + security_audit_password-hash: + name: Security Audit password-hash + runs-on: ubuntu-latest + defaults: + run: + working-directory: password-hash + steps: + - uses: actions/checkout@v1 + - name: Cache cargo bin + uses: actions/cache@v1 + with: + path: ~/.cargo/bin + key: ${{ runner.os }}-cargo-audit-v0.12.0 + - uses: actions-rs/audit-check@v1 + with: + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index c5b9498e2..5c8e83365 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -3,27 +3,111 @@ name: Workspace on: pull_request: paths-ignore: - - README.md + - '**/README.md' + - '**/CHANGELOG.md' + - .github/** push: branches: master paths-ignore: - - README.md + - '**/README.md' + - '**/CHANGELOG.md' + - .github/** jobs: clippy: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 - - uses: actions-rs/toolchain@v1 - with: - toolchain: 1.57.0 - components: clippy - override: true - profile: minimal - - run: cargo clippy --all --all-features -- -D warnings + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + toolchain: 1.57.0 + components: clippy + override: true + profile: minimal + - run: cargo clippy --all --all-features -- -D warnings + - run: cargo clippy --all --all-features -- -D warnings + working-directory: crypto + - run: cargo clippy --all --all-features -- -D warnings + working-directory: elliptic-curve + - run: cargo clippy --all --all-features -- -D warnings + working-directory: kem + - run: cargo clippy --all --all-features -- -D warnings + working-directory: password-hash + + rustfmt_workspace: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + toolchain: stable + components: rustfmt + override: true + profile: minimal + - uses: actions-rs/cargo@v1 + with: + command: fmt + args: --all -- --check + + rustfmt_crypto: + runs-on: ubuntu-latest + defaults: + run: + working-directory: crypto + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + toolchain: stable + components: rustfmt + override: true + profile: minimal + - uses: actions-rs/cargo@v1 + with: + command: fmt + args: --all -- --check + + rustfmt_elliptic-curve: + runs-on: ubuntu-latest + defaults: + run: + working-directory: elliptic-curve + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + toolchain: stable + components: rustfmt + override: true + profile: minimal + - uses: actions-rs/cargo@v1 + with: + command: fmt + args: --all -- --check + + rustfmt_kem: + runs-on: ubuntu-latest + defaults: + run: + working-directory: kem + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + toolchain: stable + components: rustfmt + override: true + profile: minimal + - uses: actions-rs/cargo@v1 + with: + command: fmt + args: --all -- --check - rustfmt: + rustfmt_password-hash: runs-on: ubuntu-latest + defaults: + run: + working-directory: password-hash steps: - uses: actions/checkout@v1 - uses: actions-rs/toolchain@v1 From a9fd0a7ab85374d5936c01e778a2d7f3f564b045 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 19 Jan 2022 06:39:33 -0700 Subject: [PATCH 0730/1461] password-hash: remove `base64ct` version restrictions (#914) These were in place to prevent MSRV-related breakages. Now that `password-hash` has been bumped to a higher MSRV than `base64ct`, it's no longer needed. --- password-hash/Cargo.lock | 4 ++-- password-hash/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/password-hash/Cargo.lock b/password-hash/Cargo.lock index a10c756bb..fe63ec2c0 100644 --- a/password-hash/Cargo.lock +++ b/password-hash/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "base64ct" -version = "1.0.1" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a32fd6af2b5827bce66c29053ba0e7c42b9dcab01835835058558c10851a46b" +checksum = "874f8444adcb4952a8bc51305c8be95c8ec8237bb0d2e78d2e039f771f8828a0" [[package]] name = "cfg-if" diff --git a/password-hash/Cargo.toml b/password-hash/Cargo.toml index a3260ca5c..9a0c3dc2e 100644 --- a/password-hash/Cargo.toml +++ b/password-hash/Cargo.toml @@ -21,7 +21,7 @@ rust-version = "1.57" members = ["."] [dependencies] -base64ct = ">=1, <1.1.0" +base64ct = "1" subtle = { version = ">=2, <2.5", default-features = false } # optional features From 898022ddcddaaf915d96c52abcb2999b6afd2e77 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 19 Jan 2022 06:50:54 -0700 Subject: [PATCH 0731/1461] elliptic-curve: bump dependencies in Cargo.lock (#915) Dependabot wasn't taking care of these since `elliptic-curve` is split out into its own workspace since older MSRV crates can't handle the 2021 edition. --- elliptic-curve/Cargo.lock | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index 6f1b4d291..886ca8c7e 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -10,9 +10,9 @@ checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" [[package]] name = "base64ct" -version = "1.3.1" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a30f9c631ae8b97868a2e841015b72f2c99b05e3f03a14d543b843816a0a5b4d" +checksum = "874f8444adcb4952a8bc51305c8be95c8ec8237bb0d2e78d2e039f771f8828a0" [[package]] name = "bitvec" @@ -141,9 +141,9 @@ checksum = "1847abb9cb65d566acd5942e94aea9c8f547ad02c98e1649326fc0e8910b8b1e" [[package]] name = "generic-array" -version = "0.14.4" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" dependencies = [ "typenum", "version_check", @@ -151,9 +151,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c" dependencies = [ "cfg-if", "libc", @@ -251,15 +251,15 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.132" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9875c23cf305cd1fd7eb77234cbb705f21ea6a72c637a5c6db5fe4b8e7f008" +checksum = "97565067517b60e2d1ea8b268e59ce036de907ac523ad83a0475da04e818989a" [[package]] name = "serde_json" -version = "1.0.73" +version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcbd0344bc6533bc7ec56df11d42fb70f1b912351c0825ccb7211b59d8af7cf5" +checksum = "c059c05b48c5c0067d4b4b2b4f0732dd65feb52daf7e0ea09cd87e7dadc1af79" dependencies = [ "itoa", "ryu", @@ -289,9 +289,9 @@ dependencies = [ [[package]] name = "spki" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "964d3a6f8b7ef6d6d20887f4c30c4848f4ffa05f600c87277d30a5b4fe32cb4b" +checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" dependencies = [ "base64ct", "der", @@ -311,21 +311,21 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "typenum" -version = "1.14.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" [[package]] name = "version_check" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" +version = "0.10.3+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" +checksum = "46a2e384a3f170b0c7543787a91411175b71afd56ba4d3a0ae5678d4e2243c0e" [[package]] name = "wyz" From 74c5be8797e59084711435750466030b49e2993e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Jan 2022 07:09:11 -0700 Subject: [PATCH 0732/1461] build(deps): bump generic-array from 0.14.4 to 0.14.5 in /kem (#911) Bumps [generic-array](https://github.com/fizyk20/generic-array) from 0.14.4 to 0.14.5. - [Release notes](https://github.com/fizyk20/generic-array/releases) - [Changelog](https://github.com/fizyk20/generic-array/blob/master/CHANGELOG.md) - [Commits](https://github.com/fizyk20/generic-array/commits) --- updated-dependencies: - dependency-name: generic-array dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- kem/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kem/Cargo.lock b/kem/Cargo.lock index a23a8f240..e5ca3ac5c 100644 --- a/kem/Cargo.lock +++ b/kem/Cargo.lock @@ -233,9 +233,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.4" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" dependencies = [ "typenum", "version_check", From 30cdb2e945e687a9d7d23f60a3d056e889ecdb0f Mon Sep 17 00:00:00 2001 From: daxpedda Date: Wed, 19 Jan 2022 19:27:54 +0100 Subject: [PATCH 0733/1461] Better constraint that `Output` is `ProjectivePoint` (#906) --- elliptic-curve/src/hash2curve/group_digest.rs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/elliptic-curve/src/hash2curve/group_digest.rs b/elliptic-curve/src/hash2curve/group_digest.rs index ba287906d..a7330058b 100644 --- a/elliptic-curve/src/hash2curve/group_digest.rs +++ b/elliptic-curve/src/hash2curve/group_digest.rs @@ -1,15 +1,16 @@ //! Traits for handling hash to curve. use super::{hash_to_field, ExpandMsg, FromOkm, MapToCurve}; -use crate::{ProjectiveArithmetic, Result}; +use crate::{ProjectiveArithmetic, ProjectivePoint, Result}; use group::cofactor::CofactorGroup; /// Adds hashing arbitrary byte sequences to a valid group element -pub trait GroupDigest: ProjectiveArithmetic { +pub trait GroupDigest: ProjectiveArithmetic +where + ProjectivePoint: CofactorGroup, +{ /// The field element representation for a group value with multiple elements - type FieldElement: FromOkm + MapToCurve + Default + Copy; - /// The resulting group element - type Output: CofactorGroup; + type FieldElement: FromOkm + MapToCurve> + Default + Copy; /// Computes the hash to curve routine. /// @@ -48,7 +49,7 @@ pub trait GroupDigest: ProjectiveArithmetic { fn hash_from_bytes<'a, X: ExpandMsg<'a>>( msgs: &[&[u8]], dst: &'a [u8], - ) -> Result { + ) -> Result> { let mut u = [Self::FieldElement::default(), Self::FieldElement::default()]; hash_to_field::(msgs, dst, &mut u)?; let q0 = u[0].map_to_curve(); @@ -63,7 +64,7 @@ pub trait GroupDigest: ProjectiveArithmetic { // isogenies are different with curves like k256 and bls12-381. // This problem doesn't manifest for curves with no isogeny like p256. // For k256 and p256 clear_cofactor doesn't do anything anyway so it will be a no-op. - Ok(q0.clear_cofactor() + q1.clear_cofactor()) + Ok(q0.clear_cofactor().into() + q1.clear_cofactor()) } /// Computes the encode to curve routine. @@ -88,11 +89,11 @@ pub trait GroupDigest: ProjectiveArithmetic { fn encode_from_bytes<'a, X: ExpandMsg<'a>>( msgs: &[&[u8]], dst: &'a [u8], - ) -> Result { + ) -> Result> { let mut u = [Self::FieldElement::default()]; hash_to_field::(msgs, dst, &mut u)?; let q0 = u[0].map_to_curve(); - Ok(q0.clear_cofactor()) + Ok(q0.clear_cofactor().into()) } /// Computes the hash to field routine according to From bf77a1194a0bb1c542a579e54febecb4cf6506f0 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 19 Jan 2022 15:17:46 -0700 Subject: [PATCH 0734/1461] elliptic-curve v0.12.0-pre.1 (#916) --- elliptic-curve/Cargo.toml | 2 +- elliptic-curve/src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/elliptic-curve/Cargo.toml b/elliptic-curve/Cargo.toml index 9fd5b94cd..8187f4654 100644 --- a/elliptic-curve/Cargo.toml +++ b/elliptic-curve/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "elliptic-curve" -version = "0.12.0-pre.0" # Also update html_root_url in lib.rs when bumping this +version = "0.12.0-pre.1" # Also update html_root_url in lib.rs when bumping this description = """ General purpose Elliptic Curve Cryptography (ECC) support, including types and traits for representing various elliptic curve forms, scalars, points, diff --git a/elliptic-curve/src/lib.rs b/elliptic-curve/src/lib.rs index c145446a2..63b99c5ef 100644 --- a/elliptic-curve/src/lib.rs +++ b/elliptic-curve/src/lib.rs @@ -4,7 +4,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/elliptic-curve/0.12.0-pre.0" + html_root_url = "https://docs.rs/elliptic-curve/0.12.0-pre.1" )] #![forbid(unsafe_code, clippy::unwrap_used)] #![warn(missing_docs, rust_2018_idioms, unused_qualifications)] From 6b05134fcd3cff03f3da1f13e9e705393f38ef7a Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 27 Jan 2022 12:48:02 -0700 Subject: [PATCH 0735/1461] elliptic-curve: v0.11.10 changelog entry (#924) The `master` branch is already the v0.12 prerelease series, however another v0.11 release was cut in #923. This adds a changelog entry, as well as "yanked" crate markers for releases which depend on `zeroize` v1.5, which #923 downgrades. --- elliptic-curve/CHANGELOG.md | 12 +++++++++--- elliptic-curve/Cargo.lock | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index 6cc45ff7f..a4a0b9028 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,13 +4,19 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 0.11.9 (2022-01-17) +## 0.11.10 (2022-01-27) +### Changed +- Revert [#884] to support a wider range of `zeroize` versions ([#923]) + +[#923]: https://github.com/RustCrypto/traits/pull/891 + +## 0.11.9 (2022-01-17) [YANKED] ### Changed - Activate `bits`, `hash2curve`, and `voprf` features on docs.rs ([#891]) [#891]: https://github.com/RustCrypto/traits/pull/891 -## 0.11.8 (2022-01-15) +## 0.11.8 (2022-01-15) [YANKED] ### Added - Impl `ZeroizeOnDrop` on appropriate items ([#884]) @@ -22,7 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [#887]: https://github.com/RustCrypto/traits/pull/887 [#888]: https://github.com/RustCrypto/traits/pull/888 -## 0.11.7 (2022-01-14) +## 0.11.7 (2022-01-14) [YANKED] ### Added - Initial hash-to-field support ([#854], [#855], [#871], [#874]) - Initial hash-to-curve support ([#865], [#876]) diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index 886ca8c7e..9659859a8 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -100,7 +100,7 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.12.0-pre.0" +version = "0.12.0-pre.1" dependencies = [ "base16ct", "base64ct", From 6c379d8829c1051e13d2c8b61bf4b341fc126d92 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 27 Jan 2022 15:47:14 -0700 Subject: [PATCH 0736/1461] build(deps): bump zeroize from 1.5.0 to 1.5.1 in /elliptic-curve (#925) Bumps [zeroize](https://github.com/RustCrypto/utils) from 1.5.0 to 1.5.1. - [Release notes](https://github.com/RustCrypto/utils/releases) - [Commits](https://github.com/RustCrypto/utils/compare/zeroize-v1.5.0...zeroize-v1.5.1) --- updated-dependencies: - dependency-name: zeroize dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- elliptic-curve/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index 9659859a8..909ced081 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -338,6 +338,6 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc222aec311c323c717f56060324f32b82da1ce1dd81d9a09aa6a9030bfe08db" +checksum = "4062c749be08d90be727e9c5895371c3a0e49b90ba2b9592dc7afda95cc2b719" From a4c2174dc0596e0c86d85651abe1dd25b41f1a98 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 30 Jan 2022 10:25:47 -0700 Subject: [PATCH 0737/1461] elliptic-curve: v0.11.11 changelog entry (#926) It looks like the docs.rs build for v0.11.10 failed due to nightly bugs: https://docs.rs/crate/elliptic-curve/0.11.10/builds/500473 This adds a changelog entry for a v0.11.11 release, which is unchanged from v0.11.10, but released again to trigger a new docs.rs build. The `master` branch is already the v0.12 prerelease series, so this commit doesn't contain a full release. --- elliptic-curve/CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index a4a0b9028..f00bfaf4a 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,9 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.11.11 (2022-01-30) +- No changes; triggering a docs.rs rebuild + ## 0.11.10 (2022-01-27) ### Changed - Revert [#884] to support a wider range of `zeroize` versions ([#923]) From 14ce927ab92f544ced8bc24e076f926a7f04b676 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 30 Jan 2022 10:54:15 -0700 Subject: [PATCH 0738/1461] elliptic-curve: add v0.11.12 changelog entry (#928) This was released in #927, and disabled the `bits` feature on docs.rs to work around a nightly breakage building the docs there. Since `master` is already the v0.12 prerelease series, this commit merely documents the release. --- elliptic-curve/CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/elliptic-curve/CHANGELOG.md b/elliptic-curve/CHANGELOG.md index f00bfaf4a..71f33e949 100644 --- a/elliptic-curve/CHANGELOG.md +++ b/elliptic-curve/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.11.12 (2022-01-30) +### Changed +- Disable `bits` feature on docs.rs due to nightly breakage ([#927]) + +[#927]: https://github.com/RustCrypto/traits/pull/927 + ## 0.11.11 (2022-01-30) - No changes; triggering a docs.rs rebuild From 941614d788506abc893508405bcdd683aa9cb58c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Feb 2022 08:00:06 -0700 Subject: [PATCH 0739/1461] build(deps): bump zeroize from 1.5.1 to 1.5.2 in /elliptic-curve (#929) Bumps [zeroize](https://github.com/RustCrypto/utils) from 1.5.1 to 1.5.2. - [Release notes](https://github.com/RustCrypto/utils/releases) - [Commits](https://github.com/RustCrypto/utils/commits) --- updated-dependencies: - dependency-name: zeroize dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- elliptic-curve/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/elliptic-curve/Cargo.lock b/elliptic-curve/Cargo.lock index 909ced081..90f53f403 100644 --- a/elliptic-curve/Cargo.lock +++ b/elliptic-curve/Cargo.lock @@ -338,6 +338,6 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.5.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4062c749be08d90be727e9c5895371c3a0e49b90ba2b9592dc7afda95cc2b719" +checksum = "7c88870063c39ee00ec285a2f8d6a966e5b6fb2becc4e8dac77ed0d370ed6006" From ff2dda49f375ce23277fb078e97199ff18d72994 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Thu, 10 Feb 2022 07:23:08 +0000 Subject: [PATCH 0740/1461] cipher v0.4, digest v0.10.2, and crypto-common v0.1.2 (#849) --- .github/workflows/cipher.yml | 18 +- .gitignore | 2 + Cargo.lock | 79 ++-- Cargo.toml | 1 - README.md | 2 +- cipher/CHANGELOG.md | 10 +- cipher/Cargo.lock | 80 ++++ cipher/Cargo.toml | 20 +- cipher/README.md | 2 +- cipher/src/block.rs | 702 +++++++++++++++++++++++------ cipher/src/dev/block.rs | 344 ++++++++++++-- cipher/src/dev/stream.rs | 198 +++----- cipher/src/errors.rs | 55 +-- cipher/src/lib.rs | 154 ++----- cipher/src/mode.rs | 42 -- cipher/src/mode_wrapper.rs | 194 -------- cipher/src/stream.rs | 200 +++++--- cipher/src/stream_core.rs | 301 +++++++++++++ cipher/src/stream_wrapper.rs | 239 ++++++++++ crypto-common/CHANGELOG.md | 8 + crypto-common/Cargo.toml | 4 +- crypto-common/src/lib.rs | 23 + digest/CHANGELOG.md | 8 +- digest/Cargo.toml | 5 +- digest/src/core_api.rs | 6 +- digest/src/core_api/ct_variable.rs | 6 +- digest/src/core_api/rt_variable.rs | 2 +- digest/src/core_api/wrapper.rs | 6 +- digest/src/core_api/xof_reader.rs | 2 +- digest/src/digest.rs | 4 +- digest/src/lib.rs | 7 +- digest/src/mac.rs | 45 +- 32 files changed, 1891 insertions(+), 878 deletions(-) create mode 100644 cipher/Cargo.lock delete mode 100644 cipher/src/mode.rs delete mode 100644 cipher/src/mode_wrapper.rs create mode 100644 cipher/src/stream_core.rs create mode 100644 cipher/src/stream_wrapper.rs diff --git a/.github/workflows/cipher.yml b/.github/workflows/cipher.yml index d18dd4b64..6389b9858 100644 --- a/.github/workflows/cipher.yml +++ b/.github/workflows/cipher.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.41.0 # MSRV + - 1.56.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -35,15 +35,16 @@ jobs: target: ${{ matrix.target }} override: true profile: minimal - - run: cargo build --target ${{ matrix.target }} --release --no-default-features - - run: cargo build --target ${{ matrix.target }} --release --no-default-features --features rand_core + - run: cargo build --target ${{ matrix.target }} + - run: cargo build --target ${{ matrix.target }} --features rand_core + - run: cargo build --target ${{ matrix.target }} --features block-padding test: runs-on: ubuntu-latest strategy: matrix: rust: - - 1.41.0 # MSRV + - 1.56.0 # MSRV - stable steps: - uses: actions/checkout@v1 @@ -52,7 +53,8 @@ jobs: profile: minimal toolchain: ${{ matrix.rust }} - run: cargo check --all-features - - run: cargo test --release - - run: cargo test --features dev --release - - run: cargo test --features std --release - - run: cargo test --all-features --release + - run: cargo test + - run: cargo test --features block-padding + - run: cargo test --features dev + - run: cargo test --features std + - run: cargo test --all-features diff --git a/.gitignore b/.gitignore index 2f7896d1d..f1148d25a 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ target/ +**/target/ +**/Cargo.lock diff --git a/Cargo.lock b/Cargo.lock index 96ff03900..65efb3529 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -22,9 +22,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.51" +version = "0.1.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44318e776df68115a881de9a8fd1b9e53368d7a4a5ce4cc48517da3393233a5e" +checksum = "061a7acccaa286c011ddc30970520b98fa40e00c9d644633fb26b5fc63a265e3" dependencies = [ "proc-macro2", "quote", @@ -39,9 +39,9 @@ checksum = "847495c209977a90e8aad588b959d0ca9f5dc228096d29a6bd3defd53f35eaec" [[package]] name = "block-buffer" -version = "0.10.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1d36a02058e76b040de25a4464ba1c80935655595b661505c8b39b664828b95" +checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" dependencies = [ "generic-array", ] @@ -58,16 +58,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "cipher" -version = "0.4.0-pre" -dependencies = [ - "blobby", - "crypto-common 0.1.1", - "generic-array", - "rand_core", -] - [[package]] name = "cpufeatures" version = "0.2.1" @@ -80,40 +70,39 @@ dependencies = [ [[package]] name = "crypto-common" version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d6b536309245c849479fba3da410962a43ed8e51c26b729208ec0ac2798d0" dependencies = [ "generic-array", - "rand_core", ] [[package]] name = "crypto-common" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683d6b536309245c849479fba3da410962a43ed8e51c26b729208ec0ac2798d0" +version = "0.1.2" dependencies = [ "generic-array", + "rand_core", ] [[package]] name = "digest" version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b697d66081d42af4fba142d56918a3cb21dc8eb63372c6b85d14f44fb9c5979b" dependencies = [ - "blobby", "block-buffer", "crypto-common 0.1.1", "generic-array", - "subtle", ] [[package]] name = "digest" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b697d66081d42af4fba142d56918a3cb21dc8eb63372c6b85d14f44fb9c5979b" +version = "0.10.2" dependencies = [ + "blobby", "block-buffer", - "crypto-common 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "generic-array", + "crypto-common 0.1.2", + "subtle", ] [[package]] @@ -128,9 +117,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c" dependencies = [ "cfg-if", "libc", @@ -148,9 +137,9 @@ dependencies = [ [[package]] name = "heapless" -version = "0.7.8" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c1ad878e07405df82b695089e63d278244344f80e764074d0bdfe99b89460f3" +checksum = "d076121838e03f862871315477528debffdb7462fb229216ecef91b1a3eb31eb" dependencies = [ "hash32", "spin", @@ -178,15 +167,15 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.109" +version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98a04dce437184842841303488f70d0188c5f51437d2a834dc097eafa909a01" +checksum = "e74d72e0f9b65b5b4ca49a346af3976df0f9c61d550727f349ecd559f251a26c" [[package]] name = "lock_api" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109" +checksum = "88943dd7ef4a2e5a4bfa2753aaab3013e34ce2533d1996fb18ef591e315e2b3b" dependencies = [ "scopeguard", ] @@ -199,18 +188,18 @@ checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" [[package]] name = "proc-macro2" -version = "1.0.33" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb37d2df5df740e582f28f8560cf425f52bb267d872fe58358eadb554909f07a" +checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" dependencies = [ "unicode-xid", ] [[package]] name = "quote" -version = "1.0.10" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" +checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" dependencies = [ "proc-macro2", ] @@ -238,14 +227,14 @@ checksum = "99c3bd8169c58782adad9290a9af5939994036b76187f7b4f0e6de91dbbfc0ec" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.10.1", ] [[package]] name = "signature" version = "1.5.0" dependencies = [ - "digest 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.10.1", "hex-literal", "rand_core", "sha2", @@ -285,9 +274,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.82" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8daf5dd0bb60cbd4137b1b587d2fc0ae729bc07cf01cd70b36a1ed5ade3b9d59" +checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b" dependencies = [ "proc-macro2", "quote", @@ -308,9 +297,9 @@ dependencies = [ [[package]] name = "typenum" -version = "1.14.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" [[package]] name = "unicode-xid" @@ -328,9 +317,9 @@ dependencies = [ [[package]] name = "version_check" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "wasi" diff --git a/Cargo.toml b/Cargo.toml index 8484c3c8e..2c1cb7dc6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,6 @@ [workspace] members = [ "aead", - "cipher", "crypto-common", "digest", "signature", diff --git a/README.md b/README.md index a52c945da..ca83276cb 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Collection of traits which describe functionality of cryptographic primitives. |---------------------|-----------|:---------:|:-----:|:----:| | [`aead`] | [Authenticated encryption] | [![crates.io](https://img.shields.io/crates/v/aead.svg)](https://crates.io/crates/aead) | [![Documentation](https://docs.rs/aead/badge.svg)](https://docs.rs/aead) | ![MSRV 1.41][msrv-1.41] | | [`async‑signature`] | [Digital signature] | [![crates.io](https://img.shields.io/crates/v/async-signature.svg)](https://crates.io/crates/async-signature) | [![Documentation](https://docs.rs/async-signature/badge.svg)](https://docs.rs/async-signature) | ![MSRV 1.41][msrv-1.41] | -| [`cipher`] | [Block] and [stream cipher] | [![crates.io](https://img.shields.io/crates/v/cipher.svg)](https://crates.io/crates/cipher) | [![Documentation](https://docs.rs/cipher/badge.svg)](https://docs.rs/cipher) | ![MSRV 1.41][msrv-1.41] | +| [`cipher`] | [Block] and [stream cipher] | [![crates.io](https://img.shields.io/crates/v/cipher.svg)](https://crates.io/crates/cipher) | [![Documentation](https://docs.rs/cipher/badge.svg)](https://docs.rs/cipher) | ![MSRV 1.56][msrv-1.56] | | [`crypto‑common`] | Common cryptographic traits | [![crates.io](https://img.shields.io/crates/v/crypto-common.svg)](https://crates.io/crates/crypto-common) | [![Documentation](https://docs.rs/crypto-common/badge.svg)](https://docs.rs/crypto-common) | ![MSRV 1.41][msrv-1.41] | | [`digest`] | [Cryptographic hash function] | [![crates.io](https://img.shields.io/crates/v/digest.svg)](https://crates.io/crates/digest) | [![Documentation](https://docs.rs/digest/badge.svg)](https://docs.rs/digest) | ![MSRV 1.41][msrv-1.41] | | [`elliptic‑curve`] | [Elliptic curve cryptography] | [![crates.io](https://img.shields.io/crates/v/elliptic-curve.svg)](https://crates.io/crates/elliptic-curve) | [![Documentation](https://docs.rs/elliptic-curve/badge.svg)](https://docs.rs/elliptic-curve) | ![MSRV 1.56][msrv-1.56] | diff --git a/cipher/CHANGELOG.md b/cipher/CHANGELOG.md index 77b955f1f..7eee95adc 100644 --- a/cipher/CHANGELOG.md +++ b/cipher/CHANGELOG.md @@ -5,11 +5,19 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [Unreleased] +## 0.3.0 (2022-02-10) +### Changed +- Major rework of traits. Core functionality of block and stream ciphers +is defined using rank-2 closures with convinience methods built on top of +it. Expose block-level trait for stream ciphers and add generic wrapper +around it. The async stream cipher trait is defined as sub-trait of +mutable block cipher traits. ([#849]) + ### Added - Re-export `rand_core` ([#683]) [#683]: https://github.com/RustCrypto/traits/pull/683 +[#849]: https://github.com/RustCrypto/traits/pull/849 ## 0.3.0 (2021-04-28) ### Added diff --git a/cipher/Cargo.lock b/cipher/Cargo.lock new file mode 100644 index 000000000..2f5d35567 --- /dev/null +++ b/cipher/Cargo.lock @@ -0,0 +1,80 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "blobby" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "847495c209977a90e8aad588b959d0ca9f5dc228096d29a6bd3defd53f35eaec" + +[[package]] +name = "block-padding" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5808df4b2412175c4db3afb115c83d8d0cd26ca4f30a042026cddef8580e526a" +dependencies = [ + "generic-array", +] + +[[package]] +name = "cipher" +version = "0.4.0" +dependencies = [ + "blobby", + "crypto-common", + "inout", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.2" +dependencies = [ + "generic-array", + "rand_core", +] + +[[package]] +name = "generic-array" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "inout" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1d8734d7f28aaff861d726dc3bc8003e2987d2fc26add21f5dab0c35d5c348a" +dependencies = [ + "block-padding", + "generic-array", +] + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" + +[[package]] +name = "typenum" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "zeroize" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c88870063c39ee00ec285a2f8d6a966e5b6fb2becc4e8dac77ed0d370ed6006" diff --git a/cipher/Cargo.toml b/cipher/Cargo.toml index 49a2b4c4e..4ef3d2a6e 100644 --- a/cipher/Cargo.toml +++ b/cipher/Cargo.toml @@ -1,25 +1,33 @@ [package] name = "cipher" description = "Traits for describing block ciphers and stream ciphers" -version = "0.4.0-pre" +version = "0.4.0" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" -edition = "2018" +edition = "2021" +rust-version = "1.56" documentation = "https://docs.rs/cipher" repository = "https://github.com/RustCrypto/traits" keywords = ["crypto", "block-cipher", "stream-cipher", "trait"] categories = ["cryptography", "no-std"] +# Hack to allow this crate to coexist with pre-2021 edition crates +[workspace] +members = ["."] + [dependencies] -generic-array = "0.14" -crypto-common = { version = "0.1", path = "../crypto-common" } +crypto-common = { version = "0.1.2", path = "../crypto-common" } +inout = "0.1" +# optional dependencies blobby = { version = "0.3", optional = true } -rand_core = { version = "0.6", optional = true } +zeroize = { version = "1.5", optional = true, default-features = false } [features] -std = ["crypto-common/std", "rand_core/std"] +std = ["crypto-common/std", "inout/std"] +block-padding = ["inout/block-padding"] +rand_core = ["crypto-common/rand_core"] # Enable random key and IV generation methods dev = ["blobby"] [package.metadata.docs.rs] diff --git a/cipher/README.md b/cipher/README.md index b2c33abd7..9d117626d 100644 --- a/cipher/README.md +++ b/cipher/README.md @@ -16,7 +16,7 @@ implementations which use these traits. ## Minimum Supported Rust Version -Rust **1.41** or higher. +Rust **1.56** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. diff --git a/cipher/src/block.rs b/cipher/src/block.rs index 1769c782e..9c22fe3e8 100644 --- a/cipher/src/block.rs +++ b/cipher/src/block.rs @@ -10,228 +10,640 @@ //! [2]: https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation //! [3]: https://en.wikipedia.org/wiki/Symmetric-key_algorithm -use crate::errors::InvalidLength; -use crate::{FromKey, FromKeyNonce}; -use core::convert::TryInto; -use generic_array::{typenum::Unsigned, ArrayLength, GenericArray}; +use crate::{ParBlocks, ParBlocksSizeUser}; +#[cfg(feature = "block-padding")] +use inout::{ + block_padding::{Padding, UnpadError}, + InOutBufReserved, PadError, +}; +use inout::{InOut, InOutBuf, NotEqualError}; + +pub use crypto_common::{generic_array::ArrayLength, typenum::Unsigned, Block, BlockSizeUser}; + +/// Marker trait for block ciphers. +pub trait BlockCipher: BlockSizeUser {} + +/// Trait implemented by block cipher encryption and decryption backends. +pub trait BlockBackend: ParBlocksSizeUser { + /// Process single inout block. + fn proc_block(&mut self, block: InOut<'_, '_, Block>); + + /// Process inout blocks in parallel. + #[inline(always)] + fn proc_par_blocks(&mut self, mut blocks: InOut<'_, '_, ParBlocks>) { + for i in 0..Self::ParBlocksSize::USIZE { + self.proc_block(blocks.get(i)); + } + } -/// Key for an algorithm that implements [`FromKey`]. -pub type BlockCipherKey = GenericArray::KeySize>; + /// Process buffer of inout blocks. Length of the buffer MUST be smaller + /// than `Self::ParBlocksSize`. + #[inline(always)] + fn proc_tail_blocks(&mut self, blocks: InOutBuf<'_, '_, Block>) { + assert!(blocks.len() < Self::ParBlocksSize::USIZE); + for block in blocks { + self.proc_block(block); + } + } -/// Block on which a [`BlockCipher`] operates. -pub type Block = GenericArray::BlockSize>; + /// Process single block in-place. + #[inline(always)] + fn proc_block_inplace(&mut self, block: &mut Block) { + self.proc_block(block.into()); + } -/// Block on which a [`BlockCipher`] operates in parallel. -pub type ParBlocks = GenericArray, ::ParBlocks>; + /// Process blocks in parallel in-place. + #[inline(always)] + fn proc_par_blocks_inplace(&mut self, blocks: &mut ParBlocks) { + self.proc_par_blocks(blocks.into()); + } -/// Trait which marks a type as being a block cipher. -pub trait BlockCipher { - /// Size of the block in bytes - type BlockSize: ArrayLength; + /// Process buffer of blocks in-place. Length of the buffer MUST be smaller + /// than `Self::ParBlocksSize`. + #[inline(always)] + fn proc_tail_blocks_inplace(&mut self, blocks: &mut [Block]) { + self.proc_tail_blocks(blocks.into()); + } +} - /// Number of blocks which can be processed in parallel by - /// cipher implementation - type ParBlocks: ArrayLength>; +/// Trait for [`BlockBackend`] users. +/// +/// This trait is used to define rank-2 closures. +pub trait BlockClosure: BlockSizeUser { + /// Execute closure with the provided block cipher backend. + fn call>(self, backend: &mut B); } /// Encrypt-only functionality for block ciphers. -pub trait BlockEncrypt: BlockCipher { - /// Encrypt block in-place - fn encrypt_block(&self, block: &mut Block); +pub trait BlockEncrypt: BlockSizeUser + Sized { + /// Encrypt data using backend provided to the rank-2 closure. + fn encrypt_with_backend(&self, f: impl BlockClosure); - /// Encrypt several blocks in parallel using instruction level parallelism - /// if possible. - /// - /// If `ParBlocks` equals to 1 it's equivalent to `encrypt_block`. + /// Encrypt single `inout` block. #[inline] - fn encrypt_par_blocks(&self, blocks: &mut ParBlocks) { - for block in blocks.iter_mut() { - self.encrypt_block(block); - } + fn encrypt_block_inout(&self, block: InOut<'_, '_, Block>) { + self.encrypt_with_backend(BlockCtx { block }); } - /// Encrypt a slice of blocks, leveraging parallelism when available. + /// Encrypt `inout` blocks. #[inline] - fn encrypt_blocks(&self, mut blocks: &mut [Block]) { - let pb = Self::ParBlocks::to_usize(); + fn encrypt_blocks_inout(&self, blocks: InOutBuf<'_, '_, Block>) { + self.encrypt_with_backend(BlocksCtx { blocks }); + } - if pb > 1 { - let mut iter = blocks.chunks_exact_mut(pb); + /// Encrypt single block in-place. + #[inline] + fn encrypt_block(&self, block: &mut Block) { + let block = block.into(); + self.encrypt_with_backend(BlockCtx { block }); + } - for chunk in &mut iter { - self.encrypt_par_blocks(chunk.try_into().unwrap()) - } + /// Encrypt `in_block` and write result to `out_block`. + #[inline] + fn encrypt_block_b2b(&self, in_block: &Block, out_block: &mut Block) { + let block = (in_block, out_block).into(); + self.encrypt_with_backend(BlockCtx { block }); + } - blocks = iter.into_remainder(); - } + /// Encrypt blocks in-place. + #[inline] + fn encrypt_blocks(&self, blocks: &mut [Block]) { + let blocks = blocks.into(); + self.encrypt_with_backend(BlocksCtx { blocks }); + } - for block in blocks { - self.encrypt_block(block); + /// Encrypt blocks buffer-to-buffer. + /// + /// Returns [`NotEqualError`] if provided `in_blocks` and `out_blocks` + /// have different lengths. + #[inline] + fn encrypt_blocks_b2b( + &self, + in_blocks: &[Block], + out_blocks: &mut [Block], + ) -> Result<(), NotEqualError> { + InOutBuf::new(in_blocks, out_blocks) + .map(|blocks| self.encrypt_with_backend(BlocksCtx { blocks })) + } + + /// Pad input and encrypt. Returns resulting ciphertext slice. + /// + /// Returns [`PadError`] if length of output buffer is not sufficient. + #[cfg(feature = "block-padding")] + #[cfg_attr(docsrs, doc(cfg(feature = "block-padding")))] + #[inline] + fn encrypt_padded_inout<'inp, 'out, P: Padding>( + &self, + data: InOutBufReserved<'inp, 'out, u8>, + ) -> Result<&'out [u8], PadError> { + let mut buf = data.into_padded_blocks::()?; + self.encrypt_blocks_inout(buf.get_blocks()); + if let Some(block) = buf.get_tail_block() { + self.encrypt_block_inout(block); } + Ok(buf.into_out()) + } + + /// Pad input and encrypt in-place. Returns resulting ciphertext slice. + /// + /// Returns [`PadError`] if length of output buffer is not sufficient. + #[cfg(feature = "block-padding")] + #[cfg_attr(docsrs, doc(cfg(feature = "block-padding")))] + #[inline] + fn encrypt_padded<'a, P: Padding>( + &self, + buf: &'a mut [u8], + msg_len: usize, + ) -> Result<&'a [u8], PadError> { + let buf = InOutBufReserved::from_mut_slice(buf, msg_len).map_err(|_| PadError)?; + self.encrypt_padded_inout::